From e266176fb98dfecfc84f9bcf5a74ab9a9128b684 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Fri, 7 Jan 2022 11:35:24 -0300 Subject: [PATCH] Add Teensy, RP2040, megaAVR - duino-coin Code --- MCU.md | 14 +++- README.md | 4 +- library.properties | 2 +- src/ArduinoUniqueID.cpp | 139 +++++++++++++++++++++++++++++++--------- src/ArduinoUniqueID.h | 18 +++++- 5 files changed, 142 insertions(+), 35 deletions(-) diff --git a/MCU.md b/MCU.md index 07e7ca0..63ee1aa 100644 --- a/MCU.md +++ b/MCU.md @@ -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 @@ -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.
+To make the variable UniqueID8 to work probably the library uses the default bytes to 0x00.
| UniqueID8 | ESP8266 | ESP32 | | :-------: | :------: | :------:| @@ -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 \ No newline at end of file +* ESP32 - 6 bytes + +# Teensy + +Todo + +# Raspberry Pi Pico - RP2040 + +Todo \ No newline at end of file diff --git a/README.md b/README.md index f2d7bb8..d47912b 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/library.properties b/library.properties index e9af289..7863cf8 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ArduinoUniqueID -version=1.1.0 +version=1.2.0 author=Luiz Henrique Cassettari maintainer=Luiz Henrique Cassettari sentence=Arduino Library to gets the Manufacture Serial Number from the Atmel AVR, SAM, SAMD, STM32, and ESP Microcontroller. diff --git a/src/ArduinoUniqueID.cpp b/src/ArduinoUniqueID.cpp index 7989a45..57df363 100644 --- a/src/ArduinoUniqueID.cpp +++ b/src/ArduinoUniqueID.cpp @@ -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]; @@ -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]; @@ -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) @@ -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 } diff --git a/src/ArduinoUniqueID.h b/src/ArduinoUniqueID.h index 6f484c8..39f9b9e 100644 --- a/src/ArduinoUniqueID.h +++ b/src/ArduinoUniqueID.h @@ -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 +#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) @@ -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)