diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 225 |
1 files changed, 128 insertions, 97 deletions
diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 080d633fa..50f7018db 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -47,20 +47,17 @@ //--------------------------------------------------------------------+ // Board code will determine the state of VBUS from USB host. -extern int8_t board_ft90x_vbus(void); +extern int8_t board_ft9xx_vbus(void); // Static array to store an incoming SETUP request for processing by tinyusb. CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN -static uint8_t _ft90x_setup_packet[8]; +static uint8_t _ft9xx_setup_packet[8]; -// Static array to store one SETUP DATA packet until required by dcd_edpt_xfer. -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN -static uint8_t _ft90x_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; -static uint8_t _ft90x_ctrl_buf_complete; - -struct ft90x_xfer_state +struct ft9xx_xfer_state { + volatile uint8_t ready; // OUT Transfer has been received and waiting for transfer. volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid. + int16_t total_size; // Total transfer size in bytes for this transfer. int16_t remain_size; // Total remaining in transfer. uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to. @@ -71,24 +68,24 @@ struct ft90x_xfer_state uint16_t size; // Max packet size for endpoint from endpoint descriptor. }; // Endpoint description array for each endpoint. -static struct ft90x_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT]; +static struct ft9xx_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT]; // USB speed. static tusb_speed_t _speed; // Interrupt handlers. -void _ft90x_usbd_ISR(void); // Interrupt handler for USB device. -void ft90x_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board). +void _ft9xx_usbd_ISR(void); // Interrupt handler for USB device. +void ft9xx_usbd_pm_ISR(void); // Interrupt handler for USB device for power management (called by board). // Internal functions forward declarations. -static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); -static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); -static void _ft90x_reset_edpts(void); -static inline void _ft90x_phy_enable(bool en); -static void _ft90x_usb_speed(void); -static void _dcd_ft90x_attach(void); -static void _dcd_ft90x_detach(void) __attribute__((unused)); -static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length); -static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length); +static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes); +static void _ft9xx_reset_edpts(void); +static inline void _ft9xx_phy_enable(bool en); +static void _ft9xx_usb_speed(void); +static void _dcd_ft9xx_attach(void); +static void _dcd_ft9xx_detach(void) __attribute__((unused)); +static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length); +static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length); // Internal functions. @@ -96,7 +93,7 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len // This can be up-to the maximum packet size of the endpoint. // Continuation of a transfer beyond the maximum packet size is performed // by the interrupt handler. -static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) +static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) { //Note: this is called from only the interrupt handler when an OUT transfer is called. uint16_t ep_size = ep_xfer[ep_number].size; @@ -111,7 +108,7 @@ static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_ //; // Send the first packet of max packet size - xfer_bytes = _ft90x_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); + xfer_bytes = _ft9xx_dusb_out(ep_number, (uint8_t *)buffer, xfer_bytes); if (ep_number == USBD_EP_0) { // Set flags to indicate data ready. @@ -129,7 +126,7 @@ static uint16_t _ft90x_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_ // This can be up-to the maximum packet size of the endpoint. // Continuation of a transfer beyond the maximum packet size is performed // by the interrupt handler. -static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) +static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes) { //Note: this may be called from the interrupt handler or from normal code. uint8_t end = 0; @@ -167,7 +164,7 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t } - xfer_bytes = _ft90x_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); + xfer_bytes = _ft9xx_dusb_in(ep_number, (uint8_t *)buffer, xfer_bytes); if (ep_number == USBD_EP_0) { @@ -193,13 +190,13 @@ static uint16_t _ft90x_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t // Reset all non-control endpoints to a default state. // Control endpoint is always enabled and ready. All others disabled. -static void _ft90x_reset_edpts(void) +static void _ft9xx_reset_edpts(void) { // Disable all endpoints and remove configuration values. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { // Clear settings. - tu_memclr(&ep_xfer[i], sizeof(struct ft90x_xfer_state)); + tu_memclr(&ep_xfer[i], sizeof(struct ft9xx_xfer_state)); // Disable hardware. USBD_EP_CR_REG(i) = 0; } @@ -209,7 +206,7 @@ static void _ft90x_reset_edpts(void) } // Enable or disable the USB PHY. -static inline void _ft90x_phy_enable(bool en) +static inline void _ft9xx_phy_enable(bool en) { if (en) SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN; @@ -218,7 +215,7 @@ static inline void _ft90x_phy_enable(bool en) } // Safely connect to the USB. -static void _dcd_ft90x_attach(void) +static void _dcd_ft9xx_attach(void) { uint8_t reg; @@ -274,7 +271,7 @@ static void _dcd_ft90x_attach(void) } // Gracefully disconnect from the USB. -static void _dcd_ft90x_detach(void) +static void _dcd_ft9xx_detach(void) { // Disable device connect/disconnect/host reset detection. SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN); @@ -316,7 +313,7 @@ static void _dcd_ft90x_detach(void) // Determine the speed of the USB to which we are connected. // Set the speed of the PHY accordingly. // High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings. -static void _ft90x_usb_speed(void) +static void _ft9xx_usb_speed(void) { uint8_t fctrl_val; @@ -379,7 +376,7 @@ static void _ft90x_usb_speed(void) // If streaming is disabled then it will send each byte of the buffer in turn // to the FIFO. The is no reason to not stream. // The total number of bytes sent to the FIFO is returned. -static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length) +static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length) { uint16_t bytes_read = 0; uint16_t buff_size = length; @@ -436,7 +433,7 @@ static uint16_t _ft90x_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_ // If streaming is disabled then it will receive each byte from the FIFO in turn // to the buffer. The is no reason to not stream. // The total number of bytes received from the FIFO is returned. -static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length) +static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length) { #ifdef USBD_USE_STREAMS volatile uint8_t *data_reg; @@ -514,11 +511,11 @@ static uint16_t _ft90x_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len // Initialize controller to device mode void dcd_init(uint8_t rhport) { - TU_LOG2("FT90x initialisation\r\n"); + TU_LOG2("FT9xx initialisation\r\n"); - _dcd_ft90x_attach(); + _dcd_ft9xx_attach(); - interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft90x_usbd_ISR); + interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft9xx_usbd_ISR); dcd_connect(rhport); } @@ -527,7 +524,7 @@ void dcd_init(uint8_t rhport) void dcd_int_enable(uint8_t rhport) { (void)rhport; - TU_LOG3("FT90x int enable\r\n"); + TU_LOG3("FT9xx int enable\r\n"); // Peripheral devices interrupt enable. interrupt_enable_globally(); @@ -537,7 +534,7 @@ void dcd_int_enable(uint8_t rhport) void dcd_int_disable(uint8_t rhport) { (void)rhport; - TU_LOG3("FT90x int disable\r\n"); + TU_LOG3("FT9xx int disable\r\n"); // Peripheral devices interrupt disable. interrupt_disable_globally(); @@ -603,18 +600,18 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { (void)rhport; - TU_LOG2("FT90x connect\r\n"); + TU_LOG2("FT9xx connect\r\n"); CRITICAL_SECTION_BEGIN // Is device connected? - if (board_ft90x_vbus()) + if (board_ft9xx_vbus()) { // Clear/disable address register. USBD_REG(faddr) = 0; - _ft90x_phy_enable(true); + _ft9xx_phy_enable(true); // Determine bus speed and signal speed to tusb. - _ft90x_usb_speed(); + _ft9xx_usb_speed(); } // Setup the control endpoint only. @@ -639,17 +636,17 @@ void dcd_connect(uint8_t rhport) USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE); // Restore default endpoint state. - _ft90x_reset_edpts(); + _ft9xx_reset_edpts(); } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { (void)rhport; - TU_LOG2("FT90x disconnect\r\n"); + TU_LOG2("FT9xx disconnect\r\n"); // Disable the USB PHY. - _ft90x_phy_enable(false); + _ft9xx_phy_enable(false); } void dcd_sof_enable(uint8_t rhport, bool en) @@ -677,12 +674,12 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) uint8_t ep_reg_data = 0; int16_t total_ram; - TU_LOG2("FT90x endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O'); + TU_LOG2("FT9xx endpoint open %d %c\r\n", ep_number, ep_dir?'I':'O'); // Check that the requested endpoint number is allowable. if (ep_number >= USBD_MAX_ENDPOINT_COUNT) { - TU_LOG1("FT90x endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT); + TU_LOG1("FT9xx endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT); return false; } @@ -694,7 +691,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) } if (ep_reg_size > USBD_EP_MAX_SIZE_1024) { - TU_LOG1("FT90x endpoint size not valid: requested %d max 1024\r\n", ep_size); + TU_LOG1("FT9xx endpoint size not valid: requested %d max 1024\r\n", ep_size); return false; } // Calculate actual amount of buffer RAM used by this endpoint. This may be more than the @@ -709,9 +706,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED) { // This could be because an endpoint has been assigned with the same number. - // On FT90x, IN and OUT endpoints may not have the same number. e.g. There + // On FT9xx, IN and OUT endpoints may not have the same number. e.g. There // cannot been an 0x81 and 0x01 endpoint. - TU_LOG1("FT90x endpoint %d already assigned\r\n", ep_number); + TU_LOG1("FT9xx endpoint %d already assigned\r\n", ep_number); return false; } @@ -723,7 +720,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) else total_ram = USBD_RAMTOTAL_OUT; // Work out how much has been allocated to existing endpoints. - // The total RAM allocated shoudl alsyes be a positive number as this + // The total RAM allocated should always be a positive number as this // algorithm should not let it go below zero. for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++) { @@ -735,14 +732,19 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) } } } - // The control endpoint is taken into account as well. - total_ram -= ep_xfer[0].buff_size; + + if (sys_check_ft900_revB()) + { + // The control endpoint is taken into account as well on RevB silicon. + total_ram -= ep_xfer[0].buff_size; + } + // Make sure we have enough space. The corner case is having zero bytes // free which means that total_ram must be signed as zero bytes free is // allowable. if (total_ram < ep_buff_size) { - TU_LOG1("FT90x insufficient buffer RAM for endpoint %d\r\n", ep_number); + TU_LOG1("FT9xx insufficient buffer RAM for endpoint %d\r\n", ep_number); return false; } @@ -761,7 +763,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) //ep_reg_data |= MASK_USBD_EPxCR_DB; // Set the control endpoint for this endpoint. USBD_EP_CR_REG(ep_number) = ep_reg_data; - TU_LOG2("FT90x endpoint setting %x\r\n", ep_reg_data); + TU_LOG2("FT9xx endpoint setting %x\r\n", ep_reg_data); } else { @@ -777,6 +779,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) ep_xfer[ep_number].buff_size = ep_buff_size; // Clear register transaction continuation and signalling state. + ep_xfer[ep_number].ready = 0; ep_xfer[ep_number].valid = 0; ep_xfer[ep_number].buff_ptr = NULL; ep_xfer[ep_number].total_size = 0; @@ -791,7 +794,7 @@ void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; // Reset the endpoint configurations. - _ft90x_reset_edpts(); + _ft9xx_reset_edpts(); } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack @@ -799,7 +802,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to { (void)rhport; uint8_t ep_number = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); + uint8_t ep_dir = tu_edpt_dir(ep_addr); uint16_t xfer_bytes; bool status = false; @@ -809,6 +812,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // ep_xfer is used to tell the interrupt handler what to do. // ep_xfer can be used at interrupt level to continue transfers. CRITICAL_SECTION_BEGIN + // Transfer currently in progress. if (ep_xfer[ep_number].valid == 0) { @@ -818,7 +822,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to if (ep_number == USBD_EP_0) { - ep_xfer[USBD_EP_0].dir = dir; + ep_xfer[USBD_EP_0].dir = ep_dir; } else { @@ -827,11 +831,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number); } - if (dir == TUSB_DIR_IN) + if (ep_dir == TUSB_DIR_IN) { // For IN transfers send the first packet as a starter. Interrupt handler to complete // this if it is larger than one packet. - xfer_bytes = _ft90x_edpt_xfer_in(ep_number, buffer, total_bytes); + xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, buffer, total_bytes); ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; @@ -839,26 +843,37 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to // Tell the interrupt handler to signal dcd_event_xfer_complete on completion. ep_xfer[ep_number].valid = 1; } - else + else // (dir == TUSB_DIR_OUT) { // For OUT transfers on the control endpoint. // The host may already have performed the first data transfer after the SETUP packet // before the transfer is setup for it. - if ((ep_number == USBD_EP_0) && (_ft90x_ctrl_buf_complete)) + if (ep_xfer[ep_number].ready) { - // Pull the received data packet from the packet cache and complete the transfer - // immediately. - memcpy(buffer, _ft90x_ctrl_buf, _ft90x_ctrl_buf_complete); - dcd_event_xfer_complete(BOARD_TUD_RHPORT, TUSB_DIR_OUT, _ft90x_ctrl_buf_complete, XFER_RESULT_SUCCESS, false); + // We have received a data packet on the endpoint without a transfer + // being initialised. This can be because the host has sent this packet before + // a new transfer has been initiated on the endpoint. + // We will now stream the data from the FIFO. + ep_xfer[ep_number].ready = 0; + + // Transfer incoming data from an OUT packet to the buffer. + xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, buffer, total_bytes); + // Report completion of the transfer. + dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number /*| TUSB_DIR_OUT_MASK */, xfer_bytes, XFER_RESULT_SUCCESS, false); } else { - // Tell the interrupt handler to wait for the packet to be received. + // Tell the interrupt handler to wait for the packet to be received and + // then report the transfer complete with dcd_event_xfer_complete. ep_xfer[ep_number].valid = 1; } } status = true; } + else + { + // Note: should not arrive here. + } CRITICAL_SECTION_END @@ -912,6 +927,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE; // Allow transfers to restart. + ep_xfer[ep_number].ready = 0; ep_xfer[ep_number].valid = 0; ep_xfer[ep_number].remain_size = 0; CRITICAL_SECTION_END @@ -920,7 +936,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) // Interrupt handling. -void _ft90x_usbd_ISR(void) +void _ft9xx_usbd_ISR(void) { dcd_int_handler(BOARD_TUD_RHPORT); } @@ -959,7 +975,7 @@ void dcd_int_handler(uint8_t rhport) if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt { // Reset endpoints to default state. - _ft90x_reset_edpts(); + _ft9xx_reset_edpts(); dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true); } if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt @@ -999,18 +1015,18 @@ void dcd_int_handler(uint8_t rhport) } // Host has sent a SETUP packet. Recieve this into the SETUP packet store. - _ft90x_dusb_out(USBD_EP_0, (uint8_t *)_ft90x_setup_packet, sizeof(USB_device_request)); + _ft9xx_dusb_out(USBD_EP_0, (uint8_t *)_ft9xx_setup_packet, sizeof(USB_device_request)); // Send the packet to tinyusb. - dcd_event_setup_received(BOARD_TUD_RHPORT, _ft90x_setup_packet, true); + dcd_event_setup_received(BOARD_TUD_RHPORT, _ft9xx_setup_packet, true); // Clear the interrupt that signals a SETUP packet is received. USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP); - // Invalidate cache packet. - _ft90x_ctrl_buf_complete = 0; + // Any SETUP packet will clear the incoming FIFO. + ep_xfer[USBD_EP_0].ready = 0; - // Allow new transfers on the control endpoint. + // Allow new DATA and ACK transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; return; } @@ -1024,35 +1040,28 @@ void dcd_int_handler(uint8_t rhport) // Transfer incoming data from an OUT packet to the buffer supplied. if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT) { - xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); + xfer_bytes = _ft9xx_edpt_xfer_out(USBD_EP_0, ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes); } // Now signal completion of data packet. - dcd_event_xfer_complete(BOARD_TUD_RHPORT, (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), xfer_bytes, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(BOARD_TUD_RHPORT, USBD_EP_0 | (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0), + xfer_bytes, XFER_RESULT_SUCCESS, true); - // Invalidate cache packet. - _ft90x_ctrl_buf_complete = 0; + // Incoming FIFO has been cleared. + ep_xfer[USBD_EP_0].ready = 0; // Allow new transfers on the control endpoint. ep_xfer[USBD_EP_0].valid = 0; } + // No transfer is in flight for EP0. else { // We have received a data packet on the control endpoint without a transfer // being initialised. This can be because the host has sent this packet before // a new transfer has been initiated on the control endpoint. - // We will cache upto the maximum packet size for the control endpoint and - // use it later in dcd_edpt_xfer. - xfer_bytes = CFG_TUD_ENDPOINT0_SIZE; - - // Transfer incoming data from an OUT packet to the cache packet. - xfer_bytes = _ft90x_edpt_xfer_out(USBD_EP_0, _ft90x_ctrl_buf, xfer_bytes); - - // Set the size of the cache packet. - _ft90x_ctrl_buf_complete = xfer_bytes; + // We will record that there is data in the FIFO for dcd_edpt_xfer to obtain + // once the transfer is initiated. + ep_xfer[USBD_EP_0].ready = 1; } - - // Clear the interrupt that signals a SETUP DATA packet is received. - USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY); } } else // !(epif & MASK_USBD_EPIF_EP0IRQ) @@ -1072,7 +1081,6 @@ void dcd_int_handler(uint8_t rhport) if (ep_xfer[ep_number].valid) { xfer_bytes = 0; - uint8_t ep_dirmask = (ep_xfer[ep_number].dir ? TUSB_DIR_IN_MASK : 0); // Clear interrupt register for this endpoint. USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number); @@ -1080,10 +1088,15 @@ void dcd_int_handler(uint8_t rhport) // Start or continue an OUT transfer. if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) { - xfer_bytes = _ft90x_edpt_xfer_out(ep_number, + xfer_bytes = _ft9xx_edpt_xfer_out(ep_number, ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); + // Report each OUT packet received to the stack. + dcd_event_xfer_complete(BOARD_TUD_RHPORT, + ep_number /* | TUSB_DIR_OUT_MASK */, + xfer_bytes, XFER_RESULT_SUCCESS, true); + ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; } @@ -1092,27 +1105,45 @@ void dcd_int_handler(uint8_t rhport) { if (ep_xfer[ep_number].remain_size > 0) { - xfer_bytes = _ft90x_edpt_xfer_in(ep_number, + xfer_bytes = _ft9xx_edpt_xfer_in(ep_number, ep_xfer[ep_number].buff_ptr, (uint16_t)ep_xfer[ep_number].remain_size); ep_xfer[ep_number].buff_ptr += xfer_bytes; ep_xfer[ep_number].remain_size -= xfer_bytes; } + + if (ep_xfer[ep_number].remain_size == 0) + { + dcd_event_xfer_complete(BOARD_TUD_RHPORT, + ep_number | TUSB_DIR_IN_MASK, + ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); + } } // When the transfer is complete... if (ep_xfer[ep_number].remain_size == 0) { - // Signal tinyUSB. - dcd_event_xfer_complete(BOARD_TUD_RHPORT, ep_number | ep_dirmask, ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true); - - // Allow new transfers on this endpoint. + // Finish this transfer and allow new transfers on this endpoint. ep_xfer[ep_number].valid = 0; // Disable the interrupt for this endpoint now it is complete. USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number)); } + + ep_xfer[ep_number].ready = 0; + } + // No OUT transfer is in flight for this endpoint. + else + { + if (ep_xfer[ep_number].dir == TUSB_DIR_OUT) + { + // We will record that there is data in the FIFO for dcd_edpt_xfer to obtain + // once the transfer is initiated. + // Strictly this should not happen for a non-control endpoint. Interrupts + // are disabled when there are no transfers setup for an endpoint. + ep_xfer[ep_number].ready = 1; + } } } } @@ -1121,7 +1152,7 @@ void dcd_int_handler(uint8_t rhport) // Power management interrupt handler. // This handles USB device related power management interrupts only. -void ft90x_usbd_pm_ISR(void) +void ft9xx_usbd_pm_ISR(void) { uint16_t pmcfg = SYS->PMCFG_H; |
