diff --git a/_Boards/RaspberryPi/Pico/MFBoards.h b/_Boards/RaspberryPi/Pico/MFBoards.h new file mode 100644 index 00000000..211cb266 --- /dev/null +++ b/_Boards/RaspberryPi/Pico/MFBoards.h @@ -0,0 +1,57 @@ +#ifndef MFBoardMicro_h +#define MFBoardMicro_h + +#ifndef MF_SEGMENT_SUPPORT +#define MF_SEGMENT_SUPPORT 1 +#endif +#ifndef MF_LCD_SUPPORT +#define MF_LCD_SUPPORT 1 +#endif +#ifndef MF_STEPPER_SUPPORT +#define MF_STEPPER_SUPPORT 1 +#endif +#ifndef MF_SERVO_SUPPORT +#define MF_SERVO_SUPPORT 1 +#endif +#ifndef MF_ANALOG_SUPPORT +#define MF_ANALOG_SUPPORT 1 +#endif +#ifndef MF_OUTPUT_SHIFTER_SUPPORT +#define MF_OUTPUT_SHIFTER_SUPPORT 1 +#endif +#ifndef MF_INPUT_SHIFTER_SUPPORT +#define MF_INPUT_SHIFTER_SUPPORT 1 +#endif +#ifndef MF_MUX_SUPPORT +#define MF_MUX_SUPPORT 1 +#endif +#ifndef MF_DIGIN_MUX_SUPPORT +#define MF_MUX_SUPPORT 1 +#define MF_DIGIN_MUX_SUPPORT 1 +#endif + +#define MAX_OUTPUTS 26 +#define MAX_BUTTONS 26 +#define MAX_LEDSEGMENTS 4 +#define MAX_ENCODERS 8 +#define MAX_STEPPERS 6 +#define MAX_MFSERVOS 8 +#define MAX_MFLCD_I2C 2 +#define MAX_ANALOG_INPUTS 3 +#define MAX_OUTPUT_SHIFTERS 4 +#define MAX_INPUT_SHIFTERS 4 +#define MAX_DIGIN_MUX 4 + +#define STEPS 64 +#define STEPPER_SPEED 400 // 300 already worked, 467, too? +#define STEPPER_ACCEL 800 + +#define MOBIFLIGHT_TYPE "MobiFlight RaspiPico" +#define MOBIFLIGHT_SERIAL "0987654321" +#define MOBIFLIGHT_NAME "MobiFlight RaspiPico" +#define EEPROM_SIZE 4096 // EEPROMSizeRaspberryPico +#define MEMLEN_CONFIG 1496 // MUST be less than EEPROM_SIZE!! MEM_OFFSET_CONFIG + MEM_LEN_CONFIG <= EEPROM_SIZE, see: eeprom_write_block (MEM_OFFSET_CONFIG, configBuffer, MEM_LEN_CONFIG); +#define MEMLEN_NAMES_BUFFER 1000 // max. size for configBuffer, contains only names from inputs +#define MF_MAX_DEVICEMEM 2000 // max. memory size for devices + +#endif diff --git a/platformio.ini b/platformio.ini index 386fa913..f975a3b8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,11 +19,13 @@ ; Common build settings across all devices [env] lib_deps = - arduino-libraries/Servo @ 1.1.8 https://github.com/MobiFlight/LedControl#1.1.0 waspinator/AccelStepper @ 1.61 https://github.com/MobiFlight/LiquidCrystal_I2C#v1.1.4 https://github.com/MobiFlight/Arduino-CmdMessenger#4.2.1 + ricaun/ArduinoUniqueID @ ^1.3.0 +lib_deps_Atmel = + arduino-libraries/Servo @ 1.1.8 build_flags = -DMF_REDUCE_FUNCT_LEDCONTROL -DMAXCALLBACKS=30 @@ -61,7 +63,8 @@ build_src_filter = ${env.build_src_filter} +<../_Boards/Atmel> lib_deps = - ${env.lib_deps} + ${env.lib_deps} + ${env.lib_deps_Atmel} monitor_speed = 115200 extra_scripts = ${env.extra_scripts} @@ -78,7 +81,8 @@ build_src_filter = ${env.build_src_filter} +<../_Boards/Atmel> lib_deps = - ${env.lib_deps} + ${env.lib_deps} + ${env.lib_deps_Atmel} monitor_speed = 115200 extra_scripts = ${env.extra_scripts} @@ -96,7 +100,8 @@ build_src_filter = ${env.build_src_filter} +<../_Boards/Atmel> lib_deps = - ${env.lib_deps} + ${env.lib_deps} + ${env.lib_deps_Atmel} monitor_speed = 115200 extra_scripts = ${env.extra_scripts} @@ -112,7 +117,32 @@ build_flags = build_src_filter = ${env.build_src_filter} +<../_Boards/Atmel> -lib_deps = +lib_deps = + ${env.lib_deps} + ${env.lib_deps_Atmel} +monitor_speed = 115200 +extra_scripts = + ${env.extra_scripts} + +; Build settings for the Raspberry Pico original +[env:raspberrypico] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git +board = pico +framework = arduino +board_build.core = earlephilhower ; select new core +board_build.filesystem_size = 0M ; configure filesystem size. Default 0 Mbyte. +lib_ldf_mode = chain+ +upload_protocol = mbed ; for debugging upoading can be changed to picoprobe +;debug_tool = picoprobe ; and uncomment this for debugging w/ picoprobe +build_flags = + ${env.build_flags} + -DUSE_INTERRUPT + -I./_Boards/RaspberryPi/Pico + -fpermissive +build_src_filter = + ${env.build_src_filter} + +<../_Boards/RaspberryPi> +lib_deps = ${env.lib_deps} monitor_speed = 115200 extra_scripts = diff --git a/src/Config.cpp b/src/Config.cpp index f20e1d18..7ad59439 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -6,11 +6,10 @@ #include "mobiflight.h" #include "MFEEPROM.h" - #include "Button.h" #include "Encoder.h" #include "Output.h" - +#include "ArduinoUniqueID.h" #if MF_ANALOG_SUPPORT == 1 #include "Analog.h" #endif @@ -54,8 +53,15 @@ const uint8_t MEM_LEN_NAME = 48; const uint8_t MEM_OFFSET_SERIAL = MEM_OFFSET_NAME + MEM_LEN_NAME; const uint8_t MEM_LEN_SERIAL = 11; const uint8_t MEM_OFFSET_CONFIG = MEM_OFFSET_NAME + MEM_LEN_NAME + MEM_LEN_SERIAL; - +#if defined(ARDUINO_ARCH_AVR) char serial[MEM_LEN_SERIAL] = MOBIFLIGHT_SERIAL; +#elif defined(ARDUINO_ARCH_RP2040) +// Pico has a unique 64-bit device identifier which is retrieved from the external NOR flash device at boot. +// These 8 bytes are transferred to characters, so 16 bytes are required +// Additionally 3 bytes for "SN-" and one byte for the NULL terminator is required +// On first start up only "SN" is written to the EEPROM to check first start up of the firmware +char serial[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1 + 3] = MOBIFLIGHT_SERIAL; +#endif char name[MEM_LEN_NAME] = MOBIFLIGHT_NAME; const int MEM_LEN_CONFIG = MEMLEN_CONFIG; char nameBuffer[MEM_LEN_CONFIG] = ""; @@ -437,15 +443,42 @@ bool getStatusConfig() // ************************************************************ void generateSerial(bool force) { - MFeeprom.read_block(MEM_OFFSET_SERIAL, serial, MEM_LEN_SERIAL); - if (!force && serial[0] == 'S' && serial[1] == 'N') + if (force) { +#if defined(ARDUINO_ARCH_AVR) + // A serial number is forced to generated from the user + // It is very likely that the reason is a double serial number as the UniqueID for AVR's must not be Unique + // so generate one acc. the old style and use millis() for seed + randomSeed(millis()); + sprintf(serial, "SN-%03x-", (unsigned int)random(4095)); + sprintf(&serial[7], "%03x", (unsigned int)random(4095)); + MFeeprom.write_block(MEM_OFFSET_SERIAL, serial, MEM_LEN_SERIAL); +#endif return; - randomSeed(analogRead(RANDOM_SEED_INPUT)); - sprintf(serial, "SN-%03x-", (unsigned int)random(4095)); - sprintf(&serial[7], "%03x", (unsigned int)random(4095)); - MFeeprom.write_block(MEM_OFFSET_SERIAL, serial, MEM_LEN_SERIAL); - if (!force) { - MFeeprom.write_byte(MEM_OFFSET_CONFIG, 0x00); // First byte of config to 0x00 to ensure to start 1st time with empty config, but not if forced from the connector to generate a new one + } + + if (MFeeprom.read_byte(MEM_OFFSET_SERIAL) == 'S' && MFeeprom.read_byte(MEM_OFFSET_SERIAL + 1) == 'N') { + // A serial number according old style is already generated and saved to the eeprom + // So keep it to avoid a connector message with orphaned board + MFeeprom.read_block(MEM_OFFSET_SERIAL, serial, MEM_LEN_SERIAL); + return; + } + + // Read the uniqueID and use it as serial numnber + sprintf(serial, "SN-"); + for (size_t i = 0; i < UniqueIDsize; i++) { + if (UniqueID[i] < 0x10) { + sprintf(&serial[3 + i * 2], "0%X", UniqueID[i]); + } else { + sprintf(&serial[3 + i * 2], "%X", UniqueID[i]); + } + } + + if (MFeeprom.read_byte(MEM_OFFSET_SERIAL) != 'I' && MFeeprom.read_byte(MEM_OFFSET_SERIAL + 1) != 'D') { + // Coming here it's the first start up of the board and no serial number or UniqueID is available + // mark this in the eeprom that a UniqueID is used on first start up + MFeeprom.write_block(MEM_OFFSET_SERIAL, "ID", 2); + // Set first byte of config to 0x00 to ensure with empty config on 1st start up + MFeeprom.write_byte(MEM_OFFSET_CONFIG, 0x00); } } diff --git a/src/MF_Modules/MFEEPROM.cpp b/src/MF_Modules/MFEEPROM.cpp index 4dddc60f..f9585af0 100644 --- a/src/MF_Modules/MFEEPROM.cpp +++ b/src/MF_Modules/MFEEPROM.cpp @@ -6,11 +6,15 @@ #include #include "MFEEPROM.h" +#include "MFBoards.h" MFEEPROM::MFEEPROM() {} void MFEEPROM::init(void) { +#if defined(ARDUINO_ARCH_RP2040) + EEPROM.begin(EEPROM_SIZE); +#endif _eepromLength = EEPROM.length(); } @@ -29,6 +33,9 @@ bool MFEEPROM::write_byte(uint16_t adr, const uint8_t data) { if (adr >= _eepromLength) return false; EEPROM.write(adr, data); +#if defined(ARDUINO_ARCH_RP2040) + EEPROM.commit(); +#endif return true; } diff --git a/src/MF_Modules/MFEEPROM.h b/src/MF_Modules/MFEEPROM.h index 064602fc..92fe7328 100644 --- a/src/MF_Modules/MFEEPROM.h +++ b/src/MF_Modules/MFEEPROM.h @@ -44,6 +44,9 @@ class MFEEPROM { if (adr + sizeof(T) > _eepromLength) return false; EEPROM.put(adr, t); +#if defined(ARDUINO_ARCH_RP2040) + EEPROM.commit(); +#endif return true; } @@ -54,6 +57,9 @@ class MFEEPROM for (uint16_t i = 0; i < len; i++) { EEPROM.put(adr + i, t[i]); } +#if defined(ARDUINO_ARCH_RP2040) + EEPROM.commit(); +#endif return true; } }; diff --git a/src/MF_Servo/MFServo.cpp b/src/MF_Servo/MFServo.cpp index 55f3e7e7..c46a15ce 100644 --- a/src/MF_Servo/MFServo.cpp +++ b/src/MF_Servo/MFServo.cpp @@ -12,7 +12,11 @@ void MFServo::moveTo(int absolute) if (_targetPos != newValue) { _targetPos = newValue; if (!_initialized) { +#if defined(ARDUINO_ARCH_RP2040) + _servo.attach(_pin, 544, 2400); +#else _servo.attach(_pin); +#endif _initialized = true; } } diff --git a/src/allocateMem.cpp b/src/allocateMem.cpp index 419517b9..0b3912ce 100644 --- a/src/allocateMem.cpp +++ b/src/allocateMem.cpp @@ -6,10 +6,19 @@ #include "mobiflight.h" -char deviceBuffer[MF_MAX_DEVICEMEM] = {0}; +#if defined (ARDUINO_ARCH_AVR) +uint8_t deviceBuffer[MF_MAX_DEVICEMEM] = {0}; +#else +std::size_t deviceBuffer[MF_MAX_DEVICEMEM] = {0}; +#endif + uint16_t nextPointer = 0; -char *allocateMemory(uint8_t size) +#if defined (ARDUINO_ARCH_AVR) +uint8_t *allocateMemory(uint8_t size) +#else +std::size_t *allocateMemory(uint8_t size) +#endif { uint16_t actualPointer = nextPointer; nextPointer = actualPointer + size; diff --git a/src/allocateMem.h b/src/allocateMem.h index 2a98c15d..e9d6f857 100644 --- a/src/allocateMem.h +++ b/src/allocateMem.h @@ -8,9 +8,12 @@ #include -extern char deviceBuffer[]; +#if defined (ARDUINO_ARCH_AVR) +uint8_t *allocateMemory(uint8_t size); +#else +std::size_t *allocateMemory(uint8_t size); +#endif -char *allocateMemory(uint8_t size); void ClearMemory(); uint16_t GetAvailableMemory(); bool FitInMemory(uint8_t size);