?? d12driver.c
字號(hào):
INT8U *pBuff,i,endpstatus;
D12_ReadLastTransactionStatus(endp); //復(fù)位中斷寄存器
if (pUsb->Grp != 0){
if (pUsb->Cnt >= pUsb->Max[pUsb->Prio]){ //獨(dú)占任務(wù)全部數(shù)據(jù)寫入緩沖區(qū)
endpstatus = D12_ReadEndpointStatus(endp) & 0x60;
if (endpstatus == 0){ //緩沖區(qū)中的數(shù)據(jù)全部發(fā)送完畢
pUsb->Sem = 0; //釋放該端點(diǎn)的發(fā)送資源
pUsb->Max[pUsb->Prio] = 0; //置正確發(fā)送標(biāo)志為0
USB_DelPrio(pUsb,pUsb->Prio); //將該任務(wù)從等待隊(duì)列中刪除
if (pUsb->bSuspend[pUsb->Prio] == 1)
OSTaskResume(pUsb->Prio);
else
OSTimeDlyResume(pUsb->Prio); //使該任務(wù)就緒
}else
return;
}
}
else
return;
if (pUsb->Grp != 0){ //還有任務(wù)在等待發(fā)送數(shù)據(jù)
if (pUsb->Sem == 0){ //該發(fā)送端點(diǎn)可以使用
pUsb->Prio = USB_GetHighPrio(pUsb);
pUsb->Cnt = 0; //發(fā)送計(jì)數(shù)清0
pUsb->Sem = 1; //使該任務(wù)獨(dú)占該發(fā)送資源
}
pBuff = pUsb->pBuff[pUsb->Prio]; //得到發(fā)送緩沖區(qū)指針
for (i = 0; i < buffnums; i++){
endpstatus = D12_ReadEndpointStatus(endp) & 0x60;
if (endpstatus == 0x60) break; //如果緩沖區(qū)全部都滿,那么不可以再寫入
len = pUsb->Max[pUsb->Prio] - pUsb->Cnt;
if (len > 0){ //有空的緩沖區(qū)而且等待發(fā)送字節(jié)數(shù)大于0
if (len >= eppsize) //寫滿緩沖區(qū)
len = D12_WriteEndpoint(endp,(INT8U)eppsize,pBuff + pUsb->Cnt);
else //寫len個(gè)字節(jié)
len = D12_WriteEndpoint(endp,(INT8U)len,pBuff + pUsb->Cnt);
pUsb->Cnt = pUsb->Cnt + len; //發(fā)送計(jì)數(shù)器加上實(shí)際上發(fā)送的字節(jié)
}//end of if (len > 0)
}//end of for()
}//end of if (pUsb->Grp != 0)
}
/**********************************************************************************
** 函數(shù)名稱: INT8U USB_ReadPort(INT8U endp,CTRL_USB *pUsb,INT32U len,INT8U *recbuff,INT16U timeout)
** 功能描述: 讀端點(diǎn)函數(shù)
** 輸 入: INT8U endp: 端點(diǎn)索引號(hào)
CTRL_USB *pUsb: USB 接收與發(fā)送控制塊指針
INT32U len: 接收字節(jié)個(gè)數(shù)
INT8U *recbuff: 接收緩沖區(qū)
INT16U timeout: 等待超時(shí)時(shí)間
** 輸 出: 0: 讀成功 > 0 讀失敗(錯(cuò)誤碼)
**********************************************************************************/
INT8U USB_ReadPort(INT8U endp, INT32U eppsize, INT8U buffnums, CTRL_USB *pUsb, INT32U len, INT8U *recbuff, INT16U timeout)
{
INT8U err,i,endpstatus;
INT32U length;
INT8U *pbuf;
OS_ENTER_CRITICAL();
err = USB_RW_Param(pUsb, len, recbuff); //填寫USB接收或發(fā)送控制塊參數(shù)
if (err != USB_NO_ERR)
{
OS_EXIT_CRITICAL();
return err;
}
/*** 如果端點(diǎn)接收緩沖區(qū)已經(jīng)有數(shù)據(jù), 執(zhí)行下面的程序 ****/
if ((pUsb->Sem == 0) && (pUsb->NoTask == 1) && (pUsb->Grp != 0))
{ //接收緩沖區(qū)中有數(shù)據(jù)
pUsb->Sem = 1; //獨(dú)占該端點(diǎn)
pUsb->Cnt = 0; //發(fā)送計(jì)數(shù)值清0
pUsb->Prio = USB_GetHighPrio(pUsb); //保存該任務(wù)優(yōu)先級(jí)
pbuf = pUsb->pBuff[pUsb->Prio];
for (i = 0; i < buffnums; i++){
length = pUsb->Max[pUsb->Prio] - pUsb->Cnt; //計(jì)算未發(fā)送字節(jié)個(gè)數(shù)
if (length > 0){ //未發(fā)送字節(jié)數(shù)大于0
if (length >= eppsize) //寫滿緩沖區(qū)
length = D12_ReadEndpoint(endp,(INT8U)eppsize,pbuf + pUsb->Cnt);
else //寫length個(gè)字節(jié)
length = D12_ReadEndpoint(endp,(INT8U)length,pbuf + pUsb->Cnt);
pUsb->Cnt = pUsb->Cnt + length; //發(fā)送計(jì)數(shù)器加length
}
if (pUsb->Cnt >= pUsb->Max[pUsb->Prio]){
pUsb->Max[pUsb->Prio] = 0;
pUsb->Sem = 0;
USB_DelPrio(pUsb, pUsb->Prio);
break;
}
endpstatus = D12_ReadEndpointStatus(endp); //讀該端點(diǎn)狀態(tài)寄存器
if ((endpstatus & 0x60) == 0)
break; //如果緩沖為空,立即跳出循環(huán)
}
pUsb->NoTask = 0;
}//end of if (pUsb->Sem == 0)
OS_EXIT_CRITICAL();
OS_ENTER_CRITICAL();
if (pUsb->Max[OSPrioCur] != 0){ //如果還沒接收完成
if (timeout != 0){
pUsb->bSuspend[OSPrioCur] = 0;
OSTimeDly(timeout); //定義超時(shí)等待
}
else{
pUsb->bSuspend[OSPrioCur] = 1; //置位掛起標(biāo)志
OSTaskSuspend(OSPrioCur);
}
}
OS_EXIT_CRITICAL(); //已接收完成,開中斷
return (USB_RW_Result(endp,pUsb,timeout)); //返回接收結(jié)果
}
/*****************************************************************
** 函數(shù)名稱: INT8U USB_WritePort(INT8U endp,INT32U eppsize,INT8U buffnums,CTRL_USB *pUsb,
INT8U *sendbuff,INT32U len,INT16U timeout)
** 功能描述:
** 輸 入: INT8U endp : 端點(diǎn)索引號(hào)
INT32U eppsize : 該端點(diǎn)的的信息包大小
INT8U buffnums : 該端點(diǎn)發(fā)送緩沖區(qū)個(gè)數(shù)
CTRL_USB *pUsb : 該端點(diǎn)的接收或發(fā)送控制塊指針
INT8U *sendbuff : 發(fā)送數(shù)據(jù)字節(jié)指針
INT32U len : 發(fā)送數(shù)據(jù)字節(jié)長(zhǎng)度
INT16U timeout : 等待超時(shí)時(shí)間
** 輸 出: 0 發(fā)送成功 > 0 發(fā)送失敗(錯(cuò)誤碼)
******************************************************************/
INT8U USB_WritePort(INT8U endp,INT32U eppsize,INT8U buffnums,CTRL_USB *pUsb,
INT8U *sendbuff,INT32U len,INT16U timeout)
{
INT8U err,i;
INT32U length;
OS_ENTER_CRITICAL();
err = USB_RW_Param(pUsb,len,sendbuff); //填寫USB接收或發(fā)送控制塊參數(shù)
if (err != USB_NO_ERR)
{
OS_EXIT_CRITICAL();
return err;
}
if (pUsb->Sem == 0){ //該端點(diǎn)沒有被獨(dú)占
pUsb->Sem = 1; //獨(dú)占該端點(diǎn)
pUsb->Cnt = 0; //發(fā)送計(jì)數(shù)值清0
pUsb->Prio = OSPrioCur; //保存獨(dú)占該端點(diǎn)的任務(wù)優(yōu)先級(jí)
for (i = 0; i < buffnums; i++){
length = pUsb->Max[pUsb->Prio] - pUsb->Cnt; //計(jì)算未發(fā)送字節(jié)個(gè)數(shù)
if (length > 0){ //未發(fā)送字節(jié)數(shù)大于0
if (length >= eppsize) //寫滿緩沖區(qū)
length = D12_WriteEndpoint(endp,(INT8U)eppsize,sendbuff + pUsb->Cnt);
else //寫length個(gè)字節(jié)
length = D12_WriteEndpoint(endp,(INT8U)length,sendbuff + pUsb->Cnt);
pUsb->Cnt = pUsb->Cnt + length; //發(fā)送計(jì)數(shù)器加length
}
}
}//end of if (pUsb->Sem == 0)
OS_EXIT_CRITICAL();
OS_ENTER_CRITICAL();
if (pUsb->Max[OSPrioCur] != 0){ //還未發(fā)送完成
if (timeout != 0){
pUsb->bSuspend[OSPrioCur] = 0;
OSTimeDly(timeout); //定義超時(shí)等待
}
else{
pUsb->bSuspend[OSPrioCur] = 1;
OSTaskSuspend(OSPrioCur); //置位掛起標(biāo)志
}
}
OS_EXIT_CRITICAL(); //發(fā)送完成
return (USB_RW_Result(endp,pUsb,timeout)); //返回發(fā)送結(jié)果
}
/*****************************************************************
** 函數(shù)名稱: INT8U USB_RW_Param(CTRL_USB *pUsb,INT32U len,INT8U *buff)
** 功能描述: 填寫USB接收或發(fā)送控制塊有關(guān)參數(shù)
** 輸 入: CTRL_USB *pUsb : USB接收或發(fā)送控制塊指針
INT32U len : 接收或發(fā)送字節(jié)數(shù)
INT8U *buff : 接收或發(fā)送緩沖區(qū)指針
** 輸 出: 0 調(diào)用成功 > 0 調(diào)用失敗(錯(cuò)誤碼)
******************************************************************/
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總線未配置錯(cuò)誤
}
if (pbuff == 0){
OS_EXIT_CRITICAL();
return (USB_ERR_BUFF_INVALID); //緩沖區(qū)指針無(wú)效錯(cuò)誤
}
pUsb->pBuff[OSPrioCur] = pbuff; //保存該任務(wù)的接收緩沖區(qū)首址
pUsb->Max[OSPrioCur] = len; //保存要收發(fā)的字節(jié)數(shù)
USB_InsertPrio(pUsb,OSPrioCur); //插入等待任務(wù)列表中
OS_EXIT_CRITICAL();
return (USB_NO_ERR);
}
/*****************************************************************
** 函數(shù)名稱: INT8U USB_RW_Result(INT8U endp,CTRL_USB *pUsb,INT16U timeout)
** 功能描述: 判斷當(dāng)前任務(wù)的數(shù)據(jù)是否收發(fā)成功
** 輸 入: INT8U endp : 端點(diǎn)索引號(hào)
CTRL_USB *pUsb : USB接收或發(fā)送控制塊指針
INT16U timeout : 超過(guò)等待時(shí)間
** 輸 出: 0 收發(fā)成功 > 0 收發(fā)失敗(錯(cuò)誤碼)
******************************************************************/
INT8U USB_RW_Result(INT8U endp,CTRL_USB *pUsb,INT16U timeout)
{
OS_ENTER_CRITICAL();
if (pUsb->Max[OSPrioCur] != 0){ //收發(fā)完成標(biāo)志不為0,說(shuō)明收發(fā)錯(cuò)誤
if (pUsb->Prio == OSPrioCur){ //該任務(wù)占用了端點(diǎn)的收發(fā)資源
pUsb->Sem = 0; //必須釋放資源
D12_ClearBuff(endp); //清空收發(fā)緩沖區(qū)
}
USB_DelPrio(pUsb,OSPrioCur); //將該任務(wù)從等待列表中刪除
OS_EXIT_CRITICAL();
return (USB_ERR_WR_TIMEOUT); //收發(fā)超時(shí)錯(cuò)誤
}else{
OS_EXIT_CRITICAL();
return (USB_NO_ERR); //收發(fā)成功
}
}
/************************************************************
下面的函數(shù)操作 USB接收或發(fā)送控制塊等待列表
*************************************************************/
/************************************************************
** 函數(shù)名稱: void USB_DelPrio(CTRL_USB *pUsb,INT8U prio)
** 功能描述: 將一任務(wù)從USB接收或發(fā)送控制塊等待列表中刪除
** 輸 入: CTRL_USB *pUsb: USB接收或發(fā)送控制塊指針
INT8U prio: 刪除的任務(wù)的優(yōu)先級(jí)
** 輸 出: 無(wú)
************************************************************/
void USB_DelPrio(CTRL_USB *pUsb,INT8U prio)
{
if ((pUsb -> Tbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)
pUsb -> Grp &= ~OSMapTbl[prio >> 3];
}
/************************************************************
** 函數(shù)名稱: void USB_InsertPrio(CTRL_USB *pUsb,INT8U prio)
** 功能描述: 將一任務(wù)插入到USB接收或發(fā)送控制塊等待列表中
** 輸 入: CTRL_USB *pUsb: USB接收或發(fā)送控制塊指針
INT8U prio: 插入任務(wù)的優(yōu)先級(jí)
** 輸 出: 無(wú)
************************************************************/
void USB_InsertPrio(CTRL_USB *pUsb,INT8U prio)
{
pUsb -> Grp |= OSMapTbl[prio >> 3];
pUsb -> Tbl[prio >> 3] |= OSMapTbl[prio & 0x07];
}
/*********************************************************************
** 函數(shù)名稱: INT8U USB_GetHighPrio(CTRL_USB *pUsb)
** 功能描述: 取得USB接收或發(fā)送控制塊等待列表中優(yōu)先級(jí)最高的任務(wù)優(yōu)先級(jí)
** 輸 入: CTRL_USB *pUsb: USB 接收或發(fā)送控制塊指針
** 輸 出: 等待列表中優(yōu)先級(jí)最高的任務(wù)優(yōu)先級(jí)
**********************************************************************/
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;
}
/*********************************************************************
** 函數(shù)名稱: INT16U USB_Get_ZLGUSBD12_Ver()
** 功能描述: 取得 ZLG/USBD12 軟件包的固件版本號(hào)
** 輸 入: NULL
** 輸 出: 固件版本號(hào)
**********************************************************************/
INT16U USB_Get_ZLGUSBD12_Ver(void)
{
return 0x0150; //當(dāng)前固件軟件版本號(hào)為1.50
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -