diff --git a/port/musb/usb_hc_musb.c b/port/musb/usb_hc_musb.c index 5c461f14..148170f2 100644 --- a/port/musb/usb_hc_musb.c +++ b/port/musb/usb_hc_musb.c @@ -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); }