mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-18 20:42:24 +00:00
add board_get_unique_id() for serial number
implemented board_get_unique_id() for rp2040 and L4
This commit is contained in:
parent
1324c2862d
commit
041f510f90
examples/device/cdc_msc/src
hw/bsp
@ -23,6 +23,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "bsp/board_api.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
|
||||||
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
/* 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 Descriptors
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// String Descriptor Index
|
||||||
|
enum {
|
||||||
|
STRID_LANGID = 0,
|
||||||
|
STRID_MANUFACTURER,
|
||||||
|
STRID_PRODUCT,
|
||||||
|
STRID_SERIAL,
|
||||||
|
};
|
||||||
|
|
||||||
// array of pointer to string descriptors
|
// array of pointer to string descriptors
|
||||||
char const* string_desc_arr [] =
|
char const* string_desc_arr [] =
|
||||||
{
|
{
|
||||||
@ -247,7 +256,7 @@ char const* string_desc_arr [] =
|
|||||||
"TinyUSB MSC", // 5: MSC Interface
|
"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
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
// 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;
|
(void) langid;
|
||||||
|
|
||||||
uint8_t chr_count;
|
size_t chr_count;
|
||||||
|
|
||||||
if ( index == 0)
|
switch(index) {
|
||||||
{
|
case STRID_LANGID:
|
||||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
chr_count = 1;
|
chr_count = 1;
|
||||||
}else
|
break;
|
||||||
{
|
|
||||||
// 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;
|
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
|
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
|
||||||
chr_count = (uint8_t) strlen(str);
|
|
||||||
if ( chr_count > 31 ) chr_count = 31;
|
|
||||||
|
|
||||||
// Convert ASCII string into UTF-16
|
const char* str = string_desc_arr[index];
|
||||||
for(uint8_t i=0; i<chr_count; i++)
|
|
||||||
{
|
// Cap at max char
|
||||||
_desc_str[1+i] = str[i];
|
chr_count = strlen(str);
|
||||||
}
|
if ( chr_count > 31 ) chr_count = 31;
|
||||||
|
|
||||||
|
// 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
|
// first byte is length (including header), second byte is string type
|
||||||
|
@ -60,12 +60,13 @@ void board_led_write(bool state);
|
|||||||
// a '1' means active (pressed), a '0' means inactive.
|
// a '1' means active (pressed), a '0' means inactive.
|
||||||
uint32_t board_button_read(void);
|
uint32_t board_button_read(void);
|
||||||
|
|
||||||
// Get characters from UART
|
// Get board unique ID for USB serial number. Return number of bytes. Note max_len is typically 16
|
||||||
// Return number of read bytes
|
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);
|
int board_uart_read(uint8_t *buf, int len);
|
||||||
|
|
||||||
// Send characters to UART
|
// Send characters to UART. Return number of sent bytes
|
||||||
// Return number of sent bytes
|
|
||||||
int board_uart_write(void const *buf, int len);
|
int board_uart_write(void const *buf, int len);
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
@ -108,6 +109,37 @@ static inline void board_led_off(void) {
|
|||||||
board_led_write(false);
|
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
|
// TODO remove
|
||||||
static inline void board_delay(uint32_t ms) {
|
static inline void board_delay(uint32_t ms) {
|
||||||
uint32_t start_ms = board_millis();
|
uint32_t start_ms = board_millis();
|
||||||
|
@ -289,7 +289,8 @@ function(family_add_default_example_warnings TARGET)
|
|||||||
-Wfatal-errors
|
-Wfatal-errors
|
||||||
-Wdouble-promotion
|
-Wdouble-promotion
|
||||||
-Wfloat-equal
|
-Wfloat-equal
|
||||||
-Wshadow
|
# FIXME commented out because of https://github.com/raspberrypi/pico-sdk/issues/1468
|
||||||
|
#-Wshadow
|
||||||
-Wwrite-strings
|
-Wwrite-strings
|
||||||
-Wsign-compare
|
-Wsign-compare
|
||||||
-Wmissing-format-attribute
|
-Wmissing-format-attribute
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "pico/binary_info.h"
|
#include "pico/binary_info.h"
|
||||||
|
#include "pico/unique_id.h"
|
||||||
#include "hardware/gpio.h"
|
#include "hardware/gpio.h"
|
||||||
#include "hardware/sync.h"
|
#include "hardware/sync.h"
|
||||||
#include "hardware/structs/ioqspi.h"
|
#include "hardware/structs/ioqspi.h"
|
||||||
@ -171,17 +172,15 @@ void board_init(void)
|
|||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
|
||||||
(void) state;
|
(void) state;
|
||||||
|
|
||||||
#ifdef LED_PIN
|
#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_button_read(void)
|
uint32_t board_button_read(void) {
|
||||||
{
|
|
||||||
#ifdef BUTTON_BOOTSEL
|
#ifdef BUTTON_BOOTSEL
|
||||||
return BUTTON_STATE_ACTIVE == get_bootsel_button();
|
return BUTTON_STATE_ACTIVE == get_bootsel_button();
|
||||||
#else
|
#else
|
||||||
@ -189,12 +188,21 @@ uint32_t board_button_read(void)
|
|||||||
#endif
|
#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
|
#ifdef UART_DEV
|
||||||
int count = 0;
|
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);
|
buf[count] = uart_getc(uart_inst);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -205,11 +213,10 @@ int board_uart_read(uint8_t* buf, int len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
int board_uart_write(void const *buf, int len) {
|
||||||
{
|
|
||||||
#ifdef UART_DEV
|
#ifdef UART_DEV
|
||||||
char const* bufch = (char const*) buf;
|
char const *bufch = (char const *) buf;
|
||||||
for(int i=0;i<len;i++) {
|
for ( int i = 0; i < len; i++ ) {
|
||||||
uart_putc(uart_inst, bufch[i]);
|
uart_putc(uart_inst, bufch[i]);
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
@ -219,8 +226,7 @@ int board_uart_write(void const * buf, int len)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_getchar(void)
|
int board_getchar(void) {
|
||||||
{
|
|
||||||
return getchar_timeout_us(0);
|
return getchar_timeout_us(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@ target_sources(tinyusb_bsp INTERFACE
|
|||||||
target_include_directories(tinyusb_bsp INTERFACE
|
target_include_directories(tinyusb_bsp INTERFACE
|
||||||
${TOP}/hw
|
${TOP}/hw
|
||||||
)
|
)
|
||||||
|
target_link_libraries(tinyusb_bsp INTERFACE pico_unique_id)
|
||||||
|
|
||||||
# tinyusb_additions will hold our extra settings for examples
|
# tinyusb_additions will hold our extra settings for examples
|
||||||
add_library(tinyusb_additions INTERFACE)
|
add_library(tinyusb_additions INTERFACE)
|
||||||
|
@ -48,8 +48,7 @@ void USB_IRQHandler(void)
|
|||||||
|
|
||||||
UART_HandleTypeDef UartHandle;
|
UART_HandleTypeDef UartHandle;
|
||||||
|
|
||||||
void board_init(void)
|
void board_init(void) {
|
||||||
{
|
|
||||||
board_clock_init();
|
board_clock_init();
|
||||||
|
|
||||||
// Enable All GPIOs clocks
|
// Enable All GPIOs clocks
|
||||||
@ -177,51 +176,60 @@ void board_init(void)
|
|||||||
// Board porting API
|
// Board porting API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void board_led_write(bool state)
|
void board_led_write(bool state) {
|
||||||
{
|
GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||||
GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1-LED_STATE_ON));
|
|
||||||
HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state);
|
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);
|
return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
int board_uart_read(uint8_t* buf, int len)
|
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
|
||||||
{
|
(void) max_len;
|
||||||
(void) buf; (void) len;
|
volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE;
|
||||||
return 0;
|
|
||||||
}
|
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];
|
||||||
|
|
||||||
int board_uart_write(void const * buf, int len)
|
|
||||||
{
|
|
||||||
HAL_UART_Transmit(&UartHandle, (uint8_t*)(uintptr_t) buf, len, 0xffff);
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
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);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||||
volatile uint32_t system_ticks = 0;
|
volatile uint32_t system_ticks = 0;
|
||||||
void SysTick_Handler (void)
|
|
||||||
{
|
void SysTick_Handler(void) {
|
||||||
HAL_IncTick();
|
HAL_IncTick();
|
||||||
system_ticks++;
|
system_ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t board_millis(void)
|
uint32_t board_millis(void) {
|
||||||
{
|
|
||||||
return system_ticks;
|
return system_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void HardFault_Handler (void)
|
void HardFault_Handler(void) {
|
||||||
{
|
|
||||||
__asm("BKPT #0\n");
|
__asm("BKPT #0\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required by __libc_init_array in startup code if we are compiling using
|
// Required by __libc_init_array in startup code if we are compiling using
|
||||||
// -nostdlib/-nostartfiles.
|
// -nostdlib/-nostartfiles.
|
||||||
void _init(void)
|
void _init(void) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user