From 041f510f909f0ce8923389c847a8d55e0b7eeee2 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 3 Aug 2023 20:42:34 +0700 Subject: [PATCH] add board_get_unique_id() for serial number implemented board_get_unique_id() for rp2040 and L4 --- examples/device/cdc_msc/src/usb_descriptors.c | 54 +++++++++++------- hw/bsp/board_api.h | 40 +++++++++++-- hw/bsp/family_support.cmake | 3 +- hw/bsp/rp2040/family.c | 36 +++++++----- hw/bsp/rp2040/family.cmake | 1 + hw/bsp/stm32l4/family.c | 56 +++++++++++-------- 6 files changed, 126 insertions(+), 64 deletions(-) diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 44c849277..baf919f84 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -23,6 +23,7 @@ * */ +#include "bsp/board_api.h" #include "tusb.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. @@ -236,6 +237,14 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) // String Descriptors //--------------------------------------------------------------------+ +// String Descriptor Index +enum { + STRID_LANGID = 0, + STRID_MANUFACTURER, + STRID_PRODUCT, + STRID_SERIAL, +}; + // array of pointer to string descriptors char const* string_desc_arr [] = { @@ -247,7 +256,7 @@ char const* string_desc_arr [] = "TinyUSB MSC", // 5: MSC Interface }; -static uint16_t _desc_str[32]; +static uint16_t _desc_str[32+1]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete @@ -255,30 +264,35 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; - uint8_t chr_count; + size_t chr_count; - if ( index == 0) - { - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - }else - { - // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. - // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors + switch(index) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str+1, 32); + break; - const char* str = string_desc_arr[index]; + default: + // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. + // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - // Cap at max char - chr_count = (uint8_t) strlen(str); - if ( chr_count > 31 ) chr_count = 31; + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; - // Convert ASCII string into UTF-16 - for(uint8_t i=0; i 31 ) chr_count = 31; + + // Convert ASCII string into UTF-16 + for(size_t i=0; i max_chars / 2 ) serial_len = max_chars / 2; + + for ( size_t i = 0; i < serial_len; i++ ) { + for ( size_t j = 0; j < 2; j++ ) { + const char nibble_to_hex[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + uint8_t const nibble = (serial_id[i] >> (j * 4)) & 0xf; + desc_str1[i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE + } + } + + return 2*serial_len; +} + // TODO remove static inline void board_delay(uint32_t ms) { uint32_t start_ms = board_millis(); diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index b2e61a824..e5571b3b5 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -289,7 +289,8 @@ function(family_add_default_example_warnings TARGET) -Wfatal-errors -Wdouble-promotion -Wfloat-equal - -Wshadow + # FIXME commented out because of https://github.com/raspberrypi/pico-sdk/issues/1468 + #-Wshadow -Wwrite-strings -Wsign-compare -Wmissing-format-attribute diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index be5e9f753..aa9d00c23 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -27,6 +27,7 @@ #include "pico/stdlib.h" #include "pico/binary_info.h" +#include "pico/unique_id.h" #include "hardware/gpio.h" #include "hardware/sync.h" #include "hardware/structs/ioqspi.h" @@ -171,17 +172,15 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { (void) state; #ifdef LED_PIN - gpio_put(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); + gpio_put(LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); #endif } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { #ifdef BUTTON_BOOTSEL return BUTTON_STATE_ACTIVE == get_bootsel_button(); #else @@ -189,12 +188,21 @@ uint32_t board_button_read(void) #endif } -int board_uart_read(uint8_t* buf, int len) -{ +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + pico_unique_board_id_t pico_id; + pico_get_unique_board_id(&pico_id); + + size_t len = PICO_UNIQUE_BOARD_ID_SIZE_BYTES; + if (len > max_len) len = max_len; + + memcpy(id, pico_id.id, len); + return len; +} + +int board_uart_read(uint8_t *buf, int len) { #ifdef UART_DEV int count = 0; - while ( (count < len) && uart_is_readable(uart_inst) ) - { + while ( (count < len) && uart_is_readable(uart_inst) ) { buf[count] = uart_getc(uart_inst); count++; } @@ -205,11 +213,10 @@ int board_uart_read(uint8_t* buf, int len) #endif } -int board_uart_write(void const * buf, int len) -{ +int board_uart_write(void const *buf, int len) { #ifdef UART_DEV - char const* bufch = (char const*) buf; - for(int i=0;i