update es32 host demo and musb driver
This commit is contained in:
@@ -248,7 +248,7 @@
|
||||
FreeRTOS与软件定时器有关的配置选项
|
||||
**********************************************************************/
|
||||
//启用软件定时器
|
||||
#define configUSE_TIMERS 0
|
||||
#define configUSE_TIMERS 1
|
||||
//软件定时器优先级
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1)
|
||||
//软件定时器队列长度
|
||||
@@ -268,7 +268,7 @@
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
//#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
//#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
//#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
|
||||
@@ -12,12 +12,24 @@
|
||||
#define CONFIG_USBHOST_EHPORTS 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_INTF_NUM
|
||||
#define CONFIG_USBHOST_INTF_NUM 6
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_EP_NUM
|
||||
#define CONFIG_USBHOST_EP_NUM 2
|
||||
#define CONFIG_USBHOST_EP_NUM 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
|
||||
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_HPWORKQ_PRIO
|
||||
@@ -54,7 +66,7 @@
|
||||
#define CONFIG_USB_EHCI_QH_NUM (10)
|
||||
#define CONFIG_USB_EHCI_QTD_NUM (10)
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
// #define CONFIG_USB_ECHI_HCOR_RESERVED
|
||||
#define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
|
||||
#endif
|
||||
@@ -167,25 +167,9 @@
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>174</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>14404</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>..\..\..\..\..\class\hid\usbh_hid.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\out\../../../../../class/hid/usbh_hid.c\174</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>175</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>14412</Address>
|
||||
<Address>18430</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
@@ -197,20 +181,36 @@
|
||||
<Expression>\\out\../../../../../class/hid/usbh_hid.c\175</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>2</Number>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>88</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<Address>19012</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>..\..\..\..\..\class\hid\usbh_hid.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
<Expression>\\out\../../../../../class/hid/usbh_hid.c\88</Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>2</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>475</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>14888</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>1</BreakIfRCount>
|
||||
<Filename>..\..\..\..\..\core\usbh_core.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression>\\out\../../../../../core/usbh_core.c\475</Expression>
|
||||
</Bp>
|
||||
</Breakpoint>
|
||||
<WatchWindow1>
|
||||
@@ -224,6 +224,11 @@
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>report_buffer</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>2</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>desc</ItemText>
|
||||
</Ww>
|
||||
</WatchWindow1>
|
||||
<MemoryWindow1>
|
||||
<Mm>
|
||||
@@ -452,7 +457,7 @@
|
||||
|
||||
<Group>
|
||||
<GroupName>app</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
@@ -600,7 +605,7 @@
|
||||
|
||||
<Group>
|
||||
<GroupName>FreeRTOS</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
|
||||
@@ -338,7 +338,7 @@
|
||||
<v6Rtti>0</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_ASSERT,ES32F36xx,USBD_CDC_HS</Define>
|
||||
<Define>USE_ASSERT,ES32F36xx,</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>..\Drivers\CMSIS\Include;..\Drivers\CMSIS\Device\EastSoft\ES32F36xx\Include;..\Drivers\ALD\ES32F36xx\Include;..\Inc;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\hub;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM3</IncludePath>
|
||||
</VariousControls>
|
||||
|
||||
@@ -130,7 +130,7 @@ void DebugMon_Handler(void)
|
||||
// /* Added thread switching operation */
|
||||
// return;
|
||||
//}
|
||||
|
||||
extern void xPortSysTickHandler( void );
|
||||
/**
|
||||
* @brief SysTick IRQ handler
|
||||
* @retval None
|
||||
@@ -139,9 +139,8 @@ void SysTick_Handler(void)
|
||||
{
|
||||
ald_inc_tick();
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){
|
||||
xPortSysTickHandler();
|
||||
}
|
||||
return;
|
||||
xPortSysTickHandler();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ALD_DMA
|
||||
|
||||
@@ -123,11 +123,6 @@ void usb_hc_low_level_init(void)
|
||||
usb_pin_init();
|
||||
}
|
||||
|
||||
void delay(uint32_t delay_us)
|
||||
{
|
||||
while (delay_us--) {
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Test main function
|
||||
* @retval Status.
|
||||
@@ -147,9 +142,8 @@ int main()
|
||||
printf("\rSystem start...\r\n");
|
||||
|
||||
usbh_initialize();
|
||||
vTaskStartScheduler();
|
||||
vTaskStartScheduler();
|
||||
while (1) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,15 +154,15 @@ int main()
|
||||
*/
|
||||
static void vtask_led(void *pvParameters)
|
||||
{
|
||||
TickType_t xlast_wake_time;
|
||||
const TickType_t xfreq = 500;
|
||||
|
||||
xlast_wake_time = xTaskGetTickCount();
|
||||
TickType_t xlast_wake_time;
|
||||
const TickType_t xfreq = 500;
|
||||
|
||||
while(1) {
|
||||
xlast_wake_time = xTaskGetTickCount();
|
||||
|
||||
while (1) {
|
||||
printf("test\r\n");
|
||||
vTaskDelayUntil(&xlast_wake_time, pdMS_TO_TICKS(xfreq));
|
||||
}
|
||||
vTaskDelayUntil(&xlast_wake_time, pdMS_TO_TICKS(xfreq));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -52,10 +52,6 @@ void USBH_IRQHandler(int, void *);
|
||||
#define MUSB_FIFO_OFFSET 0x20
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_CHANNELS
|
||||
#define CONFIG_USBHOST_CHANNELS 8
|
||||
#endif
|
||||
|
||||
#define USB ((USB0_Type *)USB_BASE)
|
||||
|
||||
#define HWREG(x) \
|
||||
@@ -78,12 +74,21 @@ void USBH_IRQHandler(int, void *);
|
||||
#define USB_TXINTERVALx_BASE (USB_BASE + MUSB_IND_TXINTERVAL_OFFSET)
|
||||
#define USB_RXINTERVALx_BASE (USB_BASE + MUSB_IND_RXINTERVAL_OFFSET)
|
||||
|
||||
#ifdef USB_MUSB_SUNXI
|
||||
#define USB_TXADDR_BASE(ep_idx) (&USB->TXFUNCADDR0)
|
||||
#define USB_TXHUBADDR_BASE(ep_idx) (&USB->TXHUBADDR0)
|
||||
#define USB_TXHUBPORT_BASE(ep_idx) (&USB->TXHUBPORT0)
|
||||
#define USB_RXADDR_BASE(ep_idx) (&USB->RXFUNCADDR0)
|
||||
#define USB_RXHUBADDR_BASE(ep_idx) (&USB->RXHUBADDR0)
|
||||
#define USB_RXHUBPORT_BASE(ep_idx) (&USB->RXHUBPORT0)
|
||||
#else
|
||||
#define USB_TXADDR_BASE(ep_idx) (&USB->TXFUNCADDR0 + 0x8 * ep_idx)
|
||||
#define USB_TXHUBADDR_BASE(ep_idx) (&USB->TXFUNCADDR0 + 0x8 * ep_idx + 2)
|
||||
#define USB_TXHUBPORT_BASE(ep_idx) (&USB->TXFUNCADDR0 + 0x8 * ep_idx + 3)
|
||||
#define USB_RXADDR_BASE(ep_idx) (&USB->TXFUNCADDR0 + 0x8 * ep_idx + 4)
|
||||
#define USB_RXHUBADDR_BASE(ep_idx) (&USB->TXFUNCADDR0 + 0x8 * ep_idx + 6)
|
||||
#define USB_RXHUBPORT_BASE(ep_idx) (&USB->TXFUNCADDR0 + 0x8 * ep_idx + 7)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
USB_EP0_STATE_SETUP = 0x0, /**< SETUP DATA */
|
||||
@@ -96,18 +101,18 @@ typedef enum {
|
||||
} ep0_state_t;
|
||||
|
||||
struct usb_musb_chan {
|
||||
usb_osal_sem_t waitsem; /* Channel wait semaphore */
|
||||
volatile bool waiter; /* True: Thread is waiting for a channel event */
|
||||
volatile int result; /* The result of the transfer */
|
||||
bool inuse; /* True: This channel is "in use" */
|
||||
bool inuse; /* True: This channel is "in use" */
|
||||
bool in; /* True: IN endpoint */
|
||||
uint16_t mps;
|
||||
uint8_t interval;
|
||||
uint8_t hubaddr;
|
||||
uint8_t hubport;
|
||||
uint8_t interval; /* Polling interval */
|
||||
uint8_t *buffer;
|
||||
uint32_t buflen;
|
||||
bool in; /* True: IN endpoint */
|
||||
volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */
|
||||
volatile uint32_t buflen;
|
||||
volatile uint32_t once_outlen;
|
||||
volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */
|
||||
volatile int result; /* The result of the transfer */
|
||||
volatile bool waiter; /* True: Thread is waiting for a channel event */
|
||||
usb_osal_sem_t waitsem; /* Channel wait semaphore */
|
||||
usb_osal_mutex_t exclsem; /* Support mutually exclusive access */
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
usbh_asynch_callback_t callback; /* Transfer complete callback */
|
||||
void *arg; /* Argument that accompanies the callback */
|
||||
@@ -116,10 +121,8 @@ struct usb_musb_chan {
|
||||
|
||||
struct usb_musb_priv {
|
||||
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 */
|
||||
volatile uint32_t fifo_size_offset;
|
||||
struct usb_musb_chan chan[CONFIG_USBHOST_CHANNELS];
|
||||
struct usb_musb_chan chan[CONFIG_USBHOST_PIPE_NUM];
|
||||
} g_usbhost;
|
||||
|
||||
volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
|
||||
@@ -248,19 +251,18 @@ static uint32_t usb_musb_get_fifo_size(uint16_t mps, uint16_t *used)
|
||||
* Allocate a channel.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int usb_musb_chan_alloc(struct usb_musb_priv *priv)
|
||||
static int usb_musb_chan_alloc(void)
|
||||
{
|
||||
int chidx;
|
||||
|
||||
/* Search the table of channels */
|
||||
|
||||
for (chidx = 2; chidx < CONFIG_USBHOST_CHANNELS; chidx++) {
|
||||
for (chidx = 2; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
|
||||
/* Is this channel available? */
|
||||
if (!priv->chan[chidx].inuse) {
|
||||
if (!g_usbhost.chan[chidx].inuse) {
|
||||
/* Yes... make it "in use" and return the index */
|
||||
|
||||
priv->chan[chidx].inuse = true;
|
||||
g_usbhost.chan[chidx].inuse = true;
|
||||
return chidx;
|
||||
}
|
||||
}
|
||||
@@ -277,30 +279,10 @@ static int usb_musb_chan_alloc(struct usb_musb_priv *priv)
|
||||
* Free a previoiusly allocated channel.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void usb_musb_chan_free(struct usb_musb_priv *priv, int chidx)
|
||||
static void usb_musb_chan_free(struct usb_musb_chan *chan)
|
||||
{
|
||||
/* Mark the channel available */
|
||||
priv->chan[chidx].inuse = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usb_synopsys_chan_freeall
|
||||
*
|
||||
* Description:
|
||||
* Free all channels.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void usb_musb_chan_freeall(struct usb_musb_priv *priv)
|
||||
{
|
||||
uint8_t chidx;
|
||||
|
||||
/* Free all host channels */
|
||||
|
||||
for (chidx = 2; chidx < CONFIG_USBHOST_CHANNELS; chidx++) {
|
||||
usb_musb_chan_free(priv, chidx);
|
||||
}
|
||||
chan->inuse = false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -318,8 +300,7 @@ static inline void usb_musb_chan_freeall(struct usb_musb_priv *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int usb_musb_chan_waitsetup(struct usb_musb_priv *priv,
|
||||
struct usb_musb_chan *chan)
|
||||
static int usb_musb_chan_waitsetup(struct usb_musb_chan *chan)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret = -ENODEV;
|
||||
@@ -328,7 +309,7 @@ static int usb_musb_chan_waitsetup(struct usb_musb_priv *priv,
|
||||
|
||||
/* Is the device still connected? */
|
||||
|
||||
if (priv->connected) {
|
||||
if (g_usbhost.connected) {
|
||||
/* Yes.. then set waiter to indicate that we expect to be informed
|
||||
* when either (1) the device is disconnected, or (2) the transfer
|
||||
* completed.
|
||||
@@ -363,9 +344,7 @@ static int usb_musb_chan_waitsetup(struct usb_musb_priv *priv,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBHOST_ASYNCH
|
||||
static int usb_musb_chan_asynchsetup(struct usb_musb_priv *priv,
|
||||
struct usb_musb_chan *chan,
|
||||
usbh_asynch_callback_t callback, void *arg)
|
||||
static int usb_musb_chan_asynchsetup(struct usb_musb_chan *chan, usbh_asynch_callback_t callback, void *arg)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret = -ENODEV;
|
||||
@@ -373,7 +352,7 @@ static int usb_musb_chan_asynchsetup(struct usb_musb_priv *priv,
|
||||
flags = usb_osal_enter_critical_section();
|
||||
/* Is the device still connected? */
|
||||
|
||||
if (priv->connected) {
|
||||
if (g_usbhost.connected) {
|
||||
/* Yes.. then set waiter to indicate that we expect to be informed
|
||||
* when either (1) the device is disconnected, or (2) the transfer
|
||||
* completed.
|
||||
@@ -403,7 +382,7 @@ static int usb_musb_chan_asynchsetup(struct usb_musb_priv *priv,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int usb_musb_chan_wait(struct usb_musb_priv *priv, struct usb_musb_chan *chan)
|
||||
static int usb_musb_chan_wait(struct usb_musb_chan *chan, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -414,7 +393,7 @@ static int usb_musb_chan_wait(struct usb_musb_priv *priv, struct usb_musb_chan *
|
||||
*/
|
||||
|
||||
if (chan->waiter) {
|
||||
ret = usb_osal_sem_take(chan->waitsem);
|
||||
ret = usb_osal_sem_take(chan->waitsem, timeout);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -422,7 +401,12 @@ static int usb_musb_chan_wait(struct usb_musb_priv *priv, struct usb_musb_chan *
|
||||
|
||||
/* The transfer is complete re-enable interrupts and return the result */
|
||||
ret = chan->result;
|
||||
return ret;
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return chan->xfrd;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -438,7 +422,7 @@ static int usb_musb_chan_wait(struct usb_musb_priv *priv, struct usb_musb_chan *
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void usb_musb_chan_wakeup(struct usb_musb_priv *priv, struct usb_musb_chan *chan)
|
||||
static void usb_musb_chan_wakeup(struct usb_musb_chan *chan)
|
||||
{
|
||||
usbh_asynch_callback_t callback;
|
||||
void *arg;
|
||||
@@ -496,13 +480,10 @@ __WEAK void usb_hc_low_level_init(void)
|
||||
int usb_hc_init(void)
|
||||
{
|
||||
g_usbhost.connected = 0;
|
||||
g_usbhost.pscwait = 0;
|
||||
g_usbhost.fifo_size_offset = 0;
|
||||
|
||||
usb_hc_low_level_init();
|
||||
|
||||
g_usbhost.exclsem = usb_osal_mutex_create();
|
||||
|
||||
USB->IE = USB_IE_RESET | USB_IE_CONN | USB_IE_DISCON |
|
||||
USB_IE_RESUME | USB_IE_SUSPND |
|
||||
USB_IE_BABBLE | USB_IE_SESREQ | USB_IE_VBUSERR;
|
||||
@@ -511,9 +492,18 @@ int usb_hc_init(void)
|
||||
USB->RXIE = 0;
|
||||
|
||||
USB->DEVCTL |= USB_DEVCTL_SESSION;
|
||||
|
||||
#ifdef USB_MUSB_SUNXI
|
||||
USB->CSRL0 = USB_CSRL0_TXRDY;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool usbh_get_port_connect_status(const uint8_t port)
|
||||
{
|
||||
return g_usbhost.connected;
|
||||
}
|
||||
|
||||
int usbh_reset_port(const uint8_t port)
|
||||
{
|
||||
USB->POWER |= USB_POWER_RESET;
|
||||
@@ -543,7 +533,8 @@ int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uin
|
||||
uint8_t ep0 = (uint8_t)ep;
|
||||
struct usb_musb_chan *chan;
|
||||
|
||||
ret = usb_osal_mutex_take(g_usbhost.exclsem);
|
||||
chan = &g_usbhost.chan[0];
|
||||
ret = usb_osal_mutex_take(chan->exclsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -562,7 +553,7 @@ int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uin
|
||||
chan = &g_usbhost.chan[ep0];
|
||||
chan->mps = ep_mps;
|
||||
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -584,18 +575,18 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
memset(chan, 0, sizeof(struct usb_musb_chan));
|
||||
|
||||
chan->waitsem = usb_osal_sem_create(0);
|
||||
|
||||
chan->exclsem = usb_osal_mutex_create();
|
||||
USBC_SelectActiveEp(0);
|
||||
|
||||
HWREGB(USB_TXINTERVALx_BASE) = 0;
|
||||
HWREGB(USB_TXHUBADDR_BASE(0)) = 0;
|
||||
HWREGB(USB_TXHUBPORT_BASE(0)) = 0;
|
||||
|
||||
USB->NAKLMT = 0;
|
||||
*ep = (usbh_epinfo_t)0;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
chidx = usb_musb_chan_alloc(&g_usbhost);
|
||||
chidx = usb_musb_chan_alloc();
|
||||
|
||||
chan = &g_usbhost.chan[chidx];
|
||||
memset(chan, 0, sizeof(struct usb_musb_chan));
|
||||
@@ -604,6 +595,7 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
chan->mps = ep_cfg->ep_mps;
|
||||
|
||||
chan->waitsem = usb_osal_sem_create(0);
|
||||
chan->exclsem = usb_osal_mutex_create();
|
||||
|
||||
USBC_SelectActiveEp(chidx);
|
||||
|
||||
@@ -689,8 +681,9 @@ int usbh_ep_alloc(usbh_epinfo_t *ep, const struct usbh_endpoint_cfg *ep_cfg)
|
||||
|
||||
int usbh_ep_free(usbh_epinfo_t ep)
|
||||
{
|
||||
usb_musb_chan_free(&g_usbhost, (int)ep);
|
||||
usb_musb_chan_free(&g_usbhost.chan[(int)ep]);
|
||||
usb_osal_sem_delete(g_usbhost.chan[(int)ep].waitsem);
|
||||
usb_osal_mutex_delete(g_usbhost.chan[(int)ep].exclsem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -700,17 +693,16 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
struct usb_musb_chan *chan;
|
||||
uint8_t ep0 = (uint8_t)ep;
|
||||
|
||||
ret = usb_osal_mutex_take(g_usbhost.exclsem);
|
||||
chan = &g_usbhost.chan[0];
|
||||
ret = usb_osal_mutex_take(chan->exclsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
chan = &g_usbhost.chan[0];
|
||||
|
||||
usb_musb_chan_waitsetup(&g_usbhost, chan);
|
||||
usb_musb_chan_waitsetup(chan);
|
||||
|
||||
usb_musb_write_packet(0, (uint8_t *)setup, 8);
|
||||
|
||||
chan->once_outlen = 8;
|
||||
if (setup->wLength && buffer) {
|
||||
if (setup->bmRequestType & 0x80) {
|
||||
usb_ep0_state = USB_EP0_STATE_IN_DATA;
|
||||
@@ -726,32 +718,31 @@ int usbh_control_transfer(usbh_epinfo_t ep, struct usb_setup_packet *setup, uint
|
||||
USBC_SelectActiveEp(0);
|
||||
USB->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_SETUP;
|
||||
|
||||
ret = usb_musb_chan_wait(&g_usbhost, chan);
|
||||
|
||||
ret = usb_musb_chan_wait(chan, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
return 0;
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
errout_with_mutex:
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct usb_musb_chan *chan;
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
|
||||
ret = usb_osal_mutex_take(g_usbhost.exclsem);
|
||||
chan = &g_usbhost.chan[chidx];
|
||||
ret = usb_osal_mutex_take(chan->exclsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
chan = &g_usbhost.chan[chidx];
|
||||
usb_musb_chan_waitsetup(&g_usbhost, chan);
|
||||
usb_musb_chan_waitsetup(chan);
|
||||
|
||||
if (chan->in) {
|
||||
chan->buffer = buffer;
|
||||
@@ -770,57 +761,94 @@ int usbh_ep_bulk_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
HWREGB(USB_TXCSRLx_BASE) = USB_TXCSRL1_TXRDY;
|
||||
chan->buffer += buflen;
|
||||
chan->buflen -= buflen;
|
||||
chan->xfrd += buflen;
|
||||
}
|
||||
ret = usb_musb_chan_wait(&g_usbhost, chan);
|
||||
ret = usb_musb_chan_wait(chan, timeout);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
|
||||
return buflen;
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
errout_with_mutex:
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen)
|
||||
int usbh_ep_intr_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct usb_musb_chan *chan;
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
|
||||
ret = usb_osal_mutex_take(g_usbhost.exclsem);
|
||||
chan = &g_usbhost.chan[chidx];
|
||||
ret = usb_osal_mutex_take(chan->exclsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
usb_musb_chan_waitsetup(chan);
|
||||
|
||||
if (chan->in) {
|
||||
chan->buffer = buffer;
|
||||
chan->buflen = buflen;
|
||||
USBC_SelectActiveEp(chidx);
|
||||
HWREGB(USB_RXCSRLx_BASE) = USB_RXCSRL1_REQPKT;
|
||||
} else {
|
||||
chan->buffer = buffer;
|
||||
chan->buflen = buflen;
|
||||
if (buflen > chan->mps) {
|
||||
buflen = chan->mps;
|
||||
}
|
||||
|
||||
usb_musb_write_packet(chidx, (uint8_t *)buffer, buflen);
|
||||
USBC_SelectActiveEp(chidx);
|
||||
HWREGB(USB_TXCSRLx_BASE) = USB_TXCSRL1_TXRDY;
|
||||
chan->buffer += buflen;
|
||||
chan->buflen -= buflen;
|
||||
chan->xfrd += buflen;
|
||||
}
|
||||
ret = usb_musb_chan_wait(chan, timeout);
|
||||
if (ret < 0) {
|
||||
goto errout_with_mutex;
|
||||
}
|
||||
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
errout_with_mutex:
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
struct usb_musb_chan *chan;
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
|
||||
ret = usb_osal_mutex_take(g_usbhost.exclsem);
|
||||
chan = &g_usbhost.chan[chidx];
|
||||
ret = usb_osal_mutex_take(chan->exclsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_ep_intr_async_transfer(usbh_epinfo_t ep, uint8_t *buffer, uint32_t buflen, usbh_asynch_callback_t callback, void *arg)
|
||||
{
|
||||
int ret;
|
||||
struct usb_musb_chan *chan;
|
||||
uint8_t chidx = (uint8_t)ep;
|
||||
|
||||
ret = usb_osal_mutex_take(g_usbhost.exclsem);
|
||||
chan = &g_usbhost.chan[chidx];
|
||||
ret = usb_osal_mutex_take(chan->exclsem);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_osal_mutex_give(g_usbhost.exclsem);
|
||||
|
||||
usb_osal_mutex_give(chan->exclsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -853,7 +881,7 @@ void handle_ep0(void)
|
||||
case USB_EP0_STATE_IN_DATA:
|
||||
USB->CSRL0 = USB_RXCSRL1_REQPKT;
|
||||
usb_ep0_state = USB_EP0_STATE_IN_DATA_C;
|
||||
|
||||
g_usbhost.chan[0].xfrd += g_usbhost.chan[0].once_outlen;
|
||||
break;
|
||||
case USB_EP0_STATE_IN_DATA_C:
|
||||
if (USB->CSRL0 & USB_CSRL0_RXRDY) {
|
||||
@@ -869,7 +897,7 @@ void handle_ep0(void)
|
||||
|
||||
g_usbhost.chan[0].buffer += size;
|
||||
g_usbhost.chan[0].buflen -= size;
|
||||
|
||||
g_usbhost.chan[0].xfrd += size;
|
||||
if ((size < g_usbhost.chan[0].mps) || (g_usbhost.chan[0].buflen == 0)) {
|
||||
usb_ep0_state = USB_EP0_STATE_IN_STATUS_C;
|
||||
USB->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_STATUS;
|
||||
@@ -891,11 +919,13 @@ void handle_ep0(void)
|
||||
case USB_EP0_STATE_IN_STATUS:
|
||||
USB->CSRL0 = USB_CSRL0_REQPKT | USB_CSRL0_STATUS;
|
||||
usb_ep0_state = USB_EP0_STATE_IN_STATUS_C;
|
||||
g_usbhost.chan[0].xfrd += g_usbhost.chan[0].once_outlen;
|
||||
break;
|
||||
|
||||
case USB_EP0_STATE_OUT_DATA: {
|
||||
uint32_t size = g_usbhost.chan[0].buflen;
|
||||
g_usbhost.chan[0].xfrd += g_usbhost.chan[0].once_outlen;
|
||||
|
||||
uint32_t size = g_usbhost.chan[0].buflen;
|
||||
if (size > g_usbhost.chan[0].mps) {
|
||||
size = g_usbhost.chan[0].mps;
|
||||
}
|
||||
@@ -904,7 +934,7 @@ void handle_ep0(void)
|
||||
|
||||
g_usbhost.chan[0].buffer += size;
|
||||
g_usbhost.chan[0].buflen -= size;
|
||||
|
||||
g_usbhost.chan[0].once_outlen = size;
|
||||
if (size == g_usbhost.chan[0].mps) {
|
||||
USB->CSRL0 = USB_CSRL0_TXRDY;
|
||||
} else {
|
||||
@@ -917,7 +947,7 @@ void handle_ep0(void)
|
||||
}
|
||||
return;
|
||||
chan_wait:
|
||||
usb_musb_chan_wakeup(&g_usbhost, &g_usbhost.chan[0]);
|
||||
usb_musb_chan_wakeup(&g_usbhost.chan[0]);
|
||||
}
|
||||
void USBH_IRQHandler(void)
|
||||
{
|
||||
@@ -934,19 +964,20 @@ void USBH_IRQHandler(void)
|
||||
rxis = USB->RXIS;
|
||||
|
||||
old_ep_idx = USBC_GetActiveEp();
|
||||
|
||||
if (is & USB_IS_CONN) {
|
||||
if (!g_usbhost.connected) {
|
||||
g_usbhost.connected = true;
|
||||
extern void usbh_event_notify_handler(uint8_t event, uint8_t rhport);
|
||||
usbh_event_notify_handler(USBH_EVENT_ATTACHED, 1);
|
||||
usbh_event_notify_handler(USBH_EVENT_CONNECTED, 1);
|
||||
}
|
||||
USB->IS = USB_IS_CONN;
|
||||
}
|
||||
|
||||
if (is & USB_IS_DISCON) {
|
||||
if (g_usbhost.connected) {
|
||||
g_usbhost.connected = false;
|
||||
|
||||
for (uint8_t chnum = 0; chnum < CONFIG_USBHOST_CHANNELS; chnum++) {
|
||||
for (uint8_t chnum = 0; chnum < CONFIG_USBHOST_PIPE_NUM; chnum++) {
|
||||
if (g_usbhost.chan[chnum].waiter) {
|
||||
/* Wake'em up! */
|
||||
g_usbhost.chan[chnum].waiter = false;
|
||||
@@ -954,12 +985,12 @@ void USBH_IRQHandler(void)
|
||||
}
|
||||
}
|
||||
|
||||
extern void usbh_event_notify_handler(uint8_t event, uint8_t rhport);
|
||||
usbh_event_notify_handler(USBH_EVENT_REMOVED, 1);
|
||||
usbh_event_notify_handler(USBH_EVENT_DISCONNECTED, 1);
|
||||
}
|
||||
USB->IS = USB_IS_DISCON;
|
||||
}
|
||||
|
||||
if (is & USB_IS_SOF) {
|
||||
USB->IS = USB_IS_SOF;
|
||||
}
|
||||
|
||||
txis &= USB->TXIE;
|
||||
@@ -986,11 +1017,11 @@ void USBH_IRQHandler(void)
|
||||
if (ep_status & USB_HOST_OUT_STALL) {
|
||||
chan->result = -EPERM;
|
||||
usb_musb_ep_status_clear(chidx, USB_HOST_OUT_STALL);
|
||||
usb_musb_chan_wakeup(&g_usbhost, chan);
|
||||
usb_musb_chan_wakeup(chan);
|
||||
} else if (ep_status & USB_HOST_OUT_ERROR) {
|
||||
chan->result = -EIO;
|
||||
usb_musb_ep_status_clear(chidx, USB_HOST_OUT_ERROR);
|
||||
usb_musb_chan_wakeup(&g_usbhost, chan);
|
||||
usb_musb_chan_wakeup(chan);
|
||||
} else {
|
||||
uint32_t size = chan->buflen;
|
||||
|
||||
@@ -1002,10 +1033,10 @@ void USBH_IRQHandler(void)
|
||||
HWREGB(USB_TXCSRLx_BASE) = USB_TXCSRL1_TXRDY;
|
||||
chan->buffer += size;
|
||||
chan->buflen -= size;
|
||||
|
||||
chan->xfrd += size;
|
||||
} else {
|
||||
chan->result = 0;
|
||||
usb_musb_chan_wakeup(&g_usbhost, chan);
|
||||
usb_musb_chan_wakeup(chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1022,11 +1053,13 @@ void USBH_IRQHandler(void)
|
||||
ep_status = HWREGB(USB_RXCSRLx_BASE);
|
||||
|
||||
if (ep_status & USB_HOST_IN_STALL) {
|
||||
chan->result = -EPERM;
|
||||
usb_musb_ep_status_clear(chidx, USB_HOST_IN_STALL);
|
||||
usb_musb_chan_wakeup(&g_usbhost, chan);
|
||||
usb_musb_chan_wakeup(chan);
|
||||
} else if (ep_status & USB_HOST_IN_ERROR) {
|
||||
chan->result = -EIO;
|
||||
usb_musb_ep_status_clear(chidx, USB_HOST_IN_ERROR);
|
||||
usb_musb_chan_wakeup(&g_usbhost, chan);
|
||||
usb_musb_chan_wakeup(chan);
|
||||
} else if (ep_status & USB_RXCSRL1_RXRDY) {
|
||||
uint32_t size = chan->buflen;
|
||||
if (size > chan->mps) {
|
||||
@@ -1038,10 +1071,10 @@ void USBH_IRQHandler(void)
|
||||
HWREGB(USB_RXCSRLx_BASE) &= ~USB_RXCSRL1_RXRDY;
|
||||
chan->buffer += size;
|
||||
chan->buflen -= size;
|
||||
|
||||
if (chan->buflen == 0) {
|
||||
chan->xfrd += size;
|
||||
if ((size < chan->mps) || (chan->buflen == 0)) {
|
||||
chan->result = 0;
|
||||
usb_musb_chan_wakeup(&g_usbhost, chan);
|
||||
usb_musb_chan_wakeup(chan);
|
||||
} else {
|
||||
HWREGB(USB_RXCSRLx_BASE) = USB_RXCSRL1_REQPKT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user