Skip to content

Commit 4f9fef7

Browse files
committed
update tinyusb lib
1 parent e770ae4 commit 4f9fef7

File tree

6 files changed

+140
-111
lines changed

6 files changed

+140
-111
lines changed

cores/arduino/Adafruit_TinyUSB_Core/tinyusb/src/class/msc/msc_device.c

Lines changed: 109 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
159159
case MSC_REQ_GET_MAX_LUN:
160160
{
161161
uint8_t maxlun = 1;
162-
if (tud_msc_maxlun_cb) maxlun = tud_msc_maxlun_cb();
162+
if (tud_msc_get_maxlun_cb) maxlun = tud_msc_get_maxlun_cb();
163163
TU_VERIFY(maxlun);
164164

165165
// MAX LUN is minus 1 by specs
@@ -186,30 +186,64 @@ bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const
186186
return true;
187187
}
188188

189-
// return length of response (copied to buffer), -1 if it is not an built-in commands
190-
int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize)
189+
// return response's length (copied to buffer). Negative if it is not an built-in command or indicate Failed status (CSW)
190+
// In case of a failed status, sense key must be set for reason of failure
191+
int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize)
191192
{
192193
(void) bufsize; // TODO refractor later
193-
int32_t ret;
194+
int32_t resplen;
194195

195-
switch ( p_cbw->command[0] )
196+
switch ( scsi_cmd[0] )
196197
{
198+
case SCSI_CMD_TEST_UNIT_READY:
199+
resplen = 0;
200+
if ( !tud_msc_test_unit_ready_cb(lun) )
201+
{
202+
// not ready response with Failed status and sense key = not ready
203+
resplen = - 1;
204+
205+
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable
206+
if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00);
207+
}
208+
break;
209+
210+
case SCSI_CMD_START_STOP_UNIT:
211+
resplen = 0;
212+
213+
if (tud_msc_start_stop_cb)
214+
{
215+
scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
216+
tud_msc_start_stop_cb(lun, start_stop->power_condition, start_stop->start, start_stop->load_eject);
217+
}
218+
break;
219+
197220
case SCSI_CMD_READ_CAPACITY_10:
198221
{
199-
scsi_read_capacity10_resp_t read_capa10;
200-
201222
uint32_t block_count;
202223
uint32_t block_size;
203224
uint16_t block_size_u16;
204225

205-
tud_msc_capacity_cb(p_cbw->lun, &block_count, &block_size_u16);
226+
tud_msc_capacity_cb(lun, &block_count, &block_size_u16);
206227
block_size = (uint32_t) block_size_u16;
207228

208-
read_capa10.last_lba = ENDIAN_BE(block_count-1);
209-
read_capa10.block_size = ENDIAN_BE(block_size);
229+
// Invalid block size/count from callback, possibly unit is not ready
230+
// stall this request, set sense key to NOT READY
231+
if (block_count == 0 || block_size == 0)
232+
{
233+
resplen = -1;
234+
235+
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable
236+
if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00);
237+
}else
238+
{
239+
scsi_read_capacity10_resp_t read_capa10;
240+
241+
read_capa10.last_lba = ENDIAN_BE(block_count-1);
242+
read_capa10.block_size = ENDIAN_BE(block_size);
210243

211-
ret = sizeof(read_capa10);
212-
memcpy(buffer, &read_capa10, ret);
244+
resplen = sizeof(read_capa10);
245+
memcpy(buffer, &read_capa10, resplen);
246+
}
213247
}
214248
break;
215249

@@ -226,12 +260,24 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
226260
uint32_t block_count;
227261
uint16_t block_size;
228262

229-
tud_msc_capacity_cb(p_cbw->lun, &block_count, &block_size);
230-
read_fmt_capa.block_num = ENDIAN_BE(block_count);
231-
read_fmt_capa.block_size_u16 = ENDIAN_BE16(block_size);
263+
tud_msc_capacity_cb(lun, &block_count, &block_size);
264+
265+
// Invalid block size/count from callback, possibly unit is not ready
266+
// stall this request, set sense key to NOT READY
267+
if (block_count == 0 || block_size == 0)
268+
{
269+
resplen = -1;
232270

233-
ret = sizeof(read_fmt_capa);
234-
memcpy(buffer, &read_fmt_capa, ret);
271+
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable
272+
if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00);
273+
}else
274+
{
275+
read_fmt_capa.block_num = ENDIAN_BE(block_count);
276+
read_fmt_capa.block_size_u16 = ENDIAN_BE16(block_size);
277+
278+
resplen = sizeof(read_fmt_capa);
279+
memcpy(buffer, &read_fmt_capa, resplen);
280+
}
235281
}
236282
break;
237283

@@ -242,23 +288,17 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
242288
.is_removable = 1,
243289
.version = 2,
244290
.response_data_format = 2,
245-
// vendor_id, product_id, product_rev is space padded string
246-
.vendor_id = "",
247-
.product_id = "",
248-
.product_rev = "",
249291
};
250292

251-
memset(inquiry_rsp.vendor_id, ' ', sizeof(inquiry_rsp.vendor_id));
252-
memcpy(inquiry_rsp.vendor_id, CFG_TUD_MSC_VENDOR, tu_min32(strlen(CFG_TUD_MSC_VENDOR), sizeof(inquiry_rsp.vendor_id)));
253-
254-
memset(inquiry_rsp.product_id, ' ', sizeof(inquiry_rsp.product_id));
255-
memcpy(inquiry_rsp.product_id, CFG_TUD_MSC_PRODUCT, tu_min32(strlen(CFG_TUD_MSC_PRODUCT), sizeof(inquiry_rsp.product_id)));
256-
293+
// vendor_id, product_id, product_rev is space padded string
294+
memset(inquiry_rsp.vendor_id , ' ', sizeof(inquiry_rsp.vendor_id));
295+
memset(inquiry_rsp.product_id , ' ', sizeof(inquiry_rsp.product_id));
257296
memset(inquiry_rsp.product_rev, ' ', sizeof(inquiry_rsp.product_rev));
258-
memcpy(inquiry_rsp.product_rev, CFG_TUD_MSC_PRODUCT_REV, tu_min32(strlen(CFG_TUD_MSC_PRODUCT_REV), sizeof(inquiry_rsp.product_rev)));
259297

260-
ret = sizeof(inquiry_rsp);
261-
memcpy(buffer, &inquiry_rsp, ret);
298+
tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev);
299+
300+
resplen = sizeof(inquiry_rsp);
301+
memcpy(buffer, &inquiry_rsp, resplen);
262302
}
263303
break;
264304

@@ -275,12 +315,12 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
275315

276316
bool writable = true;
277317
if (tud_msc_is_writable_cb) {
278-
writable = tud_msc_is_writable_cb(p_cbw->lun);
318+
writable = tud_msc_is_writable_cb(lun);
279319
}
280320
mode_resp.write_protected = !writable;
281321

282-
ret = sizeof(mode_resp);
283-
memcpy(buffer, &mode_resp, ret);
322+
resplen = sizeof(mode_resp);
323+
memcpy(buffer, &mode_resp, resplen);
284324
}
285325
break;
286326

@@ -298,18 +338,18 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
298338
sense_rsp.add_sense_code = _mscd_itf.add_sense_code;
299339
sense_rsp.add_sense_qualifier = _mscd_itf.add_sense_qualifier;
300340

301-
ret = sizeof(sense_rsp);
302-
memcpy(buffer, &sense_rsp, ret);
341+
resplen = sizeof(sense_rsp);
342+
memcpy(buffer, &sense_rsp, resplen);
303343

304344
// Clear sense data after copy
305-
tud_msc_set_sense(p_cbw->lun, 0, 0, 0);
345+
tud_msc_set_sense(lun, 0, 0, 0);
306346
}
307347
break;
308348

309-
default: ret = -1; break;
349+
default: resplen = -1; break;
310350
}
311351

312-
return ret;
352+
return resplen;
313353
}
314354

315355
bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
@@ -348,60 +388,50 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
348388
else
349389
{
350390
// For other SCSI commands
351-
// 1. Zero : Invoke app callback, skip DATA and move to STATUS stage
352-
// 2. OUT : queue transfer (invoke app callback after done)
353-
// 3. IN : invoke app callback to get response
354-
if ( p_cbw->total_bytes == 0)
391+
// 1. OUT : queue transfer (invoke app callback after done)
392+
// 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length
393+
if ( (p_cbw->total_bytes > 0 ) && !TU_BIT_TEST(p_cbw->dir, 7) )
355394
{
356-
int32_t const cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, NULL, 0);
357-
358-
p_msc->total_len = 0;
359-
p_msc->stage = MSC_STAGE_STATUS;
360-
361-
if ( cb_result < 0 )
362-
{
363-
p_csw->status = MSC_CSW_STATUS_FAILED;
364-
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
365-
}
366-
else
367-
{
368-
p_csw->status = MSC_CSW_STATUS_PASSED;
369-
}
370-
}
371-
else if ( !TU_BIT_TEST(p_cbw->dir, 7) )
372-
{
373-
// OUT transfer
395+
// queue transfer
374396
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) );
375-
}
376-
else
397+
}else
377398
{
378-
// IN Transfer
379-
int32_t cb_result;
399+
int32_t resplen;
380400

381-
// first process if it is a built-in commands
382-
cb_result = proc_builtin_scsi(p_cbw, _mscd_buf, sizeof(_mscd_buf));
401+
// First process if it is a built-in commands
402+
resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf));
383403

384-
// Not an built-in command, invoke user callback
385-
if ( cb_result < 0 )
404+
// Not built-in, invoke user callback
405+
if ( (resplen < 0) && (p_msc->sense_key == 0) )
386406
{
387-
cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
407+
resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
388408
}
389409

390-
if ( cb_result > 0 )
391-
{
392-
p_msc->total_len = (uint32_t) cb_result;
393-
p_csw->status = MSC_CSW_STATUS_PASSED;
394-
395-
TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect
396-
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
397-
}else
410+
if ( resplen < 0 )
398411
{
399412
p_msc->total_len = 0;
400413
p_csw->status = MSC_CSW_STATUS_FAILED;
401414
p_msc->stage = MSC_STAGE_STATUS;
402415

403-
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
404-
usbd_edpt_stall(rhport, p_msc->ep_in);
416+
// failed but senskey is not set: default to Illegal Request
417+
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
418+
419+
/// Stall bulk In if needed
420+
if (p_cbw->total_bytes) usbd_edpt_stall(rhport, p_msc->ep_in);
421+
}
422+
else
423+
{
424+
p_msc->total_len = (uint32_t) resplen;
425+
p_csw->status = MSC_CSW_STATUS_PASSED;
426+
427+
if (p_msc->total_len)
428+
{
429+
TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect
430+
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
431+
}else
432+
{
433+
p_msc->stage = MSC_STAGE_STATUS;
434+
}
405435
}
406436
}
407437
}

cores/arduino/Adafruit_TinyUSB_Core/tinyusb/src/class/msc/msc_device.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,6 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
4444
#error CFG_TUD_MSC_BUFSIZE must be defined, value of a block size should work well, the more the better
4545
#endif
4646

47-
#ifndef CFG_TUD_MSC_VENDOR
48-
#error CFG_TUD_MSC_VENDOR 8-byte name must be defined
49-
#endif
50-
51-
#ifndef CFG_TUD_MSC_PRODUCT
52-
#error CFG_TUD_MSC_PRODUCT 16-byte name must be defined
53-
#endif
54-
55-
#ifndef CFG_TUD_MSC_PRODUCT_REV
56-
#error CFG_TUD_MSC_PRODUCT_REV 4-byte string must be defined
57-
#endif
58-
5947
/** \addtogroup ClassDriver_MSC
6048
* @{
6149
* \defgroup MSC_Device Device
@@ -105,12 +93,23 @@ ATTR_WEAK int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset,
10593
*/
10694
ATTR_WEAK int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
10795

96+
// Invoked when received SCSI_CMD_INQUIRY
97+
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
98+
ATTR_WEAK void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
99+
100+
// Invoked when received Test Unit Ready command.
101+
// return true allowing host to read/write this LUN e.g SD card inserted
102+
ATTR_WEAK bool tud_msc_test_unit_ready_cb(uint8_t lun);
103+
108104
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
109105
// Application update block count and block size
110106
ATTR_WEAK void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
111107

112108
/**
113-
* Callback invoked when received an SCSI command not in built-in list below.
109+
* Invoked when received an SCSI command not in built-in list below.
110+
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, PREVENT_ALLOW_MEDIUM_REMOVE, MODE_SENSE6, REQUEST_SENSE
111+
* - READ10 and WRITE10 has their own callbacks
112+
*
114113
* \param[in] lun Logical unit number
115114
* \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
116115
* \param[out] buffer Buffer for SCSI Data Stage.
@@ -121,17 +120,18 @@ ATTR_WEAK void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t*
121120
* \return Actual bytes processed, can be zero for no-data command.
122121
* \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
123122
* endpoint and return failed status in command status wrapper phase.
124-
*
125-
* \note Following command is automatically handled by tinyusb stack, callback should not be worried:
126-
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
127-
* - READ10 and WRITE10 has their own callbacks
128123
*/
129124
ATTR_WEAK int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
130125

131126
/*------------- Optional callbacks -------------*/
132127

133-
// Invoked when received GET_MAX_LUN request
134-
ATTR_WEAK uint8_t tud_msc_maxlun_cb(void);
128+
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
129+
ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
130+
131+
// Invoked when received Start Stop Unit command
132+
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
133+
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
134+
ATTR_WEAK void tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
135135

136136
// Invoked when Read10 command is complete
137137
ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);

cores/arduino/Adafruit_TinyUSB_Core/tinyusb/src/device/dcd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ void dcd_remote_wakeup(uint8_t rhport);
107107
* must be called to notify the stack
108108
* - busy : Check if endpoint transferring is complete (TODO remove)
109109
* - stall : stall endpoint
110-
* - clear_stall : clear stall
110+
* - clear_stall : clear stall, data toggle is also reset to DATA0
111111
*------------------------------------------------------------------*/
112112
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
113113
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);

cores/arduino/Adafruit_TinyUSB_Core/tinyusb/src/device/usbd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
456456
case TUSB_REQ_CLEAR_FEATURE:
457457
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
458458
{
459-
dcd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
459+
usbd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
460460
}
461461
usbd_control_status(rhport, p_request);
462462
break;

cores/arduino/Adafruit_TinyUSB_Core/tinyusb/src/tusb_option.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@
128128
*/
129129
#ifndef CFG_TUSB_DEBUG
130130
#define CFG_TUSB_DEBUG 0
131-
#warning CFG_TUSB_DEBUG is not defined, default value is 0
132131
#endif
133132

134133
// place data in accessible RAM for usb controller
@@ -165,6 +164,15 @@
165164
#define CFG_TUD_MSC 0
166165
#endif
167166

167+
168+
#ifndef CFG_TUD_MIDI
169+
#define CFG_TUD_MIDI 0
170+
#endif
171+
172+
#ifndef CFG_TUD_CUSTOM_CLASS
173+
#define CFG_TUD_CUSTOM_CLASS 0
174+
#endif
175+
168176
#endif // TUSB_OPT_DEVICE_ENABLED
169177

170178
//--------------------------------------------------------------------

0 commit comments

Comments
 (0)