diff --git a/src/Config.cpp b/src/Config.cpp index 35b5153f..78d9302e 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -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(); @@ -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; diff --git a/src/MF_CustomDevice/CustomDevice.cpp b/src/MF_CustomDevice/CustomDevice.cpp index 0d0cafb3..3d166719 100644 --- a/src/MF_CustomDevice/CustomDevice.cpp +++ b/src/MF_CustomDevice/CustomDevice.cpp @@ -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 #endif @@ -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 @@ -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! @@ -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 diff --git a/src/MF_CustomDevice/CustomDevice.h b/src/MF_CustomDevice/CustomDevice.h index 5c2abff8..58d827d3 100644 --- a/src/MF_CustomDevice/CustomDevice.h +++ b/src/MF_CustomDevice/CustomDevice.h @@ -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 } \ No newline at end of file diff --git a/src/MF_Stepper/Stepper.cpp b/src/MF_Stepper/Stepper.cpp index ed2a5c4d..e6988f52 100644 --- a/src/MF_Stepper/Stepper.cpp +++ b/src/MF_Stepper/Stepper.cpp @@ -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 #endif @@ -20,7 +20,8 @@ namespace Stepper enum { FUNC_MOVETO = 1, FUNC_ZETZERO, - FUNC_SPEEDACCEL + FUNC_SPEEDACCEL, + START_STOP_2ND_CORE }; #endif @@ -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); @@ -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); @@ -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); @@ -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! @@ -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); } } } diff --git a/src/MF_Stepper/Stepper.h b/src/MF_Stepper/Stepper.h index fc7e797d..59da4822 100644 --- a/src/MF_Stepper/Stepper.h +++ b/src/MF_Stepper/Stepper.h @@ -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 \ No newline at end of file