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

📄 usbh_hcds_72v05.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
						/* 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 + -