📄 usbh_hcds_72v05.c
字号:
RegSet(&prxDMAxWindow->rcDMAx_Control, BIT_DMA_Stop);
while( RegRead(&prxDMAxWindow->rcDMAx_Control) & MASK_DMA_Running );
}
dmaCount = (RegRead(&prxDMAxWindow->rsDMAx_Count_H)<< 16) & 0xFFFF0000;
dmaCount += RegRead(&prxDMAxWindow->rsDMAx_Count_L);
psURBInfo = &URBInfo[indexCH];
if( psURBInfo->bmTranFlags.restartDMA == 0 ){
/* Usual DMA termination process */
psURBInfo->remainDataSize = dmaCount;
psURBInfo->pBufAdrs += psURBInfo->reqDataSize - dmaCount;
} else {
/* Clears the flag only, for the DMA termination process after restart */
psURBInfo->bmTranFlags.restartDMA = 0;
}
psURBInfo->bmTranFlags.usedDMA = 0;
RegWrite(REG08_H_ClrAllCHnJoin, (1 << (2 + dmaCHNum)));
RegClear(&prxDMAxWindow->rcDMAx_Config, BIT_ActiveDMA);
REG_H_CHX_INT_ENB_ADDR(prcH_CHxIntEnb, indexCH);
*prcH_CHxIntEnb = 0;
return indexCH;
}
/*=============================================================================================
// Function_Name: TransactionEnd
//
// description : Termination of transaction
//
// post process when the transaction speified by URB is completed.
//
// argument : chNum (in)Channel number
//
// return : USBH_HCD_URBSTS_SUCCESS URB is completed successfully
// USBH_HCD_URBSTS_REMOTEIO The transferred size is fewer than the requirement sizes, when transfer finished
===============================================================================================*/
Inline void TransactionEnd( unsigned char chNum )
{
volatile REG_rxH_CHxWindow *prxH_CHxWindow;
volatile unsigned short *prsH_CHxWindow;
URB_INFO *psURBInfo;
USBH_HCD_URB *psUrb;
unsigned short urbStatus;
unsigned char endpoint, toggle;
unsigned short frameCount;
unsigned char cBO_TransState=0;
psURBInfo = &URBInfo[chNum];
REG_H_CHX_WINDOW_ADDR(prsH_CHxWindow, chNum);
prxH_CHxWindow = (volatile REG_rxH_CHxWindow *)prsH_CHxWindow;
endpoint = USBH_HCDS_GetPipeEndpoint(psURBInfo->psUrb->pipe);
if( psURBInfo->bmTranFlags.usedDMA == 1 ){
/* Stop it when the DMA transfer is used */
USBH_HCDS_CPUDMAStop();
DMATransactionEnd(psURBInfo->usedDMACh);
}
/* Clear all the Join setting of the channel */
RegWrite(&prxH_CHxWindow->rcH_CHxJoin, 0x00);
if( psURBInfo->bmTranFlags.directCopy == 1 ){
/* case of direct copy operation */
psURBInfo->remainDataSize = (RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_H) << 16) & 0xFFFF0000;
psURBInfo->remainDataSize += RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_L);
}
if( chNum == 0 ){
/* Channel for Control transfer */
if( psURBInfo->bmTranFlags.tranErr == 0 ){
/* Control transfer is completed successfully*/
urbStatus = GetURBCmpStatus(psURBInfo);
} else {
/* The control transfer stopped by the transaction error */
urbStatus = GetURBErrStatus( (RegRead(REG08_H_CH0ConditionCode) & MASK_ConditionCode)>>SHIFT_ConditionCode );
psURBInfo->remainDataSize = RegRead(REG16_H_CH0TotalSize);
toggle = (RegRead(REG08_H_CH0Config_0) & MASK_Toggle) >> SHIFT_Toggle;
if( (RegRead(REG08_H_CTL_SupportControl) & MASK_CTL_SupportState) == BIT_CTL_SupportState_Data ){
if( psURBInfo->bmTranFlags.dirOUT == 1 ){
USBH_HCDS_SetOUTToggle(psURBInfo->psUrb->psDev, endpoint, toggle);
} else {
USBH_HCDS_SetINToggle(psURBInfo->psUrb->psDev, endpoint, toggle);
}
} else if( (RegRead(REG08_H_CTL_SupportControl) & MASK_CTL_SupportState) == BIT_CTL_SupportState_Status ){
if( (RegRead(REG08_H_CH0Config_1) & MASK_TID) == BIT_TID_OUT ){
USBH_HCDS_SetOUTToggle(psURBInfo->psUrb->psDev, endpoint, 1);
} else {
USBH_HCDS_SetINToggle(psURBInfo->psUrb->psDev, endpoint, 1);
}
}
}
} else if( psURBInfo->bmTranFlags.supportBO == 1 ){
/* Channel with Bulk-Only support function */
toggle = (RegRead(REG08_H_OUT_EP_Control)& MASK_OUT_Toggle)>>SHIFT_OUT_Toggle;
endpoint = (RegRead(REG08_H_OUT_EP_Control)& MASK_OUT_EP_Number)>>SHIFT_OUT_EP_Number;
USBH_HCDS_SetOUTToggle(psURBInfo->psUrb->psDev, endpoint, toggle);
toggle = (RegRead(REG08_H_IN_EP_Control) & MASK_IN_Toggle)>>SHIFT_IN_Toggle;
endpoint = (RegRead(REG08_H_IN_EP_Control) & MASK_IN_EP_Number)>>SHIFT_IN_EP_Number;
USBH_HCDS_SetINToggle(psURBInfo->psUrb->psDev, endpoint, toggle);
psUrb = psURBInfo->psUrb;
if( psURBInfo->bmTranFlags.tranErr == 0 ){
/* Bulk-Only transfer terminated normally */
/*=============/
Update URB of CBW/
/=============*/
psUrb->actualLength = BO_CBW_SIZE;
urbStatus = USBH_HCD_URBSTS_SUCCESS;
psUrb->status = urbStatus;
psUrb = psUrb->psNext;
if( psUrb->psNext != NULL ){
/* CBW -> DATA -> CSW transfer */
/*==============/
Update URB of DATA/
/==============*/
psUrb->actualLength = psURBInfo->reqDataSize - psURBInfo->remainDataSize;
psUrb->status = urbStatus;
psUrb = psUrb->psNext;
}
/*=============/
Update URB of CSW/
/=============*/
psUrb->actualLength = BO_CSW_SIZE;
psUrb->status = urbStatus;
ReadRAMData(FIFO_START_ADRS_CSW, psUrb->pTransBuf, BO_CSW_SIZE);
} else {
/* Bulk-Only transfer terminated abnormally */
urbStatus = GetURBErrStatus( (RegRead(REG08_H_CHaConditionCode)&MASK_ConditionCode) >> SHIFT_ConditionCode );
cBO_TransState = RegRead(REG08_H_BO_SupportControl)& MASK_BO_TransportState;
cBO_TransState >>= SHIFT_BO_TransportState;
switch( cBO_TransState ){
case BO_SUPPORT_STATE_CBW:
/* Transaction error by CBW*/
psUrb->status = urbStatus;
break;
case BO_SUPPORT_STATE_DATA:
/* Transaction error by DATA */
psUrb->status = USBH_HCD_URBSTS_SUCCESS;
psUrb->actualLength = BO_CBW_SIZE;
psUrb = psUrb->psNext;
psURBInfo->remainDataSize = (RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_H) << 16) & 0xFFFF0000;
psURBInfo->remainDataSize += RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_L);
psUrb->actualLength = psURBInfo->reqDataSize - psURBInfo->remainDataSize;
psUrb->status = urbStatus;
break;
case BO_SUPPORT_STATE_CSW:
/* Transaction error by CSW */
psUrb->status = USBH_HCD_URBSTS_SUCCESS;
psUrb->actualLength = BO_CBW_SIZE;
psUrb = psUrb->psNext;
if(psUrb->psNext != NULL) {
/* CBW -> DATA -> CSW transfer */
/*==============/
Update URB of DATA/
/==============*/
psUrb->status = USBH_HCD_URBSTS_SUCCESS;
psUrb->actualLength = psURBInfo->reqDataSize - psURBInfo->remainDataSize;
psUrb = psUrb->psNext;
}
/* Set the size actually received with CSW (Do not set when receiving STALL) */
if( urbStatus != USBH_HCD_URBSTS_PIPE ){
psUrb->actualLength = RegRead( REG08_H_CSW_RcvDataSize );
}
ReadRAMData(FIFO_START_ADRS_CSW, psUrb->pTransBuf, psUrb->actualLength);
if( psUrb->actualLength == BO_CSW_SIZE ){
urbStatus = USBH_HCD_URBSTS_SUCCESS;
} else if( urbStatus == USBH_HCD_URBSTS_REMOTEIO ){
/* It is not an error even if transferred size is less than requirement size when transfer terminated */
urbStatus = USBH_HCD_URBSTS_SUCCESS;
}
psUrb->status = urbStatus;
break;
}
while(1){
if( psUrb->psNext == NULL ){
break;
}
/* Set the status of cancel when URB which doesn't set the URB status exist */
psUrb = psUrb->psNext;
psUrb->status = USBH_HCD_URBSTS_CONNRESET;
}
}
} else {
/* Usual transfer which doesn't use support function */
if( psURBInfo->bmTranFlags.tranErr == 0 ){
/* Transaction terminated normally */
urbStatus = GetURBCmpStatus(psURBInfo);
} else {
/* Transaction is stopped by error */
psURBInfo->remainDataSize = (RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_H) << 16) & 0xFFFF0000;
psURBInfo->remainDataSize += RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_L);
urbStatus = GetURBErrStatus((RegRead(&prxH_CHxWindow->rcH_CHxConditionCode)&MASK_ConditionCode)>>SHIFT_ConditionCode);
if( urbStatus == USBH_HCD_URBSTS_REMOTEIO ){
if( psURBInfo->bmTranFlags.shortNotOK == 0 ){
/* It is not an error even if transferred size is less than requirement size when transfer terminated */
urbStatus = USBH_HCD_URBSTS_SUCCESS;
}
}
}
toggle = (RegRead(&prxH_CHxWindow->rcH_CHxConfig_0)&MASK_Toggle) >> SHIFT_Toggle;
if( psURBInfo->bmTranFlags.dirOUT == 1 ){
USBH_HCDS_SetOUTToggle(psURBInfo->psUrb->psDev, endpoint, toggle);
} else {
USBH_HCDS_SetINToggle(psURBInfo->psUrb->psDev, endpoint, toggle);
}
}
if( psURBInfo->bmTranFlags.supportBO == 0 ){
/* The Bulk-Only support function is not used*/
UpdateURB(psURBInfo, urbStatus);
} else {
/* Uses the Bulk-Only support function, and URB has already been updated */
psURBInfo->bmTranFlags.supportBO = 0;
}
if( (RegRead(&prxH_CHxWindow->rcH_CHxConfig_0) & MASK_TranGo) == 0 ){
/* Clear flag when transfer is stopped */
psURBInfo->bmTranFlags.tranGo = 0;
}
USBH_HCDS_ExecCallback(psURBInfo->pfnCallback, chNum, urbStatus, psURBInfo->psUrb);
if( psURBInfo->bmTranFlags.syncTransfer == 1 ){
/* case of synchronous transfer type (Interrupt/Isochronous) */
if( urbStatus == USBH_HCD_URBSTS_SUCCESS ){
/* The transaction is continued only for the normal termination. */
if( psURBInfo->bmTranFlags.tranGo == 0 ){
/* When transfer is stopped, set transfer again */
HCStatus.bmSOFCheck |= (1 << chNum);
frameCount = RegRead(&prxH_CHxWindow->rsH_CHxInterval) >> 3;
if( frameCount == 0 ){
psURBInfo->waitSOFCount = 1;
} else if(frameCount < WAIT_SOF_DELAY ){
psURBInfo->waitSOFCount = frameCount;
} else {
psURBInfo->waitSOFCount = frameCount - WAIT_SOF_DELAY;
}
RegSet( REG08_H_FrameIntEnb, BIT_EnSOF );
} else {
psURBInfo->psUrb->status = USBH_HCD_URBSTS_INPROGRESS;
psURBInfo->pBufAdrs = psURBInfo->psUrb->pTransBuf;
psURBInfo->remainDataSize = psURBInfo->reqDataSize;
psURBInfo->psUrb->actualLength = 0;
}
}
}
}
/*=============================================================================================
// Function_Name: GetURBCmpStatus
//
// description : Return the URB status when terminated normally
//
// Return the URB status when the transaction specified by URB terminated normally
//
// argument : None
//
// return : USBH_HCD_URBSTS_SUCCESS URB terminated normally
// USBH_HCD_URBSTS_REMOTEIO The transferred size is fewer than the requirement sizes, when transfer finished
===============================================================================================*/
Inline unsigned short GetURBCmpStatus( URB_INFO *psURBInfo )
{
unsigned short urbStatus;
if( (psURBInfo->remainDataSize > 0) && (psURBInfo->bmTranFlags.shortNotOK == 1) ){
/* It is not an error even if transferred size is less than requirement size when transfer terminated */
urbStatus = USBH_HCD_URBSTS_REMOTEIO;
} else {
urbStatus = USBH_HCD_URBSTS_SUCCESS;
}
return urbStatus;
}
/*=============================================================================================
// Function_Name: GetURBErrStatus
//
// description : Return URB status when terminated abnormally
//
// Return the URB status when the transaction specified by URB terminated abnormally
//
// argument : conditionCode Condition code
//
// return : USBH_HCD_URBSTS_CONNRESET URB is canceled by USBH_HCD_SubmitURB().
// USBH_HCD_URBSTS_PROTO Pipe error(CRC error and time-out, etc.)
// USBH_HCD_URBSTS_PIPE Protocol error(STALL and Complete-split mistake)
===============================================================================================*/
Inline unsigned short GetURBErrStatus( unsigned char conditionCode )
{
unsigned short urbStatus;
switch( conditionCode ){
case CONDITION_CODE_NO_ERROR:
/* The same status is set here even when canceled by USBH_HCD_UnlinkURB(). */
urbStatus = USBH_HCD_URBSTS_CONNRESET;
break;
case CONDITION_CODE_STALL:
urbStatus = USBH_HCD_URBSTS_PIPE;
break;
case CONDITION_CODE_DATA_UNDER_RUN:
urbStatus = USBH_HCD_URBSTS_REMOTEIO;
break;
default:
urbStatus = USBH_HCD_URBSTS_PROTO;
}
return urbStatus;
}
/*=============================================================================================
// Function_Name: USBH_HCDS_HCPMControl
//
// description : Host Contoller Power Management Control
//
// Power Management of Host Contoller is controlled
//
// argument : state (in)Power Management state
// USBH_HCDS_HC_PM_STATE_SLEEP
// USBH_HCDS_HC_PM_STATE_SNOOZE
// USBH_HCDS_HC_PM_STATE_ACTIVE60
// USBH_HCDS_HC_PM_STATE_ACTDEVICE
// USBH_HCDS_HC_PM_STATE_ACTHOST
// pfnCallback (in)Pointer of callback function which is called when transition finished
//
// return : None
===============================================================================================*/
void USBH_HCDS_HCPMControl( unsigned char state, CALLBACK_PROC pfnCallback )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -