mirror of
https://github.com/tillitis/tillitis-key1.git
synced 2025-07-22 06:39:18 -04:00
ch552: Add CCID (Smart Card) support
This commit is contained in:
parent
d0c049cdba
commit
770acc9b38
6 changed files with 370 additions and 39 deletions
|
@ -64,8 +64,9 @@ The different endpoints:
|
||||||
|
|
||||||
| *Name* | *Value* | *Comment* |
|
| *Name* | *Value* | *Comment* |
|
||||||
|--------|---------|----------------------------------------------------------------------|
|
|--------|---------|----------------------------------------------------------------------|
|
||||||
| DEBUG | 0x20 | A USB HID special debug pipe. Useful for debug prints. |
|
| CCID | 0x08 | USB CCID, a port for emulating a smart card |
|
||||||
| CH552 | 0x10 | USB controller control |
|
| CH552 | 0x10 | USB controller control |
|
||||||
|
| DEBUG | 0x20 | A USB HID special debug pipe. Useful for debug prints. |
|
||||||
| CDC | 0x40 | USB CDC-ACM, a serial port on the client. |
|
| CDC | 0x40 | USB CDC-ACM, a serial port on the client. |
|
||||||
| FIDO | 0x80 | A USB FIDO security token device, useful for FIDO-type applications. |
|
| FIDO | 0x80 | A USB FIDO security token device, useful for FIDO-type applications. |
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ if __name__ == "__main__":
|
||||||
"CdcCtrlInterfaceDesc": "CDC-Ctrl",
|
"CdcCtrlInterfaceDesc": "CDC-Ctrl",
|
||||||
"CdcDataInterfaceDesc": "CDC-Data",
|
"CdcDataInterfaceDesc": "CDC-Data",
|
||||||
"FidoInterfaceDesc": "FIDO",
|
"FidoInterfaceDesc": "FIDO",
|
||||||
|
"CcidInterfaceDesc": "CCID",
|
||||||
"DebugInterfaceDesc": "DEBUG"
|
"DebugInterfaceDesc": "DEBUG"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,13 @@ Header file for CH554 microcontrollers.
|
||||||
#define USB_CDC_REQ_TYPE_SET_CONTROL_LINE_STATE 0x22
|
#define USB_CDC_REQ_TYPE_SET_CONTROL_LINE_STATE 0x22
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* USB CCID (Smart Card) class request code */
|
||||||
|
#ifndef USB_CCID_REQ_TYPE
|
||||||
|
#define USB_CCID_REQ_TYPE_ABORT 0x01
|
||||||
|
#define USB_CCID_REQ_TYPE_GET_CLOCK_FREQUENCIES 0x02
|
||||||
|
#define USB_CCID_REQ_TYPE_GET_DATA_RATES 0x03
|
||||||
|
#endif
|
||||||
|
|
||||||
/* USB request type for hub class request */
|
/* USB request type for hub class request */
|
||||||
#ifndef HUB_GET_HUB_DESCRIPTOR
|
#ifndef HUB_GET_HUB_DESCRIPTOR
|
||||||
#define HUB_CLEAR_HUB_FEATURE 0x20
|
#define HUB_CLEAR_HUB_FEATURE 0x20
|
||||||
|
@ -200,7 +207,8 @@ Header file for CH554 microcontrollers.
|
||||||
#define USB_IDX_INTERFACE_CDC_CTRL_STR 0x04
|
#define USB_IDX_INTERFACE_CDC_CTRL_STR 0x04
|
||||||
#define USB_IDX_INTERFACE_CDC_DATA_STR 0x05
|
#define USB_IDX_INTERFACE_CDC_DATA_STR 0x05
|
||||||
#define USB_IDX_INTERFACE_FIDO_STR 0x06
|
#define USB_IDX_INTERFACE_FIDO_STR 0x06
|
||||||
#define USB_IDX_INTERFACE_DEBUG_STR 0x07
|
#define USB_IDX_INTERFACE_CCID_STR 0x07
|
||||||
|
#define USB_IDX_INTERFACE_DEBUG_STR 0x08
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USB_DEVICE_ADDR
|
#ifndef USB_DEVICE_ADDR
|
||||||
|
|
|
@ -8,14 +8,16 @@ enum ioend {
|
||||||
IO_NONE = 0x00, // No endpoint
|
IO_NONE = 0x00, // No endpoint
|
||||||
IO_UART = 0x01, // Only destination, raw UART access
|
IO_UART = 0x01, // Only destination, raw UART access
|
||||||
IO_QEMU = 0x02, // Only destination, QEMU debug port
|
IO_QEMU = 0x02, // Only destination, QEMU debug port
|
||||||
IO_CH552 = 0x10, // Internal CH552 control port
|
IO_CH552 = 0x04, // Internal CH552 control port
|
||||||
IO_DEBUG = 0x20, // HID debug port
|
IO_CDC = 0x08, // CDC "serial" port
|
||||||
IO_CDC = 0x40, // CDC "serial port"
|
IO_FIDO = 0x10, // FIDO security token port
|
||||||
IO_FIDO = 0x80, // FIDO security token port
|
IO_CCID = 0x20, // CCID "smart card" port
|
||||||
|
IO_DEBUG = 0x40, // Debug port over USB HID
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ch552cmd {
|
enum ch552cmd {
|
||||||
SET_ENDPOINTS = 0x01, // Config enabled/disabled USB endpoints on the CH552
|
SET_ENDPOINTS = 0x01, // Config USB endpoints on the CH552
|
||||||
|
CH552_CMD_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,6 +55,12 @@ unsigned char FLASH FidoInterfaceDesc[] = { // "FIDO"
|
||||||
'F', 0, 'I', 0, 'D', 0, 'O', 0,
|
'F', 0, 'I', 0, 'D', 0, 'O', 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned char FLASH CcidInterfaceDesc[] = { // "CCID"
|
||||||
|
10, // Length of this descriptor (in bytes)
|
||||||
|
0x03, // Descriptor type (String)
|
||||||
|
'C', 0, 'C', 0, 'I', 0, 'D', 0,
|
||||||
|
};
|
||||||
|
|
||||||
unsigned char FLASH DebugInterfaceDesc[] = { // "DEBUG"
|
unsigned char FLASH DebugInterfaceDesc[] = { // "DEBUG"
|
||||||
12, // Length of this descriptor (in bytes)
|
12, // Length of this descriptor (in bytes)
|
||||||
0x03, // Descriptor type (String)
|
0x03, // Descriptor type (String)
|
||||||
|
|
|
@ -55,6 +55,12 @@ const uint8_t *pDescr = NULL; // USB configuration flag
|
||||||
#define FIDO_EPIN_ADDR 0x83 // FIDO Endpoint IN Address
|
#define FIDO_EPIN_ADDR 0x83 // FIDO Endpoint IN Address
|
||||||
#define FIDO_EPIN_SIZE MAX_PACKET_SIZE // FIDO Endpoint IN Size
|
#define FIDO_EPIN_SIZE MAX_PACKET_SIZE // FIDO Endpoint IN Size
|
||||||
|
|
||||||
|
#define CCID_BULK_EPOUT_ADDR 0x03 // CCID Bulk Endpoint OUT Address
|
||||||
|
#define CCID_BULK_EPOUT_SIZE MAX_PACKET_SIZE // CCID Bulk Endpoint OUT Size
|
||||||
|
|
||||||
|
#define CCID_BULK_EPIN_ADDR 0x83 // CCID Bulk Endpoint IN Address
|
||||||
|
#define CCID_BULK_EPIN_SIZE MAX_PACKET_SIZE // CCID Bulk Endpoint IN Size
|
||||||
|
|
||||||
#define DEBUG_EPOUT_ADDR 0x04 // DEBUG Endpoint OUT Address
|
#define DEBUG_EPOUT_ADDR 0x04 // DEBUG Endpoint OUT Address
|
||||||
#define DEBUG_EPOUT_SIZE MAX_PACKET_SIZE // DEBUG Endpoint OUT Size
|
#define DEBUG_EPOUT_SIZE MAX_PACKET_SIZE // DEBUG Endpoint OUT Size
|
||||||
|
|
||||||
|
@ -64,21 +70,47 @@ const uint8_t *pDescr = NULL; // USB configuration flag
|
||||||
#define CDC_CTRL_FS_BINTERVAL 32 // Gives 32 ms polling interval at Full Speed for interrupt transfers
|
#define CDC_CTRL_FS_BINTERVAL 32 // Gives 32 ms polling interval at Full Speed for interrupt transfers
|
||||||
#define CDC_DATA_FS_BINTERVAL 0 // bInterval is ignored for BULK transfers
|
#define CDC_DATA_FS_BINTERVAL 0 // bInterval is ignored for BULK transfers
|
||||||
#define FIDO_FS_BINTERVAL 2 // Gives 2 ms polling interval at Full Speed for interrupt transfers
|
#define FIDO_FS_BINTERVAL 2 // Gives 2 ms polling interval at Full Speed for interrupt transfers
|
||||||
|
#define CCID_BULK_FS_BINTERVAL 0 // bInterval is ignored for BULK transfers
|
||||||
#define DEBUG_FS_BINTERVAL 2 // Gives 2 ms polling interval at Full Speed for interrupt transfers
|
#define DEBUG_FS_BINTERVAL 2 // Gives 2 ms polling interval at Full Speed for interrupt transfers
|
||||||
|
|
||||||
#define CFG_DESC_SIZE 139U // Size of Cfg_Desc
|
#define MAX_CFG_DESC_SIZE (9+66+77+32) // Size of CfgDesc+CdcDesc+MAX(FidoDesc,CcidDesc)+DebugDesc
|
||||||
|
|
||||||
#define NUM_INTERFACES 4 // Number of interfaces
|
#define NUM_INTERFACES 4 // Number of interfaces
|
||||||
|
|
||||||
|
#define CHANGE_ME 0x00 // Value placeholder
|
||||||
|
|
||||||
#define FIDO_REPORT_DESC_SIZE 47 // Size of FidoReportDesc
|
#define FIDO_REPORT_DESC_SIZE 47 // Size of FidoReportDesc
|
||||||
#define DEBUG_REPORT_DESC_SIZE 34 // Size of DebugReportDesc
|
#define DEBUG_REPORT_DESC_SIZE 34 // Size of DebugReportDesc
|
||||||
|
|
||||||
|
#define CCID_VALUE_BCDCCID 0x0110
|
||||||
|
#define CCID_VALUE_DWPROTOCOLS 0x00000002
|
||||||
|
#define CCID_VALUE_DWDEFAULTCLOCK 3580
|
||||||
|
#define CCID_VALUE_DWMAXIUMUMCLOCK 3580
|
||||||
|
#define CCID_VALUE_DWDATARATE 9600
|
||||||
|
#define CCID_VALUE_DWMAXDATARATE 9600
|
||||||
|
#define CCID_VALUE_DWMAXIFSD 254
|
||||||
|
#define CCID_VALUE_DWSYNCPROTOCOLS 0x0
|
||||||
|
#define CCID_VALUE_DWMECHANICAL 0x0
|
||||||
|
#define CCID_VALUE_DWFEATURES 0x000400FE
|
||||||
|
#define CCID_VALUE_DWMAXCCIDMESSAGELENGTH 3072
|
||||||
|
#define CCID_VALUE_WLCDLAYOUT 0x0
|
||||||
|
|
||||||
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
#define LOBYTE(x) ((uint8_t)( (x) & 0x00FFU))
|
#define LOBYTE(x) ((uint8_t)( (x) & 0x00FFU))
|
||||||
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U))
|
#define HIBYTE(x) ((uint8_t)(((x) >> 8U) & 0x00FFU))
|
||||||
|
|
||||||
|
#define BYTE0(x) ((uint8_t)( (x) & 0x000000FFU)) // Least significant byte
|
||||||
|
#define BYTE1(x) ((uint8_t)(((x) >> 8) & 0x000000FFU)) // Second byte
|
||||||
|
#define BYTE2(x) ((uint8_t)(((x) >> 16) & 0x000000FFU)) // Third byte
|
||||||
|
#define BYTE3(x) ((uint8_t)(((x) >> 24) & 0x000000FFU)) // Most significant byte
|
||||||
|
|
||||||
IDATA uint8_t FidoInterfaceNum = 0;
|
IDATA uint8_t FidoInterfaceNum = 0;
|
||||||
|
IDATA uint8_t CcidInterfaceNum = 0;
|
||||||
IDATA uint8_t DebugInterfaceNum = 0;
|
IDATA uint8_t DebugInterfaceNum = 0;
|
||||||
|
|
||||||
XDATA uint8_t ActiveCfgDesc[CFG_DESC_SIZE];
|
XDATA uint8_t ActiveCfgDesc[MAX_CFG_DESC_SIZE];
|
||||||
XDATA uint8_t ActiveCfgDescSize = 0;
|
XDATA uint8_t ActiveCfgDescSize = 0;
|
||||||
|
|
||||||
// Device Descriptor
|
// Device Descriptor
|
||||||
|
@ -101,6 +133,7 @@ FLASH uint8_t DevDesc[] = {
|
||||||
USB_IDX_PRODUCT_STR, /* Index of product string */
|
USB_IDX_PRODUCT_STR, /* Index of product string */
|
||||||
USB_IDX_SERIAL_STR, /* Index of serial number string */
|
USB_IDX_SERIAL_STR, /* Index of serial number string */
|
||||||
0x01, /* bNumConfigurations */
|
0x01, /* bNumConfigurations */
|
||||||
|
/* 18 */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Configuration Descriptor
|
// Configuration Descriptor
|
||||||
|
@ -108,9 +141,9 @@ FLASH uint8_t CfgDesc[] = {
|
||||||
/******************** Configuration Descriptor ********************/
|
/******************** Configuration Descriptor ********************/
|
||||||
0x09, /* bLength: Configuration Descriptor size */
|
0x09, /* bLength: Configuration Descriptor size */
|
||||||
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
|
||||||
CFG_DESC_SIZE, /* wTotalLength (low byte): Bytes returned */
|
CHANGE_ME, /* wTotalLength (low byte): Bytes returned */
|
||||||
0x00, /* wTotalLength (high byte): Bytes returned */
|
0x00, /* wTotalLength (high byte): Bytes returned */
|
||||||
NUM_INTERFACES, /* bNumInterfaces: 4 interfaces (1 CDC Ctrl, 1 CDC Data, 1 FIDO, 1 DEBUG ) */
|
CHANGE_ME, /* bNumInterfaces: 1 CDC Ctrl + 1 CDC Data, 1 FIDO or 1 CCID, 1 DEBUG ) */
|
||||||
0x01, /* bConfigurationValue: Configuration value */
|
0x01, /* bConfigurationValue: Configuration value */
|
||||||
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
|
||||||
0xA0, /* bmAttributes: Bus powered and Support Remote Wake-up */
|
0xA0, /* bmAttributes: Bus powered and Support Remote Wake-up */
|
||||||
|
@ -126,17 +159,17 @@ FLASH uint8_t CdcDesc[] = {
|
||||||
USB_DESC_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType: Interface Association */
|
USB_DESC_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType: Interface Association */
|
||||||
0x00, /* bFirstInterface: 0 */
|
0x00, /* bFirstInterface: 0 */
|
||||||
0x02, /* bInterfaceCount: 2 */
|
0x02, /* bInterfaceCount: 2 */
|
||||||
0x02, /* bFunctionClass: Communications & CDC Control */
|
USB_DEV_CLASS_CDC_CONTROL, /* bFunctionClass: Communications & CDC Control */
|
||||||
0x02, /* bFunctionSubClass: Abstract Control Model */
|
0x02, /* bFunctionSubClass: Abstract Control Model */
|
||||||
0x01, /* bFunctionProtocol: Common AT commands */
|
0x01, /* bFunctionProtocol: Common AT commands */
|
||||||
0x00, /* iFunction: Index of string descriptor */
|
0x00, /* iFunction: Index of string descriptor */
|
||||||
/******************** Interface 0, CDC Ctrl Descriptor (one endpoint) ********************/
|
/******************** Interface, CDC Ctrl Descriptor (one endpoint) ********************/
|
||||||
/* 8 */
|
/* 8 */
|
||||||
0x09, /* bLength: Interface Descriptor size */
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
0x00, /* bInterfaceNumber: Number of Interface */
|
CHANGE_ME, /* bInterfaceNumber: Number of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x01, /* bNumEndpoints */
|
0x01, /* bNumEndpoints: Number of endpoints in Interface */
|
||||||
USB_DEV_CLASS_CDC_CONTROL, /* bInterfaceClass: Communications and CDC Control */
|
USB_DEV_CLASS_CDC_CONTROL, /* bInterfaceClass: Communications and CDC Control */
|
||||||
0x02, /* bInterfaceSubClass : Abstract Control Model */
|
0x02, /* bInterfaceSubClass : Abstract Control Model */
|
||||||
0x01, /* bInterfaceProtocol : AT Commands: V.250 etc */
|
0x01, /* bInterfaceProtocol : AT Commands: V.250 etc */
|
||||||
|
@ -144,14 +177,14 @@ FLASH uint8_t CdcDesc[] = {
|
||||||
/******************** Header Functional Descriptor ********************/
|
/******************** Header Functional Descriptor ********************/
|
||||||
/* 17 */
|
/* 17 */
|
||||||
0x05, /* bFunctionLength: Size of this descriptor in bytes */
|
0x05, /* bFunctionLength: Size of this descriptor in bytes */
|
||||||
USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE (24h) */
|
USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: Class-Specific Interface */
|
||||||
0x00, /* bDescriptorSubtype: Header Functional Descriptor */
|
0x00, /* bDescriptorSubtype: Header Functional Descriptor */
|
||||||
0x10, /* bcdCDC (low byte): CDC version 1.10 */
|
0x10, /* bcdCDC (low byte): CDC version 1.10 */
|
||||||
0x01, /* bcdCDC (high byte): CDC version 1.10 */
|
0x01, /* bcdCDC (high byte): CDC version 1.10 */
|
||||||
/******************** Call Management Functional Descriptor (no data interface, bmCapabilities=03, bDataInterface=01) ********************/
|
/******************** Call Management Functional Descriptor (no data interface, bmCapabilities=03, bDataInterface=01) ********************/
|
||||||
/* 22 */
|
/* 22 */
|
||||||
0x05, /* bFunctionLength: Size of this descriptor */
|
0x05, /* bFunctionLength: Size of this descriptor */
|
||||||
USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE (24h) */
|
USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: Class-Specific Interface */
|
||||||
0x01, /* bDescriptorSubtype: Call Management Functional Descriptor */
|
0x01, /* bDescriptorSubtype: Call Management Functional Descriptor */
|
||||||
0x00, /* bmCapabilities:
|
0x00, /* bmCapabilities:
|
||||||
D7..2: 0x00 (RESERVED,
|
D7..2: 0x00 (RESERVED,
|
||||||
|
@ -163,7 +196,7 @@ FLASH uint8_t CdcDesc[] = {
|
||||||
/******************** Abstract Control Management Functional Descriptor ********************/
|
/******************** Abstract Control Management Functional Descriptor ********************/
|
||||||
/* 27 */
|
/* 27 */
|
||||||
0x04, /* bLength */
|
0x04, /* bLength */
|
||||||
0x24, /* bDescriptorType: CS_INTERFACE (24h) */
|
USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: Class-Specific Interface */
|
||||||
0x02, /* bDescriptorSubtype: Abstract Control Management Functional Descriptor */
|
0x02, /* bDescriptorSubtype: Abstract Control Management Functional Descriptor */
|
||||||
0x02, /* bmCapabilities:
|
0x02, /* bmCapabilities:
|
||||||
D7..4: 0x00 (RESERVED, Reset to zero)
|
D7..4: 0x00 (RESERVED, Reset to zero)
|
||||||
|
@ -174,7 +207,7 @@ FLASH uint8_t CdcDesc[] = {
|
||||||
/******************** Union Functional Descriptor. CDC Ctrl interface numbered 0; CDC Data interface numbered 1 ********************/
|
/******************** Union Functional Descriptor. CDC Ctrl interface numbered 0; CDC Data interface numbered 1 ********************/
|
||||||
/* 31 */
|
/* 31 */
|
||||||
0x05, /* bLength */
|
0x05, /* bLength */
|
||||||
0x24, /* bDescriptorType: CS_INTERFACE (24h) */
|
USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: Class-Specific Interface */
|
||||||
0x06, /* bDescriptorSubtype: Union Functional Descriptor */
|
0x06, /* bDescriptorSubtype: Union Functional Descriptor */
|
||||||
0x00, /* bControlInterface: Interface number 0 (Control interface) */
|
0x00, /* bControlInterface: Interface number 0 (Control interface) */
|
||||||
0x01, /* bSubordinateInterface0: Interface number 1 (Data interface) */
|
0x01, /* bSubordinateInterface0: Interface number 1 (Data interface) */
|
||||||
|
@ -187,13 +220,13 @@ FLASH uint8_t CdcDesc[] = {
|
||||||
LOBYTE(CDC_CTRL_EPIN_SIZE), /* wMaxPacketSize (low byte): 8 Byte max */
|
LOBYTE(CDC_CTRL_EPIN_SIZE), /* wMaxPacketSize (low byte): 8 Byte max */
|
||||||
HIBYTE(CDC_CTRL_EPIN_SIZE), /* wMaxPacketSize (high byte): 8 Byte max */
|
HIBYTE(CDC_CTRL_EPIN_SIZE), /* wMaxPacketSize (high byte): 8 Byte max */
|
||||||
CDC_CTRL_FS_BINTERVAL, /* bInterval: Polling Interval */
|
CDC_CTRL_FS_BINTERVAL, /* bInterval: Polling Interval */
|
||||||
/******************** Interface 1, CDC Data Descriptor (two endpoints) ********************/
|
/******************** Interface, CDC Data Descriptor (two endpoints) ********************/
|
||||||
/* 43 */
|
/* 43 */
|
||||||
0x09, /* bLength: Interface Descriptor size */
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
0x01, /* bInterfaceNumber: Number of Interface */
|
CHANGE_ME, /* bInterfaceNumber: Number of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x02, /* bNumEndpoints */
|
0x02, /* bNumEndpoints: Number of endpoints in Interface */
|
||||||
USB_DEV_CLASS_CDC_DATA, /* bInterfaceClass: CDC Data */
|
USB_DEV_CLASS_CDC_DATA, /* bInterfaceClass: CDC Data */
|
||||||
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||||
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||||
|
@ -221,12 +254,12 @@ FLASH uint8_t CdcDesc[] = {
|
||||||
|
|
||||||
// FIDO Descriptor
|
// FIDO Descriptor
|
||||||
FLASH uint8_t FidoDesc[] = {
|
FLASH uint8_t FidoDesc[] = {
|
||||||
/******************** Interface 2, FIDO Descriptor (two endpoints) ********************/
|
/******************** Interface, FIDO Descriptor (two endpoints) ********************/
|
||||||
0x09, /* bLength: Interface Descriptor size */
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
0x02, /* bInterfaceNumber: Number of Interface */
|
CHANGE_ME, /* bInterfaceNumber: Number of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x02, /* bNumEndpoints: 2 */
|
0x02, /* bNumEndpoints: Number of endpoints in Interface */
|
||||||
USB_DEV_CLASS_HID, /* bInterfaceClass: Human Interface Device */
|
USB_DEV_CLASS_HID, /* bInterfaceClass: Human Interface Device */
|
||||||
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||||
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||||
|
@ -263,14 +296,207 @@ FLASH uint8_t FidoDesc[] = {
|
||||||
/* 32 */
|
/* 32 */
|
||||||
};
|
};
|
||||||
|
|
||||||
// DEBUG Descriptor
|
// CCID Descriptor
|
||||||
FLASH uint8_t DebugDesc[] = {
|
FLASH uint8_t CcidDesc[] = {
|
||||||
/******************** Interface 3, DEBUG Descriptor (two endpoints) ********************/
|
/******************** Interface, CCID Descriptor (two endpoints) ********************/
|
||||||
0x09, /* bLength: Interface Descriptor size */
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
0x03, /* bInterfaceNumber: Number of Interface */
|
CHANGE_ME, /* bInterfaceNumber: Number of Interface */
|
||||||
0x00, /* bAlternateSetting: Alternate setting */
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
0x02, /* bNumEndpoints: 2 */
|
0x02, /* bNumEndpoints: Number of endpoints in Interface */
|
||||||
|
USB_DEV_CLASS_SMART_CARD, /* bInterfaceClass: Smart Card */
|
||||||
|
0x00, /* bInterfaceSubClass : Subclass code */
|
||||||
|
0x00, /* bInterfaceProtocol : For Integrated Circuit(s) Cards Interface Devices (CCID): 00h
|
||||||
|
Note: For competitiveness, values 01h and 02h are reserved for Integrated Circuit(s)
|
||||||
|
Cards Devices (USB-ICC) and other values are reserved for future use. */
|
||||||
|
USB_IDX_INTERFACE_CCID_STR, /* iInterface: Index of string descriptor */
|
||||||
|
/******************** CCID Device Descriptor ********************/
|
||||||
|
/* 9 */
|
||||||
|
0x36, /* bLength: Size of this descriptor in bytes */
|
||||||
|
USB_DESC_TYPE_HID, /* bDescriptorType: HID */
|
||||||
|
LOBYTE(CCID_VALUE_BCDCCID), /* bcdCCID (low byte)*/
|
||||||
|
HIBYTE(CCID_VALUE_BCDCCID), /* bcdCCID (high byte): 0x0110
|
||||||
|
CCID Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 0210h) */
|
||||||
|
0x00, /* bMaxSlotIndex: 0
|
||||||
|
The index of the highest available slot on this device.
|
||||||
|
All slots are consecutive starting at 00h.
|
||||||
|
i.e. 0Fh = 16 slots on this device numbered 00h to 0Fh. */
|
||||||
|
0x07, /* bVoltageSupport: 7
|
||||||
|
This value indicates what voltages the CCID can supply to its slots.
|
||||||
|
It is a bitwise OR operation performed on the following values:
|
||||||
|
- 01h 5.0V
|
||||||
|
- 02h 3.0V
|
||||||
|
- 04h 1.8V
|
||||||
|
Other bits are RFU */
|
||||||
|
BYTE0(CCID_VALUE_DWPROTOCOLS), /* dwProtocols */
|
||||||
|
BYTE1(CCID_VALUE_DWPROTOCOLS), /* dwProtocols */
|
||||||
|
BYTE2(CCID_VALUE_DWPROTOCOLS), /* dwProtocols */
|
||||||
|
BYTE3(CCID_VALUE_DWPROTOCOLS), /* dwProtocols: T=1
|
||||||
|
RRRR –Upper Word- is RFU = 0000h
|
||||||
|
PPPP –Lower Word- Encodes the supported protocol types.
|
||||||
|
A ‘1’ in a given bit position indicates support for the associated ISO protocol.
|
||||||
|
0001h = Protocol T=0
|
||||||
|
0002h = Protocol T=1
|
||||||
|
All other bits are reserved and must be set to zero.
|
||||||
|
The field is intended to correspond to the PCSC specification definitions.
|
||||||
|
See PCSC Part3. Table 3-1 Tag 0x0120.
|
||||||
|
Example: 00000003h indicates support for T = 0 and T = 1. */
|
||||||
|
BYTE0(CCID_VALUE_DWDEFAULTCLOCK), /* dwDefaultClock */
|
||||||
|
BYTE1(CCID_VALUE_DWDEFAULTCLOCK), /* dwDefaultClock */
|
||||||
|
BYTE2(CCID_VALUE_DWDEFAULTCLOCK), /* dwDefaultClock */
|
||||||
|
BYTE3(CCID_VALUE_DWDEFAULTCLOCK), /* dwDefaultClock: 3580 KHz
|
||||||
|
Default ICC clock frequency in KHz. This is an integer value.
|
||||||
|
Example: 3.58 MHz is encoded as the integer value 3580. (00000DFCh)
|
||||||
|
This is used in ETU and waiting time calculations.
|
||||||
|
It is the clock frequency used when reading the ATR data. */
|
||||||
|
BYTE0(CCID_VALUE_DWMAXIUMUMCLOCK),/* dwMaximumClock */
|
||||||
|
BYTE1(CCID_VALUE_DWMAXIUMUMCLOCK),/* dwMaximumClock */
|
||||||
|
BYTE2(CCID_VALUE_DWMAXIUMUMCLOCK),/* dwMaximumClock */
|
||||||
|
BYTE3(CCID_VALUE_DWMAXIUMUMCLOCK),/* dwMaximumClock: 3580 KHz
|
||||||
|
Maximum supported ICC clock frequency in KHz. This is an integer value.
|
||||||
|
Example: 14.32 MHz is encoded as the integer value 14320. (000037F0h) */
|
||||||
|
0x00, /* bNumClockSupported: 0
|
||||||
|
The number of clock frequencies that are supported by the CCID.
|
||||||
|
If the value is 00h, the supported clock frequencies are assumed to be the default clock
|
||||||
|
frequency defined by dwDefaultClock and the maximum clock frequency defined by dwMaximumClock.
|
||||||
|
The reader must implement the command PC_to_RDR_SetDataRateAndClockFrequency if more than one
|
||||||
|
clock frequency is supported. */
|
||||||
|
BYTE0(CCID_VALUE_DWDATARATE), /* dwDataRate */
|
||||||
|
BYTE1(CCID_VALUE_DWDATARATE), /* dwDataRate */
|
||||||
|
BYTE2(CCID_VALUE_DWDATARATE), /* dwDataRate */
|
||||||
|
BYTE3(CCID_VALUE_DWDATARATE), /* dwDataRate: 9600 bps
|
||||||
|
Default ICC I/O data rate in bps. This is an integer value.
|
||||||
|
Example: 9600 bps is encoded as the integer value 9600. (00002580h) */
|
||||||
|
BYTE0(CCID_VALUE_DWMAXDATARATE), /* dwMaxDataRate */
|
||||||
|
BYTE1(CCID_VALUE_DWMAXDATARATE), /* dwMaxDataRate */
|
||||||
|
BYTE2(CCID_VALUE_DWMAXDATARATE), /* dwMaxDataRate */
|
||||||
|
BYTE3(CCID_VALUE_DWMAXDATARATE), /* dwMaxDataRate: 9600 bps
|
||||||
|
Maximum supported ICC I/O data rate in bps.
|
||||||
|
Example: 115.2Kbps is encoded as the integer value 115200. (0001C200h) */
|
||||||
|
0x00, /* bNumDataRatesSupported: 0
|
||||||
|
The number of data rates that are supported by the CCID.
|
||||||
|
If the value is 00h, all data rates between the default data rate dwDataRate and the
|
||||||
|
maximum data rate dwMaxDataRate are supported. */
|
||||||
|
BYTE0(CCID_VALUE_DWMAXIFSD), /* dwMaxIFSD */
|
||||||
|
BYTE1(CCID_VALUE_DWMAXIFSD), /* dwMaxIFSD */
|
||||||
|
BYTE2(CCID_VALUE_DWMAXIFSD), /* dwMaxIFSD */
|
||||||
|
BYTE3(CCID_VALUE_DWMAXIFSD), /* dwMaxIFSD: 254
|
||||||
|
Indicates the maximum IFSD (Information Field Size for Device) supported by CCID for protocol T=1. */
|
||||||
|
BYTE0(CCID_VALUE_DWSYNCPROTOCOLS),/* dwSynchProtocols */
|
||||||
|
BYTE1(CCID_VALUE_DWSYNCPROTOCOLS),/* dwSynchProtocols */
|
||||||
|
BYTE2(CCID_VALUE_DWSYNCPROTOCOLS),/* dwSynchProtocols */
|
||||||
|
BYTE3(CCID_VALUE_DWSYNCPROTOCOLS),/* dwSynchProtocols: 0
|
||||||
|
RRRR-Upper Word- is RFU = 0000h
|
||||||
|
PPPP-Lower Word- encodes the supported protocol types.
|
||||||
|
A ‘1’ in a given bit position indicates support for the associated protocol.
|
||||||
|
0001h indicates support for the 2-wire protocol
|
||||||
|
0002h indicates support for the 3-wire protocol
|
||||||
|
0004h indicates support for the I2C protocol
|
||||||
|
All other values are outside of this specification, and must be handled by vendor-supplied drivers. */
|
||||||
|
BYTE0(CCID_VALUE_DWMECHANICAL), /* dwMechanical */
|
||||||
|
BYTE1(CCID_VALUE_DWMECHANICAL), /* dwMechanical */
|
||||||
|
BYTE2(CCID_VALUE_DWMECHANICAL), /* dwMechanical */
|
||||||
|
BYTE3(CCID_VALUE_DWMECHANICAL), /* dwMechanical: 0
|
||||||
|
The value is a bitwise OR operation performed on the following values:
|
||||||
|
- 00000000h No special characteristics
|
||||||
|
- 00000001h Card accept mechanism
|
||||||
|
- 00000002h Card ejection mechanism
|
||||||
|
- 00000004h Card capture mechanism
|
||||||
|
- 00000008h Card lock/unlock mechanism */
|
||||||
|
BYTE0(CCID_VALUE_DWFEATURES), /* dwFeatures */
|
||||||
|
BYTE1(CCID_VALUE_DWFEATURES), /* dwFeatures */
|
||||||
|
BYTE2(CCID_VALUE_DWFEATURES), /* dwFeatures */
|
||||||
|
BYTE3(CCID_VALUE_DWFEATURES), /* dwFeatures: 0x000400FE
|
||||||
|
Automatic parameter configuration based on ATR data
|
||||||
|
Automatic activation of ICC on inserting
|
||||||
|
Automatic ICC voltage selection
|
||||||
|
Automatic ICC clock frequency change according to active parameters provided by the Host or self determined
|
||||||
|
Automatic baud rate change according to active parameters provided by the Host or self determined
|
||||||
|
Automatic parameters negotiation made by the CCID
|
||||||
|
Automatic PPS made by the CCID according to the active parameters
|
||||||
|
Short and Extended APDU level exchange with CCID
|
||||||
|
This value indicates what intelligent features the CCID has.
|
||||||
|
The value is a bitwise OR operation performed on the following values:
|
||||||
|
- 00000000h No special characteristics
|
||||||
|
- 00000002h Automatic parameter configuration based on ATR data
|
||||||
|
- 00000004h Automatic activation of ICC on inserting
|
||||||
|
- 00000008h Automatic ICC voltage selection
|
||||||
|
- 00000010h Automatic ICC clock frequency change according to active parameters provided by the Host or self determined
|
||||||
|
- 00000020h Automatic baud rate change according to active parameters provided by the Host or self determined
|
||||||
|
- 00000040h Automatic parameters negotiation made by the CCID (use of warm or cold resets or PPS according to a
|
||||||
|
manufacturer proprietary algorithm to select the communication parameters with the ICC)
|
||||||
|
- 00000080h Automatic PPS made by the CCID according to the active parameters
|
||||||
|
- 00000100h CCID can set ICC in clock stop mode
|
||||||
|
- 00000200h NAD value other than 00 accepted (T=1 protocol in use)
|
||||||
|
- 00000400h Automatic IFSD exchange as first exchange (T=1 protocol in use)
|
||||||
|
Only one of the following values may be present to select a level of exchange:
|
||||||
|
- 00010000h TPDU level exchanges with CCID
|
||||||
|
- 00020000h Short APDU level exchange with CCID
|
||||||
|
- 00040000h Short and Extended APDU level exchange with CCID
|
||||||
|
- If none of those values is indicated the level of exchange is character.
|
||||||
|
Only one of the values 00000040h and 00000080h may be present.
|
||||||
|
When value 00000040h is present the host shall not try to change the FI, DI, and protocol currently selected.
|
||||||
|
When an APDU level for exchanges is selected, one of the values 00000040h or 00000080h must be present, as well as the
|
||||||
|
value 00000002h.
|
||||||
|
To support selective suspend:
|
||||||
|
- 00100000h USB Wake up signaling supported on card insertion and removal
|
||||||
|
When bit 20th, as shown above, is set bit D5 in bmAttributes of the Standard Configuration Descriptor must be set to 1. */
|
||||||
|
BYTE0(CCID_VALUE_DWMAXCCIDMESSAGELENGTH),/* dwMaxCCIDMessageLength */
|
||||||
|
BYTE1(CCID_VALUE_DWMAXCCIDMESSAGELENGTH),/* dwMaxCCIDMessageLength */
|
||||||
|
BYTE2(CCID_VALUE_DWMAXCCIDMESSAGELENGTH),/* dwMaxCCIDMessageLength */
|
||||||
|
BYTE3(CCID_VALUE_DWMAXCCIDMESSAGELENGTH),/* dwMaxCCIDMessageLength: 3072
|
||||||
|
For extended APDU level the value shall be between 261 + 10 (header) and 65544 +10,
|
||||||
|
otherwise the minimum value is the wMaxPacketSize of the Bulk-OUT endpoint. */
|
||||||
|
0xFF, /* bClassGetResponse: echo
|
||||||
|
Significant only for CCID that offers an APDU level for exchanges.
|
||||||
|
Indicates the default class value used by the CCID when it sends a Get Response command to perform the transportation of an APDU by T=0 protocol.
|
||||||
|
Value FFh indicates that the CCID echoes the class of the APDU. */
|
||||||
|
0xFF, /* bClassEnvelope: echo
|
||||||
|
Significant only for CCID that offers an extended APDU level for exchanges.
|
||||||
|
Indicates the default class value used by the CCID when it sends an Envelope command to perform the transportation of an extended APDU by T=0 protocol.
|
||||||
|
Value FFh indicates that the CCID echoes the class of the APDU.*/
|
||||||
|
LOBYTE(CCID_VALUE_WLCDLAYOUT), /* wLcdLayout */
|
||||||
|
HIBYTE(CCID_VALUE_WLCDLAYOUT), /* wLcdLayout: none
|
||||||
|
Number of lines and characters for the LCD display used to send messages for PIN entry.
|
||||||
|
XX: number of lines
|
||||||
|
YY: number of characters per line.
|
||||||
|
XXYY=0000h no LCD. */
|
||||||
|
0x00, /* bPINSupport: 0
|
||||||
|
This value indicates what PIN support features the CCID has.
|
||||||
|
The value is a bitwise OR operation performed on the following values:
|
||||||
|
0x01 PIN Verification supported
|
||||||
|
0x02 PIN Modification supported */
|
||||||
|
0x01, /* bMaxCCIDBusySlots: 1
|
||||||
|
Maximum number of slots which can be simultaneously busy.*/
|
||||||
|
/******************** CCID Endpoint descriptor (Bulk-OUT) ********************/
|
||||||
|
/* 63 */
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CCID_BULK_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
|
||||||
|
USB_EP_TYPE_BULK, /* bmAttributes: Bulk Endpoint */
|
||||||
|
LOBYTE(CCID_BULK_EPOUT_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */
|
||||||
|
HIBYTE(CCID_BULK_EPOUT_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */
|
||||||
|
CCID_BULK_FS_BINTERVAL, /* bInterval: Polling Interval */
|
||||||
|
/******************** CCID Endpoint descriptor (Bulk-IN) ********************/
|
||||||
|
/* 70 */
|
||||||
|
0x07, /* bLength: Endpoint Descriptor size */
|
||||||
|
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
|
||||||
|
CCID_BULK_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
|
||||||
|
USB_EP_TYPE_BULK, /* bmAttributes: Bulk Endpoint */
|
||||||
|
LOBYTE(CCID_BULK_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */
|
||||||
|
HIBYTE(CCID_BULK_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */
|
||||||
|
CCID_BULK_FS_BINTERVAL, /* bInterval: Polling Interval */
|
||||||
|
/* 77 */
|
||||||
|
};
|
||||||
|
|
||||||
|
// DEBUG Descriptor
|
||||||
|
FLASH uint8_t DebugDesc[] = {
|
||||||
|
/******************** Interface, DEBUG Descriptor (two endpoints) ********************/
|
||||||
|
0x09, /* bLength: Interface Descriptor size */
|
||||||
|
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
|
||||||
|
CHANGE_ME, /* bInterfaceNumber: Number of Interface */
|
||||||
|
0x00, /* bAlternateSetting: Alternate setting */
|
||||||
|
0x02, /* bNumEndpoints: Number of endpoints in Interface */
|
||||||
USB_DEV_CLASS_HID, /* bInterfaceClass: Human Interface Device */
|
USB_DEV_CLASS_HID, /* bInterfaceClass: Human Interface Device */
|
||||||
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||||
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||||
|
@ -426,11 +652,11 @@ volatile IDATA uint8_t DebugUartRxBufByteCount = 0;
|
||||||
|
|
||||||
/** Endpoint handling */
|
/** Endpoint handling */
|
||||||
volatile IDATA uint8_t UsbEp2ByteCount = 0; // Represents the data received by USB endpoint 2 (CDC)
|
volatile IDATA uint8_t UsbEp2ByteCount = 0; // Represents the data received by USB endpoint 2 (CDC)
|
||||||
volatile IDATA uint8_t UsbEp3ByteCount = 0; // Represents the data received by USB endpoint 3 (FIDO)
|
volatile IDATA uint8_t UsbEp3ByteCount = 0; // Represents the data received by USB endpoint 3 (FIDO or CCID)
|
||||||
volatile IDATA uint8_t UsbEp4ByteCount = 0; // Represents the data received by USB endpoint 4 (DEBUG)
|
volatile IDATA uint8_t UsbEp4ByteCount = 0; // Represents the data received by USB endpoint 4 (DEBUG)
|
||||||
|
|
||||||
volatile IDATA uint8_t Endpoint2UploadBusy = 0; // Whether the upload endpoint 2 (CDC) is busy
|
volatile IDATA uint8_t Endpoint2UploadBusy = 0; // Whether the upload endpoint 2 (CDC) is busy
|
||||||
volatile IDATA uint8_t Endpoint3UploadBusy = 0; // Whether the upload endpoint 3 (FIDO) is busy
|
volatile IDATA uint8_t Endpoint3UploadBusy = 0; // Whether the upload endpoint 3 (FIDO or CCID) is busy
|
||||||
volatile IDATA uint8_t Endpoint4UploadBusy = 0; // Whether the upload endpoint 4 (DEBUG) is busy
|
volatile IDATA uint8_t Endpoint4UploadBusy = 0; // Whether the upload endpoint 4 (DEBUG) is busy
|
||||||
|
|
||||||
/** CH552 variables */
|
/** CH552 variables */
|
||||||
|
@ -445,6 +671,9 @@ IDATA uint8_t CdcDataAvailable = 0;
|
||||||
/** FIDO variables */
|
/** FIDO variables */
|
||||||
IDATA uint8_t FidoDataAvailable = 0;
|
IDATA uint8_t FidoDataAvailable = 0;
|
||||||
|
|
||||||
|
/** CCID variables */
|
||||||
|
IDATA uint8_t CcidDataAvailable = 0;
|
||||||
|
|
||||||
/** Frame data */
|
/** Frame data */
|
||||||
#define MAX_FRAME_SIZE 64
|
#define MAX_FRAME_SIZE 64
|
||||||
XDATA uint8_t FrameBuf[MAX_FRAME_SIZE] = { 0 };
|
XDATA uint8_t FrameBuf[MAX_FRAME_SIZE] = { 0 };
|
||||||
|
@ -539,9 +768,10 @@ void CreateCfgDescriptor(uint8_t ep_config)
|
||||||
uint8_t num_iface = 0; // Interface number
|
uint8_t num_iface = 0; // Interface number
|
||||||
|
|
||||||
FidoInterfaceNum = 0xFF; // Set as invalid until we have parsed each interface
|
FidoInterfaceNum = 0xFF; // Set as invalid until we have parsed each interface
|
||||||
|
CcidInterfaceNum = 0xFF; // Set as invalid until we have parsed each interface
|
||||||
DebugInterfaceNum = 0xFF; // Set as invalid until we have parsed each interface
|
DebugInterfaceNum = 0xFF; // Set as invalid until we have parsed each interface
|
||||||
|
|
||||||
memset(ActiveCfgDesc, 0, CFG_DESC_SIZE); // Clean the descriptor
|
memset(ActiveCfgDesc, 0, MAX_CFG_DESC_SIZE); // Clean the descriptor
|
||||||
|
|
||||||
uint8_t cfg_desc_size = sizeof(CfgDesc);
|
uint8_t cfg_desc_size = sizeof(CfgDesc);
|
||||||
memcpy(ActiveCfgDesc, CfgDesc, cfg_desc_size);
|
memcpy(ActiveCfgDesc, CfgDesc, cfg_desc_size);
|
||||||
|
@ -550,7 +780,10 @@ void CreateCfgDescriptor(uint8_t ep_config)
|
||||||
if (ep_config & IO_CDC) {
|
if (ep_config & IO_CDC) {
|
||||||
uint8_t cdc_desc_size = sizeof(CdcDesc);
|
uint8_t cdc_desc_size = sizeof(CdcDesc);
|
||||||
memcpy(ActiveCfgDesc + ActiveCfgDescSize, CdcDesc, cdc_desc_size);
|
memcpy(ActiveCfgDesc + ActiveCfgDescSize, CdcDesc, cdc_desc_size);
|
||||||
num_iface += 2;
|
ActiveCfgDesc[ActiveCfgDescSize + 10] = num_iface;
|
||||||
|
num_iface++;
|
||||||
|
ActiveCfgDesc[ActiveCfgDescSize + 45] = num_iface;
|
||||||
|
num_iface++;
|
||||||
ActiveCfgDescSize += cdc_desc_size;
|
ActiveCfgDescSize += cdc_desc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,6 +796,15 @@ void CreateCfgDescriptor(uint8_t ep_config)
|
||||||
ActiveCfgDescSize += fido_desc_size;
|
ActiveCfgDescSize += fido_desc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ep_config & IO_CCID) {
|
||||||
|
uint8_t ccid_desc_size = sizeof(CcidDesc);
|
||||||
|
memcpy(ActiveCfgDesc + ActiveCfgDescSize, CcidDesc, ccid_desc_size);
|
||||||
|
ActiveCfgDesc[ActiveCfgDescSize + 2] = num_iface;
|
||||||
|
CcidInterfaceNum = num_iface;
|
||||||
|
num_iface++;
|
||||||
|
ActiveCfgDescSize += ccid_desc_size;
|
||||||
|
}
|
||||||
|
|
||||||
if (ep_config & IO_DEBUG) {
|
if (ep_config & IO_DEBUG) {
|
||||||
uint8_t debug_desc_size = sizeof(DebugDesc);
|
uint8_t debug_desc_size = sizeof(DebugDesc);
|
||||||
memcpy(ActiveCfgDesc + ActiveCfgDescSize, DebugDesc, debug_desc_size);
|
memcpy(ActiveCfgDesc + ActiveCfgDescSize, DebugDesc, debug_desc_size);
|
||||||
|
@ -692,6 +934,10 @@ void usb_irq_setup_handler(void)
|
||||||
pDescr = CdcDataInterfaceDesc;
|
pDescr = CdcDataInterfaceDesc;
|
||||||
len = sizeof(CdcDataInterfaceDesc);
|
len = sizeof(CdcDataInterfaceDesc);
|
||||||
printStrSetup("CdcDataInterfaceDesc\n");
|
printStrSetup("CdcDataInterfaceDesc\n");
|
||||||
|
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_CCID_STR) {
|
||||||
|
pDescr = CcidInterfaceDesc;
|
||||||
|
len = sizeof(CcidInterfaceDesc);
|
||||||
|
printStrSetup("CcidInterfaceDesc\n");
|
||||||
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_FIDO_STR) {
|
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_FIDO_STR) {
|
||||||
pDescr = FidoInterfaceDesc;
|
pDescr = FidoInterfaceDesc;
|
||||||
len = sizeof(FidoInterfaceDesc);
|
len = sizeof(FidoInterfaceDesc);
|
||||||
|
@ -1228,6 +1474,11 @@ void main()
|
||||||
ActiveEndpoints |= IO_CH552;
|
ActiveEndpoints |= IO_CH552;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIDO and CCID can't be enabled at the same time. Disable both!
|
||||||
|
if ((ActiveEndpoints & IO_FIDO) && (ActiveEndpoints & IO_CCID)) {
|
||||||
|
ActiveEndpoints &= ~(IO_FIDO | IO_CCID);
|
||||||
|
}
|
||||||
|
|
||||||
CreateCfgDescriptor(ActiveEndpoints);
|
CreateCfgDescriptor(ActiveEndpoints);
|
||||||
|
|
||||||
USBDeviceCfg();
|
USBDeviceCfg();
|
||||||
|
@ -1259,14 +1510,18 @@ void main()
|
||||||
UEP2_CTRL = (UEP2_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_ACK; // Enable Endpoint 2 to ACK again
|
UEP2_CTRL = (UEP2_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_ACK; // Enable Endpoint 2 to ACK again
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if Endpoint 3 (FIDO) has received data
|
// Check if Endpoint 3 (FIDO or CCID) has received data
|
||||||
if (UsbEp3ByteCount) {
|
if (UsbEp3ByteCount) {
|
||||||
Ep3ByteLen = UsbEp3ByteCount; // UsbEp3ByteCount can be maximum 64 bytes
|
Ep3ByteLen = UsbEp3ByteCount; // UsbEp3ByteCount can be maximum 64 bytes
|
||||||
memcpy(UartTxBuf, Ep3Buffer, Ep3ByteLen);
|
memcpy(UartTxBuf, Ep3Buffer, Ep3ByteLen);
|
||||||
|
|
||||||
UsbEp3ByteCount = 0;
|
UsbEp3ByteCount = 0;
|
||||||
|
if (ActiveEndpoints & IO_FIDO) {
|
||||||
CH554UART1SendByte(IO_FIDO); // Send FIDO mode header
|
CH554UART1SendByte(IO_FIDO); // Send FIDO mode header
|
||||||
CH554UART1SendByte(Ep3ByteLen); // Send length (always 64 bytes)
|
} else if (ActiveEndpoints & IO_CCID) {
|
||||||
|
CH554UART1SendByte(IO_CCID); // Send CCID mode header
|
||||||
|
}
|
||||||
|
CH554UART1SendByte(Ep3ByteLen); // Send length (always 64 bytes for FIDO, variable for CCID)
|
||||||
CH554UART1SendBuffer(UartTxBuf, Ep3ByteLen);
|
CH554UART1SendBuffer(UartTxBuf, Ep3ByteLen);
|
||||||
UEP3_CTRL = (UEP3_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_ACK; // Enable Endpoint 3 to ACK again
|
UEP3_CTRL = (UEP3_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_ACK; // Enable Endpoint 3 to ACK again
|
||||||
}
|
}
|
||||||
|
@ -1289,6 +1544,7 @@ void main()
|
||||||
FrameMode = UartRxBuf[UartRxBufOutputPointer]; // Extract frame mode
|
FrameMode = UartRxBuf[UartRxBufOutputPointer]; // Extract frame mode
|
||||||
if ((FrameMode == IO_CDC) ||
|
if ((FrameMode == IO_CDC) ||
|
||||||
(FrameMode == IO_FIDO) ||
|
(FrameMode == IO_FIDO) ||
|
||||||
|
(FrameMode == IO_CCID) ||
|
||||||
(FrameMode == IO_DEBUG) ||
|
(FrameMode == IO_DEBUG) ||
|
||||||
(FrameMode == IO_CH552)) {
|
(FrameMode == IO_CH552)) {
|
||||||
|
|
||||||
|
@ -1379,6 +1635,44 @@ void main()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy CCID data from UartRxBuf to FrameBuf
|
||||||
|
if (FrameStarted && !FrameDiscard && !CcidDataAvailable) {
|
||||||
|
if (FrameMode == IO_CCID) {
|
||||||
|
if ((FrameRemainingBytes >= MAX_FRAME_SIZE) &&
|
||||||
|
(UartRxBufByteCount >= MAX_FRAME_SIZE)) {
|
||||||
|
circular_copy(FrameBuf,
|
||||||
|
UartRxBuf,
|
||||||
|
UART_RX_BUF_SIZE,
|
||||||
|
UartRxBufOutputPointer,
|
||||||
|
MAX_FRAME_SIZE);
|
||||||
|
FrameBufLength = MAX_FRAME_SIZE;
|
||||||
|
// Update output pointer
|
||||||
|
UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer,
|
||||||
|
MAX_FRAME_SIZE,
|
||||||
|
UART_RX_BUF_SIZE);
|
||||||
|
FrameRemainingBytes -= MAX_FRAME_SIZE;
|
||||||
|
CcidDataAvailable = 1;
|
||||||
|
cts_start();
|
||||||
|
}
|
||||||
|
else if ((FrameRemainingBytes < MAX_FRAME_SIZE) &&
|
||||||
|
(UartRxBufByteCount >= FrameRemainingBytes)) {
|
||||||
|
circular_copy(FrameBuf,
|
||||||
|
UartRxBuf,
|
||||||
|
UART_RX_BUF_SIZE,
|
||||||
|
UartRxBufOutputPointer,
|
||||||
|
FrameRemainingBytes);
|
||||||
|
FrameBufLength = FrameRemainingBytes;
|
||||||
|
// Update output pointer
|
||||||
|
UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer,
|
||||||
|
FrameRemainingBytes,
|
||||||
|
UART_RX_BUF_SIZE);
|
||||||
|
FrameRemainingBytes -= FrameRemainingBytes;
|
||||||
|
CcidDataAvailable = 1;
|
||||||
|
cts_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy DEBUG data from UartRxBuf to FrameBuf
|
// Copy DEBUG data from UartRxBuf to FrameBuf
|
||||||
if (FrameStarted && !FrameDiscard && !DebugDataAvailable) {
|
if (FrameStarted && !FrameDiscard && !DebugDataAvailable) {
|
||||||
if (FrameMode == IO_DEBUG) {
|
if (FrameMode == IO_DEBUG) {
|
||||||
|
@ -1519,6 +1813,25 @@ void main()
|
||||||
FrameStarted = 0;
|
FrameStarted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we should upload data to Endpoint 3 (CCID)
|
||||||
|
if (CcidDataAvailable && !Endpoint3UploadBusy) {
|
||||||
|
|
||||||
|
// Write upload endpoint
|
||||||
|
memcpy(Ep3Buffer + MAX_PACKET_SIZE, /* Copy to IN buffer of Endpoint 3 */
|
||||||
|
FrameBuf,
|
||||||
|
FrameBufLength);
|
||||||
|
|
||||||
|
Endpoint3UploadBusy = 1; // Set busy flag
|
||||||
|
UEP3_T_LEN = FrameBufLength; // Set the number of data bytes that Endpoint 3 is ready to send
|
||||||
|
UEP3_CTRL = (UEP3_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK; // Answer ACK
|
||||||
|
|
||||||
|
CcidDataAvailable = 0;
|
||||||
|
FrameBufLength = 0;
|
||||||
|
|
||||||
|
// Get next header and data
|
||||||
|
FrameStarted = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we should upload data to Endpoint 4 (DEBUG)
|
// Check if we should upload data to Endpoint 4 (DEBUG)
|
||||||
if (DebugDataAvailable && !Endpoint4UploadBusy) {
|
if (DebugDataAvailable && !Endpoint4UploadBusy) {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue