mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52: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);
|
ep_write(ep_idx, ep_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FSDEV_BUS_32BIT
|
// Write to packet memory area (PMA) from user memory
|
||||||
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) {
|
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
||||||
const uint8_t *src8 = src;
|
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
||||||
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
|
|
||||||
*/
|
|
||||||
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
|
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
|
||||||
uint32_t n16 = (uint32_t)nbytes >> 1U;
|
enum { BUS_SIZE = sizeof(fsdev_bus_t) };
|
||||||
const uint8_t *src8 = src;
|
uint32_t n_write = nbytes / BUS_SIZE;
|
||||||
fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * dst);
|
|
||||||
|
|
||||||
while (n16--) {
|
fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst);
|
||||||
pma16->u16 = tu_unaligned_read16(src8);
|
const uint8_t *src8 = src;
|
||||||
src8 += 2;
|
|
||||||
pma16++;
|
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) {
|
// odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
|
||||||
pma16->u16 = (uint16_t) *src8;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Read from packet memory area (PMA) to user memory.
|
||||||
* @brief Copy a buffer from packet memory area (PMA) to user memory area.
|
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
||||||
* Uses unaligned for system memory and 16-bit access of packet memory
|
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
||||||
* @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) {
|
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
|
||||||
uint32_t n16 = (uint32_t)nbytes >> 1U;
|
enum { BUS_SIZE = sizeof(fsdev_bus_t) };
|
||||||
fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src);
|
uint32_t n_write = nbytes / BUS_SIZE;
|
||||||
|
|
||||||
|
fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src);
|
||||||
uint8_t *dst8 = (uint8_t *)dst;
|
uint8_t *dst8 = (uint8_t *)dst;
|
||||||
|
|
||||||
while (n16--) {
|
while (n_write--) {
|
||||||
uint16_t temp16 = pma16->u16;
|
fsdev_bus_t temp = pma_buf->value;
|
||||||
tu_unaligned_write16(dst8, temp16);
|
|
||||||
dst8 += 2;
|
#ifdef FSDEV_BUS_32BIT
|
||||||
pma16++;
|
tu_unaligned_write32(dst8, temp);
|
||||||
|
#else
|
||||||
|
tu_unaligned_write16(dst8, temp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dst8 += BUS_SIZE;
|
||||||
|
pma_buf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbytes & 0x01) {
|
// odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
|
||||||
*dst8++ = tu_u16_low(pma16->u16);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copy from FIFO to packet memory area (PMA).
|
* @brief Copy from FIFO to packet memory area (PMA).
|
||||||
* Uses byte-access of system memory and 16-bit access of packet memory
|
* Uses byte-access of system memory and 16-bit access of packet memory
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright(c) 2016 STMicroelectronics
|
|
||||||
* Copyright(c) N Conrad
|
* 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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TUSB_FSDEV_TYPE_H
|
#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
|
#define pma_aligned
|
||||||
#endif
|
#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
|
// 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))
|
#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
volatile pma_aligned uint16_t u16;
|
volatile pma_aligned fsdev_bus_t value;
|
||||||
} fsdev_pma16_t;
|
} fsdev_pma_buf_t;
|
||||||
|
|
||||||
|
#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE*(_addr)))
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Registers Typedef
|
// Registers Typedef
|
||||||
@ -105,13 +114,6 @@ typedef struct {
|
|||||||
// volatile 32-bit aligned
|
// volatile 32-bit aligned
|
||||||
#define _va32 volatile TU_ATTR_ALIGNED(4)
|
#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 {
|
typedef struct {
|
||||||
struct {
|
struct {
|
||||||
_va32 fsdev_bus_t reg;
|
_va32 fsdev_bus_t reg;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user