Skip to content

Commit

Permalink
Support for Pico (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
elral authored Jan 5, 2023
1 parent bd9b4a8 commit 622a217
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 20 deletions.
57 changes: 57 additions & 0 deletions _Boards/RaspberryPi/Pico/MFBoards.h
Original file line number Diff line number Diff line change
@@ -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
40 changes: 35 additions & 5 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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 =
Expand Down
55 changes: 44 additions & 11 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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] = "";
Expand Down Expand Up @@ -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);
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/MF_Modules/MFEEPROM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@

#include <Arduino.h>
#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();
}

Expand All @@ -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;
}

Expand Down
6 changes: 6 additions & 0 deletions src/MF_Modules/MFEEPROM.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}
};
Expand Down
4 changes: 4 additions & 0 deletions src/MF_Servo/MFServo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/allocateMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions src/allocateMem.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@

#include <new>

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);
Expand Down

0 comments on commit 622a217

Please sign in to comment.