Vender command使用 controltransfer的方式来传送资料。修改BSP之前就需要了解Control transfer流程。简单来说分成三个步骤:setup,data and status.
Setup包含8个字节,下表列出每个字节的内容。 Offset | Field | Size | Value | Description | 0 | bmRequestType | 1 | Bit-Map | D7 Data Phase Transfer Direction
0 = Host to Device
1 = Device to Host
D6..5 Type
0 = Standard
1 = Class
2 = Vendor
3 = Reserved
D4..0 Recipient
0 = Device
1 = Interface
2 = Endpoint
3 = Other
4..31 = Reserved | 1 | bRequest | 1 | Value | Request | 2 | wValue | 2 | Value | Value | 4 | wIndex | 2 | Index or Offset | Index | 6 | wLength | 2 | Count | Number of bytes to transfer if there is a data phase |
传送资料,其长度为setup.wLength,或者下位机的资料长度,两者取小值。
回报接受状态,其资料长度为0,表示资料接受完成。
Control Write 1. Setup stage 当接受到setup command,程序会进入到USBD_ProcessSetupPacket()。这次的例子是新增一个class command。在HID_ClassRequest()会新增以下程序。在这里会初始化endpoint,准备data and status stage。 #define SET_Customer 0x0C uint8_t a8temp[64]; void HID_ClassRequest(void) { … case SET_Customer: /* Data stage*/ USBD_PrepareCtrlOut(a8temp,64); /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0,0); break; … } 2. Data stage 这部分driver已经处理,不用自行修改。 3. Status stage 当资料传送结束,会产生 In token ack信号并且资料长度为0。在此就需要进一步判断,如果是对应的指令,其取读数据。 #define SET_Customer 0x0C extern uint8_t a8temp[64]; void USBD_CtrlIn(void) { if(g_usbd_CtrlInSize) { … }else { … }else if((g_usbd_SetupPacket[0] ==REQ_CLASS) && (g_usbd_SetupPacket[1] == SET_Customer)) { if(a8temp[0] == 0x55) PB13 = ~PB13; } } }
Control Read 1. Setup stage: 当接受到setup command,程序会进入到USBD_ProcessSetupPacket()。这次的例子使用standard command。在USBD_StandardRequest ()会呼叫USBD_GetDescriptor(),进行资料的上传。流程很简单,比较电脑要求的资料长度及report本身的资料长度,取最小了。透过USBD_PrepareCtrlIn(),初始化资料的起始位置及上传大小。设定USBD_PrepareCtrlOut(0, 0),回应status的资料。 void USBD_GetDescriptor(void) { … case DESC_DEVICE: { u32Len = Minimum(u32Len, LEN_DEVICE); USBD_PrepareCtrlIn((uint8_t*)g_usbd_sInfo->gu8DevDesc, u32Len); USBD_PrepareCtrlOut(0, 0); break; } … } 2. Data stage & Status stage USB driver会处理好。
大家可以透过bus hound来进行测试。 1. 选择对应的装置 2. 按”SendCommands” 3. 选择controlendpoint 4. 设定setupcommand 5. 设定data 6. Press “Run” icon to execute control transfer
|