Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for the Pico #228

Merged
merged 20 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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