mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-17 05:32:55 +08:00
read/write packet enhancement, merge 16-bit and 32-bit together
This commit is contained in:
parent
af8609e96e
commit
e180d915c6
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user