Skip to content

Commit

Permalink
Stop 2nd core for pico during config upload (#329)
Browse files Browse the repository at this point in the history
  • Loading branch information
elral authored Sep 4, 2024
1 parent 52dba44 commit 55b3b2b
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 50 deletions.
12 changes: 12 additions & 0 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,13 @@ void resetConfig()
Servos::Clear();
#endif
#if MF_STEPPER_SUPPORT == 1
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
Stepper::stopUpdate2ndCore(true);
#endif
Stepper::Clear();
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
Stepper::stopUpdate2ndCore(false);
#endif
#endif
#if MF_LCD_SUPPORT == 1
LCDDisplay::Clear();
Expand All @@ -173,7 +179,13 @@ void resetConfig()
DigInMux::Clear();
#endif
#if MF_CUSTOMDEVICE_SUPPORT == 1
#if defined(USE_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
CustomDevice::stopUpdate2ndCore(true);
#endif
CustomDevice::Clear();
#if defined(USE_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
CustomDevice::stopUpdate2ndCore(false);
#endif
#endif
configLengthEEPROM = 0;
configActivated = false;
Expand Down
71 changes: 44 additions & 27 deletions src/MF_CustomDevice/CustomDevice.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mobiflight.h"
#include "CustomDevice.h"
#include "MFCustomDevice.h"
#if defined(USE_2ND_CORE)
#if defined(USE_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
#include <FreeRTOS.h>
#endif

Expand Down Expand Up @@ -92,7 +92,7 @@ namespace CustomDevice
int16_t messageID = cmdMessenger.readInt16Arg(); // get the messageID number
char *output = cmdMessenger.readStringArg(); // get the pointer to the new raw string
cmdMessenger.unescape(output); // and unescape the string if escape characters are used
#if defined(USE_2ND_CORE)
#if defined(USE_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
// copy the message, could get be overwritten from the next message while processing on 2nd core
strncpy(payload, output, SERIAL_RX_BUFFER_SIZE);
// wait for 2nd core
Expand All @@ -117,14 +117,31 @@ namespace CustomDevice
{
for (uint8_t i = 0; i < customDeviceRegistered; ++i) {
if (state)
customDevice[i].set(MESSAGEID_POWERSAVINGMODE, (char*)"1");
customDevice[i].set(MESSAGEID_POWERSAVINGMODE, (char *)"1");
else
customDevice[i].set(MESSAGEID_POWERSAVINGMODE, (char*)"0");
customDevice[i].set(MESSAGEID_POWERSAVINGMODE, (char *)"0");
}
}

#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
void stopUpdate2ndCore(bool stop)
{
// wait for 2nd core
rp2040.fifo.pop();
// send command to stop/start updating to 2nd core
// negative device numbers are for commands to 2nd core
rp2040.fifo.push(START_STOP_2ND_CORE);
// send stop/start
rp2040.fifo.push(stop);
// communication is always done using 3 messages
rp2040.fifo.push(0);
// wait for execution of command
rp2040.fifo.pop();
}
#endif
} // end of namespace

#if defined(USE_2ND_CORE)
#if defined(USE_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
/* **********************************************************************************
This will run the set() function from the custom device on the 2nd core
Be aware NOT to use the function calls from the Pico SDK!
Expand All @@ -140,45 +157,45 @@ void setup1()

void loop1()
{
uint8_t device;
int16_t device;
int16_t messageID;
char *payload;
bool stopUpdating = false;
#ifdef MF_CUSTOMDEVICE_POLL_MS
uint32_t lastMillis = 0;
#endif

while (1) {
#ifndef MF_CUSTOMDEVICE_POLL_MS
// For now I don't know the reason why this is required.
// It might be that getting the stop command from the 1st core
// needs some idle time. If it is not used the 1st core stops when
// writing to the EEPROM which stops the 2nd core
delayMicroseconds(1);
#endif
#ifdef MF_CUSTOMDEVICE_POLL_MS
if (millis() - lastMillis >= MF_CUSTOMDEVICE_POLL_MS) {
#endif
for (int i = 0; i != CustomDevice::customDeviceRegistered; i++) {
#if defined(MF_CUSTOMDEVICE_HAS_UPDATE)
for (int i = 0; i < CustomDevice::customDeviceRegistered && !stopUpdating; i++) {
CustomDevice::customDevice[i].update();
#endif
if (rp2040.fifo.available() == 3) {
// Hmhm, how to get the function pointer to a function from class??
// int32_t (*func)(int16_t, char*) = (int32_t(*)(int16_t, char*)) rp2040.fifo.pop();
device = (uint8_t)rp2040.fifo.pop();
messageID = (int16_t)rp2040.fifo.pop();
payload = (char *)rp2040.fifo.pop();
// (*func)(messageID, payload);
CustomDevice::customDevice[device].set(messageID, payload);
// send ready for next message to 1st core
rp2040.fifo.push(true);
}

}
#endif
#ifdef MF_CUSTOMDEVICE_POLL_MS
lastMillis = millis();
}
#endif
if (rp2040.fifo.available() == 3) {
// Hmhm, how to get the function pointer to a function from class??
// int32_t (*func)(int16_t, char*) = (int32_t(*)(int16_t, char*)) rp2040.fifo.pop();
device = (int16_t)rp2040.fifo.pop();
messageID = (int16_t)rp2040.fifo.pop();
payload = (char *)rp2040.fifo.pop();
if (device == -1) {
stopUpdating = (bool)messageID;
// inform core 0 that command has been executed
// it's additional needed in this case
rp2040.fifo.push(true);
} else {
// (*func)(messageID, payload);
CustomDevice::customDevice[device].set(messageID, payload);
}
// send ready for next message to 1st core
rp2040.fifo.push(true);
}
}
}
#endif
5 changes: 5 additions & 0 deletions src/MF_CustomDevice/CustomDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

namespace CustomDevice
{
#define START_STOP_2ND_CORE -1

bool setupArray(uint16_t count);
void Add(uint16_t adrPin, uint16_t adrType, uint16_t adrConfig, bool configFromFlash);
void Clear();
void update();
void OnSet();
void PowerSave(bool state);
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
void stopUpdate2ndCore(bool stop);
#endif
}
70 changes: 47 additions & 23 deletions src/MF_Stepper/Stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "mobiflight.h"
#include "MFStepper.h"
#include "Stepper.h"
#if defined(STEPPER_ON_2ND_CORE)
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
#include <FreeRTOS.h>
#endif

Expand All @@ -20,7 +20,8 @@ namespace Stepper
enum {
FUNC_MOVETO = 1,
FUNC_ZETZERO,
FUNC_SPEEDACCEL
FUNC_SPEEDACCEL,
START_STOP_2ND_CORE
};
#endif

Expand Down Expand Up @@ -71,7 +72,7 @@ namespace Stepper

if (stepper >= steppersRegistered)
return;
#if defined(STEPPER_ON_2ND_CORE)
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
// wait for 2nd core
rp2040.fifo.pop();
rp2040.fifo.push(FUNC_MOVETO);
Expand All @@ -98,7 +99,7 @@ namespace Stepper

if (stepper >= steppersRegistered)
return;
#if defined(STEPPER_ON_2ND_CORE)
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
// wait for 2nd core
rp2040.fifo.pop();
rp2040.fifo.push(FUNC_ZETZERO);
Expand All @@ -118,7 +119,7 @@ namespace Stepper

if (stepper >= steppersRegistered)
return;
#if defined(STEPPER_ON_2ND_CORE)
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
rp2040.fifo.pop(); // wait for 2nd core
rp2040.fifo.push(FUNC_SPEEDACCEL);
rp2040.fifo.push(stepper);
Expand Down Expand Up @@ -146,9 +147,24 @@ namespace Stepper
}
}

#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
void stopUpdate2ndCore(bool stop)
{
// wait for 2nd core
rp2040.fifo.pop();
// send command to stop/start updating to 2nd core
rp2040.fifo.push(START_STOP_2ND_CORE);
// communication is always done using 4 messages
rp2040.fifo.push(0);
rp2040.fifo.push(stop);
rp2040.fifo.push(0);
// wait for execution of command
rp2040.fifo.pop();
}
#endif
} // namespace

#if defined(STEPPER_ON_2ND_CORE)
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
/* **********************************************************************************
This will run the set() function from the custom device on the 2nd core
Be aware NOT to use the function calls from the Pico SDK!
Expand All @@ -158,32 +174,40 @@ namespace Stepper
********************************************************************************** */
void setup1()
{
rp2040.fifo.push(true); // inform core 1 to be ready
// send "ready" message to 1st core
rp2040.fifo.push(true);
}

void loop1()
{
uint8_t command, stepper;
uint8_t command, stepper;
int32_t param1, param2;
bool stopUpdating = false;

while (1) {
for (uint8_t i = 0; i < Stepper::steppersRegistered; ++i) {
for (uint8_t i = 0; i < Stepper::steppersRegistered && !stopUpdating; ++i) {
Stepper::steppers[i].update();
if (rp2040.fifo.available()) {
command = (uint8_t)rp2040.fifo.pop();
stepper = (uint8_t)rp2040.fifo.pop();
param1 = (int32_t)rp2040.fifo.pop();
param2 = (int32_t)rp2040.fifo.pop();
if (command == Stepper::FUNC_MOVETO) {
Stepper::steppers[stepper].moveTo(param1);
} else if (command == Stepper::FUNC_ZETZERO) {
Stepper::steppers[stepper].setZero();
} else if (command == Stepper::FUNC_SPEEDACCEL) {
Stepper::steppers[stepper].setMaxSpeed(param1);
Stepper::steppers[stepper].setAcceleration(param2);
}
rp2040.fifo.push(true); // inform core 1 to be ready for next command
}
if (rp2040.fifo.available()) {
command = (uint8_t)rp2040.fifo.pop();
stepper = (uint8_t)rp2040.fifo.pop();
param1 = (int32_t)rp2040.fifo.pop();
param2 = (int32_t)rp2040.fifo.pop();
if (command == Stepper::FUNC_MOVETO) {
Stepper::steppers[stepper].moveTo(param1);
} else if (command == Stepper::FUNC_ZETZERO) {
Stepper::steppers[stepper].setZero();
} else if (command == Stepper::FUNC_SPEEDACCEL) {
Stepper::steppers[stepper].setMaxSpeed(param1);
Stepper::steppers[stepper].setAcceleration(param2);
} else if (command == Stepper::START_STOP_2ND_CORE) {
stopUpdating = (bool)param1;
// inform core 0 that command has been executed
// it's additional needed in this case
rp2040.fifo.push(true);
}
// send ready for next message to 1st core
rp2040.fifo.push(true);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/MF_Stepper/Stepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace Stepper
void update();
void OnSetSpeedAccel();
void PowerSave(bool state);
#if defined(STEPPER_ON_2ND_CORE) && defined(ARDUINO_ARCH_RP2040)
void stopUpdate2ndCore(bool stop);
#endif
}

// Stepper.h

0 comments on commit 55b3b2b

Please sign in to comment.