Skip to content

Commit 237cfc7

Browse files
authored
Merge pull request #13 from ricaun/develop
Add Teensy, RP2040, megaAVR
2 parents 43c1558 + e266176 commit 237cfc7

File tree

5 files changed

+142
-35
lines changed

5 files changed

+142
-35
lines changed

MCU.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Apparently, the chip Atmega328p have a hidden serial number with 9 bytes, and ot
3030

3131
## Disclaimer
3232

33-
The `Atmega328p`, `Atmega2560`, `Attiny85` does not have a 'Serial Number' on the datasheet, this mean it's possivel to have two microcontroller with the same `UniqueId`.
33+
The `Atmega328p`, `Atmega2560`, `Attiny85` does not have a 'Serial Number' on the datasheet, this mean it's possible to have two microcontroller with the same `UniqueId`.
3434

3535
# Atmel SAM ARM Microcontroller
3636

@@ -89,7 +89,7 @@ ESP microcontroller has basically two versions, ESP8266 and ESP32, each one has
8989
| Byte 4| - | Byte 1 |
9090
| Byte 5| - | Byte 0 |
9191

92-
To make the variable UniqueID8 to work propably the library uses the default bytes to 0x00. <br/>
92+
To make the variable UniqueID8 to work probably the library uses the default bytes to 0x00. <br/>
9393

9494
| UniqueID8 | ESP8266 | ESP32 |
9595
| :-------: | :------: | :------:|
@@ -105,4 +105,12 @@ To make the variable UniqueID8 to work propably the library uses the default byt
105105
## Tested Microcontroller
106106

107107
* ESP8266 - 4 bytes
108-
* ESP32 - 6 bytes
108+
* ESP32 - 6 bytes
109+
110+
# Teensy
111+
112+
Todo
113+
114+
# Raspberry Pi Pico - RP2040
115+
116+
Todo

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ ArduinoUniqueID supports the [Microcontrollers](MCU.md).
1313
* Atmel SAMD ARM
1414
* STM32
1515
* Espressif ESP
16+
* Teensy
17+
* Raspberry Pi Pico - RP2040
1618

1719
# Installation
1820

1921
* Install the library by [Using the Library Manager](https://www.arduino.cc/en/Guide/Libraries#toc3)
20-
* **OR** by [Importing the .zip library](https://www.arduino.cc/en/Guide/Libraries#toc4) using either the [master](https://github.com/ricaun/ArduinoUniqueID/archive/1.0.9.zip) or one of the [releases](https://github.com/ricaun/ArduinoUniqueID/releases) ZIP files.
22+
* **OR** by [Importing the .zip library](https://www.arduino.cc/en/Guide/Libraries#toc4) using either the [master](https://github.com/ricaun/ArduinoUniqueID/archive/1.2.0.zip) or one of the [releases](https://github.com/ricaun/ArduinoUniqueID/releases) ZIP files.
2123

2224
## Examples
2325

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ArduinoUniqueID
2-
version=1.1.0
2+
version=1.2.0
33
author=Luiz Henrique Cassettari
44
maintainer=Luiz Henrique Cassettari <ricaun@gmail.com>
55
sentence=Arduino Library to gets the Manufacture Serial Number from the Atmel AVR, SAM, SAMD, STM32, and ESP Microcontroller.

src/ArduinoUniqueID.cpp

Lines changed: 110 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ ArduinoUniqueID::ArduinoUniqueID()
3333
id[7] = chipid >> 40;
3434

3535
#elif defined(ARDUINO_ARCH_SAM)
36-
unsigned int status ;
36+
unsigned int status;
3737
/* Send the Start Read unique Identifier command (STUI) by writing the Flash Command Register with the STUI command.*/
3838
EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI;
3939
do
4040
{
41-
status = EFC1->EEFC_FSR ;
42-
} while ( (status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY ) ;
41+
status = EFC1->EEFC_FSR;
42+
} while ((status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY);
4343

4444
/* The Unique Identifier is located in the first 128 bits of the Flash memory mapping. So, at the address 0x400000-0x400003. */
4545
uint32_t pdwUniqueID[4];
@@ -49,38 +49,38 @@ ArduinoUniqueID::ArduinoUniqueID()
4949
pdwUniqueID[3] = *(uint32_t *)(IFLASH1_ADDR + 12);
5050
for (int i = 0; i < 4; i++)
5151
{
52-
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
53-
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
54-
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
55-
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
52+
id[i * 4 + 0] = (uint8_t)(pdwUniqueID[i] >> 24);
53+
id[i * 4 + 1] = (uint8_t)(pdwUniqueID[i] >> 16);
54+
id[i * 4 + 2] = (uint8_t)(pdwUniqueID[i] >> 8);
55+
id[i * 4 + 3] = (uint8_t)(pdwUniqueID[i] >> 0);
5656
}
5757

5858
/* To stop the Unique Identifier mode, the user needs to send the Stop Read unique Identifier
5959
command (SPUI) by writing the Flash Command Register with the SPUI command. */
60-
EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI ;
60+
EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI;
6161

6262
/* When the Stop read Unique Unique Identifier command (SPUI) has been performed, the
6363
FRDY bit in the Flash Programming Status Register (EEFC_FSR) rises. */
6464
do
6565
{
66-
status = EFC1->EEFC_FSR ;
67-
} while ( (status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY );
66+
status = EFC1->EEFC_FSR;
67+
} while ((status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY);
6868

6969
#elif defined(ARDUINO_ARCH_SAMD)
7070

71-
#if defined (__SAMD51__)
72-
// SAMD51 from section 9.6 of the datasheet
73-
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x008061FC)
74-
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x00806010)
75-
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x00806014)
76-
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x00806018)
71+
#if defined(__SAMD51__)
72+
// SAMD51 from section 9.6 of the datasheet
73+
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t *)(0x008061FC)
74+
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t *)(0x00806010)
75+
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t *)(0x00806014)
76+
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t *)(0x00806018)
7777
#else
78-
//#elif defined (__SAMD21E17A__) || defined(__SAMD21G18A__) || defined(__SAMD21E18A__) || defined(__SAMD21J18A__)
78+
//#elif defined (__SAMD21E17A__) || defined(__SAMD21G18A__) || defined(__SAMD21E18A__) || defined(__SAMD21J18A__)
7979
// SAMD21 from section 9.3.3 of the datasheet
80-
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C)
81-
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040)
82-
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044)
83-
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048)
80+
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t *)(0x0080A00C)
81+
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t *)(0x0080A040)
82+
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t *)(0x0080A044)
83+
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t *)(0x0080A048)
8484
#endif
8585

8686
uint32_t pdwUniqueID[4];
@@ -91,10 +91,10 @@ ArduinoUniqueID::ArduinoUniqueID()
9191

9292
for (int i = 0; i < 4; i++)
9393
{
94-
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
95-
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
96-
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
97-
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
94+
id[i * 4 + 0] = (uint8_t)(pdwUniqueID[i] >> 24);
95+
id[i * 4 + 1] = (uint8_t)(pdwUniqueID[i] >> 16);
96+
id[i * 4 + 2] = (uint8_t)(pdwUniqueID[i] >> 8);
97+
id[i * 4 + 3] = (uint8_t)(pdwUniqueID[i] >> 0);
9898
}
9999

100100
#elif defined(ARDUINO_ARCH_STM32)
@@ -104,11 +104,92 @@ ArduinoUniqueID::ArduinoUniqueID()
104104
pdwUniqueID[2] = HAL_GetUIDw2();
105105
for (int i = 0; i < 3; i++)
106106
{
107-
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
108-
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
109-
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
110-
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
107+
id[i * 4 + 0] = (uint8_t)(pdwUniqueID[i] >> 24);
108+
id[i * 4 + 1] = (uint8_t)(pdwUniqueID[i] >> 16);
109+
id[i * 4 + 2] = (uint8_t)(pdwUniqueID[i] >> 8);
110+
id[i * 4 + 3] = (uint8_t)(pdwUniqueID[i] >> 0);
111111
}
112+
113+
// Teensy, RP2040 and megaAVR code from:
114+
// https://github.com/revoxhere/duino-coin/blob/master/Arduino_Code/uniqueID.cpp
115+
#elif defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41)
116+
uint32_t uid0 = HW_OCOTP_CFG0;
117+
uint32_t uid1 = HW_OCOTP_CFG1;
118+
id[0] = uid0 >> 24;
119+
id[1] = uid0 >> 16;
120+
id[2] = uid0 >> 8;
121+
id[3] = uid0;
122+
id[4] = uid1 >> 24;
123+
id[5] = uid1 >> 16;
124+
id[6] = uid1 >> 8;
125+
id[7] = uid1;
126+
127+
#elif defined(TEENSYDUINO)
128+
uint8_t mac[6];
129+
uint8_t sn[4];
130+
uint32_t num = 0;
131+
__disable_irq();
132+
#if defined(HAS_KINETIS_FLASH_FTFA) || defined(HAS_KINETIS_FLASH_FTFL)
133+
FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL;
134+
FTFL_FCCOB0 = 0x41;
135+
FTFL_FCCOB1 = 15;
136+
FTFL_FSTAT = FTFL_FSTAT_CCIF;
137+
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF))
138+
; // wait
139+
num = *(uint32_t *)&FTFL_FCCOB7;
140+
#elif defined(HAS_KINETIS_FLASH_FTFE)
141+
kinetis_hsrun_disable();
142+
FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL;
143+
*(uint32_t *)&FTFL_FCCOB3 = 0x41070000;
144+
FTFL_FSTAT = FTFL_FSTAT_CCIF;
145+
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF))
146+
; // wait
147+
num = *(uint32_t *)&FTFL_FCCOBB;
148+
kinetis_hsrun_enable();
149+
#endif
150+
__enable_irq();
151+
sn[0] = num >> 24;
152+
sn[1] = num >> 16;
153+
sn[2] = num >> 8;
154+
sn[3] = num;
155+
mac[0] = 0x04;
156+
mac[1] = 0xE9;
157+
mac[2] = 0xE5;
158+
mac[3] = sn[1];
159+
mac[4] = sn[2];
160+
mac[5] = sn[3];
161+
id[0] = SIM_UIDML >> 24;
162+
id[1] = SIM_UIDML >> 16;
163+
id[2] = SIM_UIDML >> 8;
164+
id[3] = SIM_UIDML;
165+
id[4] = SIM_UIDL >> 24;
166+
id[5] = SIM_UIDL >> 16;
167+
id[6] = 0x40; // marked as version v4, but this uuid is not random based !!!
168+
id[7] = SIM_UIDL >> 8;
169+
id[8] = 0x80; //variant
170+
id[9] = SIM_UIDL;
171+
id[10] = mac[0];
172+
id[11] = mac[1];
173+
id[12] = mac[2];
174+
id[13] = mac[3];
175+
id[14] = mac[4];
176+
id[15] = mac[5];
177+
178+
#elif defined(ARDUINO_ARCH_MBED_RP2040)
179+
getUniqueSerialNumber(id);
180+
181+
#elif defined(ARDUINO_ARCH_MEGAAVR)
182+
id[0] = SIGROW.SERNUM0;
183+
id[1] = SIGROW.SERNUM1;
184+
id[2] = SIGROW.SERNUM2;
185+
id[3] = SIGROW.SERNUM3;
186+
id[4] = SIGROW.SERNUM4;
187+
id[5] = SIGROW.SERNUM5;
188+
id[6] = SIGROW.SERNUM6;
189+
id[7] = SIGROW.SERNUM7;
190+
id[8] = SIGROW.SERNUM8;
191+
id[9] = SIGROW.SERNUM9;
192+
112193
#endif
113194
}
114195

src/ArduinoUniqueID.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
#elif defined(ARDUINO_ARCH_SAM)
1717
#elif defined(ARDUINO_ARCH_SAMD)
1818
#elif defined(ARDUINO_ARCH_STM32)
19+
#elif defined(TEENSYDUINO)
20+
#elif defined(ARDUINO_ARCH_MBED_RP2040)
21+
//#include <pico/unique_id.h>
22+
#elif defined(ARDUINO_ARCH_MEGAAVR)
1923
#else
20-
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32 and ESP Architecture"
24+
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32, Teensy, RP2040, megaAVR and ESP Architecture"
2125
#endif
2226

2327
#if defined(ARDUINO_ARCH_AVR)
@@ -45,6 +49,18 @@
4549
#elif defined(ARDUINO_ARCH_STM32)
4650
#define UniqueIDsize 12
4751
#define UniqueIDbuffer 12
52+
#elif defined(ARDUINO_TEENSY40) || defined (ARDUINO_TEENSY41)
53+
#define UniqueIDsize 8
54+
#define UniqueIDbuffer 8
55+
#elif defined(TEENSYDUINO)
56+
#define UniqueIDsize 16
57+
#define UniqueIDbuffer 16
58+
#elif defined(ARDUINO_ARCH_MBED_RP2040)
59+
#define UniqueIDsize 32
60+
#define UniqueIDbuffer 32
61+
#elif defined(ARDUINO_ARCH_MEGAAVR)
62+
#define UniqueIDsize 10
63+
#define UniqueIDbuffer 10
4864
#endif
4965

5066
#define UniqueID8 (_UniqueID.id + UniqueIDbuffer - 8)

0 commit comments

Comments
 (0)