summaryrefslogtreecommitdiff
path: root/src/portable/st
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-01-09 10:38:47 +0700
committerhathach <[email protected]>2026-01-09 10:38:47 +0700
commit271edeb35bb0ebf38e79bed4b2bcbf34fd40e326 (patch)
tree873b7ddf09b8473fa2f481e4da838124a81c617b /src/portable/st
parent8544db8bf5e6b83527fb0e1d903a70f90cbb8873 (diff)
parent593dce28349cf5b1299c2cf1193312cb783574f3 (diff)
Merge branch 'master' into fork/zhiqiang-ch/master
Diffstat (limited to 'src/portable/st')
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c302
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_at32.h1
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_ch32.h1
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.c173
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.h126
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_stm32.h188
-rw-r--r--src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c18
7 files changed, 294 insertions, 515 deletions
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index 087639d4b..22a9e4af8 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -108,11 +108,10 @@
#include "tusb_option.h"
-#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && \
- !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
+#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
-#include "device/dcd.h"
-#include "fsdev_common.h"
+ #include "device/dcd.h"
+ #include "fsdev_common.h"
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
@@ -120,25 +119,25 @@
// One of these for every EP IN & OUT, uses a bit of RAM....
typedef struct {
- uint8_t *buffer;
+ uint8_t *buffer;
tu_fifo_t *ff;
- uint16_t total_len;
- uint16_t queued_len;
- uint16_t max_packet_size;
- uint8_t ep_idx; // index for USB_EPnR register
- bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask
+ uint16_t total_len;
+ uint16_t queued_len;
+ uint16_t max_packet_size;
+ uint8_t ep_idx; // index for USB_EPnR register
+ bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask
} xfer_ctl_t;
// EP allocator
typedef struct {
uint8_t ep_num;
uint8_t ep_type;
- bool allocated[2];
+ bool allocated[2];
} ep_alloc_t;
static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2];
static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT];
-static uint8_t remoteWakeCountdown; // When wake is requested
+static uint8_t remoteWakeCountdown; // When wake is requested
//--------------------------------------------------------------------+
// Prototypes
@@ -152,12 +151,12 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir);
// PMA allocation/access
static uint16_t ep_buf_ptr; ///< Points to first free memory location
static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf);
-static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type);
+static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type);
static void edpt0_open(uint8_t rhport);
TU_ATTR_ALWAYS_INLINE static inline void edpt0_prepare_setup(void) {
- btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8);
+ btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8);
}
//--------------------------------------------------------------------+
@@ -171,21 +170,21 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint
//--------------------------------------------------------------------+
// Controller API
//--------------------------------------------------------------------+
-bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
- (void) rh_init;
+bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
+ (void)rh_init;
fsdev_core_reset();
FSDEV_REG->CNTR = 0; // Enable USB
-#if !defined(FSDEV_BUS_32BIT)
+ #if !defined(FSDEV_BUS_32BIT)
// BTABLE register does not exist any more on 32-bit bus devices
FSDEV_REG->BTABLE = FSDEV_BTABLE_BASE;
-#endif
+ #endif
// Enable interrupts for device mode
- FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM |
- USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM;
+ FSDEV_REG->CNTR |=
+ USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM;
handle_bus_reset(rhport);
@@ -236,8 +235,8 @@ static void handle_bus_reset(uint8_t rhport) {
for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) {
// Clear EP allocation status
- ep_alloc_status[i].ep_num = 0xFF;
- ep_alloc_status[i].ep_type = 0xFF;
+ ep_alloc_status[i].ep_num = 0xFF;
+ ep_alloc_status[i].ep_type = 0xFF;
ep_alloc_status[i].allocated[0] = false;
ep_alloc_status[i].allocated[1] = false;
}
@@ -245,7 +244,7 @@ static void handle_bus_reset(uint8_t rhport) {
// Reset PMA allocation
ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT;
- edpt0_open(rhport); // open control endpoint (both IN & OUT)
+ edpt0_open(rhport); // open control endpoint (both IN & OUT)
FSDEV_REG->DADDR = USB_DADDR_EF; // Enable USB Function
}
@@ -254,8 +253,8 @@ static void handle_bus_reset(uint8_t rhport) {
static void handle_ctr_tx(uint32_t ep_id) {
uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
- uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN);
+ const uint8_t ep_num = ep_reg & USB_EPADDR_FIELD;
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN);
if (ep_is_iso(ep_reg)) {
// Ignore spurious interrupts that we don't schedule
@@ -265,11 +264,11 @@ static void handle_ctr_tx(uint32_t ep_id) {
return;
}
xfer->iso_in_sending = false;
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
uint8_t buf_id = (ep_reg & USB_EP_DTOG_TX) ? 0 : 1;
-#else
+ #else
uint8_t buf_id = BTABLE_BUF_TX;
-#endif
+ #endif
btable_set_count(ep_id, buf_id, 0);
}
@@ -282,17 +281,17 @@ static void handle_ctr_tx(uint32_t ep_id) {
static void handle_ctr_setup(uint32_t ep_id) {
uint16_t rx_count = btable_get_count(ep_id, BTABLE_BUF_RX);
- uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
- uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
+ uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
+ uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
- fsdev_read_packet_memory(setup_packet, rx_addr, rx_count);
+ tu_hwfifo_read(PMA_BUF_AT(rx_addr), setup_packet, rx_count, NULL);
// Clear CTR RX if another setup packet arrived before this, it will be discarded
ep_write_clear_ctr(ep_id, TUSB_DIR_OUT);
// Setup packet should always be 8 bytes. If not, we probably missed the packet
if (rx_count == 8) {
- dcd_event_setup_received(0, (uint8_t*) setup_packet, true);
+ dcd_event_setup_received(0, (uint8_t *)setup_packet, true);
// Hardware should reset EP0 RX/TX to NAK and both toggle to 1
} else {
// Missed setup packet !!!
@@ -303,29 +302,30 @@ static void handle_ctr_setup(uint32_t ep_id) {
// Handle CTR interrupt for the RX/OUT direction
static void handle_ctr_rx(uint32_t ep_id) {
- uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
- uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
- bool const is_iso = ep_is_iso(ep_reg);
- xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT);
+ uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
+ const uint8_t ep_num = ep_reg & USB_EPADDR_FIELD;
+ const bool is_iso = ep_is_iso(ep_reg);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT);
uint8_t buf_id;
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = is_iso;
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
if (dbl_buf) {
buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1;
} else {
buf_id = BTABLE_BUF_RX;
}
- uint16_t const rx_count = btable_get_count(ep_id, buf_id);
- uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id);
+ const uint16_t rx_count = btable_get_count(ep_id, buf_id);
+ uint16_t pma_addr = (uint16_t)btable_get_addr(ep_id, buf_id);
+ fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(pma_addr);
if (xfer->ff) {
- fsdev_read_packet_memory_ff(xfer->ff, pma_addr, rx_count);
+ tu_hwfifo_read_to_fifo(pma_buf, xfer->ff, rx_count, NULL);
} else {
- fsdev_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count);
+ tu_hwfifo_read(pma_buf, xfer->buffer + xfer->queued_len, rx_count, NULL);
}
xfer->queued_len += rx_count;
@@ -343,7 +343,7 @@ static void handle_ctr_rx(uint32_t ep_id) {
} else {
// Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always
if (!is_iso) {
- uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
+ const uint16_t cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt);
}
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits
@@ -403,18 +403,18 @@ void dcd_int_handler(uint8_t rhport) {
// loop to handle all pending CTR interrupts
while (FSDEV_REG->ISTR & USB_ISTR_CTR) {
// skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt
- uint32_t const ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID;
- uint32_t const ep_reg = ep_read(ep_id);
+ const uint32_t ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID;
+ const uint32_t ep_reg = ep_read(ep_id);
if (ep_reg & USB_EP_CTR_RX) {
- #ifdef FSDEV_BUS_32BIT
+ #ifdef FSDEV_BUS_32BIT
/* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf
* https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf
* From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers
* Description:
- * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses
- * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct.
- * Workaround:
+ * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM
+ * accesses have completed. If the software responds quickly to the interrupt, the full buffer contents may not be
+ * correct. Workaround:
* - Software should ensure that a small delay is included before accessing the SRAM contents. This delay
* should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode
* - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code
@@ -425,9 +425,9 @@ void dcd_int_handler(uint8_t rhport) {
*/
volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver
while (cycle_count > 0U) {
- cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
+ cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
}
- #endif
+ #endif
if (ep_reg & USB_EP_SETUP) {
handle_ctr_setup(ep_id); // CTR will be clear after copied setup packet
@@ -455,14 +455,13 @@ void dcd_int_handler(uint8_t rhport) {
// Invoked when a control transfer's status stage is complete.
// May help DCD to prepare for next control transfer, this API is optional.
-void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) {
+void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *request) {
(void)rhport;
if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE &&
- request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD &&
- request->bRequest == TUSB_REQ_SET_ADDRESS) {
- uint8_t const dev_addr = (uint8_t)request->wValue;
- FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr);
+ request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) {
+ const uint8_t dev_addr = (uint8_t)request->wValue;
+ FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr);
}
edpt0_prepare_setup();
@@ -473,15 +472,14 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req
* In case of double buffering, high 16bit is the address of 2nd buffer
* During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually.
*/
-static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf)
-{
- uint8_t blsize, num_block;
+static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf) {
+ uint8_t blsize, num_block;
uint16_t aligned_len = pma_align_buffer_size(len, &blsize, &num_block);
- (void) blsize;
- (void) num_block;
+ (void)blsize;
+ (void)num_block;
uint32_t addr = ep_buf_ptr;
- ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer
+ ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer
if (dbuf) {
addr |= ((uint32_t)ep_buf_ptr) << 16;
@@ -489,7 +487,7 @@ static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf)
}
// Verify packet buffer is not overflowed
- TU_ASSERT(ep_buf_ptr <= FSDEV_PMA_SIZE, 0xFFFF);
+ TU_ASSERT(ep_buf_ptr <= CFG_TUSB_FSDEV_PMA_SIZE, 0xFFFF);
return addr;
}
@@ -497,35 +495,32 @@ static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf)
/***
* Allocate hardware endpoint
*/
-static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
-{
- uint8_t const epnum = tu_edpt_number(ep_addr);
- uint8_t const dir = tu_edpt_dir(ep_addr);
+static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) {
+ const uint8_t epnum = tu_edpt_number(ep_addr);
+ const uint8_t dir = tu_edpt_dir(ep_addr);
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
// Check if already allocated
- if (ep_alloc_status[i].allocated[dir] &&
- ep_alloc_status[i].ep_type == ep_type &&
+ if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type &&
ep_alloc_status[i].ep_num == epnum) {
return i;
}
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = ep_type == TUSB_XFER_ISOCHRONOUS;
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
// If EP of current direction is not allocated
// For double-buffered mode both directions needs to be free
- if (!ep_alloc_status[i].allocated[dir] &&
- (!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) {
+ if (!ep_alloc_status[i].allocated[dir] && (!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) {
// Check if EP number is the same
if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) {
// One EP pair has to be the same type
if (ep_alloc_status[i].ep_type == 0xFF || ep_alloc_status[i].ep_type == ep_type) {
- ep_alloc_status[i].ep_num = epnum;
- ep_alloc_status[i].ep_type = ep_type;
+ ep_alloc_status[i].ep_num = epnum;
+ ep_alloc_status[i].ep_type = ep_type;
ep_alloc_status[i].allocated[dir] = true;
return i;
@@ -539,16 +534,16 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
}
void edpt0_open(uint8_t rhport) {
- (void) rhport;
+ (void)rhport;
dcd_ep_alloc(0x0, TUSB_XFER_CONTROL);
dcd_ep_alloc(0x80, TUSB_XFER_CONTROL);
xfer_status[0][0].max_packet_size = CFG_TUD_ENDPOINT0_SIZE;
- xfer_status[0][0].ep_idx = 0;
+ xfer_status[0][0].ep_idx = 0;
xfer_status[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE;
- xfer_status[0][1].ep_idx = 0;
+ xfer_status[0][1].ep_idx = 0;
uint16_t pma_addr0 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false);
uint16_t pma_addr1 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false);
@@ -566,13 +561,13 @@ void edpt0_open(uint8_t rhport) {
ep_write(0, ep_reg, false);
}
-bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
+bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) {
(void)rhport;
- uint8_t const ep_addr = desc_ep->bEndpointAddress;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
- uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
+ const uint8_t ep_addr = desc_ep->bEndpointAddress;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
+ const uint8_t ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
TU_ASSERT(ep_idx < FSDEV_EP_COUNT);
uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK;
@@ -596,9 +591,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
uint16_t pma_addr = dcd_pma_alloc(packet_size, false);
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
xfer->max_packet_size = packet_size;
- xfer->ep_idx = ep_idx;
+ xfer->ep_idx = ep_idx;
ep_change_status(&ep_reg, dir, EP_STAT_NAK);
ep_change_dtog(&ep_reg, dir, 0);
@@ -622,8 +617,8 @@ void dcd_edpt_close_all(uint8_t rhport) {
// Reset endpoint
ep_write(i, 0, false);
// Clear EP allocation status
- ep_alloc_status[i].ep_num = 0xFF;
- ep_alloc_status[i].ep_type = 0xFF;
+ ep_alloc_status[i].ep_num = 0xFF;
+ ep_alloc_status[i].ep_type = 0xFF;
ep_alloc_status[i].allocated[0] = false;
ep_alloc_status[i].allocated[1] = false;
}
@@ -637,46 +632,46 @@ void dcd_edpt_close_all(uint8_t rhport) {
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
(void)rhport;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- uint8_t const dir = tu_edpt_dir(ep_addr);
- uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const uint8_t dir = tu_edpt_dir(ep_addr);
+ const uint8_t ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
-#if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0
- uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
+ #if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0
+ uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
uint16_t pma_addr2 = pma_addr >> 16;
-#else
- uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false);
+ #else
+ uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false);
uint16_t pma_addr2 = pma_addr;
-#endif
+ #endif
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
btable_set_addr(ep_idx, 0, pma_addr);
btable_set_addr(ep_idx, 1, pma_addr2);
-#else
+ #else
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
- (void) pma_addr2;
-#endif
+ (void)pma_addr2;
+ #endif
- xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
- xfer->ep_idx = ep_idx;
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ xfer->ep_idx = ep_idx;
return true;
}
-bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
+bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) {
(void)rhport;
- uint8_t const ep_addr = desc_ep->bEndpointAddress;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_addr = desc_ep->bEndpointAddress;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ const uint8_t ep_idx = xfer->ep_idx;
xfer->max_packet_size = tu_edpt_packet_size(desc_ep);
uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK;
ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX;
-#if FSDEV_USE_SBUF_ISO != 0
+ #if FSDEV_USE_SBUF_ISO != 0
ep_reg |= USB_EP_KIND;
ep_change_status(&ep_reg, dir, EP_STAT_DISABLED);
@@ -687,12 +682,12 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
} else {
ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX);
}
-#else
+ #else
ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
ep_change_dtog(&ep_reg, dir, 0);
ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1);
-#endif
+ #endif
ep_write(ep_idx, ep_reg, true);
@@ -701,28 +696,29 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
// Currently, single-buffered, and only 64 bytes at a time (max)
static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
- uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
+ uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR
- bool const is_iso = ep_is_iso(ep_reg);
+ const bool is_iso = ep_is_iso(ep_reg);
uint8_t buf_id;
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = is_iso;
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
if (dbl_buf) {
buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0;
} else {
buf_id = BTABLE_BUF_TX;
}
- uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id);
+ uint16_t addr_ptr = (uint16_t)btable_get_addr(ep_ix, buf_id);
+ fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(addr_ptr);
if (xfer->ff) {
- fsdev_write_packet_memory_ff(xfer->ff, addr_ptr, len);
+ tu_hwfifo_write_from_fifo(pma_buf, xfer->ff, len, NULL);
} else {
- fsdev_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len);
+ tu_hwfifo_write(pma_buf, &(xfer->buffer[xfer->queued_len]), len, NULL);
}
xfer->queued_len += len;
@@ -737,10 +733,10 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
}
static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
- (void) rhport;
+ (void)rhport;
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_idx = xfer->ep_idx;
if (dir == TUSB_DIR_IN) {
dcd_transmit_packet(xfer, ep_idx);
@@ -750,11 +746,11 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size);
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = ep_is_iso(ep_reg);
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
if (dbl_buf) {
btable_set_rx_bufsize(ep_idx, 0, cnt);
btable_set_rx_bufsize(ep_idx, 1, cnt);
@@ -769,29 +765,29 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
return true;
}
-bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr) {
- (void) is_isr;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) {
+ (void)is_isr;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- xfer->buffer = buffer;
- xfer->ff = NULL;
- xfer->total_len = total_bytes;
+ xfer->buffer = buffer;
+ xfer->ff = NULL;
+ xfer->total_len = total_bytes;
xfer->queued_len = 0;
return edpt_xfer(rhport, ep_num, dir);
}
-bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr) {
- (void) is_isr;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) {
+ (void)is_isr;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- xfer->buffer = NULL;
- xfer->ff = ff;
- xfer->total_len = total_bytes;
+ xfer->buffer = NULL;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
xfer->queued_len = 0;
return edpt_xfer(rhport, ep_num, dir);
@@ -799,10 +795,10 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
(void)rhport;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_idx = xfer->ep_idx;
uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir);
@@ -814,10 +810,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
(void)rhport;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_idx = xfer->ep_idx;
uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir);
@@ -837,7 +833,7 @@ void dcd_int_disable(uint8_t rhport) {
fsdev_int_disable(rhport);
}
-#if defined(USB_BCDR_DPPU) || defined(SYSCFG_PMC_USB_PU)
+ #if defined(USB_BCDR_DPPU) || defined(SYSCFG_PMC_USB_PU)
void dcd_connect(uint8_t rhport) {
fsdev_connect(rhport);
}
@@ -845,6 +841,6 @@ void dcd_connect(uint8_t rhport) {
void dcd_disconnect(uint8_t rhport) {
fsdev_disconnect(rhport);
}
-#endif
+ #endif
#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_at32.h b/src/portable/st/stm32_fsdev/fsdev_at32.h
index 6877dc131..e75430396 100644
--- a/src/portable/st/stm32_fsdev/fsdev_at32.h
+++ b/src/portable/st/stm32_fsdev/fsdev_at32.h
@@ -35,7 +35,6 @@
#endif
-#define FSDEV_PMA_SIZE (512u)
#define FSDEV_USE_SBUF_ISO 0
#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h
index ee0057cb4..37ea7808e 100644
--- a/src/portable/st/stm32_fsdev/fsdev_ch32.h
+++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h
@@ -53,7 +53,6 @@
#pragma GCC diagnostic pop
#endif
-#define FSDEV_PMA_SIZE (512u)
#define FSDEV_USE_SBUF_ISO 0
#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
diff --git a/src/portable/st/stm32_fsdev/fsdev_common.c b/src/portable/st/stm32_fsdev/fsdev_common.c
index 5d60ad9a2..4f127ae86 100644
--- a/src/portable/st/stm32_fsdev/fsdev_common.c
+++ b/src/portable/st/stm32_fsdev/fsdev_common.c
@@ -69,179 +69,6 @@ void fsdev_deinit(void) {
}
}
-
-//--------------------------------------------------------------------+
-// PMA read/write
-//--------------------------------------------------------------------+
-
-// 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)
-bool fsdev_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
- if (nbytes == 0) {
- return true;
- }
- uint32_t n_write = nbytes / FSDEV_BUS_SIZE;
-
- fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst);
- const uint8_t *src8 = src;
-
- while (n_write--) {
- pma_buf->value = fsdevbus_unaligned_read(src8);
- src8 += FSDEV_BUS_SIZE;
- pma_buf++;
- }
-
- // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
- uint16_t odd = nbytes & (FSDEV_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;
-}
-
-// 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)
-bool fsdev_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
- if (nbytes == 0) {
- return true;
- }
- uint32_t n_read = nbytes / FSDEV_BUS_SIZE;
-
- fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src);
- uint8_t *dst8 = (uint8_t *)dst;
-
- while (n_read--) {
- fsdevbus_unaligned_write(dst8, (fsdev_bus_t ) pma_buf->value);
- dst8 += FSDEV_BUS_SIZE;
- pma_buf++;
- }
-
- // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
- uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
- if (odd) {
- fsdev_bus_t temp = pma_buf->value;
- while (odd--) {
- *dst8++ = (uint8_t) (temp & 0xfful);
- temp >>= 8;
- }
- }
-
- return true;
-}
-
-// Write to PMA from FIFO
-bool fsdev_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) {
- if (wNBytes == 0) {
- return true;
- }
-
- // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
- tu_fifo_buffer_info_t info;
- tu_fifo_get_read_info(ff, &info);
-
- uint16_t cnt_lin = tu_min16(wNBytes, info.linear.len);
- uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.wrapped.len);
- uint16_t const cnt_total = cnt_lin + cnt_wrap;
-
- // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
- // last lin byte will be combined with wrapped part To ensure PMA is always access aligned
- uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
- uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
- uint8_t const *src8 = (uint8_t const*) info.linear.ptr;
-
- // write even linear part
- fsdev_write_packet_memory(dst, src8, lin_even);
- dst += lin_even;
- src8 += lin_even;
-
- if (lin_odd == 0) {
- src8 = (uint8_t const*) info.wrapped.ptr;
- } else {
- // Combine last linear bytes + first wrapped bytes to form fsdev bus width data
- fsdev_bus_t temp = 0;
- uint16_t i;
- for(i = 0; i < lin_odd; i++) {
- temp |= *src8++ << (i * 8);
- }
-
- src8 = (uint8_t const*) info.wrapped.ptr;
- for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
- temp |= *src8++ << (i * 8);
- }
-
- fsdev_write_packet_memory(dst, &temp, FSDEV_BUS_SIZE);
- dst += FSDEV_BUS_SIZE;
- }
-
- // write the rest of the wrapped part
- fsdev_write_packet_memory(dst, src8, cnt_wrap);
-
- tu_fifo_advance_read_pointer(ff, cnt_total);
- return true;
-}
-
-// Read from PMA to FIFO
-bool fsdev_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) {
- if (wNBytes == 0) {
- return true;
- }
-
- // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
- // Check for first linear part
- tu_fifo_buffer_info_t info;
- tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO
-
- uint16_t cnt_lin = tu_min16(wNBytes, info.linear.len);
- uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.wrapped.len);
- uint16_t cnt_total = cnt_lin + cnt_wrap;
-
- // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
- // last lin byte will be combined with wrapped part To ensure PMA is always access aligned
-
- uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
- uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
- uint8_t *dst8 = (uint8_t *) info.linear.ptr;
-
- // read even linear part
- fsdev_read_packet_memory(dst8, src, lin_even);
- dst8 += lin_even;
- src += lin_even;
-
- if (lin_odd == 0) {
- dst8 = (uint8_t *) info.wrapped.ptr;
- } else {
- // Combine last linear bytes + first wrapped bytes to form fsdev bus width data
- fsdev_bus_t temp;
- fsdev_read_packet_memory(&temp, src, FSDEV_BUS_SIZE);
- src += FSDEV_BUS_SIZE;
-
- uint16_t i;
- for (i = 0; i < lin_odd; i++) {
- *dst8++ = (uint8_t) (temp & 0xfful);
- temp >>= 8;
- }
-
- dst8 = (uint8_t *) info.wrapped.ptr;
- for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
- *dst8++ = (uint8_t) (temp & 0xfful);
- temp >>= 8;
- }
- }
-
- // read the rest of the wrapped part
- fsdev_read_packet_memory(dst8, src, cnt_wrap);
-
- tu_fifo_advance_write_pointer(ff, cnt_total);
- return true;
-}
-
//--------------------------------------------------------------------+
// BTable Helper
//--------------------------------------------------------------------+
diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h
index 0c67ee0c7..c53e345b0 100644
--- a/src/portable/st/stm32_fsdev/fsdev_common.h
+++ b/src/portable/st/stm32_fsdev/fsdev_common.h
@@ -32,11 +32,11 @@
#include "common/tusb_common.h"
#if CFG_TUD_ENABLED
-#include "device/dcd.h"
+ #include "device/dcd.h"
#endif
#if CFG_TUH_ENABLED
-#include "host/hcd.h"
+ #include "host/hcd.h"
#endif
#if defined(TUP_USBIP_FSDEV_STM32)
@@ -56,41 +56,37 @@ extern "C" {
// 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
+ #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.
+// CFG_TUSB_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)
// - 2048-byte devices, access with 32-bit address
// For purposes of accessing the packet
-#if FSDEV_PMA_SIZE == 512
+#if CFG_TUSB_FSDEV_PMA_SIZE == 512
// 1x16 bit / word access scheme
#define FSDEV_PMA_STRIDE 2
#define pma_access_scheme TU_ATTR_ALIGNED(4)
-#elif FSDEV_PMA_SIZE == 1024
+#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024
// 2x16 bit / word access scheme
- #define FSDEV_PMA_STRIDE 1
+ #define FSDEV_PMA_STRIDE 1
#define pma_access_scheme
-#elif FSDEV_PMA_SIZE == 2048
+#elif CFG_TUSB_FSDEV_PMA_SIZE == 2048
// 32 bit access scheme
#define FSDEV_BUS_32BIT
- #define FSDEV_PMA_STRIDE 1
+ #define FSDEV_PMA_STRIDE 1
#define pma_access_scheme
#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;
- #define fsdevbus_unaligned_read(_addr) tu_unaligned_read32(_addr)
- #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write32(_addr, _value)
+typedef uint32_t fsdev_bus_t;
#else
- typedef uint16_t fsdev_bus_t;
- #define fsdevbus_unaligned_read(_addr) tu_unaligned_read16(_addr)
- #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write16(_addr, _value)
+typedef uint16_t fsdev_bus_t;
#endif
enum {
@@ -124,77 +120,77 @@ typedef union {
} ep32[FSDEV_EP_COUNT][2];
} 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");
+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 <= CFG_TUSB_FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM");
-#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(FSDEV_BTABLE_BASE)))
+#define FSDEV_BTABLE ((volatile fsdev_btable_t *)(FSDEV_PMA_BASE + FSDEV_PMA_STRIDE * (FSDEV_BTABLE_BASE)))
typedef struct {
volatile pma_access_scheme fsdev_bus_t value;
} fsdev_pma_buf_t;
-#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(_addr)))
+#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t *)(FSDEV_PMA_BASE + FSDEV_PMA_STRIDE * (_addr)))
//--------------------------------------------------------------------+
// Registers Typedef
//--------------------------------------------------------------------+
// volatile 32-bit aligned
-#define _va32 volatile TU_ATTR_ALIGNED(4)
+#define _va32 volatile TU_ATTR_ALIGNED(4)
typedef struct {
struct {
_va32 fsdev_bus_t reg;
- }ep[FSDEV_EP_COUNT];
+ } ep[FSDEV_EP_COUNT];
- _va32 uint32_t RESERVED7[8]; // Reserved
- _va32 fsdev_bus_t CNTR; // 40: Control register
- _va32 fsdev_bus_t ISTR; // 44: Interrupt status register
- _va32 fsdev_bus_t FNR; // 48: Frame number register
- _va32 fsdev_bus_t DADDR; // 4C: Device address register
- _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only)
- _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only)
- _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only)
+ _va32 uint32_t RESERVED7[8]; // Reserved
+ _va32 fsdev_bus_t CNTR; // 40: Control register
+ _va32 fsdev_bus_t ISTR; // 44: Interrupt status register
+ _va32 fsdev_bus_t FNR; // 48: Frame number register
+ _va32 fsdev_bus_t DADDR; // 4C: Device address register
+ _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only)
+ _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only)
+ _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only)
} fsdev_regs_t;
TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset");
TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
-#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE)
+#define FSDEV_REG ((fsdev_regs_t *)FSDEV_REG_BASE)
#ifndef USB_EPTX_STAT
-#define USB_EPTX_STAT 0x0030U
+ #define USB_EPTX_STAT 0x0030U
#endif
#ifndef USB_EPRX_STAT
-#define USB_EPRX_STAT 0x3000U
+ #define USB_EPRX_STAT 0x3000U
#endif
#ifndef USB_EPTX_STAT_Pos
-#define USB_EPTX_STAT_Pos 4u
+ #define USB_EPTX_STAT_Pos 4u
#endif
#ifndef USB_EP_DTOG_TX_Pos
-#define USB_EP_DTOG_TX_Pos 6u
+ #define USB_EP_DTOG_TX_Pos 6u
#endif
#ifndef USB_EP_CTR_TX_Pos
-#define USB_EP_CTR_TX_Pos 7u
+ #define USB_EP_CTR_TX_Pos 7u
#endif
typedef enum {
EP_STAT_DISABLED = 0,
- EP_STAT_STALL = 1,
- EP_STAT_NAK = 2,
- EP_STAT_VALID = 3
-}ep_stat_t;
+ EP_STAT_STALL = 1,
+ EP_STAT_NAK = 2,
+ EP_STAT_VALID = 3
+} ep_stat_t;
-#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
-#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
+#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
+#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
-#define CH_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
-#define CH_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
+#define CH_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
+#define CH_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
//--------------------------------------------------------------------+
// Endpoint Helper
@@ -211,7 +207,7 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value
fsdev_int_disable(0);
}
- FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value;
+ FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t)value;
if (need_exclusive) {
fsdev_int_enable(0);
@@ -226,11 +222,11 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb
ep_write(ep_id, reg, false);
}
-TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) {
+TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) {
*reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
}
-TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) {
+TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) {
*reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
}
@@ -259,11 +255,11 @@ TU_ATTR_ALWAYS_INLINE static inline void ch_write_clear_ctr(uint32_t ch_id, tusb
ep_write(ch_id, reg, false);
}
-TU_ATTR_ALWAYS_INLINE static inline void ch_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) {
+TU_ATTR_ALWAYS_INLINE static inline void ch_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) {
*reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 8 : 0)));
}
-TU_ATTR_ALWAYS_INLINE static inline void ch_change_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) {
+TU_ATTR_ALWAYS_INLINE static inline void ch_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) {
*reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0)));
}
@@ -281,8 +277,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uin
TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) {
#ifdef FSDEV_BUS_32BIT
- uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
- count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu);
+ uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
+ count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu);
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
#else
FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr;
@@ -301,12 +297,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, ui
TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) {
#ifdef FSDEV_BUS_32BIT
- uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
- count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16);
+ uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
+ count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16);
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
#else
- uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
- cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU);
+ uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
+ cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU);
FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt;
#endif
}
@@ -318,31 +314,11 @@ void fsdev_core_reset(void);
void fsdev_deinit(void);
// Aligned buffer size according to hardware
-uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block);
+uint16_t pma_align_buffer_size(uint16_t size, uint8_t *blsize, uint8_t *num_block);
// Set RX buffer size
void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount);
-//--------------------------------------------------------------------+
-// PMA (Packet Memory Area) Access
-//--------------------------------------------------------------------+
-
-// 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)
-bool fsdev_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes);
-
-// 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)
-bool fsdev_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes);
-
-// Write to PMA from FIFO
-bool fsdev_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes);
-
-// Read from PMA to FIFO
-bool fsdev_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h
index 4b7d3d301..02dba05a6 100644
--- a/src/portable/st/stm32_fsdev/fsdev_stm32.h
+++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h
@@ -32,10 +32,23 @@
#ifndef TUSB_FSDEV_STM32_H
#define TUSB_FSDEV_STM32_H
-#if CFG_TUSB_MCU == OPT_MCU_STM32F0
+#if CFG_TUSB_MCU == OPT_MCU_STM32C0
+ #include "stm32c0xx.h"
+ #define FSDEV_HAS_SBUF_ISO 1
+ #define USB USB_DRD_FS
+ #define USB_EP_CTR_RX USB_CHEP_VTRX
+ #define USB_EP_CTR_TX USB_CHEP_VTTX
+ #define USB_EPREG_MASK USB_CHEP_REG_MASK
+ #define USB_CNTR_FRES USB_CNTR_USBRST
+ #define USB_CNTR_RESUME USB_CNTR_L2RES
+ #define USB_ISTR_EP_ID USB_ISTR_IDN
+ #define USB_EPADDR_FIELD USB_CHEP_ADDR
+ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32F0
#include "stm32f0xx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_REG_BASE USB_BASE
+ #define FSDEV_REG_BASE USB_BASE
#define FSDEV_HAS_SBUF_ISO 0
// F0x2 models are crystal-less
// All have internal D+ pull-up
@@ -44,29 +57,24 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
#include "stm32f1xx.h"
- #define FSDEV_PMA_SIZE (512u)
#define FSDEV_HAS_SBUF_ISO 0
// NO internal Pull-ups
// *B, and *C: 2 x 16 bits/word
// F1 names this differently from the rest
- #define USB_CNTR_LPMODE USB_CNTR_LP_MODE
+ #define USB_CNTR_LPMODE USB_CNTR_LP_MODE
-#elif defined(STM32F302xB) || defined(STM32F302xC) || \
- defined(STM32F303xB) || defined(STM32F303xC) || \
- defined(STM32F373xC)
+#elif defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F303xB) || defined(STM32F303xC) || \
+ defined(STM32F373xC)
#include "stm32f3xx.h"
- #define FSDEV_PMA_SIZE (512u)
#define FSDEV_HAS_SBUF_ISO 0
// NO internal Pull-ups
// *B, and *C: 1 x 16 bits/word
// PMA dedicated to USB (no sharing with CAN)
-#elif defined(STM32F302x6) || defined(STM32F302x8) || \
- defined(STM32F302xD) || defined(STM32F302xE) || \
- defined(STM32F303xD) || defined(STM32F303xE)
+#elif defined(STM32F302x6) || defined(STM32F302x8) || defined(STM32F302xD) || defined(STM32F302xE) || \
+ defined(STM32F303xD) || defined(STM32F303xE)
#include "stm32f3xx.h"
- #define FSDEV_PMA_SIZE (1024u)
#define FSDEV_HAS_SBUF_ISO 0
// NO internal Pull-ups
// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support
@@ -74,28 +82,32 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
#include "stm32l0xx.h"
- #define FSDEV_PMA_SIZE (1024u)
#define FSDEV_HAS_SBUF_ISO 0
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
#include "stm32l1xx.h"
- #define FSDEV_PMA_SIZE (512u)
#define FSDEV_HAS_SBUF_ISO 0
-#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
- #include "stm32g4xx.h"
- #define FSDEV_PMA_SIZE (1024u)
+#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
+ #include "stm32l4xx.h"
+ #define FSDEV_HAS_SBUF_ISO 0
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
+ #include "stm32l5xx.h"
#define FSDEV_HAS_SBUF_ISO 0
+ #ifndef USB_PMAADDR
+ #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
+ #endif
+
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
#include "stm32g0xx.h"
- #define FSDEV_PMA_SIZE (2048u)
- #define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
+ #define FSDEV_HAS_SBUF_ISO 1
+ #define USB USB_DRD_FS
- #define USB_EP_CTR_RX USB_EP_VTRX
- #define USB_EP_CTR_TX USB_EP_VTTX
- #define USB_EP_T_FIELD USB_CHEP_UTYPE
+ #define USB_EP_CTR_RX USB_EP_VTRX
+ #define USB_EP_CTR_TX USB_EP_VTTX
+ #define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
@@ -110,78 +122,20 @@
#define USB_ISTR_EP_ID USB_ISTR_IDN
#define USB_EPADDR_FIELD USB_CHEP_ADDR
#define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
-#elif CFG_TUSB_MCU == OPT_MCU_STM32C0
- #include "stm32c0xx.h"
- #define FSDEV_PMA_SIZE (2048u)
- #define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
- #define USB_EP_CTR_RX USB_CHEP_VTRX
- #define USB_EP_CTR_TX USB_CHEP_VTTX
- #define USB_EPREG_MASK USB_CHEP_REG_MASK
- #define USB_CNTR_FRES USB_CNTR_USBRST
- #define USB_CNTR_RESUME USB_CNTR_L2RES
- #define USB_ISTR_EP_ID USB_ISTR_IDN
- #define USB_EPADDR_FIELD USB_CHEP_ADDR
- #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
+ #include "stm32g4xx.h"
+ #define FSDEV_HAS_SBUF_ISO 0
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
#include "stm32h5xx.h"
- #define FSDEV_PMA_SIZE (2048u)
- #define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
-
- #define USB_EP_CTR_RX USB_EP_VTRX
- #define USB_EP_CTR_TX USB_EP_VTTX
- #define USB_EP_T_FIELD USB_CHEP_UTYPE
- #define USB_EPREG_MASK USB_CHEP_REG_MASK
- #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
- #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
- #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
- #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
- #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
- #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
- #define USB_EPRX_STAT USB_CH_RX_VALID
- #define USB_EPKIND_MASK USB_EP_KIND_MASK
- #define USB_CNTR_FRES USB_CNTR_USBRST
- #define USB_CNTR_RESUME USB_CNTR_L2RES
- #define USB_ISTR_EP_ID USB_ISTR_IDN
- #define USB_EPADDR_FIELD USB_CHEP_ADDR
- #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
- #include "stm32wbxx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_HAS_SBUF_ISO 0
- /* ST provided header has incorrect value of USB_PMAADDR */
- #define FSDEV_PMA_BASE USB1_PMAADDR
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
- #include "stm32l4xx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_HAS_SBUF_ISO 0
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
- #include "stm32l5xx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_HAS_SBUF_ISO 0
-
- #ifndef USB_PMAADDR
- #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
- #endif
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
- #include "stm32u5xx.h"
- #define FSDEV_PMA_SIZE (2048u)
#define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
+ #define USB USB_DRD_FS
- #define USB_EP_CTR_RX USB_EP_VTRX
- #define USB_EP_CTR_TX USB_EP_VTTX
- #define USB_EP_T_FIELD USB_CHEP_UTYPE
+ #define USB_EP_CTR_RX USB_EP_VTRX
+ #define USB_EP_CTR_TX USB_EP_VTTX
+ #define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
@@ -200,7 +154,6 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32U0
#include "stm32u0xx.h"
- #define FSDEV_PMA_SIZE (1024u)
#define FSDEV_BUS_32BIT
#define FSDEV_HAS_SBUF_ISO 1
#define USB USB_DRD_FS
@@ -226,10 +179,9 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32U3
#include "stm32u3xx.h"
- #define FSDEV_PMA_SIZE (2048u)
#define FSDEV_BUS_32BIT
#define FSDEV_HAS_SBUF_ISO 1 // This is assumed to work but has not been tested...
- #define USB USB_DRD_FS
+ #define USB USB_DRD_FS
#define USB_EP_CTR_RX USB_EP_VTRX
#define USB_EP_CTR_TX USB_EP_VTTX
@@ -240,15 +192,45 @@
#define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
#define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
#define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
- #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
- #define USB_EPRX_STAT USB_CH_RX_VALID
- #define USB_EPKIND_MASK USB_EP_KIND_MASK
- #define USB_CNTR_FRES USB_CNTR_USBRST
- #define USB_CNTR_RESUME USB_CNTR_L2RES
- #define USB_ISTR_EP_ID USB_ISTR_IDN
- #define USB_EPADDR_FIELD USB_CHEP_ADDR
- #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
+ #define USB_EPRX_STAT USB_CH_RX_VALID
+ #define USB_EPKIND_MASK USB_EP_KIND_MASK
+ #define USB_CNTR_FRES USB_CNTR_USBRST
+ #define USB_CNTR_RESUME USB_CNTR_L2RES
+ #define USB_ISTR_EP_ID USB_ISTR_IDN
+ #define USB_EPADDR_FIELD USB_CHEP_ADDR
+ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
+ #include "stm32u5xx.h"
+ #define FSDEV_HAS_SBUF_ISO 1
+ #define USB USB_DRD_FS
+
+ #define USB_EP_CTR_RX USB_EP_VTRX
+ #define USB_EP_CTR_TX USB_EP_VTTX
+ #define USB_EP_T_FIELD USB_CHEP_UTYPE
+ #define USB_EPREG_MASK USB_CHEP_REG_MASK
+ #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
+ #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
+ #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
+ #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
+ #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
+ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
+ #define USB_EPRX_STAT USB_CH_RX_VALID
+ #define USB_EPKIND_MASK USB_EP_KIND_MASK
+ #define USB_CNTR_FRES USB_CNTR_USBRST
+ #define USB_CNTR_RESUME USB_CNTR_L2RES
+ #define USB_ISTR_EP_ID USB_ISTR_IDN
+ #define USB_EPADDR_FIELD USB_CHEP_ADDR
+ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
+ #include "stm32wbxx.h"
+ #define FSDEV_HAS_SBUF_ISO 0
+ /* ST provided header has incorrect value of USB_PMAADDR */
+ #define FSDEV_PMA_BASE USB1_PMAADDR
#else
#error You are using an untested or unimplemented STM32 variant. Please update the driver.
@@ -299,7 +281,7 @@
// - Enable double buffering on devices with >1KB Packet Memory Area (PMA)
// to improve isochronous transfer reliability and performance
// - Disable on devices with limited PMA to conserve memory space
- #if FSDEV_PMA_SIZE > 1024u
+ #if CFG_TUSB_FSDEV_PMA_SIZE > 1024u
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1
#else
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0
diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
index da9c6961c..acdeccf6d 100644
--- a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
@@ -303,10 +303,12 @@ static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
- if (ep_id == TUSB_INDEX_INVALID_8) return;
+ if (ep_id == TUSB_INDEX_INVALID_8) {
+ return;
+ }
- hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
- hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
+ hcd_channel_t *channel = &_hcd_data.channel[ch_id];
if (dir == TUSB_DIR_OUT) {
// OUT/TX direction
@@ -314,7 +316,7 @@ static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
// More data to send
uint16_t const len = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size);
uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_TX);
- fsdev_write_packet_memory(pma_addr, &(edpt->buffer[edpt->queued_len]), len);
+ tu_hwfifo_write(PMA_BUF_AT(pma_addr), &(edpt->buffer[edpt->queued_len]), len, NULL);
btable_set_count(ch_id, BTABLE_BUF_TX, len);
edpt->queued_len += len;
channel_write_status(ch_id, ch_reg, TUSB_DIR_OUT, EP_STAT_VALID, false);
@@ -329,8 +331,7 @@ static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
// IN/RX direction
uint16_t const rx_count = channel_get_rx_count(ch_id);
uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_RX);
-
- fsdev_read_packet_memory(edpt->buffer + edpt->queued_len, pma_addr, rx_count);
+ tu_hwfifo_read(PMA_BUF_AT(pma_addr), edpt->buffer + edpt->queued_len, rx_count, NULL);
edpt->queued_len += rx_count;
if ((rx_count < edpt->max_packet_size) || (edpt->queued_len >= edpt->buflen)) {
@@ -740,7 +741,7 @@ static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len) {
uint16_t addr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT;
addr += channel * TUSB_EPSIZE_BULK_FS * 2 + (dir == TUSB_DIR_IN ? TUSB_EPSIZE_BULK_FS : 0);
- TU_ASSERT(addr <= FSDEV_PMA_SIZE, 0xFFFF);
+ TU_ASSERT(addr <= CFG_TUSB_FSDEV_PMA_SIZE, 0xFFFF);
return addr;
}
@@ -841,8 +842,7 @@ static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) {
if (dir == TUSB_DIR_OUT) {
uint16_t const len = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size);
-
- fsdev_write_packet_memory(pma_addr, &(edpt->buffer[edpt->queued_len]), len);
+ tu_hwfifo_write(PMA_BUF_AT(pma_addr), &(edpt->buffer[edpt->queued_len]), len, NULL);
btable_set_count(ch_id, BTABLE_BUF_TX, len);
edpt->queued_len += len;