📄 drv_usb_ctl.c
字号:
/************************************************* Copyright (C), 2007, DTK Computer. File name: drv_usb_ctl.h Author: MMI Group Version: 1.0 Date: 2008.04.30 Description: usb module for control request Others: Function List: History: <author> <time> <version > <desc> Bosco Lee 08/30/04 1.0 build this moudle *************************************************/#include "drv_usb_ctl.h"#include "drv_usb_init.h"//定义控制传输结构变量CONTROL_XFER ControlData;//定义USB事件标志变量EPPFLAGS bEPPflags;//*************************************************************************//USB标准设备请求入口地址指针表 (控制命令)//*************************************************************************void (*StandardDeviceRequest[]) (void) ={ get_status, clear_feature, reserved, set_feature, reserved, set_address, get_descriptor, set_descriptor, get_configuration, set_configuration, get_interface, set_interface, synch_frame, reserved, reserved, reserved};void (*ClassDeviceRequest[]) (void) ={ reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, get_max_lun, reserved};//*************************************************************************// USB 协议层函数//*************************************************************************/************************************* ** 函数名称: void stall_ep0(void) ** 功能描述: 使控制端点处于停止状态 **************************************/voidstall_ep0 (void){ USB_SetEndpointStall (0, 1);}/************************************* ** 函数名称: void reserved(void) ** 功能描述: 保留子程序 **************************************/voidreserved (void){ stall_ep0 (); //返回STALL}/********************************************** ** 函数名称: void init_unconfig(void) ** 功能描述: 进入地址状态,禁止0除外的所有端点 ***********************************************/voidinit_unconfig (void){ USB_SetEndpointEnable (0); //禁止0除外的所有端点}/********************************************** ** 函数名称: void init_config(void) ** 功能描述: 配置处理,允许端点收发 ***********************************************/voidinit_config (void){ USB_SetEndpointEnable (1); //使能普通/同步端点使能}/********************************************************* ** 函数名称: void single_transmit(D_UINT8 * buf, D_UINT8 len) ** 功能描述: 通过端点0发送数据(DATA类型) ** 输 入 : D_UINT8 * buf: 发送数据指针 D_UINT8 len: 发送数据长度 ** 输 出: 无 **********************************************************/voidsingle_transmit (D_UINT8 * buf, D_UINT8 len){ if (len <= EP0_PACKET_SIZE) { //长度小于EP0最大信息包大小才允许发送 USB_WriteEndpoint (0, len, buf); }}/************************************************************* ** 函数名称: void code_transmit(D_UINT8 * pRomData, D_INT16 len) ** 功能描述: 通过端点EP0发送数据(CODE类型) ** 输 入: D_UINT8 *pRomData: 指向需要发送的数据 D_INT16 len: 发送数据长度 ** 输 出: 无 **************************************************************/// 将命令需要从device上获取的数据写入EP0的FIFO(不一定能把要发送的数据写完)voidcode_transmit (D_UINT8 * pRomData, D_INT16 len){ ControlData.wCount = 0; //传输字节数计数器清0 if (ControlData.wLength > len) ControlData.wLength = len; //传输数据总字节数不得超过len ControlData.pData = pRomData; //传输数据指针指向pRomData if (ControlData.wLength >= EP0_PACKET_SIZE) { //传输数据总字节数大于端点0最大信息包大小 //发送端点0最大信息包大小个字节 USB_WriteEndpoint (0, EP0_PACKET_SIZE, ControlData.pData); ControlData.wCount += EP0_PACKET_SIZE; //统计已发送字节数 DISABLE (); bEPPflags.bits.control_state = USB_TRANSMIT; //标志数据发送状态 ENABLE (); } else { USB_WriteEndpoint (0, ControlData.wLength, pRomData); //写入传输数据总字节数 ControlData.wCount += ControlData.wLength; //统计已发送字节数 DISABLE (); bEPPflags.bits.control_state = USB_IDLE; //标志空闲状态 ENABLE (); }}//*************************************************************************// USB 标准设备请求服务程序//*************************************************************************/******************************************************************** ** 函数名称: void get_status(void) ** 功能描述: 主机要求获取状态,设备返回16位的状态描述给主机 *********************************************************************/voidget_status (void){ D_UINT8 endp, txdat[2], c; D_UINT8 bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT; //取得设备请求类型 if (bRecipient == USB_RECIPIENT_DEVICE) { //对设备请求 if (bEPPflags.bits.remote_wakeup == 1) txdat[0] = 3; //支持远程唤醒、自供电 else txdat[0] = 1; //不支持远程唤醒、自供电 txdat[1] = 0; //高8位为0 single_transmit (txdat, 2); //发送16位的状态到主机 } else if (bRecipient == USB_RECIPIENT_INTERFACE) { //对接口请求 txdat[0] = 0; txdat[1] = 0; single_transmit (txdat, 2); //发送16位的状态到主机 } else if (bRecipient == USB_RECIPIENT_ENDPOINT) { //对端点请求 endp = (D_UINT8) (ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS); c = USB_ReadEndpointStatus (endp); //读取端点状态 if (c & SC_STALL_SENT_BIT) txdat[0] = 1; //端点禁止 else txdat[0] = 0; //端点有效 txdat[1] = 0; single_transmit (txdat, 2); //发送16位的状态到主机 } else stall_ep0 (); //非标准请求,发STALL USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void clear_feature(void) ** 功能描述: 清除特性 *****************************************/// 清除设备、接口或端点的某种特征(或性能)。对于设备来说,清除其远程唤醒功能;目前没有对接口性能的清除工作;对端点来说,清除其停止工作的状态。voidclear_feature (void){ D_UINT8 endp; //读取请求类型中的接收方 D_UINT8 bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT; //读取请求类型 if (bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) { DISABLE (); //对设备来说,清除其远程唤醒功能 bEPPflags.bits.remote_wakeup = 0; //清0远程唤醒标志 ENABLE (); } else if (bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) { //对端点来说,清楚其停止工作的状态 endp = (D_UINT8) (ControlData.DeviceRequest.wIndex & 0xff); if (endp < MAX_ENDPOINTS) USB_SetEndpointStall (endp, 0); //清除控制输出端点STALL特性 } else stall_ep0 (); //没有该请求,返回STALL USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void set_feature(void) ** 功能描述: 设置特性 *****************************************/// 主机要求启动一个在设备、接口或者端点上的特征(和清除特性执行相反的动作)voidset_feature (void){ USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void set_address(void) ** 功能描述: 设置地址 *****************************************/voidset_address (void){ USB_SetAddress ((D_UINT8) (ControlData.DeviceRequest.wValue & DEVICE_ADDRESS_MASK)); USB_SetEndpointReady (0, 1);}/**************************************** ** 函数名称: void get_descriptor(void) ** 功能描述: 获取描述符 *****************************************/// wValue的高字节表示描述符的类型,低字节表示描述符的索引值voidget_descriptor (void){ D_UINT8 bDescriptor = MSB (ControlData.DeviceRequest.wValue); //读取请求的描述符类型printf("get_descriptor\n"); //获取设备描述符 if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) { if (ControlData.DeviceRequest.wLength > sizeof (USB_DEVICE_DESCRIPTOR)) ControlData.DeviceRequest.wLength = sizeof (USB_DEVICE_DESCRIPTOR); // 将设备描述符DeviceDescr发送给主机 // code_transmit((D_UINT8 *)&DeviceDescr, ControlData.DeviceRequest.wLength); //获取配置描述符 } else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) { if (ControlData.DeviceRequest.wLength > CONFIG_DESCRIPTOR_LENGTH) ControlData.DeviceRequest.wLength = CONFIG_DESCRIPTOR_LENGTH; // code_transmit((D_UINT8 *)&(usb_descr), ControlData.DeviceRequest.wLength); //主机要求获取字符串描述符 } else if (bDescriptor == USB_STRING_DESCRIPTOR_TYPE) { if (ControlData.DeviceRequest.wValue == 0x0303) { if (ControlData.DeviceRequest.wLength > sizeof (USB_STRING_DESCRIPTOR)) ControlData.DeviceRequest.wLength = sizeof (USB_STRING_DESCRIPTOR); // code_transmit((D_UINT8 *)&(usb_descr.StringDescr), ControlData.DeviceRequest.wLength); } else { if (ControlData.DeviceRequest.wLength > sizeof (USB_STRING_LANG_ID_DESCRIPTOR)) ControlData.DeviceRequest.wLength =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -