1. 修改端点数量的宏定义:
#define EP_NUM (3)
EP0作为控制通道,EP1作为数据IN通道,EP2为数据OUT通道。
2. 实现字符串描述符index=4的传输,字符串描述符的结构增加一条{(uint8_t*)usbDeviceStringInterface, USB_DEVICE_STRING_INTERFACE_LEN},
ONE_DESCRIPTOR stUsbStringDescriptor[] =
{
{(uint8_t*)usbDeviceStringLangID, USB_DEVICE_STRING_LANGID},
{(uint8_t*)usbDeviceStringVendor, USB_DEVICE_STRING_VENDOR},
{(uint8_t*)usbDeviceStringProduct, USB_DEVICE_STRING_PRODUCT},
{(uint8_t*)usbDeviceStringSerial, USB_DEVICE_STRING_SERIAL}
{(uint8_t*)usbDeviceStringInterface, USB_DEVICE_STRING_INTERFACE_LEN},
};
3. 把HID相关的代码删掉,主要是删掉usbClassDataSetup和usbClassNoDataSetup相关的代码
4. 获取字符串描述符函数usbClassGetStringDescriptor中字符串index最大值判断修改
uint8_t *usbClassGetStringDescriptor(uint16_t Length)
{
uint8_t wValue0 = pInformation->USBwValue0;
if (wValue0 >= sizeof(stUsbStringDescriptor) / sizeof(ONE_DESCRIPTOR))
{
return NULL;
}
else
{
return Standard_GetDescriptorData(Length, &stUsbStringDescriptor[wValue0]);
}
}
这样以后就不需要修改了。
5. usbClassReset中初始化端点
#define ENDP0_RXADDR (0x18)
#define ENDP0_TXADDR (0x58)
#define ENDP1_TXADDR (0x98)
#define ENDP2_RXADDR (0xD8)
/* Initialize Endpoint 1 */
SetEPType(ENDP1, EP_BULK);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_DIS);
/* Initialize Endpoint 2 */
SetEPType(ENDP2, EP_BULK);
SetEPRxAddr(ENDP2, ENDP2_RXADDR);
SetEPRxCount(ENDP2, Device_Property.MaxPacketSize);
SetEPRxStatus(ENDP2, EP_RX_VALID);
SetEPTxStatus(ENDP2, EP_TX_DIS);
6. usbClassDataSetup的处理
MSC类有一个GET_MAX_LUN的命令需要响应,该请求用于确定设备支持的逻辑单元数。命令字是0xFE
#define GET_MAX_LUN 0xFE
LUN是Logical Unit Number,也就是逻辑单元号。MAX LUN是该设备LUN的最大值,MAX LUN的范围是0-15。一般usb中就一个LUN,即MAX LUN是0.
uint8_t mscMaxLun = 0;
uint8_t *mscGetMaxLun(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = 1;
return 0;
}
else
{
return((uint8_t*)(&mscMaxLun));
}
}
RESULT usbClassDataSetup(uint8_t RequestNo)
{
uint8_t *(*CopyRoutine)(uint16_t);
CopyRoutine = NULL;
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (RequestNo == GET_MAX_LUN) && (pInformation->USBwValue == 0)
&& (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x01))
{
CopyRoutine = mscGetMaxLun;
}
else
{
return USB_UNSUPPORT;
}
if (CopyRoutine == NULL)
{
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
7. usbClassNoDataSetup的处理
MSC的另外一个请求是MASS_STORAGE_RESET,这个请求用于复位MSC设备和它相关的接口。
RESULT usbClassNoDataSetup(uint8_t RequestNo)
{
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (RequestNo == MASS_STORAGE_RESET) && (pInformation->USBwValue == 0)
&& (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x00))
{
/* Initialize Endpoint 1 */
ClearDTOG_TX(ENDP1);
/* Initialize Endpoint 2 */
ClearDTOG_RX(ENDP2);
/*initialize the CBW signature to enable the clear feature*/
gMscCBW.dSignature = MSC_BOT_CBW_SIGNATURE;
gMscBotState = MSC_BOT_IDLE;
return USB_SUCCESS;
}
return USB_UNSUPPORT;
}
8. 修改SetConfiguration
void usbClassSetConfiguration(void)
{
DEVICE_INFO *pInfo = &Device_Info;
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
gbUsbDeviceState = CONFIGURED;
ClearDTOG_TX(ENDP1);
ClearDTOG_RX(ENDP2);
gMscBotState = MSC_BOT_IDLE;
}
}
9. 修改ClearFeature
void usbClassClearFeature(void)
{
/* when the host send a CBW with invalid signature or invalid length the two
Endpoints (IN & OUT) shall stall until receiving a Mass Storage Reset */
if (gMscCBW.dSignature != MSC_BOT_CBW_SIGNATURE)
mscBotAbort(MSC_BOTH_DIR);
}