summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-04-21 19:44:10 +0700
committerhathach <[email protected]>2026-04-21 19:44:10 +0700
commitd0c550cadceff3fdf30060f4ac0ebf919e5934a1 (patch)
tree74118fd0fd1b10095773d848fbe8d814535ae937
parent100cfd6360ddd0c94a0aaeaa2da05449c0648dc1 (diff)
enable double buffer for tm4c
-rw-r--r--hw/bsp/tm4c/family.c8
-rw-r--r--src/portable/mentor/musb/dcd_musb.c43
-rw-r--r--src/portable/mentor/musb/musb_type.h2
-rwxr-xr-xtest/hil/hil_test.py2
4 files changed, 41 insertions, 14 deletions
diff --git a/hw/bsp/tm4c/family.c b/hw/bsp/tm4c/family.c
index 6988a264e..c5e4bd64e 100644
--- a/hw/bsp/tm4c/family.c
+++ b/hw/bsp/tm4c/family.c
@@ -58,6 +58,14 @@ static void board_button_init(GPIOA_Type* port, uint8_t PinMsk) {
/* Set direction */
port->DIR &= ~PinMsk;
+
+ /* Enable internal pull so the idle state is deterministic. LaunchPad buttons
+ * connect the pin to GND when pressed (active-low) and require a pull-up. */
+#if BUTTON_STATE_ACTIVE == 0
+ port->PUR |= PinMsk;
+#else
+ port->PDR |= PinMsk;
+#endif
}
static void board_led_init(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) {
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index 283d8b257..02d9c2f66 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -140,7 +140,6 @@ TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigne
TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps,
bool double_packet) {
- (void) epnum;
uint8_t ffsize = hwfifo_byte2size(mps);
mps = 8 << ffsize; // round up to the next power of 2
@@ -153,6 +152,13 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign
musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8;
musb->fifo_size[is_rx] = ffsize;
+ volatile uint16_t* dp_disable = is_rx ? &musb->rx_doulbe_packet_disable : &musb->tx_double_packet_disable;
+ if (double_packet) {
+ *dp_disable &= ~(1u << epnum);
+ } else {
+ *dp_disable |= (1u << epnum);
+ }
+
alloced_fifo_bytes += mps;
return true;
}
@@ -167,17 +173,22 @@ TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigne
TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps,
bool double_packet) {
(void) epnum; (void) mps;
- if (!double_packet) {
- #if defined(TUP_USBIP_MUSB_ADI)
- musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx);
- #else
- if (is_rx) {
- musb->rx_doulbe_packet_disable |= 1u << epnum;
- } else {
- musb->tx_double_packet_disable |= 1u << epnum;
- }
- #endif
+
+ #if defined(TUP_USBIP_MUSB_ADI)
+ volatile uint8_t* csrh = &musb->indexed_csr.maxp_csr[is_rx].csrh;
+ if (double_packet) {
+ *csrh &= ~MUSB_CSRH_DISABLE_DOUBLE_PACKET;
+ } else {
+ *csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET;
}
+ #else
+ volatile uint16_t* dp_disable = is_rx ? &musb->rx_doulbe_packet_disable : &musb->tx_double_packet_disable;
+ if (double_packet) {
+ *dp_disable &= ~(1u << epnum);
+ } else {
+ *dp_disable |= (1u << epnum);
+ }
+ #endif
return true;
}
@@ -250,6 +261,14 @@ static void process_epin(uint8_t rhport, musb_regs_t *musb_regs, uint8_t epnum)
pipe_state_t* pipe = pipe_get(epnum, TUSB_DIR_IN);
if (pipe->remaining == 0) {
+ // All bytes have been loaded into the FIFO. With double-packet buffering a
+ // second packet may still be waiting in the FIFO when this IRQ fires (the
+ // hardware signals TXRDY clear as soon as a slot frees, not when the wire
+ // transfer finishes). Defer completion until FIFONE == 0 so we don't emit
+ // a duplicate xfer_complete before the final packet has been sent.
+ if (ep_csr->tx_csrl & MUSB_TXCSRL1_FIFONE) {
+ return;
+ }
const uint16_t xferred_len = pipe->length;
pipe->buf = NULL;
pipe->armed = false;
@@ -649,7 +668,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
hwfifo_flush(musb, epn, is_rx, true);
- TU_ASSERT(hwfifo_config(musb, epn, is_rx, mps, false));
+ TU_ASSERT(hwfifo_config(musb, epn, is_rx, mps, ep_desc->bmAttributes.xfer == TUSB_XFER_BULK));
musb->intren_ep[is_rx] |= TU_BIT(epn);
return true;
diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h
index b2f6492fa..6a85d2ca8 100644
--- a/src/portable/mentor/musb/musb_type.h
+++ b/src/portable/mentor/musb/musb_type.h
@@ -336,7 +336,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_
#define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6))
// 0x13, 0x17: TX/RX CSRH
-#define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1)
+#define MUSB_CSRH_DISABLE_DOUBLE_PACKET (1u << 1)
#define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO
#define MUSB_CSRH_ISO (1u << 6)
diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py
index dfe09bf23..58116fb67 100755
--- a/test/hil/hil_test.py
+++ b/test/hil/hil_test.py
@@ -1209,7 +1209,7 @@ device_tests = [
'device/printer_to_cdc',
'device/midi_test',
'device/mtp',
- # 'device/net_lwip_webserver'
+ 'device/net_lwip_webserver'
]
dual_tests = [