update musb chan with bidirectional support,remove more than one the same eps support

This commit is contained in:
sakumisu
2022-06-15 20:53:49 +08:00
parent 8e7c7d76e1
commit a03152b14f

View File

@@ -129,8 +129,8 @@
#define USB_FIFO_BASE(ep_idx) (USB_BASE + MUSB_FIFO_OFFSET + 0x4 * ep_idx)
#ifndef CONIFG_USB_MUSB_EP_NUM
#define CONIFG_USB_MUSB_EP_NUM 5
#ifndef CONIFG_USB_MUSB_PIPE_NUM
#define CONIFG_USB_MUSB_PIPE_NUM 5
#endif
typedef enum {
@@ -145,8 +145,8 @@ typedef enum {
struct musb_pipe {
uint8_t ep_idx;
bool inuse; /* True: This channel is "in use" */
bool in; /* True: IN endpoint */
bool enable; /* True: start transfer */
bool in; /* True: IN endpoint */
uint16_t mps;
uint8_t interval; /* Polling interval */
uint8_t speed;
@@ -164,27 +164,26 @@ struct musb_pipe {
};
struct musb_hcd {
struct musb_pipe chan[CONIFG_USB_MUSB_EP_NUM][CONFIG_USBHOST_PIPE_NUM];
volatile struct musb_pipe *active_chan[CONIFG_USB_MUSB_EP_NUM];
usb_osal_mutex_t exclsem[CONIFG_USB_MUSB_EP_NUM]; /* Support mutually exclusive access */
struct musb_pipe chan[CONIFG_USB_MUSB_PIPE_NUM][2]; /* Support Bidirectional ep */
usb_osal_mutex_t exclsem[CONIFG_USB_MUSB_PIPE_NUM]; /* Support mutually exclusive access */
} g_musb_hcd;
static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
volatile uint8_t ep0_outlen = 0;
/* get current active ep */
static uint8_t USBC_GetActiveEp(void)
static uint8_t musb_get_active_ep(void)
{
return HWREGB(USB_BASE + MUSB_EPIDX_OFFSET);
}
/* set the active ep */
static void USBC_SelectActiveEp(uint8_t ep_index)
static void musb_set_active_ep(uint8_t ep_index)
{
HWREGB(USB_BASE + MUSB_EPIDX_OFFSET) = ep_index;
}
static void usb_musb_fifo_flush(uint8_t ep)
static void musb_fifo_flush(uint8_t ep)
{
uint8_t ep_idx = ep & 0x7f;
if (ep_idx == 0) {
@@ -201,7 +200,7 @@ static void usb_musb_fifo_flush(uint8_t ep)
}
}
static void usb_musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
static void musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
{
uint32_t *buf32;
uint8_t *buf8;
@@ -232,7 +231,7 @@ static void usb_musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
}
}
static void usb_musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
static void musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
{
uint32_t *buf32;
uint8_t *buf8;
@@ -263,47 +262,6 @@ static void usb_musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
}
}
/****************************************************************************
* Name: musb_pipe_alloc
*
* Description:
* Allocate a channel.
*
****************************************************************************/
static int musb_pipe_alloc(uint8_t ep_idx)
{
int chidx;
/* Search the table of channels */
for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
/* Is this channel available? */
if (!g_musb_hcd.chan[ep_idx][chidx].inuse) {
/* Yes... make it "in use" and return the index */
g_musb_hcd.chan[ep_idx][chidx].inuse = true;
return chidx;
}
}
/* All of the channels are "in-use" */
return -EBUSY;
}
/****************************************************************************
* Name: musb_pipe_free
*
* Description:
* Free a previoiusly allocated channel.
*
****************************************************************************/
static void musb_pipe_free(struct musb_pipe *chan)
{
/* Mark the channel available */
chan->inuse = false;
}
/****************************************************************************
* Name: musb_pipe_waitsetup
*
@@ -333,8 +291,8 @@ static int musb_pipe_waitsetup(struct musb_pipe *chan)
* when either (1) the device is disconnected, or (2) the transfer
* completed.
*/
g_musb_hcd.active_chan[chan->ep_idx] = chan;
chan->waiter = true;
chan->enable = true;
chan->result = -EBUSY;
chan->xfrd = 0;
#ifdef CONFIG_USBHOST_ASYNCH
@@ -376,8 +334,8 @@ static int musb_pipe_asynchsetup(struct musb_pipe *chan, usbh_asynch_callback_t
* when either (1) the device is disconnected, or (2) the transfer
* completed.
*/
g_musb_hcd.active_chan[chan->ep_idx] = chan;
chan->waiter = false;
chan->enable = true;
chan->result = -EBUSY;
chan->xfrd = 0;
chan->callback = callback;
@@ -447,8 +405,7 @@ static void musb_pipe_wakeup(struct musb_pipe *chan)
void *arg;
int nbytes;
g_musb_hcd.active_chan[chan->ep_idx] = NULL;
chan->enable = false;
/* Is the transfer complete? */
if (chan->waiter) {
/* Wake'em up! */
@@ -481,8 +438,11 @@ __WEAK void usb_hc_low_level_init(void)
int usb_hc_sw_init(void)
{
memset(&g_musb_hcd, 0, sizeof(struct musb_hcd));
for (uint8_t i = 0; i < CONIFG_USB_MUSB_EP_NUM; i++) {
for (uint8_t i = 0; i < CONIFG_USB_MUSB_PIPE_NUM; i++) {
g_musb_hcd.exclsem[i] = usb_osal_mutex_create();
g_musb_hcd.chan[i][0].waitsem = usb_osal_sem_create(0);
g_musb_hcd.chan[i][1].waitsem = usb_osal_sem_create(0);
}
return 0;
@@ -495,7 +455,7 @@ int usb_hc_hw_init(void)
usb_hc_low_level_init();
USBC_SelectActiveEp(0);
musb_set_active_ep(0);
HWREGB(USB_BASE + MUSB_IND_TXINTERVAL_OFFSET) = 0;
HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_64;
HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = 0;
@@ -503,8 +463,8 @@ int usb_hc_hw_init(void)
HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = 0;
fifo_offset += 64;
for (uint8_t i = 1; i < CONIFG_USB_MUSB_EP_NUM; i++) {
USBC_SelectActiveEp(i);
for (uint8_t i = 1; i < CONIFG_USB_MUSB_PIPE_NUM; i++) {
musb_set_active_ep(i);
HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512;
HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = fifo_offset;
HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512;
@@ -526,7 +486,7 @@ int usb_hc_hw_init(void)
HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) |= USB_DEVCTL_SESSION;
#ifdef CONFIG_USB_MUSB_SUNXI
USBC_SelectActiveEp(0);
musb_set_active_ep(0);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
#endif
return 0;
@@ -601,30 +561,32 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
hport = ep_cfg->hport;
ep_idx = ep_cfg->ep_addr & 0x7f;
old_ep_index = USBC_GetActiveEp();
USBC_SelectActiveEp(ep_idx);
if (ep_idx > CONIFG_USB_MUSB_PIPE_NUM) {
return -1;
}
old_ep_index = musb_get_active_ep();
musb_set_active_ep(ep_idx);
if (ep_cfg->ep_addr & 0x80) {
chan = &g_musb_hcd.chan[ep_idx][1];
chan->in = true;
} else {
chan = &g_musb_hcd.chan[ep_idx][0];
chan->in = false;
}
chan->enable = false;
chan->ep_idx = ep_idx;
if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
chidx = musb_pipe_alloc(0);
chan = &g_musb_hcd.chan[0][chidx];
memset(chan, 0, sizeof(struct musb_pipe));
chan->inuse = true;
chan->ep_idx = 0;
chan->interval = 0;
chan->mps = ep_cfg->ep_mps;
chan->hport = hport;
chan->waitsem = usb_osal_sem_create(0);
*ep = (usbh_epinfo_t)chan;
} else {
chidx = musb_pipe_alloc(ep_idx);
chan = &g_musb_hcd.chan[ep_idx][chidx];
memset(chan, 0, sizeof(struct musb_pipe));
chan->inuse = true;
chan->in = ep_cfg->ep_addr & 0x80 ? 1 : 0;
chan->ep_idx = ep_idx;
chan->interval = ep_cfg->ep_interval;
chan->mps = ep_cfg->ep_mps;
@@ -638,8 +600,6 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
chan->hport = hport;
chan->waitsem = usb_osal_sem_create(0);
if (chan->in) {
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << ep_idx);
} else {
@@ -649,15 +609,13 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
*ep = (usbh_epinfo_t)chan;
}
USBC_SelectActiveEp(old_ep_index);
musb_set_active_ep(old_ep_index);
return 0;
}
int usbh_ep_free(usbh_epinfo_t ep)
{
struct musb_pipe *chan = (struct musb_pipe *)ep;
musb_pipe_free(chan);
usb_osal_sem_delete(chan->waitsem);
return 0;
}
@@ -677,8 +635,8 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
goto errout_with_mutex;
}
old_ep_index = USBC_GetActiveEp();
USBC_SelectActiveEp(0);
old_ep_index = musb_get_active_ep();
musb_set_active_ep(0);
HWREGB(USB_TXADDR_BASE(0)) = chan->hport->dev_addr;
HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = chan->speed;
@@ -690,7 +648,7 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
HWREGB(USB_TXHUBPORT_BASE(0)) = chan->hport->parent->index - 1;
}
usb_musb_write_packet(0, (uint8_t *)setup, 8);
musb_write_packet(0, (uint8_t *)setup, 8);
ep0_outlen = 8;
if (setup->wLength && buffer) {
if (setup->bmRequestType & 0x80) {
@@ -705,7 +663,7 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
}
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY | USB_CSRL0_SETUP;
USBC_SelectActiveEp(old_ep_index);
musb_set_active_ep(old_ep_index);
ret = musb_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
if (ret < 0) {
@@ -716,6 +674,7 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
return ret;
errout_with_mutex:
chan->waiter = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[0]);
return ret;
}
@@ -736,8 +695,8 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
goto errout_with_mutex;
}
old_ep_index = USBC_GetActiveEp();
USBC_SelectActiveEp(chan->ep_idx);
old_ep_index = musb_get_active_ep();
musb_set_active_ep(chan->ep_idx);
if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr;
@@ -773,12 +732,12 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
buflen = chan->mps;
}
usb_musb_write_packet(chan->ep_idx, chan->buffer, buflen);
musb_write_packet(chan->ep_idx, chan->buffer, buflen);
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
}
USBC_SelectActiveEp(old_ep_index);
musb_set_active_ep(old_ep_index);
ret = musb_pipe_wait(chan, timeout);
if (ret < 0) {
@@ -789,6 +748,7 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
return ret;
errout_with_mutex:
chan->waiter = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret;
}
@@ -809,8 +769,8 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
goto errout_with_mutex;
}
old_ep_index = USBC_GetActiveEp();
USBC_SelectActiveEp(chan->ep_idx);
old_ep_index = musb_get_active_ep();
musb_set_active_ep(chan->ep_idx);
if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr;
@@ -846,12 +806,12 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
buflen = chan->mps;
}
usb_musb_write_packet(chan->ep_idx, chan->buffer, buflen);
musb_write_packet(chan->ep_idx, chan->buffer, buflen);
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
}
USBC_SelectActiveEp(old_ep_index);
musb_set_active_ep(old_ep_index);
ret = musb_pipe_wait(chan, timeout);
if (ret < 0) {
@@ -862,6 +822,7 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, ui
return ret;
errout_with_mutex:
chan->waiter = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret;
}
@@ -872,7 +833,7 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
uint32_t old_ep_index;
struct musb_pipe *chan = (struct musb_pipe *)ep;
if (g_musb_hcd.active_chan[chan->ep_idx]) {
if (chan->enable) {
return -EINVAL;
}
@@ -886,8 +847,8 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
goto errout_with_mutex;
}
old_ep_index = USBC_GetActiveEp();
USBC_SelectActiveEp(chan->ep_idx);
old_ep_index = musb_get_active_ep();
musb_set_active_ep(chan->ep_idx);
if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr;
@@ -923,17 +884,18 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
buflen = chan->mps;
}
usb_musb_write_packet(chan->ep_idx, chan->buffer, buflen);
musb_write_packet(chan->ep_idx, chan->buffer, buflen);
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
}
USBC_SelectActiveEp(old_ep_index);
musb_set_active_ep(old_ep_index);
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret;
errout_with_mutex:
g_musb_hcd.active_chan[chan->ep_idx] = NULL;
chan->enable = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret;
}
@@ -944,7 +906,7 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
uint32_t old_ep_index;
struct musb_pipe *chan = (struct musb_pipe *)ep;
if (g_musb_hcd.active_chan[chan->ep_idx]) {
if (chan->enable) {
return -EINVAL;
}
@@ -958,8 +920,8 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
goto errout_with_mutex;
}
old_ep_index = USBC_GetActiveEp();
USBC_SelectActiveEp(chan->ep_idx);
old_ep_index = musb_get_active_ep();
musb_set_active_ep(chan->ep_idx);
if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr;
@@ -995,17 +957,18 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
buflen = chan->mps;
}
usb_musb_write_packet(chan->ep_idx, chan->buffer, buflen);
musb_write_packet(chan->ep_idx, chan->buffer, buflen);
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) &= ~USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) |= USB_TXCSRH1_MODE;
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
}
USBC_SelectActiveEp(old_ep_index);
musb_set_active_ep(old_ep_index);
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret;
errout_with_mutex:
g_musb_hcd.active_chan[chan->ep_idx] = NULL;
chan->enable = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret;
}
@@ -1031,7 +994,7 @@ int usb_ep_cancel(usbh_epinfo_t ep)
chan->xfrd = 0;
#endif
g_musb_hcd.active_chan[chan->ep_idx] = NULL;
chan->enable = false;
usb_osal_leave_critical_section(flags);
/* Is there a thread waiting for this transfer to complete? */
@@ -1056,9 +1019,9 @@ void handle_ep0(void)
struct musb_pipe *chan;
int result = 0;
chan = (struct musb_pipe *)g_musb_hcd.active_chan[0];
chan = (struct musb_pipe *)&g_musb_hcd.chan[0][0];
USBC_SelectActiveEp(0);
musb_set_active_ep(0);
ep0_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
if (ep0_status & USB_CSRL0_STALLED) {
@@ -1070,7 +1033,7 @@ void handle_ep0(void)
if (ep0_status & USB_CSRL0_ERROR) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_ERROR;
usb_musb_fifo_flush(0);
musb_fifo_flush(0);
usb_ep0_state = USB_EP0_STATE_SETUP;
result = -EIO;
goto chan_wait;
@@ -1100,7 +1063,7 @@ void handle_ep0(void)
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
usb_musb_read_packet(0, chan->buffer, size);
musb_read_packet(0, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_RXRDY;
@@ -1143,7 +1106,7 @@ void handle_ep0(void)
chan->xfrd += ep0_outlen;
usb_musb_write_packet(0, chan->buffer, size);
musb_write_packet(0, chan->buffer, size);
chan->buffer += size;
chan->buflen -= size;
@@ -1159,7 +1122,7 @@ void handle_ep0(void)
}
return;
chan_wait:
if (chan) {
if (chan->enable) {
chan->result = result;
musb_pipe_wakeup(chan);
}
@@ -1183,7 +1146,7 @@ void USBH_IRQHandler(void)
HWREGB(USB_BASE + MUSB_IS_OFFSET) = is;
old_ep_idx = USBC_GetActiveEp();
old_ep_idx = musb_get_active_ep();
if (is & USB_IS_CONN) {
if (usbh_get_port_connect_status(0)) {
@@ -1193,11 +1156,14 @@ void USBH_IRQHandler(void)
if (is & USB_IS_DISCON) {
if (usbh_get_port_connect_status(0) == false) {
for (uint8_t ep_index = 0; ep_index < CONIFG_USB_MUSB_EP_NUM; ep_index++) {
if (g_musb_hcd.active_chan[ep_index]) {
chan = (struct musb_pipe *)g_musb_hcd.active_chan[ep_index];
chan->result = -ENXIO;
musb_pipe_wakeup(chan);
for (uint8_t ep_idx = 0; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
for (uint8_t j = 0; j < 2; j++) {
chan = &g_musb_hcd.chan[ep_idx][j];
if (chan->waiter) {
chan->result = -ENXIO;
musb_pipe_wakeup(chan);
}
}
}
@@ -1231,102 +1197,103 @@ void USBH_IRQHandler(void)
handle_ep0();
}
while (txis) {
ep_idx = __builtin_ctz(txis);
txis &= ~(1 << ep_idx);
HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
for (uint32_t ep_idx = 1; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
if (txis & (1 << ep_idx)) {
HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
chan = (struct musb_pipe *)g_musb_hcd.active_chan[ep_idx];
chan = &g_musb_hcd.chan[ep_idx][0];
USBC_SelectActiveEp(ep_idx);
musb_set_active_ep(ep_idx);
ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
if (ep_csrl_status & USB_TXCSRL1_ERROR) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_ERROR;
result = -EIO;
goto chan_wait;
} else if (ep_csrl_status & USB_TXCSRL1_NAKTO) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_NAKTO;
result = -EBUSY;
goto chan_wait;
} else if (ep_csrl_status & USB_TXCSRL1_STALL) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_STALL;
result = -EPERM;
goto chan_wait;
} else {
uint32_t size = chan->buflen;
if (size > chan->mps) {
size = chan->mps;
}
chan->buffer += size;
chan->buflen -= size;
chan->xfrd += size;
if (chan->buflen == 0) {
result = 0;
if (ep_csrl_status & USB_TXCSRL1_ERROR) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_ERROR;
result = -EIO;
goto chan_wait;
} else if (ep_csrl_status & USB_TXCSRL1_NAKTO) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_NAKTO;
result = -EBUSY;
goto chan_wait;
} else if (ep_csrl_status & USB_TXCSRL1_STALL) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_STALL;
result = -EPERM;
goto chan_wait;
} else {
usb_musb_write_packet(ep_idx, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
uint32_t size = chan->buflen;
if (size > chan->mps) {
size = chan->mps;
}
chan->buffer += size;
chan->buflen -= size;
chan->xfrd += size;
if (chan->buflen == 0) {
result = 0;
goto chan_wait;
} else {
musb_write_packet(ep_idx, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
}
}
}
}
rxis &= HWREGH(USB_BASE + MUSB_RXIE_OFFSET);
while (rxis) {
ep_idx = __builtin_ctz(rxis);
rxis &= ~(1 << ep_idx);
HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx); // clear isr flag
for (uint32_t ep_idx = 1; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
if (rxis & (1 << ep_idx)) {
HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx); // clear isr flag
chan = (struct musb_pipe *)g_musb_hcd.active_chan[ep_idx];
chan = &g_musb_hcd.chan[ep_idx][1];
USBC_SelectActiveEp(ep_idx);
musb_set_active_ep(ep_idx);
ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET);
//ep_csrh_status = HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET); // todo:for iso transfer
ep_csrl_status = HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET);
//ep_csrh_status = HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET); // todo:for iso transfer
if (ep_csrl_status & USB_RXCSRL1_ERROR) {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_ERROR;
result = -EIO;
goto chan_wait;
} else if (ep_csrl_status & USB_RXCSRL1_NAKTO) {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_NAKTO;
result = -EBUSY;
goto chan_wait;
} else if (ep_csrl_status & USB_RXCSRL1_STALL) {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_STALL;
result = -EPERM;
goto chan_wait;
} else if (ep_csrl_status & USB_RXCSRL1_RXRDY) {
uint32_t size = chan->buflen;
if (size > chan->mps) {
size = chan->mps;
}
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
usb_musb_read_packet(ep_idx, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_RXRDY;
chan->buffer += size;
chan->buflen -= size;
chan->xfrd += size;
if ((size < chan->mps) || (chan->buflen == 0)) {
result = 0;
if (ep_csrl_status & USB_RXCSRL1_ERROR) {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_ERROR;
result = -EIO;
goto chan_wait;
} else {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
} else if (ep_csrl_status & USB_RXCSRL1_NAKTO) {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_NAKTO;
result = -EBUSY;
goto chan_wait;
} else if (ep_csrl_status & USB_RXCSRL1_STALL) {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_STALL;
result = -EPERM;
goto chan_wait;
} else if (ep_csrl_status & USB_RXCSRL1_RXRDY) {
uint32_t size = chan->buflen;
if (size > chan->mps) {
size = chan->mps;
}
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
musb_read_packet(ep_idx, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_RXRDY;
chan->buffer += size;
chan->buflen -= size;
chan->xfrd += size;
if ((size < chan->mps) || (chan->buflen == 0)) {
result = 0;
goto chan_wait;
} else {
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_REQPKT;
}
}
}
}
USBC_SelectActiveEp(old_ep_idx);
musb_set_active_ep(old_ep_idx);
return;
chan_wait:
USBC_SelectActiveEp(old_ep_idx);
if (chan) {
musb_set_active_ep(old_ep_idx);
if (chan->enable) {
chan->result = result;
musb_pipe_wakeup(chan);
}