summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2024-07-25 19:00:59 +0700
committerhathach <[email protected]>2024-07-25 19:00:59 +0700
commit02caf007723551f878ab3675c14681801f16354e (patch)
tree553f4d6305fb515cadc36f10ee2c458d4d8ccf3e /src
parenta5bc0430f75c4e2088690467b369db7e24bba97b (diff)
simplify btable rx/tx count/address access
Diffstat (limited to 'src')
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c20
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.h136
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
}