📄 usbd.c
字号:
/*****************************Copyright(c)****************************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**------File Info-----------------------------------------------------------------------------------------
** File Name: usbd.c
** Latest modified Date: 2007-11-15
** Latest Version: V1.0
** Description: USBD层的实现
**
**--------------------------------------------------------------------------------------------------------
** Created By: 吴隆穗 Longsui Wu
** Created date: 2007-11-15
** Version: V1.0
** Descriptions: 初始版本
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
*********************************************************************************************************/
#include "USBHostConfig.h"
USB_DEVICE_DESCRIPTOR GusbDeviceDescr; /* 设备描述符 */
USB_CONFIGURATION_DESCRIPTOR GusbConfigDescr; /* 配置描述符 */
USB_OTG_DESCRIPTOR GusbOtgDescr;
__USB_INTERFACE_EP_DESCR GusbInterEpDescr[__USB_MAX_INTERFACE]; /* 配置描述符:接口描述符及该 */
/* ...接口所具有的端点的描述符 */
USB_INT16U __GusEpMaxPktSize[__USB_MAX_INTERFACE][32] = {0};
volatile __USB_HOST_FLAGS GusbHostFlags; /* 标志位 */
__USB_HOST_EVENT_CNT __GusbHostEvtCnt;
INT8U __GucHostShedPrio = 0;
INT8U __GucHostEnumPrio = 0;
void (*__GpEnumSucessCallBack)(void) = NULL; /* 枚举成功时回调函数 */
void (*__GpDevDisconCallBack)(void) = NULL; /* 设备拨出时回调函数 */
void __usbdInit (void (*pEnumSucessCallBack)(void), void (*pDevDisconCallBack)(void));
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************************************************
** Function name: usbHostInitialize
** Descriptions: USB 主机初始化
** input parameters: ucShedPrio 调度任务的优先级
** ucEnumPrio 枚举任务的优先级
** pEnumSucessCallBack: 枚举成功回调函数,若没有则设置为NULL
** pDevDisconCallBack: 设备拨出回调函数,若没有则设置为NULL
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL usbHostInitialize (USB_INT8U ucShedPrio,
USB_INT8U ucEnumPrio,
void (*pEnumSucessCallBack)(void),
void (*pDevDisconCallBack)(void))
{
__usbdInit(pEnumSucessCallBack, pDevDisconCallBack);
if (!__usbShedInit()) {
return FALSE;
}
__hcdInit();
__usbInitHardware();
__usbHostIntInit();
__ohciInit();
if (!__usbCreateShedTask(ucShedPrio, ucEnumPrio)) { /* 创建调度任务 */
__GucHostShedPrio = 0;
__GucHostEnumPrio = 0;
return FALSE;
}
OS_ENTER_CRITICAL();
__GucHostShedPrio = ucShedPrio;
__GucHostEnumPrio = ucEnumPrio;
OS_EXIT_CRITICAL();
return TRUE;
}
/*********************************************************************************************************
** Function name: usbHostDeInit
** Descriptions: USB 主机卸载
** input parameters: None
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL usbHostDeInit (void)
{
USB_INT8U ucErr;
USB_INT32U i;
OS_TCB *ptcb = NULL;
USBDEBUG_SENDSTR("\r\nusbHostDeInit...\r\n");
OS_ENTER_CRITICAL();
GusbHostFlags.bExitDataOperaReq = TRUE;
GusbHostFlags.bExitStdOperaReq = TRUE;
OS_EXIT_CRITICAL();
/*
* 等待没有任务任务操作USB总线
*/
i = 0;
while (__GusbHostEvtCnt.ucDataTranCnt || __GusbHostEvtCnt.ucStdTranCnt) {
OSTimeDly(2);
if (i++ > 1000) { /* 等待10S */
return FALSE;
}
}
__ohciPortClose(USB_HOST_PORT);
OS_ENTER_CRITICAL();
GusbHostFlags.ucEnumed = 0;
GusbHostFlags.ucConfiged = 0;
GusbHostFlags.ucAttached = 0;
GusbHostFlags.ucCtrlPipe = 0;
GusbHostFlags.ucBulkOutPipe = 0;
GusbHostFlags.ucBulkInPipe = 0;
GusbHostFlags.ucIntrOutPipe = 0;
GusbHostFlags.ucIntrInPipe = 0;
OS_EXIT_CRITICAL();
#if 0
usbPipeClose(USB_TRAN_TYPE_CONTROL);
usbPipeClose(USB_TRAN_TYPE_INTR_OUT);
usbPipeClose(USB_TRAN_TYPE_INTR_IN);
usbPipeClose(USB_TRAN_TYPE_BULK_OUT);
usbPipeClose(USB_TRAN_TYPE_BULK_IN);
#endif
/*
* 查看枚举任务是否存在,若存在,则删除该任务
*/
if (__GucHostEnumPrio) {
ptcb = OSTCBPrioTbl[__GucHostEnumPrio]; /* 查询枚举任务是否已经存在 */
if (ptcb != NULL) { /* 删除枚举任务 */
OSTaskDel(__GucHostEnumPrio);
while (OSTCBPrioTbl[__GucHostEnumPrio] != NULL) {
OSTimeDly(1);
}
OS_ENTER_CRITICAL();
__GucHostEnumPrio = 0;
OS_EXIT_CRITICAL();
}
}
/*
* 查看调度任务是否存在,若存在,则删除该任务
*/
if (__GucHostShedPrio) {
ptcb = OSTCBPrioTbl[__GucHostShedPrio];
if (ptcb != NULL) {
OSQPost(__GevtUsbMsgQeue, (void *)(__USB_SHED_DELSELF << 24));
/* 调度任务已存在,发送消息 */
/* 要求该任务删除自己 */
while (OSTCBPrioTbl[__GucHostShedPrio] != NULL) {
OSTimeDly(1);
}
OS_ENTER_CRITICAL();
__GucHostShedPrio = 0;
OS_EXIT_CRITICAL();
}
}
OS_ENTER_CRITICAL();
__GevtUsbMsgQeue = OSQDel(__GevtUsbMsgQeue, OS_DEL_ALWAYS, &ucErr); /* 删除调度消息队列 */
__GevtUsbCtrlMbox = OSMboxDel(__GevtUsbCtrlMbox, OS_DEL_ALWAYS, &ucErr);
__GevtUsbDataTranMbox = OSMboxDel(__GevtUsbDataTranMbox, OS_DEL_ALWAYS, &ucErr);
__GevtUsbCtrlSem = OSSemDel(__GevtUsbCtrlSem, OS_DEL_ALWAYS, &ucErr);
__GevtUsbDataTranSem = OSSemDel(__GevtUsbDataTranSem, OS_DEL_ALWAYS, &ucErr);
OS_EXIT_CRITICAL();
return TRUE;
}
/*********************************************************************************************************
** Function name: usbHostNotifyExitDataOpera
** Descriptions: 使USB 主机退出往从机写数据的操作
** input parameters: None
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL usbHostNotifyExitDataOpera (void)
{
USB_INT32U i;
OS_ENTER_CRITICAL();
GusbHostFlags.bExitDataOperaReq = TRUE;
OS_EXIT_CRITICAL();
/*
* 等待没有任务任务操作USB总线
*/
i = 0;
while (__GusbHostEvtCnt.ucDataTranCnt) {
OSTimeDly(2);
if (i++ > 1000) { /* 等待10S */
return FALSE;
}
}
return TRUE;
}
/*********************************************************************************************************
** Function name: usbHostNotifyExitStdOpera
** Descriptions: 使USB主机退出控制管道的操作
** input parameters: None
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL usbHostNotifyExitStdOpera (void)
{
USB_INT32U i;
OS_ENTER_CRITICAL();
GusbHostFlags.bExitStdOperaReq = TRUE;
OS_EXIT_CRITICAL();
/*
* 等待没有任务任务操作USB总线
*/
i = 0;
while (__GusbHostEvtCnt.ucStdTranCnt) {
OSTimeDly(2);
if (i++ > 1000) { /* 等待10S */
return FALSE;
}
}
return TRUE;
}
/*********************************************************************************************************
** Function name: usbPipeOpen
** Descriptions: 打开传输管道
** input parameters: ucTranType 传输类型
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL usbPipeOpen (USB_INT8U ucTranType)
{
USB_INT8U ucEpNum;
USB_INT16U usMaxPktSize;
if (ucTranType != USB_TRAN_TYPE_CONTROL) {
ucEpNum = usbGetEp(0, ucTranType);
usMaxPktSize = usbGetEpMaxPktSize(0, ucEpNum); /* 获取该端点的最大包长度 */
if (usMaxPktSize == 0) { /* 获取失败, 可能该端点不存在 */
return FALSE;
}
}
switch (ucTranType) {
case USB_TRAN_TYPE_CONTROL: /* 控制传输 */
GusbHostFlags.ucCtrlPipe = 1;
__hcEnableSchedule(ucTranType);
break;
case USB_TRAN_TYPE_BULK_OUT: /* 批量 OUT 传输 */
if (GusbHostFlags.ucBulkOutPipe == 0) {
__GpohciEd->edsBulkOut.uiControl = (usMaxPktSize << 16) | (1 << 14) | (__GucUsbSpeed << 13) |
((ucEpNum & 0x0F) << 7) | __GucUsbDevAddr;
GusbHostFlags.ucBulkOutPipe = 1;
__hcEnableSchedule(ucTranType);
}
break;
case USB_TRAN_TYPE_BULK_IN: /* 批量 IN 传输 */
if (GusbHostFlags.ucBulkInPipe == 0) {
__GpohciEd->edsBulkIn.uiControl = (usMaxPktSize << 16) | (1 << 14) | (__GucUsbSpeed << 13) |
((ucEpNum & 0x0F) << 7) | __GucUsbDevAddr;
GusbHostFlags.ucBulkInPipe = 1;
__hcEnableSchedule(ucTranType);
}
break;
case USB_TRAN_TYPE_INTR_OUT: /* 中断 OUT 传输 */
if (GusbHostFlags.ucIntrOutPipe == 0) {
__GpohciEd->edsIntrOut.uiControl = (usMaxPktSize << 16) | (1 << 14) | (__GucUsbSpeed << 13) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -