📄 usbh_hcds_channel.c
字号:
/*
* description : USBH HCD Channel Management(static)
* Maker : Hiromichi Kondo
* Copyright : (C)2005,SEIKO EPSON Corp. All Rights Reserved.
*/
#include <string.h> /* memset */
#include <SPRDEF.h>
#include <SPRSTS.h>
#include <usbh_hcd.h>
#include <usbh_hcds_common.h>
#include <usbh_hcds_72V05.h>
#include <usbh_hcds_channel.h>
#include <usbh_hcds_fifo.h>
/*****************************************
* Define definition
*****************************************/
#define NUM_USB_CH USBH_HCDS_CH_NUM_USB_CH
#define NUM_USB_CTRL_CH USBH_HCDS_HC_NUM_USB_CTRL_CH
#define NUM_USB_BULK_CH USBH_HCDS_HC_NUM_USB_BULK_CH
#define NUM_USB_INT_CH USBH_HCDS_HC_NUM_USB_INT_CH
#define NUM_USB_ISO_CH USBH_HCDS_HC_NUM_USB_ISO_CH
#define NUM_USB_STRG_CH USBH_HCDS_HC_NUM_USB_STRG_CH
#define INDEX_USB_CTRL_CH USBH_HCDS_HC_INDEX_USB_CTRL_CH
#define INDEX_USB_BULK_CH USBH_HCDS_HC_INDEX_USB_BULK_CH
#define INDEX_USB_INT_CH USBH_HCDS_HC_INDEX_USB_INT_CH
#define INDEX_USB_ISO_CH USBH_HCDS_HC_INDEX_USB_ISO_CH
#define INDEX_USB_STRG_CH USBH_HCDS_HC_INDEX_USB_STRG_CH
#define NOT_USED_CH (0x00)
#define TYPE_CTRL USBH_HCDS_CH_TYPE_CTRL
#define TYPE_BULK USBH_HCDS_CH_TYPE_BULK
#define TYPE_INT USBH_HCDS_CH_TYPE_INT
#define TYPE_ISO USBH_HCDS_CH_TYPE_ISO
#define TYPE_STRG USBH_HCDS_CH_TYPE_STRG
/*****************************************
* Structure definition
*****************************************/
typedef struct tagCHANNEL_MANAGER{
CALLBACK_PROC pfnCallback[NUM_USB_CH];
unsigned char allocCHNum[NUM_USB_CH];
}CHANNEL_MANAGER;
/*****************************************
* Function prototype declaration
*****************************************/
#ifdef DEBUG_C
long CHTranCmpCallback( unsigned long chNum, unsigned long urbStatus, void *pParam );
#else /* #ifdef DEBUG_C */
static long CHTranCmpCallback( unsigned long chNum, unsigned long urbStatus, void *pParam );
#endif /* #ifdef DEBUG_C */
/*****************************************
* Variable definition
*****************************************/
#ifdef DEBUG_C
CHANNEL_MANAGER CHStatus;
#else /* #ifdef DEBUG_C */
static CHANNEL_MANAGER CHStatus;
#endif /* #ifdef DEBUG_C */
/*=============================================================================================
// Function_Name: USBH_HCDS_CHInit
//
// description : Channel management block initialization
//
// Initialize channel management block
//
// argument : None
//
// return : None
===============================================================================================*/
void USBH_HCDS_CHInit( void )
{
memset(&CHStatus, 0, sizeof(CHStatus));
}
/*=============================================================================================
// Function_Name: USBH_HCDS_CHAlloc
//
// description : Allocation of channel
//
// The channel of the specified type is allocated
//
// argument : *pCHNum (out)Channel number
// type (in)Channel type
// TYPE_CTL Control transfer type
// TYPE_BULK Bulk transfer type
// TYPE_INT Interrupt transfer type
// TYPE_ISO Isochronous transfer type
// TYPE_STRG Bulk-Only transfer type
// size (in)Required FIFO size
//
// return : STATUS_SUCCESS Process completed successfully
// STATUS_UNSUCCESSFUL Channel allocation failed
// STATUS_MEM_ERROR Memory allocation error
// STATUS_INVALID_PARAMETER Parameter error
// STATUS_CANNOT_SETUP It is not possible to allocate it because it is used by another
===============================================================================================*/
long USBH_HCDS_CHAlloc( unsigned char *pCHNum, unsigned char type, unsigned long size )
{
USBH_HCDS_FIFOINFO sFIFOInfo;
unsigned char indexCH, numCH, usedBulk;
unsigned int i;
long retValue;
switch( type ){
case TYPE_CTRL:
indexCH = INDEX_USB_CTRL_CH;
numCH = NUM_USB_CTRL_CH;
break;
case TYPE_BULK:
indexCH = INDEX_USB_BULK_CH;
numCH = NUM_USB_BULK_CH;
break;
case TYPE_INT:
indexCH = INDEX_USB_INT_CH;
numCH = NUM_USB_INT_CH;
break;
case TYPE_ISO:
indexCH = INDEX_USB_ISO_CH;
numCH = NUM_USB_ISO_CH;
break;
case TYPE_STRG:
indexCH = INDEX_USB_STRG_CH;
numCH = NUM_USB_STRG_CH;
break;
default:
return STATUS_INVALID_PARAMETER;
}
usedBulk = 0;
for( i = 0; i < numCH; i++ ){
if( CHStatus.allocCHNum[indexCH] == NOT_USED_CH ){
/* Not used channel be found */
break;
} else if( type == TYPE_INT || type == TYPE_ISO ){
if( CHStatus.allocCHNum[indexCH] == TYPE_BULK ){
/* It is not possible to allocate it because it is used with Bulk */
usedBulk++;
}
}
indexCH++;
}
if( i == numCH ){
/* The channel that can be allocated doesn't exist */
if( usedBulk != 0 ){
/* The channel used by Bulk be found */
return STATUS_CANNOT_SETUP;
}
return STATUS_UNSUCCESSFUL;
}
sFIFOInfo.chNum = indexCH;
sFIFOInfo.size = size;
if( type == TYPE_STRG ){
sFIFOInfo.type = TYPE_BULK;
} else {
sFIFOInfo.type = type;
}
retValue = USBH_HCDS_FIFOAlloc(&sFIFOInfo);
if( retValue != STATUS_SUCCESS ){
return retValue;
}
/*=====================/
Channel allocation completed/
/=====================*/
CHStatus.allocCHNum[indexCH] = type;
*pCHNum = indexCH;
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_HCDS_CHTranGo
//
// description : Execute channel
//
// The channel is set from passed URB, and transaction is executed
//
// argument : *psUrb (in)Pointer of URB structure
// chNum (in)Channel number
// pfnCallback (in)Pointer of callback function that is called when completed
//
// return : STATUS_SUCCESS Process completed successfully
// STATUS_INVALID_PARAMETER Parameter error
===============================================================================================*/
long USBH_HCDS_CHTranGo( USBH_HCD_URB *psUrb, unsigned char chNum, CALLBACK_PROC pfnCallback )
{
long retValue;
CHStatus.pfnCallback[chNum] = pfnCallback;
/*=============/
Execute channel/
/=============*/
retValue = USBH_HCDS_HCTranGo(psUrb, chNum, CHTranCmpCallback);
if( retValue != STATUS_SUCCESS ){
return retValue;
}
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_HCDS_CHTranCancel
//
// description : Cancel the execution of channel
//
// Cancel when executing with the channel specified by passed URB
//
// argument : *psUrb (in)Pointer of URB structure
// chNum (in)Channel number
//
// return : STATUS_SUCCESS Process completed successfully
// STATUS_INVALID_PARAMETER Parameter error
===============================================================================================*/
long USBH_HCDS_CHTranCancel( USBH_HCD_URB *psUrb, unsigned char chNum )
{
#ifdef HCD_PARAMCHK_C
long retValue;
#endif
/*=====================================================/
Stop the execution of channel(Release of FIFO area is done by CHTranCmp()) /
/=====================================================*/
#ifdef HCD_PARAMCHK_C
retValue = USBH_HCDS_HCTranStop(psUrb, chNum);
if( retValue != STATUS_SUCCESS ){
return retValue;
}
#else
USBH_HCDS_HCTranStop(psUrb, chNum);
#endif
/*===============================================================/
Release it here when FIFO of the specified channel has not been released yet /
/===============================================================*/
if( CHStatus.allocCHNum[chNum] != NOT_USED_CH ){
/*=============/
/Release the FIFO area /
/=============*/
#ifdef HCD_PARAMCHK_C
retValue = USBH_HCDS_FIFOFree((unsigned char)chNum);
if( retValue != STATUS_SUCCESS ){
return retValue;
}
#else
USBH_HCDS_FIFOFree((unsigned char)chNum);
#endif
/*=============/
Release the channel /
/=============*/
CHStatus.allocCHNum[chNum] = NOT_USED_CH;
}
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: USBH_HCDS_CHTranCmp
//
// description : Callback process when transaction of channel is completed
//
// It is called when the transaction of the channel is completes or canceled
//
// argument : chNum (in)Channel number
// urbStatus (in)URB status
// *psUrb (in)Pointer of URB structure
//
// return : None
===============================================================================================*/
long CHTranCmpCallback( unsigned long chNum, unsigned long urbStatus, void *pParam )
{
USBH_HCD_URB *psUrb;
unsigned char type;
#ifdef HCD_PARAMCHK_C
long retValue;
#endif
psUrb = pParam;
type = CHStatus.allocCHNum[chNum];
if( urbStatus == USBH_HCD_URBSTS_CONNRESET ){
/* URB is canceled */
/*=============/
Release the FIFO area /
/=============*/
#ifdef HCD_PARAMCHK_C
retValue = USBH_HCDS_FIFOFree((unsigned char)chNum);
if( retValue != STATUS_SUCCESS ){
return retValue;
}
#else
USBH_HCDS_FIFOFree((unsigned char)chNum);
#endif
/*=============/
Release the channel /
/=============*/
CHStatus.allocCHNum[chNum] = NOT_USED_CH;
/*======================/
Confirm the change of URB status /
/======================*/
if( (psUrb->transFlag & USBH_HCD_URB_ASYNC_UNLINK) == 0 ){
/* case of URB cancellation by USBH_HCD_UnlinkURB */
while(1){
if( psUrb->status == USBH_HCD_URBSTS_CONNRESET ){
/* The status of canceled URB is changed */
urbStatus = psUrb->status = USBH_HCD_URBSTS_NOENT;
}
if( psUrb->psNext == NULL ){
break;
}
psUrb = psUrb->psNext;
}
psUrb = pParam; /* Return to upper(CBW) URB for ActiveURBList */
}
USBH_HCDS_ExecCallback(CHStatus.pfnCallback[chNum],chNum, urbStatus, psUrb); /* Call the callback of abnormal process */
} else {
/* Release the FIFO area and the channel when not in cancellation operation of URB, and call the callback */
if( (type == TYPE_CTRL) || (type == TYPE_BULK) || (type == TYPE_STRG) ){
/* Except synchronous transfer type (Interrupt/Isochronous) */
/*=============/
Release the Free area /
/=============*/
#ifdef HCD_PARAMCHK_C
retValue = USBH_HCDS_FIFOFree((unsigned char)chNum);
if( retValue != STATUS_SUCCESS ){
return retValue;
}
#else
USBH_HCDS_FIFOFree((unsigned char)chNum);
#endif
/*=============/
Release the channel/
/=============*/
CHStatus.allocCHNum[chNum] = NOT_USED_CH;
}
/*=========================/
Call the completion callback /
/=========================*/
USBH_HCDS_ExecCallback(CHStatus.pfnCallback[chNum],chNum, urbStatus, psUrb);
}
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -