|
|
@@ -47,20 +47,17 @@
|
|
|
|
//--------------------------------------------------------------------+
|
|
|
|
//--------------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
// Board code will determine the state of VBUS from USB host.
|
|
|
|
// 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.
|
|
|
|
// Static array to store an incoming SETUP request for processing by tinyusb.
|
|
|
|
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
|
|
|
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.
|
|
|
|
struct ft9xx_xfer_state
|
|
|
|
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
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
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.
|
|
|
|
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 total_size; // Total transfer size in bytes for this transfer.
|
|
|
|
int16_t remain_size; // Total remaining in transfer.
|
|
|
|
int16_t remain_size; // Total remaining in transfer.
|
|
|
|
uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to.
|
|
|
|
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.
|
|
|
|
uint16_t size; // Max packet size for endpoint from endpoint descriptor.
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Endpoint description array for each endpoint.
|
|
|
|
// 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.
|
|
|
|
// USB speed.
|
|
|
|
static tusb_speed_t _speed;
|
|
|
|
static tusb_speed_t _speed;
|
|
|
|
|
|
|
|
|
|
|
|
// Interrupt handlers.
|
|
|
|
// Interrupt handlers.
|
|
|
|
void _ft90x_usbd_ISR(void); // Interrupt handler for USB device.
|
|
|
|
void _ft9xx_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_pm_ISR(void); // Interrupt handler for USB device for power management (called by board).
|
|
|
|
|
|
|
|
|
|
|
|
// Internal functions forward declarations.
|
|
|
|
// 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 _ft9xx_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 uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes);
|
|
|
|
static void _ft90x_reset_edpts(void);
|
|
|
|
static void _ft9xx_reset_edpts(void);
|
|
|
|
static inline void _ft90x_phy_enable(bool en);
|
|
|
|
static inline void _ft9xx_phy_enable(bool en);
|
|
|
|
static void _ft90x_usb_speed(void);
|
|
|
|
static void _ft9xx_usb_speed(void);
|
|
|
|
static void _dcd_ft90x_attach(void);
|
|
|
|
static void _dcd_ft9xx_attach(void);
|
|
|
|
static void _dcd_ft90x_detach(void) __attribute__((unused));
|
|
|
|
static void _dcd_ft9xx_detach(void) __attribute__((unused));
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
// Internal functions.
|
|
|
|
// 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.
|
|
|
|
// This can be up-to the maximum packet size of the endpoint.
|
|
|
|
// Continuation of a transfer beyond the maximum packet size is performed
|
|
|
|
// Continuation of a transfer beyond the maximum packet size is performed
|
|
|
|
// by the interrupt handler.
|
|
|
|
// 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.
|
|
|
|
//Note: this is called from only the interrupt handler when an OUT transfer is called.
|
|
|
|
uint16_t ep_size = ep_xfer[ep_number].size;
|
|
|
|
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
|
|
|
|
// 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)
|
|
|
|
if (ep_number == USBD_EP_0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Set flags to indicate data ready.
|
|
|
|
// 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.
|
|
|
|
// This can be up-to the maximum packet size of the endpoint.
|
|
|
|
// Continuation of a transfer beyond the maximum packet size is performed
|
|
|
|
// Continuation of a transfer beyond the maximum packet size is performed
|
|
|
|
// by the interrupt handler.
|
|
|
|
// 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.
|
|
|
|
//Note: this may be called from the interrupt handler or from normal code.
|
|
|
|
uint8_t end = 0;
|
|
|
|
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)
|
|
|
|
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.
|
|
|
|
// Reset all non-control endpoints to a default state.
|
|
|
|
// Control endpoint is always enabled and ready. All others disabled.
|
|
|
|
// 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.
|
|
|
|
// Disable all endpoints and remove configuration values.
|
|
|
|
for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++)
|
|
|
|
for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Clear settings.
|
|
|
|
// Clear settings.
|
|
|
|
tu_memclr(&ep_xfer[i], sizeof(struct ft90x_xfer_state));
|
|
|
|
tu_memclr(&ep_xfer[i], sizeof(struct ft9xx_xfer_state));
|
|
|
|
// Disable hardware.
|
|
|
|
// Disable hardware.
|
|
|
|
USBD_EP_CR_REG(i) = 0;
|
|
|
|
USBD_EP_CR_REG(i) = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -209,7 +206,7 @@ static void _ft90x_reset_edpts(void)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Enable or disable the USB PHY.
|
|
|
|
// Enable or disable the USB PHY.
|
|
|
|
static inline void _ft90x_phy_enable(bool en)
|
|
|
|
static inline void _ft9xx_phy_enable(bool en)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (en)
|
|
|
|
if (en)
|
|
|
|
SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_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.
|
|
|
|
// Safely connect to the USB.
|
|
|
|
static void _dcd_ft90x_attach(void)
|
|
|
|
static void _dcd_ft9xx_attach(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint8_t reg;
|
|
|
|
uint8_t reg;
|
|
|
|
|
|
|
|
|
|
|
@@ -274,7 +271,7 @@ static void _dcd_ft90x_attach(void)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Gracefully disconnect from the USB.
|
|
|
|
// Gracefully disconnect from the USB.
|
|
|
|
static void _dcd_ft90x_detach(void)
|
|
|
|
static void _dcd_ft9xx_detach(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Disable device connect/disconnect/host reset detection.
|
|
|
|
// Disable device connect/disconnect/host reset detection.
|
|
|
|
SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN);
|
|
|
|
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.
|
|
|
|
// Determine the speed of the USB to which we are connected.
|
|
|
|
// Set the speed of the PHY accordingly.
|
|
|
|
// Set the speed of the PHY accordingly.
|
|
|
|
// High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings.
|
|
|
|
// 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;
|
|
|
|
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
|
|
|
|
// 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.
|
|
|
|
// to the FIFO. The is no reason to not stream.
|
|
|
|
// The total number of bytes sent to the FIFO is returned.
|
|
|
|
// 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 bytes_read = 0;
|
|
|
|
uint16_t buff_size = length;
|
|
|
|
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
|
|
|
|
// 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.
|
|
|
|
// to the buffer. The is no reason to not stream.
|
|
|
|
// The total number of bytes received from the FIFO is returned.
|
|
|
|
// 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
|
|
|
|
#ifdef USBD_USE_STREAMS
|
|
|
|
volatile uint8_t *data_reg;
|
|
|
|
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
|
|
|
|
// Initialize controller to device mode
|
|
|
|
void dcd_init(uint8_t rhport)
|
|
|
|
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);
|
|
|
|
dcd_connect(rhport);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -527,7 +524,7 @@ void dcd_init(uint8_t rhport)
|
|
|
|
void dcd_int_enable(uint8_t rhport)
|
|
|
|
void dcd_int_enable(uint8_t rhport)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)rhport;
|
|
|
|
(void)rhport;
|
|
|
|
TU_LOG3("FT90x int enable\r\n");
|
|
|
|
TU_LOG3("FT9xx int enable\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
// Peripheral devices interrupt enable.
|
|
|
|
// Peripheral devices interrupt enable.
|
|
|
|
interrupt_enable_globally();
|
|
|
|
interrupt_enable_globally();
|
|
|
@@ -537,7 +534,7 @@ void dcd_int_enable(uint8_t rhport)
|
|
|
|
void dcd_int_disable(uint8_t rhport)
|
|
|
|
void dcd_int_disable(uint8_t rhport)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)rhport;
|
|
|
|
(void)rhport;
|
|
|
|
TU_LOG3("FT90x int disable\r\n");
|
|
|
|
TU_LOG3("FT9xx int disable\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
// Peripheral devices interrupt disable.
|
|
|
|
// Peripheral devices interrupt disable.
|
|
|
|
interrupt_disable_globally();
|
|
|
|
interrupt_disable_globally();
|
|
|
@@ -603,18 +600,18 @@ void dcd_remote_wakeup(uint8_t rhport)
|
|
|
|
void dcd_connect(uint8_t rhport)
|
|
|
|
void dcd_connect(uint8_t rhport)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)rhport;
|
|
|
|
(void)rhport;
|
|
|
|
TU_LOG2("FT90x connect\r\n");
|
|
|
|
TU_LOG2("FT9xx connect\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
CRITICAL_SECTION_BEGIN
|
|
|
|
CRITICAL_SECTION_BEGIN
|
|
|
|
// Is device connected?
|
|
|
|
// Is device connected?
|
|
|
|
if (board_ft90x_vbus())
|
|
|
|
if (board_ft9xx_vbus())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Clear/disable address register.
|
|
|
|
// Clear/disable address register.
|
|
|
|
USBD_REG(faddr) = 0;
|
|
|
|
USBD_REG(faddr) = 0;
|
|
|
|
_ft90x_phy_enable(true);
|
|
|
|
_ft9xx_phy_enable(true);
|
|
|
|
|
|
|
|
|
|
|
|
// Determine bus speed and signal speed to tusb.
|
|
|
|
// Determine bus speed and signal speed to tusb.
|
|
|
|
_ft90x_usb_speed();
|
|
|
|
_ft9xx_usb_speed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Setup the control endpoint only.
|
|
|
|
// Setup the control endpoint only.
|
|
|
@@ -639,17 +636,17 @@ void dcd_connect(uint8_t rhport)
|
|
|
|
USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE);
|
|
|
|
USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE);
|
|
|
|
|
|
|
|
|
|
|
|
// Restore default endpoint state.
|
|
|
|
// Restore default endpoint state.
|
|
|
|
_ft90x_reset_edpts();
|
|
|
|
_ft9xx_reset_edpts();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Disconnect by disabling internal pull-up resistor on D+/D-
|
|
|
|
// Disconnect by disabling internal pull-up resistor on D+/D-
|
|
|
|
void dcd_disconnect(uint8_t rhport)
|
|
|
|
void dcd_disconnect(uint8_t rhport)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)rhport;
|
|
|
|
(void)rhport;
|
|
|
|
TU_LOG2("FT90x disconnect\r\n");
|
|
|
|
TU_LOG2("FT9xx disconnect\r\n");
|
|
|
|
|
|
|
|
|
|
|
|
// Disable the USB PHY.
|
|
|
|
// Disable the USB PHY.
|
|
|
|
_ft90x_phy_enable(false);
|
|
|
|
_ft9xx_phy_enable(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void dcd_sof_enable(uint8_t rhport, bool en)
|
|
|
|
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;
|
|
|
|
uint8_t ep_reg_data = 0;
|
|
|
|
int16_t total_ram;
|
|
|
|
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.
|
|
|
|
// Check that the requested endpoint number is allowable.
|
|
|
|
if (ep_number >= USBD_MAX_ENDPOINT_COUNT)
|
|
|
|
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;
|
|
|
|
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)
|
|
|
|
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;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Calculate actual amount of buffer RAM used by this endpoint. This may be more than the
|
|
|
|
// 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)
|
|
|
|
if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// This could be because an endpoint has been assigned with the same number.
|
|
|
|
// 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.
|
|
|
|
// 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;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -723,7 +720,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
total_ram = USBD_RAMTOTAL_OUT;
|
|
|
|
total_ram = USBD_RAMTOTAL_OUT;
|
|
|
|
// Work out how much has been allocated to existing endpoints.
|
|
|
|
// 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.
|
|
|
|
// algorithm should not let it go below zero.
|
|
|
|
for (int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++)
|
|
|
|
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
|
|
|
|
// 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
|
|
|
|
// free which means that total_ram must be signed as zero bytes free is
|
|
|
|
// allowable.
|
|
|
|
// allowable.
|
|
|
|
if (total_ram < ep_buff_size)
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
//ep_reg_data |= MASK_USBD_EPxCR_DB;
|
|
|
|
// Set the control endpoint for this endpoint.
|
|
|
|
// Set the control endpoint for this endpoint.
|
|
|
|
USBD_EP_CR_REG(ep_number) = ep_reg_data;
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
ep_xfer[ep_number].buff_size = ep_buff_size;
|
|
|
|
|
|
|
|
|
|
|
|
// Clear register transaction continuation and signalling state.
|
|
|
|
// Clear register transaction continuation and signalling state.
|
|
|
|
|
|
|
|
ep_xfer[ep_number].ready = 0;
|
|
|
|
ep_xfer[ep_number].valid = 0;
|
|
|
|
ep_xfer[ep_number].valid = 0;
|
|
|
|
ep_xfer[ep_number].buff_ptr = NULL;
|
|
|
|
ep_xfer[ep_number].buff_ptr = NULL;
|
|
|
|
ep_xfer[ep_number].total_size = 0;
|
|
|
|
ep_xfer[ep_number].total_size = 0;
|
|
|
@@ -791,7 +794,7 @@ void dcd_edpt_close_all(uint8_t rhport)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
(void)rhport;
|
|
|
|
(void)rhport;
|
|
|
|
// Reset the endpoint configurations.
|
|
|
|
// 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
|
|
|
|
// 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;
|
|
|
|
(void)rhport;
|
|
|
|
uint8_t ep_number = tu_edpt_number(ep_addr);
|
|
|
|
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;
|
|
|
|
uint16_t xfer_bytes;
|
|
|
|
bool status = false;
|
|
|
|
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 is used to tell the interrupt handler what to do.
|
|
|
|
// ep_xfer can be used at interrupt level to continue transfers.
|
|
|
|
// ep_xfer can be used at interrupt level to continue transfers.
|
|
|
|
CRITICAL_SECTION_BEGIN
|
|
|
|
CRITICAL_SECTION_BEGIN
|
|
|
|
|
|
|
|
|
|
|
|
// Transfer currently in progress.
|
|
|
|
// Transfer currently in progress.
|
|
|
|
if (ep_xfer[ep_number].valid == 0)
|
|
|
|
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)
|
|
|
|
if (ep_number == USBD_EP_0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ep_xfer[USBD_EP_0].dir = dir;
|
|
|
|
ep_xfer[USBD_EP_0].dir = ep_dir;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
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
|
|
|
|
// For IN transfers send the first packet as a starter. Interrupt handler to complete
|
|
|
|
// this if it is larger than one packet.
|
|
|
|
// 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].buff_ptr += xfer_bytes;
|
|
|
|
ep_xfer[ep_number].remain_size -= 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.
|
|
|
|
// Tell the interrupt handler to signal dcd_event_xfer_complete on completion.
|
|
|
|
ep_xfer[ep_number].valid = 1;
|
|
|
|
ep_xfer[ep_number].valid = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else // (dir == TUSB_DIR_OUT)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// For OUT transfers on the control endpoint.
|
|
|
|
// For OUT transfers on the control endpoint.
|
|
|
|
// The host may already have performed the first data transfer after the SETUP packet
|
|
|
|
// The host may already have performed the first data transfer after the SETUP packet
|
|
|
|
// before the transfer is setup for it.
|
|
|
|
// 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
|
|
|
|
// We have received a data packet on the endpoint without a transfer
|
|
|
|
// immediately.
|
|
|
|
// being initialised. This can be because the host has sent this packet before
|
|
|
|
memcpy(buffer, _ft90x_ctrl_buf, _ft90x_ctrl_buf_complete);
|
|
|
|
// a new transfer has been initiated on the endpoint.
|
|
|
|
dcd_event_xfer_complete(BOARD_TUD_RHPORT, TUSB_DIR_OUT, _ft90x_ctrl_buf_complete, XFER_RESULT_SUCCESS, false);
|
|
|
|
// 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
|
|
|
|
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;
|
|
|
|
ep_xfer[ep_number].valid = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
status = true;
|
|
|
|
status = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// Note: should not arrive here.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CRITICAL_SECTION_END
|
|
|
|
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;
|
|
|
|
USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE;
|
|
|
|
|
|
|
|
|
|
|
|
// Allow transfers to restart.
|
|
|
|
// Allow transfers to restart.
|
|
|
|
|
|
|
|
ep_xfer[ep_number].ready = 0;
|
|
|
|
ep_xfer[ep_number].valid = 0;
|
|
|
|
ep_xfer[ep_number].valid = 0;
|
|
|
|
ep_xfer[ep_number].remain_size = 0;
|
|
|
|
ep_xfer[ep_number].remain_size = 0;
|
|
|
|
CRITICAL_SECTION_END
|
|
|
|
CRITICAL_SECTION_END
|
|
|
@@ -920,7 +936,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
|
|
|
|
|
|
|
|
|
|
|
// Interrupt handling.
|
|
|
|
// Interrupt handling.
|
|
|
|
|
|
|
|
|
|
|
|
void _ft90x_usbd_ISR(void)
|
|
|
|
void _ft9xx_usbd_ISR(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
dcd_int_handler(BOARD_TUD_RHPORT);
|
|
|
|
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
|
|
|
|
if (cmif & MASK_USBD_CMIF_RSTIRQ) //Handle Reset interrupt
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Reset endpoints to default state.
|
|
|
|
// Reset endpoints to default state.
|
|
|
|
_ft90x_reset_edpts();
|
|
|
|
_ft9xx_reset_edpts();
|
|
|
|
dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true);
|
|
|
|
dcd_event_bus_reset(BOARD_TUD_RHPORT, _speed, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cmif & MASK_USBD_CMIF_SUSIRQ) //Handle Suspend interrupt
|
|
|
|
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.
|
|
|
|
// 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.
|
|
|
|
// 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.
|
|
|
|
// Clear the interrupt that signals a SETUP packet is received.
|
|
|
|
USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP);
|
|
|
|
USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP);
|
|
|
|
|
|
|
|
|
|
|
|
// Invalidate cache packet.
|
|
|
|
// Any SETUP packet will clear the incoming FIFO.
|
|
|
|
_ft90x_ctrl_buf_complete = 0;
|
|
|
|
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;
|
|
|
|
ep_xfer[USBD_EP_0].valid = 0;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1024,35 +1040,28 @@ void dcd_int_handler(uint8_t rhport)
|
|
|
|
// Transfer incoming data from an OUT packet to the buffer supplied.
|
|
|
|
// Transfer incoming data from an OUT packet to the buffer supplied.
|
|
|
|
if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT)
|
|
|
|
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.
|
|
|
|
// 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.
|
|
|
|
// Incoming FIFO has been cleared.
|
|
|
|
_ft90x_ctrl_buf_complete = 0;
|
|
|
|
ep_xfer[USBD_EP_0].ready = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// Allow new transfers on the control endpoint.
|
|
|
|
// Allow new transfers on the control endpoint.
|
|
|
|
ep_xfer[USBD_EP_0].valid = 0;
|
|
|
|
ep_xfer[USBD_EP_0].valid = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No transfer is in flight for EP0.
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// We have received a data packet on the control endpoint without a transfer
|
|
|
|
// 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
|
|
|
|
// being initialised. This can be because the host has sent this packet before
|
|
|
|
// a new transfer has been initiated on the control endpoint.
|
|
|
|
// a new transfer has been initiated on the control endpoint.
|
|
|
|
// We will cache upto the maximum packet size for the control endpoint and
|
|
|
|
// We will record that there is data in the FIFO for dcd_edpt_xfer to obtain
|
|
|
|
// use it later in dcd_edpt_xfer.
|
|
|
|
// once the transfer is initiated.
|
|
|
|
xfer_bytes = CFG_TUD_ENDPOINT0_SIZE;
|
|
|
|
ep_xfer[USBD_EP_0].ready = 1;
|
|
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
else // !(epif & MASK_USBD_EPIF_EP0IRQ)
|
|
|
@@ -1072,7 +1081,6 @@ void dcd_int_handler(uint8_t rhport)
|
|
|
|
if (ep_xfer[ep_number].valid)
|
|
|
|
if (ep_xfer[ep_number].valid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
xfer_bytes = 0;
|
|
|
|
xfer_bytes = 0;
|
|
|
|
uint8_t ep_dirmask = (ep_xfer[ep_number].dir ? TUSB_DIR_IN_MASK : 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clear interrupt register for this endpoint.
|
|
|
|
// Clear interrupt register for this endpoint.
|
|
|
|
USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number);
|
|
|
|
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.
|
|
|
|
// Start or continue an OUT transfer.
|
|
|
|
if (ep_xfer[ep_number].dir == TUSB_DIR_OUT)
|
|
|
|
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,
|
|
|
|
ep_xfer[ep_number].buff_ptr,
|
|
|
|
(uint16_t)ep_xfer[ep_number].remain_size);
|
|
|
|
(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].buff_ptr += xfer_bytes;
|
|
|
|
ep_xfer[ep_number].remain_size -= 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)
|
|
|
|
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,
|
|
|
|
ep_xfer[ep_number].buff_ptr,
|
|
|
|
(uint16_t)ep_xfer[ep_number].remain_size);
|
|
|
|
(uint16_t)ep_xfer[ep_number].remain_size);
|
|
|
|
|
|
|
|
|
|
|
|
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
|
|
|
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
|
|
|
ep_xfer[ep_number].remain_size -= 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...
|
|
|
|
// When the transfer is complete...
|
|
|
|
if (ep_xfer[ep_number].remain_size == 0)
|
|
|
|
if (ep_xfer[ep_number].remain_size == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Signal tinyUSB.
|
|
|
|
// Finish this transfer and allow new transfers on this endpoint.
|
|
|
|
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.
|
|
|
|
|
|
|
|
ep_xfer[ep_number].valid = 0;
|
|
|
|
ep_xfer[ep_number].valid = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// Disable the interrupt for this endpoint now it is complete.
|
|
|
|
// Disable the interrupt for this endpoint now it is complete.
|
|
|
|
USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number));
|
|
|
|
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.
|
|
|
|
// Power management interrupt handler.
|
|
|
|
// This handles USB device related power management interrupts only.
|
|
|
|
// 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;
|
|
|
|
uint16_t pmcfg = SYS->PMCFG_H;
|
|
|
|
|
|
|
|
|
|
|
|