more musb update

This commit is contained in:
hathach
2024-08-18 16:34:58 +07:00
parent fe7ffc8eda
commit 76eb2f5066
3 changed files with 54 additions and 51 deletions

View File

@@ -643,8 +643,7 @@ void dcd_sof_enable(uint8_t rhport, bool en)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Configure endpoint's registers according to descriptor // Configure endpoint's registers according to descriptor
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) {
{
const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned ep_addr = ep_desc->bEndpointAddress;
const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn = tu_edpt_number(ep_addr);
const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr);
@@ -662,22 +661,30 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn);
const uint8_t is_rx = 1 - dir_in; const uint8_t is_rx = 1 - dir_in;
ep_csr->maxp_csr[is_rx].maxp = mps; musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx];
ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; maxp_csr->maxp = mps;
maxp_csr->csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0;
// flush and reset data toggle
uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx);
if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) {
csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx);
} }
ep_csr->maxp_csr[is_rx].csrl = csrl; maxp_csr->csrl = csrl;
musb->intren_ep[is_rx] |= TU_BIT(epn); musb->intren_ep[is_rx] |= TU_BIT(epn);
/* Setup FIFO */
fifo_configure(musb, epn, dir_in, mps); fifo_configure(musb, epn, dir_in, mps);
return true; return true;
} }
// bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
// }
//
// bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
// }
void dcd_edpt_close_all(uint8_t rhport) void dcd_edpt_close_all(uint8_t rhport)
{ {
musb_regs_t* musb = MUSB_REGS(rhport); musb_regs_t* musb = MUSB_REGS(rhport);
@@ -688,23 +695,20 @@ void dcd_edpt_close_all(uint8_t rhport)
musb->intr_rxen = 0; musb->intr_rxen = 0;
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); musb_ep_csr_t* ep_csr = get_ep_csr(musb, i);
ep_csr->tx_maxp = 0; for (unsigned d = 0; d < 2; d++) {
ep_csr->tx_csrh = 0; musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d];
if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) maxp_csr->maxp = 0;
ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; maxp_csr->csrh = 0;
else
ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT;
ep_csr->rx_maxp = 0; // flush and reset data toggle
ep_csr->rx_csrh = 0; uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(d);
if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) {
ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; csrl |= MUSB_CSRL_FLUSH_FIFO(d);
} else { }
ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; maxp_csr->csrl = csrl;
fifo_reset(musb, i, 1-d);
} }
fifo_reset(musb, i, 0);
fifo_reset(musb, i, 1);
} }
#if MUSB_CFG_DYNAMIC_FIFO #if MUSB_CFG_DYNAMIC_FIFO
@@ -755,12 +759,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
unsigned const epnum = tu_edpt_number(ep_addr); unsigned const epnum = tu_edpt_number(ep_addr);
unsigned const ie = musb_dcd_get_int_enable(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport);
musb_dcd_int_disable(rhport); musb_dcd_int_disable(rhport);
if (epnum) { if (epnum) {
_dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1);
ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes);
} else { } else {
ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes);
} }
if (ie) musb_dcd_int_enable(rhport); if (ie) musb_dcd_int_enable(rhport);
return ret; return ret;
} }
@@ -783,11 +789,13 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
// Stall endpoint // Stall endpoint
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
unsigned const epn = tu_edpt_number(ep_addr);
unsigned const ie = musb_dcd_get_int_enable(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport);
musb_dcd_int_disable(rhport);
unsigned const epn = tu_edpt_number(ep_addr);
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
musb_dcd_int_disable(rhport);
if (0 == epn) { if (0 == epn) {
if (!ep_addr) { /* Ignore EP80 */ if (!ep_addr) { /* Ignore EP80 */
_dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID;
@@ -795,13 +803,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
ep_csr->csr0l = MUSB_CSRL0_STALL; ep_csr->csr0l = MUSB_CSRL0_STALL;
} }
} else { } else {
if (tu_edpt_dir(ep_addr)) { /* IN */ const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr);
ep_csr->tx_csrl = MUSB_TXCSRL1_STALL; ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_SEND_STALL(is_rx);
} else { /* OUT */
TU_ASSERT(!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY),);
ep_csr->rx_csrl = MUSB_RXCSRL1_STALL;
}
} }
if (ie) musb_dcd_int_enable(rhport); if (ie) musb_dcd_int_enable(rhport);
} }
@@ -809,16 +814,16 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{ {
(void)rhport; (void)rhport;
unsigned const ie = musb_dcd_get_int_enable(rhport);
musb_dcd_int_disable(rhport);
unsigned const epn = tu_edpt_number(ep_addr); unsigned const epn = tu_edpt_number(ep_addr);
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
unsigned const ie = musb_dcd_get_int_enable(rhport); const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr);
musb_dcd_int_disable(rhport);
if (tu_edpt_dir(ep_addr)) { /* IN */ ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx);
ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT;
} else { /* OUT */
ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT;
}
if (ie) musb_dcd_int_enable(rhport); if (ie) musb_dcd_int_enable(rhport);
} }

View File

@@ -47,18 +47,15 @@ static const IRQn_Type musb_irqs[] = {
USB_IRQn USB_IRQn
}; };
TU_ATTR_ALWAYS_INLINE TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) {
static inline void musb_dcd_int_enable(uint8_t rhport) {
NVIC_EnableIRQ(musb_irqs[rhport]); NVIC_EnableIRQ(musb_irqs[rhport]);
} }
TU_ATTR_ALWAYS_INLINE TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) {
static inline void musb_dcd_int_disable(uint8_t rhport) {
NVIC_DisableIRQ(musb_irqs[rhport]); NVIC_DisableIRQ(musb_irqs[rhport]);
} }
TU_ATTR_ALWAYS_INLINE TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
#ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5 #ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5
return NVIC_GetEnableIRQ(musb_irqs[rhport]); return NVIC_GetEnableIRQ(musb_irqs[rhport]);
#else #else
@@ -67,8 +64,7 @@ static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
#endif #endif
} }
TU_ATTR_ALWAYS_INLINE TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) {
static inline void musb_dcd_int_clear(uint8_t rhport) {
NVIC_ClearPendingIRQ(musb_irqs[rhport]); NVIC_ClearPendingIRQ(musb_irqs[rhport]);
} }

View File

@@ -83,6 +83,12 @@
#define __R volatile const #define __R volatile const
#endif #endif
typedef struct TU_ATTR_PACKED {
__IO uint16_t maxp; // 0x00, 0x04: MAXP
__IO uint8_t csrl; // 0x02, 0x06: CSRL
__IO uint8_t csrh; // 0x03, 0x07: CSRH
}musb_ep_maxp_csr_t;
// 0: TX (device IN, host OUT) // 0: TX (device IN, host OUT)
// 1: RX (device OUT, host IN) // 1: RX (device OUT, host IN)
typedef struct TU_ATTR_PACKED { typedef struct TU_ATTR_PACKED {
@@ -103,11 +109,7 @@ typedef struct TU_ATTR_PACKED {
__IO uint8_t rx_csrh; // 0x07: RX CSRH __IO uint8_t rx_csrh; // 0x07: RX CSRH
}; };
struct { musb_ep_maxp_csr_t maxp_csr[2];
__IO uint16_t maxp; // 0x00: MAXP
__IO uint8_t csrl; // 0x02: CSRL
__IO uint8_t csrh; // 0x03: CSRH
}maxp_csr[2];
}; };
union { union {
@@ -330,7 +332,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_
#define MUSB_CSRL_PACKET_READY(_rx) (1u << 0) #define MUSB_CSRL_PACKET_READY(_rx) (1u << 0)
#define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3)) #define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3))
#define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4)) #define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4))
#define MUSB_CSRL_SENT_STALL(_rx) (1u << ((_rx) ? 6 : 5)) #define MUSB_CSRL_STALLED(_rx) (1u << ((_rx) ? 6 : 5))
#define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6)) #define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6))
// 0x13, 0x17: TX/RX CSRH // 0x13, 0x17: TX/RX CSRH