From fad088719e7cc4d1cab9216eb81567dd67af65f7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 15:21:23 +0700 Subject: merge CFG_TUSB_RHPORT1_MODE into CFG_TUSB_RHPORT0_MODE each port is 1 byte for easy maintenance --- src/tusb_option.h | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'src/tusb_option.h') diff --git a/src/tusb_option.h b/src/tusb_option.h index 9e6a2b532..472656424 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -114,44 +114,50 @@ /** \addtogroup group_configuration * @{ */ + //-------------------------------------------------------------------- -// CONTROLLER -// Only 1 roothub port can be configured to be device and/or host. -// tinyusb does not support dual devices or dual host configuration +// RootHub Mode Configuration +// +// Each byte of the CFG_TUSB_RHPORTx_MODE contains operation mode for +// a roothub port (device or host). Therefore each macro can have up to +// 4 ports. //-------------------------------------------------------------------- -/** \defgroup group_mode Controller Mode Selection - * \brief CFG_TUSB_CONTROLLER_N_MODE must be defined with these - * @{ */ + +// Lower 4-bit is operational mode #define OPT_MODE_NONE 0x00 ///< Disabled #define OPT_MODE_DEVICE 0x01 ///< Device Mode #define OPT_MODE_HOST 0x02 ///< Host Mode -#define OPT_MODE_HIGH_SPEED 0x10 ///< High speed -/** @} */ + +// Higher 4-bit is max operational speed (corresponding to tusb_speed_t) +#define OPT_MODE_FULL_SPEED 0x00 ///< Max Full Speed +#define OPT_MODE_LOW_SPEED 0x10 ///< Max Low Speed +#define OPT_MODE_HIGH_SPEED 0x20 ///< Max High Speed + #ifndef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif -#ifndef CFG_TUSB_RHPORT1_MODE - #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -#endif +//#ifndef CFG_TUSB_RHPORT1_MODE +// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE +//#endif -#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST)) || \ - ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)) - #error "tinyusb does not support same modes on more than 1 roothub port" +#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ) || \ + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ) + #error "TinyUSB currently does not support same modes on more than 1 roothub port" #endif // Which roothub port is configured as host -#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) ) +#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ? 1 : -1) ) #define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) // Which roothub port is configured as device -#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) ) +#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ? 1 : -1) ) #if TUD_OPT_RHPORT == 0 -#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) + #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) #else -#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED ) + #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HIGH_SPEED << 8) ) #endif #define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 ) @@ -168,15 +174,15 @@ // place data in accessible RAM for usb controller #ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) + #define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_NONE #endif //-------------------------------------------------------------------- @@ -184,7 +190,7 @@ //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE - #define CFG_TUD_ENDPOINT0_SIZE 64 + #define CFG_TUD_ENDPOINT0_SIZE 64 #endif #ifndef CFG_TUD_CDC -- cgit v1.3.1 From 0482f0d6867835d3dbb3939452fbcfaf9727b555 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 22:11:26 +0700 Subject: update h743eval with rhport=1 highspeed --- hw/bsp/stm32h743eval/board.mk | 7 +-- hw/bsp/stm32h743eval/stm32h743eval.c | 97 ++++++++++++++++++++++++++++++++---- src/tusb_option.h | 4 -- test/test/support/tusb_config.h | 5 -- 4 files changed, 89 insertions(+), 24 deletions(-) (limited to 'src/tusb_option.h') diff --git a/hw/bsp/stm32h743eval/board.mk b/hw/bsp/stm32h743eval/board.mk index 5044cdc08..68d142435 100644 --- a/hw/bsp/stm32h743eval/board.mk +++ b/hw/bsp/stm32h743eval/board.mk @@ -8,11 +8,8 @@ CFLAGS += \ -nostdlib -nostartfiles \ -DSTM32H743xx \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7 \ - -# Board specific for using usb ports -CFLAGS += \ - -DCFG_BOARD_DEVICE_RHPORT_NUM=1 \ - -DCFG_BOARD_DEVICE_RHPORT_HIGHSPEED + -DBOARD_DEVICE_RHPORT_NUM=1 \ + -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=maybe-uninitialized diff --git a/hw/bsp/stm32h743eval/stm32h743eval.c b/hw/bsp/stm32h743eval/stm32h743eval.c index 5a7934ea2..fd3d33047 100644 --- a/hw/bsp/stm32h743eval/stm32h743eval.c +++ b/hw/bsp/stm32h743eval/stm32h743eval.c @@ -32,11 +32,22 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ + +// Despite being call USB2_OTG +// OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port void OTG_FS_IRQHandler(void) { tud_int_handler(0); } +// Despite being call USB2_OTG +// OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port +void OTG_HS_IRQHandler(void) +{ + tud_int_handler(1); +} + + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -53,7 +64,7 @@ void OTG_FS_IRQHandler(void) // enable all LED, Button, Uart, USB clock static void all_rcc_clk_enable(void) { - __HAL_RCC_GPIOA_CLK_ENABLE(); // LED, USB D+, D- + __HAL_RCC_GPIOA_CLK_ENABLE(); // LED __HAL_RCC_GPIOC_CLK_ENABLE(); // Button // __HAL_RCC_GPIOD_CLK_ENABLE(); // Uart tx, rx // __HAL_RCC_USART3_CLK_ENABLE(); // Uart module @@ -187,17 +198,13 @@ void board_init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); -#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - - // USB1 HS (ULPI Phy), internal FS PHY - // PB12 ID, PB13 VBUS, PB14 DM, PB15 DP - -#endif - -#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - // USB2 FS Pin Init +#if BOARD_DEVICE_RHPORT_NUM == 0 + // Despite being call USB2_OTG + // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port // PA9 VUSB, PA10 ID, PA11 DM, PA12 DP + __HAL_RCC_GPIOA_CLK_ENABLE(); + /* Configure DM DP Pins */ GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; @@ -228,6 +235,76 @@ void board_init(void) // Enable VBUS sense (B device) via pin PA9 USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; #endif + +#if BOARD_DEVICE_RHPORT_NUM == 1 + // Despite being call USB2_OTG + // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port + __GPIOA_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + __GPIOC_CLK_ENABLE(); + __GPIOH_CLK_ENABLE(); + __GPIOI_CLK_ENABLE(); + + /* CLK */ + GPIO_InitStruct.Pin = GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* D0 */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* D1 D2 D3 D4 D5 D6 D7 */ + GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* STP */ + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /* NXT */ + GPIO_InitStruct.Pin = GPIO_PIN_4; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + + /* DIR */ + GPIO_InitStruct.Pin = GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; + HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE(); + + /* Enable USB HS Clocks */ + __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); + + // No VBUS sense + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // Force device mode + // USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; + // USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + + // B-peripheral session valid override enabl +// USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; +// USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif // rhport = 1 + } //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index 472656424..c251d578a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -138,10 +138,6 @@ #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif -//#ifndef CFG_TUSB_RHPORT1_MODE -// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -//#endif - #if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ) || \ ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ) #error "TinyUSB currently does not support same modes on more than 1 roothub port" diff --git a/test/test/support/tusb_config.h b/test/test/support/tusb_config.h index 5258513ec..76f975323 100644 --- a/test/test/support/tusb_config.h +++ b/test/test/support/tusb_config.h @@ -43,12 +43,7 @@ #define CFG_TUSB_MCU OPT_MCU_NRF5X #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#endif - #define CFG_TUSB_OS OPT_OS_NONE // CFG_TUSB_DEBUG is defined by compiler in DEBUG build -- cgit v1.3.1 From 0635bafe0af9452fd3cf0fbca391e9dbf123f382 Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 9 Jun 2020 15:22:16 +0200 Subject: Add DCD for Dialog DA1469x MCU Dialog Semiconductor's BLE MCU DA1469x comes with full speed USB. It's base on National Semiconductor discrete USB controller USBN9603/4. This adds support for: - control/interrupt/bulk endpoints (up to 64 bytes) - ISO endpoint were not tested and may not work correctly - reset/sleep/wakeup are handled - code for VBUS changes is provided --- src/portable/dialog/da146xx/dcd_da146xx.c | 842 ++++++++++++++++++++++++++++++ src/tusb_option.h | 3 + 2 files changed, 845 insertions(+) create mode 100644 src/portable/dialog/da146xx/dcd_da146xx.c (limited to 'src/tusb_option.h') diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c new file mode 100644 index 000000000..3a3459b7d --- /dev/null +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -0,0 +1,842 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Jerzy Kasenberg + * + * 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_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_DA1469X + +#include "DA1469xAB.h" + +#include "device/dcd.h" + +/*------------------------------------------------------------------*/ +/* MACRO TYPEDEF CONSTANT ENUM + *------------------------------------------------------------------*/ + +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + +#define EP_MAX 4 + +#define NFSR_NODE_RESET 0 +#define NFSR_NODE_RESUME 1 +#define NFSR_NODE_OPERATIONAL 2 +#define NFSR_NODE_SUSPEND 3 + +static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8]; + +typedef struct +{ + union + { + __IOM uint32_t epc_in; + __IOM uint32_t USB_EPC0_REG; /*!< (@ 0x00000080) Endpoint Control 0 Register */ + __IOM uint32_t USB_EPC1_REG; /*!< (@ 0x000000A0) Endpoint Control Register 1 */ + __IOM uint32_t USB_EPC3_REG; /*!< (@ 0x000000C0) Endpoint Control Register 3 */ + __IOM uint32_t USB_EPC5_REG; /*!< (@ 0x000000E0) Endpoint Control Register 5 */ + }; + union + { + __IOM uint32_t txd; + __IOM uint32_t USB_TXD0_REG; /*!< (@ 0x00000084) Transmit Data 0 Register */ + __IOM uint32_t USB_TXD1_REG; /*!< (@ 0x000000A4) Transmit Data Register 1 */ + __IOM uint32_t USB_TXD2_REG; /*!< (@ 0x000000C4) Transmit Data Register 2 */ + __IOM uint32_t USB_TXD3_REG; /*!< (@ 0x000000E4) Transmit Data Register 3 */ + }; + union + { + __IOM uint32_t txs; + __IOM uint32_t USB_TXS0_REG; /*!< (@ 0x00000088) Transmit Status 0 Register */ + __IOM uint32_t USB_TXS1_REG; /*!< (@ 0x000000A8) Transmit Status Register 1 */ + __IOM uint32_t USB_TXS2_REG; /*!< (@ 0x000000C8) Transmit Status Register 2 */ + __IOM uint32_t USB_TXS3_REG; /*!< (@ 0x000000E8) Transmit Status Register 3 */ + }; + union + { + __IOM uint32_t txc; + __IOM uint32_t USB_TXC0_REG; /*!< (@ 0x0000008C) Transmit command 0 Register */ + __IOM uint32_t USB_TXC1_REG; /*!< (@ 0x000000AC) Transmit Command Register 1 */ + __IOM uint32_t USB_TXC2_REG; /*!< (@ 0x000000CC) Transmit Command Register 2 */ + __IOM uint32_t USB_TXC3_REG; /*!< (@ 0x000000EC) Transmit Command Register 3 */ + }; + union + { + __IOM uint32_t epc_out; + __IOM uint32_t USB_EP0_NAK_REG; /*!< (@ 0x00000090) EP0 INNAK and OUTNAK Register */ + __IOM uint32_t USB_EPC2_REG; /*!< (@ 0x000000B0) Endpoint Control Register 2 */ + __IOM uint32_t USB_EPC4_REG; /*!< (@ 0x000000D0) Endpoint Control Register 4 */ + __IOM uint32_t USB_EPC6_REG; /*!< (@ 0x000000F0) Endpoint Control Register 6 */ + }; + union + { + __IOM uint32_t rxd; + __IOM uint32_t USB_RXD0_REG; /*!< (@ 0x00000094) Receive Data 0 Register */ + __IOM uint32_t USB_RXD1_REG; /*!< (@ 0x000000B4) Receive Data Register,1 */ + __IOM uint32_t USB_RXD2_REG; /*!< (@ 0x000000D4) Receive Data Register 2 */ + __IOM uint32_t USB_RXD3_REG; /*!< (@ 0x000000F4) Receive Data Register 3 */ + }; + union + { + __IOM uint32_t rxs; + __IOM uint32_t USB_RXS0_REG; /*!< (@ 0x00000098) Receive Status 0 Register */ + __IOM uint32_t USB_RXS1_REG; /*!< (@ 0x000000B8) Receive Status Register 1 */ + __IOM uint32_t USB_RXS2_REG; /*!< (@ 0x000000D8) Receive Status Register 2 */ + __IOM uint32_t USB_RXS3_REG; /*!< (@ 0x000000F8) Receive Status Register 3 */ + }; + union + { + __IOM uint32_t rxc; + __IOM uint32_t USB_RXC0_REG; /*!< (@ 0x0000009C) Receive Command 0 Register */ + __IOM uint32_t USB_RXC1_REG; /*!< (@ 0x000000BC) Receive Command Register 1 */ + __IOM uint32_t USB_RXC2_REG; /*!< (@ 0x000000DC) Receive Command Register 2 */ + __IOM uint32_t USB_RXC3_REG; /*!< (@ 0x000000FC) Receive Command Register 3 */ + }; +} EPx_REGS; + +#define EP_REGS(first_ep_reg) (EPx_REGS*)(&USB->first_ep_reg) + +// Dialog register fields and bit mask are very long. Filed masks repeat register names. +// Those convenience macros are a way to reduce complexity of register modification lines. +#define GET_BIT(val, field) (val & field ## _Msk) >> field ## _Pos +#define REG_GET_BIT(reg, field) (USB->reg & USB_ ## reg ## _ ## field ## _Msk) +#define REG_SET_BIT(reg, field) USB->reg |= USB_ ## reg ## _ ## field ## _Msk +#define REG_CLR_BIT(reg, field) USB->reg &= ~USB_ ## reg ## _ ## field ## _Msk +#define REG_SET_VAL(reg, field, val) USB->reg = (USB->reg & ~USB_ ## reg ## _ ## field ## _Msk) | (val << USB_ ## reg ## _ ## field ## _Pos) + +typedef struct { + EPx_REGS * regs; + uint8_t * buffer; + // Total length of current transfer + uint16_t total_len; + // Bytes transferred so far + uint16_t transferred; + uint16_t max_packet_size; + // Packet size sent or received so far. It is used to modify transferred field + // after ACK is received or when filling ISO endpoint with size larger then + // FIFO size. + uint16_t last_packet_size; + uint8_t ep_addr; + // DATA0/1 toggle bit 1 DATA1 is expected or transmitted + uint8_t data1 : 1; + // Endpoint is stalled + uint8_t stall : 1; +} xfer_ctl_t; + +static struct +{ + bool vbus_present; + bool in_reset; + xfer_ctl_t xfer_status[EP_MAX][2]; +} _dcd = +{ + .vbus_present = false, + .xfer_status = + { + { { .regs = EP_REGS(USB_EPC0_REG) }, { .regs = EP_REGS(USB_EPC0_REG) } }, + { { .regs = EP_REGS(USB_EPC1_REG) }, { .regs = EP_REGS(USB_EPC1_REG) } }, + { { .regs = EP_REGS(USB_EPC3_REG) }, { .regs = EP_REGS(USB_EPC3_REG) } }, + { { .regs = EP_REGS(USB_EPC5_REG) }, { .regs = EP_REGS(USB_EPC5_REG) } }, + } +}; + +// Two endpoint 0 descriptor definition for unified dcd_edpt_open() +static const tusb_desc_endpoint_t ep0OUT_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x00, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = { .size = CFG_TUD_ENDPOINT0_SIZE }, + .bInterval = 0 +}; + +static const tusb_desc_endpoint_t ep0IN_desc = +{ + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + + .bEndpointAddress = 0x80, + .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, + .wMaxPacketSize = { .size = CFG_TUD_ENDPOINT0_SIZE }, + .bInterval = 0 +}; + +#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir] + +// Function could be called when VBUS change was detected. +void tusb_vbus_changed(bool present) +{ + if (present != _dcd.vbus_present) + { + _dcd.vbus_present = present; + if (present) + { + USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk; + USB->USB_NFSR_REG = 0; + USB->USB_FAR_REG = 0x80; + USB->USB_NFSR_REG = NFSR_NODE_RESET; + USB->USB_TXMSK_REG = 0; + USB->USB_RXMSK_REG = 0; + + USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk | + USB_USB_MAMSK_REG_USB_M_ALT_Msk | + USB_USB_MAMSK_REG_USB_M_WARN_Msk; + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk; + } + else + { + USB->USB_MCTRL_REG = 0; + } + } +} + +static void transmit_packet(xfer_ctl_t * xfer) +{ + int left_to_send; + uint8_t const *src; + EPx_REGS *regs = xfer->regs; + uint32_t txc; + + txc = USB_USB_TXC1_REG_USB_TX_EN_Msk; + if (xfer->data1) txc |= USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk; + + src = &xfer->buffer[xfer->transferred]; + left_to_send = xfer->total_len - xfer->transferred; + if (left_to_send > xfer->max_packet_size - xfer->last_packet_size) + { + left_to_send = xfer->max_packet_size - xfer->last_packet_size; + } + + // Loop checks TCOUNT all the time since this value is saturated to 31 + // and can't be read just once before. + while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && left_to_send > 0) + { + regs->txd = *src++; + xfer->last_packet_size++; + left_to_send--; + } + if (tu_edpt_number(xfer->ep_addr) != 0) + { + if (left_to_send > 0) + { + // Max packet size is set to value greater then FIFO. Enable fifo level warning + // to handle larger packets. + txc |= USB_USB_TXC1_REG_USB_TFWL_Msk; + } + else + { + // Whole packet already in fifo, no need to refill it later. Mark last. + txc |= USB_USB_TXC1_REG_USB_LAST_Msk; + } + } + // Enable transfer with correct interrupts enabled + regs->txc = txc; +} + +static void receive_packet(xfer_ctl_t *xfer, uint16_t bytes_in_fifo) +{ + EPx_REGS *regs = xfer->regs; + uint16_t remaining = xfer->total_len - xfer->transferred; + uint16_t receive_this_time = bytes_in_fifo; + + if (remaining <= bytes_in_fifo) receive_this_time = remaining; + + uint8_t *buf = xfer->buffer + xfer->transferred + xfer->last_packet_size; + + for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd; + + xfer->transferred += receive_this_time; + xfer->last_packet_size += receive_this_time; +} + +static void handle_ep0_rx(void) +{ + int packet_size; + uint32_t rxs0 = USB->USB_RXS0_REG; + + xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT); + + packet_size = GET_BIT(rxs0, USB_USB_RXS0_REG_USB_RCOUNT); + if (rxs0 & USB_USB_RXS0_REG_USB_SETUP_Msk) + { + xfer_ctl_t *xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN); + // Setup packet is in + for (int i = 0; i < packet_size; ++i) _setup_packet[i] = USB->USB_RXD0_REG; + + xfer->stall = 0; + xfer->data1 = 1; + xfer_in->stall = 0; + xfer_in->data1 = 1; + REG_SET_BIT(USB_TXC0_REG, USB_TOGGLE_TX0); + REG_CLR_BIT(USB_EPC0_REG, USB_STALL); + dcd_event_setup_received(0, _setup_packet,true); + } + else + { + if (GET_BIT(rxs0, USB_USB_RXS0_REG_USB_TOGGLE_RX0) != xfer->data1) + { + // Toggle bit does not match discard packet + REG_SET_BIT(USB_RXC0_REG, USB_FLUSH); + } + else + { + receive_packet(xfer, packet_size); + xfer->data1 ^= 1; + + if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size) + { + dcd_event_xfer_complete(0, 0, xfer->transferred, XFER_RESULT_SUCCESS, true); + } + else + { + xfer->last_packet_size = 0; + // Re-enable reception + REG_SET_BIT(USB_RXC0_REG, USB_RX_EN); + } + } + } +} + +static void handle_ep0_tx(void) +{ + uint32_t txs0; + xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_IN); + EPx_REGS *regs = xfer->regs; + + txs0 = regs->USB_TXS0_REG; + + if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_TX_DONE)) + { + // ACK received + if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_ACK_STAT)) + { + xfer->transferred += xfer->last_packet_size; + xfer->last_packet_size = 0; + xfer->data1 ^= 1; + REG_SET_VAL(USB_TXC0_REG, USB_TOGGLE_TX0, xfer->data1); + if (xfer->transferred == xfer->total_len) + { + dcd_event_xfer_complete(0, 0 | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + return; + } + } + else + { + // Start from the beginning + xfer->last_packet_size = 0; + } + transmit_packet(xfer); + } +} + +static void handle_epx_rx_ev(uint8_t ep) +{ + uint32_t rxs; + int packet_size; + xfer_ctl_t *xfer = XFER_CTL_BASE(ep, TUSB_DIR_OUT); + + EPx_REGS *regs = xfer->regs; + + rxs = regs->rxs; + + if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_ERR)) + { + regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; + } + else + { + packet_size = GET_BIT(rxs, USB_USB_RXS1_REG_USB_RXCOUNT); + receive_packet(xfer, packet_size); + if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_LAST)) + { + if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_TOGGLE_RX) != xfer->data1) + { + // Toggle bit does not match discard packet + regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk; + } + else + { + xfer->data1 ^= 1; + if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size) + { + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, XFER_RESULT_SUCCESS, true); + } + else + { + xfer->last_packet_size = 0; + // Re-enable reception + regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk; + } + } + } + } +} + +static void handle_rx_ev(void) +{ + if (USB->USB_RXEV_REG & 1) + handle_epx_rx_ev(1); + if (USB->USB_RXEV_REG & 2) + handle_epx_rx_ev(2); + if (USB->USB_RXEV_REG & 4) + handle_epx_rx_ev(3); +} + +static void handle_epx_tx_ev(xfer_ctl_t *xfer) +{ + uint32_t usb_txs1_reg; + EPx_REGS *regs = xfer->regs; + + usb_txs1_reg = regs->USB_TXS1_REG; + + if (GET_BIT(usb_txs1_reg, USB_USB_TXS1_REG_USB_TX_DONE)) + { + if (GET_BIT(usb_txs1_reg, USB_USB_TXS1_REG_USB_ACK_STAT)) + { + // ACK received, update transfer state and DATA0/1 bit + xfer->transferred += xfer->last_packet_size; + xfer->last_packet_size = 0; + xfer->data1 ^= 1; + + if (xfer->transferred == xfer->total_len) + { + dcd_event_xfer_complete(0, xfer->ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); + return; + } + } + else + { + xfer->last_packet_size = 0; + } + transmit_packet(xfer); + } +} + +static void handle_tx_ev(void) +{ + if (USB->USB_TXEV_REG & 1) + handle_epx_tx_ev(XFER_CTL_BASE(1, TUSB_DIR_IN)); + if (USB->USB_TXEV_REG & 2) + handle_epx_tx_ev(XFER_CTL_BASE(2, TUSB_DIR_IN)); + if (USB->USB_TXEV_REG & 4) + handle_epx_tx_ev(XFER_CTL_BASE(3, TUSB_DIR_IN)); +} + +static void handle_bus_reset(void) +{ + USB->USB_NFSR_REG = 0; + USB->USB_FAR_REG = 0x80; + USB->USB_ALTMSK_REG = 0; + USB->USB_NFSR_REG = NFSR_NODE_RESET; + USB->USB_TXMSK_REG = 0; + USB->USB_RXMSK_REG = 0; + (void)USB->USB_ALTEV_REG; + _dcd.in_reset = true; + + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + + USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk | +#if USE_SOF + USB_USB_MAMSK_REG_USB_M_FRAME_Msk | +#endif + USB_USB_MAMSK_REG_USB_M_WARN_Msk | + USB_USB_MAMSK_REG_USB_M_ALT_Msk; + USB->USB_NFSR_REG = NFSR_NODE_OPERATIONAL; + USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_SD3_Msk | + USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; + // There is no information about end of reset state + // USB_FRAME event will be used to enable reset detection again + REG_SET_BIT(USB_MAEV_REG, USB_FRAME); + dcd_edpt_open (0, &ep0OUT_desc); + dcd_edpt_open (0, &ep0IN_desc); +} + +static void handle_alt_ev(void) +{ + uint32_t alt_ev = USB->USB_ALTEV_REG; + + if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET)) + { + handle_bus_reset(); + } + else + { + if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESUME)) + { + USB->USB_NFSR_REG = NFSR_NODE_OPERATIONAL; + USB->USB_ALTMSK_REG &= ~USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; + USB->USB_ALTMSK_REG |= USB_USB_ALTMSK_REG_USB_M_SD3_Msk; + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + } + if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_SD3)) + { + USB->USB_NFSR_REG = NFSR_NODE_SUSPEND; + USB->USB_ALTMSK_REG |= USB_USB_ALTMSK_REG_USB_M_RESUME_Msk; + USB->USB_ALTMSK_REG &= ~USB_USB_ALTMSK_REG_USB_M_SD3_Msk | USB_USB_ALTMSK_REG_USB_M_SD5_Msk; + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + } + } +} + +static void handle_epx_tx_refill(uint8_t ep) +{ + transmit_packet(XFER_CTL_BASE(ep, TUSB_DIR_IN)); +} + +static void handle_fifo_warning(void) +{ + uint32_t fifo_warning = USB->USB_FWEV_REG; + + if (fifo_warning & 0x01) + handle_epx_tx_refill(1); + if (fifo_warning & 0x02) + handle_epx_tx_refill(2); + if (fifo_warning & 0x04) + handle_epx_tx_refill(3); + if (fifo_warning & 0x10) + handle_epx_rx_ev(1); + if (fifo_warning & 0x20) + handle_epx_rx_ev(2); + if (fifo_warning & 0x40) + handle_epx_rx_ev(3); +} + +static void handle_ep0_nak(void) +{ + uint32_t ep0_nak = USB->USB_EP0_NAK_REG; + + if (REG_GET_BIT(USB_EPC0_REG, USB_STALL)) + { + if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_INNAK)) + { + // EP0 is stalled and NAK was sent, it means that RX is enabled + // Disable RX for now. + REG_CLR_BIT(USB_RXC0_REG, USB_RX_EN); + REG_SET_BIT(USB_TXC0_REG, USB_TX_EN); + } + if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK)) + { + REG_SET_BIT(USB_RXC0_REG, USB_RX_EN); + } + } + else + { + REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); + } +} + +/*------------------------------------------------------------------*/ +/* Controller API + *------------------------------------------------------------------*/ +void dcd_init(uint8_t rhport) +{ + (void)rhport; + + USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk; + tusb_vbus_changed((CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk) != 0); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + + NVIC_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + + NVIC_DisableIRQ(USB_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + + // Set default address for one ZLP + USB->USB_EPC0_REG = USB_USB_EPC0_REG_USB_DEF_Msk; + USB->USB_FAR_REG = (dev_addr & USB_USB_FAR_REG_USB_AD_Msk) | USB_USB_FAR_REG_USB_AD_EN_Msk; + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); +} + +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; +} + +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + + REG_SET_BIT(USB_MCTRL_REG, USB_NAT); +} + +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + + REG_CLR_BIT(USB_MCTRL_REG, USB_NAT); +} + + +/*------------------------------------------------------------------*/ +/* DCD Endpoint port + *------------------------------------------------------------------*/ + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) +{ + uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); + uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + uint8_t iso_mask = 0; + + (void)rhport; + + TU_ASSERT(desc_edpt->wMaxPacketSize.size <= 1023); + TU_ASSERT(epnum < EP_MAX); + + xfer->max_packet_size = desc_edpt->wMaxPacketSize.size; + xfer->ep_addr = desc_edpt->bEndpointAddress; + xfer->data1 = 0; + + if (epnum != 0 && desc_edpt->bmAttributes.xfer == 1) iso_mask = USB_USB_EPC1_REG_USB_ISO_Msk; + + if (epnum == 0) + { + USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk | + USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk; + } + else + { + if (dir == TUSB_DIR_OUT) + { + xfer->regs->epc_out = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; + USB->USB_RXMSK_REG |= 0x101 << (epnum - 1); + REG_SET_BIT(USB_MAMSK_REG, USB_M_RX_EV); + } + else + { + xfer->regs->epc_in = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask; + USB->USB_TXMSK_REG |= 0x101 << (epnum - 1); + REG_SET_BIT(USB_MAMSK_REG, USB_M_TX_EV); + } + } + + return true; +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + + (void)rhport; + + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->last_packet_size = 0; + xfer->transferred = 0; + + if (dir == TUSB_DIR_OUT) + { + if (epnum != 0) + { + if (xfer->max_packet_size > 64) + { + // For endpoint size greater then FIFO size enable FIFO level warning interrupt + // when FIFO has less then 17 bytes free. + xfer->regs->rxc |= USB_USB_RXC1_REG_USB_RFWL_Msk; + } + else + { + // If max_packet_size would fit in FIFO no need for FIFO level warning interrupt. + xfer->regs->rxc &= ~USB_USB_RXC1_REG_USB_RFWL_Msk; + } + } + // USB_RX_EN bit is in same place for all endpoints. + xfer->regs->rxc = USB_USB_RXC0_REG_USB_RX_EN_Msk; + } + else // IN + { + transmit_packet(xfer); + } + + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + (void)rhport; + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + xfer->stall = 1; + + if (epnum == 0) + { + // EP0 has just one registers to control stall for IN and OUT + REG_SET_BIT(USB_EPC0_REG, USB_STALL); + if (dir == TUSB_DIR_OUT) + { + xfer->regs->USB_RXC0_REG = USB_USB_RXC0_REG_USB_RX_EN_Msk; + } + else + { + if (xfer->regs->USB_RXC0_REG & USB_USB_RXC0_REG_USB_RX_EN_Msk) + { + // If RX is also enabled TX will not be stalled since RX has + // higher priority. Enable NAK interrupt to handle stall. + REG_SET_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); + } + else + { + xfer->regs->USB_TXC0_REG |= USB_USB_TXC0_REG_USB_TX_EN_Msk; + } + } + } + else + { + if (dir == TUSB_DIR_OUT) + { + xfer->regs->epc_out |= USB_USB_EPC1_REG_USB_STALL_Msk; + xfer->regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk; + } + else + { + xfer->regs->epc_in |= USB_USB_EPC1_REG_USB_STALL_Msk; + xfer->regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk | USB_USB_TXC1_REG_USB_LAST_Msk; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + + (void)rhport; + + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); + + // Clear stall is called in response to Clear Feature ENDPOINT_HALT, reset toggle + xfer->data1 = 0; + xfer->stall = 0; + + if (dir == TUSB_DIR_OUT) + { + xfer->regs->epc_out &= ~USB_USB_EPC1_REG_USB_STALL_Msk; + } + else + { + xfer->regs->epc_in &= ~USB_USB_EPC1_REG_USB_STALL_Msk; + } + if (epnum == 0) + { + REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK); + } +} + +/*------------------------------------------------------------------*/ +/* Interrupt Handler + *------------------------------------------------------------------*/ + +void dcd_int_handler(uint8_t rhport) +{ + uint32_t int_status = USB->USB_MAEV_REG; + + (void)rhport; + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_WARN)) + { + handle_fifo_warning(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_CH_EV)) + { + // TODO: for now just clear interrupt + (void)USB->USB_CHARGER_STAT_REG; + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_NAK)) + { + handle_ep0_nak(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_RX)) + { + handle_ep0_rx(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_TX)) + { + handle_ep0_tx(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_RX_EV)) + { + handle_rx_ev(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_NAK)) + { + (void)USB->USB_NAKEV_REG; + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_FRAME)) + { + if (_dcd.in_reset) + { + // Enable reset detection + _dcd.in_reset = false; + (void)USB->USB_ALTEV_REG; + } +#if USE_SOF + dcd_event_bus_signal(0, DCD_EVENT_SOF, true); +#else + // SOF was used to re-enable reset detection + // No need to keep it enabled + USB->USB_MAMSK_REG &= ~USB_USB_MAMSK_REG_USB_M_FRAME_Msk; +#endif + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_TX_EV)) + { + handle_tx_ev(); + } + + if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_ALT)) + { + handle_alt_ev(); + } +} + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 0a227483f..706a94584 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -92,6 +92,9 @@ // Espressif #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 +// Dialog +#define OPT_MCU_DA1469X 1000 ///< Dialog Semiconductor DA1469x + /** @} */ /** \defgroup group_supported_os Supported RTOS -- cgit v1.3.1 From a347de6e50e98b339a1605dc927c0417e79b86a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 14 Jun 2020 18:28:45 +0700 Subject: revert CFG_TUSB_RHPORT0_MODE to previous way --- examples/device/cdc_msc/src/tusb_config.h | 9 ++++++++- hw/bsp/stm32h743eval/stm32h743eval.c | 3 +-- src/tusb_option.h | 23 ++++++++++++----------- 3 files changed, 21 insertions(+), 14 deletions(-) (limited to 'src/tusb_option.h') diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 9beb9f6a2..b05d219c6 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -56,7 +56,14 @@ #endif // Device mode with rhport and speed defined by board.mk -#define CFG_TUSB_RHPORT0_MODE ((OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) << (8*BOARD_DEVICE_RHPORT_NUM)) +#if BOARD_DEVICE_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + #define CFG_TUSB_OS OPT_OS_NONE // CFG_TUSB_DEBUG is defined by compiler in DEBUG build diff --git a/hw/bsp/stm32h743eval/stm32h743eval.c b/hw/bsp/stm32h743eval/stm32h743eval.c index 836f1ecab..a28110920 100644 --- a/hw/bsp/stm32h743eval/stm32h743eval.c +++ b/hw/bsp/stm32h743eval/stm32h743eval.c @@ -262,9 +262,8 @@ void board_init(void) // Enable VBUS sense (B device) via pin PA9 USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; -#endif -#if BOARD_DEVICE_RHPORT_NUM == 1 +#elif BOARD_DEVICE_RHPORT_NUM == 1 // Despite being call USB2_OTG // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port diff --git a/src/tusb_option.h b/src/tusb_option.h index c251d578a..01bb1301a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -117,10 +117,7 @@ //-------------------------------------------------------------------- // RootHub Mode Configuration -// -// Each byte of the CFG_TUSB_RHPORTx_MODE contains operation mode for -// a roothub port (device or host). Therefore each macro can have up to -// 4 ports. +// CFG_TUSB_RHPORTx_MODE contains operation mode and speed for that port //-------------------------------------------------------------------- // Lower 4-bit is operational mode @@ -138,27 +135,31 @@ #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif -#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ) || \ - ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ) + +#ifndef CFG_TUSB_RHPORT1_MODE + #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE +#endif + +#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST )) || \ + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)) #error "TinyUSB currently does not support same modes on more than 1 roothub port" #endif // Which roothub port is configured as host -#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ? 1 : -1) ) +#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) ) #define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) // Which roothub port is configured as device -#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ? 1 : -1) ) +#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) ) #if TUD_OPT_RHPORT == 0 - #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) +#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) #else - #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HIGH_SPEED << 8) ) +#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED ) #endif #define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 ) - //--------------------------------------------------------------------+ // COMMON OPTIONS //--------------------------------------------------------------------+ -- cgit v1.3.1 From d4d6e06c1dac7fa50e86794a05feff0c7ab9c32d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Jun 2020 00:53:17 +0700 Subject: added OPT_MCU_SAME5X option --- src/portable/microchip/samd/dcd_samd.c | 3 ++- src/tusb_option.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/tusb_option.h') diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index a859b72b9..06959b98d 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -26,7 +26,8 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAMD21) +#if TUSB_OPT_DEVICE_ENABLED && \ + (CFG_TUSB_MCU == OPT_MCU_SAMD21 || CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X) #include "sam.h" #include "device/dcd.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 0a227483f..6ce43f885 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -58,6 +58,7 @@ #define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21 #define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51 #define OPT_MCU_SAMG 202 ///< MicroChip SAMDG series +#define OPT_MCU_SAME5X 203 ///< MicroChip SAM E5x // STM32 #define OPT_MCU_STM32F0 300 ///< ST STM32F0 -- cgit v1.3.1