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

📄 usbdma.c

📁 周立功 214x pack 配套光盘
💻 C
📖 第 1 页 / 共 2 页
字号:

/****************************************Copyright (c)**************************************************
**                               Guangzhou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			USBCI.c
** Created by:			MingYuan Zheng
** Created date:		2005-1-6
** Last modified Date:	
** Last Version:		V1.0
** Descriptions:		LPC2148 USB DMA 
**												 
*******************************************************************************************************/

#include "config.h"

#include "USBConfig.h"
#include "USBCI.h"
#include "descriptor.h"

#include "USBDriver.h"
#include "USBdma.h"
#include "string.h"

#if DMA_ENGINE_EN 

/*
******************************************************************************
*		uCOS-II相关 API 函数 	   API Function releated with uCOS-II
******************************************************************************
*/

/*************************************************************************************************************************
** 函数名称: USB_ReadPortDMA()								  Name:		  USB_ReadPortDMA()
** 功能描述: 读端点(DMA方式)								  Function:	  read data from endpoint(DMA Mode)
** 输   入: INT8U	   endp:  物理端点索引号 	  			  Input:	  INT8U	    endp: the physical endpoint number
			 CTRL_USB *pUsb:  接收/发送数据控制块                         CTRL_USB *pUsb: the control block of receiving/sending 
			 INT32U     len:  接收字节个数								  INT32U     len: the numbers(Bytes) that will be received
			 INT8U *recbuff:  接收缓冲区								  INT8U *recbuff: the reception buffer
			 INT16U	timeout:  超时等待时间, 等于0表示无限等待             INT16U timeout: timeout of receiving,0 indicates limitless waiting
** 输	 出: 0:	读成功       > 0 读失败(错误码)				  Output:	  0:  sucessfully	 >0: fail (it is error code)
**************************************************************************************************************************/
INT8U USB_ReadPortDMA(INT8U endp, CTRL_USB *pUsb, INT32U len, INT8U *recbuff, INT16U timeout)
{
	INT8U err;
	
	OS_ENTER_CRITICAL();
	err = USB_RW_Param(pUsb, recbuff);						   /* 检查参数正确性  				  check the parameter */
	if (err != USB_NO_ERR)
	{
		OS_EXIT_CRITICAL();	
		return err;											   /* 返回错误码     				  return error code   */
	}	
	OS_EXIT_CRITICAL();	
	
	OS_ENTER_CRITICAL();
	pUsb->buff    = recbuff;								
	pUsb->len     = len;									   /* 要接收的字节长度 				  the bytes length that will be received */	
	pUsb->cnt 	  = 0; 
	USB_DMASetTransLength(endp, len);
	OS_EXIT_CRITICAL();	
	OSSemPend(pUsb->Ep_Sem, timeout, &err); 				   /* 等待DMA接收数据的完成		      wait for finishing receiving data */

	OS_ENTER_CRITICAL();
	pUsb->bEpUsed = 0;
	OS_EXIT_CRITICAL();
	if (err == OS_NO_ERR)
		return USB_NO_ERR;									   /* 接收成功						  receive sucessfully */
	else
		return USB_ERR_WR_TIMEOUT;							   /* 接收超时错误					  receive fail because it is timeout */
}


/*************************************************************************************************************************
** 函数名称: USB_WritePortDMA()								  Name:		  USB_WritePortDMA()
** 功能描述: 向USB主机发送数据(DMA方式)					  	  Function:	  send data to USB Host(DMA Mode)
** 输   入: INT8U	   endp:  物理端点索引号 	  			  Input:	  INT8U	    endp:  the physical endpoint number
			 CTRL_USB *pUsb:  接收/发送数据控制块                         CTRL_USB *pUsb:  the control block of receiving/sending 
			 INT8U *sendbuff: 接收缓冲区								  INT8U *sendbuff: the transmision buffer
			 INT32U     len:  接收字节个数								  INT32U     len:  the numbers(Bytes) that will be received
			 INT16U	timeout:  超时等待时间, 等于0表示无限等待             INT16U timeout:  timeout of transmision,0 indicates limitless waiting
** 输	 出: 0:	读成功       > 0 读失败(错误码)				  Output:	  0:  sucessfully	 >0: fail (it is error code)
**************************************************************************************************************************/
INT8U USB_WritePortDMA(INT8U endp, CTRL_USB *pUsb, INT8U *sendbuff, INT32U len, INT16U timeout)
{
	INT8U err,*pdmabuf;
	INT32U sendlen;
	
	OS_ENTER_CRITICAL();
	err = USB_RW_Param(pUsb, sendbuff);						  /* 检查参数正确性  				check the parameter */
	if (err != USB_NO_ERR)
	{
		OS_EXIT_CRITICAL();
		return err;											  /* 返回错误码     				return error code   */
	}
	OS_EXIT_CRITICAL();	
	
	OS_ENTER_CRITICAL();
	pUsb->buff    = sendbuff;
	pUsb->len     = len;
	pUsb->cnt     = 0;
	
	pdmabuf = USB_DMAGetBuffer(endp);						  /* 取得该端点的DMA缓冲区首地址    get the DMA buffer */
	sendlen = USB_DMASetTransLength(endp, len);				  
	
	memcpy(pdmabuf, sendbuff, sendlen);						  /* 复制数据到DMA发送缓冲区        copy data to DMA send buffer */
	pUsb->cnt = pUsb->cnt + sendlen;						  /* 计数器计数                     counter counting */
	USB_DMAStart_IN(endp);									  /* 启动 IN 端点的 DMA 传输        start the DMA transfer */
	OS_EXIT_CRITICAL();
		
   	OSSemPend(pUsb->Ep_Sem, timeout, &err);					  /* 等待 DMA 发送数据的完成		wait for finishing transmitting data */
   	pUsb->bEpUsed = 0;
   	if (err == OS_NO_ERR)
    {	
    	USBEPIntEn |= (0x01 << endp);
    	return USB_NO_ERR;									  /* 发送成功						transmit sucessfully */
	}
	else
	{
		USBEPIntEn |= (0x01 << endp);
		return USB_ERR_WR_TIMEOUT;							  /* 发送成功						transmit sucessfully */
	}
}


/*
***********************************************************************
*		用户可使用的API函数    API Function
***********************************************************************
*/
	
/************************************************************************************************************
** 函数名称: USB_DMAInit()								Name	 : USB_DMAInit()
** 功能描述: LPC214x DMA引擎初始化						Function : Initialize DMA engine of LPC214x USB
************************************************************************************************************/
void USB_DMAInit(void)
{
	USB_InitUdcaTable();								/* 初始化UDCA表      Initialize the UDCA table */
		
	USB_InitEndpointDD(2);								/* 初始化各端点的DD  Initialize the DD of each endpoint */
	USB_InitEndpointDD(3);
	USB_InitEndpointDD(4);
	USB_InitEndpointDD(5);
	
														/* Enable System error, New DD Request and End of Transfer Interrupt of DMA */
	USBDMAIntEn = USBDMA_EOT_INT | USBDMA_NDD_INT | USBDMA_ERR_INT;			/* 使能DMA的系统错误中断, 新DD请求中断, 传输结束中断 */
	
	USBEpDMAEn = (0x01 << 2) | (0x01 << 3) | (0x01 << 4) | (0x01 << 5);
														/* 使能端点DMA功能   Enable Endpoint DMA */
}


/************************************************************************************************************
** 函数名称: USB_DMASetTransLength()					Name	 : USB_DMASetTransLength()
** 功能描述: 设置 DMA 传输长度							Function : Config DMA transfer length
** 输	 入: INT8U endp: 物理端点号						Input	 : INT8U endp: physical endpoint
			 INT16U len: 传输字节长度				  		  	   INT16U len: transfer byte length
** 输	 出: 实际 DMA 传输长度							Output	 : the actual transfer length	
************************************************************************************************************/
INT32U USB_DMASetTransLength(INT8U endp, INT32U len)
{ 
	DD_DESCRIPTOR *pDD = USB_GetDDPointer(endp);		/* 取得 DD 指针 		   Get the DD pointer of the endpoint */

	USB_InitEndpointDD(endp);							/* 初始化DD      		   Initialize the DD */
	
	if (len > (pDD->control >> 16))						/* 长度超过本端点DMA缓冲区 len is beyond the dma buffer of the endpoint*/
		len = pDD->control >> 16;
	
	pDD->control &= 0x0000FFFF;
	pDD->control |= (len << 16);						/* 将len写入DD	 		   Write the len into DD */

	return len;											
}


/************************************************************************************************************
** 函数名称: USB_DMAGetRecLength()						Name	 : USB_DMAGetRecLength()
** 功能描述: 取得当前 DMA 传输长度						Function : get the current DMA transfer length
** 输	 入: INT8U endp: 物理端点号						Input	 : INT8U endp: physical endpoint
** 输	 出: 当前 DMA 传输长度							Output	 : current transfer length	
************************************************************************************************************/
INT32U USB_DMAGetRecLength(INT8U endp)
{
	DD_DESCRIPTOR *pDD = USB_GetDDPointer(endp);		/* 取得 DD 指针 		   Get the DD pointer of the endpoint */	
	
	return (pDD->status & 0xFFFF0000) >> 16;			/* 返回长度值 			   return the length value */
}


/************************************************************************************************************
** 函数名称: USB_DMAStart_IN()							Name	 : USB_DMAStart_IN()
** 功能描述: 启动 IN 端点的 DMA 传输					Function : start the DMA transfer of IN endpoint
** 输	 入: INT8U endp: 物理端点号						Input	 : INT8U endp: physical endpoint
** 输	 出: 无											Output	 : NULL	
************************************************************************************************************/
void USB_DMAStart_IN(INT8U endp)
{
	USBEPIntEn &= ~(0x01 << endp);						/* 清0 从机端点中断使能寄存器来启动 IN 传输 */
}														/* clear slave endpoint interrupt enable register to start IN transfer */


/************************************************************************************************************
** 函数名称: USB_DMAGetBuffer()							Name	 : USB_DMAGetBuffer()
** 功能描述: 得到DMA缓冲区首址							Function : Initialize DMA engine of LPC214x USB
************************************************************************************************************/
INT8U* USB_DMAGetBuffer(INT8U endp)
{
	const INT32U DmaTbl[4] = {DMA_BUFFER_ADDR_EP02, DMA_BUFFER_ADDR_EP03,
							  DMA_BUFFER_ADDR_EP04, DMA_BUFFER_ADDR_EP05};

	return (INT8U *)((INT32U *)DmaTbl[endp - 2]);		/* 返回缓冲区字节指针   return the byte buffer pointer */
}




/*
***********************************************************************
*		DMA 中断服务程序	 The Interrupt Service of the DMA 
***********************************************************************
*/

/************************************************************************************************************
** 函数名称: Usb_DMAService()							Name	 : Usb_DMAService()
** 功能描述: DMA 中断服务程序							Function : USB DMA Interrupt Service Program
************************************************************************************************************/
void USB_DMAService(void)
{
	INT32U dma_st;
		
	dma_st = USBDMAIntSt;								/* 读DMA中断状态寄存器  Read USBDMAIntSt */

	if (dma_st & USBDMA_EOT_INT)										
		USB_DMATransferEnd();							/* 传输结束中断			End of Transfer Interrupt */
		
	if (dma_st & USBDMA_NDD_INT)	
		USB_DMANewDDRequest();							/* 新DD请求中断			New DD Request Interrupt */
	
	if (dma_st & USBDMA_ERR_INT)
		USB_DMASystemError();							/* 系统错误中断			System Error Interrupt */
}


/************************************************************************************************************************
** 函数名称:  USB_DMAWriteISR()									Name:		USB_DMAWriteISR()
** 功能描述:  USB 端点发送中断服务程序(DMA)						Function:	the transmission interrupt service of USB endpoint 
** 输   入:  CTRL_USB *pUsb:  USB接收与发送控制结构体指针		Input:		CTRL_USB *pUsb: the CTRL_USB structure
			  INT8U		endp:  物理端点号									INT8U	  endp: the number of physical endpoint
** 输   出:  无												Output:		NULL
*************************************************************************************************************************/
void USB_DMAWriteISR(CTRL_USB *pUsb, INT8U endp)
{
	INT8U *pBuff,*sendbuf;
	INT32U len,sendlen;
	
	if (pUsb->bEpUsed != 0)
	{															   /* 有任务在等待发送    	  exist task waiting for transmission */
		if (pUsb->cnt >= pUsb->len)
		{
			OSSemPost(Ctrl_Usb[endp - 2].Ep_Sem);				   /* 数据全部发送完成 	  	  all data have been send */
			return;
		}
		
		len = pUsb->len - pUsb->cnt;   			   				   /* 计算未发送字节数  	  calculate the numbers of bytes that will be transmitted */
		pBuff = pUsb->buff;
		if (len > 0)

⌨️ 快捷键说明

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