mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-20 18:40:57 +00:00
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
This commit is contained in:
parent
51def3f7ed
commit
8f70a6a886
@ -60,8 +60,8 @@ static scsi_inquiry_data_t mscd_inquiry_data TUSB_CFG_ATTR_USBRAM =
|
|||||||
ATTR_USB_MIN_ALIGNMENT
|
ATTR_USB_MIN_ALIGNMENT
|
||||||
static scsi_read_capacity10_data_t mscd_read_capacity10_data TUSB_CFG_ATTR_USBRAM =
|
static scsi_read_capacity10_data_t mscd_read_capacity10_data TUSB_CFG_ATTR_USBRAM =
|
||||||
{
|
{
|
||||||
.last_lba = __le2be(DISK_BLOCK_NUM-1), // read capacity
|
.last_lba = __n2be(DISK_BLOCK_NUM-1), // read capacity
|
||||||
.block_size = __le2be(DISK_BLOCK_SIZE)
|
.block_size = __n2be(DISK_BLOCK_SIZE)
|
||||||
};
|
};
|
||||||
|
|
||||||
ATTR_USB_MIN_ALIGNMENT
|
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 =
|
static scsi_read_format_capacity_data_t mscd_format_capacity_data TUSB_CFG_ATTR_USBRAM =
|
||||||
{
|
{
|
||||||
.list_length = 8,
|
.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
|
.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
|
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)
|
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])
|
switch (scsi_cmd[0])
|
||||||
{
|
{
|
||||||
case SCSI_CMD_INQUIRY:
|
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;
|
(*p_length) = 0;
|
||||||
break;
|
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;
|
default: return MSC_CSW_STATUS_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,11 @@ enum
|
|||||||
DISK_BLOCK_SIZE = 512
|
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
|
#if TUSB_CFG_MCU==MCU_LPC11UXX || TUSB_CFG_MCU==MCU_LPC13UXX
|
||||||
#define MSCD_APP_ROMDISK
|
#define MSCD_APP_ROMDISK
|
||||||
#else // defaults is ram disk
|
#else // defaults is ram disk
|
||||||
|
@ -43,10 +43,6 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// 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
|
// 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
|
[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] =
|
[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 -------------//
|
//------------- 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);
|
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];
|
(*pp_buffer) = mscd_app_ramdisk[lba];
|
||||||
|
|
||||||
|
@ -47,10 +47,6 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// 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
|
// 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
|
[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] =
|
[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 -------------//
|
//------------- Root Directory -------------//
|
||||||
@ -90,21 +86,21 @@ const uint8_t mscd_app_rommdisk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
ATTR_USB_MIN_ALIGNMENT
|
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
|
// IMPLEMENTATION
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
uint16_t tusbd_msc_read10_cb (uint8_t coreid, uint8_t lun, void** pp_buffer, uint32_t lba, uint16_t block_count)
|
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);
|
memcpy(sector_buffer, mscd_app_rommdisk[lba], DISK_BLOCK_SIZE);
|
||||||
(*pp_buffer) = ramdisk_buffer;
|
(*pp_buffer) = sector_buffer;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stall write10 as this is readonly disk
|
// 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;
|
(*pp_buffer) = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -136,91 +136,118 @@ tusb_error_t mscd_control_request(uint8_t coreid, tusb_control_request_t const *
|
|||||||
return TUSB_ERROR_NONE;
|
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
|
// 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;
|
mscd_interface_t * const p_msc = &mscd_data;
|
||||||
msc_cmd_block_wrapper_t * const p_cbw = &p_msc->cbw;
|
msc_cmd_block_wrapper_t * const p_cbw = &p_msc->cbw;
|
||||||
msc_cmd_status_wrapper_t * const p_csw = &p_msc->csw;
|
msc_cmd_status_wrapper_t * const p_csw = &p_msc->csw;
|
||||||
|
|
||||||
if ( endpointhandle_is_equal(p_msc->edpt_in, edpt_hdl) )
|
if ( !is_waiting_read10_write10)
|
||||||
{
|
{ // new CBW received
|
||||||
return; // currently no need to handle bulk in
|
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) &&
|
ASSERT( endpointhandle_is_equal(p_msc->edpt_out, edpt_hdl) &&
|
||||||
xferred_bytes == sizeof(msc_cmd_block_wrapper_t) &&
|
xferred_bytes == sizeof(msc_cmd_block_wrapper_t) &&
|
||||||
event == TUSB_EVENT_XFER_COMPLETE &&
|
event == TUSB_EVENT_XFER_COMPLETE &&
|
||||||
p_cbw->signature == MSC_CBW_SIGNATURE, VOID_RETURN );
|
p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA );
|
||||||
|
|
||||||
void *p_buffer = NULL;
|
if ( (SCSI_CMD_READ_10 != p_cbw->command[0]) && (SCSI_CMD_WRITE_10 != p_cbw->command[0]) )
|
||||||
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:
|
|
||||||
{
|
{
|
||||||
scsi_read10_t const * const p_read10 = &p_cbw->command; // read10 & write10 has the same data structure
|
void *p_buffer = NULL;
|
||||||
uint32_t const lba = __be2le(p_read10->lba);
|
uint16_t actual_length = p_cbw->xfer_bytes;
|
||||||
uint16_t const block_count = __be2h_16(p_read10->block_count);
|
|
||||||
|
|
||||||
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);
|
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 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]) )
|
||||||
//------------- Data Phase -------------//
|
|
||||||
if ( p_cbw->xfer_bytes )
|
|
||||||
{
|
{
|
||||||
if ( p_buffer == NULL || actual_length == 0 )
|
if (is_waiting_read10_write10)
|
||||||
{ // application does not provide data to response --> possibly unsupported SCSI command
|
{ // continue with read10, write10 data transfer, interrupt must come from endpoint IN
|
||||||
ASSERT( TUSB_ERROR_NONE == dcd_pipe_stall(p_msc->edpt_in), VOID_RETURN );
|
ASSERT( endpointhandle_is_equal(p_msc->edpt_in, edpt_hdl) && event == TUSB_EVENT_XFER_COMPLETE, TUSB_ERROR_INVALID_PARA);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
is_waiting_read10_write10 = !read10_write10_data_xfer(p_msc);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Status Phase -------------//
|
//------------- 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_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 !!
|
||||||
ASSERT( dcd_pipe_xfer( p_msc->edpt_out, p_cbw, sizeof(msc_cmd_block_wrapper_t), true) == TUSB_ERROR_NONE, VOID_RETURN );
|
|
||||||
|
|
||||||
|
//------------- 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
|
#endif
|
||||||
|
@ -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);
|
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 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);
|
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_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);
|
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);
|
void mscd_close(uint8_t coreid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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 =
|
scsi_read10_t cmd_read10 =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_READ_10,
|
.cmd_code = SCSI_CMD_READ_10,
|
||||||
.lba = __le2be(lba),
|
.lba = __n2be(lba),
|
||||||
.block_count = u16_le2be(block_count)
|
.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 =
|
scsi_write10_t cmd_write10 =
|
||||||
{
|
{
|
||||||
.cmd_code = SCSI_CMD_WRITE_10,
|
.cmd_code = SCSI_CMD_WRITE_10,
|
||||||
.lba = __le2be(lba),
|
.lba = __n2be(lba),
|
||||||
.block_count = u16_le2be(block_count)
|
.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);
|
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].last_lba = __be2n( ((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].block_size = (uint16_t) __be2n( ((scsi_read_capacity10_data_t*)msch_buffer)->block_size );
|
||||||
|
|
||||||
msch_data[dev_addr-1].is_initialized = true;
|
msch_data[dev_addr-1].is_initialized = true;
|
||||||
tusbh_msc_mounted_cb(dev_addr);
|
tusbh_msc_mounted_cb(dev_addr);
|
||||||
|
@ -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_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 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 __n2be_16(u16) ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) ) // TODO refractor later
|
||||||
#define __be2h_16(u16) __h2be_16(u16)
|
#define __be2n_16(u16) __n2be_16(u16)
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// INLINE FUNCTION
|
// INLINE FUNCTION
|
||||||
@ -180,6 +180,12 @@ static inline uint32_t max32_of(uint32_t x, uint32_t y)
|
|||||||
return (x > y) ? x : 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 -------------//
|
//------------- Align -------------//
|
||||||
static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
|
||||||
static inline uint32_t align32 (uint32_t value)
|
static inline uint32_t align32 (uint32_t value)
|
||||||
|
@ -130,9 +130,9 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// built-in function to convert 32-bit Big-Endian to Little-Endian
|
// built-in function to convert 32-bit from native to Big Endian
|
||||||
#define __be2le __builtin_bswap32
|
#define __be2n __builtin_bswap32
|
||||||
#define __le2be __be2le
|
#define __n2be __be2n
|
||||||
|
|
||||||
//#define __le2be_16 __builtin_bswap16
|
//#define __le2be_16 __builtin_bswap16
|
||||||
|
|
||||||
|
@ -82,8 +82,8 @@
|
|||||||
#define ATTR_UNUSED
|
#define ATTR_UNUSED
|
||||||
|
|
||||||
// built-in function to convert 32-bit Big-Endian to Little-Endian
|
// built-in function to convert 32-bit Big-Endian to Little-Endian
|
||||||
#define __be2le __REV
|
#define __be2n __REV
|
||||||
#define __le2be __be2le
|
#define __n2be __be2n
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR
|
|||||||
.init = hidd_init,
|
.init = hidd_init,
|
||||||
.open = hidd_open,
|
.open = hidd_open,
|
||||||
.control_request = hidd_control_request,
|
.control_request = hidd_control_request,
|
||||||
.isr = hidd_isr,
|
.xfer_cb = hidd_isr,
|
||||||
.close = hidd_close
|
.close = hidd_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
@ -81,7 +81,7 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR
|
|||||||
.init = mscd_init,
|
.init = mscd_init,
|
||||||
.open = mscd_open,
|
.open = mscd_open,
|
||||||
.control_request = mscd_control_request,
|
.control_request = mscd_control_request,
|
||||||
.isr = mscd_isr,
|
.xfer_cb = mscd_xfer_cb,
|
||||||
.close = mscd_close
|
.close = mscd_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
@ -92,7 +92,7 @@ static usbd_class_driver_t const usbd_class_drivers[TUSB_CLASS_MAPPED_INDEX_STAR
|
|||||||
.init = cdcd_init,
|
.init = cdcd_init,
|
||||||
.open = cdcd_open,
|
.open = cdcd_open,
|
||||||
.control_request = cdcd_control_request,
|
.control_request = cdcd_control_request,
|
||||||
.isr = cdcd_isr,
|
.xfer_cb = cdcd_isr,
|
||||||
.close = cdcd_close
|
.close = cdcd_close
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
@ -123,16 +123,29 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
USBD_EVENTID_SETUP_RECEIVED = 1
|
USBD_EVENTID_SETUP_RECEIVED = 1,
|
||||||
|
USBD_EVENTID_XFER_DONE
|
||||||
}usbd_eventid_t;
|
}usbd_eventid_t;
|
||||||
|
|
||||||
typedef struct ATTR_ALIGNED(2)
|
typedef struct ATTR_ALIGNED(4)
|
||||||
{
|
{
|
||||||
uint8_t coreid;
|
uint8_t coreid;
|
||||||
uint8_t event_id;
|
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;
|
}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_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_QUEUE_DEF(usbd_queue_def, USBD_TASK_QUEUE_DEPTH, usbd_task_event_t);
|
||||||
OSAL_SEM_DEF(usbd_control_xfer_semaphore_def);
|
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;
|
error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Class/Interface Specific Request -------------//
|
//------------- Class/Interface Specific Request -------------//
|
||||||
else if ( TUSB_REQUEST_RECIPIENT_INTERFACE == p_request->bmRequestType_bit.recipient)
|
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;
|
error = TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------- Endpoint Request -------------//
|
//------------- Endpoint Request -------------//
|
||||||
else if ( TUSB_REQUEST_RECIPIENT_ENDPOINT == p_request->bmRequestType_bit.recipient &&
|
else if ( TUSB_REQUEST_RECIPIENT_ENDPOINT == p_request->bmRequestType_bit.recipient &&
|
||||||
TUSB_REQUEST_TYPE_STANDARD == p_request->bmRequestType_bit.type &&
|
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 )
|
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
|
}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
|
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)
|
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,
|
.coreid = coreid,
|
||||||
.event_id = USBD_EVENTID_SETUP_RECEIVED
|
.event_id = USBD_EVENTID_SETUP_RECEIVED,
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(event.data, p_request, sizeof(tusb_control_request_t));
|
task_event.setup_received = (*p_request);
|
||||||
|
osal_queue_send(usbd_queue_hdl, &task_event);
|
||||||
osal_queue_send(usbd_queue_hdl, &event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbd_xfer_isr(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32_t xferred_bytes)
|
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];
|
if (edpt_hdl.class_code == 0 ) // Control Transfer
|
||||||
uint8_t class_index = std_class_code_to_index(edpt_hdl.class_code);
|
|
||||||
|
|
||||||
if (class_index == 0 ) // Control Transfer
|
|
||||||
{
|
{
|
||||||
if (usbd_devices[edpt_hdl.coreid].is_waiting_control_xfer)
|
if (usbd_devices[edpt_hdl.coreid].is_waiting_control_xfer)
|
||||||
{
|
{
|
||||||
osal_semaphore_post( usbd_control_xfer_sem_hdl );
|
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
|
}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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
@ -71,7 +71,7 @@ typedef struct {
|
|||||||
void (* const init) (void);
|
void (* const init) (void);
|
||||||
tusb_error_t (* const open)(uint8_t, tusb_descriptor_interface_t const *, uint16_t*);
|
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 *);
|
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);
|
void (* const close) (uint8_t);
|
||||||
} usbd_class_driver_t;
|
} usbd_class_driver_t;
|
||||||
|
|
||||||
|
@ -109,8 +109,10 @@ static inline bool hal_debugger_is_attached(void)
|
|||||||
// TODO check core M3/M4 defined instead
|
// TODO check core M3/M4 defined instead
|
||||||
#if !defined(_TEST_) && !(TUSB_CFG_MCU==MCU_LPC11UXX)
|
#if !defined(_TEST_) && !(TUSB_CFG_MCU==MCU_LPC11UXX)
|
||||||
return ( (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == CoreDebug_DHCSR_C_DEBUGEN_Msk );
|
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
|
#else
|
||||||
return true; // force to break into breakpoint
|
return false
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ static inline uint32_t osal_tick_get(void)
|
|||||||
#define OSAL_TASK_LOOP_BEGIN \
|
#define OSAL_TASK_LOOP_BEGIN \
|
||||||
ATTR_UNUSED static uint32_t timeout = 0;\
|
ATTR_UNUSED static uint32_t timeout = 0;\
|
||||||
static uint16_t state = 0;\
|
static uint16_t state = 0;\
|
||||||
switch(state) {\
|
switch(state) { \
|
||||||
case 0: { \
|
case 0: { \
|
||||||
|
|
||||||
#define OSAL_TASK_LOOP_END \
|
#define OSAL_TASK_LOOP_END \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user