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

📄 d12driver.c

📁 移植了可运行于arm lpc2294下的uc/os2
💻 C
📖 第 1 页 / 共 2 页
字号:
	   	  		USB_DelPrio(pUsb,pUsb->Prio);			//将该任务从等待队列中删除
	  			OSTimeDlyResume(pUsb->Prio);		    //使该接收任务就绪
	  			break;
	  	 	}
			endpstatus = D12_ReadEndpointStatus(endp);	//读该端点状态寄存器
			if ((endpstatus & 0x60) == 0)  break;		//如果缓冲为空,立即跳出循环
		}//end of for()
	}//end of if (pUsb->Grp != 0)
	else
		D12_ClearBuff(endp);			//没有任务接收数据,清空该端点接收缓冲区
}


/**********************************************************************************************************
** 函数名称:  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;
	INT8U *pBuff,i,endpstatus;
	
	D12_ReadLastTransactionStatus(endp);					//复位中断寄存器

	if (pUsb->Grp != 0){															
		if (pUsb->Cnt >= pUsb->Max[pUsb->Prio]){			//独占任务全部数据写入缓冲区
			endpstatus = D12_ReadEndpointStatus(endp) & 0x60;
			if (endpstatus == 0){							//缓冲区中的数据全部发送完毕
				pUsb->Sem  = 0;								//释放该端点的发送资源
				pUsb->Max[pUsb->Prio] = 0;					//置正确发送标志为0
				USB_DelPrio(pUsb,pUsb->Prio);				//将该任务从等待队列中删除
				OSTimeDlyResume(pUsb->Prio);	    		//使该任务就绪
			}else
				return;
		}
	}
	else
  		return;
  	
  	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++){
			endpstatus = D12_ReadEndpointStatus(endp) & 0x60;
			if (endpstatus == 0x60)  break;					//如果缓冲区全部都满,那么不可以再写入
				
			len = pUsb->Max[pUsb->Prio] - pUsb->Cnt;
			if (len > 0){					   				//有空的缓冲区而且等待发送字节数大于0
				if (len >= eppsize)			   				//写满缓冲区
					len = D12_WriteEndpoint(endp,(INT8U)eppsize,pBuff + pUsb->Cnt); 
				else						   				//写len个字节
					len = D12_WriteEndpoint(endp,(INT8U)len,pBuff + pUsb->Cnt);  
				pUsb->Cnt = pUsb->Cnt + len;      			//发送计数器加上实际上发送的字节
			}//end of if (len > 0)
		}//end of for()	
	}//end of if (pUsb->Grp != 0)	
}

/**********************************************************************************
** 函数名称: INT8U USB_ReadPort(INT8U endp,CTRL_USB *pUsb,INT32U len,INT8U *recbuff,INT16U timeout)
** 功能描述: 读端点函数
** 输	 入: INT8U endp:	  端点索引号		
			 CTRL_USB *pUsb:  USB 接收与发送控制块指针
			 INT32U     len:  接收字节个数
			 INT8U *recbuff:  接收缓冲区
			 INT16U	timeout:  等待超时时间
** 输	 出: 0:	读成功       > 0 读失败(错误码)
**********************************************************************************/
INT8U USB_ReadPort(INT8U endp,CTRL_USB *pUsb,INT32U len,INT8U *recbuff,INT16U timeout)
{
	INT8U err;
	
	err = USB_RW_Param(pUsb,len,recbuff);		//填写USB接收或发送控制块参数
	if (err != USB_NO_ERR)   return err;	
	
	OS_ENTER_CRITICAL();
	if (pUsb->Max[OSPrioCur] != 0){				//如果还没接收完成
		OS_EXIT_CRITICAL();
		OSTimeDly(timeout);						//定义超时等待
	}	
	OS_EXIT_CRITICAL();
	
	return (USB_RW_Result(endp,pUsb,timeout));	//返回接收结果
}

/*****************************************************************
** 函数名称: INT8U USB_WritePort(INT8U endp,INT32U eppsize,INT8U buffnums,CTRL_USB *pUsb,
								 INT8U *sendbuff,INT32U len,INT16U timeout)
** 功能描述: 
** 输	 入: INT8U endp		  : 端点索引号
			 INT32U eppsize   : 该端点的的信息包大小
			 INT8U buffnums   : 该端点发送缓冲区个数
			 CTRL_USB *pUsb   : 该端点的接收或发送控制块指针
			 INT8U  *sendbuff : 发送数据字节指针
			 INT32U   len	  : 发送数据字节长度
			 INT16U	timeout	  : 等待超时时间
** 输	 出: 0   发送成功    > 0 发送失败(错误码)
******************************************************************/
INT8U USB_WritePort(INT8U endp,INT32U eppsize,INT8U buffnums,CTRL_USB *pUsb,
					INT8U *sendbuff,INT32U len,INT16U timeout)
{
	INT8U err,i;
	INT32U length;

	err = USB_RW_Param(pUsb,len,sendbuff);		//填写USB接收或发送控制块参数
	if (err != USB_NO_ERR)   return err;

	OS_ENTER_CRITICAL();
    if (pUsb->Sem == 0){			  			//该端点没有被独占
		pUsb->Sem  = 1;				    		//独占该端点
		pUsb->Cnt  = 0;							//发送计数值清0
		pUsb->Prio = OSPrioCur; 				//保存独占该端点的任务优先级

		for (i = 0; i < buffnums; i++){										
			length = pUsb->Max[pUsb->Prio] - pUsb->Cnt;	//计算未发送字节个数
			if (length > 0){							//未发送字节数大于0
				if (length >= eppsize)					//写满缓冲区
					length = D12_WriteEndpoint(endp,(INT8U)eppsize,sendbuff + pUsb->Cnt);
				else									//写length个字节
		   			length = D12_WriteEndpoint(endp,(INT8U)length,sendbuff + pUsb->Cnt);
		 		pUsb->Cnt = pUsb->Cnt + length;			//发送计数器加length
			}
		}
	}//end of if (pUsb->Sem == 0)
	OS_EXIT_CRITICAL();
	
	OS_ENTER_CRITICAL();
	if (pUsb->Max[OSPrioCur] != 0){						//还未发送完成
		OS_EXIT_CRITICAL();						
		OSTimeDly(timeout);								//定义超时等待时间				
	}	
	OS_EXIT_CRITICAL();
	
	return (USB_RW_Result(endp,pUsb,timeout));  		//返回发送结果					
}

/*****************************************************************
** 函数名称: INT8U USB_RW_Param(CTRL_USB *pUsb,INT32U len,INT8U *buff)
** 功能描述: 填写USB接收或发送控制块有关参数
** 输	 入: CTRL_USB *pUsb   : USB接收或发送控制块指针
			 INT32U len		  : 接收或发送字节数
			 INT8U *buff	  : 接收或发送缓冲区指针
** 输	 出: 0   调用成功    > 0 调用失败(错误码)
******************************************************************/
INT8U USB_RW_Param(CTRL_USB *pUsb,INT32U len,INT8U *pbuff)
{
	OS_ENTER_CRITICAL();
	if (bEPPflags.bits.configuration == 0){	//USB总线未配置完成
		OS_EXIT_CRITICAL();
		return (USB_ERR_NO_CONFIG);			//USB总线未配置错误
	}
	if (pbuff == 0){     	
		OS_EXIT_CRITICAL();			    
		return (USB_ERR_BUFF_INVALID);		//缓冲区指针无效错误
	}
	
	pUsb->pBuff[OSPrioCur] = pbuff;			//保存该任务的接收缓冲区首址
	pUsb->Max[OSPrioCur]   = len;			//保存要收发的字节数
	USB_InsertPrio(pUsb,OSPrioCur);			//插入等待任务列表中
	OS_EXIT_CRITICAL();
	
	return (USB_NO_ERR);
}

/*****************************************************************
** 函数名称: INT8U USB_RW_Result(INT8U endp,CTRL_USB *pUsb,INT16U timeout)
** 功能描述: 判断当前任务的数据是否收发成功
** 输	 入: INT8U endp		  : 端点索引号
			 CTRL_USB *pUsb   : USB接收或发送控制块指针
			 INT16U timeout	  : 超过等待时间
** 输	 出: 0   收发成功    > 0 收发失败(错误码)
******************************************************************/
INT8U USB_RW_Result(INT8U endp,CTRL_USB *pUsb,INT16U timeout)
{	
	OS_ENTER_CRITICAL();	
	if (pUsb->Max[OSPrioCur] != 0){			//收发完成标志不为0,说明收发错误
		if (pUsb->Prio == OSPrioCur){		//该任务占用了端点的收发资源
			pUsb->Sem = 0;					//必须释放资源
			D12_ClearBuff(endp);			//清空收发缓冲区
		}
		USB_DelPrio(pUsb,OSPrioCur);		//将该任务从等待列表中删除
		OS_EXIT_CRITICAL();
		return (USB_ERR_WR_TIMEOUT);		//收发超时错误	
	}else{									
		OS_EXIT_CRITICAL();						
		return (USB_NO_ERR);				//收发成功
	}
}

/************************************************************
          下面的函数操作 USB接收或发送控制块等待列表
*************************************************************/
/************************************************************
** 函数名称:  void USB_DelPrio(CTRL_USB *pUsb,INT8U prio)
** 功能描述:  将一任务从USB接收或发送控制块等待列表中删除
** 输   入:  CTRL_USB *pUsb:	USB接收或发送控制块指针
			  INT8U prio:		删除的任务的优先级
** 输   出:  无
************************************************************/
void USB_DelPrio(CTRL_USB *pUsb,INT8U prio)
{
	if ((pUsb -> Tbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)
	     pUsb -> Grp &= ~OSMapTbl[prio >> 3];
}

/************************************************************
** 函数名称:  void USB_InsertPrio(CTRL_USB *pUsb,INT8U prio)
** 功能描述:  将一任务插入到USB接收或发送控制块等待列表中
** 输   入:  CTRL_USB *pUsb:	USB接收或发送控制块指针
			  INT8U prio:		插入任务的优先级
** 输   出:  无
************************************************************/
void USB_InsertPrio(CTRL_USB *pUsb,INT8U prio)
{
	pUsb -> Grp		 	   |= OSMapTbl[prio >> 3];
	pUsb -> Tbl[prio >> 3] |= OSMapTbl[prio & 0x07];
}

/*********************************************************************
** 函数名称:  INT8U USB_GetHighPrio(CTRL_USB *pUsb)
** 功能描述:  取得USB接收或发送控制块等待列表中优先级最高的任务优先级
** 输   入:  CTRL_USB *pUsb:	USB 接收或发送控制块指针
** 输   出:  等待列表中优先级最高的任务优先级
**********************************************************************/
INT8U USB_GetHighPrio(CTRL_USB *pUsb)
{
	INT8U x,y;
	INT8U prio;

	y    = OSUnMapTbl[pUsb->Grp];
	x    = OSUnMapTbl[pUsb->Tbl[y]];
	prio = (INT8U)((y << 3) + x);
	return prio;
}

⌨️ 快捷键说明

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