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

📄 hcd.c

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