📄 otgdriver.c
字号:
/*****************************Copyright(c)****************************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**------File Info-----------------------------------------------------------------------------------------
** File Name: OTGDriver.c
** Latest modified Date: 2007-12-10
** Latest Version: V1.0
** Description: 实现OTG协议栈
**
**--------------------------------------------------------------------------------------------------------
** Created By: 吴隆穗 Longsui Wu
** Created date: 2007-12-10
** Version: V1.0
** Descriptions: 初始版本
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
*********************************************************************************************************/
#include "OTGIncludes.h"
#include "OTGHal.h"
#define __OTG_MSGQEUE_LENGTH 10 /* 消息队列长度 */
#define __TASK_OTG_SCHED_STK_LEN 128 /* OTG调度任务堆栈大小 */
OS_EVENT *__GevtOtgMsgQeue; /* 调度消息队列 */
void *__GevtOtgMsgQeueTbl[__OTG_MSGQEUE_LENGTH]; /* 消息队列缓冲区 */
OS_STK __taskOTGShedulerStk[__TASK_OTG_SCHED_STK_LEN];
void __taskOtgShed (void *pdata);
USB_BOOL __otgChangeRoleToHost (void);
USB_BOOL __otgChangeRoleToDevice (void);
USB_INT8U __GetDefaultRole (void);
void __usbOtgException (void);
void __usbAtxException (void);
USB_BOOL __otgHNPStart (void);
USB_BOOL __usbIDChange (void);
void __otgHNPFailure (void);
void __otgHNPTmrOut (void);
void __otgBusSuspDeal (void);
void __usbVbusDrv (void);
void __usbVbusDisChrg (void);
USB_BOOL usbHostClientInit (void);
USB_BOOL usbHostClientDeInit (void);
USB_BOOL usbFunctionInit (void);
USB_BOOL usbFunctionDeInit (void);
#ifdef __cplusplus
extern "C" {
#endif
static __OTG_INFO __GsOtgInfo; /* OTG 信息 */
static void __otgSetDeviceAB (USB_INT8U ucDeviceAB);
static void __otgSetCurRole (USB_INT8U ucRole);
/*********************************************************************************************************
** Function name: otgInit
** Descriptions: OTG初始化
** input parameters: ucOtgTaskPrio OTG调度任务优先级
** ucHostDevShedPrio 主机或从机的调度任务优先级
** ucHostEnumPrio 主机枚举任务优先级,
** 当有大容量类从机设备驱动程序时也做该驱动程序的服务任务优先级
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL otgInit (USB_INT8U ucOtgTaskPrio,
USB_INT8U ucHostDevShedPrio,
USB_INT8U ucHostEnumPrio)
{
USB_BOOL bRet;
USB_INT8U ucErrCode;
__usbHalInit(); /* 底层硬件初始化 */
__usbAtxIntInit(); /* 初始化外部收发器ISP1301中断 */
/*
* 创建 OTG 协议栈所要的消息队列
*/
__GevtOtgMsgQeue = OSQCreate(&__GevtOtgMsgQeueTbl[0], __OTG_MSGQEUE_LENGTH);
if (__GevtOtgMsgQeue == NULL) {
USBDEBUG_SENDSTR("\r\n!!Create OTG Msg Qeue failed!\r\n ");
return FALSE;
}
/*
* 创建 OTG 调度任务
*/
if (OSTaskCreate(__taskOtgShed, (void *)0, \
&__taskOTGShedulerStk[__TASK_OTG_SCHED_STK_LEN - 1], ucOtgTaskPrio) != OS_NO_ERR) {
USBDEBUG_SENDSTR("\r\n!!Create OTG scheduler task failed!\r\n ");
return FALSE;
}
__GsOtgInfo.ucHostDevShedPrio = ucHostDevShedPrio; /* 主机或从机的调度任务优先级 */
__GsOtgInfo.ucHostEnumPrio = ucHostEnumPrio; /* 主机枚举任务优先级或从机 */
/* 大容量类驱动调试任务优先级 */
if (__GetDefaultRole() == OTG_DEVICE_A) { /* A-Device */
USBDEBUG_SENDSTR("\r\nDefault Role : A-Device\r\n");
__otgSetDeviceAB(OTG_DEVICE_A); /* A设备 */
__otgSetCurRole(OTG_ROLE_HOST); /* 默认为HOST */
__usbVbusDrv(); /* 驱动VBUS,给总线供电 */
bRet = usbHostInitialize(ucHostDevShedPrio, ucHostEnumPrio, NULL, NULL);
/* 初始化主机 */
if (!bRet) {
USBDEBUG_SENDSTR("\r\nHost initialize failed!\r\n");
return FALSE;
}
} else { /* B-DEVICE */
USBDEBUG_SENDSTR("\r\nDefault Role : B-Device\r\n");
OS_ENTER_CRITICAL();
__otgSetDeviceAB(OTG_DEVICE_B); /* B设备 */
__otgSetCurRole(OTG_ROLE_DEVICE); /* 默认为DEVICE */
massDevInit(ucHostEnumPrio); /* 大容量类设备初始化 */
ucErrCode = usbDevInitialize(ucHostDevShedPrio); /* USB从机初始化 */
OS_EXIT_CRITICAL();
if (ucErrCode != USB_NO_ERR) {
USBDEBUG_SENDSTR("\r\nDevice initialize failed!\r\n");
return FALSE;
}
}
return TRUE;
}
/*********************************************************************************************************
** Function name: otgException
** Descriptions: USB OTG中断服务程序
** input parameters: None
** output parameters: None
** Returned value: None
*********************************************************************************************************/
void otgException (void)
{
USB_INT32U uiIntSt;
VICVectAddr = 0;
uiIntSt = (USB_INT32U)USBIntSt;
OS_ENTER_CRITICAL();
if (uiIntSt & 0x07) { /* device interrupt */
Usb_Exception(uiIntSt & 0x07);
USBINTDEBUG_SENDSTR("\r\nDev Int\r\n");
} else if (uiIntSt & 0x08) { /* host interrupt */
usbHostException();
USBINTDEBUG_SENDSTR("\r\nHost Int\r\n");
} else if (uiIntSt & (1 << 4)) { /* USB ATX中断 */
__usbAtxException();
USBINTDEBUG_SENDSTR("\r\nExtern Atx Int\r\n");
} else if (uiIntSt & (1 << 5)) { /* otg interrupt */
__usbOtgException();
USBINTDEBUG_SENDSTR("\r\nOTG Int\r\n");
} else {
USBINTDEBUG_SENDSTR("\r\nunknow int");
}
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** Function name: otgHNPStart
** Descriptions: 启动HNP,此函数供外部应用程序调用
** 注意:只有A-Device在a_host状态时可以启动HNP
** input parameters: None
** output parameters: None
** Returned value: TRUE: 成功, FALSE:失败
*********************************************************************************************************/
USB_BOOL otgHNPStart (void)
{
if ((otgGetDeviceAB() == OTG_DEVICE_A) &&
(otgGetCurRole() == OTG_ROLE_HOST)) {
if ((GusbOtgDescr.bDescriptorType == __USB_OTG_DESCRIPTOR_TYPE) &&
(GusbOtgDescr.bmAttributes == 0x03)) { /* OTG描述符有效且支持HNP */
OSQPost(__GevtOtgMsgQeue, (void *)(__OTG_MSG_HNP_START << 24));
USBDEBUG_SENDSTR("\r\nOSQPost: __GevtOtgMsgQeue.Start HNP\r\n");
return TRUE;
} else {
USBDEBUG_SENDSTR("\r\nDevice Not support HNP\r\n");
return FALSE;
}
} else {
USBDEBUG_SENDSTR("\r\nOnly the host can start HNP!\r\n");
return FALSE;
}
}
/*********************************************************************************************************
** Function name: otgRetControlToA
** Descriptions: 将USB总线的控制权传递回A设备,此函数只能由B设备在b_host状态时调用
** input parameters: None
** output parameters: None
** Returned value: TRUE: 成功, FALSE:失败
*********************************************************************************************************/
USB_BOOL otgRetControlToA (void)
{
if ((otgGetDeviceAB() == OTG_DEVICE_B) &&
(otgGetCurRole() == OTG_ROLE_HOST)) {
USBDEBUG_SENDSTR("\r\n\r\notgRetControlToA\r\n");
usbBusSusp(); /* 挂起总线 */
OSTimeDly(1);
return __otgChangeRoleToDevice(); /* 切换至从机 */
} else {
USBDEBUG_SENDSTR("\r\nCan not do otgRetControlToA\r\n");
return FALSE;
}
}
/*********************************************************************************************************
** Function name: otgIsDeviceReady
** Descriptions: 检测主机是否已枚举设备或从机是否已配置
** input parameters: None
** output parameters: None
** Returned value: TRUE : 成功 FALSE : 失败
*********************************************************************************************************/
USB_BOOL otgIsDeviceReady (void)
{
if (otgGetCurRole() == OTG_ROLE_HOST) {
return usbIsDeviceReady();
} else if (otgGetCurRole() == OTG_ROLE_DEVICE) {
return IsUsbDevConfig();
}
return FALSE;
}
/*********************************************************************************************************
** Function name: otgGetDeviceAB
** Descriptions: 获取设备状态(A设备或B设备)
** input parameters: None
** output parameters: None
** Returned value: OTG_DEVICE_A(1): A设备, OTG_DEVICE_B(2): B设备
*********************************************************************************************************/
USB_INT8U otgGetDeviceAB (void)
{
USB_INT8U ucRole;
OS_ENTER_CRITICAL();
ucRole = __GsOtgInfo.ucOtgDevice_AB;
OS_EXIT_CRITICAL();
return ucRole;
}
/*********************************************************************************************************
** Function name: otgSetRole
** Descriptions: 设置设备状态(A设备或B设备)
** input parameters: ucDeviceAB: 设备状态,OTG_DEVICE_A(1)或OTG_DEVICE_B(2)
** output parameters: None
** Returned value: None
*********************************************************************************************************/
static void __otgSetDeviceAB (USB_INT8U ucDeviceAB)
{
OS_ENTER_CRITICAL();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -