⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbh_hcds_72v05.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 5 页
字号:

		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 + -