Skip to content

Commit f752bc6

Browse files
authored
Merge pull request #448 from adafruit/more-ch32v203-update
update tinyusb to fix ch32v203 race with hub in setup
2 parents 0061a40 + 8587060 commit f752bc6

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested
155155
// into the stack.
156156
static void handle_bus_reset(uint8_t rhport);
157157
static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix);
158-
static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir);
158+
static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir);
159159

160160
// PMA allocation/access
161161
static uint16_t ep_buf_ptr; ///< Points to first free memory location
@@ -275,7 +275,6 @@ static void handle_bus_reset(uint8_t rhport) {
275275
// Handle CTR interrupt for the TX/IN direction
276276
static void handle_ctr_tx(uint32_t ep_id) {
277277
uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
278-
ep_reg &= USB_EPREG_MASK;
279278

280279
uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
281280
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN);
@@ -345,12 +344,14 @@ static void handle_ctr_rx(uint32_t ep_id) {
345344

346345
if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) {
347346
// all bytes received or short packet
348-
dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true);
349347

350348
// For ch32v203: reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with msc write10)
351-
// also ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous
352-
// transfer. So reset total_len and queued_len to 0.
353349
btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size);
350+
351+
dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true);
352+
353+
// ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous
354+
// transfer. So reset total_len and queued_len to 0.
354355
xfer->total_len = xfer->queued_len = 0;
355356
} else {
356357
// Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always
@@ -412,11 +413,6 @@ void dcd_int_handler(uint8_t rhport) {
412413
FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF;
413414
}
414415

415-
if (int_status & USB_ISTR_PMAOVR) {
416-
TU_BREAKPOINT();
417-
FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR;
418-
}
419-
420416
// loop to handle all pending CTR interrupts
421417
while (FSDEV_REG->ISTR & USB_ISTR_CTR) {
422418
// skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt
@@ -459,6 +455,11 @@ void dcd_int_handler(uint8_t rhport) {
459455
handle_ctr_tx(ep_id);
460456
}
461457
}
458+
459+
if (int_status & USB_ISTR_PMAOVR) {
460+
TU_BREAKPOINT();
461+
FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR;
462+
}
462463
}
463464

464465
//--------------------------------------------------------------------+
@@ -576,7 +577,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
576577
(void)rhport;
577578
uint8_t const ep_addr = desc_ep->bEndpointAddress;
578579
uint8_t const ep_num = tu_edpt_number(ep_addr);
579-
uint8_t const dir = tu_edpt_dir(ep_addr);
580+
tusb_dir_t const dir = tu_edpt_dir(ep_addr);
580581
const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
581582
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
582583
TU_ASSERT(ep_idx < FSDEV_EP_COUNT);
@@ -649,10 +650,11 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
649650

650651
/* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA,
651652
for smaller devices double buffering occupy too much space. */
652-
uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
653653
#if FSDEV_PMA_SIZE > 1024u
654+
uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
654655
uint16_t pma_addr2 = pma_addr >> 16;
655656
#else
657+
uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false);
656658
uint16_t pma_addr2 = pma_addr;
657659
#endif
658660

@@ -669,7 +671,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
669671
(void)rhport;
670672
uint8_t const ep_addr = desc_ep->bEndpointAddress;
671673
uint8_t const ep_num = tu_edpt_number(ep_addr);
672-
uint8_t const dir = tu_edpt_dir(ep_addr);
674+
tusb_dir_t const dir = tu_edpt_dir(ep_addr);
673675
xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
674676

675677
uint8_t const ep_idx = xfer->ep_idx;
@@ -681,7 +683,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
681683
ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
682684
ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
683685
ep_change_dtog(&ep_reg, dir, 0);
684-
ep_change_dtog(&ep_reg, 1 - dir, 1);
686+
ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1);
685687

686688
ep_write(ep_idx, ep_reg, true);
687689

@@ -692,7 +694,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
692694
static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
693695
uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
694696
uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR
695-
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits
696697

697698
bool const is_iso = ep_is_iso(ep_reg);
698699

@@ -717,10 +718,11 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
717718
if (is_iso) {
718719
xfer->iso_in_sending = true;
719720
}
721+
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits
720722
ep_write(ep_ix, ep_reg, true);
721723
}
722724

723-
static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) {
725+
static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
724726
(void) rhport;
725727

726728
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
@@ -750,7 +752,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) {
750752

751753
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) {
752754
uint8_t const ep_num = tu_edpt_number(ep_addr);
753-
uint8_t const dir = tu_edpt_dir(ep_addr);
755+
tusb_dir_t const dir = tu_edpt_dir(ep_addr);
754756
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
755757

756758
xfer->buffer = buffer;
@@ -763,7 +765,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
763765

764766
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) {
765767
uint8_t const ep_num = tu_edpt_number(ep_addr);
766-
uint8_t const dir = tu_edpt_dir(ep_addr);
768+
tusb_dir_t const dir = tu_edpt_dir(ep_addr);
767769
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
768770

769771
xfer->buffer = NULL;
@@ -777,7 +779,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t
777779
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
778780
(void)rhport;
779781
uint8_t const ep_num = tu_edpt_number(ep_addr);
780-
uint8_t const dir = tu_edpt_dir(ep_addr);
782+
tusb_dir_t const dir = tu_edpt_dir(ep_addr);
781783
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
782784
uint8_t const ep_idx = xfer->ep_idx;
783785

@@ -792,7 +794,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
792794
(void)rhport;
793795

794796
uint8_t const ep_num = tu_edpt_number(ep_addr);
795-
uint8_t const dir = tu_edpt_dir(ep_addr);
797+
tusb_dir_t const dir = tu_edpt_dir(ep_addr);
796798
xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
797799
uint8_t const ep_idx = xfer->ep_idx;
798800

@@ -806,6 +808,10 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
806808
ep_write(ep_idx, ep_reg, true);
807809
}
808810

811+
//--------------------------------------------------------------------+
812+
// PMA read/write
813+
//--------------------------------------------------------------------+
814+
809815
// Write to packet memory area (PMA) from user memory
810816
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
811817
// - Uses unaligned for RAM (since M0 cannot access unaligned address)

src/portable/st/stm32_fsdev/fsdev_type.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,9 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u
285285
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
286286
uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10);
287287
if (bl_nb == 0) {
288-
// zlp but 0 is invalid value, set num_block to 1 (2 bytes)
289-
bl_nb = 1 << 10;
288+
// zlp but 0 is invalid value, set blsize to 1 (32 bytes)
289+
// Note: lower value can cause PMAOVR on setup with ch32v203
290+
bl_nb = 1 << 15;
290291
}
291292

292293
#ifdef FSDEV_BUS_32BIT

0 commit comments

Comments
 (0)