diff --git a/ccid.h b/ccid.h index 25fb99b..2c587aa 100644 --- a/ccid.h +++ b/ccid.h @@ -7,21 +7,23 @@ static const class_desc_ccid_t desc_ccid = { .bLength = sizeof (class_desc_ccid_t), .bDescriptorType = 0x21, - .bcdCCID = 0x0110, + .bcdCCID = (0x0110), .bMaxSlotIndex = 0, .bVoltageSupport = 0x01, // 5.0V - .dwProtocols = 0x01| // T=0 - 0x02, // T=1 - .dwDefaultClock = 0xdfc, - .dwMaximumClock = 0xdfc, + .dwProtocols = ( + 0x01| // T=0 + 0x02), // T=1 + .dwDefaultClock = (0xDFC), + .dwMaximumClock = (0xDFC), .bNumClockSupport = 1, - .dwDataRate = 0x2580, - .dwMaxDataRate = 0x2580, + .dwDataRate = (0x2580), + .dwMaxDataRate = (0x2580), .bNumDataRatesSupported = 1, - .dwMaxIFSD = 0xff, // IFSD is handled by the real reader driver - .dwSynchProtocols = 0, - .dwMechanical = 0, - .dwFeatures = 0x00000002| // Automatic parameter configuration based on ATR data + .dwMaxIFSD = (0xFF), // IFSD is handled by the real reader driver + .dwSynchProtocols = (0), + .dwMechanical = (0), + .dwFeatures = ( + 0x00000002| // Automatic parameter configuration based on ATR data 0x00000004| // Automatic activation of ICC on inserting 0x00000008| // Automatic ICC voltage selection 0x00000010| // Automatic ICC clock frequency change @@ -30,16 +32,17 @@ static const class_desc_ccid_t desc_ccid = { 0x00000080| // Automatic PPS 0x00000400| // Automatic IFSD exchange as first exchange 0x00040000| // Short and Extended APDU level exchange with CCID - 0x00100000, // USB Wake up signaling supported - .dwMaxCCIDMessageLength = CCID_EXT_APDU_MAX, - .bClassGetResponse = 0xff, - .bclassEnvelope = 0xff, - .wLcdLayout = 0xff00| // Number of lines for the LCD display - 0x00ff, // Number of characters per line + 0x00100000), // USB Wake up signaling supported + .dwMaxCCIDMessageLength = (CCID_EXT_APDU_MAX), + .bClassGetResponse = 0xFF, + .bclassEnvelope = 0xFF, + .wLcdLayout = ( + 0xFF00| // Number of lines for the LCD display + 0x00FF), // Number of characters per line .bPINSupport = 0x1| // PIN Verification supported - 0x2| + 0x2| // PIN Modification supported 0x10| // PIN PACE Capabilities supported - 0x20, // PIN Modification supported + 0x20, // PIN PACE Verification supported .bMaxCCIDBusySlots = 0x01, }; diff --git a/hsm2040.c b/hsm2040.c index 203dd2e..24bdb9d 100644 --- a/hsm2040.c +++ b/hsm2040.c @@ -15,10 +15,92 @@ #include "bsp/board.h" #include "tusb.h" #include "usb_descriptors.h" +#include "device/usbd_pvt.h" // Device descriptors #include "hsm2040.h" +static uint8_t itf_num; + +static void ccid_init(void) { +} + +static void ccid_reset(uint8_t __unused rhport) { + itf_num = 0; +} + +static uint16_t ccid_open(uint8_t __unused rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { + TU_VERIFY(itf_desc->bInterfaceClass == TUSB_CLASS_SMART_CARD && itf_desc->bInterfaceSubClass == 0 && itf_desc->bInterfaceProtocol == 0, 0); + + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(class_desc_ccid_t) + 2*sizeof(tusb_desc_endpoint_t); + TU_VERIFY(max_len >= drv_len, 0); + + itf_num = itf_desc->bInterfaceNumber; + return drv_len; +} + +// Support for parameterized reset via vendor interface control request +static bool ccid_control_xfer_cb(uint8_t __unused rhport, uint8_t stage, tusb_control_request_t const * request) { + // nothing to do with DATA & ACK stage + if (stage != CONTROL_STAGE_SETUP) return true; + + if (request->wIndex == itf_num) + { + TU_LOG2("-------- bmRequestType %x, bRequest %x, wValue %x, wLength %x\r\n",request->bmRequestType,request->bRequest, request->wValue, request->wLength); +/* +#if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_BOOTSEL + if (request->bRequest == RESET_REQUEST_BOOTSEL) { +#ifdef PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED + uint gpio_mask = 1u << PICO_STDIO_USB_RESET_BOOTSEL_ACTIVITY_LED; +#else + uint gpio_mask = 0u; +#endif +#if !PICO_STDIO_USB_RESET_BOOTSEL_FIXED_ACTIVITY_LED + if (request->wValue & 0x100) { + gpio_mask = 1u << (request->wValue >> 9u); + } +#endif + reset_usb_boot(gpio_mask, (request->wValue & 0x7f) | PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK); + // does not return, otherwise we'd return true + } +#endif + +#if PICO_STDIO_USB_RESET_INTERFACE_SUPPORT_RESET_TO_FLASH_BOOT + if (request->bRequest == RESET_REQUEST_FLASH) { + watchdog_reboot(0, 0, PICO_STDIO_USB_RESET_RESET_TO_FLASH_DELAY_MS); + return true; + } +#endif +*/ + return true; + } + return false; +} + +static bool ccid_xfer_cb(uint8_t __unused rhport, uint8_t __unused ep_addr, xfer_result_t __unused result, uint32_t __unused xferred_bytes) { + return true; +} + + +static usbd_class_driver_t const ccid_driver = +{ +#if CFG_TUSB_DEBUG >= 2 + .name = "CCID", +#endif + .init = ccid_init, + .reset = ccid_reset, + .open = ccid_open, + .control_xfer_cb = ccid_control_xfer_cb, + .xfer_cb = ccid_xfer_cb, + .sof = NULL +}; + +// Implement callback to add our custom driver +usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) { + *driver_count = 1; + return &ccid_driver; +} + enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, diff --git a/usb_descriptors.c b/usb_descriptors.c index 3b0b877..4f15c1e 100644 --- a/usb_descriptors.c +++ b/usb_descriptors.c @@ -37,8 +37,8 @@ #define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) -#define USB_VID 0xCafe -#define USB_BCD 0x0200 +#define USB_VID 0x0D46 +#define USB_BCD 0x3010 #define USB_CONFIG_ATT_ONE TU_BIT(7) @@ -65,11 +65,11 @@ tusb_desc_device_t const desc_device = .idProduct = (USB_PID), .bcdDevice = (0x0100), - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, - .bNumConfigurations = 0x01 + .bNumConfigurations = 1 }; // Invoked when received GET DEVICE DESCRIPTOR @@ -100,9 +100,9 @@ tusb_desc_configuration_t const desc_config = { .bLength = sizeof(tusb_desc_configuration_t), .bDescriptorType = TUSB_DESC_CONFIGURATION, - .wTotalLength = U16_TO_U8S_LE(sizeof(tusb_desc_configuration_t) + sizeof(tusb_desc_interface_t) + sizeof(class_desc_ccid_t) + 2*sizeof(tusb_desc_endpoint_t)), + .wTotalLength = (sizeof(tusb_desc_configuration_t) + sizeof(tusb_desc_interface_t) + sizeof(class_desc_ccid_t) + 2*sizeof(tusb_desc_endpoint_t)), .bNumInterfaces = 1, - .bConfigurationValue = 3, + .bConfigurationValue = 1, .iConfiguration = 4, .bmAttributes = USB_CONFIG_ATT_ONE | TUSB_DESC_CONFIG_ATT_SELF_POWERED, .bMaxPower = TUSB_DESC_CONFIG_POWER_MA(MAX_USB_POWER+1), @@ -112,9 +112,9 @@ tusb_desc_endpoint_t const desc_ep1 = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = TUSB_DIR_IN_MASK | 1, + .bEndpointAddress = TUSB_DIR_IN_MASK | 4, .bmAttributes.xfer = TUSB_XFER_BULK, - .wMaxPacketSize.size = U16_TO_U8S_LE(64), + .wMaxPacketSize.size = (64), .bInterval = 0 }; @@ -122,10 +122,10 @@ tusb_desc_endpoint_t const desc_ep2 = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 2, + .bEndpointAddress = 5, .bmAttributes.xfer = TUSB_XFER_BULK, - .wMaxPacketSize.size = U16_TO_U8S_LE(64), - .bInterval = 1 + .wMaxPacketSize.size = (64), + .bInterval = 0 }; @@ -163,7 +163,7 @@ char const* string_desc_arr [] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer - "TinyUSB Device", // 2: Product + "TinyUSB CCID", // 2: Product "11223344", // 3: Serials, should use chip ID "TinyUSB Config", // 4: Vendor Interface "TinyUSB Interface"