mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-23 22:43:49 +00:00
commit
bfa073818c
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,6 +15,4 @@ tests/build
|
|||||||
.env
|
.env
|
||||||
/tests/lpc175x_6x/build/
|
/tests/lpc175x_6x/build/
|
||||||
/tests/lpc18xx_43xx/build/
|
/tests/lpc18xx_43xx/build/
|
||||||
/demos/*/*/Board_*
|
|
||||||
/demos/*/*/KeilBuild/
|
|
||||||
/examples/*/*/build-*
|
/examples/*/*/build-*
|
||||||
|
@ -118,6 +118,59 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
|
|||||||
README_CONTENTS
|
README_CONTENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_INQUIRY
|
||||||
|
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||||
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
const char vid[] = "TinyUSB";
|
||||||
|
const char pid[] = "Mass Storage";
|
||||||
|
const char rev[] = "1.0";
|
||||||
|
|
||||||
|
memcpy(vendor_id , vid, strlen(vid));
|
||||||
|
memcpy(product_id , pid, strlen(pid));
|
||||||
|
memcpy(product_rev, rev, strlen(rev));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Test Unit Ready command.
|
||||||
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
|
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
return true; // RAM disk is always ready
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
|
// Application update block count and block size
|
||||||
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
*block_count = DISK_BLOCK_NUM;
|
||||||
|
*block_size = DISK_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Start Stop Unit command
|
||||||
|
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||||
|
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||||
|
void tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
(void) power_condition;
|
||||||
|
|
||||||
|
if ( load_eject )
|
||||||
|
{
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
// load disk storage
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// unload disk storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Callback invoked when received READ10 command.
|
// Callback invoked when received READ10 command.
|
||||||
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
||||||
@ -147,15 +200,6 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
|
|||||||
return bufsize;
|
return bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback invoked to determine disk's size
|
|
||||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
|
||||||
{
|
|
||||||
(void) lun;
|
|
||||||
|
|
||||||
*block_count = DISK_BLOCK_NUM;
|
|
||||||
*block_size = DISK_BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback invoked when received an SCSI command not in built-in list below
|
// Callback invoked when received an SCSI command not in built-in list below
|
||||||
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
||||||
// - READ10 and WRITE10 has their own callbacks
|
// - READ10 and WRITE10 has their own callbacks
|
||||||
@ -171,28 +215,11 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_TEST_UNIT_READY:
|
|
||||||
// Command that host uses to check our readiness before sending other commands
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
// Host is about to read/write etc ... better not to disconnect disk
|
||||||
resplen = 0;
|
resplen = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_CMD_START_STOP_UNIT:
|
|
||||||
// Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
|
|
||||||
/* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
|
|
||||||
// Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
|
|
||||||
// Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
|
|
||||||
start_stop->start;
|
|
||||||
start_stop->load_eject;
|
|
||||||
*/
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Set Sense = Invalid Command Operation
|
// Set Sense = Invalid Command Operation
|
||||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
@ -88,15 +88,6 @@
|
|||||||
// Buffer size of Device Mass storage
|
// Buffer size of Device Mass storage
|
||||||
#define CFG_TUD_MSC_BUFSIZE 512
|
#define CFG_TUD_MSC_BUFSIZE 512
|
||||||
|
|
||||||
// Vendor name included in Inquiry response, max 8 bytes
|
|
||||||
#define CFG_TUD_MSC_VENDOR "tinyusb"
|
|
||||||
|
|
||||||
// Product name included in Inquiry response, max 16 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT "tusb msc"
|
|
||||||
|
|
||||||
// Product revision string included in Inquiry response, max 4 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT_REV "1.0"
|
|
||||||
|
|
||||||
//------------- HID -------------//
|
//------------- HID -------------//
|
||||||
|
|
||||||
// Should be sufficient to hold ID (if any) + Data
|
// Should be sufficient to hold ID (if any) + Data
|
||||||
|
@ -117,7 +117,7 @@ enum
|
|||||||
|
|
||||||
uint8_t const desc_configuration[] =
|
uint8_t const desc_configuration[] =
|
||||||
{
|
{
|
||||||
// Inteface count, string index, total length, attribute, power in mA
|
// Interface count, string index, total length, attribute, power in mA
|
||||||
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||||
|
|
||||||
#if CFG_TUD_CDC
|
#if CFG_TUD_CDC
|
||||||
|
@ -118,6 +118,60 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
|
|||||||
README_CONTENTS
|
README_CONTENTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_INQUIRY
|
||||||
|
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||||
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
const char vid[] = "TinyUSB";
|
||||||
|
const char pid[] = "Mass Storage";
|
||||||
|
const char rev[] = "1.0";
|
||||||
|
|
||||||
|
memcpy(vendor_id , vid, strlen(vid));
|
||||||
|
memcpy(product_id , pid, strlen(pid));
|
||||||
|
memcpy(product_rev, rev, strlen(rev));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Test Unit Ready command.
|
||||||
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
|
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
return true; // RAM disk is always ready
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
|
// Application update block count and block size
|
||||||
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
*block_count = DISK_BLOCK_NUM;
|
||||||
|
*block_size = DISK_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Start Stop Unit command
|
||||||
|
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||||
|
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||||
|
void tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
(void) power_condition;
|
||||||
|
|
||||||
|
if ( load_eject )
|
||||||
|
{
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
// load disk storage
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// unload disk storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Callback invoked when received READ10 command.
|
// Callback invoked when received READ10 command.
|
||||||
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
||||||
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
|
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
|
||||||
@ -146,14 +200,6 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
|
|||||||
return bufsize;
|
return bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
|
||||||
{
|
|
||||||
(void) lun;
|
|
||||||
|
|
||||||
*block_count = DISK_BLOCK_NUM;
|
|
||||||
*block_size = DISK_BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback invoked when received an SCSI command not in built-in list below
|
// Callback invoked when received an SCSI command not in built-in list below
|
||||||
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
||||||
// - READ10 and WRITE10 has their own callbacks
|
// - READ10 and WRITE10 has their own callbacks
|
||||||
@ -169,11 +215,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_TEST_UNIT_READY:
|
|
||||||
// Command that host uses to check our readiness before sending other commands
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
// Host is about to read/write etc ... better not to disconnect disk
|
||||||
resplen = 0;
|
resplen = 0;
|
||||||
|
@ -88,15 +88,6 @@
|
|||||||
// Buffer size of Device Mass storage
|
// Buffer size of Device Mass storage
|
||||||
#define CFG_TUD_MSC_BUFSIZE 512
|
#define CFG_TUD_MSC_BUFSIZE 512
|
||||||
|
|
||||||
// Vendor name included in Inquiry response, max 8 bytes
|
|
||||||
#define CFG_TUD_MSC_VENDOR "tinyusb"
|
|
||||||
|
|
||||||
// Product name included in Inquiry response, max 16 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT "tusb msc"
|
|
||||||
|
|
||||||
// Product revision string included in Inquiry response, max 4 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT_REV "1.0"
|
|
||||||
|
|
||||||
//------------- HID -------------//
|
//------------- HID -------------//
|
||||||
|
|
||||||
// Should be sufficient to hold ID (if any) + Data
|
// Should be sufficient to hold ID (if any) + Data
|
||||||
|
@ -3,7 +3,9 @@ import hid
|
|||||||
|
|
||||||
USB_VID = 0xcafe
|
USB_VID = 0xcafe
|
||||||
|
|
||||||
for dict in hid.enumerate(0xcafe):
|
print("Openning HID device with VID = 0x%X" % USB_VID)
|
||||||
|
|
||||||
|
for dict in hid.enumerate(USB_VID):
|
||||||
print(dict)
|
print(dict)
|
||||||
dev = hid.Device(dict['vendor_id'], dict['product_id'])
|
dev = hid.Device(dict['vendor_id'], dict['product_id'])
|
||||||
if dev:
|
if dev:
|
||||||
|
@ -205,20 +205,64 @@ uint8_t msc_disk1[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Invoked to determine max LUN
|
// Invoked to determine max LUN
|
||||||
uint8_t tud_msc_maxlun_cb(void)
|
uint8_t tud_msc_get_maxlun_cb(void)
|
||||||
{
|
{
|
||||||
return 2; // dual LUN
|
return 2; // dual LUN
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback invoked to determine disk's size
|
// Invoked when received SCSI_CMD_INQUIRY
|
||||||
|
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||||
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
||||||
|
{
|
||||||
|
(void) lun; // use same ID for both LUNs
|
||||||
|
|
||||||
|
const char vid[] = "TinyUSB";
|
||||||
|
const char pid[] = "Mass Storage";
|
||||||
|
const char rev[] = "1.0";
|
||||||
|
|
||||||
|
memcpy(vendor_id , vid, strlen(vid));
|
||||||
|
memcpy(product_id , pid, strlen(pid));
|
||||||
|
memcpy(product_rev, rev, strlen(rev));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Test Unit Ready command.
|
||||||
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
|
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
return true; // RAM disk is always ready
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
|
// Application update block count and block size
|
||||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
||||||
{
|
{
|
||||||
(void) lun; // both LUNs have same size
|
(void) lun;
|
||||||
|
|
||||||
*block_count = DISK_BLOCK_NUM;
|
*block_count = DISK_BLOCK_NUM;
|
||||||
*block_size = DISK_BLOCK_SIZE;
|
*block_size = DISK_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoked when received Start Stop Unit command
|
||||||
|
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||||
|
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||||
|
void tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
(void) power_condition;
|
||||||
|
|
||||||
|
if ( load_eject )
|
||||||
|
{
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
// load disk storage
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// unload disk storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Callback invoked when received READ10 command.
|
// Callback invoked when received READ10 command.
|
||||||
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
||||||
@ -259,11 +303,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
|||||||
|
|
||||||
switch (scsi_cmd[0])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_TEST_UNIT_READY:
|
|
||||||
// Command that host uses to check our readiness before sending other commands
|
|
||||||
resplen = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||||
// Host is about to read/write etc ... better not to disconnect disk
|
// Host is about to read/write etc ... better not to disconnect disk
|
||||||
resplen = 0;
|
resplen = 0;
|
||||||
|
@ -81,15 +81,6 @@
|
|||||||
// Buffer size of Device Mass storage
|
// Buffer size of Device Mass storage
|
||||||
#define CFG_TUD_MSC_BUFSIZE 512
|
#define CFG_TUD_MSC_BUFSIZE 512
|
||||||
|
|
||||||
// Vendor name included in Inquiry response, max 8 bytes
|
|
||||||
#define CFG_TUD_MSC_VENDOR "tinyusb"
|
|
||||||
|
|
||||||
// Product name included in Inquiry response, max 16 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT "tusb msc"
|
|
||||||
|
|
||||||
// Product revision string included in Inquiry response, max 4 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT_REV "1.0"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -101,15 +101,6 @@
|
|||||||
// Buffer size of Device Mass storage
|
// Buffer size of Device Mass storage
|
||||||
#define CFG_TUD_MSC_BUFSIZE 512
|
#define CFG_TUD_MSC_BUFSIZE 512
|
||||||
|
|
||||||
// Vendor name included in Inquiry response, max 8 bytes
|
|
||||||
#define CFG_TUD_MSC_VENDOR "tinyusb"
|
|
||||||
|
|
||||||
// Product name included in Inquiry response, max 16 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT "tusb msc"
|
|
||||||
|
|
||||||
// Product revision string included in Inquiry response, max 4 bytes
|
|
||||||
#define CFG_TUD_MSC_PRODUCT_REV "1.0"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// HID
|
// HID
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -159,7 +159,7 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
|
|||||||
case MSC_REQ_GET_MAX_LUN:
|
case MSC_REQ_GET_MAX_LUN:
|
||||||
{
|
{
|
||||||
uint8_t maxlun = 1;
|
uint8_t maxlun = 1;
|
||||||
if (tud_msc_maxlun_cb) maxlun = tud_msc_maxlun_cb();
|
if (tud_msc_get_maxlun_cb) maxlun = tud_msc_get_maxlun_cb();
|
||||||
TU_VERIFY(maxlun);
|
TU_VERIFY(maxlun);
|
||||||
|
|
||||||
// MAX LUN is minus 1 by specs
|
// MAX LUN is minus 1 by specs
|
||||||
@ -186,30 +186,64 @@ bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return length of response (copied to buffer), -1 if it is not an built-in commands
|
// return response's length (copied to buffer). Negative if it is not an built-in command or indicate Failed status (CSW)
|
||||||
int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize)
|
// In case of a failed status, sense key must be set for reason of failure
|
||||||
|
int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize)
|
||||||
{
|
{
|
||||||
(void) bufsize; // TODO refractor later
|
(void) bufsize; // TODO refractor later
|
||||||
int32_t ret;
|
int32_t resplen;
|
||||||
|
|
||||||
switch ( p_cbw->command[0] )
|
switch ( scsi_cmd[0] )
|
||||||
{
|
{
|
||||||
|
case SCSI_CMD_TEST_UNIT_READY:
|
||||||
|
resplen = 0;
|
||||||
|
if ( !tud_msc_test_unit_ready_cb(lun) )
|
||||||
|
{
|
||||||
|
// not ready response with Failed status and sense key = not ready
|
||||||
|
resplen = - 1;
|
||||||
|
|
||||||
|
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable
|
||||||
|
if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_CMD_START_STOP_UNIT:
|
||||||
|
resplen = 0;
|
||||||
|
|
||||||
|
if (tud_msc_start_stop_cb)
|
||||||
|
{
|
||||||
|
scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
|
||||||
|
tud_msc_start_stop_cb(lun, start_stop->power_condition, start_stop->start, start_stop->load_eject);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SCSI_CMD_READ_CAPACITY_10:
|
case SCSI_CMD_READ_CAPACITY_10:
|
||||||
{
|
{
|
||||||
scsi_read_capacity10_resp_t read_capa10;
|
|
||||||
|
|
||||||
uint32_t block_count;
|
uint32_t block_count;
|
||||||
uint32_t block_size;
|
uint32_t block_size;
|
||||||
uint16_t block_size_u16;
|
uint16_t block_size_u16;
|
||||||
|
|
||||||
tud_msc_capacity_cb(p_cbw->lun, &block_count, &block_size_u16);
|
tud_msc_capacity_cb(lun, &block_count, &block_size_u16);
|
||||||
block_size = (uint32_t) block_size_u16;
|
block_size = (uint32_t) block_size_u16;
|
||||||
|
|
||||||
read_capa10.last_lba = ENDIAN_BE(block_count-1);
|
// Invalid block size/count from callback, possibly unit is not ready
|
||||||
read_capa10.block_size = ENDIAN_BE(block_size);
|
// stall this request, set sense key to NOT READY
|
||||||
|
if (block_count == 0 || block_size == 0)
|
||||||
|
{
|
||||||
|
resplen = -1;
|
||||||
|
|
||||||
ret = sizeof(read_capa10);
|
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable
|
||||||
memcpy(buffer, &read_capa10, ret);
|
if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
scsi_read_capacity10_resp_t read_capa10;
|
||||||
|
|
||||||
|
read_capa10.last_lba = ENDIAN_BE(block_count-1);
|
||||||
|
read_capa10.block_size = ENDIAN_BE(block_size);
|
||||||
|
|
||||||
|
resplen = sizeof(read_capa10);
|
||||||
|
memcpy(buffer, &read_capa10, resplen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -226,12 +260,24 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
|
|||||||
uint32_t block_count;
|
uint32_t block_count;
|
||||||
uint16_t block_size;
|
uint16_t block_size;
|
||||||
|
|
||||||
tud_msc_capacity_cb(p_cbw->lun, &block_count, &block_size);
|
tud_msc_capacity_cb(lun, &block_count, &block_size);
|
||||||
read_fmt_capa.block_num = ENDIAN_BE(block_count);
|
|
||||||
read_fmt_capa.block_size_u16 = ENDIAN_BE16(block_size);
|
|
||||||
|
|
||||||
ret = sizeof(read_fmt_capa);
|
// Invalid block size/count from callback, possibly unit is not ready
|
||||||
memcpy(buffer, &read_fmt_capa, ret);
|
// stall this request, set sense key to NOT READY
|
||||||
|
if (block_count == 0 || block_size == 0)
|
||||||
|
{
|
||||||
|
resplen = -1;
|
||||||
|
|
||||||
|
// If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable
|
||||||
|
if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
read_fmt_capa.block_num = ENDIAN_BE(block_count);
|
||||||
|
read_fmt_capa.block_size_u16 = ENDIAN_BE16(block_size);
|
||||||
|
|
||||||
|
resplen = sizeof(read_fmt_capa);
|
||||||
|
memcpy(buffer, &read_fmt_capa, resplen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -242,23 +288,17 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
|
|||||||
.is_removable = 1,
|
.is_removable = 1,
|
||||||
.version = 2,
|
.version = 2,
|
||||||
.response_data_format = 2,
|
.response_data_format = 2,
|
||||||
// vendor_id, product_id, product_rev is space padded string
|
|
||||||
.vendor_id = "",
|
|
||||||
.product_id = "",
|
|
||||||
.product_rev = "",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
memset(inquiry_rsp.vendor_id, ' ', sizeof(inquiry_rsp.vendor_id));
|
// vendor_id, product_id, product_rev is space padded string
|
||||||
memcpy(inquiry_rsp.vendor_id, CFG_TUD_MSC_VENDOR, tu_min32(strlen(CFG_TUD_MSC_VENDOR), sizeof(inquiry_rsp.vendor_id)));
|
memset(inquiry_rsp.vendor_id , ' ', sizeof(inquiry_rsp.vendor_id));
|
||||||
|
memset(inquiry_rsp.product_id , ' ', sizeof(inquiry_rsp.product_id));
|
||||||
memset(inquiry_rsp.product_id, ' ', sizeof(inquiry_rsp.product_id));
|
|
||||||
memcpy(inquiry_rsp.product_id, CFG_TUD_MSC_PRODUCT, tu_min32(strlen(CFG_TUD_MSC_PRODUCT), sizeof(inquiry_rsp.product_id)));
|
|
||||||
|
|
||||||
memset(inquiry_rsp.product_rev, ' ', sizeof(inquiry_rsp.product_rev));
|
memset(inquiry_rsp.product_rev, ' ', sizeof(inquiry_rsp.product_rev));
|
||||||
memcpy(inquiry_rsp.product_rev, CFG_TUD_MSC_PRODUCT_REV, tu_min32(strlen(CFG_TUD_MSC_PRODUCT_REV), sizeof(inquiry_rsp.product_rev)));
|
|
||||||
|
|
||||||
ret = sizeof(inquiry_rsp);
|
tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev);
|
||||||
memcpy(buffer, &inquiry_rsp, ret);
|
|
||||||
|
resplen = sizeof(inquiry_rsp);
|
||||||
|
memcpy(buffer, &inquiry_rsp, resplen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -275,12 +315,12 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
|
|||||||
|
|
||||||
bool writable = true;
|
bool writable = true;
|
||||||
if (tud_msc_is_writable_cb) {
|
if (tud_msc_is_writable_cb) {
|
||||||
writable = tud_msc_is_writable_cb(p_cbw->lun);
|
writable = tud_msc_is_writable_cb(lun);
|
||||||
}
|
}
|
||||||
mode_resp.write_protected = !writable;
|
mode_resp.write_protected = !writable;
|
||||||
|
|
||||||
ret = sizeof(mode_resp);
|
resplen = sizeof(mode_resp);
|
||||||
memcpy(buffer, &mode_resp, ret);
|
memcpy(buffer, &mode_resp, resplen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -298,18 +338,18 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
|
|||||||
sense_rsp.add_sense_code = _mscd_itf.add_sense_code;
|
sense_rsp.add_sense_code = _mscd_itf.add_sense_code;
|
||||||
sense_rsp.add_sense_qualifier = _mscd_itf.add_sense_qualifier;
|
sense_rsp.add_sense_qualifier = _mscd_itf.add_sense_qualifier;
|
||||||
|
|
||||||
ret = sizeof(sense_rsp);
|
resplen = sizeof(sense_rsp);
|
||||||
memcpy(buffer, &sense_rsp, ret);
|
memcpy(buffer, &sense_rsp, resplen);
|
||||||
|
|
||||||
// Clear sense data after copy
|
// Clear sense data after copy
|
||||||
tud_msc_set_sense(p_cbw->lun, 0, 0, 0);
|
tud_msc_set_sense(lun, 0, 0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: ret = -1; break;
|
default: resplen = -1; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return resplen;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
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
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For other SCSI commands
|
// For other SCSI commands
|
||||||
// 1. Zero : Invoke app callback, skip DATA and move to STATUS stage
|
// 1. OUT : queue transfer (invoke app callback after done)
|
||||||
// 2. OUT : queue transfer (invoke app callback after done)
|
// 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length
|
||||||
// 3. IN : invoke app callback to get response
|
if ( (p_cbw->total_bytes > 0 ) && !TU_BIT_TEST(p_cbw->dir, 7) )
|
||||||
if ( p_cbw->total_bytes == 0)
|
|
||||||
{
|
{
|
||||||
int32_t const cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, NULL, 0);
|
// queue transfer
|
||||||
|
|
||||||
p_msc->total_len = 0;
|
|
||||||
p_msc->stage = MSC_STAGE_STATUS;
|
|
||||||
|
|
||||||
if ( cb_result < 0 )
|
|
||||||
{
|
|
||||||
p_csw->status = MSC_CSW_STATUS_FAILED;
|
|
||||||
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_csw->status = MSC_CSW_STATUS_PASSED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( !TU_BIT_TEST(p_cbw->dir, 7) )
|
|
||||||
{
|
|
||||||
// OUT transfer
|
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) );
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) );
|
||||||
}
|
}else
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// IN Transfer
|
int32_t resplen;
|
||||||
int32_t cb_result;
|
|
||||||
|
|
||||||
// first process if it is a built-in commands
|
// First process if it is a built-in commands
|
||||||
cb_result = proc_builtin_scsi(p_cbw, _mscd_buf, sizeof(_mscd_buf));
|
resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf));
|
||||||
|
|
||||||
// Not an built-in command, invoke user callback
|
// Not built-in, invoke user callback
|
||||||
if ( cb_result < 0 )
|
if ( (resplen < 0) && (p_msc->sense_key == 0) )
|
||||||
{
|
{
|
||||||
cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
|
resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( cb_result > 0 )
|
if ( resplen < 0 )
|
||||||
{
|
|
||||||
p_msc->total_len = (uint32_t) cb_result;
|
|
||||||
p_csw->status = MSC_CSW_STATUS_PASSED;
|
|
||||||
|
|
||||||
TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect
|
|
||||||
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
|
|
||||||
}else
|
|
||||||
{
|
{
|
||||||
p_msc->total_len = 0;
|
p_msc->total_len = 0;
|
||||||
p_csw->status = MSC_CSW_STATUS_FAILED;
|
p_csw->status = MSC_CSW_STATUS_FAILED;
|
||||||
p_msc->stage = MSC_STAGE_STATUS;
|
p_msc->stage = MSC_STAGE_STATUS;
|
||||||
|
|
||||||
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation
|
// failed but senskey is not set: default to Illegal Request
|
||||||
usbd_edpt_stall(rhport, p_msc->ep_in);
|
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
|
||||||
|
/// Stall bulk In if needed
|
||||||
|
if (p_cbw->total_bytes) usbd_edpt_stall(rhport, p_msc->ep_in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p_msc->total_len = (uint32_t) resplen;
|
||||||
|
p_csw->status = MSC_CSW_STATUS_PASSED;
|
||||||
|
|
||||||
|
if (p_msc->total_len)
|
||||||
|
{
|
||||||
|
TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect
|
||||||
|
TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
p_msc->stage = MSC_STAGE_STATUS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,18 +44,6 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
|
|||||||
#error CFG_TUD_MSC_BUFSIZE must be defined, value of a block size should work well, the more the better
|
#error CFG_TUD_MSC_BUFSIZE must be defined, value of a block size should work well, the more the better
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CFG_TUD_MSC_VENDOR
|
|
||||||
#error CFG_TUD_MSC_VENDOR 8-byte name must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CFG_TUD_MSC_PRODUCT
|
|
||||||
#error CFG_TUD_MSC_PRODUCT 16-byte name must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CFG_TUD_MSC_PRODUCT_REV
|
|
||||||
#error CFG_TUD_MSC_PRODUCT_REV 4-byte string must be defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \addtogroup ClassDriver_MSC
|
/** \addtogroup ClassDriver_MSC
|
||||||
* @{
|
* @{
|
||||||
* \defgroup MSC_Device Device
|
* \defgroup MSC_Device Device
|
||||||
@ -105,12 +93,23 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf
|
|||||||
*/
|
*/
|
||||||
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_INQUIRY
|
||||||
|
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||||
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
|
||||||
|
|
||||||
|
// Invoked when received Test Unit Ready command.
|
||||||
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
|
bool tud_msc_test_unit_ready_cb(uint8_t lun);
|
||||||
|
|
||||||
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
// Application update block count and block size
|
// Application update block count and block size
|
||||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback invoked when received an SCSI command not in built-in list below.
|
* Invoked when received an SCSI command not in built-in list below.
|
||||||
|
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
|
||||||
|
* - READ10 and WRITE10 has their own callbacks
|
||||||
|
*
|
||||||
* \param[in] lun Logical unit number
|
* \param[in] lun Logical unit number
|
||||||
* \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
|
* \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
|
||||||
* \param[out] buffer Buffer for SCSI Data Stage.
|
* \param[out] buffer Buffer for SCSI Data Stage.
|
||||||
@ -121,17 +120,18 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz
|
|||||||
* \return Actual bytes processed, can be zero for no-data command.
|
* \return Actual bytes processed, can be zero for no-data command.
|
||||||
* \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
|
* \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
|
||||||
* endpoint and return failed status in command status wrapper phase.
|
* endpoint and return failed status in command status wrapper phase.
|
||||||
*
|
|
||||||
* \note Following command is automatically handled by tinyusb stack, callback should not be worried:
|
|
||||||
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
|
||||||
* - READ10 and WRITE10 has their own callbacks
|
|
||||||
*/
|
*/
|
||||||
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
|
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
|
||||||
|
|
||||||
/*------------- Optional callbacks -------------*/
|
/*------------- Optional callbacks -------------*/
|
||||||
|
|
||||||
// Invoked when received GET_MAX_LUN request
|
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
|
||||||
ATTR_WEAK uint8_t tud_msc_maxlun_cb(void);
|
ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
|
||||||
|
|
||||||
|
// Invoked when received Start Stop Unit command
|
||||||
|
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||||
|
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||||
|
ATTR_WEAK void tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
|
||||||
|
|
||||||
// Invoked when Read10 command is complete
|
// Invoked when Read10 command is complete
|
||||||
ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
|
ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
|
||||||
|
@ -107,7 +107,7 @@ void dcd_remote_wakeup(uint8_t rhport);
|
|||||||
* must be called to notify the stack
|
* must be called to notify the stack
|
||||||
* - busy : Check if endpoint transferring is complete (TODO remove)
|
* - busy : Check if endpoint transferring is complete (TODO remove)
|
||||||
* - stall : stall endpoint
|
* - stall : stall endpoint
|
||||||
* - clear_stall : clear stall
|
* - clear_stall : clear stall, data toggle is also reset to DATA0
|
||||||
*------------------------------------------------------------------*/
|
*------------------------------------------------------------------*/
|
||||||
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
|
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
|
||||||
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
|
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
|
||||||
|
@ -456,7 +456,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
|||||||
case TUSB_REQ_CLEAR_FEATURE:
|
case TUSB_REQ_CLEAR_FEATURE:
|
||||||
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
|
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
|
||||||
{
|
{
|
||||||
dcd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
|
usbd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
|
||||||
}
|
}
|
||||||
usbd_control_status(rhport, p_request);
|
usbd_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
@ -223,9 +223,9 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
|||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1 | USB_DEVICE_EPSTATUSCLR_DTGLIN;
|
||||||
} else {
|
} else {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0 | USB_DEVICE_EPSTATUSCLR_DTGLOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,9 +227,9 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
|||||||
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
UsbDeviceEndpoint* ep = &USB->DEVICE.DeviceEndpoint[epnum];
|
||||||
|
|
||||||
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1 | USB_DEVICE_EPSTATUSCLR_DTGLIN;
|
||||||
} else {
|
} else {
|
||||||
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
|
ep->EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0 | USB_DEVICE_EPSTATUSCLR_DTGLOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +322,12 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
|||||||
|
|
||||||
if ( tu_edpt_number(ep_addr) )
|
if ( tu_edpt_number(ep_addr) )
|
||||||
{
|
{
|
||||||
|
// clear stall
|
||||||
NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr;
|
NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep_addr;
|
||||||
|
|
||||||
|
// reset data toggle to DATA0
|
||||||
|
NRF_USBD->DTOGGLE = (USBD_DTOGGLE_VALUE_Data0 << USBD_DTOGGLE_VALUE_Pos) | ep_addr;
|
||||||
|
|
||||||
__ISB(); __DSB();
|
__ISB(); __DSB();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,6 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef CFG_TUSB_DEBUG
|
#ifndef CFG_TUSB_DEBUG
|
||||||
#define CFG_TUSB_DEBUG 0
|
#define CFG_TUSB_DEBUG 0
|
||||||
#warning CFG_TUSB_DEBUG is not defined, default value is 0
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// place data in accessible RAM for usb controller
|
// place data in accessible RAM for usb controller
|
||||||
@ -165,6 +164,14 @@
|
|||||||
#define CFG_TUD_MSC 0
|
#define CFG_TUD_MSC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_MIDI
|
||||||
|
#define CFG_TUD_MIDI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_CUSTOM_CLASS
|
||||||
|
#define CFG_TUD_CUSTOM_CLASS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // TUSB_OPT_DEVICE_ENABLED
|
#endif // TUSB_OPT_DEVICE_ENABLED
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
@ -6,7 +6,6 @@ import time
|
|||||||
|
|
||||||
travis = False
|
travis = False
|
||||||
if "TRAVIS" in os.environ and os.environ["TRAVIS"] == "true":
|
if "TRAVIS" in os.environ and os.environ["TRAVIS"] == "true":
|
||||||
PARALLEL="-j 2"
|
|
||||||
travis = True
|
travis = True
|
||||||
|
|
||||||
success_count = 0
|
success_count = 0
|
||||||
@ -47,10 +46,10 @@ for example in all_device_example:
|
|||||||
# FreeRTOS example
|
# FreeRTOS example
|
||||||
#example = 'cdc_msc_hid_freertos'
|
#example = 'cdc_msc_hid_freertos'
|
||||||
#board = 'pca10056'
|
#board = 'pca10056'
|
||||||
#subprocess.run("make -j2 -C examples/device/{} BOARD={} clean all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
#build_example(example, board)
|
||||||
|
|
||||||
|
|
||||||
total_time = time.monotonic() - total_time
|
total_time = time.monotonic() - total_time
|
||||||
|
|
||||||
print("Total build time took {:.2f}s".format(total_time))
|
print("Total build time took {:.2f}s".format(total_time))
|
||||||
|
|
||||||
sys.exit(exit_status)
|
sys.exit(exit_status)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user