Skip to content

Commit b5278c5

Browse files
committed
add msc
1 parent 3ae1f98 commit b5278c5

6 files changed

+324
-0
lines changed

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 Ha Thach for Adafruit Industries
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

Diff for: library.properties

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name=Adafruit TinyUSB Library
2+
version=0.0.1
3+
author=Adafruit
4+
maintainer=Adafruit <[email protected]>
5+
sentence=TinyUSB library for Arduino
6+
paragraph=TinyUSB library for Arduino
7+
category=Communication
8+
url=https://github.com/adafruit/Adafruit_TinyUSB_Arduino
9+
architectures=*
10+
includes=Adafruit_TinyUSB.h

Diff for: src/Adafruit_TinyUSB.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach for Adafruit Industries
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#include "Arduino.h"
26+
#include "Adafruit_TinyUSB.h"
27+
28+
//--------------------------------------------------------------------+
29+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
30+
//--------------------------------------------------------------------+
31+
32+
33+
//------------- IMPLEMENTATION -------------//
34+

Diff for: src/Adafruit_TinyUSB.h

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach for Adafruit Industries
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#ifndef ADAFRUIT_TINYUSB_H_
26+
#define ADAFRUIT_TINYUSB_H_
27+
28+
#include "Adafruit_USBD_MSC.h"
29+
30+
#endif /* ADAFRUIT_TINYUSB_H_ */

Diff for: src/Adafruit_USBD_MSC.cpp

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach for Adafruit Industries
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#include "Adafruit_USBD_MSC.h"
26+
27+
#define EPOUT 0x00
28+
#define EPIN 0x80
29+
#define EPSIZE 64 // TODO must be 512 for highspeed device
30+
31+
static Adafruit_USBD_MSC* _msc_dev = NULL;
32+
33+
Adafruit_USBD_MSC::Adafruit_USBD_MSC(void)
34+
{
35+
_block_count = 0;
36+
_block_size = 0;
37+
}
38+
39+
uint16_t Adafruit_USBD_MSC::getDescriptor(uint8_t* buf, uint16_t bufsize)
40+
{
41+
uint8_t desc[] = { TUD_MSC_DESCRIPTOR(0, 0, EPOUT, EPIN, EPSIZE) };
42+
uint16_t const len = sizeof(desc);
43+
44+
if ( bufsize < len ) return 0;
45+
memcpy(buf, desc, len);
46+
return len;
47+
}
48+
49+
void Adafruit_USBD_MSC::setCapacity(uint32_t block_count, uint16_t block_size)
50+
{
51+
_block_count = block_count;
52+
_block_size = block_size;
53+
}
54+
55+
void Adafruit_USBD_MSC::getCapacity(uint32_t* block_count, uint16_t* block_size)
56+
{
57+
(*block_count) = _block_count;
58+
(*block_size) = _block_size;
59+
}
60+
61+
void Adafruit_USBD_MSC::setCallback(read_callback_t rd_cb, write_callback_t wr_cb, flush_callback_t fl_cb)
62+
{
63+
_rd_cb = rd_cb;
64+
_wr_cb = wr_cb;
65+
_fl_cb = fl_cb;
66+
}
67+
68+
bool Adafruit_USBD_MSC::begin(void)
69+
{
70+
if ( !USBDevice.addInterface(*this) ) return false;
71+
72+
_msc_dev = this;
73+
return true;
74+
}
75+
76+
extern "C"
77+
{
78+
79+
// Callback invoked when received an SCSI command not in built-in list below
80+
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
81+
// - READ10 and WRITE10 has their own callbacks
82+
int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer, uint16_t bufsize)
83+
{
84+
const void* response = NULL;
85+
uint16_t resplen = 0;
86+
87+
switch ( scsi_cmd[0] )
88+
{
89+
case SCSI_CMD_TEST_UNIT_READY:
90+
// Command that host uses to check our readiness before sending other commands
91+
resplen = 0;
92+
break;
93+
94+
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
95+
// Host is about to read/write etc ... better not to disconnect disk
96+
resplen = 0;
97+
break;
98+
99+
case SCSI_CMD_START_STOP_UNIT:
100+
// Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
101+
/* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
102+
// Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
103+
// Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
104+
start_stop->start;
105+
start_stop->load_eject;
106+
*/
107+
resplen = 0;
108+
break;
109+
110+
default:
111+
// Set Sense = Invalid Command Operation
112+
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
113+
114+
// negative means error -> tinyusb could stall and/or response with failed status
115+
resplen = -1;
116+
break;
117+
}
118+
119+
// return len must not larger than bufsize
120+
if ( resplen > bufsize ) resplen = bufsize;
121+
122+
// copy response to stack's buffer if any
123+
if ( response && resplen )
124+
{
125+
memcpy(buffer, response, resplen);
126+
}
127+
128+
return resplen;
129+
}
130+
131+
// Callback invoked when received READ10 command.
132+
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
133+
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
134+
{
135+
if ( !(_msc_dev && _msc_dev->_rd_cb) ) return -1;
136+
137+
return _msc_dev->_rd_cb(lun, lba, offset, buffer, bufsize);
138+
}
139+
140+
// Callback invoked when received WRITE10 command.
141+
// Process data in buffer to disk's storage and return number of written bytes
142+
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
143+
{
144+
if ( !(_msc_dev && _msc_dev->_wr_cb) ) return -1;
145+
146+
return _msc_dev->_wr_cb(lun, lba, offset, buffer, bufsize);
147+
}
148+
149+
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
150+
// used to flush any pending cache.
151+
void tud_msc_write10_complete_cb (uint8_t lun)
152+
{
153+
if ( !(_msc_dev && _msc_dev->_fl_cb) ) return;
154+
155+
// flush pending cache when write10 is complete
156+
return _msc_dev->_fl_cb(lun);
157+
}
158+
159+
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
160+
{
161+
(void) lun;
162+
if (!_msc_dev) return;
163+
164+
_msc_dev->getCapacity(block_count, block_size);
165+
}
166+
167+
}
168+

Diff for: src/Adafruit_USBD_MSC.h

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach for Adafruit Industries
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#ifndef ADAFRUIT_USBD_MSC_H_
26+
#define ADAFRUIT_USBD_MSC_H_
27+
28+
#include "Adafruit_TinyUSB_core.h"
29+
30+
class Adafruit_USBD_MSC : Adafruit_USBD_Interface
31+
{
32+
public:
33+
typedef int32_t (*read_callback_t ) (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
34+
typedef int32_t (*write_callback_t) (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
35+
typedef void (*flush_callback_t) (uint8_t lun);
36+
37+
Adafruit_USBD_MSC(void);
38+
39+
bool begin(void);
40+
41+
void setCapacity(uint32_t block_count, uint16_t block_size);
42+
void getCapacity(uint32_t* block_count, uint16_t* block_size);
43+
void setCallback(read_callback_t rd_cb, write_callback_t wr_cb, flush_callback_t fl_cb);
44+
45+
// from Adafruit_USBD_Interface
46+
virtual uint16_t getDescriptor(uint8_t* buf, uint16_t bufsize);
47+
48+
private:
49+
uint32_t _block_count;
50+
uint16_t _block_size;
51+
52+
read_callback_t _rd_cb;
53+
write_callback_t _wr_cb;
54+
flush_callback_t _fl_cb;
55+
56+
friend int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
57+
friend int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
58+
friend void tud_msc_write10_complete_cb (uint8_t lun);
59+
};
60+
61+
#endif /* ADAFRUIT_USBD_MSC_H_ */

0 commit comments

Comments
 (0)