Skip to content

Commit

Permalink
Merge pull request #13 from ricaun/develop
Browse files Browse the repository at this point in the history
Add Teensy, RP2040, megaAVR
  • Loading branch information
ricaun authored Jan 7, 2022
2 parents 43c1558 + e266176 commit 237cfc7
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 35 deletions.
14 changes: 11 additions & 3 deletions MCU.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Apparently, the chip Atmega328p have a hidden serial number with 9 bytes, and ot

## Disclaimer

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`.
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`.

# Atmel SAM ARM Microcontroller

Expand Down Expand Up @@ -89,7 +89,7 @@ ESP microcontroller has basically two versions, ESP8266 and ESP32, each one has
| Byte 4| - | Byte 1 |
| Byte 5| - | Byte 0 |

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

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

* ESP8266 - 4 bytes
* ESP32 - 6 bytes
* ESP32 - 6 bytes

# Teensy

Todo

# Raspberry Pi Pico - RP2040

Todo
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ ArduinoUniqueID supports the [Microcontrollers](MCU.md).
* Atmel SAMD ARM
* STM32
* Espressif ESP
* Teensy
* Raspberry Pi Pico - RP2040

# Installation

* Install the library by [Using the Library Manager](https://www.arduino.cc/en/Guide/Libraries#toc3)
* **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.
* **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.

## Examples

Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ArduinoUniqueID
version=1.1.0
version=1.2.0
author=Luiz Henrique Cassettari
maintainer=Luiz Henrique Cassettari <[email protected]>
sentence=Arduino Library to gets the Manufacture Serial Number from the Atmel AVR, SAM, SAMD, STM32, and ESP Microcontroller.
Expand Down
139 changes: 110 additions & 29 deletions src/ArduinoUniqueID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ ArduinoUniqueID::ArduinoUniqueID()
id[7] = chipid >> 40;

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

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

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

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

#elif defined(ARDUINO_ARCH_SAMD)

#if defined (__SAMD51__)
// SAMD51 from section 9.6 of the datasheet
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x008061FC)
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x00806010)
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x00806014)
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x00806018)
#if defined(__SAMD51__)
// SAMD51 from section 9.6 of the datasheet
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t *)(0x008061FC)
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t *)(0x00806010)
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t *)(0x00806014)
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t *)(0x00806018)
#else
//#elif defined (__SAMD21E17A__) || defined(__SAMD21G18A__) || defined(__SAMD21E18A__) || defined(__SAMD21J18A__)
//#elif defined (__SAMD21E17A__) || defined(__SAMD21G18A__) || defined(__SAMD21E18A__) || defined(__SAMD21J18A__)
// SAMD21 from section 9.3.3 of the datasheet
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C)
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040)
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044)
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048)
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t *)(0x0080A00C)
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t *)(0x0080A040)
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t *)(0x0080A044)
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t *)(0x0080A048)
#endif

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

for (int i = 0; i < 4; i++)
{
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
id[i * 4 + 0] = (uint8_t)(pdwUniqueID[i] >> 24);
id[i * 4 + 1] = (uint8_t)(pdwUniqueID[i] >> 16);
id[i * 4 + 2] = (uint8_t)(pdwUniqueID[i] >> 8);
id[i * 4 + 3] = (uint8_t)(pdwUniqueID[i] >> 0);
}

#elif defined(ARDUINO_ARCH_STM32)
Expand All @@ -104,11 +104,92 @@ ArduinoUniqueID::ArduinoUniqueID()
pdwUniqueID[2] = HAL_GetUIDw2();
for (int i = 0; i < 3; i++)
{
id[i*4+0] = (uint8_t)(pdwUniqueID[i] >> 24);
id[i*4+1] = (uint8_t)(pdwUniqueID[i] >> 16);
id[i*4+2] = (uint8_t)(pdwUniqueID[i] >> 8);
id[i*4+3] = (uint8_t)(pdwUniqueID[i] >> 0);
id[i * 4 + 0] = (uint8_t)(pdwUniqueID[i] >> 24);
id[i * 4 + 1] = (uint8_t)(pdwUniqueID[i] >> 16);
id[i * 4 + 2] = (uint8_t)(pdwUniqueID[i] >> 8);
id[i * 4 + 3] = (uint8_t)(pdwUniqueID[i] >> 0);
}

// Teensy, RP2040 and megaAVR code from:
// https://github.com/revoxhere/duino-coin/blob/master/Arduino_Code/uniqueID.cpp
#elif defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41)
uint32_t uid0 = HW_OCOTP_CFG0;
uint32_t uid1 = HW_OCOTP_CFG1;
id[0] = uid0 >> 24;
id[1] = uid0 >> 16;
id[2] = uid0 >> 8;
id[3] = uid0;
id[4] = uid1 >> 24;
id[5] = uid1 >> 16;
id[6] = uid1 >> 8;
id[7] = uid1;

#elif defined(TEENSYDUINO)
uint8_t mac[6];
uint8_t sn[4];
uint32_t num = 0;
__disable_irq();
#if defined(HAS_KINETIS_FLASH_FTFA) || defined(HAS_KINETIS_FLASH_FTFL)
FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL;
FTFL_FCCOB0 = 0x41;
FTFL_FCCOB1 = 15;
FTFL_FSTAT = FTFL_FSTAT_CCIF;
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF))
; // wait
num = *(uint32_t *)&FTFL_FCCOB7;
#elif defined(HAS_KINETIS_FLASH_FTFE)
kinetis_hsrun_disable();
FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL;
*(uint32_t *)&FTFL_FCCOB3 = 0x41070000;
FTFL_FSTAT = FTFL_FSTAT_CCIF;
while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF))
; // wait
num = *(uint32_t *)&FTFL_FCCOBB;
kinetis_hsrun_enable();
#endif
__enable_irq();
sn[0] = num >> 24;
sn[1] = num >> 16;
sn[2] = num >> 8;
sn[3] = num;
mac[0] = 0x04;
mac[1] = 0xE9;
mac[2] = 0xE5;
mac[3] = sn[1];
mac[4] = sn[2];
mac[5] = sn[3];
id[0] = SIM_UIDML >> 24;
id[1] = SIM_UIDML >> 16;
id[2] = SIM_UIDML >> 8;
id[3] = SIM_UIDML;
id[4] = SIM_UIDL >> 24;
id[5] = SIM_UIDL >> 16;
id[6] = 0x40; // marked as version v4, but this uuid is not random based !!!
id[7] = SIM_UIDL >> 8;
id[8] = 0x80; //variant
id[9] = SIM_UIDL;
id[10] = mac[0];
id[11] = mac[1];
id[12] = mac[2];
id[13] = mac[3];
id[14] = mac[4];
id[15] = mac[5];

#elif defined(ARDUINO_ARCH_MBED_RP2040)
getUniqueSerialNumber(id);

#elif defined(ARDUINO_ARCH_MEGAAVR)
id[0] = SIGROW.SERNUM0;
id[1] = SIGROW.SERNUM1;
id[2] = SIGROW.SERNUM2;
id[3] = SIGROW.SERNUM3;
id[4] = SIGROW.SERNUM4;
id[5] = SIGROW.SERNUM5;
id[6] = SIGROW.SERNUM6;
id[7] = SIGROW.SERNUM7;
id[8] = SIGROW.SERNUM8;
id[9] = SIGROW.SERNUM9;

#endif
}

Expand Down
18 changes: 17 additions & 1 deletion src/ArduinoUniqueID.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
#elif defined(ARDUINO_ARCH_SAM)
#elif defined(ARDUINO_ARCH_SAMD)
#elif defined(ARDUINO_ARCH_STM32)
#elif defined(TEENSYDUINO)
#elif defined(ARDUINO_ARCH_MBED_RP2040)
//#include <pico/unique_id.h>
#elif defined(ARDUINO_ARCH_MEGAAVR)
#else
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32 and ESP Architecture"
#error "ArduinoUniqueID only works on AVR, SAM, SAMD, STM32, Teensy, RP2040, megaAVR and ESP Architecture"
#endif

#if defined(ARDUINO_ARCH_AVR)
Expand Down Expand Up @@ -45,6 +49,18 @@
#elif defined(ARDUINO_ARCH_STM32)
#define UniqueIDsize 12
#define UniqueIDbuffer 12
#elif defined(ARDUINO_TEENSY40) || defined (ARDUINO_TEENSY41)
#define UniqueIDsize 8
#define UniqueIDbuffer 8
#elif defined(TEENSYDUINO)
#define UniqueIDsize 16
#define UniqueIDbuffer 16
#elif defined(ARDUINO_ARCH_MBED_RP2040)
#define UniqueIDsize 32
#define UniqueIDbuffer 32
#elif defined(ARDUINO_ARCH_MEGAAVR)
#define UniqueIDsize 10
#define UniqueIDbuffer 10
#endif

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

0 comments on commit 237cfc7

Please sign in to comment.