summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2024-08-01 23:08:12 +0700
committerhathach <[email protected]>2024-08-01 23:08:12 +0700
commite180d915c64c98ce7349cf4696f23abd55a91e19 (patch)
tree4c4b63db61f1757d9f54e70f29b7724d6a91ec56
parentaf8609e96e269a423449cfb679977c150494c3a4 (diff)
read/write packet enhancement, merge 16-bit and 32-bit together
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c139
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_type.h24
2 files changed, 60 insertions, 103 deletions
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index d1c40deb6..2aa776dbb 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -825,121 +825,76 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
ep_write(ep_idx, ep_reg);
}
-#ifdef FSDEV_BUS_32BIT
-static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) {
- const uint8_t *src8 = src;
- volatile uint32_t *pma32 = (volatile uint32_t *)(USB_PMAADDR + dst);
-
- for (uint32_t n = wNBytes / 4; n > 0; --n) {
- *pma32++ = tu_unaligned_read32(src8);
- src8 += 4;
- }
-
- uint16_t odd = wNBytes & 0x03;
- if (odd) {
- uint32_t wrVal = *src8;
- odd--;
-
- if (odd) {
- wrVal |= *++src8 << 8;
- odd--;
-
- if (odd) {
- wrVal |= *++src8 << 16;
- }
- }
-
- *pma32 = wrVal;
- }
+// Write to packet memory area (PMA) from user memory
+// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
+// - Uses unaligned for RAM (since M0 cannot access unaligned address)
+static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
+ enum { BUS_SIZE = sizeof(fsdev_bus_t) };
+ uint32_t n_write = nbytes / BUS_SIZE;
- return true;
-}
+ fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst);
+ const uint8_t *src8 = src;
-static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) {
- uint8_t *dst8 = dst;
- volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src);
+ while (n_write--) {
+ #ifdef FSDEV_BUS_32BIT
+ pma_buf->value = tu_unaligned_read32(src8);
+ #else
+ pma_buf->value = tu_unaligned_read16(src8);
+ #endif
- for (uint32_t n = wNBytes / 4; n > 0; --n) {
- tu_unaligned_write32(dst8, *src32++);
- dst8 += 4;
+ src8 += BUS_SIZE;
+ pma_buf++;
}
- uint16_t odd = wNBytes & 0x03;
+ // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
+ uint16_t odd = nbytes & (BUS_SIZE - 1);
if (odd) {
- uint32_t rdVal = *src32;
-
- *dst8 = tu_u32_byte0(rdVal);
- odd--;
-
- if (odd) {
- *++dst8 = tu_u32_byte1(rdVal);
- odd--;
-
- if (odd) {
- *++dst8 = tu_u32_byte2(rdVal);
- }
+ fsdev_bus_t temp = 0;
+ for(uint16_t i = 0; i < odd; i++) {
+ temp |= *src8++ << (i * 8);
}
+ pma_buf->value = temp;
}
return true;
}
-#else
-// Packet buffer access can only be 8- or 16-bit.
-/**
- * @brief Copy a buffer from user memory area to packet memory area (PMA).
- * This uses un-aligned for user memory and 16-bit access for packet memory.
- * @param dst, byte address in PMA; must be 16-bit aligned
- * @param src pointer to user memory area.
- * @param wPMABufAddr address into PMA.
- * @param nbytes no. of bytes to be copied.
- * @retval None
- */
-static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
- uint32_t n16 = (uint32_t)nbytes >> 1U;
- const uint8_t *src8 = src;
- fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * dst);
-
- while (n16--) {
- pma16->u16 = tu_unaligned_read16(src8);
- src8 += 2;
- pma16++;
- }
+// Read from packet memory area (PMA) to user memory.
+// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
+// - Uses unaligned for RAM (since M0 cannot access unaligned address)
+static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
+ enum { BUS_SIZE = sizeof(fsdev_bus_t) };
+ uint32_t n_write = nbytes / BUS_SIZE;
- if (nbytes & 0x01) {
- pma16->u16 = (uint16_t) *src8;
- }
+ fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src);
+ uint8_t *dst8 = (uint8_t *)dst;
- return true;
-}
+ while (n_write--) {
+ fsdev_bus_t temp = pma_buf->value;
-/**
- * @brief Copy a buffer from packet memory area (PMA) to user memory area.
- * Uses unaligned for system memory and 16-bit access of packet memory
- * @param nbytes no. of bytes to be copied.
- * @retval None
- */
-static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
- uint32_t n16 = (uint32_t)nbytes >> 1U;
- fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src);
- uint8_t *dst8 = (uint8_t *)dst;
+ #ifdef FSDEV_BUS_32BIT
+ tu_unaligned_write32(dst8, temp);
+ #else
+ tu_unaligned_write16(dst8, temp);
+ #endif
- while (n16--) {
- uint16_t temp16 = pma16->u16;
- tu_unaligned_write16(dst8, temp16);
- dst8 += 2;
- pma16++;
+ dst8 += BUS_SIZE;
+ pma_buf++;
}
- if (nbytes & 0x01) {
- *dst8++ = tu_u16_low(pma16->u16);
+ // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
+ uint16_t odd = nbytes & (BUS_SIZE - 1);
+ if (odd) {
+ fsdev_bus_t temp = pma_buf->value;
+ while (odd--) {
+ *dst8++ = (uint8_t) (temp & 0xfful);
+ temp >>= 8;
+ }
}
return true;
}
-#endif
-
/**
* @brief Copy from FIFO to packet memory area (PMA).
* Uses byte-access of system memory and 16-bit access of packet memory
diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h
index a44d8b35b..cac3b4386 100644
--- a/src/portable/st/stm32_fsdev/fsdev_type.h
+++ b/src/portable/st/stm32_fsdev/fsdev_type.h
@@ -1,9 +1,8 @@
/*
* The MIT License (MIT)
*
- * Copyright(c) 2016 STMicroelectronics
* Copyright(c) N Conrad
- * Copyright (c) 2024, hathach (tinyusb.org)
+ * Copyright(c) 2024, hathach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +22,7 @@
* 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.
*/
#ifndef TUSB_FSDEV_TYPE_H
@@ -62,6 +62,13 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b
#define pma_aligned
#endif
+// The fsdev_bus_t type can be used for both register and PMA access necessities
+#ifdef FSDEV_BUS_32BIT
+ typedef uint32_t fsdev_bus_t;
+#else
+ typedef uint16_t fsdev_bus_t;
+#endif
+
//--------------------------------------------------------------------+
// BTable Typedef
//--------------------------------------------------------------------+
@@ -95,8 +102,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE
#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE))
typedef struct {
- volatile pma_aligned uint16_t u16;
-} fsdev_pma16_t;
+ volatile pma_aligned fsdev_bus_t value;
+} fsdev_pma_buf_t;
+
+#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE*(_addr)))
//--------------------------------------------------------------------+
// Registers Typedef
@@ -105,13 +114,6 @@ typedef struct {
// volatile 32-bit aligned
#define _va32 volatile TU_ATTR_ALIGNED(4)
-// The fsdev_bus_t type can be used for both register and PMA access necessities
-#ifdef FSDEV_BUS_32BIT
-typedef uint32_t fsdev_bus_t;
-#else
-typedef uint16_t fsdev_bus_t;
-#endif
-
typedef struct {
struct {
_va32 fsdev_bus_t reg;