mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
commit
656673fb58
0
examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX
Normal file
0
examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX
Normal file
@ -19,9 +19,9 @@ SRC_C += \
|
||||
src/host/hub.c \
|
||||
src/host/usbh.c \
|
||||
src/host/usbh_control.c \
|
||||
src/host/ehci/ehci.c \
|
||||
src/host/ohci/ohci.c \
|
||||
src/portable/nxp/lpc18_43/hcd_lpc18_43.c \
|
||||
src/portable/ehci/ehci.c \
|
||||
src/portable/ohci/ohci.c \
|
||||
src/portable/nxp/transdimension/hcd_transdimension.c \
|
||||
src/portable/nxp/lpc17_40/hcd_lpc17_40.c
|
||||
|
||||
include ../../rules.mk
|
||||
|
@ -31,31 +31,6 @@
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
static scsi_inquiry_resp_t inquiry_resp;
|
||||
static scsi_read_capacity10_resp_t capacity_resp;
|
||||
|
||||
uint32_t block_size;
|
||||
uint32_t block_count;
|
||||
|
||||
bool capacity_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
|
||||
{
|
||||
(void) dev_addr;
|
||||
(void) cbw;
|
||||
|
||||
if (csw->status != 0)
|
||||
{
|
||||
printf("Read Capacity (10) failed\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Capacity response field: Block size and Last LBA are both Big-Endian
|
||||
block_count = tu_ntohl(capacity_resp.last_lba) + 1;
|
||||
block_size = tu_ntohl(capacity_resp.block_size);
|
||||
|
||||
printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size));
|
||||
printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool inquiry_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
|
||||
{
|
||||
@ -68,21 +43,23 @@ bool inquiry_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const
|
||||
// Print out Vendor ID, Product ID and Rev
|
||||
printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
|
||||
|
||||
// Read capacity of device
|
||||
tuh_msc_read_capacity(dev_addr, cbw->lun, &capacity_resp, capacity_complete_cb);
|
||||
// Get capacity of device
|
||||
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
|
||||
uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
|
||||
|
||||
printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size));
|
||||
printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------- IMPLEMENTATION -------------//
|
||||
void tuh_msc_mounted_cb(uint8_t dev_addr)
|
||||
void tuh_msc_mount_cb(uint8_t dev_addr)
|
||||
{
|
||||
printf("A MassStorage device is mounted\r\n");
|
||||
|
||||
block_size = block_count = 0;
|
||||
|
||||
uint8_t const lun = 0;
|
||||
tuh_msc_scsi_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb);
|
||||
tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb);
|
||||
//
|
||||
// //------------- file system (only 1 LUN support) -------------//
|
||||
// uint8_t phy_disk = dev_addr-1;
|
||||
@ -96,13 +73,6 @@ void tuh_msc_mounted_cb(uint8_t dev_addr)
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// puts("---------------------------------------------------------------------");
|
||||
// puts("- MASSSTORAGE CLASS CLI IS A IMMATURE CODE. DISK-WRITING COMMANDS");
|
||||
// puts("- SUCH AS cp(COPY), mkdir(MAKE DIRECTORY) ARE POTENTIAL TO DAMAGE");
|
||||
// puts("- YOUR USB THUMBDRIVE. USING THOSE COMMANDS ARE AT YOUR OWN RISK.");
|
||||
// puts("- THE AUTHOR HAS NO RESPONSIBILITY WITH YOUR DEVICE NOR ITS DATA");
|
||||
// puts("---------------------------------------------------------------------");
|
||||
//
|
||||
// f_chdrive(phy_disk); // change to newly mounted drive
|
||||
// f_chdir("/"); // root as current dir
|
||||
//
|
||||
@ -110,7 +80,7 @@ void tuh_msc_mounted_cb(uint8_t dev_addr)
|
||||
// }
|
||||
}
|
||||
|
||||
void tuh_msc_unmounted_cb(uint8_t dev_addr)
|
||||
void tuh_msc_unmount_cb(uint8_t dev_addr)
|
||||
{
|
||||
(void) dev_addr;
|
||||
printf("A MassStorage device is unmounted\r\n");
|
||||
@ -133,11 +103,4 @@ void tuh_msc_unmounted_cb(uint8_t dev_addr)
|
||||
// }
|
||||
}
|
||||
|
||||
//void tuh_msc_scsi_complete_cb(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
|
||||
//{
|
||||
// (void) dev_addr;
|
||||
// (void) cbw;
|
||||
// (void) csw;
|
||||
//}
|
||||
|
||||
#endif
|
||||
|
@ -48,7 +48,7 @@ CFG_TUSB_MEM_SECTION static FATFS fatfs[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
//--------------------------------------------------------------------+
|
||||
// tinyusb callbacks
|
||||
//--------------------------------------------------------------------+
|
||||
void tuh_msc_mounted_cb(uint8_t dev_addr)
|
||||
void tuh_msc_mount_cb(uint8_t dev_addr)
|
||||
{
|
||||
puts("\na MassStorage device is mounted");
|
||||
|
||||
@ -94,7 +94,7 @@ void tuh_msc_mounted_cb(uint8_t dev_addr)
|
||||
}
|
||||
}
|
||||
|
||||
void tuh_msc_unmounted_cb(uint8_t dev_addr)
|
||||
void tuh_msc_unmount_cb(uint8_t dev_addr)
|
||||
{
|
||||
puts("\na MassStorage device is unmounted");
|
||||
|
||||
|
@ -82,10 +82,15 @@ void board_init(void)
|
||||
LPUART_Init(UART_PORT, &uart_config, (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U));
|
||||
|
||||
//------------- USB0 -------------//
|
||||
|
||||
// Clock
|
||||
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
|
||||
|
||||
// USB1
|
||||
// CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||
// CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
|
||||
|
||||
USBPHY_Type* usb_phy;
|
||||
|
||||
// RT105x RT106x have dual USB controller. TODO support USB2
|
||||
@ -106,10 +111,6 @@ void board_init(void)
|
||||
phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK);
|
||||
phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
|
||||
usb_phy->TX = phytx;
|
||||
|
||||
// USB1
|
||||
// CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
|
||||
// CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -157,51 +157,12 @@ void board_init(void)
|
||||
Chip_UART_TXEnable(UART_DEV);
|
||||
|
||||
//------------- USB -------------//
|
||||
enum {
|
||||
USBMODE_DEVICE = 2,
|
||||
USBMODE_HOST = 3
|
||||
};
|
||||
|
||||
enum {
|
||||
USBMODE_VBUS_LOW = 0,
|
||||
USBMODE_VBUS_HIGH = 1
|
||||
};
|
||||
|
||||
// USB0
|
||||
#if CFG_TUSB_RHPORT0_MODE
|
||||
Chip_USB0_Init();
|
||||
|
||||
// Host/Device mode can only be set right after controller reset
|
||||
LPC_USB0->USBCMD_D |= 0x02;
|
||||
while( LPC_USB0->USBCMD_D & 0x02 ) {}
|
||||
|
||||
// Set mode
|
||||
#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST
|
||||
LPC_USB0->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5);
|
||||
LPC_USB0->PORTSC1_H |= (1<<24); // FIXME force full speed for debugging
|
||||
#else // TODO OTG
|
||||
LPC_USB0->USBMODE_D = USBMODE_DEVICE;
|
||||
LPC_USB0->OTGSC = (1<<3) | (1<<0) /*| (1<<16)| (1<<24)| (1<<25)| (1<<26)| (1<<27)| (1<<28)| (1<<29)| (1<<30)*/;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// USB1
|
||||
#if CFG_TUSB_RHPORT1_MODE
|
||||
Chip_USB1_Init();
|
||||
|
||||
// // Reset controller
|
||||
// LPC_USB1->USBCMD_D |= 0x02;
|
||||
// while( LPC_USB1->USBCMD_D & 0x02 ) {}
|
||||
//
|
||||
// // Set mode
|
||||
// #if CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST
|
||||
// LPC_USB1->USBMODE_H = USBMODE_HOST | (USBMODE_VBUS_HIGH << 5);
|
||||
// #else // TODO OTG
|
||||
// LPC_USB1->USBMODE_D = USBMODE_DEVICE;
|
||||
// #endif
|
||||
//
|
||||
// // USB1 as fullspeed
|
||||
// LPC_USB1->PORTSC1_D |= (1<<24);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ static DSTATUS disk_state[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
static DRESULT wait_for_io_complete(uint8_t usb_addr)
|
||||
{
|
||||
// TODO with RTOS, this should use semaphore instead of blocking
|
||||
while ( tuh_msc_is_busy(usb_addr) )
|
||||
while ( !tuh_msc_ready(usb_addr) )
|
||||
{
|
||||
// TODO should have timeout here
|
||||
#if CFG_TUSB_OS != OPT_OS_NONE
|
||||
|
@ -47,14 +47,21 @@ enum
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_in;
|
||||
uint8_t ep_out;
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_in;
|
||||
uint8_t ep_out;
|
||||
|
||||
uint8_t max_lun;
|
||||
uint8_t max_lun;
|
||||
|
||||
volatile bool mounted;
|
||||
volatile bool configured; // Receive SET_CONFIGURE
|
||||
volatile bool mounted; // Enumeration is complete
|
||||
|
||||
struct {
|
||||
uint32_t block_size;
|
||||
uint32_t block_count;
|
||||
} capacity[CFG_TUH_MSC_MAXLUN];
|
||||
|
||||
//------------- SCSI -------------//
|
||||
uint8_t stage;
|
||||
void* buffer;
|
||||
tuh_msc_complete_cb_t complete_cb;
|
||||
@ -63,14 +70,15 @@ typedef struct
|
||||
msc_csw_t csw;
|
||||
}msch_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION static msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
CFG_TUSB_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
|
||||
// buffer used to read scsi information when mounted, largest response data currently is inquiry
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t msch_buffer[sizeof(scsi_inquiry_resp_t)];
|
||||
// buffer used to read scsi information when mounted
|
||||
// largest response data currently is inquiry TODO Inquiry is not part of enum anymore
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)];
|
||||
|
||||
static inline msch_interface_t* get_itf(uint8_t dev_addr)
|
||||
{
|
||||
return &msch_data[dev_addr-1];
|
||||
return &_msch_itf[dev_addr-1];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@ -82,34 +90,45 @@ uint8_t tuh_msc_get_maxlun(uint8_t dev_addr)
|
||||
return p_msc->max_lun;
|
||||
}
|
||||
|
||||
uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->capacity[lun].block_count;
|
||||
}
|
||||
|
||||
uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->capacity[lun].block_size;
|
||||
}
|
||||
|
||||
bool tuh_msc_mounted(uint8_t dev_addr)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
|
||||
// is configured can be omitted
|
||||
return tuh_device_is_configured(dev_addr) && p_msc->mounted;
|
||||
return p_msc->mounted;
|
||||
}
|
||||
|
||||
bool tuh_msc_is_busy(uint8_t dev_addr)
|
||||
bool tuh_msc_ready(uint8_t dev_addr)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->mounted && hcd_edpt_busy(dev_addr, p_msc->ep_in);
|
||||
return p_msc->mounted && !hcd_edpt_busy(dev_addr, p_msc->ep_in);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PUBLIC API: SCSI COMMAND
|
||||
//--------------------------------------------------------------------+
|
||||
static inline void msc_cbw_add_signature(msc_cbw_t *p_cbw, uint8_t lun)
|
||||
static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun)
|
||||
{
|
||||
p_cbw->signature = MSC_CBW_SIGNATURE;
|
||||
p_cbw->tag = 0x54555342; // TUSB
|
||||
p_cbw->lun = lun;
|
||||
tu_memclr(cbw, sizeof(msc_cbw_t));
|
||||
cbw->signature = MSC_CBW_SIGNATURE;
|
||||
cbw->tag = 0x54555342; // TUSB
|
||||
cbw->lun = lun;
|
||||
}
|
||||
|
||||
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
// TU_VERIFY(p_msc->mounted); // TODO part of the enumeration also use scsi command
|
||||
TU_VERIFY(p_msc->configured);
|
||||
|
||||
// TODO claim endpoint
|
||||
|
||||
@ -125,12 +144,12 @@ bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tu
|
||||
|
||||
bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
if ( !p_msc->mounted ) return false;
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured);
|
||||
|
||||
msc_cbw_t cbw = { 0 };
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
msc_cbw_add_signature(&cbw, lun);
|
||||
cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t);
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_read_capacity10_t);
|
||||
@ -139,11 +158,14 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb);
|
||||
}
|
||||
|
||||
bool tuh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb)
|
||||
bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msc_cbw_t cbw = { 0 };
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->mounted);
|
||||
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
msc_cbw_add_signature(&cbw, lun);
|
||||
cbw.total_bytes = sizeof(scsi_inquiry_resp_t);
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_inquiry_t);
|
||||
@ -160,26 +182,29 @@ bool tuh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* re
|
||||
|
||||
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msc_cbw_t cbw = { 0 };
|
||||
msc_cbw_add_signature(&cbw, lun);
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured);
|
||||
|
||||
cbw.total_bytes = 0; // Number of bytes
|
||||
cbw.dir = TUSB_DIR_OUT;
|
||||
cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
|
||||
cbw.command[0] = SCSI_CMD_TEST_UNIT_READY;
|
||||
cbw.command[1] = lun; // according to wiki TODO need verification
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = 0;
|
||||
cbw.dir = TUSB_DIR_OUT;
|
||||
cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
|
||||
cbw.command[0] = SCSI_CMD_TEST_UNIT_READY;
|
||||
cbw.command[1] = lun; // according to wiki TODO need verification
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb);
|
||||
}
|
||||
|
||||
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msc_cbw_t cbw = { 0 };
|
||||
msc_cbw_add_signature(&cbw, lun);
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = 18; // TODO sense response
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_request_sense_t);
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_request_sense_t);
|
||||
|
||||
scsi_request_sense_t const cmd_request_sense =
|
||||
{
|
||||
@ -192,61 +217,54 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_ms
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, resposne, complete_cb);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
tusb_error_t tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count)
|
||||
bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->mounted);
|
||||
|
||||
//------------- Command Block Wrapper -------------//
|
||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||
|
||||
p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
|
||||
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
|
||||
p_msch->cbw.cmd_len = sizeof(scsi_read10_t);
|
||||
|
||||
//------------- SCSI command -------------//
|
||||
scsi_read10_t cmd_read10 =msch_sem_hdl
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_read10_t);
|
||||
|
||||
scsi_read10_t const cmd_read10 =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_READ_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
.cmd_code = SCSI_CMD_READ_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
};
|
||||
|
||||
memcpy(cbw.command, &cmd_read10, cbw.cmd_len);
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb);
|
||||
}
|
||||
|
||||
bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->mounted);
|
||||
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
|
||||
cbw.dir = TUSB_DIR_OUT;
|
||||
cbw.cmd_len = sizeof(scsi_write10_t);
|
||||
|
||||
scsi_write10_t const cmd_write10 =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_WRITE_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
};
|
||||
|
||||
memcpy(p_msch->cbw.command, &cmd_read10, p_msch->cbw.cmd_len);
|
||||
memcpy(cbw.command, &cmd_write10, cbw.cmd_len);
|
||||
|
||||
TU_ASSERT_ERR ( send_cbw(dev_addr, p_msch, p_buffer));
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, (void*) buffer, complete_cb);
|
||||
}
|
||||
|
||||
tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count)
|
||||
{
|
||||
msch_interface_t* p_msch = &msch_data[dev_addr-1];
|
||||
|
||||
//------------- Command Block Wrapper -------------//
|
||||
msc_cbw_add_signature(&p_msch->cbw, lun);
|
||||
|
||||
p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
|
||||
p_msch->cbw.dir = TUSB_DIR_OUT;
|
||||
p_msch->cbw.cmd_len = sizeof(scsi_write10_t);
|
||||
|
||||
//------------- SCSI command -------------//
|
||||
scsi_write10_t cmd_write10 =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_WRITE_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
};
|
||||
|
||||
memcpy(p_msch->cbw.command, &cmd_write10, p_msch->cbw.cmd_len);
|
||||
|
||||
TU_ASSERT_ERR ( send_cbw(dev_addr, p_msch, (void*) p_buffer));
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// MSC interface Reset (not used now)
|
||||
bool tuh_msc_reset(uint8_t dev_addr)
|
||||
@ -273,14 +291,14 @@ bool tuh_msc_reset(uint8_t dev_addr)
|
||||
//--------------------------------------------------------------------+
|
||||
void msch_init(void)
|
||||
{
|
||||
tu_memclr(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
tu_memclr(_msch_itf, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
}
|
||||
|
||||
void msch_close(uint8_t dev_addr)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
tu_memclr(p_msc, sizeof(msch_interface_t));
|
||||
tuh_msc_unmounted_cb(dev_addr); // invoke Application Callback
|
||||
tuh_msc_unmount_cb(dev_addr); // invoke Application Callback
|
||||
}
|
||||
|
||||
bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||
@ -337,6 +355,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
|
||||
static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
|
||||
static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
|
||||
static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
|
||||
static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
|
||||
|
||||
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
|
||||
{
|
||||
@ -375,6 +394,8 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num)
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_ASSERT(p_msc->itf_num == itf_num);
|
||||
|
||||
p_msc->configured = true;
|
||||
|
||||
//------------- Get Max Lun -------------//
|
||||
TU_LOG2("MSC Get Max Lun\r\n");
|
||||
tusb_control_request_t request =
|
||||
@ -402,12 +423,13 @@ static bool config_get_maxlun_complete (uint8_t dev_addr, tusb_control_request_t
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
|
||||
// STALL means zero
|
||||
p_msc->max_lun = (XFER_RESULT_SUCCESS == result) ? msch_buffer[0] : 0;
|
||||
p_msc->max_lun = (XFER_RESULT_SUCCESS == result) ? _msch_buffer[0] : 0;
|
||||
p_msc->max_lun++; // MAX LUN is minus 1 by specs
|
||||
|
||||
// TODO multiple LUN support
|
||||
TU_LOG2("SCSI Test Unit Ready\r\n");
|
||||
tuh_msc_test_unit_ready(dev_addr, 0, config_test_unit_ready_complete);
|
||||
uint8_t const lun = 0;
|
||||
tuh_msc_test_unit_ready(dev_addr, lun, config_test_unit_ready_complete);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -416,19 +438,16 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* c
|
||||
{
|
||||
if (csw->status == 0)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
|
||||
usbh_driver_set_config_complete(dev_addr, p_msc->itf_num);
|
||||
|
||||
// Unit is ready, Enumeration is complete
|
||||
p_msc->mounted = true;
|
||||
tuh_msc_mounted_cb(dev_addr);
|
||||
// Unit is ready, read its capacity
|
||||
TU_LOG2("SCSI Read Capacity\r\n");
|
||||
tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) _msch_buffer, config_read_capacity_complete);
|
||||
}else
|
||||
{
|
||||
// Note: During enumeration, some device fails Test Unit Ready and require a few retries
|
||||
// with Request Sense to start working !!
|
||||
// TODO limit number of retries
|
||||
TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, msch_buffer, config_request_sense_complete));
|
||||
TU_LOG2("SCSI Request Sense\r\n");
|
||||
TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -441,4 +460,24 @@ static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)
|
||||
{
|
||||
TU_ASSERT(csw->status == 0);
|
||||
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
|
||||
// Capacity response field: Block size and Last LBA are both Big-Endian
|
||||
scsi_read_capacity10_resp_t* resp = (scsi_read_capacity10_resp_t*) _msch_buffer;
|
||||
p_msc->capacity[cbw->lun].block_count = tu_ntohl(resp->last_lba) + 1;
|
||||
p_msc->capacity[cbw->lun].block_size = tu_ntohl(resp->block_size);
|
||||
|
||||
// Mark enumeration is complete
|
||||
p_msc->mounted = true;
|
||||
tuh_msc_mount_cb(dev_addr);
|
||||
|
||||
usbh_driver_set_config_complete(dev_addr, p_msc->itf_num);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Class Driver Configuration
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifndef CFG_TUH_MSC_MAXLUN
|
||||
#define CFG_TUH_MSC_MAXLUN 4
|
||||
#endif
|
||||
|
||||
|
||||
/** \addtogroup ClassDriver_MSC
|
||||
* @{
|
||||
* \defgroup MSC_Host Host
|
||||
@ -51,73 +60,56 @@ typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, msc_cbw_t const* cbw, ms
|
||||
// This function true after tuh_msc_mounted_cb() and false after tuh_msc_unmounted_cb()
|
||||
bool tuh_msc_mounted(uint8_t dev_addr);
|
||||
|
||||
/** \brief Check if the interface is currently busy or not
|
||||
* \param[in] dev_addr device address
|
||||
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
|
||||
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
|
||||
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
|
||||
* can be scheduled. User needs to make sure the corresponding interface is mounted (by \ref tuh_msc_is_mounted)
|
||||
* before calling this function
|
||||
*/
|
||||
bool tuh_msc_is_busy(uint8_t dev_addr);
|
||||
// Check if the interface is currently ready or busy transferring data
|
||||
bool tuh_msc_ready(uint8_t dev_addr);
|
||||
|
||||
// Get Max Lun
|
||||
uint8_t tuh_msc_get_maxlun(uint8_t dev_addr);
|
||||
|
||||
// Carry out a full SCSI command (cbw, data, csw) in non-blocking manner.
|
||||
// `complete_cb` callback is invoked when SCSI op is complete.
|
||||
// Get number of block
|
||||
uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun);
|
||||
|
||||
// Get block size in bytes
|
||||
uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun);
|
||||
|
||||
// Perform a full SCSI command (cbw, data, csw) in non-blocking manner.
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
// return true if success, false if there is already pending operation.
|
||||
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
// Carry out SCSI INQUIRY command in non-blocking manner.
|
||||
bool tuh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb);
|
||||
// Perform SCSI Inquiry command
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
// Carry out SCSI REQUEST SENSE (10) command in non-blocking manner.
|
||||
// Perform SCSI Test Unit Ready command
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
// Carry out SCSI REQUEST SENSE (10) command in non-blocking manner.
|
||||
// Perform SCSI Request Sense 10 command
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
// Carry out SCSI READ CAPACITY (10) command in non-blocking manner.
|
||||
// Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
// Perform SCSI Write 10 command. Write n blocks starting from LBA to device
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
// Perform SCSI Read Capacity 10 command
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
// Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by
|
||||
// simply call tuh_msc_get_block_count() and tuh_msc_get_block_size()
|
||||
bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb);
|
||||
|
||||
#if 0
|
||||
/** \brief Perform SCSI READ 10 command to read data from MassStorage device
|
||||
* \param[in] dev_addr device address
|
||||
* \param[in] lun Targeted Logical Unit
|
||||
* \param[out] p_buffer Buffer used to store data read from device. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||
* \param[in] lba Starting Logical Block Address to be read
|
||||
* \param[in] block_count Number of Block to be read
|
||||
* \retval TUSB_ERROR_NONE on success
|
||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
||||
*/
|
||||
tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count);
|
||||
|
||||
/** \brief Perform SCSI WRITE 10 command to write data to MassStorage device
|
||||
* \param[in] dev_addr device address
|
||||
* \param[in] lun Targeted Logical Unit
|
||||
* \param[in] p_buffer Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
|
||||
* \param[in] lba Starting Logical Block Address to be written
|
||||
* \param[in] block_count Number of Block to be written
|
||||
* \retval TUSB_ERROR_NONE on success
|
||||
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
|
||||
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
|
||||
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
|
||||
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
|
||||
*/
|
||||
tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count);
|
||||
#endif
|
||||
|
||||
//------------- Application Callback -------------//
|
||||
|
||||
// Invoked when a device with MassStorage interface is mounted
|
||||
void tuh_msc_mounted_cb(uint8_t dev_addr);
|
||||
void tuh_msc_mount_cb(uint8_t dev_addr);
|
||||
|
||||
// Invoked when a device with MassStorage interface is unmounted
|
||||
void tuh_msc_unmounted_cb(uint8_t dev_addr);
|
||||
void tuh_msc_unmount_cb(uint8_t dev_addr);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Internal Class Driver API
|
||||
|
@ -98,7 +98,7 @@ enum {
|
||||
//--------------------------------------------------------------------+
|
||||
// Controller & Port API
|
||||
//--------------------------------------------------------------------+
|
||||
bool hcd_init(void);
|
||||
bool hcd_init(uint8_t rhport);
|
||||
void hcd_int_handler(uint8_t rhport);
|
||||
void hcd_int_enable (uint8_t rhport);
|
||||
void hcd_int_disable(uint8_t rhport);
|
||||
|
@ -197,7 +197,7 @@ bool tuh_init(void)
|
||||
usbh_class_drivers[drv_id].init();
|
||||
}
|
||||
|
||||
TU_ASSERT(hcd_init());
|
||||
TU_ASSERT(hcd_init(TUH_OPT_RHPORT));
|
||||
hcd_int_enable(TUH_OPT_RHPORT);
|
||||
|
||||
return true;
|
||||
|
@ -26,14 +26,17 @@
|
||||
|
||||
#include "common/tusb_common.h"
|
||||
|
||||
#if TUSB_OPT_HOST_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX)
|
||||
#if TUSB_OPT_HOST_ENABLED && \
|
||||
(CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || \
|
||||
CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX )
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INCLUDE
|
||||
//--------------------------------------------------------------------+
|
||||
#include "osal/osal.h"
|
||||
|
||||
#include "../hcd.h"
|
||||
#include "../usbh_hcd.h"
|
||||
#include "host/hcd.h"
|
||||
#include "host/usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@ -48,6 +51,7 @@ CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data;
|
||||
|
||||
// EHCI portable
|
||||
uint32_t hcd_ehci_register_addr(uint8_t rhport);
|
||||
bool hcd_ehci_init (uint8_t rhport); // TODO move later
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PROTOTYPE
|
||||
@ -97,16 +101,9 @@ static void qtd_init (ehci_qtd_t* p_qtd, void* buffer, uint16_t total_bytes);
|
||||
static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
|
||||
static inline ehci_link_t* list_next (ehci_link_t *p_link_pointer);
|
||||
|
||||
static bool ehci_init (uint8_t rhport);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// HCD API
|
||||
//--------------------------------------------------------------------+
|
||||
bool hcd_init(void)
|
||||
{
|
||||
tu_memclr(&ehci_data, sizeof(ehci_data_t));
|
||||
return ehci_init(TUH_OPT_RHPORT);
|
||||
}
|
||||
|
||||
uint32_t hcd_uframe_number(uint8_t rhport)
|
||||
{
|
||||
@ -203,8 +200,10 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
}
|
||||
|
||||
// EHCI controller init
|
||||
static bool ehci_init(uint8_t rhport)
|
||||
bool hcd_ehci_init(uint8_t rhport)
|
||||
{
|
||||
tu_memclr(&ehci_data, sizeof(ehci_data_t));
|
||||
|
||||
ehci_data.regs = (ehci_registers_t* ) hcd_ehci_register_addr(rhport);
|
||||
|
||||
ehci_registers_t* regs = ehci_data.regs;
|
@ -33,8 +33,6 @@
|
||||
#ifndef _TUSB_EHCI_H_
|
||||
#define _TUSB_EHCI_H_
|
||||
|
||||
#include "common/tusb_common.h"
|
||||
#include "../hcd.h"
|
||||
|
||||
/* Abbreviation
|
||||
* HC: Host Controller
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if TUSB_OPT_HOST_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX)
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
// LPC18xx and 43xx use EHCI driver
|
||||
|
||||
void hcd_int_enable(uint8_t rhport)
|
||||
{
|
||||
NVIC_EnableIRQ(rhport ? USB1_IRQn : USB0_IRQn);
|
||||
}
|
||||
|
||||
void hcd_int_disable(uint8_t rhport)
|
||||
{
|
||||
NVIC_DisableIRQ(rhport ? USB1_IRQn : USB0_IRQn);
|
||||
}
|
||||
|
||||
uint32_t hcd_ehci_register_addr(uint8_t rhport)
|
||||
{
|
||||
return (uint32_t) (rhport ? &LPC_USB1->USBCMD_H : &LPC_USB0->USBCMD_H );
|
||||
}
|
||||
|
||||
#endif
|
136
src/portable/nxp/transdimension/common_transdimension.h
Normal file
136
src/portable/nxp/transdimension/common_transdimension.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021, Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_TRANSDIMENSION_H_
|
||||
#define COMMON_TRANSDIMENSION_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// USBCMD
|
||||
enum {
|
||||
USBCMD_RUN_STOP = TU_BIT(0),
|
||||
USBCMD_RESET = TU_BIT(1),
|
||||
USBCMD_SETUP_TRIPWIRE = TU_BIT(13),
|
||||
USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD
|
||||
// Interrupt Threshold bit 23:16
|
||||
};
|
||||
|
||||
// PORTSC1
|
||||
#define PORTSC1_PORT_SPEED_POS 26
|
||||
|
||||
enum {
|
||||
PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0),
|
||||
PORTSC1_FORCE_PORT_RESUME = TU_BIT(6),
|
||||
PORTSC1_SUSPEND = TU_BIT(7),
|
||||
PORTSC1_FORCE_FULL_SPEED = TU_BIT(24),
|
||||
PORTSC1_PORT_SPEED = TU_BIT(26) | TU_BIT(27)
|
||||
};
|
||||
|
||||
// OTGSC
|
||||
enum {
|
||||
OTGSC_VBUS_DISCHARGE = TU_BIT(0),
|
||||
OTGSC_VBUS_CHARGE = TU_BIT(1),
|
||||
// OTGSC_HWASSIST_AUTORESET = TU_BIT(2),
|
||||
OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode
|
||||
OTGSC_DATA_PULSING = TU_BIT(4),
|
||||
OTGSC_ID_PULLUP = TU_BIT(5),
|
||||
// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6),
|
||||
// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7),
|
||||
OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device
|
||||
OTGSC_A_VBUS_VALID = TU_BIT(9),
|
||||
OTGSC_A_SESSION_VALID = TU_BIT(10),
|
||||
OTGSC_B_SESSION_VALID = TU_BIT(11),
|
||||
OTGSC_B_SESSION_END = TU_BIT(12),
|
||||
OTGSC_1MS_TOGGLE = TU_BIT(13),
|
||||
OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14),
|
||||
};
|
||||
|
||||
// USBMode
|
||||
enum {
|
||||
USBMODE_CM_DEVICE = 2,
|
||||
USBMODE_CM_HOST = 3,
|
||||
|
||||
USBMODE_SLOM = TU_BIT(3),
|
||||
USBMODE_SDIS = TU_BIT(4),
|
||||
|
||||
USBMODE_VBUS_POWER_SELECT = TU_BIT(5), // Need to be enabled for LPC18XX/43XX in host mode
|
||||
};
|
||||
|
||||
// Device Registers
|
||||
typedef struct
|
||||
{
|
||||
//------------- ID + HW Parameter Registers-------------//
|
||||
__I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX
|
||||
|
||||
//------------- Capability Registers-------------//
|
||||
__I uint8_t CAPLENGTH; ///< Capability Registers Length
|
||||
__I uint8_t TU_RESERVED[1];
|
||||
__I uint16_t HCIVERSION; ///< Host Controller Interface Version
|
||||
|
||||
__I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters
|
||||
__I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters
|
||||
__I uint32_t TU_RESERVED[5];
|
||||
|
||||
__I uint16_t DCIVERSION; ///< Device Controller Interface Version
|
||||
__I uint8_t TU_RESERVED[2];
|
||||
|
||||
__I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters
|
||||
__I uint32_t TU_RESERVED[6];
|
||||
|
||||
//------------- Operational Registers -------------//
|
||||
__IO uint32_t USBCMD; ///< USB Command Register
|
||||
__IO uint32_t USBSTS; ///< USB Status Register
|
||||
__IO uint32_t USBINTR; ///< Interrupt Enable Register
|
||||
__IO uint32_t FRINDEX; ///< USB Frame Index
|
||||
__I uint32_t TU_RESERVED;
|
||||
__IO uint32_t DEVICEADDR; ///< Device Address
|
||||
__IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address
|
||||
__I uint32_t TU_RESERVED;
|
||||
__IO uint32_t BURSTSIZE; ///< Programmable Burst Size
|
||||
__IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning
|
||||
uint32_t TU_RESERVED[4];
|
||||
__IO uint32_t ENDPTNAK; ///< Endpoint NAK
|
||||
__IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable
|
||||
__I uint32_t TU_RESERVED;
|
||||
__IO uint32_t PORTSC1; ///< Port Status & Control
|
||||
__I uint32_t TU_RESERVED[7];
|
||||
__IO uint32_t OTGSC; ///< On-The-Go Status & control
|
||||
__IO uint32_t USBMODE; ///< USB Device Mode
|
||||
__IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status
|
||||
__IO uint32_t ENDPTPRIME; ///< Endpoint Prime
|
||||
__IO uint32_t ENDPTFLUSH; ///< Endpoint Flush
|
||||
__I uint32_t ENDPTSTAT; ///< Endpoint Status
|
||||
__IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete
|
||||
__IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7
|
||||
} dcd_registers_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* COMMON_TRANSDIMENSION_H_ */
|
@ -26,16 +26,12 @@
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC18XX || \
|
||||
CFG_TUSB_MCU == OPT_MCU_LPC43XX || \
|
||||
CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX)
|
||||
#if TUSB_OPT_DEVICE_ENABLED && \
|
||||
(CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INCLUDE
|
||||
//--------------------------------------------------------------------+
|
||||
#include "common/tusb_common.h"
|
||||
#include "device/dcd.h"
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
|
||||
#include "fsl_device_registers.h"
|
||||
#else
|
||||
@ -43,6 +39,10 @@
|
||||
#include "chip.h"
|
||||
#endif
|
||||
|
||||
#include "common/tusb_common.h"
|
||||
#include "device/dcd.h"
|
||||
#include "common_transdimension.h"
|
||||
|
||||
#if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1
|
||||
#define CleanInvalidateDCache_by_Addr SCB_CleanInvalidateDCache_by_Addr
|
||||
#else
|
||||
@ -61,15 +61,6 @@ enum {
|
||||
ENDPTCTRL_ENABLE = TU_BIT(7)
|
||||
};
|
||||
|
||||
// USBCMD
|
||||
enum {
|
||||
USBCMD_RUN_STOP = TU_BIT(0),
|
||||
USBCMD_RESET = TU_BIT(1),
|
||||
USBCMD_SETUP_TRIPWIRE = TU_BIT(13),
|
||||
USBCMD_ADD_QTD_TRIPWIRE = TU_BIT(14) ///< This bit is used as a semaphore to ensure the to proper addition of a new dTD to an active (primed) endpoint’s linked list. This bit is set and cleared by software during the process of adding a new dTD
|
||||
};
|
||||
// Interrupt Threshold bit 23:16
|
||||
|
||||
// USBSTS, USBINTR
|
||||
enum {
|
||||
INTR_USB = TU_BIT(0),
|
||||
@ -81,96 +72,6 @@ enum {
|
||||
INTR_NAK = TU_BIT(16)
|
||||
};
|
||||
|
||||
// PORTSC1
|
||||
#define PORTSC1_PORT_SPEED_POS 26
|
||||
|
||||
enum {
|
||||
PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0),
|
||||
PORTSC1_FORCE_PORT_RESUME = TU_BIT(6),
|
||||
PORTSC1_SUSPEND = TU_BIT(7),
|
||||
PORTSC1_FORCE_FULL_SPEED = TU_BIT(24),
|
||||
PORTSC1_PORT_SPEED = TU_BIT(26) | TU_BIT(27)
|
||||
};
|
||||
|
||||
// OTGSC
|
||||
enum {
|
||||
OTGSC_VBUS_DISCHARGE = TU_BIT(0),
|
||||
OTGSC_VBUS_CHARGE = TU_BIT(1),
|
||||
// OTGSC_HWASSIST_AUTORESET = TU_BIT(2),
|
||||
OTGSC_OTG_TERMINATION = TU_BIT(3), ///< Must set to 1 when OTG go to device mode
|
||||
OTGSC_DATA_PULSING = TU_BIT(4),
|
||||
OTGSC_ID_PULLUP = TU_BIT(5),
|
||||
// OTGSC_HWASSIT_DATA_PULSE = TU_BIT(6),
|
||||
// OTGSC_HWASSIT_BDIS_ACONN = TU_BIT(7),
|
||||
OTGSC_ID = TU_BIT(8), ///< 0 = A device, 1 = B Device
|
||||
OTGSC_A_VBUS_VALID = TU_BIT(9),
|
||||
OTGSC_A_SESSION_VALID = TU_BIT(10),
|
||||
OTGSC_B_SESSION_VALID = TU_BIT(11),
|
||||
OTGSC_B_SESSION_END = TU_BIT(12),
|
||||
OTGSC_1MS_TOGGLE = TU_BIT(13),
|
||||
OTGSC_DATA_BUS_PULSING_STATUS = TU_BIT(14),
|
||||
};
|
||||
|
||||
// USBMode
|
||||
enum {
|
||||
USBMODE_CM_DEVICE = 2,
|
||||
USBMODE_CM_HOST = 3,
|
||||
|
||||
USBMODE_SLOM = TU_BIT(3),
|
||||
USBMODE_SDIS = TU_BIT(4),
|
||||
|
||||
USBMODE_VBUS_POWER_SELCT = TU_BIT(5), // Enable for LPC18XX/43XX in host most only
|
||||
};
|
||||
|
||||
// Device Registers
|
||||
typedef struct
|
||||
{
|
||||
//------------- ID + HW Parameter Registers-------------//
|
||||
__I uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX
|
||||
|
||||
//------------- Capability Registers-------------//
|
||||
__I uint8_t CAPLENGTH; ///< Capability Registers Length
|
||||
__I uint8_t TU_RESERVED[1];
|
||||
__I uint16_t HCIVERSION; ///< Host Controller Interface Version
|
||||
|
||||
__I uint32_t HCSPARAMS; ///< Host Controller Structural Parameters
|
||||
__I uint32_t HCCPARAMS; ///< Host Controller Capability Parameters
|
||||
__I uint32_t TU_RESERVED[5];
|
||||
|
||||
__I uint16_t DCIVERSION; ///< Device Controller Interface Version
|
||||
__I uint8_t TU_RESERVED[2];
|
||||
|
||||
__I uint32_t DCCPARAMS; ///< Device Controller Capability Parameters
|
||||
__I uint32_t TU_RESERVED[6];
|
||||
|
||||
//------------- Operational Registers -------------//
|
||||
__IO uint32_t USBCMD; ///< USB Command Register
|
||||
__IO uint32_t USBSTS; ///< USB Status Register
|
||||
__IO uint32_t USBINTR; ///< Interrupt Enable Register
|
||||
__IO uint32_t FRINDEX; ///< USB Frame Index
|
||||
__I uint32_t TU_RESERVED;
|
||||
__IO uint32_t DEVICEADDR; ///< Device Address
|
||||
__IO uint32_t ENDPTLISTADDR; ///< Endpoint List Address
|
||||
__I uint32_t TU_RESERVED;
|
||||
__IO uint32_t BURSTSIZE; ///< Programmable Burst Size
|
||||
__IO uint32_t TXFILLTUNING; ///< TX FIFO Fill Tuning
|
||||
uint32_t TU_RESERVED[4];
|
||||
__IO uint32_t ENDPTNAK; ///< Endpoint NAK
|
||||
__IO uint32_t ENDPTNAKEN; ///< Endpoint NAK Enable
|
||||
__I uint32_t TU_RESERVED;
|
||||
__IO uint32_t PORTSC1; ///< Port Status & Control
|
||||
__I uint32_t TU_RESERVED[7];
|
||||
__IO uint32_t OTGSC; ///< On-The-Go Status & control
|
||||
__IO uint32_t USBMODE; ///< USB Device Mode
|
||||
__IO uint32_t ENDPTSETUPSTAT; ///< Endpoint Setup Status
|
||||
__IO uint32_t ENDPTPRIME; ///< Endpoint Prime
|
||||
__IO uint32_t ENDPTFLUSH; ///< Endpoint Flush
|
||||
__I uint32_t ENDPTSTAT; ///< Endpoint Status
|
||||
__IO uint32_t ENDPTCOMPLETE; ///< Endpoint Complete
|
||||
__IO uint32_t ENDPTCTRL[8]; ///< Endpoint Control 0 - 7
|
||||
} dcd_registers_t;
|
||||
|
||||
|
||||
// Queue Transfer Descriptor
|
||||
typedef struct
|
||||
{
|
||||
@ -280,7 +181,7 @@ CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048)
|
||||
static dcd_data_t _dcd_data;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// CONTROLLER API
|
||||
// Controller API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
/// follows LPC43xx User Manual 23.10.3
|
||||
|
127
src/portable/nxp/transdimension/hcd_transdimension.c
Normal file
127
src/portable/nxp/transdimension/hcd_transdimension.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
// NXP Trans-Dimension USB IP implement EHCI for host functionality
|
||||
|
||||
#if TUSB_OPT_HOST_ENABLED && \
|
||||
(CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INCLUDE
|
||||
//--------------------------------------------------------------------+
|
||||
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
|
||||
#include "fsl_device_registers.h"
|
||||
#else
|
||||
// LPCOpen for 18xx & 43xx
|
||||
#include "chip.h"
|
||||
#endif
|
||||
|
||||
#include "common/tusb_common.h"
|
||||
#include "common_transdimension.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// TODO can be merged with dcd_controller_t
|
||||
typedef struct
|
||||
{
|
||||
uint32_t regs_base; // registers base
|
||||
const IRQn_Type irqnum; // IRQ number
|
||||
}hcd_controller_t;
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
|
||||
static const hcd_controller_t _hcd_controller[] =
|
||||
{
|
||||
// RT1010 and RT1020 only has 1 USB controller
|
||||
#if FSL_FEATURE_SOC_USBHS_COUNT == 1
|
||||
{ .regs_base = USB_BASE , .irqnum = USB_OTG1_IRQn }
|
||||
#else
|
||||
{ .regs_base = USB1_BASE, .irqnum = USB_OTG1_IRQn },
|
||||
{ .regs_base = USB2_BASE, .irqnum = USB_OTG2_IRQn }
|
||||
#endif
|
||||
};
|
||||
|
||||
#else
|
||||
static const hcd_controller_t _hcd_controller[] =
|
||||
{
|
||||
{ .regs_base = LPC_USB0_BASE, .irqnum = USB0_IRQn },
|
||||
{ .regs_base = LPC_USB1_BASE, .irqnum = USB1_IRQn }
|
||||
};
|
||||
#endif
|
||||
|
||||
// TODO better prototype later
|
||||
extern bool hcd_ehci_init (uint8_t rhport); // from ehci.c
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Controller API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
bool hcd_init(uint8_t rhport)
|
||||
{
|
||||
dcd_registers_t* dcd_reg = (dcd_registers_t*) _hcd_controller[rhport].regs_base;
|
||||
|
||||
// Reset controller
|
||||
dcd_reg->USBCMD |= USBCMD_RESET;
|
||||
while( dcd_reg->USBCMD & USBCMD_RESET ) {}
|
||||
|
||||
// Set mode to device, must be set immediately after reset
|
||||
#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX
|
||||
// LPC18XX/43XX need to set VBUS Power Select to HIGH
|
||||
// RHPORT1 is fullspeed only (need external PHY for Highspeed)
|
||||
dcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT;
|
||||
if (rhport == 1) dcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
|
||||
#else
|
||||
dcd_reg->USBMODE = USBMODE_CM_HOST;
|
||||
#endif
|
||||
|
||||
// FIXME force full speed, still have issue with Highspeed enumeration
|
||||
dcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
|
||||
|
||||
return hcd_ehci_init(rhport);
|
||||
}
|
||||
|
||||
void hcd_int_enable(uint8_t rhport)
|
||||
{
|
||||
NVIC_EnableIRQ(_hcd_controller[rhport].irqnum);
|
||||
}
|
||||
|
||||
void hcd_int_disable(uint8_t rhport)
|
||||
{
|
||||
NVIC_DisableIRQ(_hcd_controller[rhport].irqnum);
|
||||
}
|
||||
|
||||
uint32_t hcd_ehci_register_addr(uint8_t rhport)
|
||||
{
|
||||
dcd_registers_t* hcd_reg = (dcd_registers_t*) _hcd_controller[rhport].regs_base;
|
||||
|
||||
// EHCI USBCMD has same address within dcd_register_t
|
||||
return (uint32_t) &hcd_reg->USBCMD;
|
||||
}
|
||||
|
||||
#endif
|
@ -26,14 +26,16 @@
|
||||
|
||||
#include <common/tusb_common.h>
|
||||
|
||||
#if TUSB_OPT_HOST_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX)
|
||||
#if TUSB_OPT_HOST_ENABLED && \
|
||||
(CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC40XX)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INCLUDE
|
||||
//--------------------------------------------------------------------+
|
||||
#include "osal/osal.h"
|
||||
|
||||
#include "../hcd.h"
|
||||
#include "../usbh_hcd.h"
|
||||
#include "host/hcd.h"
|
||||
#include "host/usbh_hcd.h"
|
||||
#include "ohci.h"
|
||||
|
||||
// TODO remove
|
||||
@ -141,8 +143,10 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr);
|
||||
// USBH-HCD API
|
||||
//--------------------------------------------------------------------+
|
||||
// Initialization according to 5.1.1.4
|
||||
bool hcd_init(void)
|
||||
bool hcd_init(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
//------------- Data Structure init -------------//
|
||||
tu_memclr(&ohci_data, sizeof(ohci_data_t));
|
||||
for(uint8_t i=0; i<32; i++)
|
@ -37,8 +37,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/tusb_common.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// OHCI CONFIGURATION & CONSTANTS
|
||||
//--------------------------------------------------------------------+
|
Loading…
x
Reference in New Issue
Block a user