diff options
| author | hathach <[email protected]> | 2023-08-03 20:42:34 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2023-08-03 20:42:34 +0700 |
| commit | 041f510f909f0ce8923389c847a8d55e0b7eeee2 (patch) | |
| tree | cb669dc6e1f4945898f2f0822a86731c293d3dd0 | |
| parent | 1324c2862df921d9634e90a78048f5d71a77d894 (diff) | |
add board_get_unique_id() for serial number
implemented board_get_unique_id() for rp2040 and L4
| -rw-r--r-- | examples/device/cdc_msc/src/usb_descriptors.c | 54 | ||||
| -rw-r--r-- | hw/bsp/board_api.h | 40 | ||||
| -rw-r--r-- | hw/bsp/family_support.cmake | 3 | ||||
| -rw-r--r-- | hw/bsp/rp2040/family.c | 36 | ||||
| -rw-r--r-- | hw/bsp/rp2040/family.cmake | 1 | ||||
| -rw-r--r-- | hw/bsp/stm32l4/family.c | 52 |
6 files changed, 124 insertions, 62 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; + + switch(index) { + case STRID_LANGID: + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + break; + + case STRID_SERIAL: + chr_count = board_usb_get_serial(_desc_str+1, 32); + break; - 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 + 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 - if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; - const char* str = string_desc_arr[index]; + const char* str = string_desc_arr[index]; - // Cap at max char - chr_count = (uint8_t) strlen(str); - if ( chr_count > 31 ) chr_count = 31; + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) chr_count = 31; - // Convert ASCII string into UTF-16 - for(uint8_t i=0; i<chr_count; i++) - { - _desc_str[1+i] = str[i]; - } + // Convert ASCII string into UTF-16 + for(size_t i=0; i<chr_count; i++) { + _desc_str[1+i] = str[i]; + } + break; } // first byte is length (including header), second byte is string type diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index 7249f618d..53296cd56 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -60,12 +60,13 @@ void board_led_write(bool state); // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void); -// Get characters from UART -// Return number of read bytes +// Get board unique ID for USB serial number. Return number of bytes. Note max_len is typically 16 +TU_ATTR_WEAK size_t board_get_unique_id(uint8_t id[], size_t max_len); + +// Get characters from UART. Return number of read bytes int board_uart_read(uint8_t *buf, int len); -// Send characters to UART -// Return number of sent bytes +// Send characters to UART. Return number of sent bytes int board_uart_write(void const *buf, int len); #if CFG_TUSB_OS == OPT_OS_NONE @@ -108,6 +109,37 @@ static inline void board_led_off(void) { board_led_write(false); } +// Get USB Serial number string from unique ID if available. Return number of character. +// Input is string descriptor from index 1 (index 0 is type + len) +static inline size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars) { + uint8_t serial_id[16] TU_ATTR_ALIGNED(4); + size_t serial_len; + + if ( board_get_unique_id ) { + serial_len = board_get_unique_id(serial_id, sizeof(serial_id)); + }else { + // fixed serial string is 01234567889ABCDEF + *((uint32_t*)(uintptr_t) serial_id) = 0x67452301; + *((uint32_t*)(uintptr_t) (serial_id+4)) = 0xEFCDAB89; + serial_len = 8; + } + + if ( serial_len > 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<len;i++) { + char const *bufch = (char const *) buf; + for ( int i = 0; i < len; i++ ) { uart_putc(uart_inst, bufch[i]); } return len; @@ -219,8 +226,7 @@ int board_uart_write(void const * buf, int len) #endif } -int board_getchar(void) -{ +int board_getchar(void) { return getchar_timeout_us(0); } diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 17900dd7a..465041b12 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -112,6 +112,7 @@ target_sources(tinyusb_bsp INTERFACE target_include_directories(tinyusb_bsp INTERFACE ${TOP}/hw ) +target_link_libraries(tinyusb_bsp INTERFACE pico_unique_id) # tinyusb_additions will hold our extra settings for examples add_library(tinyusb_additions INTERFACE) diff --git a/hw/bsp/stm32l4/family.c b/hw/bsp/stm32l4/family.c index 0b2c22d19..1c6c595f1 100644 --- a/hw/bsp/stm32l4/family.c +++ b/hw/bsp/stm32l4/family.c @@ -48,8 +48,7 @@ void USB_IRQHandler(void) UART_HandleTypeDef UartHandle; -void board_init(void) -{ +void board_init(void) { board_clock_init(); // Enable All GPIOs clocks @@ -177,51 +176,60 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ - GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1-LED_STATE_ON)); +void board_led_write(bool state) { + GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON)); HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; + + uint8_t const len = 12; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; return 0; } -int board_uart_write(void const * buf, int len) -{ - HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff); +int board_uart_write(void const *buf, int len) { + HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff); return len; } -#if CFG_TUSB_OS == OPT_OS_NONE +#if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -void SysTick_Handler (void) -{ + +void SysTick_Handler(void) { HAL_IncTick(); system_ticks++; } -uint32_t board_millis(void) -{ +uint32_t board_millis(void) { return system_ticks; } + #endif -void HardFault_Handler (void) -{ +void HardFault_Handler(void) { __asm("BKPT #0\n"); } // Required by __libc_init_array in startup code if we are compiling using // -nostdlib/-nostartfiles. -void _init(void) -{ +void _init(void) { } |
