From e180d915c64c98ce7349cf4696f23abd55a91e19 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 23:08:12 +0700 Subject: [PATCH] read/write packet enhancement, merge 16-bit and 32-bit together --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 147 ++++++------------ src/portable/st/stm32_fsdev/fsdev_type.h | 24 +-- 2 files changed, 64 insertions(+), 107 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; - } - - return true; -} - -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); - - for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dst8, *src32++); - dst8 += 4; - } - - uint16_t odd = wNBytes & 0x03; - 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); - } - } - } - - 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 - */ +// 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) { - 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); + enum { BUS_SIZE = sizeof(fsdev_bus_t) }; + uint32_t n_write = nbytes / BUS_SIZE; - while (n16--) { - pma16->u16 = tu_unaligned_read16(src8); - src8 += 2; - pma16++; + fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst); + const uint8_t *src8 = src; + + while (n_write--) { + #ifdef FSDEV_BUS_32BIT + pma_buf->value = tu_unaligned_read32(src8); + #else + pma_buf->value = tu_unaligned_read16(src8); + #endif + + src8 += BUS_SIZE; + pma_buf++; } - if (nbytes & 0x01) { - pma16->u16 = (uint16_t) *src8; + // 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 = 0; + for(uint16_t i = 0; i < odd; i++) { + temp |= *src8++ << (i * 8); + } + pma_buf->value = temp; } return true; } -/** - * @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 - */ +// 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) { - uint32_t n16 = (uint32_t)nbytes >> 1U; - fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src); + enum { BUS_SIZE = sizeof(fsdev_bus_t) }; + uint32_t n_write = nbytes / BUS_SIZE; + + fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src); uint8_t *dst8 = (uint8_t *)dst; - while (n16--) { - uint16_t temp16 = pma16->u16; - tu_unaligned_write16(dst8, temp16); - dst8 += 2; - pma16++; + while (n_write--) { + fsdev_bus_t temp = pma_buf->value; + + #ifdef FSDEV_BUS_32BIT + tu_unaligned_write32(dst8, temp); + #else + tu_unaligned_write16(dst8, temp); + #endif + + 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;