1 /*
2  * Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _PICO_UNIQUE_ID_H
8 #define _PICO_UNIQUE_ID_H
9 
10 #include "pico.h"
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /** \file pico/unique_id.h
17  *  \defgroup pico_unique_id pico_unique_id
18  *
19  * \brief Unique device ID access API
20  *
21  * \if rp2040_specific
22  * RP2040 does not have an on-board unique identifier (all instances of RP2040
23  * silicon are identical and have no persistent state). However, RP2040 boots
24  * from serial NOR flash devices which have at least a 64-bit unique ID as a standard
25  * feature, and there is a 1:1 association between RP2040 and flash, so this
26  * is suitable for use as a unique identifier for an RP2040-based board.
27  *
28  * This library injects a call to the flash_get_unique_id function from the
29  * hardware_flash library, to run before main, and stores the result in a
30  * static location which can safely be accessed at any time via
31  * pico_get_unique_id().
32  *
33  * This avoids some pitfalls of the hardware_flash API, which requires any
34  * flash-resident interrupt routines to be disabled when called into.
35  * \endif
36  *
37  * \if rp2350_specific
38  * On boards using RP2350, the unique identifier is read from OTP memory on boot.
39  * \endif
40  */
41 
42 #define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8
43 
44 /**
45  * \brief Unique board identifier
46  * \ingroup pico_unique_id
47  *
48  * This structure contains an array of PICO_UNIQUE_BOARD_ID_SIZE_BYTES identifier bytes suitable for
49  * holding the unique identifier for the device.
50  *
51  * \if rp2040_specific
52  * On an RP2040-based board, the unique identifier is retrieved from the external NOR flash device at boot,
53  * or for PICO_NO_FLASH builds the unique identifier is set to all 0xEE.
54  * \endif
55  *
56  * \if rp2350_specific
57  * On an RP2350-based board, the unique identifier is retrieved from OTP memory at boot.
58  * \endif
59  *
60  */
61 typedef struct {
62 	uint8_t id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES];
63 } pico_unique_board_id_t;
64 
65 /*! \brief Get unique ID
66  *  \ingroup pico_unique_id
67  *
68  * Get the unique 64-bit device identifier.
69  *
70  * \if rp2040_specific
71  * On an RP2040-based board, the unique identifier is retrieved from the external NOR flash device at boot,
72  * or for PICO_NO_FLASH builds the unique identifier is set to all 0xEE.
73  * \endif
74  *
75  * \if rp2350_specific
76  * On an RP2350-based board, the unique identifier is retrieved from OTP memory at boot.
77  * \endif
78  *
79  * \param id_out a pointer to a pico_unique_board_id_t struct, to which the identifier will be written
80  */
81 void pico_get_unique_board_id(pico_unique_board_id_t *id_out);
82 
83 /*! \brief Get unique ID in string format
84  *  \ingroup pico_unique_id
85  *
86  * Get the unique 64-bit device identifier formatted as a 0-terminated ASCII hex string.
87  *
88  * \if rp2040_specific
89  * On an RP2040-based board, the unique identifier is retrieved from the external NOR flash device at boot,
90  * or for PICO_NO_FLASH builds the unique identifier is set to all 0xEE.
91  * \endif
92  *
93  * \if rp2350_specific
94  * On an RP2350-based board, the unique identifier is retrieved from OTP memory at boot.
95  * \endif
96  *
97  * \param id_out a pointer to a char buffer of size len, to which the identifier will be written
98  * \param len the size of id_out. For full serial, len >= 2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1
99  */
100 void pico_get_unique_board_id_string(char *id_out, uint len);
101 
102 
103 #ifdef __cplusplus
104 }
105 #endif
106 
107 #endif
108