Code import
This commit is contained in:
@@ -0,0 +1,351 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/11/07.
|
||||
//
|
||||
|
||||
#include "platform.h"
|
||||
#include "framework/system_settings.h"
|
||||
#include "usbd_desc.h"
|
||||
#include "task_main.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "usbd_msc_cdc.h"
|
||||
|
||||
#define USBD_MSC_CDC_CONFIG_DESC_SIZ 98
|
||||
/* USB Mass storage device Configuration Descriptor */
|
||||
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
|
||||
|
||||
// NOTE: This must NOT be in flash, otherwise the driver / peripheral crashes
|
||||
__ALIGN_BEGIN uint8_t USBD_MSC_CDC_CfgFSDesc[USBD_MSC_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
/*0*/ 0x09, /* bLength: Configuation Descriptor size */
|
||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||
LOBYTE(USBD_MSC_CDC_CONFIG_DESC_SIZ), // TODO
|
||||
HIBYTE(USBD_MSC_CDC_CONFIG_DESC_SIZ),
|
||||
3, /* bNumInterfaces - 1 MSC + 2 composite CDC ACM */
|
||||
0x01, /* bConfigurationValue: */
|
||||
0, /* iConfiguration: - string descriptor */
|
||||
0xC0, /* bmAttributes: - self powered */
|
||||
150, /* MaxPower 300 mA */
|
||||
|
||||
/******************** Mass Storage interface ********************/
|
||||
/*9*/ 0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints*/
|
||||
0x08, /* bInterfaceClass: MSC Class */ // #14
|
||||
0x06, /* bInterfaceSubClass : SCSI transparent*/
|
||||
0x50, /* nInterfaceProtocol */
|
||||
0x04, /* iInterface: String descriptor */
|
||||
|
||||
/******************** Mass Storage Endpoints ********************/
|
||||
/*18*/ 0x07, /*Endpoint descriptor length = 7*/
|
||||
0x05, /*Endpoint descriptor type */
|
||||
MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
LOBYTE(MSC_MAX_FS_PACKET),
|
||||
HIBYTE(MSC_MAX_FS_PACKET),
|
||||
0x00, /*Polling interval in milliseconds */
|
||||
|
||||
/*25*/ 0x07, /*Endpoint descriptor length = 7 */
|
||||
0x05, /*Endpoint descriptor type */
|
||||
MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
LOBYTE(MSC_MAX_FS_PACKET),
|
||||
HIBYTE(MSC_MAX_FS_PACKET),
|
||||
0x00, /*Polling interval in milliseconds*/
|
||||
|
||||
/********************** IFACE ASSOC *************************/
|
||||
/*32*/ 0x08, /* bLength */
|
||||
USB_DESC_TYPE_IFACE_ASSOCIATION, /* bDescriptorType */
|
||||
0x01, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass */ // #36
|
||||
0x02, /* bFunctionSubClass (ACM) */
|
||||
0x01, /* bFunctionProtocol (AT-COMMANDS) */
|
||||
0x05, /* iFunction: string descriptor */
|
||||
|
||||
/********************** ACM interface **********************/
|
||||
/*40*/ 0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||
0x01, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints: One endpoints used */
|
||||
0x02, /* bInterfaceClass: Communication Interface Class */ // #45
|
||||
0x02, /* bInterfaceSubClass: Abstract Control Model */
|
||||
0x01, /* bInterfaceProtocol: Common AT commands */
|
||||
0x05, /* iInterface: string descriptor */
|
||||
|
||||
/**************** Header Functional Descriptor ***************/
|
||||
/*49*/ 0x05, /* bLength: Endpoint Descriptor size */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x00, /* bDescriptorSubtype: Header Func Desc */
|
||||
0x10, /* bcdCDC: spec release number */
|
||||
0x01,
|
||||
|
||||
/*********** Call Management Functional Descriptor **********/
|
||||
/*54*/ 0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x01, /* bDescriptorSubtype: Call Management Func Desc */
|
||||
0x00, /* bmCapabilities: D0+D1 */
|
||||
0x02, /* bDataInterface: 2 */
|
||||
|
||||
/*************** ACM Functional Descriptor ***************/
|
||||
/*59*/ 0x04, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
|
||||
0x06, /* bmCapabilities XXX was:0x02? */
|
||||
|
||||
/************* Union Functional Descriptor **************/
|
||||
/*63*/ 0x05, /* bFunctionLength */
|
||||
0x24, /* bDescriptorType: CS_INTERFACE */
|
||||
0x06, /* bDescriptorSubtype: Union func desc */
|
||||
0x01, /* bMasterInterface: Communication class interface */
|
||||
0x02, /* bSlaveInterface0: Data Class Interface */
|
||||
|
||||
/******************** CDC Endpoints ********************/
|
||||
|
||||
/// Command endpoint
|
||||
/*68*/ 0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_CMD_EP, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes: Interrupt */
|
||||
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: TODO: 2?*/
|
||||
HIBYTE(CDC_CMD_PACKET_SIZE),
|
||||
0xFF, /* bInterval: TODO was 0x10?*/
|
||||
|
||||
/********** CDC Data Class Interface Descriptor ***********/
|
||||
/*75*/ 0x09, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
|
||||
0x02, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints: Two endpoints used */
|
||||
0x0A, /* bInterfaceClass: CDC */ // #80
|
||||
0x00, /* bInterfaceSubClass: */
|
||||
0x00, /* bInterfaceProtocol: */
|
||||
0x06, /* iInterface: TODO: string descriptor */
|
||||
|
||||
/// Endpoint OUT Descriptor
|
||||
/*84*/ 0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: TODO 8? */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00, /* bInterval: ignore for Bulk transfer */
|
||||
|
||||
/// Endpoint IN Descriptor
|
||||
/*91*/ 0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||
CDC_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes: Bulk */
|
||||
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: TODO 16? */
|
||||
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
|
||||
0x00 /* bInterval: ignore for Bulk transfer */
|
||||
};
|
||||
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
__ALIGN_BEGIN uint8_t USBD_MSC_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
|
||||
{
|
||||
USB_LEN_DEV_QUALIFIER_DESC,
|
||||
USB_DESC_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
MSC_MAX_FS_PACKET,
|
||||
0x01,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static uint8_t USBD_MSC_CDC_Init(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
// this is not correct, but will work if neither returns BUSY (which they don't)
|
||||
uint8_t ret = 0;
|
||||
ret |= USBD_MSC_Init(pdev, cfgidx);
|
||||
ret |= USBD_CDC_Init(pdev, cfgidx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t USBD_MSC_CDC_DeInit(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
ret |= USBD_MSC_DeInit(pdev, cfgidx);
|
||||
ret |= USBD_CDC_DeInit(pdev, cfgidx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Control Endpoints*/
|
||||
static uint8_t USBD_MSC_CDC_Setup(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
|
||||
{
|
||||
static uint8_t interface_bit;
|
||||
|
||||
// handle common
|
||||
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
|
||||
case USB_REQ_TYPE_STANDARD:
|
||||
switch (req->bRequest) {
|
||||
// those don't really do anything useful, but each class implements
|
||||
// them and it would send the data twice.
|
||||
case USB_REQ_GET_INTERFACE :
|
||||
USBD_CtlSendData(pdev, &interface_bit, 1);
|
||||
return USBD_OK;
|
||||
|
||||
case USB_REQ_SET_INTERFACE :
|
||||
interface_bit = (uint8_t) (req->wValue);
|
||||
return USBD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// class specific, or Interface -> Clear Feature
|
||||
USBD_MSC_Setup(pdev, req);
|
||||
USBD_CDC_Setup(pdev, req);
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static uint8_t USBD_MSC_CDC_EP0_TxSent(struct _USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
// not handled by either
|
||||
xTaskNotify(tskUsbEventHandle, USBEVT_FLAG_EP0_TX_SENT, eSetBits);
|
||||
return USBD_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t USBD_MSC_CDC_EP0_RxReady(struct _USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(tskMainHandle, USBEVT_FLAG_EP0_RX_RDY, eSetBits, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
//USBD_CDC_EP0_RxReady(pdev);
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
/* Class Specific Endpoints*/
|
||||
static uint8_t USBD_MSC_CDC_DataIn(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(tskMainHandle, USBEVT_FLAG_EPx_IN(epnum), eSetBits, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
// if (epnum == MSC_EPIN_ADDR||epnum==MSC_EPOUT_ADDR) USBD_MSC_DataIn(pdev, epnum);
|
||||
// else if (epnum == CDC_IN_EP||epnum == CDC_CMD_EP) USBD_CDC_DataIn(pdev, epnum);
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint8_t USBD_MSC_CDC_DataOut(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTaskNotifyFromISR(tskMainHandle, USBEVT_FLAG_EPx_OUT(epnum), eSetBits, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
// if (epnum == MSC_EPIN_ADDR||epnum == MSC_EPOUT_ADDR) USBD_MSC_DataOut(pdev, epnum);
|
||||
// else if (epnum == CDC_OUT_EP||epnum == CDC_CMD_EP) USBD_CDC_DataOut(pdev, epnum);
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static uint8_t USBD_MSC_CDC_SOF(struct _USBD_HandleTypeDef *pdev)
|
||||
{
|
||||
// not handled by either
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint8_t USBD_MSC_CDC_IsoINIncomplete(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
// not handled by either
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint8_t USBD_MSC_CDC_IsoOUTIncomplete(struct _USBD_HandleTypeDef *pdev, uint8_t epnum)
|
||||
{
|
||||
// not handled by either
|
||||
return USBD_OK;
|
||||
}
|
||||
|
||||
static uint8_t *USBD_MSC_CDC_GetUsrStrDescriptor(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
|
||||
{
|
||||
// not handled by either
|
||||
return USBD_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
uint8_t *USBD_MSC_CDC_GetHSCfgDesc (uint16_t *length)
|
||||
{
|
||||
// *length = sizeof (USBD_MSC_CDC_CfgHSDesc);
|
||||
// return USBD_MSC_CDC_CfgHSDesc;
|
||||
*length = sizeof (USBD_MSC_CDC_CfgFSDesc);
|
||||
return USBD_MSC_CDC_CfgFSDesc;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t *USBD_MSC_CDC_GetFSCfgDesc (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (USBD_MSC_CDC_CfgFSDesc);
|
||||
|
||||
// Optionally hide CDC-ACM by setting its class to Vendor Specific
|
||||
bool cdc_visible = SystemSettings.visible_vcom;
|
||||
USBD_MSC_CDC_CfgFSDesc[36] = (uint8_t) (cdc_visible ? 0x02 : 0xFF);
|
||||
USBD_MSC_CDC_CfgFSDesc[45] = (uint8_t) (cdc_visible ? 0x02 : 0xFF);
|
||||
USBD_MSC_CDC_CfgFSDesc[80] = (uint8_t) (cdc_visible ? 0x0A : 0xFF);
|
||||
|
||||
// Optionally hide settings (if lock jumper is installed)
|
||||
bool msc_visible = SystemSettings.editable;
|
||||
USBD_MSC_CDC_CfgFSDesc[14] = (uint8_t) (msc_visible ? 0x08 : 0xFF);
|
||||
|
||||
return USBD_MSC_CDC_CfgFSDesc;
|
||||
}
|
||||
|
||||
#if 0
|
||||
uint8_t *USBD_MSC_CDC_GetOtherSpeedCfgDesc (uint16_t *length)
|
||||
{
|
||||
// *length = sizeof (USBD_MSC_CDC_OtherSpeedCfgDesc);
|
||||
// return USBD_MSC_CDC_OtherSpeedCfgDesc;
|
||||
*length = sizeof (USBD_MSC_CDC_CfgFSDesc);
|
||||
return USBD_MSC_CDC_CfgFSDesc;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t *USBD_MSC_CDC_GetDeviceQualifierDescriptor (uint16_t *length)
|
||||
{
|
||||
*length = sizeof (USBD_MSC_CDC_DeviceQualifierDesc);
|
||||
return USBD_MSC_CDC_DeviceQualifierDesc;
|
||||
}
|
||||
|
||||
uint8_t *USBD_MSC_CDC_GetUsrStrDescriptor(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length)
|
||||
{
|
||||
const char *str;
|
||||
switch (index) {
|
||||
case 0x04: str = "Settings Virtual Mass Storage"; break;
|
||||
case 0x05: str = "Virtual Comport ACM"; break;
|
||||
case 0x06: str = "Virtual Comport CDC"; break;
|
||||
default: str = "No Descriptor";
|
||||
}
|
||||
USBD_GetString ((uint8_t *) str, USBD_StrDesc, length);
|
||||
return USBD_StrDesc;
|
||||
}
|
||||
|
||||
USBD_ClassTypeDef USBD_MSC_CDC =
|
||||
{
|
||||
USBD_MSC_CDC_Init,
|
||||
USBD_MSC_CDC_DeInit,
|
||||
USBD_MSC_CDC_Setup,
|
||||
|
||||
NULL, // USBD_MSC_CDC_EP0_TxSent,
|
||||
USBD_MSC_CDC_EP0_RxReady,
|
||||
|
||||
USBD_MSC_CDC_DataIn,
|
||||
USBD_MSC_CDC_DataOut,
|
||||
|
||||
NULL, // USBD_MSC_CDC_SOF,
|
||||
NULL, // USBD_MSC_CDC_IsoINIncomplete,
|
||||
NULL, // USBD_MSC_CDC_IsoOUTIncomplete,
|
||||
|
||||
// we return only the FS one, others are useless
|
||||
USBD_MSC_CDC_GetFSCfgDesc, //USBD_MSC_CDC_GetHSCfgDesc,
|
||||
USBD_MSC_CDC_GetFSCfgDesc,
|
||||
USBD_MSC_CDC_GetFSCfgDesc, //USBD_MSC_CDC_GetOtherSpeedCfgDesc,
|
||||
|
||||
USBD_MSC_CDC_GetDeviceQualifierDescriptor,
|
||||
USBD_MSC_CDC_GetUsrStrDescriptor
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/11/07.
|
||||
//
|
||||
|
||||
#ifndef GEX_USBD_CDC_MSC_H
|
||||
#define GEX_USBD_CDC_MSC_H
|
||||
|
||||
#include "usbd_def.h"
|
||||
extern USBD_ClassTypeDef USBD_MSC_CDC;
|
||||
|
||||
#endif //GEX_USBD_CDC_MSC_H
|
||||
Reference in New Issue
Block a user