/** * \brief Handle USB SET CONFIGURATION request. * */ static void SetConfigurationReq(void) { if ((usb_device_state == USB_STATE_ADDRESS) || (usb_device_state == USB_STATE_CONFIGURED)) { if (usb_setup.value <= DeviceDescriptor.num_configurations) { uint8 i; if (usb_setup.value) { for (i = 2; i < USB_EP_MAX; i += 2) { hw_usb_ep_rx_enable(i); } usb_device_state = USB_STATE_CONFIGURED; usb_enable_app(0); } else { for (i = 1; i < USB_EP_MAX; i++) { hw_usb_ep_disable(i, true); } usb_device_state = USB_STATE_ADDRESS; usb_disable_app(0); } hw_usb_ep_tx_start(USB_EP_DEFAULT, NULL, 0); usb_charger_connected(dg_configBATTERY_CHARGE_CURRENT); return; } } hw_usb_ep0_stall(); }
/** * \brief Handle USB SET FEATURE request. * */ static void SetFeatureReq(void) { if (usb_device_state == USB_STATE_ADDRESS || usb_device_state == USB_STATE_CONFIGURED) { switch (usb_setup.request_type & USB_RECIP_MASK) { case USB_RECIP_ENDPOINT: { USB_Endpoint_Id_Type EpNr = GetEpId(usb_setup.index); if (EpNr >= USB_EP_MAX) { break; } if (usb_setup.value != USB_ENDPOINT_HALT) { break; } hw_usb_ep_stall(EpNr); } hw_usb_ep_tx_start(USB_EP_DEFAULT, NULL, 0); return; } } hw_usb_ep0_stall(); }
/** * \brief Handle USB GET STATUS request. * */ static void GetStatusReq(void) { uint16 v = 0; if (usb_device_state == USB_STATE_ADDRESS || usb_device_state == USB_STATE_CONFIGURED) { switch (usb_setup.request_type & USB_RECIP_MASK) { case USB_RECIP_DEVICE: SendEp0Data((uint8*) &v, 2); return; case USB_RECIP_ENDPOINT: { USB_Endpoint_Id_Type EpNr = GetEpId(usb_setup.index); if (EpNr >= USB_EP_MAX) { break; } if (hw_usb_ep_is_stalled(EpNr)) { v = 1; } } SendEp0Data((uint8*) &v, 2); return; } } hw_usb_ep0_stall(); }
/** * \brief Convert char string to wide-char, and send. * * \param[in] str The string. * * \warning Note that this is not a real ansi-to-wide conversion, just an extension of each * character to 16-bit. */ static void SendEp0String(const char* str) { uint8 len = strlen(str); uint8 size = 2 + (2 * len); ep0_buffer = OS_MALLOC(size); if (ep0_buffer) { uint8* pb = ep0_buffer; const char* ps = str; uint8 i; *pb++ = size; *pb++ = USB_DT_STRING; for (i = 0; i < len; i++) { *pb++ = *ps++; *pb++ = 0; } hw_usb_ep_tx_start(USB_EP_DEFAULT, ep0_buffer, MIN(size, usb_setup.length)); } else { hw_usb_ep0_stall(); } }
/** * \brief Handle USB VENDOR request. * */ static void HandleVendorReq(void) { switch (usb_setup.request) { case MS_WINUSB_COMP_ID_FEATURE: MSGetWinusbCompIDFeatureReq(); break; default: hw_usb_ep0_stall(); break; } }
/** * \brief Handle USB SET ADDRESS request. * */ static void SetAddressReq(void) { if ((usb_device_state == USB_STATE_DEFAULT) || (usb_device_state == USB_STATE_ADDRESS)) { hw_usb_bus_address(usb_setup.value); hw_usb_ep_tx_start(USB_EP_DEFAULT, NULL, 0); usb_device_state = USB_STATE_ADDRESS; usb_disable_app(0); return; } hw_usb_ep0_stall(); }
/** * \brief Transmit data on endpoint zero. * * \param[in] data The buffer holding the data. * \param[in] size The size of the data in the buffer. * */ static void SendEp0Data(uint8* data, uint8 size) { ep0_buffer = OS_MALLOC(size); if (ep0_buffer) { memcpy(ep0_buffer, data, size); hw_usb_ep_tx_start(USB_EP_DEFAULT, ep0_buffer, size); } else { hw_usb_ep0_stall(); } }
/** * \brief Handle USB GET CONFIGURATION request. * */ static void GetConfigurationReq(void) { if ((usb_device_state == USB_STATE_ADDRESS) || (usb_device_state == USB_STATE_CONFIGURED)) { uint8 v = 0; if (usb_device_state == USB_STATE_CONFIGURED) { v = 1; } SendEp0Data(&v, 1); return; } hw_usb_ep0_stall(); }
static void MSGetWinusbCompIDFeatureReq(void) { switch (usb_setup.value & 0xFF) { case MS_WINUSB: if (usb_setup.index == MS_COMPATIBLE_ID_FEATURE) { SendEp0Data((uint8*) UsbMSOSCompatibleID, MIN(UsbMSOSCompatibleID[0], usb_setup.length)); } break; default: hw_usb_ep0_stall(); break; } }
/** * \brief Handle USB standard request. * */ static void HandleStandardReq(void) { switch (usb_setup.request) { case USB_REQ_GET_STATUS: GetStatusReq(); break; case USB_REQ_CLEAR_FEATURE: ClearFeatureReq(); break; case USB_REQ_SET_FEATURE: SetFeatureReq(); break; case USB_REQ_SET_ADDRESS: SetAddressReq(); break; case USB_REQ_GET_DESCRIPTOR: GetDescriptorReq(); break; case USB_REQ_GET_CONFIGURATION: GetConfigurationReq(); break; case USB_REQ_SET_CONFIGURATION: SetConfigurationReq(); break; default: hw_usb_ep0_stall(); break; } }
//========================================================================= //函数名: hw_usb_setup_handler //功 能: 对SETUP包解包和处理 //参 数: 无 //返 回: 无 //说 明: // (1)只有接收到SETUP包才调用该函数 // (2)SETUP包中8字节数据 // bmRequestType:1 // bRequest:1 // wValue.H:1 :描述符的类型 // wValue.L:1 :描述符的索引 // wIndex:2 // wLength:2 //========================================================================= void hw_usb_setup_handler(void) { uint_8 u8State; // 从DATA0 开始传输。 FLAG_CLR(0,gu8USB_Toogle_flags); switch(Setup_Pkt->bmRequestType & 0x1F) { /* #define STANDARD_REQ 0x00 #define SPECIFIC_REQ 0x20 #define VENDORSPEC_REQ 0x40 #define DEVICE_REQ 0x00 #define INTERFACE_REQ 0x01 #define ENDPOINT_REQ 0x02 */ // #define DEVICE_REQ 0x00 case DEVICE_REQ: // 设备 if((Setup_Pkt->bmRequestType & 0x1F)== STANDARD_REQ) { //tBDTtable[bEP0IN_ODD].Stat._byte= kUDATA1; // USB 设备的标准请求 hw_usb_stdReq_handler(); } //#define kUDATA0 0x88 //#define kUDATA1 0xC8 // 把BDT 的控制权交给USB 模块 tBDTtable[bEP0OUT_ODD].Stat._byte= kUDATA0; break; // #define INTERFACE_REQ 0x01 case INTERFACE_REQ: // 接口 /* u8State=USB_InterfaceReq_Handler(); if(u8State==uSETUP) tBDTtable[bEP0OUT_ODD].Stat._byte= kUDATA0; else tBDTtable[bEP0OUT_ODD].Stat._byte= kUDATA1; */ break; // #define ENDPOINT_REQ 0x02 case ENDPOINT_REQ: // 端点 hw_usb_endpoint_setup_handler(); tBDTtable[bEP0OUT_ODD].Stat._byte= kUDATA0; break; default: hw_usb_ep0_stall(); break; } //USB_CTL&=!USB_CTL_TXSUSPENDTOKENBUSY_MASK; //CTL_TXSUSPEND_TOKENBUSY=0; // 为0 时: SIE 继续处理令牌 FLAG_CLR(USB_CTL_TXSUSPENDTOKENBUSY_SHIFT,USB0_CTL); }
//========================================================================= //函数名: hw_usb_stdReq_handler //功 能: 对标准的SETUP包解包和处理 //参 数: 无 //返 回: 无 //========================================================================= void hw_usb_stdReq_handler(void) { uint_16 gu8Status; switch(Setup_Pkt->bRequest) { /* 1)获取状态 Get Status (00H) A:[To Device]获取设备的状态: *.位0:自供电(0表示总线供电;1表示自供电). *.位1:远程唤醒(0表示不支持远程唤醒;1表示远程唤醒). *.位2~15:保留. *.一般选择总线供电,不支持远程唤醒,所以返回数据就是0x0000. B:[To Interface]获取接口的状态: *.接口状态的16位字节全部保留,所以返回数据就是0x0000. C:[To Endpoint]获取端点的状态: *.位0:Halt(0表示端点允许;1表示端点禁止). *.位1~15:保留(复位为0). 2)清除特性 Clear Feature (01H) A:[To Device]清除设备的远程唤醒功能,并返回一个空包. B:[To Endpoint]解禁端点. 3)设置特性 Set Feature (03H) A:[To Device]设置设备的远程唤醒功能,并返回一个空包. B:[To Endpoint]禁止端点. 4)设置地址 Set Address (05H) A:设置设备地址. 5)获取描述符 Get Descriptor (06H) A:[To Device]获取设备描述符: *.描述当前USB协议的版本号.设备端点0的FIFO大小.USB设备的ID号等. B:[To Configuration]获取配置描述符: *.描述USB设备接口个数及是否有自供电能力等. C:[To Interface]获取接口描述符: *.描述端点0以外的物理端点个数等信息. D:[To Endpoint]获取端点描述符: *.描述端点0各端点的传输类型和最大信息包大小和端点的传输方向(IN/OUT). 6)设置描述符(可选,无法更新) Set Descriptor (07H) 7)获取配置信息 Get Configuration (08H) 8)设置配置 Set Configuration (09H) A:[To Configuration]设置配置描述符. B:[To Interface]设置接口描述符. C:[To Endpoint]设置端点描述符. 9) 获取接口信息 Get Interface (0AH) 10)设置接口 Set Interface (0BH) 11)SYNCH_FRAME(0CH) 用于设备设置和报告一个端点的同步帧. */ // #define mGET_STATUS 0 // #define mCLR_FEATURE 1 // #define mSET_FEATURE 3 // #define mSET_ADDRESS 5 // #define mGET_DESC 6 // #define mSET_DESC 7 // #define mGET_CONFIG 8 // #define mSET_CONFIG 9 // #define mGET_INTF 10 // #define mSET_INTF 11 // #define mSYNC_FRAME 12 // PC 给芯片地址配置 // #define mSET_ADDRESS 5 // case mSET_ADDRESS: hw_usb_ep_in_transfer(EP0,0,0); gu8USB_State=uADDRESS; break; // PC 从芯片获取描述符 // define mGET_DESC 6 case mGET_DESC: // 高字节 : Setup_Pkt->wValue_h 表示描述符类型 // 低字节 : Setup_Pkt->wValue_l 表示描述符的索引值 switch(Setup_Pkt->wValue_h) { /* #define mDEVICE 0x01 //设备描述符 #define mCONFIGURATION 0x02 //配置描述符 #define mSTRING 0x03 //字符串描述符 #define mINTERFACE 0x04 //接口描述符 #define mENDPOINT 0x05 //端点描述符 #define mDEVICE_QUALIFIER 6 #define mOTHER_SPEED_CONFIGURATION 7 #define mINTERFACE_POWER 8 */ case mDEVICE: // 发送设备描述符 hw_usb_ep_in_transfer(EP0,(uint_8*)Device_Descriptor,sizeof(Device_Descriptor)); break; case mCONFIGURATION: // 发送配置描述符 hw_usb_ep_in_transfer(EP0,(uint_8*)Configuration_Descriptor,sizeof(Configuration_Descriptor)); break; case mSTRING: // 发送字符串描述符 hw_usb_ep_in_transfer(EP0,(uint_8*)String_Table[Setup_Pkt->wValue_l],String_Table[Setup_Pkt->wValue_l][0]); break; default: hw_usb_ep0_stall(); break; } break; // 设置配置 Set Configuration // #define mSET_CONFIG 9 case mSET_CONFIG: // 选择配置值 gu8Dummy=Setup_Pkt->wValue_h+Setup_Pkt->wValue_l; if(Setup_Pkt->wValue_h+Setup_Pkt->wValue_l) { //使能1 、2 、3 端点 hw_usb_set_interface(); hw_usb_ep_in_transfer(EP0,0,0); gu8USB_State=uENUMERATED; } break; // 获取配置信息 Get Configuration // #define mGET_CONFIG 8 case mGET_CONFIG: // 获取配置信息 hw_usb_ep_in_transfer(EP0,(uint_8*)&gu8Dummy,1); break; // 获取状态 Get Status // #define mGET_STATUS 0 case mGET_STATUS: // gu8Status=0; hw_usb_ep_in_transfer(EP0,(uint_8*)&gu8Status,2); break; default: hw_usb_ep0_stall(); break; } }
/** * \brief Handle USB GET DESCRIPTOR request. * */ static void GetDescriptorReq(void) { uint16 size; switch (usb_setup.value >> 8) { case USB_DT_DEVICE: SendEp0Data((uint8*) &DeviceDescriptor, MIN(sizeof(DeviceDescriptor), usb_setup.length)); return; case USB_DT_CONFIG: size = sizeof(ConfigDescriptor) + SIZE_OF_CONFIGURATION; ep0_buffer = OS_MALLOC(size); if (ep0_buffer == NULL) { break; } // Create full configuration descriptor. { uint8 *pb = ep0_buffer; uint8 i; // Config descriptor. memcpy(pb, &ConfigDescriptor, sizeof(ConfigDescriptor)); ((usb_config_descriptor_type*) pb)->total_length = size; pb += sizeof(ConfigDescriptor); // HID interfaces. for (i = 0; i < NUM_OF_INTERFACES; i++) { memcpy(pb, &Interface0, sizeof(Interface0)); ((usb_interface_descriptor_type*) pb)->interface_number = i; pb += sizeof(Interface0); memcpy(pb, &BulkEpTx, sizeof(BulkEpTx)); ((usb_endpoint_descriptor_type*) pb)->endpoint_address = USB_DIR_IN | (USB_EP_BULK_TX + (2 * i)); pb += sizeof(BulkEpTx); memcpy(pb, &BulkEpRx, sizeof(BulkEpRx)); ((usb_endpoint_descriptor_type*) pb)->endpoint_address = USB_DIR_OUT | (USB_EP_BULK_RX + (2 * i)); pb += sizeof(BulkEpRx); } } // Send it. hw_usb_ep_tx_start(USB_EP_DEFAULT, ep0_buffer, MIN(size, usb_setup.length)); return; case USB_DT_STRING: switch (usb_setup.value & 0xFF) { case 0: SendEp0Data((uint8*) UsbLanguageId, MIN(sizeof(UsbLanguageId), usb_setup.length)); return; case MANUFACTURER_STR_INDEX: SendEp0String(UsbManufacturerString); return; case PRODUCT_STR_INDEX: SendEp0String(UsbProductString); return; case CONFIGURATION_STR_INDEX: SendEp0String(UsbConfigurationfString); return; case SERIAL_STR_INDEX: SendEp0String(UsbSerialNumberString); return; case IFACE_STR_INDEX: SendEp0String(UsbInterfaceString); return; case MSFT_OS_STR_INDEX: SendEp0Data((uint8*) UsbMSOSString, MIN(UsbMSOSString[0], usb_setup.length)); return; } break; case USB_DT_DEVICE_QUALIFIER: break; } hw_usb_ep0_stall(); }