ch552: Add new USB debug pipe (TKEYCTRL)

Make the CH552 present a new HID endpoint used for debug data.
This commit is contained in:
Jonas Thörnblad 2025-01-15 15:08:18 +01:00 committed by Mikael Ågren
parent bfc43093ec
commit 04ec938200
No known key found for this signature in database
GPG Key ID: E02DA3D397792C46
5 changed files with 379 additions and 62 deletions

View File

@ -9,6 +9,7 @@
#define PROTO_H #define PROTO_H
enum mode { enum mode {
MODE_TKEYCTRL = 0x20,
MODE_CDC = 0x40, MODE_CDC = 0x40,
MODE_HID = 0x80, MODE_HID = 0x80,
}; };

View File

@ -193,15 +193,17 @@ Header file for CH554 microcontrollers.
#define USB_IDX_MFC_STR 0x01 #define USB_IDX_MFC_STR 0x01
#define USB_IDX_PRODUCT_STR 0x02 #define USB_IDX_PRODUCT_STR 0x02
#define USB_IDX_SERIAL_STR 0x03 #define USB_IDX_SERIAL_STR 0x03
#define USB_IDX_CONFIG_STR 0x04 #define USB_IDX_INTERFACE_CDC_CTRL_STR 0x04
#define USB_IDX_INTERFACE_STR 0x05 #define USB_IDX_INTERFACE_CDC_DATA_STR 0x05
#define USB_IDX_INTERFACE_FIDO_HID_STR 0x06
#define USB_IDX_INTERFACE_TKEY_CTRL_STR 0x07
#endif #endif
#ifndef USB_DEVICE_ADDR #ifndef USB_DEVICE_ADDR
#define USB_DEVICE_ADDR 0x02 #define USB_DEVICE_ADDR 0x02
#endif #endif
#ifndef DEFAULT_EP0_SIZE #ifndef DEFAULT_EP0_SIZE
#define DEFAULT_EP0_SIZE 8 /* Default maximum packet size for Endpoint 0 */ #define DEFAULT_EP0_SIZE 64 /* Default maximum packet size for Endpoint 0 */
#endif #endif
#ifndef DEFAULT_EP1_SIZE #ifndef DEFAULT_EP1_SIZE
#define DEFAULT_EP1_SIZE 8 /* Default maximum packet size for Endpoint 1 */ #define DEFAULT_EP1_SIZE 8 /* Default maximum packet size for Endpoint 1 */

View File

@ -13,7 +13,11 @@
#define AT0050 __at(0x0050) // 0x050, 80 #define AT0050 __at(0x0050) // 0x050, 80
#define AT0080 __at(0x0080) // 0x080, 128 #define AT0080 __at(0x0080) // 0x080, 128
#define AT0090 __at(0x0090) // 0x090, 144 #define AT0090 __at(0x0090) // 0x090, 144
#define AT0100 __at(0x0100) // 0x100, 256 #define AT00C0 __at(0x00C0) // 0x0C0, 192
#define AT00C8 __at(0x00C8) // 0x0C8, 200
#define AT0110 __at(0x0110) // 0x110, 272
#define AT0148 __at(0x0148) // 0x148, 328
#define AT01C8 __at(0x01C8) // 0x1C8, 456
#define FLASH __code #define FLASH __code
#else #else
#define IDATA #define IDATA
@ -25,7 +29,11 @@
#define AT0050 #define AT0050
#define AT0080 #define AT0080
#define AT0090 #define AT0090
#define AT0100 #define AT00C0
#define AT00C8
#define AT0110
#define AT0148
#define AT01C8
#define FLASH #define FLASH
#endif #endif

View File

@ -4,28 +4,61 @@
#include "mem.h" #include "mem.h"
unsigned char FLASH ProdDesc[]={ // "MTA1-USB-V1" unsigned char FLASH ProdDesc[]={ // "MTA1-USB-V1"
0x18, 0x03, 0x4d, 0x00, 0x54, 0x00, 0x41, 0x00, 24, // Length of this descriptor (in bytes)
0x31, 0x00, 0x2d, 0x00, 0x55, 0x00, 0x53, 0x00, 0x03, // Descriptor type (String)
0x42, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x31, 0x00 'M', 0, 'T', 0, 'A', 0, '1', 0,
'-', 0, 'U', 0, 'S', 0, 'B', 0,
'-', 0, 'V', 0, '1', 0
}; };
unsigned char FLASH ManufDesc[]={ // "Tillitis" unsigned char FLASH ManufDesc[]={ // "Tillitis"
0x12, 0x03, 0x54, 0x00, 0x69, 0x00, 0x6c, 0x00, 18, // Length of this descriptor (in bytes)
0x6c, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x03, // Descriptor type (String)
0x73, 0x00 'T', 0, 'i', 0, 'l', 0, 'l', 0,
'i', 0, 't', 0, 'i', 0, 's', 0
}; };
unsigned char FLASH SerialDesc[]={ // "68de5d27-e223-4874-bc76-a54d6e84068f" unsigned char FLASH SerialDesc[]={ // "68de5d27-e223-4874-bc76-a54d6e84068f"
0x4a, 0x03, 0x36, 0x00, 0x38, 0x00, 0x64, 0x00, 74, // Length of this descriptor (in bytes)
0x65, 0x00, 0x35, 0x00, 0x64, 0x00, 0x32, 0x00, 0x03, // Descriptor type (String)
0x37, 0x00, 0x2d, 0x00, 0x65, 0x00, 0x32, 0x00, '6', 0, '8', 0, 'd', 0, 'e', 0,
0x32, 0x00, 0x33, 0x00, 0x2d, 0x00, 0x34, 0x00, '5', 0, 'd', 0, '2', 0, '7', 0,
0x38, 0x00, 0x37, 0x00, 0x34, 0x00, 0x2d, 0x00, '-', 0, 'e', 0, '2', 0, '2', 0,
0x62, 0x00, 0x63, 0x00, 0x37, 0x00, 0x36, 0x00, '3', 0, '-', 0, '4', 0, '8', 0,
0x2d, 0x00, 0x61, 0x00, 0x35, 0x00, 0x34, 0x00, '7', 0, '4', 0, '-', 0, 'b', 0,
0x64, 0x00, 0x36, 0x00, 0x65, 0x00, 0x38, 0x00, 'c', 0, '7', 0, '6', 0, '-', 0,
0x34, 0x00, 0x30, 0x00, 0x36, 0x00, 0x38, 0x00, 'a', 0, '5', 0, '4', 0, 'd', 0,
0x66, 0x00 '6', 0, 'e', 0, '8', 0, '4', 0,
'0', 0, '6', 0, '8', 0, 'f', 0,
};
unsigned char FLASH CdcCtrlInterfaceDesc[] = {
18, // Length of this descriptor (in bytes)
0x03, // Descriptor type (String)
'C', 0, 'D', 0, 'C', 0, '-', 0,
'C', 0, 't', 0, 'r', 0, 'l', 0,
};
unsigned char FLASH CdcDataInterfaceDesc[] = {
18, // Length of this descriptor (in bytes)
0x03, // Descriptor type (String)
'C', 0, 'D', 0, 'C', 0, '-', 0,
'D', 0, 'a', 0, 't', 0, 'a', 0,
};
unsigned char FLASH FidoHidInterfaceDesc[] = {
18, // Length of this descriptor (in bytes)
0x03, // Descriptor type (String)
'F', 0, 'I', 0, 'D', 0, 'O', 0,
'-', 0, 'H', 0, 'I', 0, 'D', 0,
};
unsigned char FLASH TkeyCtrlInterfaceDesc[] = {
20, // Length of this descriptor (in bytes)
0x03, // Descriptor type (String)
'T', 0, 'K', 0, 'E', 0, 'Y', 0,
'-', 0, 'C', 0, 't', 0, 'r', 0,
'l', 0,
}; };
#endif #endif

View File

@ -17,10 +17,11 @@
#include "print.h" #include "print.h"
#include "usb_strings.h" #include "usb_strings.h"
XDATA AT0000 uint8_t Ep0Buffer[DEFAULT_EP0_SIZE] = { 0 }; // Endpoint 0, Default endpoint, OUT & IN buffer, must be an even address XDATA AT0000 uint8_t Ep0Buffer[3*MAX_PACKET_SIZE] = { 0 }; // Endpoint 0, Default endpoint, OUT & IN buffer[64], must be an even address +
XDATA AT0008 uint8_t Ep1Buffer[DEFAULT_EP1_SIZE] = { 0 }; // Endpoint 1, CDC Ctrl, IN[8] buffer // Endpoint 4, TKEYCTRL, buffer OUT[64]+IN[64], must be an even address
XDATA AT0010 uint8_t Ep2Buffer[2*MAX_PACKET_SIZE] = { 0 }; // Endpoint 2, CDC Data, buffer OUT[64]+IN[64], must be an even address XDATA AT00C0 uint8_t Ep1Buffer[DEFAULT_EP1_SIZE] = { 0 }; // Endpoint 1, CDC Ctrl, IN[8] buffer
XDATA AT0090 uint8_t Ep3Buffer[2*MAX_PACKET_SIZE] = { 0 }; // Endpoint 3, HID, buffer OUT[64]+IN[64], must be an even address XDATA AT00C8 uint8_t Ep2Buffer[2*MAX_PACKET_SIZE] = { 0 }; // Endpoint 2, CDC Data, buffer OUT[64]+IN[64], must be an even address
XDATA AT0148 uint8_t Ep3Buffer[2*MAX_PACKET_SIZE] = { 0 }; // Endpoint 3, HID, buffer OUT[64]+IN[64], must be an even address
uint16_t SetupLen = 0; uint16_t SetupLen = 0;
uint8_t SetupReq = 0; uint8_t SetupReq = 0;
@ -30,6 +31,9 @@ USB_SETUP_REQ SetupReqBuf = { 0 }; // Temporary Setup package
#define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer) #define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer)
#define CDC_CTRL_EPOUT_ADDR 0x01 // CDC Ctrl Endpoint OUT Address
#define CDC_CTRL_EPOUT_SIZE DEFAULT_EP1_SIZE // CDC Ctrl Endpoint OUT Size
#define CDC_CTRL_EPIN_ADDR 0x81 // CDC Ctrl Endpoint IN Address #define CDC_CTRL_EPIN_ADDR 0x81 // CDC Ctrl Endpoint IN Address
#define CDC_CTRL_EPIN_SIZE DEFAULT_EP1_SIZE // CDC Ctrl Endpoint IN Size #define CDC_CTRL_EPIN_SIZE DEFAULT_EP1_SIZE // CDC Ctrl Endpoint IN Size
@ -45,11 +49,19 @@ USB_SETUP_REQ SetupReqBuf = { 0 }; // Temporary Setup package
#define HID_EPIN_ADDR 0x83 // HID Endpoint IN Address #define HID_EPIN_ADDR 0x83 // HID Endpoint IN Address
#define HID_EPIN_SIZE MAX_PACKET_SIZE // HID Endpoint IN Size #define HID_EPIN_SIZE MAX_PACKET_SIZE // HID Endpoint IN Size
#define CDC_CTRL_FS_BINTERVAL 0xFF // 255 ms polling interval at Full Speed #define TKEYCTRL_EPOUT_ADDR 0x04 // TKEYCTRL Endpoint OUT Address
#define CDC_DATA_FS_BINTERVAL 1 /* was: 0 */ // 1 ms polling interval at Full Speed #define TKEYCTRL_EPOUT_SIZE MAX_PACKET_SIZE // TKEYCTRL Endpoint OUT Size
#define HID_FS_BINTERVAL 1 // 1 ms polling interval at Full Speed
#define HID_REPORT_DESC_SIZE 47 // HID Report Descriptor size #define TKEYCTRL_EPIN_ADDR 0x84 // TKEYCTRL Endpoint IN Address
#define TKEYCTRL_EPIN_SIZE MAX_PACKET_SIZE // TKEYCTRL Endpoint IN Size
#define CDC_CTRL_FS_BINTERVAL 0xFF // 255 ms polling interval at Full Speed
#define CDC_DATA_FS_BINTERVAL 1 // 1 ms polling interval at Full Speed
#define HID_FS_BINTERVAL 1 // 1 ms polling interval at Full Speed
#define TKEYCTRL_FS_BINTERVAL 1 // 1 ms polling interval at Full Speed
#define HID_REPORT_DESC_SIZE 47 // Size of HID_ReportDesc
#define TKEYCTRL_REPORT_DESC_SIZE 34 // Size of TKEYCTRL_ReportDesc
#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) & 0xFF00U) >> 8U))
@ -81,15 +93,26 @@ 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 */
99U, /* wTotalLength (low byte): Bytes returned */ 131U, /* wTotalLength (low byte): Bytes returned */
0x00, /* wTotalLength (high byte): Bytes returned */ 0x00, /* wTotalLength (high byte): Bytes returned */
0x03, /* bNumInterfaces: 3 interfaces (1 CDC Ctrl, 1 CDC Data, 1 HID) */ 0x04, /* bNumInterfaces: 4 interfaces (1 CDC Ctrl, 1 CDC Data, 1 HID, 1 HID (TKEYCTRL) ) */
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, /*Mouse:0xE0,whatis:0xC0?*/ /* bmAttributes: Bus powered and Support Remote Wake-up */ 0xA0, /* bmAttributes: Bus powered and Support Remote Wake-up */
0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */
/******************** Interface 0, CDC Ctrl Descriptor (one endpoint) ********************/ /******************** IAD (Interface Association Descriptor), should be positioned just before the CDC interfaces ********************/
/******************** This is to associate the two CDC interfaces with the CDC class ********************/
/* 9 */ /* 9 */
0x08, /* bLength: IAD Descriptor size */
USB_DESC_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType: Interface Association */
0x00, /* bFirstInterface: 0 */
0x02, /* bInterfaceCount: 2 */
0x02, /* bFunctionClass: Communications & CDC Control */
0x02, /* bFunctionSubClass: Abstract Control Model */
0x01, /* bFunctionProtocol: Common AT commands */
0x00, /* iFunction: Index of string descriptor */
/******************** Interface 0, CDC Ctrl Descriptor (one endpoint) ********************/
/* 17 */
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 */ 0x00, /* bInterfaceNumber: Number of Interface */
@ -98,7 +121,7 @@ FLASH uint8_t CfgDesc[] = {
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 */
0x00, /* iInterface: Index of string descriptor */ 0x04, /* iInterface: Index of string descriptor */
/******************** Header Functional Descriptor ********************/ /******************** Header Functional Descriptor ********************/
/* 18 */ /* 18 */
0x05, /* bFunctionLength: Size of this descriptor in bytes */ 0x05, /* bFunctionLength: Size of this descriptor in bytes */
@ -155,7 +178,7 @@ FLASH uint8_t CfgDesc[] = {
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 */
0x00, /* iInterface: Index of string descriptor */ 0x05, /* iInterface: Index of string descriptor */
/******************** CDC Data Endpoint descriptor (OUT) ********************/ /******************** CDC Data Endpoint descriptor (OUT) ********************/
/* 53 */ /* 53 */
0x07, /* bLength: Endpoint Descriptor size */ 0x07, /* bLength: Endpoint Descriptor size */
@ -184,7 +207,7 @@ FLASH uint8_t CfgDesc[] = {
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 */
0x00, /* iInterface: Index of string descriptor */ 0x06, /* iInterface: Index of string descriptor */
/******************** HID Device Descriptor ********************/ /******************** HID Device Descriptor ********************/
/* 76 */ /* 76 */
0x09, /* bLength: HID Descriptor size */ 0x09, /* bLength: HID Descriptor size */
@ -214,7 +237,47 @@ FLASH uint8_t CfgDesc[] = {
LOBYTE(HID_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ LOBYTE(HID_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */
HIBYTE(HID_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ HIBYTE(HID_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */
HID_FS_BINTERVAL, /* bInterval: Polling Interval */ HID_FS_BINTERVAL, /* bInterval: Polling Interval */
/******************** Interface 3, HID (TKEYCTRL) Descriptor (two endpoints) ********************/
/* 99 */ /* 99 */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
0x03, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: 2 */
USB_DEV_CLASS_HID, /* bInterfaceClass: Human Interface Device */
0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0x07, /* iInterface: Index of string descriptor */
/******************** HID (TKEYCTRL) Device Descriptor ********************/
/* 108 */
0x09, /* bLength: HID Descriptor size */
USB_DESC_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID (low byte): HID Class Spec release number */
0x01, /* bcdHID (high byte): HID Class Spec release number */
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
USB_DESC_TYPE_REPORT, /* bDescriptorType: Report */
LOBYTE(TKEYCTRL_REPORT_DESC_SIZE),/* wDescriptorLength (low byte): Total length of Report descriptor */
HIBYTE(TKEYCTRL_REPORT_DESC_SIZE),/* wDescriptorLength (high byte): Total length of Report descriptor */
/******************** HID (TKEYCTRL) Endpoint Descriptor (OUT) ********************/
/* 117 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
TKEYCTRL_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */
USB_EP_TYPE_INTERRUPT, /* bmAttributes: Interrupt endpoint */
LOBYTE(TKEYCTRL_EPOUT_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */
HIBYTE(TKEYCTRL_EPOUT_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */
TKEYCTRL_FS_BINTERVAL, /* bInterval: Polling Interval */
/******************** HID (TKEYCTRL) Endpoint Descriptor (IN) ********************/
/* 124 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
TKEYCTRL_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */
USB_EP_TYPE_INTERRUPT, /* bmAttributes: Interrupt endpoint */
LOBYTE(TKEYCTRL_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */
HIBYTE(TKEYCTRL_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */
TKEYCTRL_FS_BINTERVAL, /* bInterval: Polling Interval */
/* 131 */
}; };
// HID Device Descriptor (copy from CfgDesc) // HID Device Descriptor (copy from CfgDesc)
@ -234,34 +297,74 @@ FLASH uint8_t HID_ReportDesc[] ={
0x06, 0xD0, 0xF1, /* Usage Page (FIDO Alliance Page) */ 0x06, 0xD0, 0xF1, /* Usage Page (FIDO Alliance Page) */
0x09, 0x01, /* Usage (U2F Authenticator Device) */ 0x09, 0x01, /* Usage (U2F Authenticator Device) */
0xA1, 0x01, /* Collection (Application) */ 0xA1, 0x01, /* Collection (Application) */
/* 7 */
0x09, 0x20, /* Usage (Input Report Data) */ 0x09, 0x20, /* Usage (Input Report Data) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, MAX_PACKET_SIZE, /* Report Count (64) */ 0x95, MAX_PACKET_SIZE, /* Report Count (64) */
0x81, 0x02, /* Input (Data, Variable, Absolute); */ 0x81, 0x02, /* Input (Data, Variable, Absolute); */
/* 20 */
0x09, 0x21, /* Usage (Output Report Data) */ 0x09, 0x21, /* Usage (Output Report Data) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, MAX_PACKET_SIZE, /* Report Count (64) */ 0x95, MAX_PACKET_SIZE, /* Report Count (64) */
0x91, 0x02, /* Output (Data, Variable, Absolute); */ 0x91, 0x02, /* Output (Data, Variable, Absolute); */
/* 33 */
0x09, 0x07, /* Usage (7, Reserved) */ 0x09, 0x07, /* Usage (7, Reserved) */
0x15, 0x00, /* Logical Minimum (0) */ 0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8) */ 0x75, 0x08, /* Report Size (8) */
0x95, 0x08, /* Report Count (8) */ 0x95, 0x08, /* Report Count (8) */
0xB1, 0x02, /* Feature (2) (???) */ 0xB1, 0x02, /* Feature (2) (???) */
/* 46 */
0xC0 /* End Collection */ 0xC0 /* End Collection */
/* 47 */
};
// TKEYCTRL Device Descriptor (copy from CfgDesc)
FLASH uint8_t TKEYCTRL_CfgDesc[] = {
0x09, /* bLength: HID Descriptor size */
USB_DESC_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID (low byte): HID Class Spec release number */
0x01, /* bcdHID (high byte): HID Class Spec release number */
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
USB_DESC_TYPE_REPORT, /* bDescriptorType: Report */
LOBYTE(TKEYCTRL_REPORT_DESC_SIZE),/* wDescriptorLength (low byte): Total length of Report descriptor */
HIBYTE(TKEYCTRL_REPORT_DESC_SIZE),/* wDescriptorLength (high byte): Total length of Report descriptor */
};
// TKEYCTRL Report Descriptor
FLASH uint8_t TKEYCTRL_ReportDesc[] ={
0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined 0xFF00) */
0x09, 0x01, /* Usage (Vendor Usage 1) */
0xA1, 0x01, /* Collection (Application) */
/* 7 */
0x09, 0x02, /* Usage (Output Report Data), 0x02 defines that the output report carries raw data from the host to the device. */
0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8 bits) */
0x95, MAX_PACKET_SIZE, /* Report Count (64 bytes) */
0x91, 0x02, /* Output (Data, Variable, Absolute) */
/* 20 */
0x09, 0x03, /* Usage (Input Report), 0x03 defines that the input report carries raw data for the host. */
0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xFF, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8 bits) */
0x95, MAX_PACKET_SIZE, /* Report Count (64 bytes) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
/* 33 */
0xC0 /* End Collection */
/* 34 */
}; };
// String Descriptor (Language descriptor ) // String Descriptor (Language descriptor )
FLASH uint8_t LangDesc[] = { FLASH uint8_t LangDesc[] = {
0x04, 0x03, 0x09, 0x04 4, // Length of this descriptor (in bytes)
0x03, // Descriptor type (String)
0x09, 0x04, // Language ID (English - US)
}; };
// CDC Parameters: The initial baud rate is 500000, 1 stop bit, no parity, 8 data bits. // CDC Parameters: The initial baud rate is 500000, 1 stop bit, no parity, 8 data bits.
@ -271,6 +374,7 @@ XDATA uint8_t LineCoding[7] = { 0x20, 0xA1, 0x07, 0x00, /* Data terminal rate, i
0x08, /* Data bits (5, 6, 7, 8 or 16) */ 0x08, /* Data bits (5, 6, 7, 8 or 16) */
}; };
#define TKEYCTRL_FRAME_SIZE 64
#define HID_FRAME_SIZE 64 #define HID_FRAME_SIZE 64
#define MAX_CDC_FRAME_SIZE 64 #define MAX_CDC_FRAME_SIZE 64
@ -281,6 +385,7 @@ XDATA uint8_t LineCoding[7] = { 0x20, 0xA1, 0x07, 0x00, /* Data terminal rate, i
XDATA uint8_t UartTxBuf[UART_TX_BUF_SIZE] = { 0 }; // Serial transmit buffer XDATA uint8_t UartTxBuf[UART_TX_BUF_SIZE] = { 0 }; // Serial transmit buffer
volatile IDATA uint8_t Ep2ByteLen; volatile IDATA uint8_t Ep2ByteLen;
volatile IDATA uint8_t Ep3ByteLen; volatile IDATA uint8_t Ep3ByteLen;
volatile IDATA uint8_t Ep4ByteLen;
XDATA uint8_t UartRxBuf[UART_RX_BUF_SIZE] = { 0 }; // Serial receive buffer XDATA uint8_t UartRxBuf[UART_RX_BUF_SIZE] = { 0 }; // Serial receive buffer
volatile IDATA uint8_t UartRxBufInputPointer = 0; // Circular buffer write pointer, bus reset needs to be initialized to 0 volatile IDATA uint8_t UartRxBufInputPointer = 0; // Circular buffer write pointer, bus reset needs to be initialized to 0
@ -298,8 +403,16 @@ 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 (HID) volatile IDATA uint8_t UsbEp3ByteCount = 0; // Represents the data received by USB endpoint 3 (HID)
volatile IDATA uint8_t UsbEp4ByteCount = 0; // Represents the data received by USB endpoint 4 (TKEYCTRL)
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 (HID) is busy volatile IDATA uint8_t Endpoint3UploadBusy = 0; // Whether the upload endpoint 3 (HID) is busy
volatile IDATA uint8_t Endpoint4UploadBusy = 0; // Whether the upload endpoint 4 (TKEYCTRL) is busy
/** TKEYCTRL variables */
XDATA uint8_t TkeyCtrlRxBuf[TKEYCTRL_FRAME_SIZE] = { 0 };
IDATA uint8_t TkeyCtrlRxBufLength = 0;
IDATA uint8_t TkeyCtrlDataAvailable = 0;
/** CDC variables */ /** CDC variables */
XDATA uint8_t CdcRxBuf[MAX_CDC_FRAME_SIZE] = { 0 }; XDATA uint8_t CdcRxBuf[MAX_CDC_FRAME_SIZE] = { 0 };
@ -312,6 +425,8 @@ IDATA uint8_t HidRxBufLength = 0;
IDATA uint8_t HidDataAvailable = 0; IDATA uint8_t HidDataAvailable = 0;
/** Frame data */ /** Frame data */
#define MODE_TKEYCTRL 0x20
#define MODE_CDC 0x40 #define MODE_CDC 0x40
#define MODE_HID 0x80 #define MODE_HID 0x80
#define MODE_MASK 0xC0 #define MODE_MASK 0xC0
@ -382,18 +497,22 @@ void USBDeviceIntCfg()
void USBDeviceEndPointCfg() void USBDeviceEndPointCfg()
{ {
// TODO: Is casting the right thing here? What about endianness? // TODO: Is casting the right thing here? What about endianness?
UEP0_DMA = (uint16_t) Ep0Buffer; // Endpoint 0 data transfer address UEP0_DMA = (uint16_t) Ep0Buffer; // Endpoint 0 data transfer address, Endpoint 4
UEP1_DMA = (uint16_t) Ep1Buffer; // Endpoint 1 sends data transfer address UEP1_DMA = (uint16_t) Ep1Buffer; // Endpoint 1 sends data transfer address
UEP2_DMA = (uint16_t) Ep2Buffer; // Endpoint 2 IN data transfer address UEP2_DMA = (uint16_t) Ep2Buffer; // Endpoint 2 IN data transfer address
UEP3_DMA = (uint16_t) Ep3Buffer; // Endpoint 3 IN data transfer address UEP3_DMA = (uint16_t) Ep3Buffer; // Endpoint 3 IN data transfer address
UEP4_1_MOD = bUEP1_TX_EN; // Endpoint 1, transmit enable; Endpoint 0 single 8-byte send and receive buffer UEP4_1_MOD = bUEP4_TX_EN | bUEP4_RX_EN | bUEP1_TX_EN; // Endpoint 0 single 8-byte send and receive buffer
UEP2_3_MOD = bUEP2_TX_EN | bUEP2_RX_EN | bUEP3_TX_EN | bUEP3_RX_EN; // Endpoint 2/3, single buffer, transmit+receive enable // Endpoint 1, transmit enable
// Endpoint 4, single buffer, transmit+receive enable
UEP2_3_MOD = bUEP2_TX_EN | bUEP2_RX_EN | bUEP3_TX_EN | bUEP3_RX_EN; // Endpoint 2, single buffer, transmit+receive enable
// Endpoint 3, single buffer, transmit+receive enable
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; // Manual flip, OUT transaction returns ACK, IN transaction returns NAK UEP0_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 0, manual flip, OUT transaction returns ACK, IN transaction returns NAK
UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; // Endpoint 1 automatically flips the synchronization flag, IN transaction returns NAK UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; // Endpoint 1, automatically flips the synchronization flag, IN transaction returns NAK
UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 2 automatically flips the synchronization flag, IN transaction returns NAK, OUT returns ACK UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 2, automatically flips the synchronization flag, IN transaction returns NAK, OUT returns ACK
UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 3 automatically flips the synchronization flag, IN transaction returns NAK, OUT returns ACK UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 3, automatically flips the synchronization flag, IN transaction returns NAK, OUT returns ACK
UEP4_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 4, manual flip, OUT transaction returns ACK, IN transaction returns NAK
} }
@ -505,20 +624,58 @@ void usb_irq_setup_handler(void)
pDescr = SerialDesc; pDescr = SerialDesc;
len = sizeof(SerialDesc); len = sizeof(SerialDesc);
printStrSetup("SerialDesc\n"); printStrSetup("SerialDesc\n");
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_CDC_CTRL_STR) {
pDescr = CdcCtrlInterfaceDesc;
len = sizeof(CdcCtrlInterfaceDesc);
printStrSetup("CdcCtrlInterfaceDesc\n");
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_CDC_DATA_STR) {
pDescr = CdcDataInterfaceDesc;
len = sizeof(CdcDataInterfaceDesc);
printStrSetup("CdcDataInterfaceDesc\n");
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_FIDO_HID_STR) {
pDescr = FidoHidInterfaceDesc;
len = sizeof(FidoHidInterfaceDesc);
printStrSetup("FidoHidInterfaceDesc\n");
} else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_TKEY_CTRL_STR) {
pDescr = TkeyCtrlInterfaceDesc;
len = sizeof(TkeyCtrlInterfaceDesc);
printStrSetup("TkeyCtrlInterfaceDesc\n");
} else { } else {
printStrSetup("Error: USB_DESC_TYPE_STRING\n"); printStrSetup("Error: USB_DESC_TYPE_STRING\n");
} }
break; break;
case USB_DESC_TYPE_HID: case USB_DESC_TYPE_HID:
switch (UsbSetupBuf->wIndexL) {
case 0x02: // Interface 2 (HID)
pDescr = HID_CfgDesc; pDescr = HID_CfgDesc;
len = sizeof(HID_CfgDesc); len = sizeof(HID_CfgDesc);
printStrSetup("HID_CfgDesc\n"); printStrSetup("HID_CfgDesc\n");
break; break;
case 0x03: // Interface 3 (TKEYCTRL)
pDescr = TKEYCTRL_CfgDesc;
len = sizeof(TKEYCTRL_CfgDesc);
printStrSetup("TKEYCTRL_CfgDesc\n");
break;
default:
break;
}
break;
case USB_DESC_TYPE_REPORT: case USB_DESC_TYPE_REPORT:
switch (UsbSetupBuf->wIndexL) {
case 0x02: // Interface 2 (HID)
pDescr = HID_ReportDesc; pDescr = HID_ReportDesc;
len = sizeof(HID_ReportDesc); len = sizeof(HID_ReportDesc);
printStrSetup("HID_ReportDesc\n"); printStrSetup("HID_ReportDesc\n");
break; break;
case 0x03: // Interface 3 (TKEYCTRL)
pDescr = TKEYCTRL_ReportDesc;
len = sizeof(TKEYCTRL_ReportDesc);
printStrSetup("TKEYCTRL_ReportDesc\n");
break;
default:
break;
}
break;
default: default:
len = 0xFF; // Unsupported command or error len = 0xFF; // Unsupported command or error
printStrSetup("Unsupported\n"); printStrSetup("Unsupported\n");
@ -574,6 +731,12 @@ void usb_irq_setup_handler(void)
} }
} else if ((UsbSetupBuf->bmRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) { // Endpoint } else if ((UsbSetupBuf->bmRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) { // Endpoint
switch (UsbSetupBuf->wIndexL) { switch (UsbSetupBuf->wIndexL) {
case 0x84:
UEP4_CTRL = (UEP4_CTRL & ~(bUEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK; // Set endpoint 4 IN (TX) NAK
break;
case 0x04:
UEP4_CTRL = (UEP4_CTRL & ~(bUEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK; // Set endpoint 4 OUT (RX) ACK
break;
case 0x83: case 0x83:
UEP3_CTRL = (UEP3_CTRL & ~(bUEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK; // Set endpoint 3 IN (TX) NAK UEP3_CTRL = (UEP3_CTRL & ~(bUEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK; // Set endpoint 3 IN (TX) NAK
break; break;
@ -628,6 +791,12 @@ void usb_irq_setup_handler(void)
} else if (( UsbSetupBuf->bmRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) { // Set endpoint } else if (( UsbSetupBuf->bmRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) { // Set endpoint
if ((((uint16_t) UsbSetupBuf->wValueH << 8) | UsbSetupBuf->wValueL) == 0x00) { if ((((uint16_t) UsbSetupBuf->wValueH << 8) | UsbSetupBuf->wValueL) == 0x00) {
switch (((uint16_t) UsbSetupBuf->wIndexH << 8) | UsbSetupBuf->wIndexL) { switch (((uint16_t) UsbSetupBuf->wIndexH << 8) | UsbSetupBuf->wIndexL) {
case 0x84:
UEP4_CTRL = (UEP4_CTRL & ~bUEP_T_TOG) | UEP_T_RES_STALL; // Set endpoint 4 IN (TX) Stall (error)
break;
case 0x04:
UEP4_CTRL = (UEP4_CTRL & ~bUEP_R_TOG) | UEP_R_RES_STALL; // Set endpoint 4 OUT (RX) Stall (error)
break;
case 0x83: case 0x83:
UEP3_CTRL = (UEP3_CTRL & ~bUEP_T_TOG) | UEP_T_RES_STALL; // Set endpoint 3 IN (TX) Stall (error) UEP3_CTRL = (UEP3_CTRL & ~bUEP_T_TOG) | UEP_T_RES_STALL; // Set endpoint 3 IN (TX) Stall (error)
break; break;
@ -752,6 +921,13 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist
Endpoint3UploadBusy = 0; // Clear busy flag Endpoint3UploadBusy = 0; // Clear busy flag
break; break;
case UIS_TOKEN_IN | 4: // Endpoint 4 IN (TX), Endpoint bulk upload
UEP4_T_LEN = 0; // Transmit length must be cleared (Endpoint 4)
UEP4_CTRL = (UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; // Default answer NAK
UEP4_CTRL ^= bUEP_T_TOG; // Sync flag flip
Endpoint4UploadBusy = 0; // Clear busy flag
break;
case UIS_TOKEN_OUT | 0: // Endpoint 0 OUT (RX) case UIS_TOKEN_OUT | 0: // Endpoint 0 OUT (RX)
switch (SetupReq) { switch (SetupReq) {
case USB_CDC_REQ_TYPE_SET_LINE_CODING: // We ignore line coding here because baudrate to the FPGA should not change case USB_CDC_REQ_TYPE_SET_LINE_CODING: // We ignore line coding here because baudrate to the FPGA should not change
@ -790,6 +966,15 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist
} }
break; break;
case UIS_TOKEN_OUT | 4: // Endpoint 4 OUT (RX), Endpoint batch download
// Out-of-sync packets will be dropped
if (U_TOG_OK) {
UsbEp4ByteCount = USB_RX_LEN; // Length of received data
UEP4_CTRL = (UEP4_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_NAK; // NAK after receiving a packet of data, the main function finishes processing, and the main function modifies the response mode
UEP4_CTRL ^= bUEP_R_TOG; // Sync flag flip
}
break;
default: default:
break; break;
} }
@ -804,6 +989,7 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist
UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK;
UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK;
UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK;
UEP4_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK;
USB_DEV_AD = 0x00; USB_DEV_AD = 0x00;
UIF_SUSPEND = 0; UIF_SUSPEND = 0;
UIF_TRANSFER = 0; // Writing 0 clears the interrupt UIF_TRANSFER = 0; // Writing 0 clears the interrupt
@ -994,6 +1180,7 @@ void main()
UEP1_T_LEN = 0; // Transmit length must be cleared (Endpoint 1) UEP1_T_LEN = 0; // Transmit length must be cleared (Endpoint 1)
UEP2_T_LEN = 0; // Transmit length must be cleared (Endpoint 2) UEP2_T_LEN = 0; // Transmit length must be cleared (Endpoint 2)
UEP3_T_LEN = 0; // Transmit length must be cleared (Endpoint 3) UEP3_T_LEN = 0; // Transmit length must be cleared (Endpoint 3)
UEP4_T_LEN = 0; // Transmit length must be cleared (Endpoint 4)
while (1) { while (1) {
if (UsbConfig) { if (UsbConfig) {
@ -1022,12 +1209,25 @@ void main()
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
} }
// Check if Endpoint 4 (TKEYCTRL) has received data
if (UsbEp4ByteCount) {
Ep4ByteLen = UsbEp4ByteCount; // UsbEp4ByteCount can be maximum 64 bytes
memcpy(UartTxBuf, Ep0Buffer+64, Ep4ByteLen); // Endpoint 4 receive is at address UEP0_DMA+64
UsbEp4ByteCount = 0;
CH554UART1SendByte(MODE_TKEYCTRL); // Send TKEYCTRL mode header
CH554UART1SendByte(Ep4ByteLen); // Send length (always 64 bytes)
CH554UART1SendBuffer(UartTxBuf, Ep4ByteLen);
UEP4_CTRL = (UEP4_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_ACK; // Enable Endpoint 4 to ACK again
}
UartRxBufByteCount = uart_byte_count(); // Check amount of data in buffer UartRxBufByteCount = uart_byte_count(); // Check amount of data in buffer
if ((UartRxBufByteCount >= 2) && !FrameStarted) { // If we have data and the header is not yet validated if ((UartRxBufByteCount >= 2) && !FrameStarted) { // If we have data and the header is not yet validated
FrameMode = UartRxBuf[UartRxBufOutputPointer]; // Extract frame mode FrameMode = UartRxBuf[UartRxBufOutputPointer]; // Extract frame mode
if ((FrameMode == MODE_CDC) || if ((FrameMode == MODE_CDC) ||
(FrameMode == MODE_HID)) { (FrameMode == MODE_HID) ||
(FrameMode == MODE_TKEYCTRL)) {
FrameLength = UartRxBuf[increment_pointer(UartRxBufOutputPointer, FrameLength = UartRxBuf[increment_pointer(UartRxBufOutputPointer,
1, 1,
UART_RX_BUF_SIZE)]; // Extract frame length UART_RX_BUF_SIZE)]; // Extract frame length
@ -1067,6 +1267,44 @@ void main()
} }
} }
// Copy TKEYCTRL data from UartRxBuf to TkeyCtrlRxBuf
if (FrameStarted && !TkeyCtrlDataAvailable) {
if (FrameMode == MODE_TKEYCTRL) {
if ((FrameRemainingBytes >= MAX_PACKET_SIZE) &&
(UartRxBufByteCount >= MAX_PACKET_SIZE)) {
circular_copy(TkeyCtrlRxBuf,
UartRxBuf,
UART_RX_BUF_SIZE,
UartRxBufOutputPointer,
MAX_PACKET_SIZE);
TkeyCtrlRxBufLength = MAX_PACKET_SIZE;
// Update output pointer
UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer,
MAX_PACKET_SIZE,
UART_RX_BUF_SIZE);
FrameRemainingBytes -= MAX_PACKET_SIZE;
TkeyCtrlDataAvailable = 1;
cts_start();
}
else if ((FrameRemainingBytes < MAX_PACKET_SIZE) &&
(UartRxBufByteCount >= FrameRemainingBytes)) {
circular_copy(TkeyCtrlRxBuf,
UartRxBuf,
UART_RX_BUF_SIZE,
UartRxBufOutputPointer,
FrameRemainingBytes);
TkeyCtrlRxBufLength = FrameRemainingBytes;
// Update output pointer
UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer,
FrameRemainingBytes,
UART_RX_BUF_SIZE);
FrameRemainingBytes -= FrameRemainingBytes;
TkeyCtrlDataAvailable = 1;
cts_start();
}
}
}
// Copy CDC data from UartRxBuf to CdcRxBuf // Copy CDC data from UartRxBuf to CdcRxBuf
if (FrameStarted && !CdcDataAvailable) { if (FrameStarted && !CdcDataAvailable) {
if (FrameMode == MODE_CDC) { if (FrameMode == MODE_CDC) {
@ -1128,6 +1366,7 @@ void main()
// Check if we should upload data to Endpoint 2 (CDC) // Check if we should upload data to Endpoint 2 (CDC)
if (CdcDataAvailable && !Endpoint2UploadBusy) { if (CdcDataAvailable && !Endpoint2UploadBusy) {
// Write upload endpoint // Write upload endpoint
memcpy(Ep2Buffer + MAX_PACKET_SIZE, /* Copy to IN buffer of Endpoint 2 */ memcpy(Ep2Buffer + MAX_PACKET_SIZE, /* Copy to IN buffer of Endpoint 2 */
CdcRxBuf, CdcRxBuf,
@ -1164,6 +1403,35 @@ void main()
FrameStarted = 0; FrameStarted = 0;
} }
// Check if we should upload data to Endpoint 4 (TKEYCTRL)
if (TkeyCtrlDataAvailable && !Endpoint4UploadBusy) {
if (TkeyCtrlRxBufLength == MAX_PACKET_SIZE) {
// Write upload endpoint
memcpy(Ep0Buffer+128, /* Copy to IN (TX) buffer of Endpoint 4 */
TkeyCtrlRxBuf,
TkeyCtrlRxBufLength);
} else {
memset(Ep0Buffer+128, 0, MAX_PACKET_SIZE);
// Write upload endpoint
memcpy(Ep0Buffer+128, /* Copy to IN (TX) buffer of Endpoint 4 */
TkeyCtrlRxBuf,
TkeyCtrlRxBufLength);
}
UEP4_T_LEN = MAX_PACKET_SIZE; // Set the number of data bytes that Endpoint 4 is ready to send
UEP4_CTRL = (UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK; // Answer ACK
Endpoint4UploadBusy = 1; // Set busy flag
TkeyCtrlDataAvailable = 0;
TkeyCtrlRxBufLength = 0;
if (FrameRemainingBytes == 0) {
// Complete frame sent, get next header and data
FrameStarted = 0;
}
}
#if 0 #if 0
DebugUartRxBufByteCount = debug_uart_byte_count(); DebugUartRxBufByteCount = debug_uart_byte_count();
if (DebugUartRxBufByteCount) { if (DebugUartRxBufByteCount) {
@ -1195,6 +1463,7 @@ void main()
/** Endpoints */ /** Endpoints */
UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; UEP2_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK;
UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK; UEP3_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK | UEP_R_RES_ACK;
UEP4_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK;
UIF_TRANSFER = 0; // Writing 0 clears the interrupt UIF_TRANSFER = 0; // Writing 0 clears the interrupt
UIF_BUS_RST = 0; // Clear interrupt flag UIF_BUS_RST = 0; // Clear interrupt flag
@ -1217,6 +1486,10 @@ void main()
printStr("UsbEp3ByteCount = "); printNumU32(UsbEp3ByteCount); printStr("\n"); printStr("UsbEp3ByteCount = "); printNumU32(UsbEp3ByteCount); printStr("\n");
printStr("UEP3_CTRL = 0x"); printNumHex(UEP3_CTRL); printStr("\n"); printStr("UEP3_CTRL = 0x"); printNumHex(UEP3_CTRL); printStr("\n");
printStr("Endpoint4UploadBusy = "); printNumU32(Endpoint4UploadBusy); printStr("\n");
printStr("UsbEp4ByteCount = "); printNumU32(UsbEp4ByteCount); printStr("\n");
printStr("UEP4_CTRL = 0x"); printNumHex(UEP4_CTRL); printStr("\n");
printStr("UartRxBufInputPointer = "); printNumU32(UartRxBufInputPointer); printStr("\n"); printStr("UartRxBufInputPointer = "); printNumU32(UartRxBufInputPointer); printStr("\n");
printStr("UartRxBufOutputPointer = "); printNumU32(UartRxBufOutputPointer); printStr("\n"); printStr("UartRxBufOutputPointer = "); printNumU32(UartRxBufOutputPointer); printStr("\n");
printStr("UartRxBufOverflow = "); printNumU32(UartRxBufOverflow); printStr("\n"); printStr("UartRxBufOverflow = "); printNumU32(UartRxBufOverflow); printStr("\n");