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) #define USB_FIFO_BASE(ep_idx) (USB_BASE + MUSB_FIFO_OFFSET + 0x4 * ep_idx)
#ifndef CONIFG_USB_MUSB_EP_NUM #ifndef CONIFG_USB_MUSB_PIPE_NUM
#define CONIFG_USB_MUSB_EP_NUM 5 #define CONIFG_USB_MUSB_PIPE_NUM 5
#endif #endif
typedef enum { typedef enum {
@@ -145,7 +145,7 @@ typedef enum {
struct musb_pipe { struct musb_pipe {
uint8_t ep_idx; uint8_t ep_idx;
bool inuse; /* True: This channel is "in use" */ bool enable; /* True: start transfer */
bool in; /* True: IN endpoint */ bool in; /* True: IN endpoint */
uint16_t mps; uint16_t mps;
uint8_t interval; /* Polling interval */ uint8_t interval; /* Polling interval */
@@ -164,27 +164,26 @@ struct musb_pipe {
}; };
struct musb_hcd { struct musb_hcd {
struct musb_pipe chan[CONIFG_USB_MUSB_EP_NUM][CONFIG_USBHOST_PIPE_NUM]; struct musb_pipe chan[CONIFG_USB_MUSB_PIPE_NUM][2]; /* Support Bidirectional ep */
volatile struct musb_pipe *active_chan[CONIFG_USB_MUSB_EP_NUM]; usb_osal_mutex_t exclsem[CONIFG_USB_MUSB_PIPE_NUM]; /* Support mutually exclusive access */
usb_osal_mutex_t exclsem[CONIFG_USB_MUSB_EP_NUM]; /* Support mutually exclusive access */
} g_musb_hcd; } g_musb_hcd;
static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP; static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
volatile uint8_t ep0_outlen = 0; volatile uint8_t ep0_outlen = 0;
/* get current active ep */ /* 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); return HWREGB(USB_BASE + MUSB_EPIDX_OFFSET);
} }
/* set the active ep */ /* 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; 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; uint8_t ep_idx = ep & 0x7f;
if (ep_idx == 0) { 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; uint32_t *buf32;
uint8_t *buf8; 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; uint32_t *buf32;
uint8_t *buf8; 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 * 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 * when either (1) the device is disconnected, or (2) the transfer
* completed. * completed.
*/ */
g_musb_hcd.active_chan[chan->ep_idx] = chan;
chan->waiter = true; chan->waiter = true;
chan->enable = true;
chan->result = -EBUSY; chan->result = -EBUSY;
chan->xfrd = 0; chan->xfrd = 0;
#ifdef CONFIG_USBHOST_ASYNCH #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 * when either (1) the device is disconnected, or (2) the transfer
* completed. * completed.
*/ */
g_musb_hcd.active_chan[chan->ep_idx] = chan;
chan->waiter = false; chan->waiter = false;
chan->enable = true;
chan->result = -EBUSY; chan->result = -EBUSY;
chan->xfrd = 0; chan->xfrd = 0;
chan->callback = callback; chan->callback = callback;
@@ -447,8 +405,7 @@ static void musb_pipe_wakeup(struct musb_pipe *chan)
void *arg; void *arg;
int nbytes; int nbytes;
g_musb_hcd.active_chan[chan->ep_idx] = NULL; chan->enable = false;
/* Is the transfer complete? */ /* Is the transfer complete? */
if (chan->waiter) { if (chan->waiter) {
/* Wake'em up! */ /* Wake'em up! */
@@ -481,8 +438,11 @@ __WEAK void usb_hc_low_level_init(void)
int usb_hc_sw_init(void) int usb_hc_sw_init(void)
{ {
memset(&g_musb_hcd, 0, sizeof(struct musb_hcd)); 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.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; return 0;
@@ -495,7 +455,7 @@ int usb_hc_hw_init(void)
usb_hc_low_level_init(); 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_IND_TXINTERVAL_OFFSET) = 0;
HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_64; HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_64;
HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = 0; HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = 0;
@@ -503,8 +463,8 @@ int usb_hc_hw_init(void)
HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = 0; HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = 0;
fifo_offset += 64; fifo_offset += 64;
for (uint8_t i = 1; i < CONIFG_USB_MUSB_EP_NUM; i++) { for (uint8_t i = 1; i < CONIFG_USB_MUSB_PIPE_NUM; i++) {
USBC_SelectActiveEp(i); musb_set_active_ep(i);
HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512; HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512;
HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = fifo_offset; HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = fifo_offset;
HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = USB_TXFIFOSZ_SIZE_512; 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; HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) |= USB_DEVCTL_SESSION;
#ifdef CONFIG_USB_MUSB_SUNXI #ifdef CONFIG_USB_MUSB_SUNXI
USBC_SelectActiveEp(0); musb_set_active_ep(0);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY; HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
#endif #endif
return 0; 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; hport = ep_cfg->hport;
ep_idx = ep_cfg->ep_addr & 0x7f; 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) { 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->interval = 0;
chan->mps = ep_cfg->ep_mps; chan->mps = ep_cfg->ep_mps;
chan->hport = hport; chan->hport = hport;
chan->waitsem = usb_osal_sem_create(0);
*ep = (usbh_epinfo_t)chan; *ep = (usbh_epinfo_t)chan;
} else { } 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->interval = ep_cfg->ep_interval;
chan->mps = ep_cfg->ep_mps; 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->hport = hport;
chan->waitsem = usb_osal_sem_create(0);
if (chan->in) { if (chan->in) {
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << ep_idx); HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << ep_idx);
} else { } 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; *ep = (usbh_epinfo_t)chan;
} }
USBC_SelectActiveEp(old_ep_index); musb_set_active_ep(old_ep_index);
return 0; return 0;
} }
int usbh_ep_free(usbh_epinfo_t ep) int usbh_ep_free(usbh_epinfo_t ep)
{ {
struct musb_pipe *chan = (struct musb_pipe *)ep; struct musb_pipe *chan = (struct musb_pipe *)ep;
musb_pipe_free(chan);
usb_osal_sem_delete(chan->waitsem);
return 0; return 0;
} }
@@ -677,8 +635,8 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
goto errout_with_mutex; goto errout_with_mutex;
} }
old_ep_index = USBC_GetActiveEp(); old_ep_index = musb_get_active_ep();
USBC_SelectActiveEp(0); musb_set_active_ep(0);
HWREGB(USB_TXADDR_BASE(0)) = chan->hport->dev_addr; HWREGB(USB_TXADDR_BASE(0)) = chan->hport->dev_addr;
HWREGB(USB_BASE + MUSB_IND_TXTYPE_OFFSET) = chan->speed; 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; 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; ep0_outlen = 8;
if (setup->wLength && buffer) { if (setup->wLength && buffer) {
if (setup->bmRequestType & 0x80) { 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; 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); ret = musb_pipe_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
if (ret < 0) { if (ret < 0) {
@@ -716,6 +674,7 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
return ret; return ret;
errout_with_mutex: errout_with_mutex:
chan->waiter = false; chan->waiter = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[0]); usb_osal_mutex_give(g_musb_hcd.exclsem[0]);
return ret; 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; goto errout_with_mutex;
} }
old_ep_index = USBC_GetActiveEp(); old_ep_index = musb_get_active_ep();
USBC_SelectActiveEp(chan->ep_idx); musb_set_active_ep(chan->ep_idx);
if (chan->in) { if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr; 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; 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_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; 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); ret = musb_pipe_wait(chan, timeout);
if (ret < 0) { 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; return ret;
errout_with_mutex: errout_with_mutex:
chan->waiter = false; chan->waiter = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]); usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret; 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; goto errout_with_mutex;
} }
old_ep_index = USBC_GetActiveEp(); old_ep_index = musb_get_active_ep();
USBC_SelectActiveEp(chan->ep_idx); musb_set_active_ep(chan->ep_idx);
if (chan->in) { if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr; 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; 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_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; 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); ret = musb_pipe_wait(chan, timeout);
if (ret < 0) { 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; return ret;
errout_with_mutex: errout_with_mutex:
chan->waiter = false; chan->waiter = false;
chan->enable = false;
usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]); usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret; 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; uint32_t old_ep_index;
struct musb_pipe *chan = (struct musb_pipe *)ep; struct musb_pipe *chan = (struct musb_pipe *)ep;
if (g_musb_hcd.active_chan[chan->ep_idx]) { if (chan->enable) {
return -EINVAL; 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; goto errout_with_mutex;
} }
old_ep_index = USBC_GetActiveEp(); old_ep_index = musb_get_active_ep();
USBC_SelectActiveEp(chan->ep_idx); musb_set_active_ep(chan->ep_idx);
if (chan->in) { if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr; 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; 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_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; 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]); usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret; return ret;
errout_with_mutex: 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]); usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret; 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; uint32_t old_ep_index;
struct musb_pipe *chan = (struct musb_pipe *)ep; struct musb_pipe *chan = (struct musb_pipe *)ep;
if (g_musb_hcd.active_chan[chan->ep_idx]) { if (chan->enable) {
return -EINVAL; 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; goto errout_with_mutex;
} }
old_ep_index = USBC_GetActiveEp(); old_ep_index = musb_get_active_ep();
USBC_SelectActiveEp(chan->ep_idx); musb_set_active_ep(chan->ep_idx);
if (chan->in) { if (chan->in) {
HWREGB(USB_RXADDR_BASE(chan->ep_idx)) = chan->hport->dev_addr; 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; 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_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; 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]); usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret; return ret;
errout_with_mutex: 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]); usb_osal_mutex_give(g_musb_hcd.exclsem[chan->ep_idx]);
return ret; return ret;
} }
@@ -1031,7 +994,7 @@ int usb_ep_cancel(usbh_epinfo_t ep)
chan->xfrd = 0; chan->xfrd = 0;
#endif #endif
g_musb_hcd.active_chan[chan->ep_idx] = NULL; chan->enable = false;
usb_osal_leave_critical_section(flags); usb_osal_leave_critical_section(flags);
/* Is there a thread waiting for this transfer to complete? */ /* Is there a thread waiting for this transfer to complete? */
@@ -1056,9 +1019,9 @@ void handle_ep0(void)
struct musb_pipe *chan; struct musb_pipe *chan;
int result = 0; 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); ep0_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
if (ep0_status & USB_CSRL0_STALLED) { if (ep0_status & USB_CSRL0_STALLED) {
@@ -1070,7 +1033,7 @@ void handle_ep0(void)
if (ep0_status & USB_CSRL0_ERROR) { if (ep0_status & USB_CSRL0_ERROR) {
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~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; usb_ep0_state = USB_EP0_STATE_SETUP;
result = -EIO; result = -EIO;
goto chan_wait; goto chan_wait;
@@ -1100,7 +1063,7 @@ void handle_ep0(void)
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET)); 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; HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_RXRDY;
@@ -1143,7 +1106,7 @@ void handle_ep0(void)
chan->xfrd += ep0_outlen; chan->xfrd += ep0_outlen;
usb_musb_write_packet(0, chan->buffer, size); musb_write_packet(0, chan->buffer, size);
chan->buffer += size; chan->buffer += size;
chan->buflen -= size; chan->buflen -= size;
@@ -1159,7 +1122,7 @@ void handle_ep0(void)
} }
return; return;
chan_wait: chan_wait:
if (chan) { if (chan->enable) {
chan->result = result; chan->result = result;
musb_pipe_wakeup(chan); musb_pipe_wakeup(chan);
} }
@@ -1183,7 +1146,7 @@ void USBH_IRQHandler(void)
HWREGB(USB_BASE + MUSB_IS_OFFSET) = is; 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 (is & USB_IS_CONN) {
if (usbh_get_port_connect_status(0)) { if (usbh_get_port_connect_status(0)) {
@@ -1193,13 +1156,16 @@ void USBH_IRQHandler(void)
if (is & USB_IS_DISCON) { if (is & USB_IS_DISCON) {
if (usbh_get_port_connect_status(0) == false) { if (usbh_get_port_connect_status(0) == false) {
for (uint8_t ep_index = 0; ep_index < CONIFG_USB_MUSB_EP_NUM; ep_index++) { for (uint8_t ep_idx = 0; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
if (g_musb_hcd.active_chan[ep_index]) { for (uint8_t j = 0; j < 2; j++) {
chan = (struct musb_pipe *)g_musb_hcd.active_chan[ep_index]; chan = &g_musb_hcd.chan[ep_idx][j];
if (chan->waiter) {
chan->result = -ENXIO; chan->result = -ENXIO;
musb_pipe_wakeup(chan); musb_pipe_wakeup(chan);
} }
} }
}
usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1); usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1);
} }
@@ -1231,14 +1197,13 @@ void USBH_IRQHandler(void)
handle_ep0(); handle_ep0();
} }
while (txis) { for (uint32_t ep_idx = 1; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
ep_idx = __builtin_ctz(txis); if (txis & (1 << ep_idx)) {
txis &= ~(1 << ep_idx);
HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (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);
@@ -1269,21 +1234,21 @@ void USBH_IRQHandler(void)
result = 0; result = 0;
goto chan_wait; goto chan_wait;
} else { } else {
usb_musb_write_packet(ep_idx, chan->buffer, size); musb_write_packet(ep_idx, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY; HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
} }
} }
} }
}
rxis &= HWREGH(USB_BASE + MUSB_RXIE_OFFSET); rxis &= HWREGH(USB_BASE + MUSB_RXIE_OFFSET);
while (rxis) { for (uint32_t ep_idx = 1; ep_idx < CONIFG_USB_MUSB_PIPE_NUM; ep_idx++) {
ep_idx = __builtin_ctz(rxis); if (rxis & (1 << ep_idx)) {
rxis &= ~(1 << ep_idx);
HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx); // clear isr flag 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_csrl_status = HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET);
//ep_csrh_status = HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET); // todo:for iso transfer //ep_csrh_status = HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET); // todo:for iso transfer
@@ -1307,7 +1272,7 @@ void USBH_IRQHandler(void)
} }
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET)); size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
usb_musb_read_packet(ep_idx, chan->buffer, size); musb_read_packet(ep_idx, chan->buffer, size);
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_RXRDY; HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~USB_RXCSRL1_RXRDY;
@@ -1322,11 +1287,13 @@ void USBH_IRQHandler(void)
} }
} }
} }
USBC_SelectActiveEp(old_ep_idx); }
musb_set_active_ep(old_ep_idx);
return; return;
chan_wait: chan_wait:
USBC_SelectActiveEp(old_ep_idx); musb_set_active_ep(old_ep_idx);
if (chan) { if (chan->enable) {
chan->result = result; chan->result = result;
musb_pipe_wakeup(chan); musb_pipe_wakeup(chan);
} }