📄 hcd.c
字号:
** phcdFreeTd 要释放的TD
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __hcdFreeTd (__PED_INFO pEdInfo, __PHC_GEN_TRANSFER_DESCRIPTOR phcdFreeTd)
{
USB_INT32U i ,j;
if (phcdFreeTd == NULL) {
return;
}
OS_ENTER_CRITICAL();
i = phcdFreeTd - pEdInfo->pTdHead; /* 要回收的TD的序号 */
j = i / 32; /* 要收回的TD的状态位在状态 */
/* 数组中的下标 */
*(pEdInfo->puiTdSts + j) &= ~(1 << (i - j * 32)); /* 在该下标元素中的位序号 */
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** Function name: __hcdFreeAllTd
** Descriptions: 释放所有 TD
** input parameters: pEdInfo 要释放的TD所属ED的信息结构体
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __hcdFreeAllTd (__PED_INFO pEdInfo)
{
USB_INT32U i;
OS_ENTER_CRITICAL();
for (i = 0; i < (pEdInfo->uiMaxTd +31) / 32; i++) {
*(pEdInfo->puiTdSts + i) = 0;
}
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** Function name: __hcdAddTd
** Descriptions: 在目标 ED 上添加 TD,目标 ED 由 pGenTdParam->ucType 指定
** input parameters: pGenTdParam: TD 的参数
** ptdAddTd 要增加的TD
** pEdInfo ED信息结构体
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL __hcdAddTd (__PHC_GEN_TD_PARAM pGenTdParam,
__PHC_GEN_TRANSFER_DESCRIPTOR ptdAddTd,
__PED_INFO pEdInfo)
{
USB_INT32U *puiHeap;
USB_INT32U i;
__PHC_GEN_TRANSFER_DESCRIPTOR ptdInsert = NULL;
/*
* 配置 TD 参数
*/
ptdAddTd->uiControl = (pGenTdParam->ucDataToggle << 24) |
(pGenTdParam->ucDelayIntr << 21) |
(pGenTdParam->ucDirect_PID << 19) |
(pGenTdParam->ucBufferRound << 18);
ptdAddTd->pucCBP = pGenTdParam->pucCBP;
if (pGenTdParam->usBufLen != 0) {
ptdAddTd->pucBufEnd = pGenTdParam->pucCBP + pGenTdParam->usBufLen - 1;
} else {
pGenTdParam->pucCBP = NULL;
ptdAddTd->pucBufEnd = ptdAddTd->pucCBP;
}
/*
* 将TD插入ED.如果该ED为空,则直接将TD插入ED的TD List
* 否则将TD插入该ED的尾部
*/
OS_ENTER_CRITICAL();
if (((USB_INT32U)(pEdInfo->pEd->ptdHeadP) & 0xFFFFFFF0) == \
((USB_INT32U)(pEdInfo->pEd->ptdTailP) & 0xFFFFFFF0)) {
/* 如果为空ED,则直接将TD插入ED */
puiHeap = (USB_INT32U *)&(pEdInfo->pEd->ptdHeadP);
i = *puiHeap;
pEdInfo->pEd->ptdHeadP = ptdAddTd;
*puiHeap |= i & 0x02;
} else { /* 该 ED 已经含有 TD */
ptdInsert = (__PHC_GEN_TRANSFER_DESCRIPTOR)((USB_INT32U)(pEdInfo->pEd->ptdHeadP) & 0xFFFFFFF0);
while (((USB_INT32U)ptdInsert->ptdNextTD & 0xFFFFFFF0) != /* 寻找最后一个 TD */
((USB_INT32U)pEdInfo->pEd->ptdTailP & 0xFFFFFFF0)) {
ptdInsert = (__PHC_GEN_TRANSFER_DESCRIPTOR)((USB_INT32U)ptdInsert->ptdNextTD & 0xFFFFFFF0);
}
ptdInsert->ptdNextTD = ptdAddTd;
}
ptdAddTd->ptdNextTD = pEdInfo->pEd->ptdTailP;
if (pEdInfo->ucTranType == USB_TRAN_TYPE_CONTROL) {
__GsTranEndTd.pCtrlEndTd = ptdAddTd;
} else {
__GsTranEndTd.pDataEndTd = ptdAddTd;
}
OS_EXIT_CRITICAL();
return TRUE;
}
/*********************************************************************************************************
** Function name: __hcdGetEdPtr
** Descriptions: 获取 ED 首地址
** input parameters: ucTranType 传输类型
** output parameters: None
** Returned value: ED 首地址
*********************************************************************************************************/
__PHC_ENDPOINT_DESCRIPTOR __hcdGetEdPtr (USB_INT8U ucTranType)
{
__PHC_ENDPOINT_DESCRIPTOR pedEd;
switch (ucTranType) {
case USB_TRAN_TYPE_CONTROL: /* Control 端点 */
pedEd = &(__GpohciEd->edsControl);
break;
case USB_TRAN_TYPE_BULK_OUT: /* Bulk Out 端点 */
pedEd = &(__GpohciEd->edsBulkOut);
break;
case USB_TRAN_TYPE_BULK_IN: /* Bulk In 端点 */
pedEd = &(__GpohciEd->edsBulkIn);
break;
case USB_TRAN_TYPE_INTR_OUT: /* Intrrupt Out 端点 */
pedEd = &(__GpohciEd->edsIntrOut);
break;
case USB_TRAN_TYPE_INTR_IN: /* Intrrupt In 端点 */
pedEd = &(__GpohciEd->edsIntrIn);
break;
default:
pedEd = NULL;
break;
}
return pedEd;
}
/*********************************************************************************************************
** Function name: __usbEdSetSkipAndWaitNextFrame
** Descriptions: 设置ED中的skip位并等待下一帧开始
** input parameters: ucType : 类型: 控制传输, 块传输, 中断传输, 同步传输
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL __usbEdSetSkipAndWaitNextFrame (USB_INT8U ucType)
{
__PHC_ENDPOINT_DESCRIPTOR pedEd;
pedEd = __hcdGetEdPtr(ucType); /* 获取端点描述符首地址 */
pedEd->uiControl |= 1 << 14; /* 设置 sKip = 1 */
__hcWaitNextFrame(); /* 等待下一帧 */
return TRUE;
}
/*********************************************************************************************************
** Function name: __usbEdSetSkipAndWaitNextFrame
** Descriptions: 设置ED中的skip位并等待下一帧开始
** input parameters: ucType : 类型: 控制传输, 块传输, 中断传输, 同步传输
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL __usbEdClearSkip (USB_INT8U ucType)
{
__PHC_ENDPOINT_DESCRIPTOR pedEd;
pedEd = __hcdGetEdPtr(ucType);
pedEd->uiControl &= ~(1 << 14);
return TRUE;
}
/*********************************************************************************************************
** Function name: __hcdIsEdHeadEquTail
** Descriptions: 判断 ED 中的 HeadP 是否等于 TailP
** input parameters: ED的信息结构体
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL __hcdIsEdHeadEquTail (__PED_INFO pEdInfo)
{
USB_INT32U uiTmp1, uiTmp2;
uiTmp1 = (USB_INT32U)pEdInfo->pEd->ptdHeadP;
uiTmp2 = (USB_INT32U)pEdInfo->pEd->ptdTailP;
if ((uiTmp1 & ~0x0F) == (uiTmp2 & ~0x0F)) {
return TRUE;
} else {
return FALSE;
}
}
/*********************************************************************************************************
** Function name: __hcdEdLetHeadEquTail
** Descriptions: 强制使 ED 中的 HeadP 等于 TailP, 这在传输出现错误时调用
** input parameters: ED的信息结构体
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __hcdEdLetHeadEquTail (__PED_INFO pEdInfo)
{
USB_INT32U uiTmp;
USB_INT32U *puiHeadp;
__usbEdSetSkipAndWaitNextFrame(pEdInfo->ucTranType);
OS_ENTER_CRITICAL();
puiHeadp = (USB_INT32U *)&(pEdInfo->pEd->ptdHeadP);
uiTmp = *puiHeadp;
pEdInfo->pEd->ptdHeadP = pEdInfo->pEd->ptdTailP;
*puiHeadp |= uiTmp & 0x02; /* 保留 ToggleCarry 位 */
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** Function name: __hcdEnableEd
** Descriptions: 使能ED
** input parameters: ucEdType: ED 类型
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL __hcdEnableEd (USB_INT8U ucEdType)
{
__PHC_ENDPOINT_DESCRIPTOR pedEd = __hcdGetEdPtr(ucEdType);
if (pedEd) {
pedEd->uiControl &= ~(1 << 14);
}
return TRUE;
}
/*********************************************************************************************************
HC管理部分
*********************************************************************************************************/
const __POHCI_REG volatile __GpsOhciReg = (const __POHCI_REG)OHCI_REG_BASE_ADDR;
/* OHCI 寄存器地址 */
/*********************************************************************************************************
** Function name: __ohciInit
** Descriptions: OHCI初始化,系统初始化时调用
** input parameters: None
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL __ohciInit (void)
{
USB_INT8U i;
USB_INT32U uiTmp = 0x0000ffff;
__GpsOhciReg->uiHcControl = 0; /* 复位 */
OSTimeDly(1);
__GpsOhciReg->uiHcCommandStatus = 0x01; /* 复位 HC */
while ((__GpsOhciReg->uiHcCommandStatus & 0x01) && --uiTmp);
if (uiTmp == 0) {
return FALSE;
}
uiTmp = __GpsOhciReg->uiHcRevision; /* 读取HC版本号 */
if ( (uiTmp & 0xFF) != 0x10) {
return( FALSE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -