📄 drv_usb.c
字号:
/** @brief Controls the different operations that can be performed by USBF
*
* This API is used to carry out the different operations performed by USBF.
* Refer to @a CSL_UsbfHwControlCmd for various operations that can be performed.
*
* <b> Usage Constraints: </b>
* Both @a CSL_usbfInit() and @a CSL_usbfOpen() must be called successfully
* in that order before @a CSL_usbfHwControl() can be called. For the
* argument type that can be @a void* casted & passed with a particular command
* refer to @a CSL_UsbfHwControlCmd
*
* @b Example:
* @verbatim
CSL_UsbfHandle hUsbf;
CSL_Status status;
CSL_UsbfSharedPer timer1 = CSL_USBF_SHAREDPER_GPTIMER1 ;
...
status = CSL_usbfHwControl(hUsbf,
CSL_USBF_CMD_ACQUIRE,
&timer1);
@endverbatim
*
* @return Returns the status of the operation
*
*/
CSL_Status CSL_usbfHwControl(
/** Pointer to the object that holds reference to the
* instance of SSw requested after the open call */
CSL_UsbfHandle hUsbf,
/** The command that indicates the operation to be performed */
CSL_UsbfHwControlCmd cmd,
/** Command argument: Type casted to type mentioned in @a CSL_UsbfHwControlCmd enumeration */
void *cmdArg
)
{
CSL_Status status = CSL_SOK;
if(hUsbf == NULL)
return CSL_ESYS_BADHANDLE;
switch(cmd)
{
/* Start DMA transfer */
case CSL_USBF_CMD_START_DMA_TRANSFER:
CSL_usbfStartDmaTransfer (hUsbf, *(CSL_UsbfDmaNum *)cmdArg );
break ;
/* Initiate the remote wake-up sequence */
case CSL_USBF_CMD_INIT_REMOTE_WAKEUP:
CSL_usbfInitRemoteWakeup(hUsbf);
break ;
/* Stall current USB command */
case CSL_USBF_CMD_STALL_USB_CMD:
CSL_usbfStallUsbCmd(hUsbf);
break ;
/* Inform the command decode that the device becomes moves to configured state */
case CSL_USBF_CMD_INFORM_DEVICE_CFG_DONE:
CSL_usbfInformDeviceCfgDone(hUsbf);
break ;
/* Inform the command decode that the device becomes deconfigured */
case CSL_USBF_CMD_INFORM_DEVICE_CFG_CLEARED:
CSL_usbfInformDeviceCfgCleared(hUsbf);
break ;
/* Clear halt condition */
case CSL_USBF_CMD_CLEAR_HALT:
CSL_usbfClearHalt(hUsbf);
break ;
/* Halt endpoint */
case CSL_USBF_CMD_HALT_EP:
CSL_usbfHaltEp(hUsbf);
break ;
/* Clear endpoint */
case CSL_USBF_CMD_CLEAR_EP:
CSL_FINS(hUsbf->regs->CTRL, USBF_CTRL_CLR_EP, 1 );
break ;
/* Reset endpoint */
case CSL_USBF_CMD_RESET_EP:
CSL_usbfResetEp(hUsbf);
break ;
/* Enable FIFO; Applies only for non-ISO endpoints*/
case CSL_USBF_CMD_ENABLE_FIFO:
CSL_usbfEnableFifo(hUsbf);
break ;
/* Connect the device to USB bus */
case CSL_USBF_CMD_CONNECT_DEVICE:
CSL_usbfConnectDevice(hUsbf);
break ;
/* Disconnect the device from USB bus */
case CSL_USBF_CMD_DISCONNECT_DEVICE:
CSL_FINS(hUsbf->regs->SYSCON1, USBF_SYSCON1_PULLUP_EN, 0 );
break ;
/* Clear interrupt source */
case CSL_USBF_CMD_CLEAR_INTERRUPT:
CSL_usbfClearInterrupt(hUsbf, *(INT16U *)cmdArg);
break ;
/* Enable interrupt */
case CSL_USBF_CMD_ENABLE_INTERRUPT:
CSL_usbfEnableInterrupt(hUsbf, *(INT16U *)cmdArg);
break ;
/* Disable interrupt */
case CSL_USBF_CMD_DISABLE_INTERRUPT:
CSL_usbfDisableInterrupt(hUsbf, (*(INT16U *)cmdArg));
break ;
/* Enable DMA interrupt */
case CSL_USBF_CMD_ENABLE_DMA_INTERRUPT:
CSL_usbfEnableDmaInterrupt(hUsbf, *(INT16U *)cmdArg);
break ;
/* Disable DMA interrupt */
case CSL_USBF_CMD_DISABLE_DMA_INTERRUPT:
CSL_usbfDisableDmaInterrupt(hUsbf, (*(INT16U *)cmdArg));
break ;
/* Write from application buffer to endpoint FIFO */
case CSL_USBF_CMD_WRITE_FIFO:
CSL_usbfWriteFifo(hUsbf, (CSL_UsbfRxTxFifo *)cmdArg );
break ;
/* Read from endpoint FIFO into application buffer*/
case CSL_USBF_CMD_READ_FIFO:
CSL_usbfReadFifo(hUsbf, (CSL_UsbfRxTxFifo *)cmdArg );
break ;
/** Select an endpoint */
case CSL_USBF_CMD_SELECT_EP:
CSL_usbfSelectEp (hUsbf, *(INT8U *)cmdArg);
break;
/* Deselect an endpoint */
case CSL_USBF_CMD_DESELECT_EP:
CSL_usbfDeselectEp(hUsbf);
break;
/* Read setup data */
case CSL_USBF_CMD_READ_SETUP:
CSL_usbfReadSetup (hUsbf, (CSL_UsbfSetupPacket *)cmdArg);
break;
/* Unknown command type */
default:
status = CSL_ESYS_INVCMD;
}
return status ;
}
/** ============================================================================
* @n@b send
*
* @b Description
* @n Function to send the data to the host
*
* =============================================================================
*/
INT16U usbsend( INT8U endpt_num, INT8U * data, INT32U length )
{
INT8U * src = data;
CSL_UsbfRxTxFifo TxFifo;
/* Setup USB to transmit data on Endpoint [endpt_num] */
hUsbf->regs->EPNUM = 0x10 | endpt_num;
TxFifo.data = src;
TxFifo.length = length;
/* transmitt data through the FIFO*/
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_WRITE_FIFO,&TxFifo))
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_CMD_WRITE_FIFO:cmd failed \r\n"));
}
return (TxFifo.length);
}
/** ============================================================================
* @n@b receive
*
* @b Description
* @n Function to Receive incoming data from Host
*
* =============================================================================
*/
INT16U receive( INT8U endpt_num, INT8U* data, INT32U max_length )
{
CSL_UsbfRxTxFifo RxFifo;
PARAMETER_NOT_USED(endpt_num);
RxFifo.data = data;
RxFifo.length = max_length;
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_READ_FIFO,&RxFifo))
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_CMD_WRITE_FIFO:cmd failed \r\n"));
}
return (RxFifo.length);
}
/** ============================================================================
* @n@b ack
*
* @b Description
* @n Function to Respond with an ACK
*
* =============================================================================
*/
void ack( INT8U endpt_num, INT8U direction )
{
INT8U epNum;
epNum = ( direction == USB_DIR_OUT ) ?
0x10 | endpt_num : 0x00 | endpt_num;
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_SELECT_EP,&epNum))
{
OS_DEBUGF(DEV_USB,(" ack:CSL_USBF_CMD_SELECT_EP:cmd failed \r\n"));
}
/* Clear Endpoint */
hUsbf->regs->CTRL = 0x0002;
/* Enable FIFO for Communication Transfers */
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_ENABLE_FIFO,NULL))
{
OS_DEBUGF(DEV_USB,("ack: CSL_USBF_CMD_ENABLE_FIFO:cmd failed \r\n"));
}
/* Remove FIFO Access */
hUsbf->regs->EPNUM = ( direction == USB_DIR_OUT ) ?
0x10 | endpt_num : 0x00 | endpt_num;
}
/** ============================================================================
* @n@b stall
*
* @b Description
* @n Function to send the STALL signal for unsupported request
*
* =============================================================================
*/
void stall( INT8U direction )
{
/* Set access for USB Channel to Host */
hUsbf->regs->EPNUM = ( direction == USB_DIR_IN ) ? 0x30 : 0x20;
/* Stall */
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_STALL_USB_CMD,NULL))
{
OS_DEBUGF(DEV_USB,("stall: CSL_USBF_CMD_STALL_USB_CMD:cmd failed \r\n"));
}
/* Clear Control Halt */
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_CLEAR_HALT,NULL))
{
OS_DEBUGF(DEV_USB,(" stall:CSL_USBF_CMD_CLEAR_HALT:cmd failed \r\n"));
}
/* Remove access to Endpt FIFO */
hUsbf->regs->EPNUM = ( direction == USB_DIR_IN ) ? 0x10 : 0;
}
void processEP0( INT8U endpt_num, INT8U endpt_dir )
{
INT16U length;
CSL_BitMask16 irq_Src;
if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,CSL_USBF_QUERY_IRQ_SRC,&irq_Src))
{
OS_DEBUGF(DEV_USB,(" PEp0:CSL_USBF_QUERY_IRQ_SRC:cmd failed \r\n"));
}
if ( endpt_dir == USB_DIR_OUT )
{
/* Check if a new USB Setup Packet has arrived */
if ( irq_Src & CSL_USBF_IRQ_SRC_SETUP )
{
processSetup( );
OS_DEBUGF(DEV_USB,("processEP0: CSL_USBF_IRQ_SRC_SETUP \r\n"));
}
/* If not new Setup Packet, send ACK */
else
{
ack( 0, USB_DIR_OUT );
OS_DEBUGF(DEV_USB,("processEP0: ack \r\n"));
}
}
else /* endpt_dir == IN */
{
/* Write non-ISO Data still queued in TX buffer */
if ( ( ep0_post_send ) && ( ep0_send_len ) )
{
/* Send next chunk of data, up to 64 bytes */
length = usbsend( endpt_num, ep0_send_ptr, ep0_send_len );
ep0_send_ptr += length;
ep0_send_len -= length;
}
/* NO Data send, return ACK */
else
{
ep0_post_send = 0;
ack( endpt_num, USB_DIR_IN );
}
}
}
void processEP3(INT8U endpoint, INT8U direction )
{
INT8U buf[20];
ep3_num++;
sprintf(buf,"test ok (%d)\r\n",ep3_num);
usbsend( endpoint, buf, sizeof(buf) );
OS_DEBUGF(DEV_USB,("processEP3: stall\r\n"));
}
void processEP4(INT8U endpoint, INT8U direction )
{
INT16U receiveLength;
INT8U buf[40];
INT8U i;
receiveLength = receive( endpoint, buf, 40 );
OS_DEBUGF(DEV_USB,("processEP4: %d ",receiveLength));
for(i=0;i<receiveLength;i++)OS_DEBUGF(DEV_USB,("%02x ",buf[i]));
OS_DEBUGF(DEV_USB,("\r\n"));
dLed_toggle(LED2);
}
/** ============================================================================
* @n@b processSetup
*
* @b Description
* @n Function to service all the ep0 requests
*
* =============================================================================
*/
void processSetup(void)
{
INT16U devStatus;
INT16U epStatus;
INT16U send_len;
/* Different Reponse types - 8/16/+ bits */
INT8U response8;
INT8U response16;
Bool selfPwr;
INT16S i;
/* Variables for Setup Packet */
INT8U request_type = 0 ;
INT8U request = 0 ;
INT16U value = 0 ;
INT16U length = 0 ;
CSL_BitMask16 irq_Src = 0;
CSL_UsbfSetupPacket setup_Packet;
if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,CSL_USBF_QUERY_IRQ_SRC,&irq_Src))
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_IRQ_SRC:cmd failed \r\n"));
}
/* Parse Setup Packet */
/* Verify that there is no other setup packet by establishing a loop */
for ( ; irq_Src & CSL_USBF_IRQ_SRC_SETUP ; )
{
/* Set to read the SETUP-FIFO only available through endpoint 0 */
/* Set FIFO enable */
if (CSL_SOK != CSL_usbfHwControl(hUsbf,CSL_USBF_CMD_READ_SETUP,&setup_Packet))
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_CMD_READ_SETUP:cmd failed \r\n"));
}
request_type = setup_Packet.bmRequestType ;
value = setup_Packet.wValue ;
length = setup_Packet.wLength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -