diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index 645725237b..82ed6cc549 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -89,10 +89,6 @@ #define MACHINE_NAME DEFAULT_MACHINE_NAME #endif -#ifndef MACHINE_UUID - #define MACHINE_UUID DEFAULT_MACHINE_UUID -#endif - #define MARLIN_WEBSITE_URL "marlinfw.org" //#if !defined(STRING_SPLASH_LINE3) && defined(WEBSITE_URL) diff --git a/Marlin/src/gcode/host/M115.cpp b/Marlin/src/gcode/host/M115.cpp index d1571d58ac..cd2bcb0f94 100644 --- a/Marlin/src/gcode/host/M115.cpp +++ b/Marlin/src/gcode/host/M115.cpp @@ -35,7 +35,7 @@ #include "../../feature/caselight.h" #endif -#if ENABLED(HAS_STM32_UID) && !defined(MACHINE_UUID) +#if !defined(MACHINE_UUID) && HAS_STM32_UID #include "../../libs/hex_print.h" #endif @@ -62,6 +62,7 @@ * at https://reprap.org/wiki/Firmware_Capabilities_Protocol */ void GcodeSuite::M115() { + SERIAL_ECHOPGM("FIRMWARE_NAME:Marlin" " " DETAILED_BUILD_VERSION " (" __DATE__ " " __TIME__ ")" " SOURCE_CODE_URL:" SOURCE_CODE_URL @@ -71,24 +72,31 @@ void GcodeSuite::M115() { #if NUM_AXES != XYZ " AXIS_COUNT:" STRINGIFY(NUM_AXES) #endif + #if defined(MACHINE_UUID) || HAS_STM32_UID + " UUID:" + #endif #ifdef MACHINE_UUID - " UUID:" MACHINE_UUID + MACHINE_UUID #endif ); - // STM32UID:111122223333 - #if ENABLED(HAS_STM32_UID) && !defined(MACHINE_UUID) - // STM32 based devices output the CPU device serial number - // Used by LumenPnP / OpenPNP to keep track of unique hardware/configurations - // https://github.com/opulo-inc/lumenpnp - // Although this code should work on all STM32 based boards - SERIAL_ECHOPGM(" UUID:"); - uint32_t *uid_address = (uint32_t*)UID_BASE; - for (uint8_t i = 0; i < 3; ++i) { - const uint32_t UID = uint32_t(READ_REG(*(uid_address))); - uid_address += 4U; - for (int B = 24; B >= 0; B -= 8) print_hex_byte(UID >> B); - } + #if !defined(MACHINE_UUID) && HAS_STM32_UID + /** + * STM32-based devices have a 96-bit CPU device serial number. + * Used by LumenPnP / OpenPNP to keep track of unique hardware/configurations. + * https://github.com/opulo-inc/lumenpnp + * This code should work on all STM32-based boards. + */ + #if ENABLED(STM32_UID_SHORT_FORM) + uint32_t * const UID = (uint32_t*)UID_BASE; + SERIAL_ECHO(hex_long(UID[0]), hex_long(UID[1]), hex_long(UID[2])); + #else + uint16_t * const UID = (uint16_t*)UID_BASE; + SERIAL_ECHO( + F("CEDE2A2F-"), hex_word(UID[0]), '-', hex_word(UID[1]), '-', hex_word(UID[2]), '-', + hex_word(UID[3]), hex_word(UID[4]), hex_word(UID[5]) + ); + #endif #endif SERIAL_EOL(); diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 20b357c9e3..9f182a108d 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -1243,11 +1243,6 @@ #define NO_EEPROM_SELECTED 1 #endif -// Flag whether hex_print.cpp is used -#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT) - #define NEED_HEX_PRINT 1 -#endif - // Flags for Case Light having a color property or a single pin #if ENABLED(CASE_LIGHT_ENABLE) #if ANY(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED) diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 076b1301d5..a344d6183d 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -3417,3 +3417,15 @@ FIL_RUNOUT5_PULLDOWN, FIL_RUNOUT6_PULLDOWN, FIL_RUNOUT7_PULLDOWN, FIL_RUNOUT8_PULLDOWN) #define USING_PULLDOWNS 1 #endif + +// Machine UUID can come from STM32 CPU Serial Number +#ifdef MACHINE_UUID + #undef HAS_STM32_UID +#elif !HAS_STM32_UID && defined(DEFAULT_MACHINE_UUID) + #define MACHINE_UUID DEFAULT_MACHINE_UUID +#endif + +// Flag whether hex_print.cpp is needed +#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT, HAS_STM32_UID) + #define NEED_HEX_PRINT 1 +#endif diff --git a/Marlin/src/libs/hex_print.cpp b/Marlin/src/libs/hex_print.cpp index 1958084abb..b9edc38c77 100644 --- a/Marlin/src/libs/hex_print.cpp +++ b/Marlin/src/libs/hex_print.cpp @@ -20,7 +20,7 @@ * */ -#include "../inc/MarlinConfigPre.h" +#include "../inc/MarlinConfig.h" #if NEED_HEX_PRINT @@ -41,28 +41,26 @@ char* hex_byte(const uint8_t b) { return &_hex[byte_start + 4]; } -inline void _hex_word(const uint16_t w) { +inline void __hex_word(const uint16_t w) { _hex[byte_start + 2] = hex_nybble(w >> 12); _hex[byte_start + 3] = hex_nybble(w >> 8); _hex[byte_start + 4] = hex_nybble(w >> 4); _hex[byte_start + 5] = hex_nybble(w); } -char* hex_word(const uint16_t w) { - _hex_word(w); +char* _hex_word(const uint16_t w) { + __hex_word(w); return &_hex[byte_start + 2]; } -#ifdef CPU_32_BIT - char* hex_long(const uintptr_t l) { - _hex[2] = hex_nybble(l >> 28); - _hex[3] = hex_nybble(l >> 24); - _hex[4] = hex_nybble(l >> 20); - _hex[5] = hex_nybble(l >> 16); - _hex_word((uint16_t)(l & 0xFFFF)); - return &_hex[2]; - } -#endif +char* _hex_long(const uintptr_t l) { + _hex[2] = hex_nybble(l >> 28); + _hex[3] = hex_nybble(l >> 24); + _hex[4] = hex_nybble(l >> 20); + _hex[5] = hex_nybble(l >> 16); + __hex_word((uint16_t)(l & 0xFFFF)); + return &_hex[2]; +} char* hex_address(const void * const w) { #ifdef CPU_32_BIT @@ -78,11 +76,11 @@ void print_hex_byte(const uint8_t b) { SERIAL_ECHO(hex_byte(b)); } void print_hex_word(const uint16_t w) { SERIAL_ECHO(hex_word(w)); } void print_hex_address(const void * const w) { SERIAL_ECHO(hex_address(w)); } -void print_hex_long(const uint32_t w, const char delimiter) { +void print_hex_long(const uint32_t w, const char delimiter/*='\0'*/) { SERIAL_ECHOPGM("0x"); for (int B = 24; B >= 8; B -= 8) { print_hex_byte(w >> B); - SERIAL_CHAR(delimiter); + if (delimiter) SERIAL_CHAR(delimiter); } print_hex_byte(w); } diff --git a/Marlin/src/libs/hex_print.h b/Marlin/src/libs/hex_print.h index 0baae15bd3..2278ec2c24 100644 --- a/Marlin/src/libs/hex_print.h +++ b/Marlin/src/libs/hex_print.h @@ -31,11 +31,15 @@ constexpr char hex_nybble(const uint8_t n) { return (n & 0xF) + ((n & 0xF) < 10 ? '0' : 'A' - 10); } char* hex_byte(const uint8_t b); -char* hex_word(const uint16_t w); +char* _hex_word(const uint16_t w); char* hex_address(const void * const w); +char* _hex_long(const uintptr_t l); + +template char* hex_word(T w) { return hex_word((uint16_t)w); } +template char* hex_long(T w) { return hex_long((uint32_t)w); } void print_hex_nybble(const uint8_t n); void print_hex_byte(const uint8_t b); void print_hex_word(const uint16_t w); void print_hex_address(const void * const w); -void print_hex_long(const uint32_t w, const char delimiter); +void print_hex_long(const uint32_t w, const char delimiter='\0'); diff --git a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h index 5802c07241..dc907cd5b7 100644 --- a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h +++ b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV3.h @@ -44,8 +44,10 @@ // I2C MCP3426 (16-Bit, 240SPS, dual-channel ADC) #define HAS_MCP3426_ADC + +// Opulo Lumen uses the CPU serial number #ifdef STM32F4 - #define HAS_STM32_UID + #define HAS_STM32_UID 1 #endif // diff --git a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h index 1697cf000e..3c59f521d5 100644 --- a/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h +++ b/Marlin/src/pins/stm32f4/pins_OPULO_LUMEN_REV4.h @@ -45,6 +45,11 @@ // I2C MCP3426 (16-Bit, 240SPS, dual-channel ADC) #define HAS_MCP3426_ADC +// Opulo Lumen uses the CPU serial number +#ifdef STM32F4 + #define HAS_STM32_UID 1 +#endif + // // Servos // diff --git a/buildroot/tests/Opulo_Lumen_REV3 b/buildroot/tests/Opulo_Lumen_REV3 index ddd8e1f3c9..f12f69011e 100755 --- a/buildroot/tests/Opulo_Lumen_REV3 +++ b/buildroot/tests/Opulo_Lumen_REV3 @@ -7,6 +7,7 @@ set -e use_example_configs Opulo/Lumen_REV3 +opt_disable TMC_DEBUG exec_test $1 $2 "Opulo Lumen REV3 Pick-and-Place" "$3" # cleanup