mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-16 05:42:56 +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
@ -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,14 +264,19 @@ 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)
|
||||
{
|
||||
switch(index) {
|
||||
case STRID_LANGID:
|
||||
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||
chr_count = 1;
|
||||
}else
|
||||
{
|
||||
break;
|
||||
|
||||
case STRID_SERIAL:
|
||||
chr_count = board_usb_get_serial(_desc_str+1, 32);
|
||||
break;
|
||||
|
||||
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
|
||||
|
||||
@ -271,14 +285,14 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||
const char* str = string_desc_arr[index];
|
||||
|
||||
// Cap at max char
|
||||
chr_count = (uint8_t) strlen(str);
|
||||
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++)
|
||||
{
|
||||
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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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,8 +172,7 @@ void board_init(void)
|
||||
// Board porting API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void board_led_write(bool state)
|
||||
{
|
||||
void board_led_write(bool state) {
|
||||
(void) state;
|
||||
|
||||
#ifdef LED_PIN
|
||||
@ -180,8 +180,7 @@ void board_led_write(bool state)
|
||||
#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,8 +213,7 @@ 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++ ) {
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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) {
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user