Skip to content

Commit 841cac6

Browse files
authored
Merge pull request #3152 from Milek7/sb-ep
stm32_fsdev: Allow configuring single-buffered isochronous endpoints.
2 parents 2027ac2 + 8515e47 commit 841cac6

File tree

4 files changed

+90
-8
lines changed

4 files changed

+90
-8
lines changed

examples/device/audio_test_freertos/skip.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ mcu:VALENTYUSB_EPTRI
1414
mcu:RAXXX
1515
family:broadcom_32bit
1616
family:broadcom_64bit
17+
board:stm32l0538disco

src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,13 @@ static void handle_ctr_rx(uint32_t ep_id) {
333333
xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT);
334334

335335
uint8_t buf_id;
336-
if (is_iso) {
337-
buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered
336+
#if FSDEV_USE_SBUF_ISO == 0
337+
bool const dbl_buf = is_iso;
338+
#else
339+
bool const dbl_buf = false;
340+
#endif
341+
if (dbl_buf) {
342+
buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1;
338343
} else {
339344
buf_id = BTABLE_BUF_RX;
340345
}
@@ -529,10 +534,16 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
529534
return i;
530535
}
531536

537+
#if FSDEV_USE_SBUF_ISO == 0
538+
bool const dbl_buf = ep_type == TUSB_XFER_ISOCHRONOUS;
539+
#else
540+
bool const dbl_buf = false;
541+
#endif
542+
532543
// If EP of current direction is not allocated
533-
// Except for ISO endpoint, both direction should be free
544+
// For double-buffered mode both directions needs to be free
534545
if (!ep_alloc_status[i].allocated[dir] &&
535-
(ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) {
546+
(!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) {
536547
// Check if EP number is the same
537548
if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) {
538549
// One EP pair has to be the same type
@@ -654,18 +665,20 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
654665
uint8_t const dir = tu_edpt_dir(ep_addr);
655666
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
656667

657-
/* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA,
658-
for smaller devices double buffering occupy too much space. */
659-
#if FSDEV_PMA_SIZE > 1024u
668+
#if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0
660669
uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
661670
uint16_t pma_addr2 = pma_addr >> 16;
662671
#else
663672
uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false);
664673
uint16_t pma_addr2 = pma_addr;
665674
#endif
666675

676+
#if FSDEV_USE_SBUF_ISO == 0
667677
btable_set_addr(ep_idx, 0, pma_addr);
668678
btable_set_addr(ep_idx, 1, pma_addr2);
679+
#else
680+
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
681+
#endif
669682

670683
xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
671684
xfer->ep_idx = ep_idx;
@@ -686,10 +699,23 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
686699

687700
uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK;
688701
ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX;
702+
#if FSDEV_USE_SBUF_ISO != 0
703+
ep_reg |= USB_EP_KIND;
704+
705+
ep_change_status(&ep_reg, dir, EP_STAT_DISABLED);
706+
ep_change_dtog(&ep_reg, dir, 0);
707+
708+
if (dir == TUSB_DIR_IN) {
709+
ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX);
710+
} else {
711+
ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX);
712+
}
713+
#else
689714
ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
690715
ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
691716
ep_change_dtog(&ep_reg, dir, 0);
692717
ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1);
718+
#endif
693719

694720
ep_write(ep_idx, ep_reg, true);
695721

@@ -704,7 +730,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
704730
bool const is_iso = ep_is_iso(ep_reg);
705731

706732
uint8_t buf_id;
707-
if (is_iso) {
733+
#if FSDEV_USE_SBUF_ISO == 0
734+
bool const dbl_buf = is_iso;
735+
#else
736+
bool const dbl_buf = false;
737+
#endif
738+
if (dbl_buf) {
708739
buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0;
709740
} else {
710741
buf_id = BTABLE_BUF_TX;

src/portable/st/stm32_fsdev/fsdev_ch32.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,14 @@
5454
#endif
5555

5656
#define FSDEV_PMA_SIZE (512u)
57+
#define FSDEV_USE_SBUF_ISO 0
5758
#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
5859
#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
5960

61+
#ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP
62+
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0
63+
#endif
64+
6065
/**************************** ISTR interrupt events *************************/
6166
#define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */
6267
#define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */

src/portable/st/stm32_fsdev/fsdev_stm32.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "stm32f0xx.h"
3737
#define FSDEV_PMA_SIZE (1024u)
3838
#define FSDEV_REG_BASE USB_BASE
39+
#define FSDEV_HAS_SBUF_ISO 0
3940
// F0x2 models are crystal-less
4041
// All have internal D+ pull-up
4142
// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support
@@ -44,6 +45,7 @@
4445
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
4546
#include "stm32f1xx.h"
4647
#define FSDEV_PMA_SIZE (512u)
48+
#define FSDEV_HAS_SBUF_ISO 0
4749
// NO internal Pull-ups
4850
// *B, and *C: 2 x 16 bits/word
4951

@@ -55,6 +57,7 @@
5557
defined(STM32F373xC)
5658
#include "stm32f3xx.h"
5759
#define FSDEV_PMA_SIZE (512u)
60+
#define FSDEV_HAS_SBUF_ISO 0
5861
// NO internal Pull-ups
5962
// *B, and *C: 1 x 16 bits/word
6063
// PMA dedicated to USB (no sharing with CAN)
@@ -64,25 +67,30 @@
6467
defined(STM32F303xD) || defined(STM32F303xE)
6568
#include "stm32f3xx.h"
6669
#define FSDEV_PMA_SIZE (1024u)
70+
#define FSDEV_HAS_SBUF_ISO 0
6771
// NO internal Pull-ups
6872
// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support
6973
// When CAN clock is enabled, USB can use first 768 bytes ONLY.
7074

7175
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
7276
#include "stm32l0xx.h"
7377
#define FSDEV_PMA_SIZE (1024u)
78+
#define FSDEV_HAS_SBUF_ISO 0
7479

7580
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
7681
#include "stm32l1xx.h"
7782
#define FSDEV_PMA_SIZE (512u)
83+
#define FSDEV_HAS_SBUF_ISO 0
7884

7985
#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
8086
#include "stm32g4xx.h"
8187
#define FSDEV_PMA_SIZE (1024u)
88+
#define FSDEV_HAS_SBUF_ISO 0
8289

8390
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
8491
#include "stm32g0xx.h"
8592
#define FSDEV_PMA_SIZE (2048u)
93+
#define FSDEV_HAS_SBUF_ISO 1
8694
#define USB USB_DRD_FS
8795

8896
#define USB_EP_CTR_RX USB_EP_VTRX
@@ -107,6 +115,7 @@
107115
#elif CFG_TUSB_MCU == OPT_MCU_STM32C0
108116
#include "stm32c0xx.h"
109117
#define FSDEV_PMA_SIZE (2048u)
118+
#define FSDEV_HAS_SBUF_ISO 1
110119
#define USB USB_DRD_FS
111120
#define USB_EP_CTR_RX USB_CHEP_VTRX
112121
#define USB_EP_CTR_TX USB_CHEP_VTTX
@@ -121,6 +130,7 @@
121130
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
122131
#include "stm32h5xx.h"
123132
#define FSDEV_PMA_SIZE (2048u)
133+
#define FSDEV_HAS_SBUF_ISO 1
124134
#define USB USB_DRD_FS
125135

126136
#define USB_EP_CTR_RX USB_EP_VTRX
@@ -145,16 +155,19 @@
145155
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
146156
#include "stm32wbxx.h"
147157
#define FSDEV_PMA_SIZE (1024u)
158+
#define FSDEV_HAS_SBUF_ISO 0
148159
/* ST provided header has incorrect value of USB_PMAADDR */
149160
#define FSDEV_PMA_BASE USB1_PMAADDR
150161

151162
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
152163
#include "stm32l4xx.h"
153164
#define FSDEV_PMA_SIZE (1024u)
165+
#define FSDEV_HAS_SBUF_ISO 0
154166

155167
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
156168
#include "stm32l5xx.h"
157169
#define FSDEV_PMA_SIZE (1024u)
170+
#define FSDEV_HAS_SBUF_ISO 0
158171

159172
#ifndef USB_PMAADDR
160173
#define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
@@ -163,6 +176,7 @@
163176
#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
164177
#include "stm32u5xx.h"
165178
#define FSDEV_PMA_SIZE (2048u)
179+
#define FSDEV_HAS_SBUF_ISO 1
166180
#define USB USB_DRD_FS
167181

168182
#define USB_EP_CTR_RX USB_EP_VTRX
@@ -187,6 +201,7 @@
187201
#elif CFG_TUSB_MCU == OPT_MCU_STM32U0
188202
#include "stm32u0xx.h"
189203
#define FSDEV_PMA_SIZE (2048u)
204+
#define FSDEV_HAS_SBUF_ISO 1
190205
#define USB USB_DRD_FS
191206

192207
#define USB_EP_CTR_RX USB_EP_VTRX
@@ -248,6 +263,36 @@
248263
#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \
249264
USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED )
250265

266+
#ifndef FSDEV_HAS_SBUF_ISO
267+
#error "FSDEV_HAS_SBUF_ISO not defined"
268+
#endif
269+
270+
#ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP
271+
// Default configuration for double-buffered isochronous endpoints:
272+
// - Enable double buffering on devices with >1KB Packet Memory Area (PMA)
273+
// to improve isochronous transfer reliability and performance
274+
// - Disable on devices with limited PMA to conserve memory space
275+
#if FSDEV_PMA_SIZE > 1024u
276+
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1
277+
#else
278+
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0
279+
#endif
280+
#endif
281+
282+
#if FSDEV_HAS_SBUF_ISO != 0 && CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP == 0
283+
// SBUF_ISO configuration:
284+
// - Some STM32 devices have special hardware support for single-buffered isochronous endpoints
285+
// - When SBUF_ISO bit is available and double buffering is disabled:
286+
// Enable SBUF_ISO to optimize endpoint register usage (one half of endpoint pair register)
287+
#define FSDEV_USE_SBUF_ISO 1
288+
#else
289+
// When either:
290+
// - Hardware doesn't support SBUF_ISO feature, or
291+
// - Double buffering is enabled for isochronous endpoints
292+
// We must use the entire endpoint pair register
293+
#define FSDEV_USE_SBUF_ISO 0
294+
#endif
295+
251296
//--------------------------------------------------------------------+
252297
//
253298
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)