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

📄 hcd.c

📁 smartARM2400 USB host例程
💻 C
📖 第 1 页 / 共 4 页
字号:
/*****************************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 + -