update musb chan with bidirectional support,remove more than one the same eps support
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user