📄 hcd.c
字号:
/*****************************Copyright(c)****************************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**------File Info-----------------------------------------------------------------------------------------
** File Name: hcd.c
** Latest modified Date: 2007-11-06
** Latest Version: V1.0
** Description: HCD层驱动
**
**--------------------------------------------------------------------------------------------------------
** Created By: 吴隆穗 Longsui Wu
** Created date: 2007-11-06
** Version: V1.0
** Descriptions: 初始版本
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
*********************************************************************************************************/
#include "USBHostConfig.h"
/*********************************************************************************************************
HCD层,主要包括以下几个部分:
1. 链表管理部分,包括ED和ED链表管理,TD和TD链表管理
2. HC管理部分
3. 根集线器管理部分
4. USB RAM管理部分
*********************************************************************************************************/
/*********************************************************************************************************
链表管理部分,包括ED和ED链表管理,TD和TD链表管理
*********************************************************************************************************/
__POHCI_ED __GpohciEd;
__POHCI_TD __GpohciTd;
__OHCI_TD_STAT __GohciTdStat;
__TRAN_END_TD __GsTranEndTd;
volatile USB_INT8U __GucUsbSpeed = 0; /* 设备速度,全速(0)或低速(1) */
volatile USB_INT8U __GucUsbDevAddr = 0; /* 设备地址 */
void __hcdAllocBufferInit (void);
/*********************************************************************************************************
** Function name: __hcdEdInit
** Descriptions: 初始化各 ED
** input parameters: None
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __hcdEdInit (void)
{
__GpohciEd = (__POHCI_ED)__OHCI_ED_BASE_ADDR;
__GpohciEd->edsControl.uiControl = (8 << 16) | (1 << 14) | (__GucUsbSpeed << 13);
__GpohciEd->edsControl.pedNextED = NULL;
__GpohciEd->edsControl.ptdHeadP = NULL;
__GpohciEd->edsControl.ptdTailP = NULL;
__GpohciEd->edsBulkOut.uiControl = (8 << 16) | (1 << 14);
__GpohciEd->edsBulkOut.pedNextED = &(__GpohciEd->edsBulkIn);
__GpohciEd->edsBulkOut.ptdHeadP = NULL;
__GpohciEd->edsBulkOut.ptdTailP = NULL;
__GpohciEd->edsBulkIn.uiControl = (8 << 16) | (1 << 14);
__GpohciEd->edsBulkIn.pedNextED = NULL;
__GpohciEd->edsBulkIn.ptdHeadP = NULL;
__GpohciEd->edsBulkIn.ptdTailP = NULL;
__GpohciEd->edsIntrOut.uiControl = (8 << 16) | (1 << 14);
__GpohciEd->edsIntrOut.pedNextED = (__PHC_ENDPOINT_DESCRIPTOR)&(__GpohciEd->edsIntrIn);
__GpohciEd->edsIntrOut.ptdHeadP = NULL;
__GpohciEd->edsIntrOut.ptdTailP = NULL;
__GpohciEd->edsIntrIn.uiControl = (8 << 16) | (1 << 14);
__GpohciEd->edsIntrIn.pedNextED = (__PHC_ENDPOINT_DESCRIPTOR)&(__GpohciEd->edsIso);
__GpohciEd->edsIntrIn.ptdHeadP = NULL;
__GpohciEd->edsIntrIn.ptdTailP = NULL;
__GpohciEd->edsIso.uiControl = (__HC_ISO_MAXPACKETSIZE << 16) | (3 << 7) | (1 << 14) | (1 << 15);
__GpohciEd->edsIso.pedNextED = NULL;
__GpohciEd->edsIso.ptdHeadP = NULL;
__GpohciEd->edsIso.ptdTailP = NULL;
}
/*********************************************************************************************************
** Function name: __hcdTdInit
** Descriptions: TD 初始化
** input parameters: None
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __hcdTdInit (void)
{
__GpohciTd = (__POHCI_TD)__OHCI_TD_BASE_ADDR;
usbMemSet(&__GohciTdStat, 0, sizeof(__GohciTdStat)); /* 清除所有TD使用标志 */
usbMemSet(__GpohciTd, 0, sizeof(__OHCI_TD)); /* 清零所有TD */
}
/*********************************************************************************************************
** Function name: __hcdInit
** Descriptions: HCD层的软件环境初始化
** input parameters: None
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void __hcdInit (void)
{
__hcdAllocBufferInit();
__hcdTdInit();
__hcdEdInit();
}
/*********************************************************************************************************
** Function name: __hcdGetEdInfo
** Descriptions: 获取ED的相关信息
** input parameters: ucTranType 传输类型
** output parameters: pedInfo 获取到的信息
** Returned value: None
*********************************************************************************************************/
void __hcdGetEdInfo (USB_INT8U ucTranType, __PED_INFO pedInfo)
{
pedInfo->ucTranType = ucTranType;
switch (ucTranType) {
case USB_TRAN_TYPE_CONTROL:
pedInfo->pEd = &__GpohciEd->edsControl;
pedInfo->pTdHead = &(__GpohciTd->tdCtrlTd[0]);
pedInfo->puiTdSts = (volatile USB_INT32 *)&__GohciTdStat.uiCtrlTdStatus[0];
pedInfo->uiMaxTd = USB_MAX_CTRL_TD;
pedInfo->usMaxPktSize = (USB_INT16U)((pedInfo->pEd->uiControl >> 16) & 0x7FF);
break;
case USB_TRAN_TYPE_BULK_OUT:
pedInfo->pEd = &__GpohciEd->edsBulkOut;
pedInfo->pTdHead = &(__GpohciTd->tdBulkOutTd[0]);
pedInfo->puiTdSts = (volatile USB_INT32 *)&__GohciTdStat.uiBulkOutTdStatus[0];
pedInfo->uiMaxTd = USB_MAX_BULKOUT_TD;
pedInfo->usMaxPktSize = (USB_INT16U)((pedInfo->pEd->uiControl >> 16) & 0x7FF);
break;
case USB_TRAN_TYPE_BULK_IN:
pedInfo->pEd = &__GpohciEd->edsBulkIn;
pedInfo->pTdHead = &(__GpohciTd->tdBulkInTd[0]);
pedInfo->puiTdSts = (volatile USB_INT32 *)&__GohciTdStat.uiBulkInTdStatus[0];
pedInfo->uiMaxTd = USB_MAX_BULKIN_TD;
pedInfo->usMaxPktSize = (USB_INT16U)((pedInfo->pEd->uiControl >> 16) & 0x7FF);
break;
case USB_TRAN_TYPE_INTR_OUT:
pedInfo->pEd = &__GpohciEd->edsIntrOut;
pedInfo->pTdHead = &(__GpohciTd->tdIntrOutTd[0]);
pedInfo->puiTdSts = (volatile USB_INT32 *)&__GohciTdStat.uiIntrOutTdStatus[0];
pedInfo->uiMaxTd = USB_MAX_INTROUT_TD;
pedInfo->usMaxPktSize = (USB_INT16U)((pedInfo->pEd->uiControl >> 16) & 0x7FF);
break;
case USB_TRAN_TYPE_INTR_IN:
pedInfo->pEd = &__GpohciEd->edsIntrIn;
pedInfo->pTdHead = &(__GpohciTd->tdIntrInTd[0]);
pedInfo->puiTdSts = (volatile USB_INT32 *)&__GohciTdStat.uiIntrInTdStatus[0];
pedInfo->uiMaxTd = USB_MAX_INTRIN_TD;
pedInfo->usMaxPktSize = (USB_INT16U)((pedInfo->pEd->uiControl >> 16) & 0x7FF);
break;
default:
pedInfo = NULL;
}
}
/*********************************************************************************************************
** Function name: __hcdGetTdType
** Descriptions: 根据TD的地址获取TD的类型
** input parameters: tdTd: TD指针,即TD地址
** output parameters: None
** Returned value: None
*********************************************************************************************************/
USB_INT8U __hcdGetTdType (__PHC_GEN_TRANSFER_DESCRIPTOR ptdTd)
{
USB_INT8U ucType;
USB_INT32U uiTmp = (USB_INT32U)ptdTd;
if ((uiTmp >= __OHCI_TD_CTRL_BASE_ADDR) && (uiTmp <= __OHCI_TD_CTRL_END_ADDR)) {
ucType = USB_TRAN_TYPE_CONTROL;
} else if ((uiTmp >= __OHCI_TD_BULKOUT_BASE_ADDR) && (uiTmp <= __OHCI_TD_BULKOUT_END_ADDR)) {
ucType = USB_TRAN_TYPE_BULK_OUT;
} else if ((uiTmp >= __OHCI_TD_BULKIN_BASE_ADDR) && (uiTmp <= __OHCI_TD_BULKIN_END_ADDR)) {
ucType = USB_TRAN_TYPE_BULK_IN;
} else if ((uiTmp >= __OHCI_TD_INTROUT_BASE_ADDR) && (uiTmp <= __OHCI_TD_INTROUT_END_ADDR)) {
ucType = USB_TRAN_TYPE_INTR_OUT;
} else if ((uiTmp >= __OHCI_TD_INTRIN_BASE_ADDR) && (uiTmp <= __OHCI_TD_INTRIN_END_ADDR)) {
ucType = USB_TRAN_TYPE_INTR_IN;
} else {
ucType = 0xff;
}
return ucType;
}
/*********************************************************************************************************
** Function name: __hcdAllocTd
** Descriptions: 申请空闲 TD
** input parameters: pEdInfo: TD所属ED的信息结构体
** output parameters: None
** Returned value: 申请到的 TD 首地址,若申请失败,则返回 NULL
*********************************************************************************************************/
__PHC_GEN_TRANSFER_DESCRIPTOR __hcdAllocTd (__PED_INFO pEdInfo)
{
USB_INT32U i, j;
USB_INT32U uiTdIndex;
__PHC_GEN_TRANSFER_DESCRIPTOR phcdAllocTd;
if (pEdInfo == NULL) {
return NULL;
}
phcdAllocTd = NULL;
OS_ENTER_CRITICAL();
do {
for (i = 0; i < (pEdInfo->uiMaxTd +31) / 32; i++) { /* 查找可利用的空闲TD所在的字段*/
if (*(pEdInfo->puiTdSts + i) != 0xFFFFFFFF) {
break;
}
}
if (i >= (pEdInfo->uiMaxTd +31) / 32) { /* 无空闲TD */
break;
}
for (j = 0; j < 32; j++) {
if ((*(pEdInfo->puiTdSts + i) & (0x01U << j)) == 0) { /* 查找到第一个TD,则跳出 */
break;
}
}
uiTdIndex = i * 32 + j;
if (uiTdIndex >= pEdInfo->uiMaxTd) { /* 得到的TD序号大于等于最大TD号*/
break; /* 说明该TD号无效,跳出do..while*/
} else {
*(pEdInfo->puiTdSts + i) |= 1U << j;
phcdAllocTd = pEdInfo->pTdHead + uiTdIndex;
}
} while (0);
OS_EXIT_CRITICAL();
#if 0
if (phcdAllocTd != NULL) {
usbMemSet(phcdAllocTd, 0, sizeof(__PHC_GEN_TRANSFER_DESCRIPTOR));
}
#endif
return phcdAllocTd;
}
/*********************************************************************************************************
** Function name: __hcdFreeTd
** Descriptions: 释放一个 TD
** input parameters: pEdInfo 要释放的TD所属ED的信息结构体
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -