diff options
| author | hathach <[email protected]> | 2024-07-25 19:00:59 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2024-07-25 19:00:59 +0700 |
| commit | 02caf007723551f878ab3675c14681801f16354e (patch) | |
| tree | 553f4d6305fb515cadc36f10ee2c458d4d8ccf3e /src | |
| parent | a5bc0430f75c4e2088690467b369db7e24bba97b (diff) | |
simplify btable rx/tx count/address access
Diffstat (limited to 'src')
| -rw-r--r-- | src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 20 | ||||
| -rw-r--r-- | src/portable/st/stm32_fsdev/fsdev_common.h | 136 |
2 files changed, 98 insertions, 58 deletions
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 602b220ab..927ecac85 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -129,21 +129,7 @@ // Configuration //--------------------------------------------------------------------+ -// hardware limit endpoint -#define FSDEV_EP_COUNT 8 -// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it -// Both of these MUST be a multiple of 2, and are in byte units. -#ifndef DCD_STM32_BTABLE_BASE -#define DCD_STM32_BTABLE_BASE 0U -#endif - -#ifndef DCD_STM32_BTABLE_SIZE -#define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) -#endif - -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM"); -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -231,7 +217,7 @@ void dcd_init(uint8_t rhport) { #if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address - USB->BTABLE = DCD_STM32_BTABLE_BASE; + USB->BTABLE = FSDEV_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts @@ -289,7 +275,7 @@ static void handle_bus_reset(uint8_t rhport) { } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), @@ -705,7 +691,7 @@ void dcd_edpt_close_all(uint8_t rhport) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 920c17a04..d0f928552 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -34,6 +34,14 @@ #include "stdint.h" +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef FSDEV_BTABLE_BASE +#define FSDEV_BTABLE_BASE 0U +#endif + +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); + // FSDEV_PMA_SIZE is PMA buffer size in bytes. // - 512-byte devices, access with a stride of two words (use every other 16-bit address) // - 1024-byte devices, access with a stride of one word (use every 16-bit address) @@ -41,15 +49,50 @@ // For purposes of accessing the packet #if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) + #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme + #define pma_aligned TU_ATTR_ALIGNED(4) #elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) + #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme + #define pma_aligned #elif FSDEV_PMA_SIZE == 2048 #ifndef FSDEV_BUS_32BIT #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" #endif + #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme + #define pma_aligned #endif +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 + +// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either +// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +typedef struct { + union { + struct { + volatile pma_aligned uint16_t tx_addr; + volatile pma_aligned uint16_t tx_count; + volatile pma_aligned uint16_t rx_addr; + volatile pma_aligned uint16_t rx_count; + } ep16[FSDEV_EP_COUNT]; + + struct { + volatile uint32_t tx_count_addr; + volatile uint32_t rx_count_addr; + } ep32[FSDEV_EP_COUNT]; + }; +} fsdev_btable_t; + +TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); + + +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) + +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + // The fsdev_bus_t type can be used for both register and PMA access necessities // For type-safety create a new macro for the volatile address of PMAADDR // The compiler should warn us if we cast it to a non-volatile type? @@ -110,6 +153,21 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return *reg; } +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param bAddr Address. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= (uint32_t)USB_EP_T_MASK; @@ -153,58 +211,47 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, * @retval Counter value */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr >> 16); #else - volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; + count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; #endif + + return count & 0x3FFU; } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr >> 16); #else - volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; + count = FSDEV_BTABLE->ep16[bEpIdx].rx_count; #endif + + return count & 0x3FFU; } #define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt #define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return pma32[2*bEpIdx] & 0x0000FFFFu ; +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr & 0x0000FFFFu; #else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); + return FSDEV_BTABLE->ep16[bEpIdx].tx_addr; #endif } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return pma32[2*bEpIdx + 1] & 0x0000FFFFu; +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr & 0x0000FFFFu; #else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); + return FSDEV_BTABLE->ep16[bEpIdx].rx_addr; #endif } @@ -212,20 +259,24 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; #else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; + FSDEV_BTABLE->ep16[bEpIdx].tx_addr = addr; #endif } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr = count_addr; #else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; + FSDEV_BTABLE->ep16[bEpIdx].rx_addr = addr; #endif } @@ -233,12 +284,15 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB #define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; #else - volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); + uint16_t count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; + count = (count & ~0x3FFU) | (wCount & 0x3FFU); + FSDEV_BTABLE->ep16[bEpIdx].tx_count = count; #endif } |
