From 7de49d2021154fc6e60472df820a93405473d152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Th=C3=B6rnblad?= Date: Wed, 19 Mar 2025 15:44:37 +0100 Subject: [PATCH 1/3] ch552: Reorganize file directory structure - Move source files to separate directory. - Move include files to separate directory. - Add specific output direcory for intermediate files. --- hw/usb_interface/ch552_fw/Makefile | 40 +++++++++---------- .../ch552_fw/encode_usb_strings.py | 2 +- .../ch552_fw/{include => inc}/ch554.h | 0 .../ch552_fw/{include => inc}/ch554_usb.h | 0 .../ch552_fw/{include => inc}/debug.h | 0 .../ch552_fw/{include => inc}/mem.h | 0 .../ch552_fw/{include => inc}/print.h | 0 .../ch552_fw/{include => inc}/usb_strings.h | 0 .../ch552_fw/{include => src}/debug.c | 0 hw/usb_interface/ch552_fw/{ => src}/main.c | 0 .../ch552_fw/{include => src}/print.c | 0 11 files changed, 19 insertions(+), 23 deletions(-) rename hw/usb_interface/ch552_fw/{include => inc}/ch554.h (100%) rename hw/usb_interface/ch552_fw/{include => inc}/ch554_usb.h (100%) rename hw/usb_interface/ch552_fw/{include => inc}/debug.h (100%) rename hw/usb_interface/ch552_fw/{include => inc}/mem.h (100%) rename hw/usb_interface/ch552_fw/{include => inc}/print.h (100%) rename hw/usb_interface/ch552_fw/{include => inc}/usb_strings.h (100%) rename hw/usb_interface/ch552_fw/{include => src}/debug.c (100%) rename hw/usb_interface/ch552_fw/{ => src}/main.c (100%) rename hw/usb_interface/ch552_fw/{include => src}/print.c (100%) diff --git a/hw/usb_interface/ch552_fw/Makefile b/hw/usb_interface/ch552_fw/Makefile index 619b4a8..b278fff 100644 --- a/hw/usb_interface/ch552_fw/Makefile +++ b/hw/usb_interface/ch552_fw/Makefile @@ -10,7 +10,7 @@ CHPROG = chprog TARGET = usb_device -ROOT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +OUT_DIR = _out XRAM_SIZE = 0x0400 # 1 KB on-chip xRAM XRAM_LOC = 0x0000 # xRAM area starts at address 0 in the External Data Address Space @@ -26,7 +26,7 @@ CFLAGS = \ --xram-size $(XRAM_SIZE) \ --xram-loc $(XRAM_LOC) \ --code-size $(CODE_SIZE) \ - -I$(ROOT_DIR)include \ + -Iinc \ -DFREQ_SYS=$(FREQ_SYS) \ $(EXTRA_FLAGS) @@ -34,25 +34,28 @@ LFLAGS = \ $(CFLAGS) C_FILES = \ - main.c \ - include/debug.c \ - include/print.c + src/main.c \ + src/debug.c \ + src/print.c -# Create a .rel file for each .c file -RELS = $(C_FILES:.c=.rel) +# Create a .rel file for each .c file in $(OUT_DIR)/ +RELS = $(patsubst %.c,$(OUT_DIR)/%.rel,$(C_FILES)) -%.rel : %.c - $(CC) -c $(CFLAGS) $< +OUT_SUBDIRS = $(sort $(dir $(RELS))) + +# Ensure out directory exists +$(OUT_DIR): + mkdir -p $(OUT_SUBDIRS) + +$(OUT_DIR)/%.rel: %.c | $(OUT_DIR) + $(CC) -c $(CFLAGS) $< -o $@ usb_strings.h: encode_usb_strings.py ./encode_usb_strings.py -# Note: SDCC will dump all of the temporary files into this one, -# so strip the paths from RELS -# For now, get around this by stripping the paths off of the RELS list. - +# Compile the final ihx file $(TARGET).ihx: $(RELS) - $(CC) $(notdir $(RELS)) $(LFLAGS) -o $(TARGET).ihx + $(CC) $(RELS) $(LFLAGS) -o $(TARGET).ihx $(TARGET).hex: $(TARGET).ihx $(PACK_HEX) $(TARGET).ihx > $(TARGET).hex @@ -72,14 +75,7 @@ flash_patched: $(TARGET).bin all: $(TARGET).bin $(TARGET).hex clean: - rm -f \ - $(notdir $(RELS:.rel=.asm)) \ - $(notdir $(RELS:.rel=.lst)) \ - $(notdir $(RELS:.rel=.mem)) \ - $(notdir $(RELS:.rel=.rel)) \ - $(notdir $(RELS:.rel=.rst)) \ - $(notdir $(RELS:.rel=.sym)) \ - $(notdir $(RELS:.rel=.adb)) \ + rm -rf $(OUT_DIR) \ $(TARGET).lk \ $(TARGET).map \ $(TARGET).mem \ diff --git a/hw/usb_interface/ch552_fw/encode_usb_strings.py b/hw/usb_interface/ch552_fw/encode_usb_strings.py index 697514e..98c4feb 100755 --- a/hw/usb_interface/ch552_fw/encode_usb_strings.py +++ b/hw/usb_interface/ch552_fw/encode_usb_strings.py @@ -57,7 +57,7 @@ if __name__ == "__main__": "TkeyCtrlInterfaceDesc": "TKEY-Ctrl" } - with open('include/usb_strings.h', 'w') as f: + with open('inc/usb_strings.h', 'w') as f: f.write('#ifndef __USB_STRINGS_H__\n') f.write('#define __USB_STRINGS_H__\n') f.write('\n') diff --git a/hw/usb_interface/ch552_fw/include/ch554.h b/hw/usb_interface/ch552_fw/inc/ch554.h similarity index 100% rename from hw/usb_interface/ch552_fw/include/ch554.h rename to hw/usb_interface/ch552_fw/inc/ch554.h diff --git a/hw/usb_interface/ch552_fw/include/ch554_usb.h b/hw/usb_interface/ch552_fw/inc/ch554_usb.h similarity index 100% rename from hw/usb_interface/ch552_fw/include/ch554_usb.h rename to hw/usb_interface/ch552_fw/inc/ch554_usb.h diff --git a/hw/usb_interface/ch552_fw/include/debug.h b/hw/usb_interface/ch552_fw/inc/debug.h similarity index 100% rename from hw/usb_interface/ch552_fw/include/debug.h rename to hw/usb_interface/ch552_fw/inc/debug.h diff --git a/hw/usb_interface/ch552_fw/include/mem.h b/hw/usb_interface/ch552_fw/inc/mem.h similarity index 100% rename from hw/usb_interface/ch552_fw/include/mem.h rename to hw/usb_interface/ch552_fw/inc/mem.h diff --git a/hw/usb_interface/ch552_fw/include/print.h b/hw/usb_interface/ch552_fw/inc/print.h similarity index 100% rename from hw/usb_interface/ch552_fw/include/print.h rename to hw/usb_interface/ch552_fw/inc/print.h diff --git a/hw/usb_interface/ch552_fw/include/usb_strings.h b/hw/usb_interface/ch552_fw/inc/usb_strings.h similarity index 100% rename from hw/usb_interface/ch552_fw/include/usb_strings.h rename to hw/usb_interface/ch552_fw/inc/usb_strings.h diff --git a/hw/usb_interface/ch552_fw/include/debug.c b/hw/usb_interface/ch552_fw/src/debug.c similarity index 100% rename from hw/usb_interface/ch552_fw/include/debug.c rename to hw/usb_interface/ch552_fw/src/debug.c diff --git a/hw/usb_interface/ch552_fw/main.c b/hw/usb_interface/ch552_fw/src/main.c similarity index 100% rename from hw/usb_interface/ch552_fw/main.c rename to hw/usb_interface/ch552_fw/src/main.c diff --git a/hw/usb_interface/ch552_fw/include/print.c b/hw/usb_interface/ch552_fw/src/print.c similarity index 100% rename from hw/usb_interface/ch552_fw/include/print.c rename to hw/usb_interface/ch552_fw/src/print.c From 1ed8398700a83fa726ed38482cd9fdb10fee379e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Th=C3=B6rnblad?= Date: Mon, 24 Mar 2025 14:14:43 +0100 Subject: [PATCH 2/3] ch552: Split functionality into separate files - Move GPIO functions to gpio.c and gpio.h - Move string handling functions for debug to lib.c and lib.h - Add main.h and move config defines there - Add debug print functionality via FPGA with framing protocol - Add Flash Code and Flash Data functions to flash.c and flash.h --- hw/usb_interface/ch552_fw/Makefile | 5 +- hw/usb_interface/ch552_fw/inc/debug.h | 13 +- hw/usb_interface/ch552_fw/inc/flash.h | 9 ++ hw/usb_interface/ch552_fw/inc/gpio.h | 20 +++ hw/usb_interface/ch552_fw/inc/lib.h | 23 +++ hw/usb_interface/ch552_fw/inc/main.h | 18 +++ hw/usb_interface/ch552_fw/inc/print.h | 35 +++-- hw/usb_interface/ch552_fw/src/debug.c | 105 -------------- hw/usb_interface/ch552_fw/src/flash.c | 79 ++++++++++ hw/usb_interface/ch552_fw/src/gpio.c | 108 ++++++++++++++ hw/usb_interface/ch552_fw/src/lib.c | 200 ++++++++++++++++++++++++++ hw/usb_interface/ch552_fw/src/main.c | 22 +-- hw/usb_interface/ch552_fw/src/print.c | 187 ++++++++++-------------- 13 files changed, 562 insertions(+), 262 deletions(-) create mode 100644 hw/usb_interface/ch552_fw/inc/flash.h create mode 100644 hw/usb_interface/ch552_fw/inc/gpio.h create mode 100644 hw/usb_interface/ch552_fw/inc/lib.h create mode 100644 hw/usb_interface/ch552_fw/inc/main.h create mode 100644 hw/usb_interface/ch552_fw/src/flash.c create mode 100644 hw/usb_interface/ch552_fw/src/gpio.c create mode 100644 hw/usb_interface/ch552_fw/src/lib.c diff --git a/hw/usb_interface/ch552_fw/Makefile b/hw/usb_interface/ch552_fw/Makefile index b278fff..6cf1932 100644 --- a/hw/usb_interface/ch552_fw/Makefile +++ b/hw/usb_interface/ch552_fw/Makefile @@ -34,8 +34,11 @@ LFLAGS = \ $(CFLAGS) C_FILES = \ - src/main.c \ src/debug.c \ + src/flash.c \ + src/gpio.c \ + src/lib.c \ + src/main.c \ src/print.c # Create a .rel file for each .c file in $(OUT_DIR)/ diff --git a/hw/usb_interface/ch552_fw/inc/debug.h b/hw/usb_interface/ch552_fw/inc/debug.h index 1e443b3..e17f54c 100644 --- a/hw/usb_interface/ch552_fw/inc/debug.h +++ b/hw/usb_interface/ch552_fw/inc/debug.h @@ -8,6 +8,7 @@ #include #include "ch554.h" +#include "gpio.h" // UART1 baud rates // Setting Actual % error @@ -40,18 +41,6 @@ void CfgFsys(void); // CH554 clock selection and configuration void mDelayuS(uint16_t n); // Delay in units of uS void mDelaymS(uint16_t n); // Delay in mS -// Set pin p1.4 and p1.5 to GPIO output mode. -void gpio_init(void); -void gpio_set(uint8_t pin); -void gpio_unset(uint8_t pin); -uint8_t gpio_get(uint8_t pin); - -void gpio_init_p1_4_in(void); -void gpio_init_p1_5_out(void); -uint8_t gpio_p1_4_get(void); -void gpio_p1_5_set(void); -void gpio_p1_5_unset(void); - /******************************************************************************* * Function Name : CH554UART0Alter() * Description : Set the alternate pin mappings for UART0 (RX on P1.2, TX on P1.3) diff --git a/hw/usb_interface/ch552_fw/inc/flash.h b/hw/usb_interface/ch552_fw/inc/flash.h new file mode 100644 index 0000000..3a37b77 --- /dev/null +++ b/hw/usb_interface/ch552_fw/inc/flash.h @@ -0,0 +1,9 @@ +#ifndef __FLASH_H__ +#define __FLASH_H__ + +#include + +uint8_t write_code_flash(uint16_t address, uint16_t data); +uint8_t write_data_flash(uint8_t address, uint8_t data); + +#endif diff --git a/hw/usb_interface/ch552_fw/inc/gpio.h b/hw/usb_interface/ch552_fw/inc/gpio.h new file mode 100644 index 0000000..30b6f83 --- /dev/null +++ b/hw/usb_interface/ch552_fw/inc/gpio.h @@ -0,0 +1,20 @@ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#include + +#include "main.h" + +// Set pin p1.4 and p1.5 to GPIO output mode. +void gpio_init(void); +void gpio_set(uint8_t pin); +void gpio_unset(uint8_t pin); +uint8_t gpio_get(uint8_t pin); + +void gpio_init_p1_4_in(void); +void gpio_init_p1_5_out(void); +uint8_t gpio_p1_4_get(void); +void gpio_p1_5_set(void); +void gpio_p1_5_unset(void); + +#endif diff --git a/hw/usb_interface/ch552_fw/inc/lib.h b/hw/usb_interface/ch552_fw/inc/lib.h new file mode 100644 index 0000000..5292a35 --- /dev/null +++ b/hw/usb_interface/ch552_fw/inc/lib.h @@ -0,0 +1,23 @@ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + +#include "main.h" + +#ifdef USE_NUM_U8 +int8_t uint8_to_str(uint8_t *buf, uint8_t bufsize, uint8_t n); +#endif + +#ifdef USE_NUM_U32 +int8_t uint32_to_str(uint8_t *buf, uint8_t bufsize, uint32_t n); +#endif + +//uint8_t hex_to_uint8(const char *hex, uint8_t len); +//uint16_t hex_to_uint16(const char *hex, uint8_t len); +uint32_t hex_to_uint32(const char *hex, uint8_t len); + +uint8_t ascii_hex_char_to_byte(uint8_t c); +//int ascii_hex_string_to_bytes(uint8_t *hex_str, uint8_t *out_bytes, size_t out_len); + +#endif diff --git a/hw/usb_interface/ch552_fw/inc/main.h b/hw/usb_interface/ch552_fw/inc/main.h new file mode 100644 index 0000000..aa21f8c --- /dev/null +++ b/hw/usb_interface/ch552_fw/inc/main.h @@ -0,0 +1,18 @@ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#define USE_DEBUG_PRINT /* Enable to print debug messages */ +#define DEBUG_PRINT_SW /* Enable to print debug messages via FPGA */ +//#define DEBUG_PRINT_HW /* Enable to print debug messages via UART0 */ + +#define USE_NUM_U8 +//#define USE_NUM_U32 + +//#define DEBUG_SETUP /* Enable to debug USB setup flow (printStrSetup,printNumU8HexSetup) */ + +#define USE_NUM_U8HEX +#define USE_NUM_U16HEX +//#define USE_NUM_U32HEX +//#define USE_NEGATIVE_NUMS + +#endif diff --git a/hw/usb_interface/ch552_fw/inc/print.h b/hw/usb_interface/ch552_fw/inc/print.h index f5a4844..0a117dc 100644 --- a/hw/usb_interface/ch552_fw/inc/print.h +++ b/hw/usb_interface/ch552_fw/inc/print.h @@ -3,30 +3,17 @@ #include -//#define DEBUG_PRINT -//#define DEBUG_SETUP -//#define UART_OUT_DEBUG -//#define USE_NUM_U8 -#define USE_NUM_U32 -//#define USE_NEGATIVE_NUMS +#include "main.h" void printStr(uint8_t *str); void printChar(uint8_t c); #ifdef DEBUG_SETUP -#define printStrSetup(x) printStr(x) -#define printNumHexSetup(x) printNumHex(x) +#define printStrSetup printStr +#define printNumU8HexSetup printNumU8Hex #else -#define printStrSetup(x) -#define printNumHexSetup(x) -#endif - -#ifdef USE_NUM_U8 -int8_t uint8_to_str(uint8_t *buf, uint8_t bufsize, uint8_t n); -#endif - -#ifdef USE_NUM_U32 -int8_t uint32_to_str(uint8_t *buf, uint8_t bufsize, uint32_t n); +#define printStrSetup +#define printNumU8HexSetup #endif #ifdef USE_NUM_U8 @@ -37,6 +24,16 @@ void printNumU8(uint8_t num); void printNumU32(uint32_t num); #endif -void printNumHex(uint8_t num); +#ifdef USE_NUM_U8HEX +void printNumU8Hex(uint8_t num); +#endif + +#ifdef USE_NUM_U16HEX +void printNumU16Hex(uint16_t num); +#endif + +#ifdef USE_NUM_U32HEX +void printNumU32Hex(uint32_t num); +#endif #endif diff --git a/hw/usb_interface/ch552_fw/src/debug.c b/hw/usb_interface/ch552_fw/src/debug.c index f13d8b0..e67a02f 100644 --- a/hw/usb_interface/ch552_fw/src/debug.c +++ b/hw/usb_interface/ch552_fw/src/debug.c @@ -160,108 +160,3 @@ int getchar(void) return SBUF; } #endif - -// Set pin p1.4 and p1.5 to GPIO output mode. -void gpio_init() -{ - // p1.4 - P1_MOD_OC &= ~0x10; - P1_DIR_PU |= 0x10; - - // p1.5 - P1_MOD_OC &= ~0x20; - P1_DIR_PU |= 0x20; -} - -void gpio_set(uint8_t pin) -{ - switch (pin) { - case 0x10: // p1.4 - P1 |= 0x10; - break; - case 0x20: // p1.5 - P1 |= 0x20; - break; - default: // do nothing, unsupported pin. - break; - } -} - -void gpio_unset(uint8_t pin) -{ - switch (pin) { - case 0x10: - P1 &= ~0x10; - break; - case 0x20: - P1 &= ~0x20; - break; - default: // do nothing, unsupported pin. - break; - } -} - -uint8_t gpio_get(uint8_t pin) -{ - uint8_t ret = 0; - - switch (pin) { - case 0x10: // p1.4 - ret = P1 & 0x10; - break; - case 0x20: // p1.5 - ret = P1 & 0x20; - break; - default: // do nothing, unsupported pin. - ret = 0xff; - break; - } - - return ret; -} - -// Set pin p1.4 to GPIO input mode. (FPGA_CTS) -void gpio_init_p1_4_in() -{ - // p1.4 - P1_MOD_OC &= ~0x10; // Output Mode: 0 = Push-pull output, 1 = Open-drain output - P1_DIR_PU &= ~0x10; // Port Direction Control and Pull-up Enable Register: - // Push-pull output mode: - // 0 = Input. - // 1 = Output - // Open-drain output mode: - // 0 = Pull-up resistor disabled - // 1 = Pull-up resistor enabled -} - -// Read status of pin 1.4 -uint8_t gpio_p1_4_get(void) -{ - return (P1 & 0x10); // p1.4 -} - -// Set pin p1.5 to GPIO output mode. (CH552_CTS) -void gpio_init_p1_5_out() -{ - // p1.5 - P1_MOD_OC &= ~0x20; // Output Mode: 0 = Push-pull output, 1 = Open-drain output - P1_DIR_PU |= 0x20; // Port Direction Control and Pull-up Enable Register: - // Push-pull output mode: - // 0 = Input. - // 1 = Output - // Open-drain output mode: - // 0 = Pull-up resistor disabled - // 1 = Pull-up resistor enabled -} - -// Set pin 1.5 high -void gpio_p1_5_set(void) -{ - P1 |= 0x20; -} - -// Set pin 1.5 low -void gpio_p1_5_unset(void) -{ - P1 &= ~0x20; -} diff --git a/hw/usb_interface/ch552_fw/src/flash.c b/hw/usb_interface/ch552_fw/src/flash.c new file mode 100644 index 0000000..ced6909 --- /dev/null +++ b/hw/usb_interface/ch552_fw/src/flash.c @@ -0,0 +1,79 @@ +#include + +#include "ch554.h" + +uint8_t write_code_flash(uint16_t address, uint16_t data) +{ + uint8_t ret = 0; + + SAFE_MOD = 0x55; + SAFE_MOD = 0xAA; // Enter Safe mode + GLOBAL_CFG |= bCODE_WE; // Enable flash-ROM write + SAFE_MOD = 0; // Exit Safe mode + + // Set address + ROM_ADDR = address; + ROM_DATA = data; + + // Check that write operation address is valid + if ((ROM_STATUS & bROM_ADDR_OK) == 0) { + ret |= 0x01; + } + + if (ROM_CTRL & bROM_ADDR_OK) { + E_DIS = 1; // Disable global interrupts to prevent Flash operation from being interrupted + ROM_CTRL = ROM_CMD_WRITE; // Write + E_DIS = 0; // Enable global interrupts + } + + // Check operation command error + if (ROM_STATUS & bROM_CMD_ERR) { + ret |= 0x02; + } + + SAFE_MOD = 0x55; + SAFE_MOD = 0xAA; // Enter Safe mode + GLOBAL_CFG &= ~bCODE_WE; // Disable flash-ROM write + SAFE_MOD = 0; // Exit Safe mode + + return ret; +} + +uint8_t write_data_flash(uint8_t address, uint8_t data) +{ + uint8_t ret = 0; + + EA = 0; // Disable global interrupts to prevent Flash operation from being interrupted + + SAFE_MOD = 0x55; + SAFE_MOD = 0xAA; // Enter Safe mode + GLOBAL_CFG |= bDATA_WE; // Enable Data-Flash write + SAFE_MOD = 0; // Exit Safe mode + + ROM_ADDR_H = DATA_FLASH_ADDR >> 8; + ROM_ADDR_L = address << 1; + ROM_DATA_L = data; + + // Check that write operation address is valid + if ((ROM_STATUS & bROM_ADDR_OK) == 0) { + ret |= 0x01; + } + + if (ROM_CTRL & bROM_ADDR_OK) { + ROM_CTRL = ROM_CMD_WRITE; // Write + } + + // Check operation command error + if (ROM_STATUS & bROM_CMD_ERR) { + ret |= 0x02; + } + + SAFE_MOD = 0x55; + SAFE_MOD = 0xAA; // Enter Safe mode + GLOBAL_CFG &= ~bDATA_WE; // Disable Data-Flash write + SAFE_MOD = 0; // Exit Safe mode + + EA = 1; // Enable global interrupts + + return ret; +} diff --git a/hw/usb_interface/ch552_fw/src/gpio.c b/hw/usb_interface/ch552_fw/src/gpio.c new file mode 100644 index 0000000..546e3a8 --- /dev/null +++ b/hw/usb_interface/ch552_fw/src/gpio.c @@ -0,0 +1,108 @@ +#include + +#include "ch554.h" + +// Set pin p1.4 and p1.5 to GPIO output mode. +void gpio_init() +{ + // p1.4 + P1_MOD_OC &= ~0x10; + P1_DIR_PU |= 0x10; + + // p1.5 + P1_MOD_OC &= ~0x20; + P1_DIR_PU |= 0x20; +} + +void gpio_set(uint8_t pin) +{ + switch (pin) { + case 0x10: // p1.4 + P1 |= 0x10; + break; + case 0x20: // p1.5 + P1 |= 0x20; + break; + default: // do nothing, unsupported pin. + break; + } +} + +void gpio_unset(uint8_t pin) +{ + switch (pin) { + case 0x10: + P1 &= ~0x10; + break; + case 0x20: + P1 &= ~0x20; + break; + default: // do nothing, unsupported pin. + break; + } +} + +uint8_t gpio_get(uint8_t pin) +{ + uint8_t ret = 0; + + switch (pin) { + case 0x10: // p1.4 + ret = P1 & 0x10; + break; + case 0x20: // p1.5 + ret = P1 & 0x20; + break; + default: // do nothing, unsupported pin. + ret = 0xff; + break; + } + + return ret; +} + +// Set pin p1.4 to GPIO input mode. (FPGA_CTS) +void gpio_init_p1_4_in() +{ + // p1.4 + P1_MOD_OC &= ~0x10; // Output Mode: 0 = Push-pull output, 1 = Open-drain output + P1_DIR_PU &= ~0x10; // Port Direction Control and Pull-up Enable Register: + // Push-pull output mode: + // 0 = Input. + // 1 = Output + // Open-drain output mode: + // 0 = Pull-up resistor disabled + // 1 = Pull-up resistor enabled +} + +// Read status of pin 1.4 +uint8_t gpio_p1_4_get(void) +{ + return (P1 & 0x10); // p1.4 +} + +// Set pin p1.5 to GPIO output mode. (CH552_CTS) +void gpio_init_p1_5_out() +{ + // p1.5 + P1_MOD_OC &= ~0x20; // Output Mode: 0 = Push-pull output, 1 = Open-drain output + P1_DIR_PU |= 0x20; // Port Direction Control and Pull-up Enable Register: + // Push-pull output mode: + // 0 = Input. + // 1 = Output + // Open-drain output mode: + // 0 = Pull-up resistor disabled + // 1 = Pull-up resistor enabled +} + +// Set pin 1.5 high +void gpio_p1_5_set(void) +{ + P1 |= 0x20; +} + +// Set pin 1.5 low +void gpio_p1_5_unset(void) +{ + P1 &= ~0x20; +} diff --git a/hw/usb_interface/ch552_fw/src/lib.c b/hw/usb_interface/ch552_fw/src/lib.c new file mode 100644 index 0000000..a3250c2 --- /dev/null +++ b/hw/usb_interface/ch552_fw/src/lib.c @@ -0,0 +1,200 @@ +#include + +#include "main.h" + +#ifdef USE_NUM_U8 +int8_t uint8_to_str(uint8_t *buf, uint8_t bufsize, uint8_t n) +{ + uint8_t *start; + +#ifdef USE_NEGATIVE_NUMS + if (n < 0) { // Handle negative numbers. + if (!bufsize) { + return -1; + } + *buf++ = '-'; + bufsize--; + } +#endif + + start = buf; // Remember the start of the string. This will come into play at the end. + + do { + // Handle the current digit. + uint8_t digit; + if (!bufsize) { + return -1; + } + digit = n % 10; +#ifdef USE_NEGATIVE_NUMS + if (digit < 0) { + digit *= -1; + } +#endif + *buf++ = digit + '0'; + bufsize--; + n /= 10; + } while (n); + + // Terminate the string. + if (!bufsize) { + return -1; + } + *buf = 0; + + // We wrote the string backwards, i.e. with least significant digits first. Now reverse the string. + --buf; + while (start < buf) { + uint8_t a = *start; + *start = *buf; + *buf = a; + ++start; + --buf; + } + + return 0; +} +#endif + +#ifdef USE_NUM_U32 +int8_t uint32_to_str(uint8_t *buf, uint8_t bufsize, uint32_t n) +{ + uint8_t *start; + +#ifdef USE_NEGATIVE_NUMS + if (n < 0) { // Handle negative numbers. + if (!bufsize) { + return -1; + } + *buf++ = '-'; + bufsize--; + } +#endif + + start = buf; // Remember the start of the string. This will come into play at the end. + + do { + // Handle the current digit. + uint8_t digit; + if (!bufsize) { + return -1; + } + digit = n % 10; +#ifdef USE_NEGATIVE_NUMS + if (digit < 0) { + digit *= -1; + } +#endif + *buf++ = digit + '0'; + bufsize--; + n /= 10; + } while (n); + + // Terminate the string. + if (!bufsize) { + return -1; + } + *buf = 0; + + // We wrote the string backwards, i.e. with least significant digits first. Now reverse the string. + --buf; + while (start < buf) { + uint8_t a = *start; + *start = *buf; + *buf = a; + ++start; + --buf; + } + + return 0; +} +#endif + +#if 0 +uint8_t hex_to_uint8(const char *hex, uint8_t len) +{ + uint8_t val = 0; + while (len) { + char c = *hex++; + val <<= 4; + if (c >= '0' && c <= '9') { + val |= c - '0'; + } else if (c >= 'A' && c <= 'F') { + val |= c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + val |= c - 'a' + 10; + } else { + return 0; // Invalid character + } + len--; + } + return val; +} +#endif + +#if 0 +uint16_t hex_to_uint16(const char *hex, uint8_t len) +{ + uint16_t val = 0; + while (len) { + char c = *hex++; + val <<= 4; + if (c >= '0' && c <= '9') { + val |= c - '0'; + } else if (c >= 'A' && c <= 'F') { + val |= c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + val |= c - 'a' + 10; + } else { + return 0; // Invalid character + } + len--; + } + return val; +} +#endif + +uint32_t hex_to_uint32(const char *hex, uint8_t len) +{ + uint32_t val = 0; + while (len) { + char c = *hex++; + val <<= 4; + if (c >= '0' && c <= '9') { + val |= c - '0'; + } else if (c >= 'A' && c <= 'F') { + val |= c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + val |= c - 'a' + 10; + } else { + return 0; // Invalid character + } + len--; + } + return val; +} + +uint8_t ascii_hex_char_to_byte(uint8_t c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; // Invalid character, should not happen if input is valid +} + +#if 0 +int ascii_hex_string_to_bytes(uint8_t *hex_str, uint8_t *out_bytes, size_t out_len) +{ + if (!hex_str || !out_bytes || out_len < 32) + return -1; // Error handling + + for (size_t i = 0; i < 32; i++) { + out_bytes[i] = (ascii_hex_char_to_byte(hex_str[i * 2]) << 4) | ascii_hex_char_to_byte(hex_str[i * 2 + 1]); + } + + return 0; // Success +} +#endif diff --git a/hw/usb_interface/ch552_fw/src/main.c b/hw/usb_interface/ch552_fw/src/main.c index 33277a9..588de6f 100644 --- a/hw/usb_interface/ch552_fw/src/main.c +++ b/hw/usb_interface/ch552_fw/src/main.c @@ -6,13 +6,15 @@ * Description : CH554 as CDC device to serial port, select serial port 1 *******************************************************************************/ #include -#include #include #include #include #include "debug.h" +#include "flash.h" +#include "lib.h" +#include "main.h" #include "mem.h" #include "print.h" #include "usb_strings.h" @@ -550,7 +552,7 @@ void usb_irq_setup_handler(void) printStrSetup("Class-Specific "); printStrSetup("SetupReq="); printStrSetup("0x"); - printNumHexSetup(SetupReq); + printNumU8HexSetup(SetupReq); printStrSetup(" "); switch(SetupReq) { case USB_HID_REQ_TYPE_GET_REPORT: @@ -984,7 +986,7 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist } else if (UIF_BUS_RST) { // Check device mode USB bus reset interrupt - printStr("Reset\n"); + printStrSetup("Reset\n"); UEP0_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK; UEP1_CTRL = bUEP_AUTO_TOG | UEP_T_RES_NAK; @@ -1016,7 +1018,7 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist if (USB_MIS_ST & bUMS_SUSPEND) { // Hang - printStr("Suspend\n"); + printStrSetup("Suspend\n"); while (XBUS_AUX & bUART0_TX) { ; // Wait for sending to complete @@ -1032,7 +1034,7 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist } } else { // Unexpected IRQ, should not happen - printStr("Unexpected IRQ\n"); + printStrSetup("Unexpected IRQ\n"); USB_INT_FG = 0xFF; // Clear interrupt flag } } @@ -1241,16 +1243,16 @@ void main() } else { // Invalid mode if (!Halted) { printStr("Invalid header: 0x"); - printNumHex(FrameMode); + printNumU8Hex(FrameMode); printStr(", len = "); - printNumU32(UartRxBuf[increment_pointer(UartRxBufOutputPointer, - 1, - UART_RX_BUF_SIZE)]); + printNumU8Hex(UartRxBuf[increment_pointer(UartRxBufOutputPointer, + 1, + UART_RX_BUF_SIZE)]); printStr("\n"); uint16_t i; uint8_t print_char_count_out = 0; for (i=0; i +#include #include "debug.h" +#include "lib.h" +#include "main.h" +#include "mem.h" #include "print.h" +#define MODE_CH552 0x10 + void printStr(uint8_t *str) { -#ifdef DEBUG_PRINT +#ifdef USE_DEBUG_PRINT +#if defined(DEBUG_PRINT_HW) while (*str != 0) { CH554UART0SendByte(*str); ++str; } +#elif defined(DEBUG_PRINT_SW) + uint32_t str_len = strlen(str); + CH554UART1SendByte(MODE_CH552); + CH554UART1SendByte(str_len); + CH554UART1SendBuffer(str, str_len); +#endif #else (void)str; #endif @@ -17,131 +30,31 @@ void printStr(uint8_t *str) void printChar(uint8_t c) { -#ifdef DEBUG_PRINT +#ifdef USE_DEBUG_PRINT +#if defined(DEBUG_PRINT_HW) CH554UART0SendByte(c); +#elif defined(DEBUG_PRINT_SW) + CH554UART1SendByte(MODE_CH552); + CH554UART1SendByte(1); + CH554UART1SendByte(c); +#endif #else (void)c; #endif } -#ifdef USE_NUM_U8 -int8_t uint8_to_str(uint8_t *buf, uint8_t bufsize, uint8_t n) -{ - uint8_t *start; - -#ifdef USE_NEGATIVE_NUMS - if (n < 0) { // Handle negative numbers. - if (!bufsize) { - return -1; - } - *buf++ = '-'; - bufsize--; - } -#endif - - start = buf; // Remember the start of the string. This will come into play at the end. - - do { - // Handle the current digit. - uint8_t digit; - if (!bufsize) { - return -1; - } - digit = n % 10; -#ifdef USE_NEGATIVE_NUMS - if (digit < 0) { - digit *= -1; - } -#endif - *buf++ = digit + '0'; - bufsize--; - n /= 10; - } while (n); - - // Terminate the string. - if (!bufsize) { - return -1; - } - *buf = 0; - - // We wrote the string backwards, i.e. with least significant digits first. Now reverse the string. - --buf; - while (start < buf) { - uint8_t a = *start; - *start = *buf; - *buf = a; - ++start; - --buf; - } - - return 0; -} -#endif - -#ifdef USE_NUM_U32 -int8_t uint32_to_str(uint8_t *buf, uint8_t bufsize, uint32_t n) -{ - uint8_t *start; - -#ifdef USE_NEGATIVE_NUMS - if (n < 0) { // Handle negative numbers. - if (!bufsize) { - return -1; - } - *buf++ = '-'; - bufsize--; - } -#endif - - start = buf; // Remember the start of the string. This will come into play at the end. - - do { - // Handle the current digit. - uint8_t digit; - if (!bufsize) { - return -1; - } - digit = n % 10; -#ifdef USE_NEGATIVE_NUMS - if (digit < 0) { - digit *= -1; - } -#endif - *buf++ = digit + '0'; - bufsize--; - n /= 10; - } while (n); - - // Terminate the string. - if (!bufsize) { - return -1; - } - *buf = 0; - - // We wrote the string backwards, i.e. with least significant digits first. Now reverse the string. - --buf; - while (start < buf) { - uint8_t a = *start; - *start = *buf; - *buf = a; - ++start; - --buf; - } - - return 0; -} -#endif - #ifdef USE_NUM_U8 void printNumU8(uint8_t num) { -#ifdef DEBUG_PRINT - uint8_t num_str[4] = { 0 }; +#ifdef USE_DEBUG_PRINT int8_t ret; + uint8_t num_str[4] = { 0 }; ret = uint8_to_str(num_str, 4, num); if (!ret) { printStr(num_str); } +#else + (void)num; #endif } #endif @@ -149,9 +62,9 @@ void printNumU8(uint8_t num) #ifdef USE_NUM_U32 void printNumU32(uint32_t num) { -#ifdef DEBUG_PRINT - uint8_t num_str[11] = { 0 }; +#ifdef USE_DEBUG_PRINT int8_t ret; + uint8_t num_str[11] = { 0 }; ret = uint32_to_str(num_str, 10, num); if (!ret) { printStr(num_str); @@ -164,7 +77,7 @@ void printNumU32(uint32_t num) void printNumHex(uint8_t num) { -#ifdef DEBUG_PRINT +#ifdef USE_DEBUG_PRINT // High nibble uint8_t val = num >> 4; if (val <= 9) { @@ -186,3 +99,47 @@ void printNumHex(uint8_t num) (void)num; #endif } + +#ifdef USE_NUM_U8HEX +void printNumU8Hex(uint8_t num) +{ +#ifdef USE_DEBUG_PRINT + printStr("0x"); + printNumHex(num); +#else + (void)num; +#endif +} +#endif + +#ifdef USE_NUM_U16HEX +void printNumU16Hex(uint16_t num) +{ +#ifdef USE_DEBUG_PRINT + uint8_t buf[2]; + memcpy(buf, &num, 2); + printStr("0x"); + for (int8_t i = 1; i > -1; i--) { + printNumHex(buf[i]); + } +#else + (void)num; +#endif +} +#endif + +#ifdef USE_NUM_U32HEX +void printNumU32Hex(uint32_t num) +{ +#ifdef USE_DEBUG_PRINT + uint8_t buf[4]; + memcpy(buf, &num, 4); + printStr("0x"); + for (int8_t i = 3; i > -1; i--) { + printNumHex(buf[i]); + } +#else + (void)num; +#endif +} +#endif From d080dedca0219deef426f54a509e6e27474267a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Th=C3=B6rnblad?= Date: Mon, 24 Mar 2025 16:00:41 +0100 Subject: [PATCH 3/3] ch552: Add functionality to dynamically control USB endpoints - Make it possible to enable and disable endpoints on demand - Add internal FPGA<->CH552 communication channel (IO_CH552) - Reorder IO endpoint numbering - Rename endpoint from TKEYCTRL to DEBUG and update related variables - Rename endpoint from HID to FIDO and update related variables --- hw/application_fpga/fw/README.md | 10 +- .../ch552_fw/encode_usb_strings.py | 4 +- hw/usb_interface/ch552_fw/inc/ch554_usb.h | 4 +- hw/usb_interface/ch552_fw/inc/io.h | 14 + hw/usb_interface/ch552_fw/inc/main.h | 8 +- hw/usb_interface/ch552_fw/inc/usb_strings.h | 14 +- hw/usb_interface/ch552_fw/src/main.c | 752 ++++++++++-------- hw/usb_interface/ch552_fw/src/print.c | 7 +- 8 files changed, 449 insertions(+), 364 deletions(-) create mode 100644 hw/usb_interface/ch552_fw/inc/io.h diff --git a/hw/application_fpga/fw/README.md b/hw/application_fpga/fw/README.md index 44effb4..27af0c9 100644 --- a/hw/application_fpga/fw/README.md +++ b/hw/application_fpga/fw/README.md @@ -62,11 +62,11 @@ Mode Protocol. It is used in both directions. The different endpoints: -| *Name* | *Value* | *Comment* | -|--------|---------|---------------------------------------------------------------------| -| CTRL | 0x20 | A USB HID special debug pipe. Useful for debug prints. | -| CDC | 0x40 | USB CDC-ACM, a serial port on the client. | -| HID | 0x80 | A USB HID security token device, useful for FIDO-type applications. | +| *Name* | *Value* | *Comment* | +|--------|---------|----------------------------------------------------------------------| +| DEBUG | 0x20 | A USB HID special debug pipe. Useful for debug prints. | +| CDC | 0x40 | USB CDC-ACM, a serial port on the client. | +| FIDO | 0x80 | A USB FIDO security token device, useful for FIDO-type applications. | On top of the USB Mode Protocol is [the TKey Framing Protocol](https://dev.tillitis.se/protocol/) which is described in the diff --git a/hw/usb_interface/ch552_fw/encode_usb_strings.py b/hw/usb_interface/ch552_fw/encode_usb_strings.py index 98c4feb..8b5d9f2 100755 --- a/hw/usb_interface/ch552_fw/encode_usb_strings.py +++ b/hw/usb_interface/ch552_fw/encode_usb_strings.py @@ -53,8 +53,8 @@ if __name__ == "__main__": "SerialDesc": "68de5d27-e223-4874-bc76-a54d6e84068f", "CdcCtrlInterfaceDesc": "CDC-Ctrl", "CdcDataInterfaceDesc": "CDC-Data", - "FidoHidInterfaceDesc": "FIDO-HID", - "TkeyCtrlInterfaceDesc": "TKEY-Ctrl" + "FidoInterfaceDesc": "FIDO", + "DebugInterfaceDesc": "DEBUG" } with open('inc/usb_strings.h', 'w') as f: diff --git a/hw/usb_interface/ch552_fw/inc/ch554_usb.h b/hw/usb_interface/ch552_fw/inc/ch554_usb.h index b9ca5f2..360c910 100644 --- a/hw/usb_interface/ch552_fw/inc/ch554_usb.h +++ b/hw/usb_interface/ch552_fw/inc/ch554_usb.h @@ -195,8 +195,8 @@ Header file for CH554 microcontrollers. #define USB_IDX_SERIAL_STR 0x03 #define USB_IDX_INTERFACE_CDC_CTRL_STR 0x04 #define USB_IDX_INTERFACE_CDC_DATA_STR 0x05 -#define USB_IDX_INTERFACE_FIDO_HID_STR 0x06 -#define USB_IDX_INTERFACE_TKEY_CTRL_STR 0x07 +#define USB_IDX_INTERFACE_FIDO_STR 0x06 +#define USB_IDX_INTERFACE_DEBUG_STR 0x07 #endif #ifndef USB_DEVICE_ADDR diff --git a/hw/usb_interface/ch552_fw/inc/io.h b/hw/usb_interface/ch552_fw/inc/io.h new file mode 100644 index 0000000..dd1d1b5 --- /dev/null +++ b/hw/usb_interface/ch552_fw/inc/io.h @@ -0,0 +1,14 @@ +#ifndef __IO_H__ +#define __IO_H__ + +enum ioend { + IO_NONE = 0x00, // No endpoint + IO_UART = 0x01, // Only destination, raw UART access + IO_QEMU = 0x02, // Only destination, QEMU debug port + IO_CH552 = 0x10, // Internal CH552 control port + IO_DEBUG = 0x20, // HID debug port + IO_CDC = 0x40, // CDC "serial port" + IO_FIDO = 0x80, // FIDO security token port +}; + +#endif diff --git a/hw/usb_interface/ch552_fw/inc/main.h b/hw/usb_interface/ch552_fw/inc/main.h index aa21f8c..e117118 100644 --- a/hw/usb_interface/ch552_fw/inc/main.h +++ b/hw/usb_interface/ch552_fw/inc/main.h @@ -1,14 +1,14 @@ #ifndef __MAIN_H__ #define __MAIN_H__ -#define USE_DEBUG_PRINT /* Enable to print debug messages */ -#define DEBUG_PRINT_SW /* Enable to print debug messages via FPGA */ -//#define DEBUG_PRINT_HW /* Enable to print debug messages via UART0 */ +//#define USE_DEBUG_PRINT /* Enable to print debug messages */ +//#define DEBUG_PRINT_SW /* Enable to print debug messages via FPGA */ +//#define DEBUG_PRINT_HW /* Enable to print debug messages via UART0 */ #define USE_NUM_U8 //#define USE_NUM_U32 -//#define DEBUG_SETUP /* Enable to debug USB setup flow (printStrSetup,printNumU8HexSetup) */ +//#define DEBUG_SETUP /* Enable to debug USB setup flow (printStrSetup,printNumU8HexSetup) */ #define USE_NUM_U8HEX #define USE_NUM_U16HEX diff --git a/hw/usb_interface/ch552_fw/inc/usb_strings.h b/hw/usb_interface/ch552_fw/inc/usb_strings.h index 2302329..a2e295d 100644 --- a/hw/usb_interface/ch552_fw/inc/usb_strings.h +++ b/hw/usb_interface/ch552_fw/inc/usb_strings.h @@ -46,19 +46,17 @@ unsigned char FLASH CdcDataInterfaceDesc[] = { // "CDC-Data" 'D', 0, 'a', 0, 't', 0, 'a', 0, }; -unsigned char FLASH FidoHidInterfaceDesc[] = { // "FIDO-HID" - 18, // Length of this descriptor (in bytes) +unsigned char FLASH FidoInterfaceDesc[] = { // "FIDO" + 10, // 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[] = { // "TKEY-Ctrl" - 20, // Length of this descriptor (in bytes) +unsigned char FLASH DebugInterfaceDesc[] = { // "DEBUG" + 12, // 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, + 'D', 0, 'E', 0, 'B', 0, 'U', 0, + 'G', 0, }; #endif diff --git a/hw/usb_interface/ch552_fw/src/main.c b/hw/usb_interface/ch552_fw/src/main.c index 588de6f..bddc041 100644 --- a/hw/usb_interface/ch552_fw/src/main.c +++ b/hw/usb_interface/ch552_fw/src/main.c @@ -13,6 +13,7 @@ #include "debug.h" #include "flash.h" +#include "io.h" #include "lib.h" #include "main.h" #include "mem.h" @@ -20,14 +21,14 @@ #include "usb_strings.h" XDATA AT0000 uint8_t Ep0Buffer[3*MAX_PACKET_SIZE] = { 0 }; // Endpoint 0, Default endpoint, OUT & IN buffer[64], must be an even address + - // Endpoint 4, TKEYCTRL, 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 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 + // Endpoint 4, DEBUG endpoint, buffer OUT[64]+IN[64], must be an even address +XDATA AT00C0 uint8_t Ep1Buffer[DEFAULT_EP1_SIZE] = { 0 }; // Endpoint 1, CDC Ctrl endpoint, IN[8] buffer +XDATA AT00C8 uint8_t Ep2Buffer[2*MAX_PACKET_SIZE] = { 0 }; // Endpoint 2, CDC Data endpoint, buffer OUT[64]+IN[64], must be an even address +XDATA AT0148 uint8_t Ep3Buffer[2*MAX_PACKET_SIZE] = { 0 }; // Endpoint 3, FIDO endpoint, buffer OUT[64]+IN[64], must be an even address -uint16_t SetupLen = 0; -uint8_t SetupReq = 0; -uint8_t UsbConfig = 0; +IDATA uint16_t SetupLen = 0; +IDATA uint8_t SetupReq = 0; +IDATA uint8_t UsbConfig = 0; const uint8_t *pDescr = NULL; // USB configuration flag #define UsbSetupBuf ((PUSB_SETUP_REQ)Ep0Buffer) @@ -44,32 +45,38 @@ const uint8_t *pDescr = NULL; // USB configuration flag #define CDC_DATA_EPIN_ADDR 0x82 // CDC Data Endpoint IN Address #define CDC_DATA_EPIN_SIZE MAX_PACKET_SIZE // CDC Data Endpoint IN Size -#define HID_EPOUT_ADDR 0x03 // HID Endpoint OUT Address -#define HID_EPOUT_SIZE MAX_PACKET_SIZE // HID Endpoint OUT Size +#define FIDO_EPOUT_ADDR 0x03 // FIDO Endpoint OUT Address +#define FIDO_EPOUT_SIZE MAX_PACKET_SIZE // FIDO Endpoint OUT Size -#define HID_EPIN_ADDR 0x83 // HID Endpoint IN Address -#define HID_EPIN_SIZE MAX_PACKET_SIZE // HID Endpoint IN Size +#define FIDO_EPIN_ADDR 0x83 // FIDO Endpoint IN Address +#define FIDO_EPIN_SIZE MAX_PACKET_SIZE // FIDO Endpoint IN Size -#define TKEYCTRL_EPOUT_ADDR 0x04 // TKEYCTRL Endpoint OUT Address -#define TKEYCTRL_EPOUT_SIZE MAX_PACKET_SIZE // TKEYCTRL Endpoint OUT Size +#define DEBUG_EPOUT_ADDR 0x04 // DEBUG Endpoint OUT Address +#define DEBUG_EPOUT_SIZE MAX_PACKET_SIZE // DEBUG Endpoint OUT Size -#define TKEYCTRL_EPIN_ADDR 0x84 // TKEYCTRL Endpoint IN Address -#define TKEYCTRL_EPIN_SIZE MAX_PACKET_SIZE // TKEYCTRL Endpoint IN Size +#define DEBUG_EPIN_ADDR 0x84 // DEBUG Endpoint IN Address +#define DEBUG_EPIN_SIZE MAX_PACKET_SIZE // DEBUG Endpoint IN Size #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 HID_FS_BINTERVAL 2 // Gives 2 ms polling interval at Full Speed for interrupt transfers -#define TKEYCTRL_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 DEBUG_FS_BINTERVAL 2 // Gives 2 ms polling interval at Full Speed for interrupt transfers -#define CFGDESC_SIZE 139U // Size of CfgDesc +#define CFG_DESC_SIZE 139U // Size of Cfg_Desc #define NUM_INTERFACES 4 // Number of interfaces -#define HID_REPORT_DESC_SIZE 47 // Size of HID_ReportDesc -#define TKEYCTRL_REPORT_DESC_SIZE 34 // Size of TKEYCTRL_ReportDesc +#define FIDO_REPORT_DESC_SIZE 47 // Size of FidoReportDesc +#define DEBUG_REPORT_DESC_SIZE 34 // Size of DebugReportDesc #define LOBYTE(x) ((uint8_t)( (x) & 0x00FFU)) #define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) +IDATA uint8_t FidoInterfaceNum = 0; +IDATA uint8_t DebugInterfaceNum = 0; + +XDATA uint8_t ActiveCfgDesc[CFG_DESC_SIZE]; +XDATA uint8_t ActiveCfgDescSize = 0; + // Device Descriptor FLASH uint8_t DevDesc[] = { 0x12, /* bLength */ @@ -86,9 +93,9 @@ FLASH uint8_t DevDesc[] = { 0x88, /* idProduct */ // PID HIBYTE 0x00, /* bcdDevice (device release number in binary-coded decimal (BCD) format, low byte, i.e. YY) rel. XX.YY */ 0x01, /* bcdDevice (device release number in binary-coded decimal (BCD) format, high byte, i.e. XX) rel. XX.YY */ - 0x01, /* Index of manufacturer string */ - 0x02, /* Index of product string */ - 0x03, /* Index of serial number string */ + USB_IDX_MFC_STR, /* Index of manufacturer string */ + USB_IDX_PRODUCT_STR, /* Index of product string */ + USB_IDX_SERIAL_STR, /* Index of serial number string */ 0x01, /* bNumConfigurations */ }; @@ -97,16 +104,20 @@ FLASH uint8_t CfgDesc[] = { /******************** Configuration Descriptor ********************/ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - CFGDESC_SIZE, /* wTotalLength (low byte): Bytes returned */ + CFG_DESC_SIZE, /* wTotalLength (low byte): Bytes returned */ 0x00, /* wTotalLength (high byte): Bytes returned */ - NUM_INTERFACES, /* bNumInterfaces: 4 interfaces (1 CDC Ctrl, 1 CDC Data, 1 HID, 1 HID (TKEYCTRL) ) */ + NUM_INTERFACES, /* bNumInterfaces: 4 interfaces (1 CDC Ctrl, 1 CDC Data, 1 FIDO, 1 DEBUG ) */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0xA0, /* bmAttributes: Bus powered and Support Remote Wake-up */ 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ + /* 9 */ +}; + +// CDC Descriptor +FLASH uint8_t CdcDesc[] = { /******************** 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 */ 0x08, /* bLength: IAD Descriptor size */ USB_DESC_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType: Interface Association */ 0x00, /* bFirstInterface: 0 */ @@ -116,7 +127,7 @@ FLASH uint8_t CfgDesc[] = { 0x01, /* bFunctionProtocol: Common AT commands */ 0x00, /* iFunction: Index of string descriptor */ /******************** Interface 0, CDC Ctrl Descriptor (one endpoint) ********************/ - /* 17 */ + /* 8 */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ 0x00, /* bInterfaceNumber: Number of Interface */ @@ -125,16 +136,16 @@ FLASH uint8_t CfgDesc[] = { USB_DEV_CLASS_CDC_CONTROL, /* bInterfaceClass: Communications and CDC Control */ 0x02, /* bInterfaceSubClass : Abstract Control Model */ 0x01, /* bInterfaceProtocol : AT Commands: V.250 etc */ - 0x04, /* iInterface: Index of string descriptor */ + USB_IDX_INTERFACE_CDC_CTRL_STR, /* iInterface: Index of string descriptor */ /******************** Header Functional Descriptor ********************/ - /* 26 */ + /* 17 */ 0x05, /* bFunctionLength: Size of this descriptor in bytes */ USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE (24h) */ 0x00, /* bDescriptorSubtype: Header Functional Descriptor */ 0x10, /* bcdCDC (low byte): CDC version 1.10 */ 0x01, /* bcdCDC (high byte): CDC version 1.10 */ /******************** Call Management Functional Descriptor (no data interface, bmCapabilities=03, bDataInterface=01) ********************/ - /* 31 */ + /* 22 */ 0x05, /* bFunctionLength: Size of this descriptor */ USB_DESC_TYPE_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE (24h) */ 0x01, /* bDescriptorSubtype: Call Management Functional Descriptor */ @@ -146,7 +157,7 @@ FLASH uint8_t CfgDesc[] = { 1 - Device handles call management itself) */ 0x00, /* bDataInterface: Interface number of Data Class interface optionally used for call management */ /******************** Abstract Control Management Functional Descriptor ********************/ - /* 36 */ + /* 27 */ 0x04, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE (24h) */ 0x02, /* bDescriptorSubtype: Abstract Control Management Functional Descriptor */ @@ -157,14 +168,14 @@ FLASH uint8_t CfgDesc[] = { D1 : 0x01 (1 - Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State) D0 : 0x00 (1 - Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature) */ /******************** Union Functional Descriptor. CDC Ctrl interface numbered 0; CDC Data interface numbered 1 ********************/ - /* 40 */ + /* 31 */ 0x05, /* bLength */ 0x24, /* bDescriptorType: CS_INTERFACE (24h) */ 0x06, /* bDescriptorSubtype: Union Functional Descriptor */ 0x00, /* bControlInterface: Interface number 0 (Control interface) */ 0x01, /* bSubordinateInterface0: Interface number 1 (Data interface) */ /******************** CDC Ctrl Endpoint descriptor (IN) ********************/ - /* 45 */ + /* 36 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_CTRL_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ @@ -173,7 +184,7 @@ FLASH uint8_t CfgDesc[] = { HIBYTE(CDC_CTRL_EPIN_SIZE), /* wMaxPacketSize (high byte): 8 Byte max */ CDC_CTRL_FS_BINTERVAL, /* bInterval: Polling Interval */ /******************** Interface 1, CDC Data Descriptor (two endpoints) ********************/ - /* 52 */ + /* 43 */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ 0x01, /* bInterfaceNumber: Number of Interface */ @@ -182,9 +193,9 @@ FLASH uint8_t CfgDesc[] = { USB_DEV_CLASS_CDC_DATA, /* bInterfaceClass: CDC Data */ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0x05, /* iInterface: Index of string descriptor */ + USB_IDX_INTERFACE_CDC_DATA_STR, /* iInterface: Index of string descriptor */ /******************** CDC Data Endpoint descriptor (OUT) ********************/ - /* 61 */ + /* 52 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_DATA_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ @@ -193,7 +204,7 @@ FLASH uint8_t CfgDesc[] = { HIBYTE(CDC_DATA_EPOUT_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ CDC_DATA_FS_BINTERVAL, /* bInterval: Polling Interval */ /******************** CDC Data Endpoint descriptor (IN) ********************/ - /* 68 */ + /* 59 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_DATA_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ @@ -201,8 +212,12 @@ FLASH uint8_t CfgDesc[] = { LOBYTE(CDC_DATA_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ HIBYTE(CDC_DATA_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ CDC_DATA_FS_BINTERVAL, /* bInterval: Polling Interval */ - /******************** Interface 2, HID Descriptor (two endpoints) ********************/ - /* 75 */ + /* 66 */ +}; + +// FIDO Descriptor +FLASH uint8_t FidoDesc[] = { + /******************** Interface 2, FIDO Descriptor (two endpoints) ********************/ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ 0x02, /* bInterfaceNumber: Number of Interface */ @@ -211,9 +226,9 @@ FLASH uint8_t CfgDesc[] = { USB_DEV_CLASS_HID, /* bInterfaceClass: Human Interface Device */ 0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 0x00, /* bInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0x06, /* iInterface: Index of string descriptor */ - /******************** HID Device Descriptor ********************/ - /* 84 */ + USB_IDX_INTERFACE_FIDO_STR, /* iInterface: Index of string descriptor */ + /******************** FIDO Device Descriptor ********************/ + /* 9 */ 0x09, /* bLength: HID Descriptor size */ USB_DESC_TYPE_HID, /* bDescriptorType: HID */ 0x11, /* bcdHID (low byte): HID Class Spec release number */ @@ -221,28 +236,32 @@ FLASH uint8_t CfgDesc[] = { 0x00, /* bCountryCode: Hardware target country */ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ USB_DESC_TYPE_REPORT, /* bDescriptorType: Report */ - LOBYTE(HID_REPORT_DESC_SIZE), /* wDescriptorLength (low byte): Total length of Report descriptor */ - HIBYTE(HID_REPORT_DESC_SIZE), /* wDescriptorLength (high byte): Total length of Report descriptor */ - /******************** HID Endpoint Descriptor (OUT) ********************/ - /* 93 */ + LOBYTE(FIDO_REPORT_DESC_SIZE), /* wDescriptorLength (low byte): Total length of Report descriptor */ + HIBYTE(FIDO_REPORT_DESC_SIZE), /* wDescriptorLength (high byte): Total length of Report descriptor */ + /******************** FIDO Endpoint Descriptor (OUT) ********************/ + /* 18 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - HID_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ + FIDO_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ USB_EP_TYPE_INTERRUPT, /* bmAttributes: Interrupt endpoint */ - LOBYTE(HID_EPOUT_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ - HIBYTE(HID_EPOUT_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ - HID_FS_BINTERVAL, /* bInterval: Polling Interval */ - /******************** HID Endpoint Descriptor (IN) ********************/ - /* 100 */ + LOBYTE(FIDO_EPOUT_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ + HIBYTE(FIDO_EPOUT_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ + FIDO_FS_BINTERVAL, /* bInterval: Polling Interval */ + /******************** FIDO Endpoint Descriptor (IN) ********************/ + /* 25 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + FIDO_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ USB_EP_TYPE_INTERRUPT, /* bmAttributes: Interrupt endpoint */ - LOBYTE(HID_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ - HIBYTE(HID_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ - HID_FS_BINTERVAL, /* bInterval: Polling Interval */ - /******************** Interface 3, HID (TKEYCTRL) Descriptor (two endpoints) ********************/ - /* 107 */ + LOBYTE(FIDO_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ + HIBYTE(FIDO_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ + FIDO_FS_BINTERVAL, /* bInterval: Polling Interval */ + /* 32 */ +}; + +// DEBUG Descriptor +FLASH uint8_t DebugDesc[] = { + /******************** Interface 3, DEBUG Descriptor (two endpoints) ********************/ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ 0x03, /* bInterfaceNumber: Number of Interface */ @@ -251,9 +270,9 @@ FLASH uint8_t CfgDesc[] = { 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 ********************/ - /* 116 */ + USB_IDX_INTERFACE_DEBUG_STR, /* iInterface: Index of string descriptor */ + /******************** DEBUG Device Descriptor ********************/ + /* 9 */ 0x09, /* bLength: HID Descriptor size */ USB_DESC_TYPE_HID, /* bDescriptorType: HID */ 0x11, /* bcdHID (low byte): HID Class Spec release number */ @@ -261,31 +280,31 @@ FLASH uint8_t CfgDesc[] = { 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) ********************/ - /* 125 */ + LOBYTE(DEBUG_REPORT_DESC_SIZE), /* wDescriptorLength (low byte): Total length of Report descriptor */ + HIBYTE(DEBUG_REPORT_DESC_SIZE), /* wDescriptorLength (high byte): Total length of Report descriptor */ + /******************** DEBUG Endpoint Descriptor (OUT) ********************/ + /* 18 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - TKEYCTRL_EPOUT_ADDR, /* bEndpointAddress: Endpoint Address (OUT) */ + DEBUG_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) ********************/ - /* 132 */ + LOBYTE(DEBUG_EPOUT_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ + HIBYTE(DEBUG_EPOUT_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ + DEBUG_FS_BINTERVAL, /* bInterval: Polling Interval */ + /******************** DEBUG Endpoint Descriptor (IN) ********************/ + /* 25 */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - TKEYCTRL_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + DEBUG_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 */ - /* 139 */ + LOBYTE(DEBUG_EPIN_SIZE), /* wMaxPacketSize (low byte): 64 Byte max */ + HIBYTE(DEBUG_EPIN_SIZE), /* wMaxPacketSize (high byte): 64 Byte max */ + DEBUG_FS_BINTERVAL, /* bInterval: Polling Interval */ + /* 32 */ }; -// HID Device Descriptor (copy from CfgDesc) -FLASH uint8_t HID_CfgDesc[] = { +// FIDO Device Descriptor (copy from FidoDesc) +FLASH uint8_t FidoCfgDesc[] = { 0x09, /* bLength: HID Descriptor size */ USB_DESC_TYPE_HID, /* bDescriptorType: HID */ 0x11, /* bcdHID (low byte): HID Class Spec release number */ @@ -293,11 +312,11 @@ FLASH uint8_t HID_CfgDesc[] = { 0x00, /* bCountryCode: Hardware target country */ 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ USB_DESC_TYPE_REPORT, /* bDescriptorType: Report */ - LOBYTE(HID_REPORT_DESC_SIZE), /* wDescriptorLength (low byte): Total length of Report descriptor */ - HIBYTE(HID_REPORT_DESC_SIZE), /* wDescriptorLength (high byte): Total length of Report descriptor */ + LOBYTE(FIDO_REPORT_DESC_SIZE), /* wDescriptorLength (low byte): Total length of Report descriptor */ + HIBYTE(FIDO_REPORT_DESC_SIZE), /* wDescriptorLength (high byte): Total length of Report descriptor */ }; -FLASH uint8_t HID_ReportDesc[] ={ +FLASH uint8_t FidoReportDesc[] ={ 0x06, 0xD0, 0xF1, /* Usage Page (FIDO Alliance Page) */ 0x09, 0x01, /* Usage (U2F Authenticator Device) */ 0xA1, 0x01, /* Collection (Application) */ @@ -327,8 +346,8 @@ FLASH uint8_t HID_ReportDesc[] ={ /* 47 */ }; -// TKEYCTRL Device Descriptor (copy from CfgDesc) -FLASH uint8_t TKEYCTRL_CfgDesc[] = { +// DEBUG Device Descriptor (copy from DebugDesc) +FLASH uint8_t DebugCfgDesc[] = { 0x09, /* bLength: HID Descriptor size */ USB_DESC_TYPE_HID, /* bDescriptorType: HID */ 0x11, /* bcdHID (low byte): HID Class Spec release number */ @@ -336,31 +355,31 @@ FLASH uint8_t TKEYCTRL_CfgDesc[] = { 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 */ + LOBYTE(DEBUG_REPORT_DESC_SIZE), /* wDescriptorLength (low byte): Total length of Report descriptor */ + HIBYTE(DEBUG_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) */ +// DEBUG Report Descriptor +FLASH uint8_t DebugReportDesc[] ={ + 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) */ + 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) */ + 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 */ + 0xC0 /* End Collection */ /* 34 */ }; @@ -372,16 +391,12 @@ FLASH uint8_t LangDesc[] = { }; // CDC Parameters: The initial baud rate is 500000, 1 stop bit, no parity, 8 data bits. -XDATA uint8_t LineCoding[7] = { 0x20, 0xA1, 0x07, 0x00, /* Data terminal rate, in bits per second: 500000 */ +FLASH uint8_t LineCoding[7] = { 0x20, 0xA1, 0x07, 0x00, /* Data terminal rate, in bits per second: 500000 */ 0x00, /* Stop bits: 0 - 1 Stop bit, 1 - 1.5 Stop bits, 2 - 2 Stop bits */ 0x00, /* Parity: 0 - None, 1 - Odd, 2 - Even, 3 - Mark, 4 - Space */ 0x08, /* Data bits (5, 6, 7, 8 or 16) */ }; -#define TKEYCTRL_FRAME_SIZE 64 -#define HID_FRAME_SIZE 64 -#define MAX_CDC_FRAME_SIZE 64 - #define UART_TX_BUF_SIZE 64 // Serial transmit buffer #define UART_RX_BUF_SIZE 140 // Serial receive buffer @@ -397,49 +412,46 @@ volatile IDATA uint8_t UartRxBufOutputPointer = 0; // Take pointer out of circu volatile IDATA uint8_t UartRxBufByteCount = 0; // Number of unprocessed bytes remaining in the buffer /** Debug UART */ +#ifdef DEBUG_PRINT_HW #define DEBUG_UART_RX_BUF_SIZE 8 XDATA uint8_t DebugUartRxBuf[DEBUG_UART_RX_BUF_SIZE] = { 0 }; volatile IDATA uint8_t DebugUartRxBufInputPointer = 0; volatile IDATA uint8_t DebugUartRxBufOutputPointer = 0; volatile IDATA uint8_t DebugUartRxBufByteCount = 0; +#endif /** Endpoint handling */ 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 UsbEp4ByteCount = 0; // Represents the data received by USB endpoint 4 (TKEYCTRL) +volatile IDATA uint8_t UsbEp3ByteCount = 0; // Represents the data received by USB endpoint 3 (FIDO) +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 Endpoint3UploadBusy = 0; // Whether the upload endpoint 3 (HID) is busy -volatile IDATA uint8_t Endpoint4UploadBusy = 0; // Whether the upload endpoint 4 (TKEYCTRL) is busy +volatile IDATA uint8_t Endpoint3UploadBusy = 0; // Whether the upload endpoint 3 (FIDO) is busy +volatile IDATA uint8_t Endpoint4UploadBusy = 0; // Whether the upload endpoint 4 (DEBUG) is busy -/** TKEYCTRL variables */ -XDATA uint8_t TkeyCtrlRxBuf[TKEYCTRL_FRAME_SIZE] = { 0 }; -IDATA uint8_t TkeyCtrlRxBufLength = 0; -IDATA uint8_t TkeyCtrlDataAvailable = 0; +/** CH552 variables */ +IDATA uint8_t CH552DataAvailable = 0; + +/** DEBUG variables */ +IDATA uint8_t DebugDataAvailable = 0; /** CDC variables */ -XDATA uint8_t CdcRxBuf[MAX_CDC_FRAME_SIZE] = { 0 }; -IDATA uint8_t CdcRxBufLength = 0; IDATA uint8_t CdcDataAvailable = 0; -/** HID variables */ -XDATA uint8_t HidRxBuf[HID_FRAME_SIZE] = { 0 }; -IDATA uint8_t HidRxBufLength = 0; -IDATA uint8_t HidDataAvailable = 0; +/** FIDO variables */ +IDATA uint8_t FidoDataAvailable = 0; /** Frame data */ +#define MAX_FRAME_SIZE 64 +XDATA uint8_t FrameBuf[MAX_FRAME_SIZE] = { 0 }; +IDATA uint8_t FrameBufLength = 0; -#define MODE_TKEYCTRL 0x20 -#define MODE_CDC 0x40 -#define MODE_HID 0x80 -#define MODE_MASK 0xC0 -#define NUM_MASK 0x3F - -volatile IDATA uint8_t FrameMode = 0; -volatile IDATA uint8_t FrameLength = 0; -volatile IDATA uint8_t FrameRemainingBytes = 0; -volatile IDATA uint8_t FrameStarted = 0; -volatile IDATA uint8_t Halted = 0; +IDATA uint8_t FrameMode = 0; +IDATA uint8_t FrameLength = 0; +IDATA uint8_t FrameRemainingBytes = 0; +IDATA uint8_t FrameStarted = 0; +IDATA uint8_t FrameDiscard = 0; +IDATA uint8_t DiscardDataAvailable = 0; uint32_t increment_pointer(uint32_t pointer, uint32_t increment, uint32_t buffer_size); uint32_t decrement_pointer(uint32_t pointer, uint32_t decrement, uint32_t buffer_size); @@ -516,7 +528,48 @@ void USBDeviceEndPointCfg() 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 UEP4_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK; // Endpoint 4, manual flip, OUT transaction returns ACK, IN transaction returns NAK +} +void CreateCfgDescriptor(uint8_t ep_config) +{ + uint8_t num_iface = 0; // Interface number + + FidoInterfaceNum = 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 + + uint8_t cfg_desc_size = sizeof(CfgDesc); + memcpy(ActiveCfgDesc, CfgDesc, cfg_desc_size); + ActiveCfgDescSize += cfg_desc_size; + + if (ep_config & IO_CDC) { + uint8_t cdc_desc_size = sizeof(CdcDesc); + memcpy(ActiveCfgDesc + ActiveCfgDescSize, CdcDesc, cdc_desc_size); + num_iface += 2; + ActiveCfgDescSize += cdc_desc_size; + } + + if (ep_config & IO_FIDO) { + uint8_t fido_desc_size = sizeof(FidoDesc); + memcpy(ActiveCfgDesc + ActiveCfgDescSize, FidoDesc, fido_desc_size); + ActiveCfgDesc[ActiveCfgDescSize + 2] = num_iface; + FidoInterfaceNum = num_iface; + num_iface++; + ActiveCfgDescSize += fido_desc_size; + } + + if (ep_config & IO_DEBUG) { + uint8_t debug_desc_size = sizeof(DebugDesc); + memcpy(ActiveCfgDesc + ActiveCfgDescSize, DebugDesc, debug_desc_size); + ActiveCfgDesc[ActiveCfgDescSize + 2] = num_iface; + DebugInterfaceNum = num_iface; + num_iface++; + ActiveCfgDescSize += debug_desc_size; + } + + ActiveCfgDesc[2] = ActiveCfgDescSize; + ActiveCfgDesc[4] = num_iface; } /******************************************************************************* @@ -606,8 +659,8 @@ void usb_irq_setup_handler(void) printStrSetup("DevDesc\n"); break; case USB_DESC_TYPE_CONFIGURATION: // Configuration descriptor - pDescr = CfgDesc; // Send the configuration descriptor to the buffer to be sent - len = sizeof(CfgDesc); + pDescr = ActiveCfgDesc; // Send the configuration descriptor to the buffer to be sent + len = sizeof(ActiveCfgDesc); printStrSetup("CfgDesc\n"); break; case USB_DESC_TYPE_STRING: // String descriptors @@ -635,48 +688,38 @@ void usb_irq_setup_handler(void) pDescr = CdcDataInterfaceDesc; len = sizeof(CdcDataInterfaceDesc); printStrSetup("CdcDataInterfaceDesc\n"); - } else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_FIDO_HID_STR) { - pDescr = FidoHidInterfaceDesc; - len = sizeof(FidoHidInterfaceDesc); + } else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_FIDO_STR) { + pDescr = FidoInterfaceDesc; + len = sizeof(FidoInterfaceDesc); printStrSetup("FidoHidInterfaceDesc\n"); - } else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_TKEY_CTRL_STR) { - pDescr = TkeyCtrlInterfaceDesc; - len = sizeof(TkeyCtrlInterfaceDesc); - printStrSetup("TkeyCtrlInterfaceDesc\n"); + } else if (UsbSetupBuf->wValueL == USB_IDX_INTERFACE_DEBUG_STR) { + pDescr = DebugInterfaceDesc; + len = sizeof(DebugInterfaceDesc); + printStrSetup("DebugInterfaceDesc\n"); } else { printStrSetup("Error: USB_DESC_TYPE_STRING\n"); } break; case USB_DESC_TYPE_HID: - switch (UsbSetupBuf->wIndexL) { - case 0x02: // Interface 2 (HID) - pDescr = HID_CfgDesc; - len = sizeof(HID_CfgDesc); - printStrSetup("HID_CfgDesc\n"); - break; - case 0x03: // Interface 3 (TKEYCTRL) - pDescr = TKEYCTRL_CfgDesc; - len = sizeof(TKEYCTRL_CfgDesc); - printStrSetup("TKEYCTRL_CfgDesc\n"); - break; - default: - break; + if (UsbSetupBuf->wIndexL == FidoInterfaceNum) { // Interface number for FIDO + pDescr = FidoCfgDesc; + len = sizeof(FidoCfgDesc); + printStrSetup("FidoCfgDesc\n"); + } else if (UsbSetupBuf->wIndexL == DebugInterfaceNum) { // Interface number for DEBUG + pDescr = DebugCfgDesc; + len = sizeof(DebugCfgDesc); + printStrSetup("DebugCfgDesc\n"); } break; case USB_DESC_TYPE_REPORT: - switch (UsbSetupBuf->wIndexL) { - case 0x02: // Interface 2 (HID) - pDescr = HID_ReportDesc; - len = sizeof(HID_ReportDesc); - printStrSetup("HID_ReportDesc\n"); - break; - case 0x03: // Interface 3 (TKEYCTRL) - pDescr = TKEYCTRL_ReportDesc; - len = sizeof(TKEYCTRL_ReportDesc); - printStrSetup("TKEYCTRL_ReportDesc\n"); - break; - default: - break; + if (UsbSetupBuf->wIndexL == FidoInterfaceNum) { // Interface number for FIDO + pDescr = FidoReportDesc; + len = sizeof(FidoReportDesc); + printStrSetup("FidoReportDesc\n"); + } else if (UsbSetupBuf->wIndexL == DebugInterfaceNum) { // Interface number for DEBUG + pDescr = DebugReportDesc; + len = sizeof(DebugReportDesc); + printStrSetup("DebugReportDesc\n"); } break; default: @@ -1002,8 +1045,8 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist UartRxBufOutputPointer = 0; // Circular buffer read pointer UartRxBufByteCount = 0; // The number of bytes remaining in the current buffer to be fetched UsbEp2ByteCount = 0; // USB endpoint 2 (CDC) received length - UsbEp3ByteCount = 0; // USB endpoint 3 (HID) received length - UsbEp4ByteCount = 0; // USB endpoint 4 (TKEYCTRL) received length + UsbEp3ByteCount = 0; // USB endpoint 3 (FIDO) received length + UsbEp4ByteCount = 0; // USB endpoint 4 (DEBUG) received length Endpoint2UploadBusy = 0; // Clear busy flag Endpoint3UploadBusy = 0; // Clear busy flag Endpoint4UploadBusy = 0; // Clear busy flag @@ -1043,7 +1086,7 @@ void DeviceInterrupt(void)IRQ_USB // USB interrupt service routine, using regist * Function Name : Uart0_ISR() * Description : Serial debug port receiving interrupt function to realize circular buffer receiving *******************************************************************************/ -#if 1 +#ifdef DEBUG_PRINT_HW #ifdef BUILD_CODE #define IRQ_UART0 __interrupt(INT_NO_UART0) #else @@ -1127,7 +1170,6 @@ void circular_copy(uint8_t *dest, uint8_t *src, uint32_t src_size, uint32_t star } } - // Function to increment a pointer and wrap around the buffer uint32_t increment_pointer(uint32_t pointer, uint32_t increment, uint32_t buffer_size) { @@ -1160,20 +1202,29 @@ void check_cts_stop(void) void main() { - // Enable GPIO signalling on p1.4 and p1.5 - gpio_init_p1_4_in(); // Init GPIO p1.4 to input mode for FPGA_CTS - gpio_init_p1_5_out(); // Init GPIO p1.5 to output mode for CH552_CTS - cts_start(); // Signal OK to send - CfgFsys(); // CH559 clock selection configuration mDelaymS(5); // Modify the main frequency and wait for the internal crystal to stabilize, which must be added -#if 0 +#ifdef DEBUG_PRINT_HW mInitSTDIO(); // Serial port 0, can be used for debugging #endif UART1Setup(); // For communication with FPGA UART1Clean(); // Clean register from spurious data - printStr("\n\nStartup...\n"); + printStrSetup("Startup\n"); + + uint8_t ActiveEndpoints = RESET_KEEP; + + // Always enable CDC endpoint + if ((ActiveEndpoints & IO_CDC) == 0x0) { + ActiveEndpoints |= IO_CDC; + } + + // Always enable CH552 endpoint + if ((ActiveEndpoints & IO_CH552) == 0x0) { + ActiveEndpoints |= IO_CH552; + } + + CreateCfgDescriptor(ActiveEndpoints); USBDeviceCfg(); USBDeviceEndPointCfg(); // Endpoint configuration @@ -1185,6 +1236,10 @@ void main() UEP3_T_LEN = 0; // Transmit length must be cleared (Endpoint 3) UEP4_T_LEN = 0; // Transmit length must be cleared (Endpoint 4) + gpio_init_p1_4_in(); // Init GPIO p1.4 to input mode for FPGA_CTS + gpio_init_p1_5_out(); // Init GPIO p1.5 to output mode for CH552_CTS + cts_start(); // Signal OK to send + while (1) { if (UsbConfig) { @@ -1194,31 +1249,31 @@ void main() memcpy(UartTxBuf, Ep2Buffer, Ep2ByteLen); UsbEp2ByteCount = 0; - CH554UART1SendByte(MODE_CDC); // Send CDC mode header + CH554UART1SendByte(IO_CDC); // Send CDC mode header CH554UART1SendByte(Ep2ByteLen); // Send length CH554UART1SendBuffer(UartTxBuf, Ep2ByteLen); UEP2_CTRL = (UEP2_CTRL & ~MASK_UEP_R_RES) | UEP_R_RES_ACK; // Enable Endpoint 2 to ACK again } - // Check if Endpoint 3 (HID) has received data + // Check if Endpoint 3 (FIDO) has received data if (UsbEp3ByteCount) { Ep3ByteLen = UsbEp3ByteCount; // UsbEp3ByteCount can be maximum 64 bytes memcpy(UartTxBuf, Ep3Buffer, Ep3ByteLen); UsbEp3ByteCount = 0; - CH554UART1SendByte(MODE_HID); // Send HID mode header + CH554UART1SendByte(IO_FIDO); // Send FIDO mode header CH554UART1SendByte(Ep3ByteLen); // Send length (always 64 bytes) CH554UART1SendBuffer(UartTxBuf, Ep3ByteLen); 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 + // Check if Endpoint 4 (DEBUG) 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(IO_DEBUG); // Send DEBUG 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 @@ -1228,9 +1283,11 @@ void main() if ((UartRxBufByteCount >= 2) && !FrameStarted) { // If we have data and the header is not yet validated FrameMode = UartRxBuf[UartRxBufOutputPointer]; // Extract frame mode - if ((FrameMode == MODE_CDC) || - (FrameMode == MODE_HID) || - (FrameMode == MODE_TKEYCTRL)) { + if ((FrameMode == IO_CDC) || + (FrameMode == IO_FIDO) || + (FrameMode == IO_DEBUG) || + (FrameMode == IO_CH552)) { + FrameLength = UartRxBuf[increment_pointer(UartRxBufOutputPointer, 1, UART_RX_BUF_SIZE)]; // Extract frame length @@ -1240,63 +1297,52 @@ void main() UART_RX_BUF_SIZE); // Start at valid data so skip the mode and length byte UartRxBufByteCount -= 2; // Subtract the frame mode and frame length bytes from the total byte count FrameStarted = 1; - } else { // Invalid mode - if (!Halted) { - printStr("Invalid header: 0x"); - printNumU8Hex(FrameMode); - printStr(", len = "); - printNumU8Hex(UartRxBuf[increment_pointer(UartRxBufOutputPointer, - 1, - UART_RX_BUF_SIZE)]); - printStr("\n"); - uint16_t i; - uint8_t print_char_count_out = 0; - for (i=0; i= 16) { - printStr("\n"); - print_char_count_out = 0; - } - } - if (print_char_count_out != 0) { - printStr("\n"); - } - printStr("Halting!\n"); - Halted = 1; + + // Mark that we should discard data if destination for the frame is not active + if ((FrameMode & ActiveEndpoints) == 0) { + FrameDiscard = 1; } + + } else { // Invalid frame mode + + cts_stop(); + + // Reset CH552 to start from a known state + SAFE_MOD = 0x55; + SAFE_MOD = 0xAA; + GLOBAL_CFG = bSW_RESET; + while (1) + ; } } - // Copy CDC data from UartRxBuf to CdcRxBuf - if (FrameStarted && !CdcDataAvailable) { - if (FrameMode == MODE_CDC) { - if ((FrameRemainingBytes >= MAX_PACKET_SIZE) && - (UartRxBufByteCount >= MAX_PACKET_SIZE)) { - circular_copy(CdcRxBuf, + // Copy CDC data from UartRxBuf to FrameBuf + if (FrameStarted && !FrameDiscard && !CdcDataAvailable) { + if (FrameMode == IO_CDC) { + if ((FrameRemainingBytes >= MAX_FRAME_SIZE) && + (UartRxBufByteCount >= MAX_FRAME_SIZE)) { + circular_copy(FrameBuf, UartRxBuf, UART_RX_BUF_SIZE, UartRxBufOutputPointer, - MAX_PACKET_SIZE); - CdcRxBufLength = MAX_PACKET_SIZE; + MAX_FRAME_SIZE); + FrameBufLength = MAX_FRAME_SIZE; // Update output pointer UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, - MAX_PACKET_SIZE, + MAX_FRAME_SIZE, UART_RX_BUF_SIZE); - FrameRemainingBytes -= MAX_PACKET_SIZE; + FrameRemainingBytes -= MAX_FRAME_SIZE; CdcDataAvailable = 1; cts_start(); } - else if ((FrameRemainingBytes < MAX_PACKET_SIZE) && + else if ((FrameRemainingBytes < MAX_FRAME_SIZE) && (UartRxBufByteCount >= FrameRemainingBytes)) { - circular_copy(CdcRxBuf, + circular_copy(FrameBuf, UartRxBuf, UART_RX_BUF_SIZE, UartRxBufOutputPointer, FrameRemainingBytes); - CdcRxBufLength = FrameRemainingBytes; + FrameBufLength = FrameRemainingBytes; // Update output pointer UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, FrameRemainingBytes, @@ -1308,79 +1354,141 @@ void main() } } - // Copy HID data from UartRxBuf to HidRxBuf - if (FrameStarted && !HidDataAvailable) { - if (FrameMode == MODE_HID) { + // Copy FIDO data from UartRxBuf to FrameBuf + if (FrameStarted && !FrameDiscard && !FidoDataAvailable) { + if (FrameMode == IO_FIDO) { // Check if a complete frame has been received if (UartRxBufByteCount >= FrameRemainingBytes) { - circular_copy(HidRxBuf, + circular_copy(FrameBuf, UartRxBuf, UART_RX_BUF_SIZE, UartRxBufOutputPointer, FrameRemainingBytes); - HidRxBufLength = MAX_PACKET_SIZE; + FrameBufLength = MAX_FRAME_SIZE; // Update output pointer UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, FrameRemainingBytes, UART_RX_BUF_SIZE); - HidDataAvailable = 1; + FidoDataAvailable = 1; cts_start(); } } } - // 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, + // Copy DEBUG data from UartRxBuf to FrameBuf + if (FrameStarted && !FrameDiscard && !DebugDataAvailable) { + if (FrameMode == IO_DEBUG) { + if ((FrameRemainingBytes >= MAX_FRAME_SIZE) && + (UartRxBufByteCount >= MAX_FRAME_SIZE)) { + circular_copy(FrameBuf, UartRxBuf, UART_RX_BUF_SIZE, UartRxBufOutputPointer, - MAX_PACKET_SIZE); - TkeyCtrlRxBufLength = MAX_PACKET_SIZE; + MAX_FRAME_SIZE); + FrameBufLength = MAX_FRAME_SIZE; // Update output pointer UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, - MAX_PACKET_SIZE, + MAX_FRAME_SIZE, UART_RX_BUF_SIZE); - FrameRemainingBytes -= MAX_PACKET_SIZE; - TkeyCtrlDataAvailable = 1; + FrameRemainingBytes -= MAX_FRAME_SIZE; + DebugDataAvailable = 1; cts_start(); } - else if ((FrameRemainingBytes < MAX_PACKET_SIZE) && + else if ((FrameRemainingBytes < MAX_FRAME_SIZE) && (UartRxBufByteCount >= FrameRemainingBytes)) { - circular_copy(TkeyCtrlRxBuf, + circular_copy(FrameBuf, UartRxBuf, UART_RX_BUF_SIZE, UartRxBufOutputPointer, FrameRemainingBytes); - TkeyCtrlRxBufLength = FrameRemainingBytes; + FrameBufLength = FrameRemainingBytes; // Update output pointer UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, FrameRemainingBytes, UART_RX_BUF_SIZE); FrameRemainingBytes -= FrameRemainingBytes; - TkeyCtrlDataAvailable = 1; + DebugDataAvailable = 1; cts_start(); } } } + // Copy CH552 data from UartRxBuf to FrameBuf + if (FrameStarted && !FrameDiscard && !CH552DataAvailable) { + if (FrameMode == IO_CH552) { + 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; + CH552DataAvailable = 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; + CH552DataAvailable = 1; + cts_start(); + } + } + } + + // Discard frame + if (FrameStarted && FrameDiscard && !DiscardDataAvailable) { + if ((FrameRemainingBytes >= MAX_FRAME_SIZE) && + (UartRxBufByteCount >= MAX_FRAME_SIZE)) { + // Update output pointer + UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, + MAX_FRAME_SIZE, + UART_RX_BUF_SIZE); + FrameRemainingBytes -= MAX_FRAME_SIZE; + DiscardDataAvailable = 1; + cts_start(); + } + else if ((FrameRemainingBytes < MAX_FRAME_SIZE) && + (UartRxBufByteCount >= FrameRemainingBytes)) { + // Update output pointer + UartRxBufOutputPointer = increment_pointer(UartRxBufOutputPointer, + FrameRemainingBytes, + UART_RX_BUF_SIZE); + FrameRemainingBytes -= FrameRemainingBytes; + DiscardDataAvailable = 1; + cts_start(); + } + } + // Check if we should upload data to Endpoint 2 (CDC) if (CdcDataAvailable && !Endpoint2UploadBusy) { // Write upload endpoint memcpy(Ep2Buffer + MAX_PACKET_SIZE, /* Copy to IN buffer of Endpoint 2 */ - CdcRxBuf, - CdcRxBufLength); + FrameBuf, + FrameBufLength); Endpoint2UploadBusy = 1; // Set busy flag - UEP2_T_LEN = CdcRxBufLength; // Set the number of data bytes that Endpoint 2 is ready to send + UEP2_T_LEN = FrameBufLength; // Set the number of data bytes that Endpoint 2 is ready to send UEP2_CTRL = (UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_ACK; // Answer ACK CdcDataAvailable = 0; - CdcRxBufLength = 0; + FrameBufLength = 0; if (FrameRemainingBytes == 0) { // Complete frame sent, get next header and data @@ -1388,46 +1496,47 @@ void main() } } - // Check if we should upload data to Endpoint 3 (HID) - if (HidDataAvailable && !Endpoint3UploadBusy) { + // Check if we should upload data to Endpoint 3 (FIDO) + if (FidoDataAvailable && !Endpoint3UploadBusy) { // Write upload endpoint memcpy(Ep3Buffer + MAX_PACKET_SIZE, /* Copy to IN buffer of Endpoint 3 */ - HidRxBuf, - HidRxBufLength); + FrameBuf, + FrameBufLength); Endpoint3UploadBusy = 1; // Set busy flag UEP3_T_LEN = MAX_PACKET_SIZE; // 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 - HidDataAvailable = 0; + FidoDataAvailable = 0; + FrameBufLength = 0; // Get next header and data FrameStarted = 0; } - // Check if we should upload data to Endpoint 4 (TKEYCTRL) - if (TkeyCtrlDataAvailable && !Endpoint4UploadBusy) { + // Check if we should upload data to Endpoint 4 (DEBUG) + if (DebugDataAvailable && !Endpoint4UploadBusy) { - if (TkeyCtrlRxBufLength == MAX_PACKET_SIZE) { + if (FrameBufLength == MAX_PACKET_SIZE) { // Write upload endpoint memcpy(Ep0Buffer + 128, /* Copy to IN (TX) buffer of Endpoint 4 */ - TkeyCtrlRxBuf, - TkeyCtrlRxBufLength); + FrameBuf, + FrameBufLength); } else { memset(Ep0Buffer + 128, 0, MAX_PACKET_SIZE); // Write upload endpoint memcpy(Ep0Buffer + 128, /* Copy to IN (TX) buffer of Endpoint 4 */ - TkeyCtrlRxBuf, - TkeyCtrlRxBufLength); + FrameBuf, + FrameBufLength); } Endpoint4UploadBusy = 1; // Set busy flag 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 - TkeyCtrlDataAvailable = 0; - TkeyCtrlRxBufLength = 0; + DebugDataAvailable = 0; + FrameBufLength = 0; if (FrameRemainingBytes == 0) { // Complete frame sent, get next header and data @@ -1435,88 +1544,53 @@ void main() } } -#if 0 - DebugUartRxBufByteCount = debug_uart_byte_count(); - if (DebugUartRxBufByteCount) { - switch(DebugUartRxBuf[DebugUartRxBufOutputPointer]) { - case 'h': - printStr("h Show help\n"); - printStr("r Reset UART1\n"); - printStr("s Show status\n"); + // Check if we should handle CH552 data + if (CH552DataAvailable) { + + switch(FrameBuf[0]) { + + case 0x01: { // Enable endpoints + cts_stop(); // Stop UART data from FPGA + RESET_KEEP = FrameBuf[1]; // Save endpoints to persistent register + SAFE_MOD = 0x55; // Start reset sequence + SAFE_MOD = 0xAA; + GLOBAL_CFG = bSW_RESET; + while (1) + ; + } break; - case 'r': - /** UART */ - UartRxBufInputPointer = 0; - UartRxBufOutputPointer = 0; - /** Frame */ - FrameMode = 0; - FrameLength = 0; - FrameStarted = 0; - /** CDC */ - CdcDataAvailable = 0; - CdcRxBufLength = 0; - CdcLoopCount = 0; - /** HID */ - HidDataAvailable = 0; - /** Timeout */ - LoopCounter = 0; - LastReceiveCounter = 0; - /** Endpoints */ - 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; - UEP4_CTRL = UEP_T_RES_NAK | UEP_R_RES_ACK; - UIF_TRANSFER = 0; // Writing 0 clears the interrupt - UIF_BUS_RST = 0; // Clear interrupt flag - Endpoint2UploadBusy = 0; - Endpoint3UploadBusy = 0; - UsbEp2ByteCount = 0; // USB endpoint 2 (CDC) received length - UsbEp3ByteCount = 0; // USB endpoint 3 (HID) received length - - /** Misc */ - Halted = 0; - printStr("Reset done!\n"); + default: { + } break; - case 's': - printStr("Endpoint2UploadBusy = "); printNumU32(Endpoint2UploadBusy); printStr("\n"); - printStr("UsbEp2ByteCount = "); printNumU32(UsbEp2ByteCount); printStr("\n"); - printStr("UEP2_CTRL = 0x"); printNumHex(UEP2_CTRL); printStr("\n"); - - printStr("Endpoint3UploadBusy = "); printNumU32(Endpoint3UploadBusy); printStr("\n"); - printStr("UsbEp3ByteCount = "); printNumU32(UsbEp3ByteCount); 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("UartRxBufOutputPointer = "); printNumU32(UartRxBufOutputPointer); printStr("\n"); - - printStr("UartRxBufByteCount = "); printNumU32(UartRxBufByteCount); printStr("\n"); - printStr("FrameMode = 0x"); printNumHex(FrameMode); printStr("\n"); - printStr("FrameLength = "); printNumU32(FrameLength); printStr("\n"); - printStr("FrameStarted = "); printNumU32(FrameStarted); printStr("\n"); - - printStr("CdcDataAvailable = "); printNumU32(CdcDataAvailable); printStr("\n"); - printStr("HidDataAvailable = "); printNumU32(HidDataAvailable); printStr("\n"); - - printStr("Halted = "); printNumU32(Halted); printStr("\n"); - break; - - default: - printStr("\n"); - break; } - // Update out pointer - DebugUartRxBufOutputPointer = increment_pointer(DebugUartRxBufOutputPointer, - DebugUartRxBufByteCount, - DEBUG_UART_RX_BUF_SIZE); + CH552DataAvailable = 0; + FrameBufLength = 0; + + memset(FrameBuf, 0, MAX_FRAME_SIZE); + + if (FrameRemainingBytes == 0) { + // Complete frame sent, get next header and data + FrameStarted = 0; + } } -#endif + + if (DiscardDataAvailable) { + + DiscardDataAvailable = 0; + printStr("Frame discarded!\n"); + + if (FrameRemainingBytes == 0) { + // Complete frame discarded, get next header and data + FrameStarted = 0; + // Stop discarding frames + FrameDiscard = 0; + } + } + } /* END if (UsbConfig) */ } /* END while (1) */ } diff --git a/hw/usb_interface/ch552_fw/src/print.c b/hw/usb_interface/ch552_fw/src/print.c index 11c9cc8..9cc0a92 100644 --- a/hw/usb_interface/ch552_fw/src/print.c +++ b/hw/usb_interface/ch552_fw/src/print.c @@ -2,13 +2,12 @@ #include #include "debug.h" +#include "io.h" #include "lib.h" #include "main.h" #include "mem.h" #include "print.h" -#define MODE_CH552 0x10 - void printStr(uint8_t *str) { #ifdef USE_DEBUG_PRINT @@ -19,7 +18,7 @@ void printStr(uint8_t *str) } #elif defined(DEBUG_PRINT_SW) uint32_t str_len = strlen(str); - CH554UART1SendByte(MODE_CH552); + CH554UART1SendByte(IO_CH552); CH554UART1SendByte(str_len); CH554UART1SendBuffer(str, str_len); #endif @@ -34,7 +33,7 @@ void printChar(uint8_t c) #if defined(DEBUG_PRINT_HW) CH554UART0SendByte(c); #elif defined(DEBUG_PRINT_SW) - CH554UART1SendByte(MODE_CH552); + CH554UART1SendByte(IO_CH552); CH554UART1SendByte(1); CH554UART1SendByte(c); #endif