34#if CFG_TUD_ENABLED && \
35 (CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X)
39#include <registers/ft900_registers.h>
41#define USBD_USE_STREAMS
54CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
102 if (xfer_bytes > ep_size)
104 xfer_bytes = ep_size;
113 if (ep_number == USBD_EP_0)
116 USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_OPRDY);
120 USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_OPRDY);
137 if ((xfer_bytes == 0) || (xfer_bytes < ep_size))
143 xfer_bytes = ep_size;
146 if (ep_number == USBD_EP_0)
150 while (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_STALL)
153 USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_STALL);
166 sr_reg = USBD_EP_SR_REG(ep_number);
167 }
while (sr_reg & MASK_USBD_EPxSR_INPRDY);
177 if (ep_number == USBD_EP_0)
182 USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_INPRDY | MASK_USBD_EP0SR_DATAEND;
187 USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_INPRDY);
193 USBD_EP_SR_REG(ep_number) = (MASK_USBD_EPxSR_INPRDY);
204 for (
int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++)
209 USBD_EP_CR_REG(i) = 0;
213 USBD_REG(cmie) = MASK_USBD_CMIE_ALL;
220 SYS->PMCFG_L |= MASK_SYS_PMCFG_DEV_PHY_EN;
222 SYS->PMCFG_L &= ~MASK_SYS_PMCFG_DEV_PHY_EN;
230 CRITICAL_SECTION_BEGIN
235 SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL;
237 SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_DIS_DEV;
238 SYS->PMCFG_H = MASK_SYS_PMCFG_DEV_CONN_DEV;
239 SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN);
242 sys_enable(sys_device_usb_device);
243 CRITICAL_SECTION_END;
248 CRITICAL_SECTION_BEGIN
250#if BOARD_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED
254 USBD_REG(fctrl) = MASK_USBD_FCTRL_MODE_FS_ONLY;
260 reg = USBD_REG(cmif);
261 USBD_REG(cmif) = reg;
264 reg = USBD_REG(epif);
265 USBD_REG(epif) = reg;
269 CRITICAL_SECTION_END;
273 SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN;
275#if defined(__FT930__)
277 SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN;
285 SYS->PMCFG_L = SYS->PMCFG_L & (~MASK_SYS_PMCFG_DEV_DETECT_EN);
287#if defined(__FT930__)
289 SYS->MSC0CFG = SYS->MSC0CFG & (~MASK_SYS_MSC0CFG_USB_VBUS_EN);
291 CRITICAL_SECTION_BEGIN
297 CRITICAL_SECTION_END;
306 sys_disable(sys_device_usb_device);
309 SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RESET_ALL;
313 SYS->PMCFG_L = SYS->PMCFG_L | MASK_SYS_PMCFG_DEV_DETECT_EN;
315#if defined(__FT930__)
317 SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_USB_VBUS_EN;
329 if (USBD_REG(fctrl) & MASK_USBD_FCTRL_USB_DEV_EN) {
330 USBD_REG(fctrl) = (USBD_REG(fctrl) & (~MASK_USBD_FCTRL_USB_DEV_EN));
334#if BOARD_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED
337 fctrl_val = MASK_USBD_FCTRL_USB_DEV_EN;
338#if defined(__FT900__)
339 if (!sys_check_ft900_revB())
341 fctrl_val |= MASK_USBD_FCTRL_IMP_PERF;
344 USBD_REG(fctrl) = fctrl_val;
346#if defined(__FT930__)
349 _speed = (SYS->MSC0CFG & MASK_SYS_MSC0CFG_HIGH_SPED_MODE) ?
353 while (!(USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ));
354 USBD_REG(cmif) = MASK_USBD_CMIF_SOFIRQ;
356 _speed = (USBD_REG(cmif) & MASK_USBD_CMIF_SOFIRQ) ?
367 MASK_USBD_FCTRL_USB_DEV_EN | MASK_USBD_FCTRL_MODE_FS_ONLY;
368#if defined(__FT900__)
369 if (!sys_check_ft900_revB())
371 fctrl_val |= MASK_USBD_FCTRL_IMP_PERF;
374 USBD_REG(fctrl) = fctrl_val;
389 uint16_t bytes_read = 0;
392#ifdef USBD_USE_STREAMS
393 volatile uint8_t *data_reg;
395 data_reg = (
volatile uint8_t *)&(USBD->ep[ep_number].epxfifo);
398 if (((uint32_t)
buffer) % 4 == 0)
405 __asm__
volatile(
"streamout.l %0,%1,%2"
407 :
"r"(data_reg),
"r"(
buffer),
"r"(aligned));
412 __asm__
volatile(
"streamout.b %0,%1,%2"
414 :
"r"(data_reg),
"r"(
buffer),
"r"(left));
419 __asm__
volatile(
"streamout.b %0,%1,%2"
430 USBD_EP_FIFO_REG(ep_number) = *
buffer++;
446#ifdef USBD_USE_STREAMS
447 volatile uint8_t *data_reg;
449 uint16_t bytes_read = 0;
454 if (ep_number == USBD_EP_0)
460 if (USBD_EP_SR_REG(ep_number) & (MASK_USBD_EPxSR_OPRDY))
471#ifdef USBD_USE_STREAMS
472 data_reg = (
volatile uint8_t *)&(USBD->ep[ep_number].epxfifo);
475 if ((uint32_t)
buffer % 4 == 0)
482 __asm__
volatile(
"streamin.l %0,%1,%2"
484 :
"r"(
buffer),
"r"(data_reg),
"r"(aligned));
489 __asm__
volatile(
"streamin.b %0,%1,%2"
491 :
"r"(
buffer),
"r"(data_reg),
"r"(left));
496 __asm__
volatile(
"streamin.b %0,%1,%2"
507 *
buffer++ = USBD_EP_FIFO_REG(ep_number);
522 TU_LOG2(
"FT9xx initialisation\r\n");
526 interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device,
_ft9xx_usbd_ISR);
536 TU_LOG3(
"FT9xx int enable\r\n");
539 interrupt_enable_globally();
546 TU_LOG3(
"FT9xx int disable\r\n");
549 interrupt_disable_globally();
565 CRITICAL_SECTION_BEGIN
569 CRITICAL_SECTION_END;
597 SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RMWAKEUP;
602 SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP;
612 TU_LOG2(
"FT9xx connect\r\n");
614 CRITICAL_SECTION_BEGIN
627#if CFG_TUD_ENDPOINT0_SIZE == 64
628 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE);
629#elif CFG_TUD_ENDPOINT0_SIZE == 32
630 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_32 << BIT_USBD_EP0_MAX_SIZE);
631#elif CFG_TUD_ENDPOINT0_SIZE == 16
632 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_16 << BIT_USBD_EP0_MAX_SIZE);
633#elif CFG_TUD_ENDPOINT0_SIZE == 8
634 USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_8 << BIT_USBD_EP0_MAX_SIZE);
636#error "CFG_TUD_ENDPOINT0_SIZE must be defined with a value of 8, 16, 32 or 64."
638 CRITICAL_SECTION_END;
645 USBD_REG(epie) = (MASK_USBD_EPIE_EP0IE);
655 TU_LOG2(
"FT9xx disconnect\r\n");
681 uint16_t ep_buff_size;
682 uint8_t ep_reg_size = USBD_EP_MAX_SIZE_8;
683 uint8_t ep_reg_data = 0;
686 TU_LOG2(
"FT9xx endpoint open %d %c\r\n", ep_number, ep_dir?
'I':
'O');
689 if (ep_number >= USBD_MAX_ENDPOINT_COUNT)
691 TU_LOG1(
"FT9xx endpoint not valid: requested %d max %d\r\n", ep_number, USBD_MAX_ENDPOINT_COUNT);
697 while (ep_size > (8 * (1 << ep_reg_size)))
701 if (ep_reg_size > USBD_EP_MAX_SIZE_1024)
703 TU_LOG1(
"FT9xx endpoint size not valid: requested %d max 1024\r\n", ep_size);
708 ep_buff_size = 8 << ep_reg_size;
713 ep_reg_data |= (ep_reg_size << BIT_USBD_EP_MAX_SIZE);
715 if (
ep_xfer[ep_number].
type != USBD_EP_TYPE_DISABLED)
720 TU_LOG1(
"FT9xx endpoint %d already assigned\r\n", ep_number);
727 if (ep_dir == USBD_DIR_IN)
728 total_ram = USBD_RAMTOTAL_IN;
730 total_ram = USBD_RAMTOTAL_OUT;
734 for (
int i = 1; i < USBD_MAX_ENDPOINT_COUNT; i++)
745 if (sys_check_ft900_revB())
754 if (total_ram < ep_buff_size)
756 TU_LOG1(
"FT9xx insufficient buffer RAM for endpoint %d\r\n", ep_number);
762 ep_reg_data |= (USBD_EP_DIS_BULK << BIT_USBD_EP_CONTROL_DIS);
764 ep_reg_data |= (USBD_EP_DIS_INT << BIT_USBD_EP_CONTROL_DIS);
766 ep_reg_data |= (USBD_EP_DIS_ISO << BIT_USBD_EP_CONTROL_DIS);
768 if (ep_dir == USBD_DIR_IN)
769 ep_reg_data |= MASK_USBD_EPxCR_DIR;
774 USBD_EP_CR_REG(ep_number) = ep_reg_data;
775 TU_LOG2(
"FT9xx endpoint setting %x\r\n", ep_reg_data);
780 USBD_EP_CR_REG(USBD_EP_0) = (ep_reg_size << BIT_USBD_EP0_MAX_SIZE);
783 CRITICAL_SECTION_BEGIN
823 CRITICAL_SECTION_BEGIN
832 if (ep_number == USBD_EP_0)
840 USBD_REG(epie) = USBD_REG(epie) | (1 << ep_number);
910 CRITICAL_SECTION_BEGIN
911 if (ep_number == USBD_EP_0)
913 USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) |
914 MASK_USBD_EP0CR_SDSTL;
918 USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) |
919 MASK_USBD_EPxCR_SDSTL;
920 USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE |
921 MASK_USBD_EPxSR_FIFO_FLUSH;
932 if (ep_number > USBD_EP_0)
934 CRITICAL_SECTION_BEGIN
935 USBD_EP_CR_REG(ep_number) = USBD_EP_CR_REG(ep_number) &
936 (~MASK_USBD_EPxCR_SDSTL);
937 USBD_EP_SR_REG(ep_number) = MASK_USBD_EPxSR_CLR_TOGGLE;
959 uint8_t cmif = USBD_REG(cmif);
961#if defined(__FT930__)
963 uint16_t epif = USBD_REG(epif);
966 uint8_t epif = USBD_REG(epif);
969 if (cmif & MASK_USBD_CMIF_ALL)
972 USBD_REG(cmif) = MASK_USBD_CMIF_ALL;
973 if (cmif & MASK_USBD_CMIF_PHYIRQ)
976 if (cmif & MASK_USBD_CMIF_PIDIRQ)
979 if (cmif & MASK_USBD_CMIF_CRC16IRQ)
982 if (cmif & MASK_USBD_CMIF_CRC5IRQ)
985 if (cmif & MASK_USBD_CMIF_RSTIRQ)
991 if (cmif & MASK_USBD_CMIF_SUSIRQ)
995 if (cmif & MASK_USBD_CMIF_RESIRQ)
999 if (cmif & MASK_USBD_CMIF_SOFIRQ)
1007 uint16_t xfer_bytes;
1010 if (epif & MASK_USBD_EPIF_EP0IRQ)
1013 USBD_REG(epif) = MASK_USBD_EPIF_EP0IRQ;
1015 if (USBD_EP_SR_REG(USBD_EP_0) & MASK_USBD_EP0SR_SETUP)
1018 if (USBD_EP_CR_REG(USBD_EP_0) & MASK_USBD_EP0CR_SDSTL)
1021 USBD_EP_CR_REG(USBD_EP_0) = USBD_EP_CR_REG(USBD_EP_0) &
1022 (~MASK_USBD_EP0CR_SDSTL);
1024 USBD_EP_SR_REG(USBD_EP_0) = MASK_USBD_EP0SR_STALL;
1034 USBD_EP_SR_REG(USBD_EP_0) = (MASK_USBD_EP0SR_SETUP);
1080 epif &= USBD_REG(epie);
1083 for (uint8_t ep_number = 1; ep_number < USBD_MAX_ENDPOINT_COUNT; ep_number++)
1085 if ((epif & MASK_USBD_EPIF_IRQ(ep_number)) == 0)
1096 USBD_REG(epif) = MASK_USBD_EPIF_IRQ(ep_number);
1141 USBD_REG(epie) = USBD_REG(epie) & (~(1 << ep_number));
1167 uint16_t pmcfg = SYS->PMCFG_H;
1170 if (pmcfg & MASK_SYS_PMCFG_DEV_CONN_DEV)
1173 SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND;
1177 if (pmcfg & MASK_SYS_PMCFG_DEV_DIS_DEV)
1180 SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND;
1184 if (pmcfg & MASK_SYS_PMCFG_HOST_RST_DEV)
1187 SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND;
1191 if (pmcfg & MASK_SYS_PMCFG_HOST_RESUME_DEV)
1194 SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND;
1195 if (!(SYS->MSC0CFG & MASK_SYS_MSC0CFG_DEV_RMWAKEUP))
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_signal(uint8_t rhport, dcd_eventid_t eid, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
static void _ft9xx_usb_speed(void)
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes)
static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length)
static tusb_speed_t _speed
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
void _ft9xx_usbd_ISR(void)
static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
void dcd_int_handler(uint8_t rhport)
void dcd_disconnect(uint8_t rhport)
static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
static void _dcd_ft9xx_attach(void)
int8_t board_ft9xx_vbus(void)
void dcd_edpt_close_all(uint8_t rhport)
void dcd_int_disable(uint8_t rhport)
CFG_TUD_MEM_SECTION static CFG_TUSB_MEM_ALIGN uint8_t _ft9xx_setup_packet[8]
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
static void _dcd_ft9xx_detach(void)
static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length)
void dcd_connect(uint8_t rhport)
void ft9xx_usbd_pm_ISR(void)
static void _ft9xx_reset_edpts(void)
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
int board_uart_write(void const *buf, int len)
static struct ft9xx_xfer_state ep_xfer[USBD_MAX_ENDPOINT_COUNT]
static void _ft9xx_phy_enable(bool en)
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request)
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
struct __attribute__((__packed__)) reportHID_t
AUDIO Channel Cluster Descriptor (4.1)
struct TU_ATTR_PACKED::@16::TU_ATTR_PACKED bmRequestType_bit
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
uint8_t bRequest
Request type audio_cs_req_t.
@ TUSB_REQ_SET_CONFIGURATION
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
CFG_TUH_MEM_ALIGN tusb_control_request_t request