📄 usbdl_usb.c
字号:
break;
case USB_CMD_CONFIG:
byConfig = (kal_uint8)(pcmd->wValue & 0x00FF);
if (byConfig >= gUsbDevice.devdscr.bNumConfigurations)
{
bError = KAL_TRUE;
}
else
{
/* Get pointer to request configuration descriptor */
pcfg = (Usb_Cfg_Dscr*)gUsbDevice.conf;
/* Prepare to return Configuration Descriptors */
USB_Generate_EP0Data(pep0state, pcmd, pcfg, pcfg->wTotalLength);
}
break;
case USB_CMD_STRING:
bystr = (kal_uint8)(pcmd->wValue & 0x00FF);
if (bystr >= gUsbDevice.resource_string_number)
{
bError = KAL_TRUE;
}
else
{
/* Get pointer to requested string descriptor */
USB_Generate_EP0Data(pep0state, pcmd, (void *)gUsbDevice.resource_string[bystr],
(*(kal_uint8 *)gUsbDevice.resource_string[bystr]));
}
break;
default:
bError = KAL_TRUE;
break;
}
}
return bError;
}
/* Parse command Set Configuration */
static kal_bool USB_Cmd_SetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
kal_bool bError = KAL_FALSE;
kal_uint8 byConfig;
byConfig = (kal_uint8)(pcmd->wValue & 0x00FF);
if (gUsbDevice.nDevState == DEVSTATE_DEFAULT)
{
bError = KAL_TRUE;
}
/* Assumes configurations are numbered from 1 to NumConfigurations */
else
{
if (byConfig > gUsbDevice.devdscr.bNumConfigurations)
{
bError = KAL_TRUE;
}
else if (byConfig == 0)
{
gUsbDevice.nDevState = DEVSTATE_ADDRESS;
gUsbDevice.config_num = 0;
}
else
{
gUsbDevice.nDevState = DEVSTATE_CONFIG;
// gUsbDevice.is_configured_now = KAL_TRUE;
gUsbDevice.config_num = byConfig;
}
}
return bError;
}
/* parse command Get Configuration */
static kal_bool USB_Cmd_GetConfiguration(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
kal_bool bError = KAL_FALSE;
if( (gUsbDevice.nDevState == DEVSTATE_ADDRESS) && (!pcmd->wValue))
{
/* Prepare to return zero */
USB_Generate_EP0Data(pep0state, pcmd, &pcmd->wValue, 1);
}
else if( gUsbDevice.nDevState == DEVSTATE_CONFIG)
{
/* Prepare to return configuration value */
//pcfg = (Usb_Cfg_Dscr *)gUsbDevice.pCurCfg;
//USB_Generate_EP0Data(pep0state, pcmd, &pcfg->bConfigurationValue, 1);
USB_Generate_EP0Data(pep0state, pcmd, &gUsbDevice.config_num, 1);
}
else
{
bError = KAL_TRUE;
}
return bError;
}
/* parse command Set Interface */
static kal_bool USB_Cmd_SetInterface(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
kal_bool bError = KAL_FALSE;
gUsbDevice.interface_num = (pcmd->wValue&0x00FF);
return bError;
}
/* parse command Get Interface */
static kal_bool USB_Cmd_GetInterface(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
kal_bool bError = KAL_FALSE;
USB_Generate_EP0Data(pep0state, pcmd, &gUsbDevice.interface_num, 1);
return bError;
}
/* parse command Set/Clear Feature */
/* bset true means command SET_FETURE, false means command CLEAR_FEATURE */
static kal_bool USB_Cmd_SetFeature(Usb_Command *pcmd, kal_bool bset)
{
kal_bool bError = KAL_FALSE;
switch (pcmd->bmRequestType)
{
/* device */
case USB_CMD_STDDEVOUT:
switch (pcmd->wValue)
{
case USB_FTR_DEVREMWAKE:
gUsbDevice.remoteWk = bset;
break;
default:
bError = KAL_TRUE;
break;
}
break;
/* endpoint */
case USB_CMD_STDEPOUT:
switch (pcmd->wValue)
{
case USB_FTR_EPHALT:
if (pcmd->wIndex == 0)
{
/* endpoint 0 */
}
else
{
/* command EP direction zero indicate OUT EP */
if(pcmd->wIndex & 0x80)
{
/* In EP*/
if((pcmd->wIndex& 0x0f) > MAX_INTR_EP_NUM)
{
bError = KAL_TRUE;
}
else
{
USB_CtrlEPStall((pcmd->wIndex& 0x0f), USB_TX_EP_TYPE, bset, USB_CTRL_STALL_ENTRY_1);
}
}
else
{
/* Out EP*/
if((pcmd->wIndex& 0x0f) > MAX_INTR_EP_NUM)
{
bError = KAL_TRUE;
}
else
{
USB_CtrlEPStall((pcmd->wIndex& 0x0f), USB_RX_EP_TYPE, bset, USB_CTRL_STALL_ENTRY_1);
}
}
}
break;
default:
bError = KAL_TRUE;
break;
}
break;
case USB_CMD_STDIFOUT:
default:
bError = KAL_TRUE;
break;
}
return bError;
}
/* parse command Get Status */
static kal_bool USB_Cmd_GetStatus(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
kal_bool bError = KAL_FALSE;
static kal_uint16 status = 0;
switch (pcmd->bmRequestType)
{
case USB_CMD_STDDEVIN:
status = (kal_uint16)((gUsbDevice.remoteWk<<1)|(gUsbDevice.self_powered));
USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
break;
case USB_CMD_STDIFIN:
USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
break;
case USB_CMD_STDEPIN:
if(pcmd->wIndex & 0x80)
{
/* In EP*/
status = (kal_uint16)USB_Get_EP_Stall_Status((pcmd->wIndex & 0x000f), USB_TX_EP_TYPE);
}
else
{
/* Out EP*/
status = (kal_uint16)USB_Get_EP_Stall_Status((pcmd->wIndex & 0x000f), USB_RX_EP_TYPE);
}
USB_Generate_EP0Data( pep0state, pcmd, &status, 2);
break;
default:
bError = KAL_TRUE;
break;
}
return bError;
}
static void USB_Stdcmd(Usb_Ep0_Status *pep0state, Usb_Command *pcmd)
{
kal_bool bError = KAL_FALSE;
switch (pcmd->bRequest)
{
case USB_SET_ADDRESS:
USB_Dbg_Trace(USB_EP0_SET_ADDRESS, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_SetAddress(pep0state, pcmd);
break;
case USB_GET_DESCRIPTOR:
USB_Dbg_Trace(USB_EP0_GET_DESCRIPTOR, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_GetDescriptor(pep0state, pcmd);
break;
case USB_SET_CONFIGURATION:
USB_Dbg_Trace(USB_EP0_SET_CONFIGURATION, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_SetConfiguration(pep0state, pcmd);
break;
case USB_SET_INTERFACE:
USB_Dbg_Trace(USB_EP0_SET_INTERFACE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_SetInterface(pep0state, pcmd);
break;
case USB_GET_CONFIGURATION:
USB_Dbg_Trace(USB_EP0_GET_CONFIGURATION, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_GetConfiguration(pep0state, pcmd);
break;
case USB_GET_INTERFACE:
USB_Dbg_Trace(USB_EP0_GET_INTERFACE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_GetInterface(pep0state, pcmd);
break;
case USB_SET_FEATURE:
USB_Dbg_Trace(USB_EP0_SET_FEATURE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_SetFeature(pcmd, KAL_TRUE);
break;
case USB_CLEAR_FEATURE:
USB_Dbg_Trace(USB_EP0_CLEAR_FEATURE, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_SetFeature(pcmd, KAL_FALSE);
break;
case USB_GET_STATUS:
USB_Dbg_Trace(USB_EP0_GET_STATUS, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = USB_Cmd_GetStatus(pep0state, pcmd);
break;
/* Stall the command if an unrecognized request is received */
case USB_SYNCH_FRAME: /*Only support for Isoc traffic*/
case USB_SET_DESCRIPTOR:
default:
USB_Dbg_Trace(USB_EP0_CMD_ERROR, drv_get_current_time(), pcmd->wValue, pcmd->wIndex);
bError = KAL_TRUE;
// ASSERT(0);
break;
}
if (gUsbDevice.ep0_state == USB_EP0_IDLE) /* no data to transmit */
{
gUsbDevice.ep0_state = USB_EP0_RX_STATUS;
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_TRUE);
/*
if((gUsbDevice.ep0_class_cmd_handler.b_enable == KAL_TRUE) &&
(gUsbDevice.ep0_class_cmd_handler.cmd == pcmd->bRequest) )
{
gUsbDevice.ep0_class_cmd_handler.ep0_cmd_hdlr(pcmd);
}
*/
}
else
{
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, bError, KAL_FALSE);
}
}
/* parse EP0 requested command */
static void USB_Endpoint0_Idle (void)
{
/* read ep0 data*/
USB_EPFIFORead(0, 8, &gUsbDevice.cmd);
/* Check request type */
switch (gUsbDevice.cmd.bmRequestType & USB_CMD_TYPEMASK)
{
case USB_CMD_STDREQ:
/* standard request */
USB_Stdcmd(&gUsbDevice.ep0info, &gUsbDevice.cmd);
break;
case USB_CMD_CLASSREQ:
/* class specific request */
if((gUsbDevice.cmd.bmRequestType == USB_CMD_CLASSIFIN) || (gUsbDevice.cmd.bmRequestType == USB_CMD_CLASSIFOUT))
{
if(gUsbDevice.if_info[(gUsbDevice.cmd.wIndex & 0xff)].if_class_specific_hdlr != NULL)
{
gUsbDevice.if_info[(gUsbDevice.cmd.wIndex & 0xff)].if_class_specific_hdlr(&gUsbDevice.ep0info, &gUsbDevice.cmd);
}
else
{
/* error occur, stall endpoint*/
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
}
}
else
{
/* error occur, stall endpoint*/
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
}
break;
case USB_CMD_VENDREQ:
default:
/* Stall the command if a reserved request is received */
USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
break;
}
}
/* EP0 RX handler, called when EP0 interrupt happened and in RX state */
static void USB_Endpoint0_Rx(void)
{
if (gUsbDevice.ep0_rx_handler != NULL)
{
/* called rx handler to get data*/
gUsbDevice.ep0_rx_handler(&gUsbDevice.ep0info);
}
else
{
/* this should not happened, user should register rx handler when set EP0 into RX state */
/* error occur, stall endpoint*/
ASSERT(0);
// USB_Update_EP0_State(USB_EP0_DRV_STATE_READ_END, KAL_TRUE, KAL_FALSE);
}
}
/* EP0 TX handler, called when EP0 interrupt happened and in TX state,
or EP0 just translate from IDLE to TX state */
static void USB_Endpoint0_Tx(void)
{
kal_int32 nBytes;
/* Determine number of bytes to send */
if (gUsbDevice.ep0info.nBytesLeft <= USB_EP0_MAXP)
{
nBytes = gUsbDevice.ep0info.nBytesLeft;
gUsbDevice.ep0info.nBytesLeft = 0;
}
else
{
nBytes = USB_EP0_MAXP;
gUsbDevice.ep0info.nBytesLeft -= USB_EP0_MAXP;
}
/* send out data */
USB_EPFIFOWrite (0, nBytes, gUsbDevice.ep0info.pData);
/* update data pointer and prepare for next transaction */
gUsbDevice.ep0info.pData = (kal_uint8 *)gUsbDevice.ep0info.pData + nBytes;
if (nBytes < USB_EP0_MAXP)
{
gUsbDevice.ep0_state = USB_EP0_IDLE;
/* last data, set end as true*/
USB_Update_EP0_State(USB_EP0_DRV_STATE_WRITE_RDY, KAL_FALSE, KAL_TRUE);
}
else
{
USB_Update_EP0_State(USB_EP0_DRV_STATE_WRITE_RDY, KAL_FALSE, KAL_FALSE);
}
}
/* EP0 interrupt handler called by USB_HISR */
static void USB_Endpoint0_Hdlr(void)
{
kal_bool b_transaction_end;
kal_bool b_sent_stall;
kal_uint32 nCount;
USB_Get_EP0_Status(&b_transaction_end, &b_sent_stall);
/* Check for SentStall */
/* SentStall && SetupEnd are impossible to occur together*/
if (b_sent_stall == KAL_TRUE)
{
USB_Update_EP0_State(USB_EP0_DRV_STATE_CLEAR_SENT_STALL, KAL_FALSE, KAL_FALSE);
gUsbDevice.ep0_state = USB_EP0_IDLE;
}
/* Check for SetupEnd */
if (b_transaction_end == KAL_TRUE)
{
USB_Update_EP0_State(USB_EP0_DRV_STATE_TRANSACTION_END, KAL_FALSE, KAL_FALSE);
gUsbDevice.ep0_state = USB_EP0_IDLE;
}
/* Call relevant routines for endpoint 0 state */
if (gUsbDevice.ep0_state == USB_EP0_IDLE)
{
/* receive command request */
nCount = USB_EP0_Pkt_Len();
if (nCount > 0)
{
/* idle state handler */
USB_Endpoint0_Idle();
}
}
else if (gUsbDevice.ep0_state == USB_EP0_RX)
{
/* Rx state handler */
USB_Endpoint0_Rx();
}
else if (gUsbDevice.ep0_state == USB_EP0_RX_STATUS)
{
/* Data stage is RX, status stage is TX*/
if(gUsbDevice.nDevState == DEVSTATE_SET_ADDRESS)
{
USB_SetAddress(gUsbDevice.ep0info.byFAddr, USB_SET_ADDR_STATUS);
gUsbDevice.nDevState = DEVSTATE_ADDRESS;
}
gUsbDevice.ep0_state = USB_EP0_IDLE;
/* In case next setup followed the previous status very fast and interrupt only happens once*/
/* receive command request */
nCount = USB_EP0_Pkt_Len();
if (nCount > 0)
{
/* idle state handler */
USB_Endpoint0_Idle();
}
}
/* must use if, not else if, EP0 may enter TX state in previous IDLE state handler */
if (gUsbDevice.ep0_state == USB_EP0_TX)
{
/* Tx state handler */
USB_Endpoint0_Tx();
}
}
#endif /* __USB_DOWNLOAD__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -