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

📄 usbdevdma.c

📁 SmartARM2400系列开发板全套资料
💻 C
📖 第 1 页 / 共 2 页
字号:
			
				if ((ucEpIndex % 2) != 0) {
					__usbDevDMAWriteISR(&Ctrl_Usb[ucEpIndex - 2],ucEpIndex);
				
				} else {
					__usbDevDMAReadISR(&Ctrl_Usb[ucEpIndex - 2],ucEpIndex);
				}
			}
			
			if ((ucEpIndex % 2) == 0) {
				USBEpDMAEn |= (0x01 << ucEpIndex);						/*  重新使能该端点DMA功能 		*/		
			}
				
			USBEoTIntClr |= (INT32U)(0x01 << ucEpIndex);				/*  清除传输结束中断状态寄存器  */
		}
	}
}

/*********************************************************************************************************
** Function name:       __usbDevDMASystemError
** Descriptions:        DMA 系统中断错误处理
** input parameters:    无					
** output parameters:	无
** Returned value:      无
*********************************************************************************************************/
void __usbDevDMASystemError (void)
{ 
	INT8U ucEpIndex = 0;
	unsigned long ulEpState = 0;

	ulEpState = USBSysErrIntSt;											/*  读取系统错误中断状态寄存器 */						

	for (ucEpIndex = 2; ucEpIndex < 5; ucEpIndex++) {
		
		if(ulEpState & ((INT32U)(0x01 << ucEpIndex))) {
			
			__usbDevDMAInitEndpointDD(ucEpIndex);						/*  重新初始化DD  				*/

			USBEpDMAEn = (INT32U)(0x01 << ucEpIndex);					/*  重新使能该端点的DMA功能 	*/ 			
			
			USBSysErrIntClr |= (INT32U)(0x01 << ucEpIndex);				/*  清除系统错误中断 			*/
			
			if ((ucEpIndex % 2) != 0) {
			
				USBEpIntEn |= (INT32U)(0x01 << ucEpIndex);				/*  重新使能该 IN 端点从机中断 	*/
			}
		}		
	}
}

/*********************************************************************************************************
** Function name:       __usbDevDMANewDDDone
** Descriptions:        DMA 新 DD 请求中断服务程序
** input parameters:    ucEpIndex:	物理端点索引
**						pstUsb:		USB传输控制块结构体指针					
** output parameters:	无
** Returned value:      无
*********************************************************************************************************/
void __usbDevDMANewDDDone (INT8U ucEpIndex,CTRL_USB *pstUsb)
{
	INT32U ulLeftLen = 0;
	
	if (pstUsb->bEpUsed != 0) {
							   	   					  	   				/*  有任务在等待接收           	*/
		if (pstUsb->cnt >= pstUsb->len) {
														   				/*  如果接收完毕 			    */
 			OSSemPost(Ctrl_Usb[ucEpIndex - 2].Ep_Sem);
	  	
	  	} else {
	 
	  		ulLeftLen = pstUsb->len - pstUsb->cnt;						/*  计算未传输字节数			*/
	  		__usbDevDMASetTransLength(ucEpIndex,ulLeftLen);	  			/*  设置DMA接收/发送的字节长度  */
	  	}
	}
}

/*********************************************************************************************************
** Function name:       __usbDevDMANewDDRequest
** Descriptions:        DMA 新 DD 请求中断服务程序
** input parameters:    无					
** output parameters:	无
** Returned value:      无
*********************************************************************************************************/
void __usbDevDMANewDDRequest (void)
{
	INT8U ucEpIndex = 0;
	unsigned long ulEpIntState = 0;

	ulEpIntState = USBNDDRIntSt;										/*  读取新DD请求中断状态寄存器  */
	
	for (ucEpIndex = 2; ucEpIndex <= 5; ucEpIndex++) {

		if(ulEpIntState & ((INT32U)(0x01 << ucEpIndex))) { 											
			
			__usbDevDMANewDDDone(ucEpIndex,&Ctrl_Usb[ucEpIndex - 2]);	/*  重新设置该端点的DD          */
						
			USBNDDRIntClr = (INT32U)(0x01 << ucEpIndex);				/*  清除新DD请求中断 			*/

			if ((ucEpIndex % 2) != 0) {
			
				USBEpIntEn |= (unsigned long)(0x01 << ucEpIndex);		/*  重新使能该端点从机中断 		*/
			}
		}		
	}
}

/*********************************************************************************************************
  下面为提供给应用层调用的函数
*********************************************************************************************************/

/*********************************************************************************************************
** Function name:       __usbDevDMAInit
** Descriptions:        初始化LPC23xx USB设备控制器的DMA引擎
** input parameters:    无						
** output parameters:	无
** Returned value:      无
*********************************************************************************************************/
void __usbDevDMAInit (void)
{
	__usbDevDMAInitUdcaTable();											/*  初始化UDCA表 				*/
		
	__usbDevDMAInitEndpointDD(2);										/*  初始化各端点的DD			*/
	__usbDevDMAInitEndpointDD(3);
	__usbDevDMAInitEndpointDD(4);
	__usbDevDMAInitEndpointDD(5);
	
	USBDMAIntEn = USBDMA_EOT_INT | 										/*  使能DMA的传输结束中断 		*/
				  USBDMA_NDD_INT | 										/*  使能DMA的新DD请求中断 		*/
				  USBDMA_ERR_INT;										/*  使能DMA的系统错误中断		*/
	
	USBEpDMAEn  = (0x01 << 2) | 										/*  使能端点DMA功能				*/
				  (0x01 << 3) | 
				  (0x01 << 4) | 
				  (0x01 << 5);													
}

/*********************************************************************************************************
** Function name:       __usbDevDMAService
** Descriptions:        DMA 中断服务程序
** input parameters:    无						
** output parameters:	无
** Returned value:      无
*********************************************************************************************************/
void __usbDevDMAService(void)
{
	unsigned long ulIntState = 0;
		
	ulIntState = USBDMAIntSt;											/*  读DMA中断状态寄存器   		*/

	if (ulIntState & USBDMA_EOT_INT) {										
		__usbDevDMATransferEnd();										/*  传输结束中断				*/
	}
		
	if (ulIntState & USBDMA_NDD_INT) {	
		__usbDevDMANewDDRequest();										/*  新DD请求中断			 	*/
	}
	
	if (ulIntState & USBDMA_ERR_INT) {
		__usbDevDMASystemError();										/*  系统错误中断			 	*/
	}
}

/*********************************************************************************************************
** Function name:       __usbDevDMAReadPort
** Descriptions:        DMA模式下,从USB Device的OUT端点FIFO中读取数据	
** input parameters:    ucEpIndex		物理端点索引号2,4等
**						ucBufNum		物理端点FIFO个数
**						pstUsb			指向物理端点传输控制块结构体的指针	
**						pucRcvBuf		接收数据缓冲区指针
**						ulReadLen		待读取字节数
**						usWaitTime		超时等待时间ms,为0时无限等待
** output parameters:	无
** Returned value:      0:操作成功;>0:操作失败
*********************************************************************************************************/
INT8U __usbDevDMAReadPort (INT8U ucEpIndex,
						   INT8U ucBufNum, 
                       	   CTRL_USB *pstUsb, 
                           INT8U *pucRcvBuf,
                           INT32U ulReadLen, 
                           INT16U usWaitTime)                                                 
{
	INT8U ucErr = 0;
	
	OS_ENTER_CRITICAL();
	
	ucErr = __usbDevRwParam(pstUsb,pucRcvBuf);						   	/*  检查参数正确性  		    */
	
	if (ucErr != USB_NO_ERR) {
	
		OS_EXIT_CRITICAL();	
		return ucErr;											   		/*  返回错误码     				*/
	}
	
	OS_EXIT_CRITICAL();	
	
	OS_ENTER_CRITICAL();
	
	pstUsb->buff = pucRcvBuf;								
	pstUsb->len  = ulReadLen;									   		/*  要接收的字节长度 			*/	
	pstUsb->cnt  = 0; 
	__usbDevDMASetTransLength(ucEpIndex,ulReadLen);
	
	OS_EXIT_CRITICAL();	
	
	OSSemPend(pstUsb->Ep_Sem, 
			  usWaitTime, 
			  &ucErr); 				   									/*  等待DMA接收数据的完成		*/

	OS_ENTER_CRITICAL();
	pstUsb->bEpUsed = 0;
	OS_EXIT_CRITICAL();
	
	if (ucErr == OS_NO_ERR) {
		return USB_NO_ERR;									   			/*  接收成功				    */
	} else {
		return USB_ERR_WR_TIMEOUT;							   			/*  接收超时错误			    */
	}
}                        
                           
/*********************************************************************************************************
** Function name:       __usbDevDMAWritePort
** Descriptions:        DMA模式下,向USB Device的IN端点FIFO中写入数据
** input parameters:    ucEpIndex		物理端点索引号2,4等
**						ucBufNum		物理端点FIFO个数
**						pstUsb			指向物理端点传输控制块结构体的指针	
**						pucSendBuf		发送数据缓冲区	
**						ulSendLen		待发送字节数
**						usWaitTime		超时等待时间ms,为0时无限等待
** output parameters:	无
** Returned value:      0:操作成功;>0:操作失败
*********************************************************************************************************/
INT8U __usbDevDMAWritePort (INT8U ucEpIndex,
							INT8U ucBufNum, 
                    	 	CTRL_USB *pstUsb, 
                    	 	INT8U *pucSendBuf, 
                    	 	INT32U ulSendLen, 
                    	 	INT16U usWaitTime)                   	 	                           
{
	INT8U 	i = 0;
	INT8U 	ucEpState = 0;
	INT8U  	ucErr    = 0;
	INT32U 	ulSetLen = 0;
	INT8U  	*pucDstBuf = NULL;
	
	OS_ENTER_CRITICAL();
	
	ucErr = __usbDevRwParam(pstUsb,pucSendBuf);						  	/*  检查参数正确性  		    */
	
	if (ucErr != USB_NO_ERR) {
	
		OS_EXIT_CRITICAL();
		return ucErr;											  		/*  返回错误码     				*/
	}
	
	OS_EXIT_CRITICAL();	
	
	OS_ENTER_CRITICAL();
	
	pstUsb->buff = pucSendBuf;
	pstUsb->len  = ulSendLen;
	pstUsb->cnt  = 0;
	
	for (i = 0; i < ucBufNum; i++) {
		
		ucEpState = __usbDevSelectEndpoint(ucEpIndex);
			
		if ((ucEpState & 0x60) != 0) {									/*  接收/发送缓冲区不空   		*/
															
			 __usbDevSetEndpointStatus(ucEpIndex, 1);					/*  禁止 IN 端点			 	*/
			
		}
	}	
	
	pucDstBuf = __usbDevDMAGetBuffer(ucEpIndex);						/*  取得该端点的DMA缓冲区首地址 */
	ulSetLen  = __usbDevDMASetTransLength(ucEpIndex,ulSendLen);				  
	
	memcpy(pucDstBuf,pucSendBuf,ulSetLen);						  		/*  复制数据到DMA发送缓冲区     */
	pstUsb->cnt = pstUsb->cnt + ulSetLen;						  		/*  计数器计数                  */
	__usbDevDMAStartIN(ucEpIndex);									  	/*  启动 IN 端点的 DMA 传输     */
	
	OS_EXIT_CRITICAL();
		
   	OSSemPend(pstUsb->Ep_Sem, 
   			  usWaitTime, 
   			  &ucErr);					  								/*  等待 DMA 发送数据的完成		*/
   			  
   	pstUsb->bEpUsed = 0;
   	
   	if (ucErr == OS_NO_ERR) {
    	
    	return USB_NO_ERR;									  			/*  发送成功					*/
	} else {
	
		return USB_ERR_WR_TIMEOUT;							  			/*  发送成功					*/
	}
}

#endif

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -