update synopsys driver
This commit is contained in:
@@ -13,13 +13,19 @@ HCD_HandleTypeDef hhcd_USB_OTG_FS;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define USBH_PID_SETUP 0U
|
||||
#define USBH_PID_DATA 1U
|
||||
|
||||
#ifndef CONFIG_USBHOST_CHANNELS
|
||||
#define CONFIG_USBHOST_CHANNELS 12 /* Number of host channels */
|
||||
#endif
|
||||
|
||||
#define CONFIG_CONTROL_RETRY_COUNT 10
|
||||
|
||||
#define USBH_PID_SETUP 0U
|
||||
#define USBH_PID_DATA 1U
|
||||
|
||||
enum usb_synopsys_transfer_state {
|
||||
TRANSFER_IDLE = 0,
|
||||
TRANSFER_BUSY,
|
||||
};
|
||||
/* This structure retains the state of one host channel. NOTE: Since there
|
||||
* is only one channel operation active at a time, some of the fields in
|
||||
* in the structure could be moved in struct stm32_ubhost_s to achieve
|
||||
@@ -30,6 +36,8 @@ struct usb_synopsys_chan {
|
||||
usb_osal_sem_t waitsem; /* Channel wait semaphore */
|
||||
volatile int result; /* The result of the transfer */
|
||||
bool inuse; /* True: This channel is "in use" */
|
||||
uint8_t interval; /* Interrupt/isochronous EP polling interval */
|
||||
uint8_t transfer_state; /* Interrupt/isochronous EP transfer state */
|
||||
bool in; /* True: IN endpoint */
|
||||
volatile bool waiter; /* True: Thread is waiting for a channel event */
|
||||
volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */
|
||||
@@ -51,6 +59,7 @@ struct usb_synopsys_ctrlinfo {
|
||||
|
||||
struct usb_synopsys_priv {
|
||||
HCD_HandleTypeDef *handle;
|
||||
volatile uint64_t sof_timer;
|
||||
volatile bool connected; /* Connected to device */
|
||||
volatile bool pscwait; /* True: Thread is waiting for a port event */
|
||||
usb_osal_sem_t exclsem; /* Support mutually exclusive access */
|
||||
@@ -154,6 +163,8 @@ static int usb_synopsys_chan_waitsetup(struct usb_synopsys_priv *priv,
|
||||
*/
|
||||
|
||||
chan->waiter = true;
|
||||
chan->result = -EBUSY;
|
||||
chan->xfrd = 0;
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
chan->callback = NULL;
|
||||
chan->arg = NULL;
|
||||
@@ -197,6 +208,8 @@ static int usb_synopsys_chan_asynchsetup(struct usb_synopsys_priv *priv,
|
||||
*/
|
||||
|
||||
chan->waiter = false;
|
||||
chan->result = -EBUSY;
|
||||
chan->xfrd = 0;
|
||||
chan->callback = callback;
|
||||
chan->arg = arg;
|
||||
ret = 0;
|
||||
@@ -228,8 +241,11 @@ static int usb_synopsys_chan_wait(struct usb_synopsys_priv *priv, struct usb_syn
|
||||
* when the transfer is completed.
|
||||
*/
|
||||
|
||||
while (chan->waiter) {
|
||||
usb_osal_sem_take(chan->waitsem);
|
||||
if (chan->waiter) {
|
||||
ret = usb_osal_sem_take(chan->waitsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* The transfer is complete re-enable interrupts and return the result */
|
||||
@@ -371,9 +387,9 @@ int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uin
|
||||
}
|
||||
|
||||
if (speed == USB_SPEED_FULL) {
|
||||
speed = HCD_SPEED_FULL;
|
||||
speed = 1;
|
||||
} else if (speed == USB_SPEED_LOW) {
|
||||
speed = HCD_SPEED_LOW;
|
||||
speed = 2;
|
||||
}
|
||||
|
||||
ret = HAL_HCD_HC_Init(g_usbhost.handle, ep0info->outndx, 0x00, dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_mps);
|
||||
@@ -384,6 +400,8 @@ int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uin
|
||||
|
||||
int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
struct usb_synopsys_chan *chan;
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
struct usb_synopsys_ctrlinfo *ep0;
|
||||
struct usbh_hubport *hport;
|
||||
int chidx;
|
||||
@@ -398,9 +416,9 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
hport = ep_cfg->hport;
|
||||
|
||||
if (hport->speed == USB_SPEED_FULL) {
|
||||
speed = HCD_SPEED_FULL;
|
||||
speed = 1;
|
||||
} else if (hport->speed == USB_SPEED_LOW) {
|
||||
speed = HCD_SPEED_LOW;
|
||||
speed = 2;
|
||||
}
|
||||
|
||||
if (ep_cfg->ep_type == USB_ENDPOINT_TYPE_CONTROL) {
|
||||
@@ -409,6 +427,11 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
ep0->outndx = usb_synopsys_chan_alloc(&g_usbhost);
|
||||
ep0->inndx = usb_synopsys_chan_alloc(&g_usbhost);
|
||||
|
||||
chan = &priv->chan[ep0->outndx];
|
||||
chan->interval = 0;
|
||||
chan = &priv->chan[ep0->inndx];
|
||||
chan->interval = 0;
|
||||
|
||||
HAL_HCD_HC_Init(g_usbhost.handle, ep0->outndx, 0x00, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
|
||||
HAL_HCD_HC_Init(g_usbhost.handle, ep0->inndx, 0x80, hport->dev_addr, speed, USB_ENDPOINT_TYPE_CONTROL, ep_cfg->ep_mps);
|
||||
|
||||
@@ -416,6 +439,10 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
|
||||
} else {
|
||||
chidx = usb_synopsys_chan_alloc(&g_usbhost);
|
||||
|
||||
chan = &priv->chan[chidx];
|
||||
chan->interval = ep_cfg->ep_interval;
|
||||
|
||||
HAL_HCD_HC_Init(g_usbhost.handle, chidx, ep_cfg->ep_addr, hport->dev_addr, speed, ep_cfg->ep_type, ep_cfg->ep_mps);
|
||||
|
||||
g_usbhost.handle->hc[chidx].toggle_in = 0;
|
||||
@@ -450,7 +477,7 @@ int usbh_ep_free(usbh_epinfo_t ep)
|
||||
int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint8_t *buffer)
|
||||
{
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
uint32_t retries;
|
||||
struct usb_synopsys_chan *chan;
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
struct usb_synopsys_ctrlinfo *ep0info = (struct usb_synopsys_ctrlinfo *)ep;
|
||||
@@ -460,9 +487,9 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
return ret;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[ep0info->outndx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->outndx, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
@@ -471,17 +498,17 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
(uint8_t *)setup, /* data buffer */
|
||||
8, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
if (setup->wLength && buffer) {
|
||||
if (setup->bmRequestType & 0x80) {
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[ep0info->inndx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->inndx, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
@@ -490,49 +517,74 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
buffer, /* data buffer */
|
||||
setup->wLength, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[ep0info->outndx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->outndx, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
0, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
NULL, /* data buffer */
|
||||
0, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
|
||||
/* For ep0 out,we must retry more */
|
||||
for (retries = 0; retries < 10; retries++) {
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->outndx, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
0, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
NULL, /* data buffer */
|
||||
0, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret == -EAGAIN) {
|
||||
continue;
|
||||
} else if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
} else if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (retries >= CONFIG_CONTROL_RETRY_COUNT) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
} else {
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[ep0info->outndx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->outndx, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
0, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buffer, /* data buffer */
|
||||
setup->wLength, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
|
||||
/* For ep0 out,we must retry more */
|
||||
for (retries = 0; retries < CONFIG_CONTROL_RETRY_COUNT; retries++) {
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->outndx, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
0, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buffer, /* data buffer */
|
||||
setup->wLength, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret == -EAGAIN) {
|
||||
continue;
|
||||
} else if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
} else if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (retries >= CONFIG_CONTROL_RETRY_COUNT) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[ep0info->inndx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->inndx, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
@@ -541,16 +593,16 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
NULL, /* data buffer */
|
||||
0, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[ep0info->inndx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
ep0info->inndx, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
@@ -559,7 +611,7 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
NULL, /* data buffer */
|
||||
0, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
@@ -575,7 +627,6 @@ errout_with_mutex:
|
||||
int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
{
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
struct usb_synopsys_chan *chan;
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
@@ -585,9 +636,9 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
return ret;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[chidx];
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
chidx, /* Pipe index */
|
||||
g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
|
||||
@@ -596,7 +647,7 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
buffer, /* data buffer */
|
||||
buflen, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
@@ -612,6 +663,7 @@ errout_with_mutex:
|
||||
int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
{
|
||||
uint32_t flags;
|
||||
uint32_t retries;
|
||||
int ret;
|
||||
struct usb_synopsys_chan *chan;
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
@@ -621,9 +673,13 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
chan = &priv->chan[chidx];
|
||||
|
||||
usb_synopsys_chan_waitsetup(priv, chan);
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan->transfer_state = TRANSFER_BUSY;
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
chidx, /* Pipe index */
|
||||
g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
|
||||
@@ -632,6 +688,7 @@ int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
buffer, /* data buffer */
|
||||
buflen, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
ret = usb_synopsys_chan_wait(priv, chan);
|
||||
if (ret < 0) {
|
||||
@@ -648,7 +705,6 @@ errout_with_mutex:
|
||||
int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
|
||||
{
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
struct usb_synopsys_chan *chan;
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
@@ -658,9 +714,9 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
|
||||
return ret;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[chidx];
|
||||
usb_synopsys_chan_asynchsetup(priv, chan, callback, arg);
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
chidx, /* Pipe index */
|
||||
g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
|
||||
@@ -669,7 +725,6 @@ int usbh_ep_bulk_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
|
||||
buffer, /* data buffer */
|
||||
buflen, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
|
||||
@@ -689,9 +744,11 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
|
||||
return ret;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan = &priv->chan[chidx];
|
||||
usb_synopsys_chan_asynchsetup(priv, chan, callback, arg);
|
||||
flags = usb_osal_enter_critical_section();
|
||||
chan->transfer_state = TRANSFER_BUSY;
|
||||
|
||||
ret = HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
chidx, /* Pipe index */
|
||||
g_usbhost.handle->hc[chidx].ep_is_in ? 1 : 0, /* Direction : IN */
|
||||
@@ -700,8 +757,8 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
|
||||
buffer, /* data buffer */
|
||||
buflen, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
|
||||
return ret;
|
||||
@@ -709,6 +766,49 @@ int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t bufl
|
||||
|
||||
int usb_ep_cancel(usbh_epinfo_t ep)
|
||||
{
|
||||
int ret;
|
||||
uint32_t flags;
|
||||
struct usb_synopsys_chan *chan;
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
|
||||
chan = &priv->chan[chidx];
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
chan->result = -ESHUTDOWN;
|
||||
/* Is there a thread waiting for this transfer to complete? */
|
||||
|
||||
if (chan->waiter) {
|
||||
/* Wake'em up! */
|
||||
chan->waiter = false;
|
||||
usb_osal_sem_give(chan->waitsem);
|
||||
}
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
/* No.. is an asynchronous callback expected when the transfer
|
||||
* completes?
|
||||
*/
|
||||
|
||||
else if (chan->callback) {
|
||||
usbh_asynch_callback_t callback;
|
||||
void *arg;
|
||||
|
||||
/* Extract the callback information */
|
||||
|
||||
callback = chan->callback;
|
||||
arg = chan->arg;
|
||||
|
||||
chan->callback = NULL;
|
||||
chan->arg = NULL;
|
||||
chan->xfrd = 0;
|
||||
|
||||
/* Then perform the callback */
|
||||
|
||||
callback(arg, -ESHUTDOWN);
|
||||
}
|
||||
#endif
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -731,6 +831,17 @@ void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
|
||||
if (g_usbhost.connected) {
|
||||
g_usbhost.connected = false;
|
||||
usb_synopsys_chan_freeall(&g_usbhost);
|
||||
|
||||
if (g_usbhost.chan[0].waiter) {
|
||||
/* Wake'em up! */
|
||||
g_usbhost.chan[0].waiter = false;
|
||||
usb_osal_sem_give(g_usbhost.chan[0].waitsem);
|
||||
}
|
||||
if (g_usbhost.chan[1].waiter) {
|
||||
/* Wake'em up! */
|
||||
g_usbhost.chan[1].waiter = false;
|
||||
usb_osal_sem_give(g_usbhost.chan[1].waitsem);
|
||||
}
|
||||
extern void usbh_event_notify_handler(uint8_t event, uint8_t rhport);
|
||||
usbh_event_notify_handler(USBH_EVENT_REMOVED, 1);
|
||||
}
|
||||
@@ -742,28 +853,45 @@ void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum,
|
||||
struct usb_synopsys_priv *priv = &g_usbhost;
|
||||
|
||||
chan = &priv->chan[chnum];
|
||||
if (urb_state == URB_DONE || urb_state == URB_STALL || urb_state == URB_ERROR || urb_state == URB_NOTREADY) {
|
||||
if (urb_state != URB_NOTREADY) {
|
||||
if (urb_state == URB_ERROR) {
|
||||
chan->result = -EIO;
|
||||
} else if (urb_state == URB_STALL) {
|
||||
chan->result = -EPERM;
|
||||
} else if (urb_state == URB_DONE) {
|
||||
chan->result = 0;
|
||||
}
|
||||
chan->in = g_usbhost.handle->hc[chnum].ep_is_in;
|
||||
chan->xfrd = g_usbhost.handle->hc[chnum].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chnum) : g_usbhost.handle->hc[chnum].xfer_len;
|
||||
usb_synopsys_chan_wakeup(priv, chan);
|
||||
} else {
|
||||
if (g_usbhost.handle->hc[chnum].ep_is_in == 0 && (g_usbhost.handle->hc[chnum].ep_type == USB_ENDPOINT_TYPE_CONTROL || g_usbhost.handle->hc[chnum].ep_type == USB_ENDPOINT_TYPE_BULK)) {
|
||||
|
||||
if (urb_state == URB_NOTREADY) {
|
||||
chan->result = -EAGAIN;
|
||||
} else if (urb_state == URB_STALL) {
|
||||
chan->result = -EPERM;
|
||||
} else if (urb_state == URB_ERROR) {
|
||||
chan->result = -EIO;
|
||||
} else if (urb_state == URB_DONE) {
|
||||
chan->transfer_state = TRANSFER_IDLE;
|
||||
chan->result = 0;
|
||||
}
|
||||
chan->in = g_usbhost.handle->hc[chnum].ep_is_in;
|
||||
chan->xfrd = g_usbhost.handle->hc[chnum].ep_is_in ? HAL_HCD_HC_GetXferCount(g_usbhost.handle, chnum) : g_usbhost.handle->hc[chnum].xfer_len;
|
||||
|
||||
if (g_usbhost.handle->hc[chnum].ep_type == 0x00 && (urb_state == URB_NOTREADY) && g_usbhost.handle->hc[chnum].ep_is_in) {
|
||||
return;
|
||||
}
|
||||
if ((g_usbhost.handle->hc[chnum].ep_type == 0x02) && (urb_state == URB_NOTREADY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
usb_synopsys_chan_wakeup(priv, chan);
|
||||
}
|
||||
|
||||
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
g_usbhost.sof_timer++;
|
||||
for (uint8_t chnum = 2; chnum < CONFIG_USBHOST_CHANNELS; chnum++) {
|
||||
if (g_usbhost.handle->hc[chnum].ep_type == 0x01 || g_usbhost.handle->hc[chnum].ep_type == 0x03) {
|
||||
if ((g_usbhost.chan[chnum].transfer_state == TRANSFER_BUSY) &&
|
||||
((g_usbhost.sof_timer % g_usbhost.chan[chnum].interval) == 0)) {
|
||||
HAL_HCD_HC_SubmitRequest(g_usbhost.handle,
|
||||
chnum, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
g_usbhost.handle->hc[chnum].ep_type, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
g_usbhost.handle->hc[chnum].xfer_buff, /* data buffer */
|
||||
g_usbhost.handle->hc[chnum].xfer_len, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
chnum, /* Pipe index */
|
||||
g_usbhost.handle->hc[chnum].ep_is_in ? 1 : 0, /* Direction : IN */
|
||||
g_usbhost.handle->hc[chnum].ep_type, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
g_usbhost.handle->hc[chnum].xfer_buff, /* data buffer */
|
||||
g_usbhost.handle->hc[chnum].xfer_len, /* data length */
|
||||
0); /* do ping (HS Only)*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user