use musb_ep_csr_t for indexed CSR, also use indexed csr for TI access as well. Merge ep0 and epn together

This commit is contained in:
hathach
2024-08-15 19:05:28 +07:00
parent 7d8d364332
commit 6152adb17f
4 changed files with 162 additions and 151 deletions

View File

@@ -41,10 +41,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"");
// Following symbols must be defined by port header // Following symbols must be defined by port header
// - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_enable/disable/clear/get_enable
// - musb_dcd_int_handler_enter/exit // - musb_dcd_int_handler_enter/exit
// - musb_dcd_epn_regs: Get memory mapped struct of end point registers
// - musb_dcd_ep0_regs: Get memory mapped struct of EP0 registers
// - musb_dcd_ctl_regs: Get memory mapped struct of control registers
// - musb_dcd_ep_get_fifo_ptr: Gets the address of the provided EP's FIFO
// - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO // - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO
#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129)
#include "musb_ti.h" #include "musb_ti.h"
@@ -157,7 +153,7 @@ static void process_setup_packet(uint8_t rhport) {
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
uint32_t *p = (void*)&_dcd.setup_packet; uint32_t *p = (void*)&_dcd.setup_packet;
volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; volatile uint32_t *fifo_ptr = &musb_regs->fifo[0];
volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport);
p[0] = *fifo_ptr; p[0] = *fifo_ptr;
p[1] = *fifo_ptr; p[1] = *fifo_ptr;
@@ -170,7 +166,10 @@ static void process_setup_packet(uint8_t rhport) {
_dcd.remaining_ctrl = len; _dcd.remaining_ctrl = len;
const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType);
/* Clear RX FIFO and reverse the transaction direction */ /* Clear RX FIFO and reverse the transaction direction */
if (len && dir_in) ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; if (len && dir_in) {
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0);
ep_csr->csr0l = USB_CSRL0_RXRDYC;
}
} }
static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
@@ -186,8 +185,8 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
} }
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum);
const unsigned mps = regs->TXMAXP; const unsigned mps = ep_csr->tx_maxp;
const unsigned len = TU_MIN(mps, rem); const unsigned len = TU_MIN(mps, rem);
void *buf = pipe->buf; void *buf = pipe->buf;
volatile void *fifo_ptr = &musb_regs->fifo[epnum]; volatile void *fifo_ptr = &musb_regs->fifo[epnum];
@@ -201,8 +200,8 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
} }
pipe->remaining = rem - len; pipe->remaining = rem - len;
} }
regs->TXCSRL = USB_TXCSRL1_TXRDY; ep_csr->tx_csrl = USB_TXCSRL1_TXRDY;
// TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, regs->TXCSRL, rem - len); // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, ep_csr->tx_csrl, rem - len);
return false; return false;
} }
@@ -212,14 +211,14 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr)
unsigned epnum_minus1 = epnum - 1; unsigned epnum_minus1 = epnum - 1;
pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1];
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum);
// TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl);
TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); TU_ASSERT(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY);
const unsigned mps = regs->RXMAXP; const unsigned mps = ep_csr->rx_maxp;
const unsigned rem = pipe->remaining; const unsigned rem = pipe->remaining;
const unsigned vld = regs->RXCOUNT; const unsigned vld = ep_csr->rx_count;
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
void *buf = pipe->buf; void *buf = pipe->buf;
volatile void *fifo_ptr = &musb_regs->fifo[epnum]; volatile void *fifo_ptr = &musb_regs->fifo[epnum];
@@ -236,7 +235,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr)
pipe->buf = NULL; pipe->buf = NULL;
return NULL != buf; return NULL != buf;
} }
regs->RXCSRL = 0; /* Clear RXRDY bit */ ep_csr->rx_csrl = 0; /* Clear RXRDY bit */
return false; return false;
} }
@@ -254,8 +253,9 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16
if (dir_in) { if (dir_in) {
handle_xfer_in(rhport, ep_addr); handle_xfer_in(rhport, ep_addr);
} else { } else {
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); musb_regs_t* musb_regs = MUSB_REGS(rhport);
if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum);
if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0;
} }
return true; return true;
} }
@@ -265,7 +265,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
(void)rhport; (void)rhport;
TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0);
const unsigned req = _dcd.setup_packet.bmRequestType; const unsigned req = _dcd.setup_packet.bmRequestType;
TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0);
@@ -276,7 +276,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
* may have already finished and received the next setup packet * may have already finished and received the next setup packet
* without calling this function, so we have no choice but to * without calling this function, so we have no choice but to
* invoke the callback function of status packet here. */ * invoke the callback function of status packet here. */
// TU_LOG1(" STATUS OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); // TU_LOG1(" STATUS OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l);
_dcd.status_out = 0; _dcd.status_out = 0;
if (req == REQUEST_TYPE_INVALID) { if (req == REQUEST_TYPE_INVALID) {
dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false);
@@ -305,25 +305,25 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
_dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */
_dcd.status_out = 1; _dcd.status_out = 1;
/* Flush TX FIFO and reverse the transaction direction. */ /* Flush TX FIFO and reverse the transaction direction. */
ep0_regs->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; ep_csr->csr0l = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND;
} else { } else {
ep0_regs->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ ep_csr->csr0l = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */
} }
// TU_LOG1(" IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); // TU_LOG1(" IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l);
} else { } else {
// TU_LOG1(" OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); // TU_LOG1(" OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l);
_dcd.pipe0.buf = buffer; _dcd.pipe0.buf = buffer;
_dcd.pipe0.length = len; _dcd.pipe0.length = len;
_dcd.pipe0.remaining = len; _dcd.pipe0.remaining = len;
ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ ep_csr->csr0l = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */
} }
} else if (dir_in) { } else if (dir_in) {
// TU_LOG1(" STATUS IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); // TU_LOG1(" STATUS IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l);
_dcd.pipe0.buf = NULL; _dcd.pipe0.buf = NULL;
_dcd.pipe0.length = 0; _dcd.pipe0.length = 0;
_dcd.pipe0.remaining = 0; _dcd.pipe0.remaining = 0;
/* Clear RX FIFO and reverse the transaction direction */ /* Clear RX FIFO and reverse the transaction direction */
ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND;
} }
return true; return true;
} }
@@ -331,21 +331,21 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
static void process_ep0(uint8_t rhport) static void process_ep0(uint8_t rhport)
{ {
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0);
uint_fast8_t csrl = ep0_regs->CSRL0; uint_fast8_t csrl = ep_csr->csr0l;
// TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl);
if (csrl & USB_CSRL0_STALLED) { if (csrl & USB_CSRL0_STALLED) {
/* Returned STALL packet to HOST. */ /* Returned STALL packet to HOST. */
ep0_regs->CSRL0 = 0; /* Clear STALL */ ep_csr->csr0l = 0; /* Clear STALL */
return; return;
} }
unsigned req = _dcd.setup_packet.bmRequestType; unsigned req = _dcd.setup_packet.bmRequestType;
if (csrl & USB_CSRL0_SETEND) { if (csrl & USB_CSRL0_SETEND) {
TU_LOG1(" ABORT by the next packets\r\n"); TU_LOG1(" ABORT by the next packets\r\n");
ep0_regs->CSRL0 = USB_CSRL0_SETENDC; ep_csr->csr0l = USB_CSRL0_SETENDC;
if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) {
/* DATA stage was aborted by receiving STATUS or SETUP packet. */ /* DATA stage was aborted by receiving STATUS or SETUP packet. */
_dcd.pipe0.buf = NULL; _dcd.pipe0.buf = NULL;
@@ -363,13 +363,13 @@ static void process_ep0(uint8_t rhport)
/* Received SETUP or DATA OUT packet */ /* Received SETUP or DATA OUT packet */
if (req == REQUEST_TYPE_INVALID) { if (req == REQUEST_TYPE_INVALID) {
/* SETUP */ /* SETUP */
TU_ASSERT(sizeof(tusb_control_request_t) == ep0_regs->COUNT0,); TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->rx_count,);
process_setup_packet(rhport); process_setup_packet(rhport);
return; return;
} }
if (_dcd.pipe0.buf) { if (_dcd.pipe0.buf) {
/* DATA OUT */ /* DATA OUT */
const unsigned vld = ep0_regs->COUNT0; const unsigned vld = ep_csr->rx_count;
const unsigned rem = _dcd.pipe0.remaining; const unsigned rem = _dcd.pipe0.remaining;
const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); const unsigned len = TU_MIN(TU_MIN(rem, 64), vld);
volatile void *fifo_ptr = &musb_regs->fifo[0]; volatile void *fifo_ptr = &musb_regs->fifo[0];
@@ -419,18 +419,19 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr)
const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn = tu_edpt_number(ep_addr);
const unsigned epn_minus1 = epn - 1; const unsigned epn_minus1 = epn - 1;
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); musb_regs_t* musb_regs = MUSB_REGS(rhport);
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
if (dir_in) { if (dir_in) {
// TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); // TU_LOG1(" TX CSRL%d = %x\r\n", epn, ep_csr->tx_csrl);
if (regs->TXCSRL & USB_TXCSRL1_STALLED) { if (ep_csr->tx_csrl & USB_TXCSRL1_STALLED) {
regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); ep_csr->tx_csrl &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN);
return; return;
} }
completed = handle_xfer_in(rhport, ep_addr); completed = handle_xfer_in(rhport, ep_addr);
} else { } else {
// TU_LOG1(" RXCSRL%d = %x\r\n", epn, regs->RXCSRL); // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl);
if (regs->RXCSRL & USB_RXCSRL1_STALLED) { if (ep_csr->rx_csrl & USB_RXCSRL1_STALLED) {
regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); ep_csr->rx_csrl &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER);
return; return;
} }
completed = handle_xfer_out(rhport, ep_addr); completed = handle_xfer_out(rhport, ep_addr);
@@ -492,12 +493,14 @@ void dcd_int_disable(uint8_t rhport)
void dcd_set_address(uint8_t rhport, uint8_t dev_addr) void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
{ {
(void)dev_addr; (void)dev_addr;
volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0);
_dcd.pipe0.buf = NULL; _dcd.pipe0.buf = NULL;
_dcd.pipe0.length = 0; _dcd.pipe0.length = 0;
_dcd.pipe0.remaining = 0; _dcd.pipe0.remaining = 0;
/* Clear RX FIFO to return ACK. */ /* Clear RX FIFO to return ACK. */
ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND;
} }
// Wake up host // Wake up host
@@ -554,24 +557,24 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
pipe->length = 0; pipe->length = 0;
pipe->remaining = 0; pipe->remaining = 0;
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn);
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);
if (dir_in) { if (dir_in) {
regs->TXMAXP = mps; ep_csr->tx_maxp = mps;
regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; ep_csr->tx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0;
if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) {
regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH;
} else { } else {
regs->TXCSRL = USB_TXCSRL1_CLRDT; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
} }
musb_regs->intr_txen |= TU_BIT(epn); musb_regs->intr_txen |= TU_BIT(epn);
} else { } else {
regs->RXMAXP = mps; ep_csr->rx_maxp = mps;
regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; ep_csr->rx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0;
if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) {
regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH;
} else { } else {
regs->RXCSRL = USB_RXCSRL1_CLRDT; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
} }
musb_regs->intr_rxen |= TU_BIT(epn); musb_regs->intr_rxen |= TU_BIT(epn);
} }
@@ -584,27 +587,26 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
void dcd_edpt_close_all(uint8_t rhport) void dcd_edpt_close_all(uint8_t rhport)
{ {
volatile musb_epn_regs_t *regs;
musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport);
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);
musb_regs->intr_txen = 1; /* Enable only EP0 */ musb_regs->intr_txen = 1; /* Enable only EP0 */
musb_regs->intr_rxen = 0; musb_regs->intr_rxen = 0;
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
regs = musb_dcd_epn_regs(rhport, i); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, i);
regs->TXMAXP = 0; ep_csr->tx_maxp = 0;
regs->TXCSRH = 0; ep_csr->tx_csrh = 0;
if (regs->TXCSRL & USB_TXCSRL1_TXRDY) if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY)
regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH;
else else
regs->TXCSRL = USB_TXCSRL1_CLRDT; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
regs->RXMAXP = 0; ep_csr->rx_maxp = 0;
regs->RXCSRH = 0; ep_csr->rx_csrh = 0;
if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) {
regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH;
} else { } else {
regs->RXCSRL = USB_RXCSRL1_CLRDT; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
} }
musb_dcd_reset_fifo(rhport, i, 0); musb_dcd_reset_fifo(rhport, i, 0);
@@ -618,28 +620,27 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
{ {
unsigned const epn = tu_edpt_number(ep_addr); unsigned const epn = tu_edpt_number(ep_addr);
unsigned const dir_in = tu_edpt_dir(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr);
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn);
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);
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 (dir_in) { if (dir_in) {
musb_regs->intr_txen &= ~TU_BIT(epn); musb_regs->intr_txen &= ~TU_BIT(epn);
regs->TXMAXP = 0; ep_csr->tx_maxp = 0;
regs->TXCSRH = 0; ep_csr->tx_csrh = 0;
if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) {
regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH;
} else { } else {
regs->TXCSRL = USB_TXCSRL1_CLRDT; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
} }
} else { } else {
musb_regs->intr_rxen &= ~TU_BIT(epn); musb_regs->intr_rxen &= ~TU_BIT(epn);
regs->RXMAXP = 0; ep_csr->rx_maxp = 0;
regs->RXCSRH = 0; ep_csr->rx_csrh = 0;
if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) {
regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH;
} else { } else {
regs->RXCSRL = USB_RXCSRL1_CLRDT; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
} }
} }
musb_dcd_reset_fifo(rhport, epn, dir_in); musb_dcd_reset_fifo(rhport, epn, dir_in);
@@ -682,25 +683,24 @@ 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 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_regs_t* musb_regs = MUSB_REGS(rhport);
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
musb_dcd_int_disable(rhport); musb_dcd_int_disable(rhport);
if (0 == epn) { if (0 == epn) {
volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport);
if (!ep_addr) { /* Ignore EP80 */ if (!ep_addr) { /* Ignore EP80 */
_dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID;
_dcd.pipe0.buf = NULL; _dcd.pipe0.buf = NULL;
ep0_regs->CSRL0 = USB_CSRL0_STALL; ep_csr->csr0l = USB_CSRL0_STALL;
} }
} else { } else {
volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn);
if (tu_edpt_dir(ep_addr)) { /* IN */ if (tu_edpt_dir(ep_addr)) { /* IN */
regs->TXCSRL = USB_TXCSRL1_STALL; ep_csr->tx_csrl = USB_TXCSRL1_STALL;
} else { /* OUT */ } else { /* OUT */
TU_ASSERT(!(regs->RXCSRL & USB_RXCSRL1_RXRDY),); TU_ASSERT(!(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY),);
regs->RXCSRL = USB_RXCSRL1_STALL; ep_csr->rx_csrl = USB_RXCSRL1_STALL;
} }
} }
if (ie) musb_dcd_int_enable(rhport); if (ie) musb_dcd_int_enable(rhport);
@@ -711,13 +711,14 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{ {
(void)rhport; (void)rhport;
unsigned const epn = tu_edpt_number(ep_addr); unsigned const epn = tu_edpt_number(ep_addr);
musb_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); musb_regs_t* musb_regs = MUSB_REGS(rhport);
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn);
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 (tu_edpt_dir(ep_addr)) { /* IN */ if (tu_edpt_dir(ep_addr)) { /* IN */
regs->TXCSRL = USB_TXCSRL1_CLRDT; ep_csr->tx_csrl = USB_TXCSRL1_CLRDT;
} else { /* OUT */ } else { /* OUT */
regs->RXCSRL = USB_RXCSRL1_CLRDT; ep_csr->rx_csrl = USB_RXCSRL1_CLRDT;
} }
if (ie) musb_dcd_int_enable(rhport); if (ie) musb_dcd_int_enable(rhport);
} }

View File

@@ -136,20 +136,6 @@ static inline void musb_dcd_phy_init(uint8_t rhport) {
musb_periph_inst[rhport]->m31_phy_ponrst = 1; musb_periph_inst[rhport]->m31_phy_ponrst = 1;
} }
static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) {
//Need to set index to map EP registers
musb_periph_inst[rhport]->index = epnum;
volatile musb_epn_regs_t* regs = (volatile musb_epn_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->inmaxp));
return regs;
}
static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) {
//Need to set index to map EP0 registers
musb_periph_inst[rhport]->index = 0;
volatile musb_ep0_regs_t* regs = (volatile musb_ep0_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->csr0));
return regs;
}
static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) {
(void) mps; (void) mps;

View File

@@ -97,22 +97,6 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){
//Nothing to do for this part //Nothing to do for this part
} }
static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum)
{
uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1);
//On the TI parts, the epn registers are 16-bytes apart. The core regs defined
//by musb_dcd_epn_regs and 6 reserved/other use bytes
volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)(baseptr + ((epnum - 1) * 16));
return regs;
}
static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport)
{
volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0));
return regs;
}
typedef struct { typedef struct {
uint_fast16_t beg; /* offset of including first element */ uint_fast16_t beg; /* offset of including first element */
uint_fast16_t end; /* offset of excluding the last element */ uint_fast16_t end; /* offset of excluding the last element */

View File

@@ -1,3 +1,29 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/****************************************************************************** /******************************************************************************
* *
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
@@ -57,24 +83,29 @@
#define __R volatile const #define __R volatile const
#endif #endif
// Endpoint register mapping. Non-zero end points.
typedef struct TU_ATTR_PACKED { typedef struct TU_ATTR_PACKED {
uint16_t TXMAXP; __IO uint16_t tx_maxp; // 0x00: TXMAXP
uint8_t TXCSRL; union {
uint8_t TXCSRH; __IO uint8_t csr0l; // 0x02: CSR0
uint16_t RXMAXP; __IO uint8_t tx_csrl; // 0x02: TX CSRL
uint8_t RXCSRL; };
uint8_t RXCSRH; union {
uint16_t RXCOUNT; __IO uint8_t csr0h; // 0x03: CSR0H
} musb_epn_regs_t; __IO uint8_t tx_csrh; // 0x03: TX CSRH
};
__IO uint16_t rx_maxp; // 0x04: RX MAXP
__IO uint8_t rx_csrl; // 0x06: RX CSRL
__IO uint8_t rx_csrh; // 0x07: RX CSRH
__IO uint16_t rx_count; // 0x08: RX COUNT
__IO uint8_t tx_type; // 0x0A: TX TYPE
__IO uint8_t tx_interval; // 0x0B: TX INTERVAL
__IO uint8_t rx_type; // 0x0C: RX TYPE
__IO uint8_t rx_interval; // 0x0D: RX INTERVAL
__IO uint8_t reserved_0x0e; // 0x0E: Reserved
__IO uint8_t fifo_size; // 0x0F: FIFO_SIZE
} musb_ep_csr_t;
// Endpoint 0 register mapping. TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct");
typedef struct TU_ATTR_PACKED {
uint8_t CSRL0;
uint8_t CSRH0;
uint32_t RESERVED;
uint8_t COUNT0;
} musb_ep0_regs_t;
typedef struct { typedef struct {
//------------- Common -------------// //------------- Common -------------//
@@ -93,21 +124,14 @@ typedef struct {
__IO uint16_t frame; // 0x0C: FRAME __IO uint16_t frame; // 0x0C: FRAME
__IO uint8_t index; // 0x0E: INDEX __IO uint8_t index; // 0x0E: INDEX
__IO uint8_t testmode; // 0x0F: TESTMODE __IO uint8_t testmode; // 0x0F: TESTMODE
__IO uint16_t inmaxp; // 0x10: INMAXP
union { //------------- Indexed CSR -------------//
__IO uint8_t csr0; // 0x12: CSR0 musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15
__IO uint8_t incsrl; // 0x12: INCSRL
}; //------------- FIFOs -------------//
__IO uint8_t incsru; // 0x13: INCSRU
__IO uint16_t outmaxp; // 0x14: OUTMAXP
__IO uint8_t outcsrl; // 0x16: OUTCSRL
__IO uint8_t outcsru; // 0x17: OUTCSRU
union {
__IO uint16_t count0; // 0x18: COUNT0
__IO uint16_t outcount; // 0x18: OUTCOUNT
};
__R uint16_t rsv_0x1a_0x1f[3];
__IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15
// Common (2)
__IO uint8_t devctl; // 0x60: DEVCTL __IO uint8_t devctl; // 0x60: DEVCTL
__IO uint8_t misc; // 0x61: MISC __IO uint8_t misc; // 0x61: MISC
@@ -138,7 +162,13 @@ typedef struct {
//------------- Extended -------------// //------------- Extended -------------//
__IO uint16_t ctuch; // 0x80: CTUCH __IO uint16_t ctuch; // 0x80: CTUCH
__IO uint16_t cthsrtn; // 0x82: CTHSRTN __IO uint16_t cthsrtn; // 0x82: CTHSRTN
__R uint32_t rsv_0x84_0x3ff[223]; __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved
//------------- Absolute CSR (used index to remap to Indexed above) -------------//
// TI tm4c can access this directly, but should use indexed_csr for portability
musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR
__R uint32_t rsv_0x200_0x3ff[128]; // 0x200-0x3FF: Reserved
//------------- Analog PHY -------------// //------------- Analog PHY -------------//
__IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00
@@ -187,6 +217,16 @@ typedef struct {
TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct");
//--------------------------------------------------------------------+
// Helper
//--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_regs, unsigned epnum) {
musb_regs->index = epnum;
return &musb_regs->indexed_csr;
}
//***************************************************************************** //*****************************************************************************
// //
// The following are defines for the bit fields in the USB_O_FADDR register. // The following are defines for the bit fields in the USB_O_FADDR register.