📄 usbh_hcds_72v05.c
字号:
/* The transaction is in executing*/
if( indexCH == 0 ){
/* The control transfer support function is in using*/
if( (RegRead(REG08_H_CH0IntStat) & MASK_CTL_SupportCmp) != BIT_CTL_SupportCmp ){
/* Except for the case that the support function of control transfer has already completed */
RegWrite(REG08_H_CH0IntStat ,INT_CTL_SUPPORT_STOP); /* Clear the interrupt when cancel */
RegSet(REG08_H_CTL_SupportControl, BIT_CTL_SupportGo);
}
} else if( psURBInfo->bmTranFlags.supportBO == 1 ){
/* The Bulk-Only support function is in using */
if( (RegRead(REG08_H_CHaIntStat) & MASK_BO_SupportCmp) != BIT_BO_SupportCmp ){
/* Except for the case that the Bulk-Only support function has already completed*/
RegWrite(REG08_H_CHaIntStat, INT_BO_SUPPORT_STOP); /* Clear the interrupt when cancel */
RegSet(REG08_H_BO_SupportControl, BIT_BO_SupportGo);
}
} else {
REG_H_CHX_WINDOW_ADDR(prsH_CHxWindow, indexCH);
prxH_CHxWindow = (volatile REG_rxH_CHxWindow *)prsH_CHxWindow;
REG_H_CHX_INT_STAT_ADDR(prcH_CHxIntStat, indexCH);
if( (*prcH_CHxIntStat & INT_TOTAL_SIZE_CMP) == 0 ){
RegWrite( prcH_CHxIntStat, INT_CHANGE_CONDITION); /* Clear the interrupt when cancel */
RegSet( &prxH_CHxWindow->rcH_CHxConfig_0, CHX_TRAN_GO );
}
}
}
}
RegWrite(REG08_H_CHrIntEnb, 0xFF); /* Enable the channel interrupt */
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_ENABLED, USBH_HCDS_PORT_SPEED_MODE_UNKNOWN, NULL );
}
if( savedH_SIE_IntStat_1 & MASK_DisabledCmp ){
/* Transition of disabled state finished*/
RegClear(REG08_H_SIE_IntEnb_1, BIT_EnDisabledCmp); /* Disable the DisabledCmp interrupt */
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_DISABLED, USBH_HCDS_PORT_SPEED_MODE_UNKNOWN, NULL );
}
/* Clear the saved interrupt status */
savedH_SIE_IntStat_1 = 0x00;
}
if( savedHostIntStat & MASK_LineStateChanged ){
/* When the device worked, something was connected with host's port */
/* Do nothing now */
}
if( savedHostIntStat & MASK_VBUS_Err ){
/* VBUS overcurrent */
HCStatus.vbusErrCount++;
if( HCStatus.vbusErrCount >= USBH_HCD_VBUS_ERR_CHECK_COUNT ){
HCStatus.vbusErrCount = 0;
HCStatus.vbusErrCalled = 0;
RegWrite(REG08_H_NegoControl_0, NEGO_AUTO_MODE_CANCEL);
while( RegRead(REG08_H_NegoControl_0) & MASK_AutoModeCancel );
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_VBUS_OVER_CURRENT, USBH_HCDS_PORT_SPEED_MODE_UNKNOWN, NULL );
USBH_HCDS_CPUTimerStart(USBH_HCDS_HCRecoveryVBUSOverCurrent);
}
}
/* Clear the saved interrupt status */
savedHostIntStat = 0x00;
}
if( savedMainIntStat & MASK_DeviceIntStat ){
/* There is Device interrupt */
/*=============================/
Save the Device interrupt status/
/=============================*/
savedDeviceIntStat = RegRead(REG08_DeviceIntStat) & RegRead(REG08_DeviceIntEnb);
RegWrite(REG08_DeviceIntStat, savedDeviceIntStat);
if( savedDeviceIntStat & MASK_VBUS_Changed ){
/* Changing of VBUS is detected with the connector by the device side */
if( RegRead(REG08_D_USB_Status) & MASK_VBUS ){
USBH_HCDS_ExecCallback(HCStatus.pfnDetDevConCallback, 0, 0, NULL);
}
}
/* Clear the saved interrupt status */
savedDeviceIntStat = 0x00;
}
/* Clear the saved interrupt status */
savedMainIntStat = 0x00;
}
/*=============================================================================================
// Function_Name: CheckCHxIntStat
//
// description : Host Contoller Power Management Control
//
// Power management of Host Contoller is controlled.
//
// argument :
//
// return : None
===============================================================================================*/
Inline void CheckCHxIntStat( unsigned char chNum )
{
volatile REG_rxH_CHxWindow *prxH_CHxWindow;
volatile unsigned short *prsH_CHxWindow;
volatile REG_rxDMAxWindow *prxDMAxWindow;
volatile unsigned short *prsDMAxWindow;
volatile unsigned char savedH_CHxIntStat;
volatile unsigned char savedH_CHxIntEnb;
volatile unsigned char *prcH_CHxIntStat;
volatile unsigned char *prcH_CHxIntEnb;
URB_INFO *psURBInfo;
unsigned long copyCount, restartDMACount;
unsigned char *pSrcAdrs, *pDesAdrs;
psURBInfo = &URBInfo[chNum];
/*==========================/
Save the CHx interrupt status/
/==========================*/
REG_H_CHX_INT_STAT_ADDR(prcH_CHxIntStat, chNum);
REG_H_CHX_INT_ENB_ADDR(prcH_CHxIntEnb, chNum);
savedH_CHxIntStat = *prcH_CHxIntStat & *prcH_CHxIntEnb;
*prcH_CHxIntStat = savedH_CHxIntStat;
if( savedH_CHxIntStat != 0 ){
if( savedH_CHxIntStat & MASK_TranACK ){
/* The data reception or data transmission was done */
if( psURBInfo->bmTranFlags.syncTransfer == 1 ){
/* case of synchronous transfer type*/
if( psURBInfo->bmTranFlags.dirOUT == 1 ){
/* case of OUT transfer*/
copyCount = WriteFIFOData(chNum, psURBInfo->pBufAdrs, psURBInfo->remainDataSize);
} else {
/* case of IN transfer */
copyCount = ReadFIFOData(chNum, psURBInfo->pBufAdrs, psURBInfo->remainDataSize);
}
if( copyCount > 0 ){
UpdateURBInfo(psURBInfo, copyCount);
}
if( psURBInfo->remainDataSize == 0 ){
if( (savedH_CHxIntStat & ~(INT_TRAN_ACK | INT_TRAN_ERR)) == 0 ){
/* There is no transaction completion interrupt */
if( psURBInfo->bmTranFlags.dirOUT == 1 ){
/* case of OUT transfer */
RegWrite( REG08_H_CHrFIFO_Clr, 1 << (chNum - 1) ); /* Clear FIFO */
}
psURBInfo->bmTranFlags.tranErr = 0;
TransactionEnd(chNum);
}
}
} else {
if( psURBInfo->bmTranFlags.dirOUT == 1 ){
/* case of OUT transfer */
copyCount = WriteFIFOData(chNum, psURBInfo->pBufAdrs, psURBInfo->remainDataSize);
} else {
/* case of IN transfer */
copyCount = ReadFIFOData(chNum, psURBInfo->pBufAdrs, psURBInfo->remainDataSize);
}
if( copyCount > 0 ){
UpdateURBInfo(psURBInfo, copyCount);
}
}
}
if( savedH_CHxIntStat & MASK_ChangeCondition ){
/* The IN transaction is stopped by error */
if( (chNum == 0) || (psURBInfo->bmTranFlags.supportBO == 1)){
/* case of using channel for control transfer or using Bulk-Only support function*/
REG_DMAX_WINDOW_ADDR(prsDMAxWindow, psURBInfo->usedDMACh);
prxDMAxWindow = (volatile REG_rxDMAxWindow *)prsDMAxWindow;
/* Save the interrupt enable bit*/
savedH_CHxIntEnb = *prcH_CHxIntEnb;
/* DMA transfer stopped*/
USBH_HCDS_CPUDMAStop();
restartDMACount = (unsigned long)RegRead( &prxDMAxWindow->rsDMAx_Remain );
restartDMACount = MIN(restartDMACount, psURBInfo->remainDataSize);
DMATransactionEnd(psURBInfo->usedDMACh);
if( restartDMACount != 0 ){
/* There are datas that DMA can transfer*/
REG_H_CHX_WINDOW_ADDR(prsH_CHxWindow, chNum);
prxH_CHxWindow = (volatile REG_rxH_CHxWindow *)prsH_CHxWindow;
RegSet(&prxH_CHxWindow->rcH_CHxJoin, (1 << (2 + psURBInfo->usedDMACh)));
RegSet(&prxDMAxWindow->rcDMAx_Config, BIT_ActiveDMA);
RegWrite( &prxDMAxWindow->rsDMAx_Count_H, HIWORD(restartDMACount));
RegWrite( &prxDMAxWindow->rsDMAx_Count_L, LOWORD(restartDMACount));
pSrcAdrs = (unsigned char *)&RegRead(&prxDMAxWindow->rsDMAx_RdData);
pDesAdrs = (unsigned char *)psURBInfo->pBufAdrs;
USBH_HCDS_CPUDMAStart((unsigned char)psURBInfo->bmTranFlags.dirOUT, pSrcAdrs, pDesAdrs,
restartDMACount, USBH_HCDS_HCCPUDMATransactionEnd);
psURBInfo->bmTranFlags.usedDMA = 1;
psURBInfo->bmTranFlags.restartDMA = 1;
psURBInfo->pBufAdrs += restartDMACount;
psURBInfo->remainDataSize -= restartDMACount;
RegSet( &prxDMAxWindow->rcDMAx_Control, BIT_DMA_Go );
/* Return state of the interrupt enable bit to the state before the DMA transfer stops */
*prcH_CHxIntEnb = savedH_CHxIntEnb;
/* No process has been done after clearing the status of the saved interrupt */
savedH_CHxIntStat = 0x00;
}
}
}
if( (savedH_CHxIntStat & ~(INT_TRAN_ACK | INT_TRAN_ERR)) != 0 ){
/* There is a transaction completion interrupt */
*prcH_CHxIntEnb = 0; /* Disable all CHxIntEnb interrupt*/
if( psURBInfo->bmTranFlags.dirOUT == 0 ){
/* case of IN transfer */
copyCount = ReadFIFOData(chNum, psURBInfo->pBufAdrs, psURBInfo->remainDataSize);
if( copyCount > 0 ){
UpdateURBInfo(psURBInfo, copyCount);
}
}
if( chNum == 0 ){
/* Channel for Control transfer */
if( (savedH_CHxIntStat & MASK_CTL_SupportStop) ||
(savedH_CHxIntStat & MASK_CTL_SupportCmp) ){
/* Stop the control transfer support function*/
if( savedH_CHxIntStat & MASK_CTL_SupportCmp ){
/* The control transfer terminated normally */
psURBInfo->bmTranFlags.tranErr = 0;
} else {
/* The control transfer stopped by the transaction error. */
psURBInfo->bmTranFlags.tranErr = 1;
}
}
} else if( psURBInfo->bmTranFlags.supportBO == 1 ){
/* Use the Bulk-Only support function */
if( (savedH_CHxIntStat & MASK_BO_SupportStop) ||
!(savedH_CHxIntStat & MASK_BO_SupportCmp)){
/* Bulk-Only transfer support function stopped */
if( savedH_CHxIntStat & MASK_BO_SupportCmp ){
/* Bulk-Only transfer terminated normally */
psURBInfo->bmTranFlags.tranErr = 0;
} else {
/* The Bulk-Only transfer terminated abnormally*/
psURBInfo->bmTranFlags.tranErr = 1;
}
}
}
if( savedH_CHxIntStat & MASK_TotalSizeCmp ){
/* Transaction terminated normally */
psURBInfo->bmTranFlags.tranErr = 0;
}
if( savedH_CHxIntStat & MASK_ChangeCondition ){
/* Transaction stopped by error */
psURBInfo->bmTranFlags.tranErr = 1;
}
TransactionEnd(chNum);
}
/* Clear the saved interrupt status */
savedH_CHxIntStat = 0x00;
}
}
/*=============================================================================================
// Function_Name: USBH_HCDS_HCCPUDMATransactionEnd
//
// description : Termination process of DMA transaction mounted on CPU
//
// Post process when the transaction speified as DMA transfer by URB is completed.
//
// argument : dmaCHNum (in)DMA channel number
//
// return : STATUS_SUCCESS Processing is completed successfully
// STATUS_INVALID_PARAMETER Parameter error
===============================================================================================*/
long USBH_HCDS_HCCPUDMATransactionEnd( unsigned long dmaCHNum, unsigned long param1, void *pParam )
{
unsigned char chNum;
if( dmaCHNum >= NUM_CPU_DMA ){
return STATUS_INVALID_PARAMETER;
}
chNum = DMATransactionEnd((unsigned char)dmaCHNum);
if( chNum == 0 ){
/* Control transfer channel */
if( RegRead(REG08_H_CH0IntStat) & MASK_CTL_SupportCmp ){
TransactionEnd(chNum);
} else {
RegSet( REG08_H_CH0IntEnb, (BIT_EnCTL_SupportCmp | BIT_EnCTL_SupportStop));
}
} else if( URBInfo[chNum].bmTranFlags.supportBO == 1 ){
/* The Bulk-Only support function is in useing */
if( RegRead(REG08_H_CHaIntStat) & MASK_BO_SupportCmp ){
TransactionEnd(chNum);
} else {
RegSet(REG08_H_CHaIntEnb, (BIT_EnBO_SupportCmp | BIT_EnBO_SupportStop));
}
} else {
TransactionEnd(chNum);
}
return STATUS_SUCCESS;
}
/*=============================================================================================
// Function_Name: DMATransactionEnd
//
// description : Termination process of DMA transaction
//
// Post process when the transaction speified as DMA transfer by URB is completed.
//
// argument : chNum (in)Channel number
//
// return : Channel number of DMA transfer finish
===============================================================================================*/
Inline unsigned char DMATransactionEnd( unsigned char dmaCHNum )
{
URB_INFO *psURBInfo;
volatile REG_rxDMAxWindow *prxDMAxWindow;
volatile unsigned short *prsDMAxWindow;
volatile unsigned char *prcH_CHxIntEnb;
unsigned long dmaCount;
unsigned char indexCH;
indexCH = HCStatus.usedDMAChforCH[dmaCHNum];
REG_DMAX_WINDOW_ADDR(prsDMAxWindow, dmaCHNum);
prxDMAxWindow = (volatile REG_rxDMAxWindow *)prsDMAxWindow;
if( RegRead(&prxDMAxWindow->rcDMAx_Control) & MASK_DMA_Running ){
/* Stop it for DMA is in transferring */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -