more musb update
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user