From 8f70a6a886aa557dd87086b807367eef662a7e77 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Nov 2013 13:15:40 +0700 Subject: [PATCH] change endian conversion to native to be & be to native completely deferred xfer isr event to usbd task complete read10, write10 sequence for large data transfer --- demos/device/device_os_none/mscd_app.c | 17 +- demos/device/device_os_none/mscd_app.h | 5 + .../device/device_os_none/mscd_app_ramdisk.c | 10 +- .../device/device_os_none/mscd_app_romdisk.c | 16 +- tinyusb/class/msc_device.c | 157 ++++++++++-------- tinyusb/class/msc_device.h | 4 +- tinyusb/class/msc_host.c | 8 +- tinyusb/common/common.h | 10 +- tinyusb/common/compiler/compiler_gcc.h | 6 +- tinyusb/common/compiler/compiler_iar.h | 4 +- tinyusb/device/usbd.c | 71 +++++--- tinyusb/device/usbd.h | 2 +- tinyusb/hal/hal.h | 4 +- tinyusb/osal/osal_none.h | 2 +- 14 files changed, 183 insertions(+), 133 deletions(-) diff --git a/demos/device/device_os_none/mscd_app.c b/demos/device/device_os_none/mscd_app.c index b30f9a5b1..dc934e4ae 100644 --- a/demos/device/device_os_none/mscd_app.c +++ b/demos/device/device_os_none/mscd_app.c @@ -60,8 +60,8 @@ static scsi_inquiry_data_t mscd_inquiry_data TUSB_CFG_ATTR_USBRAM = ATTR_USB_MIN_ALIGNMENT static scsi_read_capacity10_data_t mscd_read_capacity10_data TUSB_CFG_ATTR_USBRAM = { - .last_lba = __le2be(DISK_BLOCK_NUM-1), // read capacity - .block_size = __le2be(DISK_BLOCK_SIZE) + .last_lba = __n2be(DISK_BLOCK_NUM-1), // read capacity + .block_size = __n2be(DISK_BLOCK_SIZE) }; ATTR_USB_MIN_ALIGNMENT @@ -76,9 +76,9 @@ ATTR_USB_MIN_ALIGNMENT static scsi_read_format_capacity_data_t mscd_format_capacity_data TUSB_CFG_ATTR_USBRAM = { .list_length = 8, - .block_num = __le2be(DISK_BLOCK_NUM), // write capacity + .block_num = __n2be(DISK_BLOCK_NUM), // write capacity .descriptor_type = 2, // TODO formatted media, refractor to const - .block_size_u16 = __h2be_16(DISK_BLOCK_SIZE) + .block_size_u16 = __n2be_16(DISK_BLOCK_SIZE) }; ATTR_USB_MIN_ALIGNMENT @@ -99,6 +99,7 @@ static scsi_mode_parameters_t msc_dev_mode_para TUSB_CFG_ATTR_USBRAM = //--------------------------------------------------------------------+ msc_csw_status_t tusbd_msc_scsi_received_isr (uint8_t coreid, uint8_t lun, uint8_t scsi_cmd[16], void ** pp_buffer, uint16_t* p_length) { + // read10 & write10 has their own callback and MUST not be handled here switch (scsi_cmd[0]) { case SCSI_CMD_INQUIRY: @@ -136,14 +137,6 @@ msc_csw_status_t tusbd_msc_scsi_received_isr (uint8_t coreid, uint8_t lun, uint8 (*p_length) = 0; break; - case SCSI_CMD_READ_10: - (*p_length) = read10(coreid, lun, (scsi_read10_t*) scsi_cmd, pp_buffer); - break; - - case SCSI_CMD_WRITE_10: - (*p_length) = write10(coreid, lun, (scsi_read10_t*) scsi_cmd, pp_buffer); - break; - default: return MSC_CSW_STATUS_FAILED; } diff --git a/demos/device/device_os_none/mscd_app.h b/demos/device/device_os_none/mscd_app.h index 722cfbe99..cf57db75a 100644 --- a/demos/device/device_os_none/mscd_app.h +++ b/demos/device/device_os_none/mscd_app.h @@ -61,6 +61,11 @@ enum DISK_BLOCK_SIZE = 512 }; +#define README_CONTENTS \ +"This is tinyusb's MassStorage Class demo.\r\n\r\n\ +If you find any bugs or get any questions, feel free to file an\r\n\ +issue at github.com/hathach/tinyusb" + #if TUSB_CFG_MCU==MCU_LPC11UXX || TUSB_CFG_MCU==MCU_LPC13UXX #define MSCD_APP_ROMDISK #else // defaults is ram disk diff --git a/demos/device/device_os_none/mscd_app_ramdisk.c b/demos/device/device_os_none/mscd_app_ramdisk.c index 5e97669da..955829b84 100644 --- a/demos/device/device_os_none/mscd_app_ramdisk.c +++ b/demos/device/device_os_none/mscd_app_ramdisk.c @@ -43,10 +43,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define README_CONTENTS \ -"This is tinyusb's MassStorage Class demo.\r\n\r\n\ -If you find any bugs or get any questions, feel free to file an\r\n\ -issue at github.com/hathach/tinyusb" //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -64,10 +60,10 @@ uint8_t mscd_app_ramdisk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] TUSB_CFG_ATTR_USBRAM = [510] = 0x55, [511] = 0xAA // FAT magic code }, - //------------- FAT12 Table (first 2 entries are F8FF, third entry is cluster end of readme file-------------// + //------------- FAT12 Table -------------// [1] = { - 0xF8, 0xFF, 0xFF, 0xFF, 0x0F + 0xF8, 0xFF, 0xFF, 0xFF, 0x0F // // first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Root Directory -------------// @@ -95,7 +91,7 @@ uint16_t tusbd_msc_read10_cb (uint8_t coreid, uint8_t lun, void** pp_buffer, uin return min16_of(block_count, DISK_BLOCK_NUM); } -uint16_t tusbh_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) +uint16_t tusbd_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) { (*pp_buffer) = mscd_app_ramdisk[lba]; diff --git a/demos/device/device_os_none/mscd_app_romdisk.c b/demos/device/device_os_none/mscd_app_romdisk.c index 16118df2b..9f7723b6a 100644 --- a/demos/device/device_os_none/mscd_app_romdisk.c +++ b/demos/device/device_os_none/mscd_app_romdisk.c @@ -47,10 +47,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define README_CONTENTS \ -"This is tinyusb's MassStorage Class demo.\r\n\r\n\ -If you find any bugs or get any questions, feel free to file an\r\n\ -issue at github.com/hathach/tinyusb" //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -67,10 +63,10 @@ const uint8_t mscd_app_rommdisk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = [510] = 0x55, [511] = 0xAA // FAT magic code }, - //------------- FAT12 Table (first 2 entries are F8FF, third entry is cluster end of readme file-------------// + //------------- FAT12 Table -------------// [1] = { - 0xF8, 0xFF, 0xFF, 0xFF, 0x0F + 0xF8, 0xFF, 0xFF, 0xFF, 0x0F // first 2 entries must be F8FF, third entry is cluster end of readme file }, //------------- Root Directory -------------// @@ -90,21 +86,21 @@ const uint8_t mscd_app_rommdisk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = }; ATTR_USB_MIN_ALIGNMENT -static uint8_t ramdisk_buffer[DISK_BLOCK_SIZE] TUSB_CFG_ATTR_USBRAM; +static uint8_t sector_buffer[DISK_BLOCK_SIZE] TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ uint16_t tusbd_msc_read10_cb (uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) { - memcpy(ramdisk_buffer, mscd_app_rommdisk[lba], DISK_BLOCK_SIZE); - (*pp_buffer) = ramdisk_buffer; + memcpy(sector_buffer, mscd_app_rommdisk[lba], DISK_BLOCK_SIZE); + (*pp_buffer) = sector_buffer; return 1; } // Stall write10 as this is readonly disk -uint16_t tusbh_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) +uint16_t tusbd_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) { (*pp_buffer) = NULL; return 0; diff --git a/tinyusb/class/msc_device.c b/tinyusb/class/msc_device.c index 94545d802..7c334491d 100644 --- a/tinyusb/class/msc_device.c +++ b/tinyusb/class/msc_device.c @@ -136,91 +136,118 @@ tusb_error_t mscd_control_request(uint8_t coreid, tusb_control_request_t const * return TUSB_ERROR_NONE; } -void mscd_isr(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32_t xferred_bytes) +// return true if data phase is complete, false if not yet complete +static bool read10_write10_data_xfer(mscd_interface_t* p_msc) +{ + msc_cmd_block_wrapper_t * const p_cbw = &p_msc->cbw; + msc_cmd_status_wrapper_t * const p_csw = &p_msc->csw; + + scsi_read10_t* p_readwrite = (scsi_read10_t*) &p_cbw->command; // read10 & write10 has the same format + + endpoint_handle_t const edpt_hdl = BIT_TEST_(p_cbw->dir, 7) ? p_msc->edpt_in : p_msc->edpt_out; + + uint32_t const lba = __be2n(p_readwrite->lba); + uint16_t const block_count = __be2n_16(p_readwrite->block_count); + void *p_buffer = NULL; + + uint16_t xferred_block = (SCSI_CMD_READ_10 == p_cbw->command[0]) ? tusbd_msc_read10_cb (edpt_hdl.coreid, p_cbw->lun, &p_buffer, lba, block_count) : + tusbd_msc_write10_cb(edpt_hdl.coreid, p_cbw->lun, &p_buffer, lba, block_count); + xferred_block = min16_of(xferred_block, block_count); + + uint16_t xferred_byte = xferred_block * (p_cbw->xfer_bytes / block_count); + + if ( 0 == xferred_block ) + { // xferred_block is zero will cause pipe is stalled & status in CSW set to failed + p_csw->data_residue = __n2be(p_cbw->xfer_bytes); + p_csw->status = MSC_CSW_STATUS_FAILED; + + (void) dcd_pipe_stall(edpt_hdl); + + return true; + } else if (xferred_block < block_count) + { + ASSERT_STATUS( dcd_pipe_xfer( edpt_hdl, p_buffer, xferred_byte, true) ); + + // adjust lba, block_count, xfer_bytes for the next call + p_readwrite->lba = __n2be(lba+xferred_block); + p_readwrite->block_count = __n2be_16(block_count - xferred_block); + p_cbw->xfer_bytes -= xferred_byte; + + return false; + }else + { + p_csw->status = MSC_CSW_STATUS_PASSED; + ASSERT_STATUS( dcd_pipe_queue_xfer( edpt_hdl, p_buffer, xferred_byte) ); + return true; + } +} + +tusb_error_t mscd_xfer_cb(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32_t xferred_bytes) { // TODO failed --> STALL pipe, on clear STALL --> queue endpoint OUT + static bool is_waiting_read10_write10 = false; // indicate we are transferring data in READ10, WRITE10 command + mscd_interface_t * const p_msc = &mscd_data; msc_cmd_block_wrapper_t * const p_cbw = &p_msc->cbw; msc_cmd_status_wrapper_t * const p_csw = &p_msc->csw; - if ( endpointhandle_is_equal(p_msc->edpt_in, edpt_hdl) ) - { - return; // currently no need to handle bulk in - } + if ( !is_waiting_read10_write10) + { // new CBW received + if ( endpointhandle_is_equal(p_msc->edpt_in, edpt_hdl) ) return TUSB_ERROR_NONE; // bulk in interrupt for dcd to clean up - ASSERT( endpointhandle_is_equal(p_msc->edpt_out, edpt_hdl) && - xferred_bytes == sizeof(msc_cmd_block_wrapper_t) && - event == TUSB_EVENT_XFER_COMPLETE && - p_cbw->signature == MSC_CBW_SIGNATURE, VOID_RETURN ); + ASSERT( endpointhandle_is_equal(p_msc->edpt_out, edpt_hdl) && + xferred_bytes == sizeof(msc_cmd_block_wrapper_t) && + event == TUSB_EVENT_XFER_COMPLETE && + p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA ); - void *p_buffer = NULL; - uint16_t actual_length = p_cbw->xfer_bytes; - - p_csw->signature = MSC_CSW_SIGNATURE; - p_csw->tag = p_cbw->tag; - p_csw->data_residue = 0; - - switch(p_cbw->command[0]) - { - case SCSI_CMD_READ_10: - case SCSI_CMD_WRITE_10: + if ( (SCSI_CMD_READ_10 != p_cbw->command[0]) && (SCSI_CMD_WRITE_10 != p_cbw->command[0]) ) { - scsi_read10_t const * const p_read10 = &p_cbw->command; // read10 & write10 has the same data structure - uint32_t const lba = __be2le(p_read10->lba); - uint16_t const block_count = __be2h_16(p_read10->block_count); + void *p_buffer = NULL; + uint16_t actual_length = p_cbw->xfer_bytes; - uint16_t actual_block_count; - - if (SCSI_CMD_READ_10 == p_cbw->command[0]) - { - actual_block_count = tusbd_msc_read10_cb (edpt_hdl.coreid, p_cbw->lun, &p_buffer, lba, block_count); - }else - { - actual_block_count = tusbh_msc_write10_cb(edpt_hdl.coreid, p_cbw->lun, &p_buffer, lba, block_count); - } - - ASSERT( actual_block_count <= block_count, VOID_RETURN); - - if ( actual_block_count < block_count ) - { - uint32_t const block_size = p_cbw->xfer_bytes / block_count; - actual_length = block_size * actual_block_count; - p_csw->data_residue = p_cbw->xfer_bytes - actual_length; - p_csw->status = MSC_CSW_STATUS_FAILED; - }else - { - p_csw->status = MSC_CSW_STATUS_PASSED; - } - } - break; - - default: p_csw->status = tusbd_msc_scsi_received_isr(edpt_hdl.coreid, p_cbw->lun, p_cbw->command, &p_buffer, &actual_length); - break; + + //------------- Data Phase -------------// + if ( p_cbw->xfer_bytes ) + { + ASSERT( p_cbw->xfer_bytes >= actual_length, TUSB_ERROR_INVALID_PARA ); + if ( p_buffer == NULL || actual_length == 0 ) + { // application does not provide data to response --> possibly unsupported SCSI command + ASSERT_STATUS( dcd_pipe_stall(p_msc->edpt_in) ); + p_csw->status = MSC_CSW_STATUS_FAILED; + }else + { + ASSERT_STATUS( dcd_pipe_queue_xfer( BIT_TEST_(p_cbw->dir, 7) ? p_msc->edpt_in : p_msc->edpt_out, + p_buffer, actual_length) ); + } + } + } } - ASSERT( p_cbw->xfer_bytes >= actual_length, VOID_RETURN ); - - //------------- Data Phase -------------// - if ( p_cbw->xfer_bytes ) + //------------- Data Phase For READ10 & WRITE10 (can be executed several times) -------------// + if ( (SCSI_CMD_READ_10 == p_cbw->command[0]) || (SCSI_CMD_WRITE_10 == p_cbw->command[0]) ) { - if ( p_buffer == NULL || actual_length == 0 ) - { // application does not provide data to response --> possibly unsupported SCSI command - ASSERT( TUSB_ERROR_NONE == dcd_pipe_stall(p_msc->edpt_in), VOID_RETURN ); - p_csw->status = MSC_CSW_STATUS_FAILED; - }else - { - ASSERT( dcd_pipe_queue_xfer( BIT_TEST_(p_cbw->dir, 7) ? p_msc->edpt_in : p_msc->edpt_out, - p_buffer, actual_length) == TUSB_ERROR_NONE, VOID_RETURN); + if (is_waiting_read10_write10) + { // continue with read10, write10 data transfer, interrupt must come from endpoint IN + ASSERT( endpointhandle_is_equal(p_msc->edpt_in, edpt_hdl) && event == TUSB_EVENT_XFER_COMPLETE, TUSB_ERROR_INVALID_PARA); } + is_waiting_read10_write10 = !read10_write10_data_xfer(p_msc); } //------------- Status Phase -------------// - ASSERT( dcd_pipe_xfer( p_msc->edpt_in , p_csw, sizeof(msc_cmd_status_wrapper_t), true) == TUSB_ERROR_NONE, VOID_RETURN ); // need to be true for dcd to clean up qtd !! + if (!is_waiting_read10_write10) + { + p_csw->signature = MSC_CSW_SIGNATURE; + p_csw->tag = p_cbw->tag; + p_csw->data_residue = 0; - //------------- Queue the next CBW -------------// - ASSERT( dcd_pipe_xfer( p_msc->edpt_out, p_cbw, sizeof(msc_cmd_block_wrapper_t), true) == TUSB_ERROR_NONE, VOID_RETURN ); + ASSERT_STATUS( dcd_pipe_xfer( p_msc->edpt_in , p_csw, sizeof(msc_cmd_status_wrapper_t), true) ); // need to be true for dcd to clean up qtd !! + //------------- Queue the next CBW -------------// + ASSERT_STATUS( dcd_pipe_xfer( p_msc->edpt_out, p_cbw, sizeof(msc_cmd_block_wrapper_t), true) ); + } + + return TUSB_ERROR_NONE; } #endif diff --git a/tinyusb/class/msc_device.h b/tinyusb/class/msc_device.h index 53ba5a280..9c2a5dd67 100644 --- a/tinyusb/class/msc_device.h +++ b/tinyusb/class/msc_device.h @@ -67,7 +67,7 @@ void tusbd_msc_unmounted_cb(uint8_t coreid); msc_csw_status_t tusbd_msc_scsi_received_isr (uint8_t coreid, uint8_t lun, uint8_t scsi_cmd[16], void ** pp_buffer, uint16_t* p_length); uint16_t tusbd_msc_read10_cb (uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; -uint16_t tusbh_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; +uint16_t tusbd_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; /** @} */ /** @} */ @@ -80,7 +80,7 @@ uint16_t tusbh_msc_write10_cb(uint8_t coreid, uint8_t lun, void** pp_buffer, uin void mscd_init(void); tusb_error_t mscd_open(uint8_t coreid, tusb_descriptor_interface_t const * p_interface_desc, uint16_t *p_length); tusb_error_t mscd_control_request(uint8_t coreid, tusb_control_request_t const * p_request); -void mscd_isr(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32_t xferred_bytes); +tusb_error_t mscd_xfer_cb(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32_t xferred_bytes); void mscd_close(uint8_t coreid); #endif diff --git a/tinyusb/class/msc_host.c b/tinyusb/class/msc_host.c index 75f6fec88..bd8b449b7 100644 --- a/tinyusb/class/msc_host.c +++ b/tinyusb/class/msc_host.c @@ -255,7 +255,7 @@ tusb_error_t tusbh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, u scsi_read10_t cmd_read10 = { .cmd_code = SCSI_CMD_READ_10, - .lba = __le2be(lba), + .lba = __n2be(lba), .block_count = u16_le2be(block_count) }; @@ -281,7 +281,7 @@ tusb_error_t tusbh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buf scsi_write10_t cmd_write10 = { .cmd_code = SCSI_CMD_WRITE_10, - .lba = __le2be(lba), + .lba = __n2be(lba), .block_count = u16_le2be(block_count) }; @@ -394,8 +394,8 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con SUBTASK_ASSERT_STATUS(error); } - msch_data[dev_addr-1].last_lba = __be2le( ((scsi_read_capacity10_data_t*)msch_buffer)->last_lba ); - msch_data[dev_addr-1].block_size = (uint16_t) __be2le( ((scsi_read_capacity10_data_t*)msch_buffer)->block_size ); + msch_data[dev_addr-1].last_lba = __be2n( ((scsi_read_capacity10_data_t*)msch_buffer)->last_lba ); + msch_data[dev_addr-1].block_size = (uint16_t) __be2n( ((scsi_read_capacity10_data_t*)msch_buffer)->block_size ); msch_data[dev_addr-1].is_initialized = true; tusbh_msc_mounted_cb(dev_addr); diff --git a/tinyusb/common/common.h b/tinyusb/common/common.h index 4ea40b0e2..bf0955924 100644 --- a/tinyusb/common/common.h +++ b/tinyusb/common/common.h @@ -107,8 +107,8 @@ #define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32) #define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32) -#define __h2be_16(u16) ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) ) // TODO refractor later -#define __be2h_16(u16) __h2be_16(u16) +#define __n2be_16(u16) ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) ) // TODO refractor later +#define __be2n_16(u16) __n2be_16(u16) //--------------------------------------------------------------------+ // INLINE FUNCTION @@ -180,6 +180,12 @@ static inline uint32_t max32_of(uint32_t x, uint32_t y) return (x > y) ? x : y; } +static inline uint16_t max16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST; +static inline uint16_t max16_of(uint16_t x, uint16_t y) +{ + return (x > y) ? x : y; +} + //------------- Align -------------// static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST; static inline uint32_t align32 (uint32_t value) diff --git a/tinyusb/common/compiler/compiler_gcc.h b/tinyusb/common/compiler/compiler_gcc.h index 8f759ec9a..f300661a5 100644 --- a/tinyusb/common/compiler/compiler_gcc.h +++ b/tinyusb/common/compiler/compiler_gcc.h @@ -130,9 +130,9 @@ * @{ */ -// built-in function to convert 32-bit Big-Endian to Little-Endian -#define __be2le __builtin_bswap32 -#define __le2be __be2le +// built-in function to convert 32-bit from native to Big Endian +#define __be2n __builtin_bswap32 +#define __n2be __be2n //#define __le2be_16 __builtin_bswap16 diff --git a/tinyusb/common/compiler/compiler_iar.h b/tinyusb/common/compiler/compiler_iar.h index c611d0b2a..2d079b85f 100644 --- a/tinyusb/common/compiler/compiler_iar.h +++ b/tinyusb/common/compiler/compiler_iar.h @@ -82,8 +82,8 @@ #define ATTR_UNUSED // built-in function to convert 32-bit Big-Endian to Little-Endian -#define __be2le __REV -#define __le2be __be2le +#define __be2n __REV +#define __n2be __be2n #ifdef __cplusplus } diff --git a/tinyusb/device/usbd.c b/tinyusb/device/usbd.c index 2ca0e01ce..90a7247e6 100644 --- a/tinyusb/device/usbd.c +++ b/tinyusb/device/usbd.c @@ -70,7 +70,7 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR .init = hidd_init, .open = hidd_open, .control_request = hidd_control_request, - .isr = hidd_isr, + .xfer_cb = hidd_isr, .close = hidd_close }, #endif @@ -81,7 +81,7 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR .init = mscd_init, .open = mscd_open, .control_request = mscd_control_request, - .isr = mscd_isr, + .xfer_cb = mscd_xfer_cb, .close = mscd_close }, #endif @@ -92,7 +92,7 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR .init = cdcd_init, .open = cdcd_open, .control_request = cdcd_control_request, - .isr = cdcd_isr, + .xfer_cb = cdcd_isr, .close = cdcd_close }, #endif @@ -123,16 +123,29 @@ enum { }; typedef enum { - USBD_EVENTID_SETUP_RECEIVED = 1 + USBD_EVENTID_SETUP_RECEIVED = 1, + USBD_EVENTID_XFER_DONE }usbd_eventid_t; -typedef struct ATTR_ALIGNED(2) +typedef struct ATTR_ALIGNED(4) { uint8_t coreid; uint8_t event_id; - uint8_t data[ MAX_OF(sizeof(tusb_control_request_t), sizeof(endpoint_handle_t)) ]; // hold control request or endpoint handle + uint8_t sub_event_id; + uint8_t reserved; + + union { + tusb_control_request_t setup_received; // USBD_EVENTID_SETUP_RECEIVED + + struct { // USBD_EVENTID_XFER_DONE + endpoint_handle_t edpt_hdl; + uint32_t xferred_byte; + }xfer_done; + }; }usbd_task_event_t; +STATIC_ASSERT(sizeof(usbd_task_event_t) <= 12, "size is not correct"); + OSAL_TASK_DEF(usbd_task, 150, TUSB_CFG_OS_TASK_PRIO); OSAL_QUEUE_DEF(usbd_queue_def, USBD_TASK_QUEUE_DEPTH, usbd_task_event_t); OSAL_SEM_DEF(usbd_control_xfer_semaphore_def); @@ -190,6 +203,7 @@ tusb_error_t usbd_control_request_subtask(uint8_t coreid, tusb_control_request_t error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; } } + //------------- Class/Interface Specific Request -------------// else if ( TUSB_REQUEST_RECIPIENT_INTERFACE == p_request->bmRequestType_bit.recipient) { @@ -204,6 +218,7 @@ tusb_error_t usbd_control_request_subtask(uint8_t coreid, tusb_control_request_t error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; } } + //------------- Endpoint Request -------------// else if ( TUSB_REQUEST_RECIPIENT_ENDPOINT == p_request->bmRequestType_bit.recipient && TUSB_REQUEST_TYPE_STANDARD == p_request->bmRequestType_bit.type && @@ -242,12 +257,20 @@ OSAL_TASK_FUNCTION(usbd_task) (void* p_task_para) if ( USBD_EVENTID_SETUP_RECEIVED == event.event_id ) { - OSAL_SUBTASK_INVOKED_AND_WAIT( usbd_control_request_subtask(event.coreid, (tusb_control_request_t*) event.data), error ); + OSAL_SUBTASK_INVOKED_AND_WAIT( usbd_control_request_subtask(event.coreid, &event.setup_received), error ); }else { + uint8_t class_index; + class_index = std_class_code_to_index( event.xfer_done.edpt_hdl.class_code ); + if (usbd_class_drivers[class_index].xfer_cb) + { + usbd_class_drivers[class_index].xfer_cb( event.xfer_done.edpt_hdl, event.sub_event_id, event.xfer_done.xferred_byte); + }else + { + hal_debugger_breakpoint(); // something wrong, no one claims the isr's source + } } - //else {} OSAL_TASK_LOOP_END } @@ -381,36 +404,38 @@ void usbd_dcd_bus_event_isr(uint8_t coreid, usbd_bus_event_type_t bus_event) void usbd_setup_received_isr(uint8_t coreid, tusb_control_request_t * p_request) { - usbd_task_event_t event = + usbd_task_event_t task_event = { - .coreid = coreid, - .event_id = USBD_EVENTID_SETUP_RECEIVED + .coreid = coreid, + .event_id = USBD_EVENTID_SETUP_RECEIVED, }; - memcpy(event.data, p_request, sizeof(tusb_control_request_t)); - - osal_queue_send(usbd_queue_hdl, &event); + task_event.setup_received = (*p_request); + osal_queue_send(usbd_queue_hdl, &task_event); } void usbd_xfer_isr(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32_t xferred_bytes) { -// usbd_device_info_t *p_device = &usbd_devices[edpt_hdl.coreid]; - uint8_t class_index = std_class_code_to_index(edpt_hdl.class_code); - - if (class_index == 0 ) // Control Transfer + if (edpt_hdl.class_code == 0 ) // Control Transfer { if (usbd_devices[edpt_hdl.coreid].is_waiting_control_xfer) { osal_semaphore_post( usbd_control_xfer_sem_hdl ); } - }else if (usbd_class_drivers[class_index].isr) - { - usbd_class_drivers[class_index].isr(edpt_hdl, event, xferred_bytes); }else { - ASSERT(false, VOID_RETURN); // something wrong, no one claims the isr's source - } + usbd_task_event_t task_event = + { + .coreid = edpt_hdl.coreid, + .event_id = USBD_EVENTID_XFER_DONE, + .sub_event_id = event + }; + task_event.xfer_done.xferred_byte = xferred_bytes; + task_event.xfer_done.edpt_hdl = edpt_hdl; + + osal_queue_send(usbd_queue_hdl, &task_event); + } } //--------------------------------------------------------------------+ diff --git a/tinyusb/device/usbd.h b/tinyusb/device/usbd.h index d1e71c0dd..12b329aa8 100644 --- a/tinyusb/device/usbd.h +++ b/tinyusb/device/usbd.h @@ -71,7 +71,7 @@ typedef struct { void (* const init) (void); tusb_error_t (* const open)(uint8_t, tusb_descriptor_interface_t const *, uint16_t*); tusb_error_t (* const control_request) (uint8_t, tusb_control_request_t const *); - void (* const isr) (endpoint_handle_t, tusb_event_t, uint32_t); + tusb_error_t (* const xfer_cb) (endpoint_handle_t, tusb_event_t, uint32_t); void (* const close) (uint8_t); } usbd_class_driver_t; diff --git a/tinyusb/hal/hal.h b/tinyusb/hal/hal.h index b26804efc..65c3776b1 100644 --- a/tinyusb/hal/hal.h +++ b/tinyusb/hal/hal.h @@ -109,8 +109,10 @@ static inline bool hal_debugger_is_attached(void) // TODO check core M3/M4 defined instead #if !defined(_TEST_) && !(TUSB_CFG_MCU==MCU_LPC11UXX) return ( (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == CoreDebug_DHCSR_C_DEBUGEN_Msk ); +#elif TUSB_CFG_DEBUG == 3 + return true; // force to break into breakpoint with debug = 3 #else - return true; // force to break into breakpoint + return false #endif } diff --git a/tinyusb/osal/osal_none.h b/tinyusb/osal/osal_none.h index db11da605..adea45f32 100644 --- a/tinyusb/osal/osal_none.h +++ b/tinyusb/osal/osal_none.h @@ -104,7 +104,7 @@ static inline uint32_t osal_tick_get(void) #define OSAL_TASK_LOOP_BEGIN \ ATTR_UNUSED static uint32_t timeout = 0;\ static uint16_t state = 0;\ - switch(state) {\ + switch(state) { \ case 0: { \ #define OSAL_TASK_LOOP_END \