Support serial flash with 16 byte unique id (#1819)

* Support serial flash with 16 byte unique id

Flash devices like IS25LP016D have a 16 byte unique id. Reading just the
first 8 bytes causes devices to have duplicate unique ids as the numbers
only differ in the final 8 bytes.

Support overriding FLASH_UNIQUE_ID_SIZE_BYTES in the board header. Use
the final 8 bytes for the unique id.

Fixes #1641
This commit is contained in:
Peter Harper 2024-08-15 17:23:15 +01:00 committed by GitHub
parent a2642f93a4
commit e049f5063f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 14 additions and 4 deletions

View file

@ -19,7 +19,7 @@
// Standard RUID instruction: 4Bh command prefix, 32 dummy bits, 64 data bits.
#define FLASH_RUID_CMD 0x4b
#define FLASH_RUID_DUMMY_BYTES 4
#define FLASH_RUID_DATA_BYTES 8
#define FLASH_RUID_DATA_BYTES FLASH_UNIQUE_ID_SIZE_BYTES
#define FLASH_RUID_TOTAL_BYTES (1 + FLASH_RUID_DUMMY_BYTES + FLASH_RUID_DATA_BYTES)
//-----------------------------------------------------------------------------

View file

@ -46,7 +46,9 @@
#define FLASH_SECTOR_SIZE (1u << 12)
#define FLASH_BLOCK_SIZE (1u << 16)
#ifndef FLASH_UNIQUE_ID_SIZE_BYTES
#define FLASH_UNIQUE_ID_SIZE_BYTES 8
#endif
// PICO_CONFIG: PICO_FLASH_SIZE_BYTES, size of primary flash in bytes, type=int, default=Usually provided via board header, group=hardware_flash

View file

@ -20,7 +20,7 @@ extern "C" {
*
* RP2040 does not have an on-board unique identifier (all instances of RP2040
* silicon are identical and have no persistent state). However, RP2040 boots
* from serial NOR flash devices which have a 64-bit unique ID as a standard
* from serial NOR flash devices which have at least a 64-bit unique ID as a standard
* feature, and there is a 1:1 association between RP2040 and flash, so this
* is suitable for use as a unique identifier for an RP2040-based board.
*

View file

@ -8,7 +8,7 @@
#include "pico/bootrom.h"
#include "pico/unique_id.h"
static_assert(PICO_UNIQUE_BOARD_ID_SIZE_BYTES == FLASH_UNIQUE_ID_SIZE_BYTES, "Board ID size must match flash ID size");
static_assert(PICO_UNIQUE_BOARD_ID_SIZE_BYTES <= FLASH_UNIQUE_ID_SIZE_BYTES, "Board ID size must at least be the size of flash ID");
static pico_unique_board_id_t retrieved_id;
@ -20,8 +20,16 @@ static void __attribute__((constructor)) _retrieve_unique_id_on_boot(void) {
// debug, so just produce something well-defined and obviously wrong.
for (int i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++)
retrieved_id.id[i] = 0xee;
#else
#elif (PICO_UNIQUE_BOARD_ID_SIZE_BYTES == FLASH_UNIQUE_ID_SIZE_BYTES)
flash_get_unique_id(retrieved_id.id);
#elif (PICO_UNIQUE_BOARD_ID_SIZE_BYTES < FLASH_UNIQUE_ID_SIZE_BYTES)
// The flash ID is >8 bytes (e.g. IS25LP016D) but we want to keep the
// pico unique board ID as 8 bytes, just use the last 8 bytes which are likely to change
uint8_t flash_id[FLASH_UNIQUE_ID_SIZE_BYTES];
flash_get_unique_id(flash_id);
memcpy(retrieved_id.id, flash_id + FLASH_UNIQUE_ID_SIZE_BYTES - PICO_UNIQUE_BOARD_ID_SIZE_BYTES, PICO_UNIQUE_BOARD_ID_SIZE_BYTES);
#else
#error unique board ID size is greater than flash unique ID size
#endif
#else
rom_get_sys_info_fn func = (rom_get_sys_info_fn) rom_func_lookup(ROM_FUNC_GET_SYS_INFO);