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

📄 d12driver.c

📁 周立功MagicARM2200-S USB_E2PROM编程
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                               广州周立功单片机发展有限公司
**                                     研    究    所
**                                        产品一部 
**
**                                 http://www.zlgmcu.com
**
** 文   件   名: D12Driver.c
** 最后修改日期: 2004年7月2日
** 描        述: USB驱动程序软件包: PDIUSBD12 设备端驱动程序 应用层
** 版	     本: V1.0

** 文   件   名: D12Driver.c
** 最后修改日期: 2004 年 8 月 8 日
** 描        述: 进行以下修改: 1. 初始化函数Init_D12() 对CTRL_USB的初始化使用了memset()函数,减少了代码量

							   2. 增加了端点收到数据, 但无任务接收时的矛盾, 见USB_ReadISR()函数与USB_ReadPort()函数 
							   
							   2. 增加了读/写端点无限等待功能
							   
 						       3. 对初始化 CTRL_USB 使用了memset()函数,减少了代码量
 						       
							   4. 修正了读/写端点函数误开中断的问题
							   
						       5. 减少了读/写端点函数中频繁开关中断
						       
						       6. 增加了获取固件版本号函数 USB_Get_ZLGUSBD12_Ver()
** 版	     本: V1.5

**********************************************************************************************************/

#include "config.h"
#include "D12Config.h"
#include "D12CI.h"
#include "D12HAL.h"
#include "Chap_9.h"
#include "D12Driver.h"

extern EPPFLAGS bEPPflags;

/** Setup包处理任务堆栈 */
OS_STK  TaskSetupStk[128];

/** Setup包处理任务事件指针  ***/			
OS_EVENT *pSetup_Event;

/******* PDIUSBD12各端点对应的 USB 接收或发送控制块 *********/
CTRL_USB UsbRec_Ep2;				//端点2接收控制块
CTRL_USB UsbRec_Ep1;				//端点1接收控制块

CTRL_USB UsbSend_Ep2;				//端点2发送控制块
CTRL_USB UsbSend_Ep1;				//端点1发送控制块

/***********************************************************************
** 函数名称: INT8U WritePort1(INT32U len,INT8U *sendbuff,INT16U timeout)
** 功能描述: 用端点 1 发送len个字节
** 输 入:   INT32U  len:	  	 发送的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
			 INT8U   sendbuff:   发送缓冲区指针
			 INT16U  timeout:    超时等待时间, 等于0表示无限等待
** 输 出:   0: 发送成功	 > 0: 发送失败(错误码)
************************************************************************/
INT8U WritePort1(INT32U len,INT8U *sendbuff,INT16U timeout)
{
	return (USB_WritePort(3, 16, 1, &UsbSend_Ep1, sendbuff, len, timeout));
}	//往端点1(端点索引号3)发送数据

/***********************************************************************
** 函数名称: INT8U WritePort2(INT32U len,INT8U *sendbuff,INT16U timeout)
** 功能描述: 用端点 2 发送len个字节
** 输 入:   INT32U  len:	      发送的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
			 INT8U   *sendbuff:   发送指针
			 INT16U  timeout:     超时等待时间, 等于0表示无限等待
** 输 出:   0: 发送成功	> 0: 发送失败(错误码)
***********************************************************************/
INT8U WritePort2(INT32U len,INT8U *sendbuff,INT16U timeout)
{
	return (USB_WritePort(5, 64, 2, &UsbSend_Ep2, sendbuff, len, timeout));
}	//往端点2(端点索引号5)发送数据

/**********************************************************************
** 函数名称: INT8U ReadPort1(INT32U len,INT8U *recbuff,INT16U timeout)
** 功能描述: 从端点 1 读出 len个字节
** 输 入:   INT32U  len:	     要读出的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
			 INT8U   *recbuff:   接收数据指针
			 INT16U  timeout:    超时等待时间, 等于0表示无限等待
** 输 出:   0: 读出成功	 > 0: 读出失败(错误码)
***********************************************************************/
INT8U ReadPort1(INT32U len,INT8U *recbuff,INT16U timeout)
{
	return (USB_ReadPort(2, 16, 1, &UsbRec_Ep1, len, recbuff, timeout));
}

/**********************************************************************
** 函数名称: INT8U ReadPort2(INT32U len,INT8U *recbuff,INT16U timeout)
** 功能描述: 从端点 2 读出len个字节
** 输 入:   INT32U  len:	     要读出的字节数(取值范围为0x00000001 ~ 0xFFFFFFFF)
			 INT8U   *recbuff:   接收数据指针
			 INT16U  timeout:    超时等待时间, 等于0表示无限等待
** 输 出:   0: 读出成功	> 0: 读出失败(错误码)
**********************************************************************/
INT8U ReadPort2(INT32U len,INT8U *recbuff,INT16U timeout)
{
	return (USB_ReadPort(4, 64, 2, &UsbRec_Ep2, len, recbuff, timeout));
}

/*********************************************************************
** 函数名称: INT8U Init_D12(void)
** 功能描述: 设置D12与硬件的连接, 初始化D12,  复位D12
** 输 入:   无
** 输 出:   0: 初始化成功    1: 初始化失败  
**********************************************************************/
INT8U Init_D12(void)
{
	INT32U i;
	
	OS_ENTER_CRITICAL();
	
	Init_D12Port();							//初始化PDIUSBD12与LPC2200的连接的硬件配置
	Rst_D12();								//复位PDIUSBD12
	
	i = readchipid();
	if (i != 0x1012){						//读取芯片ID号,如果不为 1012H
		OS_EXIT_CRITICAL(); 
		return 1;							//则复位失败
	}
	
	reconnect_USB();        				//重新连接USB
	
	bEPPflags.value = 0;					//初始化USB事件标志变量
	memset((INT8U *)&UsbSend_Ep1, 0, sizeof(CTRL_USB)); 		//初始化 USB 接收或发送控制块为0 
	memset((INT8U *)&UsbSend_Ep2, 0, sizeof(CTRL_USB)); 		//Initialize CTRL_USB structures to be zero
	
	memset((INT8U *)&UsbRec_Ep1, 0, sizeof(CTRL_USB));
	memset((INT8U *)&UsbRec_Ep2, 0, sizeof(CTRL_USB));

 	pSetup_Event = OSSemCreate(0);			//创建Setup包处理任务信号量
 	if (pSetup_Event == NULL)				//如果返回的事件指针为空
 	{
	 	OS_EXIT_CRITICAL(); 
 	 	return 1;							//则初始化失败
	}
	
	OS_EXIT_CRITICAL();
 	return 0;								//初始化成功
}


//总线复位处理子程序
void bus_reset(void)
{
}

//DMA结束处理
void dma_eot(void)
{
}

//总线挂起改变
void usb_suspend(void)
{
}

/******************************************
** 函数名称: void Usb_Exception(void)
** 功能描述: D12中断服务程序
*******************************************/
void Usb_Exception(void)
{
	INT16U i_st;

	OS_ENTER_CRITICAL();;							//进入D12中断服务程序时关中断
	i_st = D12_ReadInterruptRegister();				//读取PDIUSBD12中断寄存器值
	
	if(i_st != 0) {
		if(i_st & D12_INT_BUSRESET)
			bus_reset();							//总线复位处理
		if(i_st & D12_INT_EOT)
			dma_eot();								//DMA传输技术处理
		if(i_st & D12_INT_SUSPENDCHANGE)
			usb_suspend();							//总线挂起改变
		if(i_st & D12_INT_ENDP0IN)
			ep0_txdone();							//控制端点发送数据处理
		if(i_st & D12_INT_ENDP0OUT)
			ep0_rxdone();							//控制端点接收数据处理
		if(i_st & D12_INT_ENDP1IN)
			USB_WriteISR(&UsbSend_Ep1,3,16,1);		//端点 1发送数据处理
		if(i_st & D12_INT_ENDP1OUT)
			USB_ReadISR(&UsbRec_Ep1,2,16,1);		//端点 1接收数据处理
		if(i_st & D12_INT_ENDP2IN)
			USB_WriteISR(&UsbSend_Ep2,5,64,2);		//端点 2发送数据处理
		if(i_st & D12_INT_ENDP2OUT)
			USB_ReadISR(&UsbRec_Ep2,4,64,2);		//端点 2接收数据处理
	}
	//add for uC/OS-II
	CLR_INTD12();									//清除PDIUSBD12的中断标志
	CLR_INT();										//通知中断结束
   			
   	OS_EXIT_CRITICAL();							    //退出D12中断服务程序时开中断
}

/*******************************************************************
** 函数名称: void  TaskSetup(void *pdata)
** 功能描述: 控制传输处理
** 输	 入: void *pdata  任务参数
** 输	 出: 无
** 注	 意: 该任务的优先级应高于其它任务,才能在任何情况下传输Setup包
********************************************************************/
void  TaskSetup(void *pdata)
{
#if OS_CRITICAL_METHOD == 3       /* Allocate storage for CPU status register */
	OS_CPU_SR  cpu_sr;
#endif
	INT8U err;
	
	pdata = pdata;                /* Prevent compiler warning */
	for (;;)
	{
		OSSemPend(pSetup_Event,0,&err);		//等待Setup包
		if (err == OS_NO_ERR){				//接收到Setup包 
			OS_ENTER_CRITICAL();			//关中断
			control_handler();				//进行控制传输处理
			OS_EXIT_CRITICAL();			    //开中断
		}
	}
}


/*******************************************************************************************
** 函数名称:  void USB_ReadISR(CTRL_USB *pUsb,INT8U endp,INT32U eppsize,INT8U buffnums)
** 功能描述:  USB 端点接收中断服务程序
** 输   入:  CTRL_USB *pUsb:	USB 接收与发送控制结构体指针
			  INT8U		endp:	端点索引号
			  INT32U eppsize:	端点最大信息包大小
			  INT8U buffnums:	该端点缓冲区个数(如D12的端点2有两个接收缓冲区)
** 输   出:  无
********************************************************************************************/
void USB_ReadISR(CTRL_USB *pUsb,INT8U endp,INT32U eppsize,INT8U buffnums)
{
	INT8U *pBuff,endpstatus,i;
	INT32U len;
	
	D12_ReadLastTransactionStatus(endp);			   //复位中断寄存器
	
	if (pUsb->Grp != 0){						   	   //有任务在等待接收才允许进行接收
		if (pUsb->Sem == 0){					   	   //该端点接收资源还未被某一任务独占
			pUsb->Prio = USB_GetHighPrio(pUsb);        //取等待任务列表中优先级最高的任务的优先级
			pUsb->Cnt  = 0;				   			   //接收计数清0
			pUsb->Sem  = 1; 				   		   //标志有任务独占了该接收端点
		}
		pBuff = pUsb->pBuff[pUsb->Prio];		  	   //得到接收指针

		for (i = 0; i < buffnums; i++){											
			len = pUsb->Max[pUsb->Prio] - pUsb->Cnt;   //计算还有多少个字节未接收
			if (len > 0)
			{
				if (len >= eppsize)											
					len = (INT8U)D12_ReadEndpoint(endp,(INT8U)eppsize,pBuff + pUsb->Cnt);//接收整个缓冲区
				else
					len = (INT8U)D12_ReadEndpoint(endp,(INT8U)len,pBuff + pUsb->Cnt); 	 //接收len个字节
				pUsb->Cnt = pUsb->Cnt + len;			//计数器加上实际上收到的字节
			}

			if (pUsb->Cnt >= pUsb->Max[pUsb->Prio]){	//如果接收完毕
				pUsb->Max[pUsb->Prio] = 0;				//接收完成标志置0,表示正确接收
	   	  		pUsb->Sem  = 0;							//释放该端点接收资源
	   	  		USB_DelPrio(pUsb,pUsb->Prio);			//将该任务从等待队列中删除
	  			if (pUsb->bSuspend[pUsb->Prio] == 1)
	  				OSTaskResume(pUsb->Prio);
	  			else
	  				OSTimeDlyResume(pUsb->Prio);		//使该接收任务就绪
	  			break;
	  	 	}
			endpstatus = D12_ReadEndpointStatus(endp);	//读该端点状态寄存器
			if ((endpstatus & 0x60) == 0)  break;		//如果缓冲为空,立即跳出循环
		}//end of for()
	}//end of if (pUsb->Grp != 0)
	
	else
	{
		pUsb->NoTask = 1;								//没有任务接收数据,置位标志
	}
}


/**********************************************************************************************************
** 函数名称:  void USB_WriteISR(CTRL_USB *pUsb,INT8U endp,INT32U eppsize,INT8U buffnums)
** 功能描述:  USB 端点发送中断服务程序
** 输   入:  CTRL_USB   *pUsb:	 USB 接收与发送控制结构体指针
			  INT8U       endp:	 端点索引号
			  INT32U   eppsize:	 端点最大信息包大小
			  INT8U   buffnums:	 该端点缓冲区个数(如D12有两个缓冲区)
** 输   出:  无
***********************************************************************************************************/
void USB_WriteISR(CTRL_USB *pUsb,INT8U endp,INT32U eppsize,INT8U buffnums)
{
	INT32U len;

⌨️ 快捷键说明

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