Skip to content

Commit

Permalink
Support serial flash with 16 byte unique id
Browse files Browse the repository at this point in the history
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 raspberrypi#1641
  • Loading branch information
peterharperuk committed Aug 14, 2024
1 parent f4a691a commit 16d4011
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/rp2_common/hardware_flash/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

//-----------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/rp2_common/hardware_flash/include/hardware/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/rp2_common/pico_unique_id/include/pico/unique_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
12 changes: 10 additions & 2 deletions src/rp2_common/pico_unique_id/unique_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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. IS25WP016D) 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);
Expand Down

0 comments on commit 16d4011

Please sign in to comment.