From 1f5ca5aa1c031c26df64fa039041270e9419cba1 Mon Sep 17 00:00:00 2001 From: fabik111 Date: Tue, 17 Jun 2025 14:34:35 +0200 Subject: [PATCH 1/3] change reset pin for portenta h7 and disable the reset procedure for machine control --- README.md | 15 ++++++++++ .../NetworkConfiguratorDemo.ino | 2 ++ src/ANetworkConfigurator_Config.h | 4 ++- src/Arduino_NetworkConfigurator.cpp | 2 ++ src/Arduino_NetworkConfigurator.h | 2 ++ src/utility/ResetInput.cpp | 29 ++++++++++++++++++- 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0546307..463c614 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,22 @@ The procedure: * `Arduino MKR WiFi 1010`: short the pin 7 to GND until the led turns off * `Arduino GIGA R1 WiFi`: short the pin 7 to GND until the led turns off * `Arduino Nano RP2040 Connect`: short the pin 2 to 3.3V until the led turns off +* `Arduino Portenta H7`: short the pin 0 to GND until the led turns off * Other boards: short the pin 2 to GND until the led turns off +* `Portenta Machine Control`: currently the reset procedure is not available + +### More on the reconfiguration pin +Internally, the pin indicated in the procedure is set as `INPUT_PULLUP` (except for `Arduino Opta` ) and it's attached to an ISR fired on every change of the pin's status. + +In order to be notified when the ISR is fired, it's possible to register a callback function using the function `NetworkConfigurator.addReconfigurePinCallback(callback)`. Please take the example as reference. + +### Change the reconfiguration pin +In order to change the default pin for resetting the board, it's possible to use the function `NetworkConfigurator.setReconfigurePin(your_pin)` specifying the new pin. +The pin must be in the list of digital pins usable for interrupts. Please refer to the Arduino documentation for more details: https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/ + +### Disable the reconfiguration feature +In order to disable the reconfiguration procedure, use this function in the sketch `NetworkConfigurator.setReconfigurePin(DISABLE_PIN)` + ## Configurator Agents The library provides a set of *Configurator Agents* that added as plug-in to the sketch handle the communication between the Arduino Network Configurator and an external client ([*Arduino IoT App*](https://cloud.arduino.cc/iot-remote-app/) and Arduino IoT Cloud) for configuring the board. diff --git a/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino b/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino index 1bb8e6c..2d64ace 100644 --- a/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino +++ b/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino @@ -21,6 +21,8 @@ * - Arduino MKR WiFi 1010: short the pin 7 to GND until the led turns off * - Arduino GIGA R1 WiFi: short the pin 7 to GND until the led turns off * - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off + * - Portenta H7: short the pin 0 to GND until the led turns off + * - Portenta Machine Control: the reset is not available * - Other boards: short the pin 2 to GND until the led turns off * * In this sketch the BLE and Serial interfaces are always enabled and ready for accepting diff --git a/src/ANetworkConfigurator_Config.h b/src/ANetworkConfigurator_Config.h index e1ca4cd..e01374b 100644 --- a/src/ANetworkConfigurator_Config.h +++ b/src/ANetworkConfigurator_Config.h @@ -57,7 +57,9 @@ #if defined(ARDUINO_PORTENTA_H7_M7) #define NETWORK_CONFIGURATOR_COMPATIBLE 1 #define ZERO_TOUCH_ENABLED 1 - #define PIN_RECONFIGURE 2 + #define I2C_ADD_DETECT_MACHINE_CONTROL_1 0x23 + #define I2C_ADD_DETECT_MACHINE_CONTROL_2 0x22 + #define PIN_RECONFIGURE 0 #define LED_RECONFIGURE LED_BUILTIN #define BOARD_HAS_RGB #define GREEN_LED LEDG diff --git a/src/Arduino_NetworkConfigurator.cpp b/src/Arduino_NetworkConfigurator.cpp index f448b1f..6c6e331 100644 --- a/src/Arduino_NetworkConfigurator.cpp +++ b/src/Arduino_NetworkConfigurator.cpp @@ -122,6 +122,8 @@ NetworkConfiguratorStates NetworkConfiguratorClass::update() { * - Arduino MKR WiFi 1010: short the pin 7 to GND until the led turns off * - Arduino GIGA R1 WiFi: short the pin 7 to GND until the led turns off * - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off + * - Portenta H7: short the pin 0 to GND until the led turns off + * - Portenta Machine Control: the reset is not available * - Other boards: short the pin 2 to GND until the led turns off */ diff --git a/src/Arduino_NetworkConfigurator.h b/src/Arduino_NetworkConfigurator.h index d68bbdb..029921d 100644 --- a/src/Arduino_NetworkConfigurator.h +++ b/src/Arduino_NetworkConfigurator.h @@ -58,6 +58,8 @@ enum class NetworkConfiguratorStates { ZERO_TOUCH_CONFIG, * - Arduino MKR WiFi 1010: short the pin 7 to GND until the led turns off * - Arduino GIGA R1 WiFi: short the pin 7 to GND until the led turns off * - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off + * - Portenta H7: short the pin 0 to GND until the led turns off + * - Portenta Machine Control: the reset is not available * - Other boards: short the pin 2 to GND until the led turns off * */ diff --git a/src/utility/ResetInput.cpp b/src/utility/ResetInput.cpp index 0df5fc0..70d322e 100644 --- a/src/utility/ResetInput.cpp +++ b/src/utility/ResetInput.cpp @@ -11,6 +11,28 @@ #include "ResetInput.h" #include "utility/LEDFeedback.h" +#if defined(ARDUINO_PORTENTA_H7_M7) +#include + + +bool isPortentaMachineControlAttached() { + Wire.begin(); + Wire.beginTransmission(I2C_ADD_DETECT_MACHINE_CONTROL_1); + if (Wire.endTransmission() != 0) { + return false; + } + + Wire.beginTransmission(I2C_ADD_DETECT_MACHINE_CONTROL_2); + if (Wire.endTransmission() != 0) { + return false; + } + + Wire.end(); + return true; +} + +#endif + ResetInput &ResetInput::getInstance() { static ResetInput instance; return instance; @@ -25,6 +47,12 @@ ResetInput::ResetInput() { } void ResetInput::begin() { +#if defined(ARDUINO_PORTENTA_H7_M7) + if(isPortentaMachineControlAttached()) { + return; // Portenta Machine Control is not supported + } +#endif + if(_pin == DISABLE_PIN){ return; } @@ -35,7 +63,6 @@ void ResetInput::begin() { #endif pinMode(LED_RECONFIGURE, OUTPUT); digitalWrite(LED_RECONFIGURE, LED_OFF); - attachInterrupt(digitalPinToInterrupt(_pin),_pressedCallback, CHANGE); } From 25a89a48ae6863b9e50be47577fcfca139a921d0 Mon Sep 17 00:00:00 2001 From: fabik111 Date: Tue, 17 Jun 2025 18:03:06 +0200 Subject: [PATCH 2/3] fix reset pin for portenta machine control --- README.md | 6 +- .../NetworkConfiguratorDemo.ino | 7 +- src/Arduino_NetworkConfigurator.cpp | 7 +- src/Arduino_NetworkConfigurator.h | 13 +- src/utility/ResetInput.cpp | 121 ----------------- src/utility/ResetInput.h | 124 ++++++++++-------- src/utility/ResetInputBase.cpp | 91 +++++++++++++ src/utility/ResetInputBase.h | 76 +++++++++++ .../ResetInput_PortentaMachineControl.h | 104 +++++++++++++++ 9 files changed, 364 insertions(+), 185 deletions(-) delete mode 100644 src/utility/ResetInput.cpp create mode 100644 src/utility/ResetInputBase.cpp create mode 100644 src/utility/ResetInputBase.h create mode 100644 src/utility/ResetInput_PortentaMachineControl.h diff --git a/README.md b/README.md index 463c614..672ff49 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ The procedure: * `Arduino GIGA R1 WiFi`: short the pin 7 to GND until the led turns off * `Arduino Nano RP2040 Connect`: short the pin 2 to 3.3V until the led turns off * `Arduino Portenta H7`: short the pin 0 to GND until the led turns off +* `Portenta Machine Control`: plug the device to a 24V power source, short the pin Digital Inputs 0 to 24VOUT until the led (`LED_BUILTIN`) turns off * Other boards: short the pin 2 to GND until the led turns off -* `Portenta Machine Control`: currently the reset procedure is not available ### More on the reconfiguration pin Internally, the pin indicated in the procedure is set as `INPUT_PULLUP` (except for `Arduino Opta` ) and it's attached to an ISR fired on every change of the pin's status. @@ -47,6 +47,10 @@ In order to be notified when the ISR is fired, it's possible to register a callb In order to change the default pin for resetting the board, it's possible to use the function `NetworkConfigurator.setReconfigurePin(your_pin)` specifying the new pin. The pin must be in the list of digital pins usable for interrupts. Please refer to the Arduino documentation for more details: https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/ +N.B.: For `Portenta Machine Control`, the pin must be one of the Digital Inputs 0-7. + The parameter must be one of the range DIN_READ_CH_PIN_00-DIN_READ_CH_PIN_07. + The defines are available in the Portenta Machine Control library and you must include Arduino_PortentaMachineControl.h for having access to them. + ### Disable the reconfiguration feature In order to disable the reconfiguration procedure, use this function in the sketch `NetworkConfigurator.setReconfigurePin(DISABLE_PIN)` diff --git a/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino b/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino index 2d64ace..57840f1 100644 --- a/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino +++ b/examples/NetworkConfiguratorDemo/NetworkConfiguratorDemo.ino @@ -22,7 +22,8 @@ * - Arduino GIGA R1 WiFi: short the pin 7 to GND until the led turns off * - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off * - Portenta H7: short the pin 0 to GND until the led turns off - * - Portenta Machine Control: the reset is not available + * - Portenta Machine Control: plug the device to a 24V power source, short the pin Digital Inputs 0 + * to 24VOUT until the led (`LED_BUILTIN`) turns off * - Other boards: short the pin 2 to GND until the led turns off * * In this sketch the BLE and Serial interfaces are always enabled and ready for accepting @@ -78,6 +79,10 @@ void setup() { * The pin must be in the list of digital pins usable for interrupts. * Please refer to the Arduino documentation for more details: * https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/ + * N.B.: For Portenta Machine Control, the pin must be one of the Digital Inputs 0-7. + * The parameter must be one of the range DIN_READ_CH_PIN_00-DIN_READ_CH_PIN_07. + * The defines are available in the Portenta Machine Control library and you must include + * Arduino_PortentaMachineControl.h for having access to them. */ //NetworkConfigurator.setReconfigurePin(your_pin); diff --git a/src/Arduino_NetworkConfigurator.cpp b/src/Arduino_NetworkConfigurator.cpp index 6c6e331..680a8ab 100644 --- a/src/Arduino_NetworkConfigurator.cpp +++ b/src/Arduino_NetworkConfigurator.cpp @@ -41,7 +41,7 @@ NetworkConfiguratorClass::NetworkConfiguratorClass(ConnectionHandler &connection _receivedEvent = NetworkConfiguratorEvents::NONE; _optionUpdateTimer.begin(NC_UPDATE_NETWORK_OPTIONS_TIMER_ms); //initialize the timer before calling begin _agentsManager = &AgentsManagerClass::getInstance(); - _resetInput = &ResetInput::getInstance(); + _resetInput = &ResetInputBase::getInstance(); _ledFeedback = &LEDFeedbackClass::getInstance(); } @@ -123,7 +123,8 @@ NetworkConfiguratorStates NetworkConfiguratorClass::update() { * - Arduino GIGA R1 WiFi: short the pin 7 to GND until the led turns off * - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off * - Portenta H7: short the pin 0 to GND until the led turns off - * - Portenta Machine Control: the reset is not available + * - Portenta Machine Control: plug the device to a 24V power source, short the pin Digital Inputs 0 + * to 24VOUT until the led (`LED_BUILTIN`) turns off * - Other boards: short the pin 2 to GND until the led turns off */ @@ -210,7 +211,7 @@ void NetworkConfiguratorClass::setReconfigurePin(int pin) { _resetInput->setPin(pin); } -void NetworkConfiguratorClass::addReconfigurePinCallback(ResetInput::ResetInputCallback callback) { +void NetworkConfiguratorClass::addReconfigurePinCallback(ResetInputBase::ResetInputCallback callback) { _resetInput->setPinChangedCallback(callback); } diff --git a/src/Arduino_NetworkConfigurator.h b/src/Arduino_NetworkConfigurator.h index 029921d..b3edc9f 100644 --- a/src/Arduino_NetworkConfigurator.h +++ b/src/Arduino_NetworkConfigurator.h @@ -16,7 +16,7 @@ #include #include #include -#include "utility/ResetInput.h" +#include "utility/ResetInputBase.h" #include "utility/LEDFeedback.h" /** @@ -59,7 +59,8 @@ enum class NetworkConfiguratorStates { ZERO_TOUCH_CONFIG, * - Arduino GIGA R1 WiFi: short the pin 7 to GND until the led turns off * - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off * - Portenta H7: short the pin 0 to GND until the led turns off - * - Portenta Machine Control: the reset is not available + * - Portenta Machine Control: plug the device to a 24V power source, short the pin Digital Inputs 0 + * to 24VOUT until the led (`LED_BUILTIN`) turns off * - Other boards: short the pin 2 to GND until the led turns off * */ @@ -121,6 +122,10 @@ class NetworkConfiguratorClass { * The pin must be in the list of digital pins usable for interrupts. * Please refer to the Arduino documentation for more details: * https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/ + * N.B.: For Portenta Machine Control, the pin must be one of the Digital Inputs 0-7. + * The parameter must be one of the range DIN_READ_CH_PIN_00-DIN_READ_CH_PIN_07. + * The defines are available in the Portenta Machine Control library and you must include + * Arduino_PortentaMachineControl.h for having access to them. */ void setReconfigurePin(int pin); @@ -129,7 +134,7 @@ class NetworkConfiguratorClass { * interrupt on the reconfiguration pin is fired. * @param callback Pointer to the callback function. */ - void addReconfigurePinCallback(ResetInput::ResetInputCallback callback); + void addReconfigurePinCallback(ResetInputBase::ResetInputCallback callback); /** * @brief Checks if a specific configuration agent is enabled. @@ -165,7 +170,7 @@ class NetworkConfiguratorClass { static inline models::NetworkSetting _networkSetting; bool _connectionHandlerIstantiated; bool _configInProgress; - ResetInput *_resetInput; + ResetInputBase *_resetInput; LEDFeedbackClass *_ledFeedback; /* Timeout instances */ // Timeout for connection attempt diff --git a/src/utility/ResetInput.cpp b/src/utility/ResetInput.cpp deleted file mode 100644 index 70d322e..0000000 --- a/src/utility/ResetInput.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (c) 2024 Arduino SA - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. -*/ -#include "ANetworkConfigurator_Config.h" -#if NETWORK_CONFIGURATOR_COMPATIBLE - -#include "ResetInput.h" -#include "utility/LEDFeedback.h" - -#if defined(ARDUINO_PORTENTA_H7_M7) -#include - - -bool isPortentaMachineControlAttached() { - Wire.begin(); - Wire.beginTransmission(I2C_ADD_DETECT_MACHINE_CONTROL_1); - if (Wire.endTransmission() != 0) { - return false; - } - - Wire.beginTransmission(I2C_ADD_DETECT_MACHINE_CONTROL_2); - if (Wire.endTransmission() != 0) { - return false; - } - - Wire.end(); - return true; -} - -#endif - -ResetInput &ResetInput::getInstance() { - static ResetInput instance; - return instance; -} - -ResetInput::ResetInput() { - _pin = PIN_RECONFIGURE; - _expired = false; - _startPressed = 0; - _fireEvent = false; - _pressedCustomCallback = nullptr; -} - -void ResetInput::begin() { -#if defined(ARDUINO_PORTENTA_H7_M7) - if(isPortentaMachineControlAttached()) { - return; // Portenta Machine Control is not supported - } -#endif - - if(_pin == DISABLE_PIN){ - return; - } -#ifdef ARDUINO_OPTA - pinMode(_pin, INPUT); -#else - pinMode(_pin, INPUT_PULLUP); -#endif - pinMode(LED_RECONFIGURE, OUTPUT); - digitalWrite(LED_RECONFIGURE, LED_OFF); - attachInterrupt(digitalPinToInterrupt(_pin),_pressedCallback, CHANGE); -} - -bool ResetInput::isEventFired() { - if(_startPressed != 0){ -#if defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_SAMD_MKRWIFI1010) - LEDFeedbackClass::getInstance().stop(); -#endif - if(micros() - _startPressed > RESET_HOLD_TIME){ - digitalWrite(LED_RECONFIGURE, LED_OFF); - _expired = true; - } - } - - return _fireEvent; -} - -void ResetInput::setPinChangedCallback(ResetInputCallback callback) { - _pressedCustomCallback = callback; -} - -void ResetInput::setPin(int pin) { - if(pin < 0){ - _pin = DISABLE_PIN; - }else { - _pin = pin; - } -} - -void ResetInput::_pressedCallback() { -#if defined(ARDUINO_NANO_RP2040_CONNECT) - if(digitalRead(_pin) == HIGH){ -#else - if(digitalRead(_pin) == LOW){ -#endif -#if !defined(ARDUINO_NANO_RP2040_CONNECT) && !defined(ARDUINO_SAMD_MKRWIFI1010) - LEDFeedbackClass::getInstance().stop(); -#endif - _startPressed = micros(); - digitalWrite(LED_RECONFIGURE, LED_ON); - } else { - digitalWrite(LED_RECONFIGURE, LED_OFF); - if(_startPressed != 0 && _expired){ - _fireEvent = true; - }else{ - LEDFeedbackClass::getInstance().restart(); - } - _startPressed = 0; - } - - if (_pressedCustomCallback) { - _pressedCustomCallback(); - } -} - -#endif // NETWORK_CONFIGURATOR_COMPATIBLE diff --git a/src/utility/ResetInput.h b/src/utility/ResetInput.h index a9700ee..c7bab72 100644 --- a/src/utility/ResetInput.h +++ b/src/utility/ResetInput.h @@ -8,68 +8,82 @@ #pragma once -#include "Arduino.h" -#include +#include "ANetworkConfigurator_Config.h" +#include "ResetInputBase.h" +#include "LEDFeedback.h" -#define DISABLE_PIN -1 - -/** - * @class ResetInput - * @brief A singleton class to handle input of the reset functionality with interrupt-based monitoring. - * - * This class provides methods to configure and monitor a reset input pin. It allows - * setting up a custom callback function to be executed when the pin status changes. - */ -class ResetInput{ +class ResetInput : public ResetInputBase { public: - /** - * @typedef ResetInput::ResetInputCallback - * @brief A type definition for the callback function to be executed on pin status change. - */ - typedef std::function ResetInputCallback; - /** - * @brief Get the singleton instance of the ResetInput class. - * @return A reference to the ResetInput instance. - */ - static ResetInput& getInstance(); - /** - * @brief Initialize the reset input by setting up the interrupt pin. - */ - void begin(); - /** - * @brief Check if the reset event has been fired. - * @return True if the event is fired, otherwise false. - */ - bool isEventFired(); - /** - * @brief Set a custom callback function to be called when the pin status changes. - * This function must be called before invoking the `begin` method. - * @param callback The custom callback function to be executed. - */ - void setPinChangedCallback(ResetInputCallback callback); - /** - * @brief Set the pin to be monitored for reset events. - * By default, the pin is set as INPUT_PULLUP. - * Use the value DISABLE_PIN to disable the pin and the reset procedure. - * This function must be called before invoking the `begin` method. - * @param pin The pin number to be monitored. The pin must - * be in the list of digital pins usable for interrupts. - * Please refer to the Arduino documentation for more details: - * https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/ - */ - void setPin(int pin); + static ResetInput &getInstance() { + static ResetInput instance; + return instance; + } + + void begin() override { + if(_pin == DISABLE_PIN){ + return; + } + #ifdef ARDUINO_OPTA + pinMode(_pin, INPUT); + #else + pinMode(_pin, INPUT_PULLUP); + #endif + pinMode(LED_RECONFIGURE, OUTPUT); + digitalWrite(LED_RECONFIGURE, LED_OFF); + attachInterrupt(digitalPinToInterrupt(_pin),_pressedCallback, CHANGE); + } + + bool isEventFired() override { + if(_startPressed != 0){ + #if defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_SAMD_MKRWIFI1010) + LEDFeedbackClass::getInstance().stop(); + #endif + if(micros() - _startPressed > RESET_HOLD_TIME){ + digitalWrite(LED_RECONFIGURE, LED_OFF); + _expired = true; + } + } + + return _fireEvent; + } + private: - /** - * @brief Private constructor to enforce the singleton pattern. - */ - ResetInput(); - static inline ResetInputCallback _pressedCustomCallback; - static inline int _pin; + ResetInput() { + _pin = PIN_RECONFIGURE; + _expired = false; + _startPressed = 0; + _fireEvent = false; + } static inline volatile bool _expired; static inline volatile bool _fireEvent; static inline volatile uint32_t _startPressed; /** * @brief Internal callback function to handle pin press events. */ - static void _pressedCallback(); + static void _pressedCallback() { + #if defined(ARDUINO_NANO_RP2040_CONNECT) + if(digitalRead(_pin) == HIGH){ + #else + if(digitalRead(_pin) == LOW){ + #endif + #if !defined(ARDUINO_NANO_RP2040_CONNECT) && !defined(ARDUINO_SAMD_MKRWIFI1010) + LEDFeedbackClass::getInstance().stop(); + #endif + _startPressed = micros(); + digitalWrite(LED_RECONFIGURE, LED_ON); + } else { + digitalWrite(LED_RECONFIGURE, LED_OFF); + if(_startPressed != 0 && _expired){ + _fireEvent = true; + }else{ + LEDFeedbackClass::getInstance().restart(); + } + _startPressed = 0; + } + + if (_pressedCustomCallback) { + _pressedCustomCallback(); + } + } }; + diff --git a/src/utility/ResetInputBase.cpp b/src/utility/ResetInputBase.cpp new file mode 100644 index 0000000..735dfdc --- /dev/null +++ b/src/utility/ResetInputBase.cpp @@ -0,0 +1,91 @@ +/* + Copyright (c) 2024 Arduino SA + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ +#include "ANetworkConfigurator_Config.h" +#if NETWORK_CONFIGURATOR_COMPATIBLE + +#include "ResetInputBase.h" +#include "ResetInput.h" + + +#if defined(ARDUINO_PORTENTA_H7_M7) +#include "ResetInput_PortentaMachineControl.h" +#include +bool isPortentaMachineControlAttached() { + Wire.begin(); + Wire.beginTransmission(I2C_ADD_DETECT_MACHINE_CONTROL_1); + if (Wire.endTransmission() != 0) { + return false; + } + + Wire.beginTransmission(I2C_ADD_DETECT_MACHINE_CONTROL_2); + if (Wire.endTransmission() != 0) { + return false; + } + + Wire.end(); + return true; +} + +#endif + +ResetInputBase &ResetInputBase::getInstance() { + static ResetInputBase instance; + return instance; +} + +void ResetInputBase::begin() { + + ResetInputCallback pressedCustomCallback = _pressedCustomCallback; + int pin = _pin; + + #if defined(ARDUINO_PORTENTA_H7_M7) + if(isPortentaMachineControlAttached()) { + _instance = &ResetInput_PortentaMachineControl::getInstance(); + }else{ + _instance = &ResetInput::getInstance(); + } + #else + _instance = &ResetInput::getInstance(); + #endif + if(pin != -2) { + _instance->setPin(pin); + } + + if(pressedCustomCallback) { + _instance->setPinChangedCallback(pressedCustomCallback); + } + + _instance->begin(); +} + +bool ResetInputBase::isEventFired() { + if (_instance == nullptr) { + return false; + } + return _instance->isEventFired(); +} + +void ResetInputBase::setPinChangedCallback(ResetInputCallback callback) { + _pressedCustomCallback = callback; +} + +void ResetInputBase::setPin(int pin) { + if(pin < 0){ + _pin = DISABLE_PIN; + }else { + _pin = pin; + } +} + +ResetInputBase::ResetInputBase() { + _instance = nullptr; + _pressedCustomCallback = nullptr; + _pin = -2; +} + +#endif diff --git a/src/utility/ResetInputBase.h b/src/utility/ResetInputBase.h new file mode 100644 index 0000000..54b9293 --- /dev/null +++ b/src/utility/ResetInputBase.h @@ -0,0 +1,76 @@ +/* + Copyright (c) 2024 Arduino SA + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#pragma once +#include "Arduino.h" +#include + +#define DISABLE_PIN -1 + +/** + * @class ResetInputBase + * @brief A singleton class to handle input of the reset functionality with interrupt-based monitoring. + * + * This class provides methods to configure and monitor a reset input pin. It allows + * setting up a custom callback function to be executed when the pin status changes. + */ +class ResetInputBase{ +public: + /** + * @typedef ResetInputBase::ResetInputCallback + * @brief A type definition for the callback function to be executed on pin status change. + */ + typedef std::function ResetInputCallback; + /** + * @brief Get the singleton instance of the ResetInputBase class. + * @return A reference to the ResetInputBase instance. + */ + static ResetInputBase& getInstance(); + /** + * @brief Initialize the reset input by setting up the interrupt pin. + */ + virtual void begin(); + /** + * @brief Check if the reset event has been fired. + * @return True if the event is fired, otherwise false. + */ + virtual bool isEventFired(); + /** + * @brief Set a custom callback function to be called when the pin status changes. + * This function must be called before invoking the `begin` method. + * @param callback The custom callback function to be executed. + */ + void setPinChangedCallback(ResetInputCallback callback); + /** + * @brief Set the pin to be monitored for reset events. + * By default, the pin is set as INPUT_PULLUP. + * Use the value DISABLE_PIN to disable the pin and the reset procedure. + * This function must be called before invoking the `begin` method. + * @param pin The pin number to be monitored. The pin must + * be in the list of digital pins usable for interrupts. + * Please refer to the Arduino documentation for more details: + * https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/ + * N.B.: For Portenta Machine Control, the pin must be one of the Digital Inputs 0-7. + * The parameter must be one of the range DIN_READ_CH_PIN_00-DIN_READ_CH_PIN_07. + * The defines are available in the Portenta Machine Control library and you must include + * Arduino_PortentaMachineControl.h for having access to them. + */ + void setPin(int pin); + + +protected: + static inline ResetInputCallback _pressedCustomCallback; + static inline int _pin; + /** + * @brief Private constructor to enforce the singleton pattern. + */ + ResetInputBase(); + +private: + ResetInputBase *_instance; +}; diff --git a/src/utility/ResetInput_PortentaMachineControl.h b/src/utility/ResetInput_PortentaMachineControl.h new file mode 100644 index 0000000..8b36201 --- /dev/null +++ b/src/utility/ResetInput_PortentaMachineControl.h @@ -0,0 +1,104 @@ +/* + Copyright (c) 2025 Arduino SA + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#pragma once + +#include "ANetworkConfigurator_Config.h" +#include +#include "ResetInputBase.h" +#include "LEDFeedback.h" + +#define PORTENTA_MACHINE_CONTROL_DI_INTERRUPT PB_4 +#define PIN_RECONFIGURE_MACHINE_CONTROL DIN_READ_CH_PIN_00 + +class ResetInput_PortentaMachineControl : public ResetInputBase { +public: + static ResetInput_PortentaMachineControl &getInstance() { + static ResetInput_PortentaMachineControl instance; + return instance; + } + + void begin() override { + if (_pin == DISABLE_PIN) { + return; + } + + pinMode(LED_RECONFIGURE, OUTPUT); + digitalWrite(LED_RECONFIGURE, LED_OFF); + Wire.begin(); + attachInterrupt(PORTENTA_MACHINE_CONTROL_DI_INTERRUPT, _inputCallback, FALLING); + MachineControl_DigitalInputs.begin(); + } + + bool isEventFired() override { + if(_interruptFlag) { + bool pinChanged = false; + _interruptFlag = false; + int pinStatus = MachineControl_DigitalInputs.read(_pin); + if(pinStatus == -1) { + return false; + } else { + pinChanged = (pinStatus != _pinStatus); + _pinStatus = pinStatus; + } + + if (!pinChanged) { + return false; + } + + if (pinStatus == 1) { + LEDFeedbackClass::getInstance().stop(); + digitalWrite(LED_RECONFIGURE, LED_ON); + _startPressedTs = _interruptEventTs; + + } else { + // Pin released + if(_startPressedTs != 0){ + digitalWrite(LED_RECONFIGURE, LED_OFF); + if(_interruptEventTs - _startPressedTs > RESET_HOLD_TIME) { + return true; + } + LEDFeedbackClass::getInstance().restart(); + _startPressedTs = 0; + } + } + } + + if(_pinStatus == 1) { + // Pin is pressed + if(_startPressedTs != 0 && micros() - _startPressedTs > RESET_HOLD_TIME) { + // Turn off the led after the hold time + digitalWrite(LED_RECONFIGURE, LED_OFF); + } + } + + return false; + } + + +private: + ResetInput_PortentaMachineControl() { + _pin = PIN_RECONFIGURE_MACHINE_CONTROL; + _interruptFlag = false; + _startPressedTs = 0; + _interruptEventTs = 0; + _pinStatus = -1; + } + int _pinStatus; + uint32_t _startPressedTs; + static inline volatile bool _interruptFlag; + static inline volatile uint32_t _interruptEventTs; + static void _inputCallback() { + + _interruptFlag = true; + _interruptEventTs = micros(); + if (_pressedCustomCallback) { + _pressedCustomCallback(); + } + } +}; From db7d0f23fdabf8cf8cf4458f8f206b7d1c368b2a Mon Sep 17 00:00:00 2001 From: fabik111 Date: Wed, 18 Jun 2025 12:21:45 +0200 Subject: [PATCH 3/3] update ci test --- .github/workflows/compile-examples.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index e467e73..90f2f99 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -93,6 +93,7 @@ jobs: libraries: | - name: Arduino_Cellular - name: Blues Wireless Notecard + - name: Arduino_PortentaMachineControl # Nicla Vision - board: type: mbed_nicla