📄 drv_usb.c
字号:
request = setup_Packet.bRequest;
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"));
}
}
/* Assume that the request is valid - and is to USB SPEC v1.1 */
/* Perform any Requests */
OS_DEBUGF(DEV_USB,(" request %2x \r\n",request));
switch ( request )
{
/* ======== USB_GET_STATUS ======== */
case USB_GET_STATUS:
switch ( request_type & 0x3 )
{
case 0:
/* Get Status for DEVICE */
if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,CSL_USBF_QUERY_DEVICE_STATUS,&devStatus))
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_DEVICE_STATUS:cmd failed \r\n"));
}
selfPwr = (Bool)(CSL_FEXT(hUsbf->regs->SYSCON1, USBF_SYSCON1_SELF_PWR));
response16 = ( ( devStatus & 0x40 ) >> 5 )
| ( selfPwr );
break;
case 1:
/* Get Status for INTERFACE */
response16 = 0;
break;
case 2:
/* Get Status for ENDPOINT */
if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,\
CSL_USBF_QUERY_NONISO_EP_STATUS,&epStatus));
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_NONISO_EP_STATUS:cmd failed \n"));
}
response16 = ( epStatus & \
CSL_USBF_NONISO_EP_STATUS_EP_HALTED ) >> 6;
break;
default:
stall( USB_DIR_IN ); /* Request ERROR */
return;
}
usbsend( 0, ( INT8U* )&response16, 2 );
break;
/* ======== USB_GET_DESCRIPTOR ======== */
/* Determine which Descriptor to send */
/* Action defined in USB Spec v1.1 */
case USB_GET_DESCRIPTOR:
switch ( ( value & 0xff00 ) >> 8 )
{
/* -------- Device Descriptor -------- */
case USB_DEVICE_DESC:
/* Standard Device Descriptor */
if ( length == 18 )
usbsend( 0, dev_desc, 18 );
/* Dummy Device Descriptor - for Windows Compatiablity
* here length = 64 */
else
usbsend( 0, dev_desc, 64 );
break;
/* -------- Config Descriptor -------- */
/* Configuration Tree
* |--> Config Desc.
* |--> Interface1 Desc.
* |--> Endpt1 Desc.
* |--> Endpt2 Desc.
* |--> Interface2 Desc. :Optional Interfaces & Endpts
* |--> Endpt3 Desc.
* |--> Endpt4 Desc.
*/
case USB_CONFIG_DESC:
/* Standard Interface Descriptor - */
if ( length == 9 )
usbsend( 0, cfg_desc, 9 );
/* Expanded Interface Descriptor: Return Configuration Tree
* that corresponds to the order above
* here length >= Size of Config Tree */
else if ( length >= cfg_desc_size )
{
send_len = usbsend( 0, cfg_desc, cfg_desc_size );
ep0_send_ptr = cfg_desc + send_len;
ep0_send_len = cfg_desc_size - send_len;
ep0_post_send = 1;
}
break;
/* -------- String Descriptor -------- */
case USB_STRING_DESC:
value &= 0x00FF;
/* Lookup in the internal String Descriptor table using
* "value" as the search key */
for ( i = 0 ; i < USB_STRING_INDEX_MAX ; i++ )
if ( string_desc_tbl[i].index == value )
break;
/* If NO String Desc. found -
* Send Request Error = Stall Command */
if ( i == USB_STRING_INDEX_MAX )
stall( USB_DIR_IN );
/* Else send String Desc. */
else
{
send_len = usbsend( 0, string_desc_tbl[i].ptr, length );
ep0_send_ptr = string_desc_tbl[i].ptr + send_len;
ep0_send_len = length - send_len;
ep0_post_send = 1;
}
break;
}
break;
/* ======== USB_GET_CONFIGURATION ======== */
case USB_GET_CONFIGURATION:
if (CSL_SOK != CSL_usbfGetHwStatus(hUsbf,\
CSL_USBF_QUERY_DEVICE_STATUS,&devStatus))
{
OS_DEBUGF(DEV_USB,(" CSL_USBF_QUERY_DEVICE_STATUS:cmd failed \n"));
}
/* [ 1 = Device configured ; 0 = NOT configured ] */
response8 = ( devStatus & CSL_USBF_DEVICE_STATUS_CONFIGURED ) ? 0x01 : 0x00;
usbsend( 0, &response8, 1 );
break;
/* ======== USB_SET_CONFIGURATION ======== */
/* Check: does HOST wants to clear or set configuration?
* value = [ 1: Set Config ; 0: Clear Config ] */
case USB_SET_CONFIGURATION:
hUsbf->regs->SYSCON2 = ( value ) ? 0x8 : 0x4;
/* Respond with a zero-length data pkt - ACK */
usbsend( 0, NULL, 0 );
test_result = 1;
break;
/* ======== USB_GET_INTERFACE ======== */
/* Respond with number of interfaces, currently 1 interface
* { interface[0] }, therefore respond by send N-1 = 0 */
case USB_GET_INTERFACE:
response8 = 0;
usbsend( 0, &response8, 1 );
break;
/* ======== USB_MASS_STORAGE_RESET ======== */
/* Respond with no data */
case USB_MASS_STORAGE_RESET:
usbsend( 0, NULL, 0 );
break;
/* ======== USB_GET_MAX_LUN ======== */
/* Respond by return N - 1 logical units */
case USB_GET_MAX_LUN:
response8 = 0;
usbsend( 0, &response8, 1 );
break;
/* ======== default ======== */
/* Request Error: use a USB Stall to indicate an Error */
default:
stall( USB_DIR_IN );
return;
}
}
/** ============================================================================
* @func set_DeviceDesc
* @desc
* Sets the descriptor for the USB device
*
* =============================================================================
*/
void set_DeviceDesc( INT8U* device_desc )
{
dev_desc = device_desc;
}
/** ============================================================================
* @func set_ConfigDesc
* @desc
* Sets the configuration for the USB device
*
* =============================================================================
*/
void set_ConfigDesc( INT8U * config_desc )
{
cfg_desc = config_desc;
cfg_desc_size = *( INT16U* )&config_desc[2];
}
/** ============================================================================
* @func addStringDesc
* @desc
* Adds a String Desc to the internal String table. The index parameter
* will become the search key, when retrieving the String.
*
* =============================================================================
*/
void addStringDesc( INT8U* string, INT8U index )
{
INT16U i;
for ( i = 0 ; i < USB_STRING_INDEX_MAX ; i++ )
if ( ! string_desc_tbl[i].ptr )
{
string_desc_tbl[i].ptr = string;
string_desc_tbl[i].index = index;
return;
}
}
/** @brief Sets up the USBF to a useful state as specified
*
* Configures the USBF using the values passed in through the
* setup structure.
*
* <b> Usage Constraints: </b>
* Both @a CSL_usbfInit() and @a CSL_usbfOpen() must be called
* successfully in that order before this function can be called. The user
* has to allocate space for & fill in the main setup structure
*
* @b Example:
* @verbatim
CSL_UsbfHandle hUsbf;
CSL_UsbfHwSetup hwSetup = {
<TODO>
};
...
CSL_usbfHwSetup(hUsbf, &hwSetup);
@endverbatim
*
* @return Returns the status of the setup operation
*
*/
CSL_Status CSL_usbfHwSetup(
/** Pointer to the object that holds reference to the
* instance of USBF requested after the Open call */
CSL_UsbfHandle hUsbf,
/** Pointer to setup structure which contains the
* information to program USBF to a useful state */
CSL_UsbfHwSetup *hwSetup
)
{
if(hwSetup == NULL)
return CSL_ESYS_INVPARAMS ;
if(hUsbf == NULL)
return CSL_ESYS_BADHANDLE ;
/*==============================================================================*/
if(hwSetup->epSetup != NULL)
{
int epNum ;
if(hwSetup->epSetup->ep0 != NULL)
{
register INT16U _ep0 = hUsbf->regs->EP0;
CSL_FINS(_ep0, USBF_EP0_SIZE, hwSetup->epSetup->ep0->size);
CSL_FINS(_ep0, USBF_EP0_PTR, hwSetup->epSetup->ep0->ptr);
hUsbf->regs->EP0 = _ep0;
}
for(epNum = 0; epNum < 15; epNum++)
{
if(hwSetup->epSetup->rxEp[epNum] != NULL)
{
register INT16U _rx_ep = hUsbf->regs->RX_EP[epNum].RX_EP ;
CSL_FINS(_rx_ep, USBF_RX_EP_VALID, hwSetup->epSetup->rxEp[epNum]->valid);
CSL_FINS(_rx_ep, USBF_RX_EP_ISO, hwSetup->epSetup->rxEp[epNum]->type);
/* Double buffering applies only if endpoint is of type Non-ISO */
if((hwSetup->epSetup->rxEp[epNum]->type) == CSL_USBF_EPTYPE_NON_ISO)
{
CSL_FINS(_rx_ep, USBF_RX_EP_SIZEDB, hwSetup->epSetup->rxEp[epNum]->doubleBuffered);
CSL_FINS(_rx_ep, USBF_RX_EP_SIZE, hwSetup->epSetup->rxEp[epNum]->size);
}
if((hwSetup->epSetup->rxEp[epNum]->type) == CSL_USBF_EPTYPE_ISO)
{
/* Put MSB of 3 bit of 'size' into SIZEDB filed */
CSL_FINS(_rx_ep, USBF_RX_EP_SIZEDB, (hwSetup->epSetup->rxEp[epNum]->size) >> 2);
/* Put lower 2 bits of 'size' into SIZE filed */
CSL_FINS(_rx_ep, USBF_RX_EP_SIZE, (hwSetup->epSetup->rxEp[epNum]->size) & 0x3);
}
CSL_FINS(_rx_ep, USBF_RX_EP_PTR, hwSetup->epSetup->rxEp[epNum]->ptr);
hUsbf->regs->RX_EP[epNum].RX_EP = _rx_ep ;
}
}
for(epNum = 0; epNum < 15; epNum++)
{
if(hwSetup->epSetup->txEp[epNum] != NULL)
{
register INT16U _tx_ep = hUsbf->regs->TX_EP[epNum].TX_EP ;
CSL_FINS(_tx_ep, USBF_TX_EP_VALID, hwSetup->epSetup->txEp[epNum]->valid);
CSL_FINS(_tx_ep, USBF_TX_EP_ISO, hwSetup->epSetup->txEp[epNum]->type);
/* Double buffering applies only if endpoint is of type Non-ISO */
if((hwSetup->epSetup->txEp[epNum]->type) == CSL_USBF_EPTYPE_NON_ISO)
{
CSL_FINS(_tx_ep, USBF_TX_EP_SIZEDB, hwSetup->epSetup->txEp[epNum]->doubleBuffered);
CSL_FINS(_tx_ep, USBF_TX_EP_SIZE, hwSetup->epSetup->txEp[epNum]->size);
}
if((hwSetup->epSetup->txEp[epNum]->type) == CSL_USBF_EPTYPE_ISO)
{
/* Put MSB of 3 bit of 'size' into SIZEDB filed */
CSL_FINS(_tx_ep, USBF_TX_EP_SIZEDB, (hwSetup->epSetup->txEp[epNum]->size) >> 2);
/* Put lower 2 bits of 'size' into SIZE filed */
CSL_FINS(_tx_ep, USBF_TX_EP_SIZE, (hwSetup->epSetup->txEp[epNum]->size) & 0x3);
}
CSL_FINS(_tx_ep, USBF_TX_EP_PTR, hwSetup->epSetup->txEp[epNum]->ptr);
hUsbf->regs->TX_EP[epNum].TX_EP = _tx_ep ;
}
}
}
/*==============================================================================*/
if(hwSetup->dmaSetup != NULL)
{
register INT16U _rxdma_cfg = hUsbf->regs->RXDMA_CFG ;
register INT16U _txdma_cfg = hUsbf->regs->TXDMA_CFG ;
CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RX_REQ, hwSetup->dmaSetup->rxRequestType) ;
if(hwSetup->dmaSetup->rxChanSetup[2] != NULL)
{
CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RXDMA2_EP, hwSetup->dmaSetup->rxChanSetup[2]->chanEpNum) ;
CSL_FINS(hUsbf->regs->RXDMA2, USBF_RXDMA2_RX2_TC, hwSetup->dmaSetup->rxChanSetup[2]->transactionCount) ;
}
if(hwSetup->dmaSetup->rxChanSetup[1] != NULL)
{
CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RXDMA1_EP, hwSetup->dmaSetup->rxChanSetup[1]->chanEpNum) ;
CSL_FINS(hUsbf->regs->RXDMA1, USBF_RXDMA1_RX1_TC, hwSetup->dmaSetup->rxChanSetup[1]->transactionCount) ;
}
if(hwSetup->dmaSetup->rxChanSetup[0] != NULL)
{
CSL_FINS(_rxdma_cfg, USBF_RXDMA_CFG_RXDMA0_EP, hwSetup->dmaSetup->rxChanSetup[0]->chanEpNum) ;
CSL_FINS(hUsbf->regs->RXDMA0, USBF_RXDMA0_RX0_TC, hwSetup->dmaSetup->rxChanSetup[0]->transactionCount) ;
}
CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TX_REQ, hwSetup->dmaSetup->txRequestType) ;
if(hwSetup->dmaSetup->txChanSetup[2] != NULL)
{
CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TXDMA2_EP, hwSetup->dmaSetup->txChanSetup[2]->chanEpNum) ;
CSL_FINS(hUsbf->regs->TXDMA2, USBF_TXDMA2_TX2_TSC, hwSetup->dmaSetup->txChanSetup[2]->txSize) ;
CSL_FINS(hUsbf->regs->TXDMA2, USBF_TXDMA2_TX2_EOT, hwSetup->dmaSetup->txChanSetup[2]->txSizeType) ;
}
if(hwSetup->dmaSetup->txChanSetup[1] != NULL)
{
CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TXDMA1_EP, hwSetup->dmaSetup->txChanSetup[1]->chanEpNum) ;
CSL_FINS(hUsbf->regs->TXDMA1, USBF_TXDMA1_TX1_TSC, hwSetup->dmaSetup->txChanSetup[1]->txSize) ;
CSL_FINS(hUsbf->regs->TXDMA1, USBF_TXDMA1_TX1_EOT, hwSetup->dmaSetup->txChanSetup[1]->txSizeType) ;
}
if(hwSetup->dmaSetup->txChanSetup[0] != NULL)
{
CSL_FINS(_txdma_cfg, USBF_TXDMA_CFG_TXDMA0_EP, hwSetup->dmaSetup->txChanSetup[0]->chanEpNum) ;
CSL_FINS(hUsbf->regs->TXDMA0, USBF_TXDMA0_TX0_TSC, hwSetup->dmaSetup->txChanSetup[0]->txSize) ;
CSL_FINS(hUsbf->regs->TXDMA0, USBF_TXDMA0_TX0_EOT, hwSetup->dmaSetup->txChanSetup[0]->txSizeType) ;
}
hUsbf->regs->RXDMA_CFG = _rxdma_cfg;
hUsbf->regs->TXDMA_CFG = _txdma_cfg;
}
/*=================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -