📄 d12driver.c
字号:
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 + -