Skip to content

Commit 4ae433f

Browse files
committed
stm32_fsdev: Allow configuring single-buffered isochronous endpoints.
Controlled by the embedder defining CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP in tusb_config.h. If hardware does have SBUF_ISO bit it will use only one half of endpoint pair register.
1 parent e95973d commit 4ae433f

File tree

3 files changed

+82
-8
lines changed

3 files changed

+82
-8
lines changed

src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c

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

333333
uint8_t buf_id;
334-
if (is_iso) {
335-
buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered
334+
#if FSDEV_USE_SBUF_ISO == 0
335+
bool const dbl_buf = is_iso;
336+
#else
337+
bool const dbl_buf = false;
338+
#endif
339+
if (dbl_buf) {
340+
buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1;
336341
} else {
337342
buf_id = BTABLE_BUF_RX;
338343
}
@@ -527,10 +532,16 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
527532
return i;
528533
}
529534

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

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

674+
#if FSDEV_USE_SBUF_ISO == 0
665675
btable_set_addr(ep_idx, 0, pma_addr);
666676
btable_set_addr(ep_idx, 1, pma_addr2);
677+
#else
678+
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
679+
#endif
667680

668681
xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
669682
xfer->ep_idx = ep_idx;
@@ -684,10 +697,23 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
684697

685698
uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK;
686699
ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX;
700+
#if FSDEV_USE_SBUF_ISO != 0
701+
ep_reg |= USB_EP_KIND;
702+
703+
ep_change_status(&ep_reg, dir, EP_STAT_DISABLED);
704+
ep_change_dtog(&ep_reg, dir, 0);
705+
706+
if (dir == TUSB_DIR_IN) {
707+
ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX);
708+
} else {
709+
ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX);
710+
}
711+
#else
687712
ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
688713
ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
689714
ep_change_dtog(&ep_reg, dir, 0);
690715
ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1);
716+
#endif
691717

692718
ep_write(ep_idx, ep_reg, true);
693719

@@ -702,7 +728,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
702728
bool const is_iso = ep_is_iso(ep_reg);
703729

704730
uint8_t buf_id;
705-
if (is_iso) {
731+
#if FSDEV_USE_SBUF_ISO == 0
732+
bool const dbl_buf = is_iso;
733+
#else
734+
bool const dbl_buf = false;
735+
#endif
736+
if (dbl_buf) {
706737
buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0;
707738
} else {
708739
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: 38 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,29 @@
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+
// Defaults to double-buffered isochronous endpoints on devices with >1KB PMA
272+
#if FSDEV_PMA_SIZE > 1024u
273+
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1
274+
#else
275+
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0
276+
#endif
277+
#endif
278+
279+
#if FSDEV_HAS_SBUF_ISO != 0 && CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP == 0
280+
// If hardware has SBUF_ISO bit single-buffered endpoints consume only
281+
// one half of endpoint pair register.
282+
#define FSDEV_USE_SBUF_ISO 1
283+
#else
284+
// Otherwise it consumes entire endpoint pair but we can at least save
285+
// memory by configuring the same buffer twice.
286+
#define FSDEV_USE_SBUF_ISO 0
287+
#endif
288+
251289
//--------------------------------------------------------------------+
252290
//
253291
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)