Skip to content

Commit e60fde8

Browse files
committed
add the reset procedure (#39)
fix reset routine for nina boards fixes for ledFeedback and reset procedure
1 parent f21b467 commit e60fde8

File tree

8 files changed

+217
-4
lines changed

8 files changed

+217
-4
lines changed

examples/auto-retry/auto-retry.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void setup() {
7979

8080
void loop() {
8181
if (provisioningCompleted && networkConfigured) {
82-
NetworkConfigurator.configurationCompleted();
82+
NetworkConfigurator.disconnectAgent();
8383
if (NetworkConfigurator.isBLEenabled()) {
8484
NetworkConfigurator.enableBLE(false);
8585
}

examples/network-setting/network-setting.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ DeviceMode deviceMode = DeviceMode::CONFIG;
3131
void changeMode(DeviceMode nextMode){
3232
if(nextMode == DeviceMode::RUN){
3333
if(deviceMode == DeviceMode::CONFIG){
34-
NetworkConfigurator.configurationCompleted();
34+
NetworkConfigurator.disconnectAgent();
3535
if (NetworkConfigurator.isBLEenabled()) {
3636
NetworkConfigurator.enableBLE(false);
3737
}

src/NetworkConfigurator.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define NC_UPDATE_NETWORK_OPTIONS_TIMER_ms 120000
2424

2525
constexpr char *STORAGE_KEY{ "NETWORK_CONFIGS" };
26+
constexpr char *START_BLE_AT_STARTUP_KEY{ "START_BLE" };
2627

2728
NetworkConfiguratorClass::NetworkConfiguratorClass(ConnectionHandler &connectionHandler)
2829
:
@@ -32,6 +33,7 @@ NetworkConfiguratorClass::NetworkConfiguratorClass(ConnectionHandler &connection
3233
_optionUpdateTimer{ NC_UPDATE_NETWORK_OPTIONS_TIMER_ms, NC_UPDATE_NETWORK_OPTIONS_TIMER_ms } {
3334
_optionUpdateTimer.begin(NC_UPDATE_NETWORK_OPTIONS_TIMER_ms); //initialize the timer before calling begin
3435
_agentsManager = &AgentsManagerClass::getInstance();
36+
_resetInput = &ResetInput::getInstance();
3537
}
3638

3739
bool NetworkConfiguratorClass::begin() {
@@ -71,6 +73,7 @@ bool NetworkConfiguratorClass::begin() {
7173

7274
_connectionTimeout.begin(NC_CONNECTION_TIMEOUT_ms);
7375
_connectionRetryTimer.begin(NC_CONNECTION_RETRY_TIMER_ms);
76+
_resetInput->begin();
7477

7578
#ifdef BOARD_HAS_ETHERNET
7679
_networkSetting.type = NetworkAdapter::ETHERNET;
@@ -110,6 +113,18 @@ NetworkConfiguratorStates NetworkConfiguratorClass::poll() {
110113
_state = nextState;
111114
}
112115

116+
/* Reconfiguration procedure:
117+
* - Arduino Opta: press and hold the user button (BTN_USER) until the led (LED_USER) turns off
118+
* - Arduino Nano 33 IOT: short the pin 2 to GND until the led turns off
119+
* - Arduino Uno R4 WiFi: short the pin 2 to GND until the led turns off
120+
* - Arduino Nano RP2040 Connect: short the pin 2 to 3.3V until the led turns off
121+
* - Other boards: short the pin 7 to GND until the led turns off
122+
*/
123+
124+
if(_resetInput->isEventFired()) {
125+
startReconfigureProcedure();
126+
}
127+
113128
return _state;
114129
}
115130

@@ -153,15 +168,24 @@ bool NetworkConfiguratorClass::end() {
153168
return _agentsManager->end(SERVICE_ID_FOR_AGENTMANAGER);
154169
}
155170

171+
void NetworkConfiguratorClass::setReconfigurePin(uint32_t pin) {
172+
_resetInput->setPin(pin);
173+
}
174+
175+
void NetworkConfiguratorClass::addReconfigurePinCallback(void (*callback)()) {
176+
_resetInput->setPinChangedCallback(callback);
177+
}
178+
156179
bool NetworkConfiguratorClass::isBLEenabled() {
157180
return _agentsManager->isBLEAgentEnabled();
158181
}
159182

160183
void NetworkConfiguratorClass::enableBLE(bool enable) {
184+
_bleEnabled = enable;
161185
_agentsManager->enableBLEAgent(enable);
162186
}
163187

164-
void NetworkConfiguratorClass::configurationCompleted() {
188+
void NetworkConfiguratorClass::disconnectAgent() {
165189
_agentsManager->disconnect();
166190
}
167191

@@ -404,6 +428,19 @@ void NetworkConfiguratorClass::handleGetWiFiFWVersion() {
404428
_agentsManager->sendMsg(fwVersionMsg);
405429
}
406430

431+
void NetworkConfiguratorClass::startReconfigureProcedure() {
432+
resetStoredConfiguration();
433+
if(_kvstore != nullptr){
434+
if (_kvstore->begin()) {
435+
if(!_kvstore->putBool(START_BLE_AT_STARTUP_KEY, true)){
436+
DEBUG_ERROR("NetworkConfiguratorClass::%s Error saving BLE enabled at startup", __FUNCTION__);
437+
}
438+
_kvstore->end();
439+
}
440+
}
441+
NVIC_SystemReset();
442+
}
443+
407444
#ifdef BOARD_HAS_ETHERNET
408445
NetworkConfiguratorStates NetworkConfiguratorClass::handleCheckEth() {
409446
NetworkConfiguratorStates nextState = _state;
@@ -445,6 +482,12 @@ NetworkConfiguratorStates NetworkConfiguratorClass::handleReadStorage() {
445482
}
446483

447484
} else {
485+
if(_kvstore->exists(START_BLE_AT_STARTUP_KEY)) {
486+
if(_kvstore->getBool(START_BLE_AT_STARTUP_KEY)) {
487+
_agentsManager->enableBLEAgent(true);
488+
}
489+
_kvstore->remove(START_BLE_AT_STARTUP_KEY);
490+
}
448491
nextState = NetworkConfiguratorStates::WAITING_FOR_CONFIG;
449492
}
450493
_kvstore->end();
@@ -492,6 +535,9 @@ NetworkConfiguratorStates NetworkConfiguratorClass::handleConnecting() {
492535
ConnectionResult res = connectToNetwork(&err);
493536

494537
if (res == ConnectionResult::SUCCESS) {
538+
if(_agentsManager->isBLEAgentEnabled() && !_bleEnabled) {
539+
_agentsManager->enableBLEAgent(false);
540+
}
495541
nextState = NetworkConfiguratorStates::CONFIGURED;
496542
} else if (res == ConnectionResult::FAILED) {
497543
sendStatus(err);

src/NetworkConfigurator.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <settings/settings.h>
1717
#include <Arduino_TimedAttempt.h>
1818
#include <Arduino_KVStore.h>
19+
#include "Utility/ResetInput/ResetInput.h"
1920

2021
enum class NetworkConfiguratorStates { CHECK_ETH,
2122
READ_STORED_CONFIG,
@@ -37,16 +38,20 @@ class NetworkConfiguratorClass {
3738
_kvstore = &kvstore;
3839
}
3940

41+
void setReconfigurePin(uint32_t pin);
42+
void addReconfigurePinCallback(void (*callback)());
4043
bool isBLEenabled();
4144
void enableBLE(bool enable);
42-
void configurationCompleted();
45+
void disconnectAgent();
4346
bool addAgent(ConfiguratorAgent &agent);
4447

4548
private:
4649
NetworkConfiguratorStates _state = NetworkConfiguratorStates::END;
4750
ConnectionHandler *_connectionHandler;
4851
static inline models::NetworkSetting _networkSetting;
4952
bool _connectionHandlerIstantiated = false;
53+
ResetInput *_resetInput;
54+
bool _bleEnabled = true;
5055
TimedAttempt _connectionTimeout;
5156
TimedAttempt _connectionRetryTimer;
5257
TimedAttempt _optionUpdateTimer;
@@ -77,6 +82,8 @@ class NetworkConfiguratorClass {
7782
NetworkConfiguratorStates handleConnectRequest();
7883
void handleGetWiFiFWVersion();
7984

85+
void startReconfigureProcedure();
86+
8087
String decodeConnectionErrorMessage(NetworkConnectionState err, StatusMessage *errorCode);
8188
ConnectionResult connectToNetwork(StatusMessage *err);
8289
ConnectionResult disconnectFromNetwork();

src/Utility/LEDFeedback/LEDFeedback.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,20 @@ void LEDFeedbackClass::setMode(LEDFeedbackMode mode) {
225225
}
226226
}
227227

228+
void LEDFeedbackClass::stop() {
229+
stopped = true;
230+
turnOFF();
231+
}
232+
233+
void LEDFeedbackClass::restart() {
234+
stopped = false;
235+
}
236+
228237
void LEDFeedbackClass::poll() {
238+
if(stopped) {
239+
return;
240+
}
241+
229242
if(_ledChangeInterval == 0) {
230243
turnOFF();
231244
return;

src/Utility/LEDFeedback/LEDFeedback.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class LEDFeedbackClass {
2323
static LEDFeedbackClass& getInstance();
2424
void begin();
2525
void setMode(LEDFeedbackMode mode);
26+
void stop();
27+
void restart();
2628
void poll();
2729
private:
2830
LEDFeedbackClass() {};
@@ -35,4 +37,5 @@ class LEDFeedbackClass {
3537
uint16_t _ledPin = 0;
3638
uint32_t* _framePtr = nullptr;
3739
int32_t _ledChangeInterval = 500;
40+
bool stopped = false;
3841
};

src/Utility/ResetInput/ResetInput.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
Copyright (c) 2024 Arduino SA
3+
4+
This Source Code Form is subject to the terms of the Mozilla Public
5+
License, v. 2.0. If a copy of the MPL was not distributed with this
6+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
9+
#include "ResetInput.h"
10+
#include "Utility/LEDFeedback/LEDFeedback.h"
11+
12+
#ifdef ARDUINO_OPTA
13+
#define PIN_RECONFIGURE BTN_USER
14+
#define LED_RECONFIGURE LED_USER
15+
#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_NANO_RP2040_CONNECT)
16+
#define PIN_RECONFIGURE 2
17+
#define LED_RECONFIGURE LED_BUILTIN
18+
#else
19+
#define PIN_RECONFIGURE 7
20+
#define LED_RECONFIGURE LED_BUILTIN
21+
#endif
22+
23+
#ifndef RESET_HOLD_TIME
24+
#define RESET_HOLD_TIME 3000000
25+
#endif
26+
27+
ResetInput &ResetInput::getInstance() {
28+
static ResetInput instance;
29+
return instance;
30+
}
31+
32+
ResetInput::ResetInput():
33+
_pin {PIN_RECONFIGURE}
34+
{
35+
_pressed = false;
36+
_startPressed = 0;
37+
_fireEvent = false;
38+
_pressedCustomCallback = nullptr;
39+
}
40+
41+
void ResetInput::begin() {
42+
#ifdef ARDUINO_OPTA
43+
pinMode(PIN_RECONFIGURE, INPUT);
44+
#else
45+
pinMode(PIN_RECONFIGURE, INPUT_PULLUP);
46+
#endif
47+
pinMode(LED_RECONFIGURE, OUTPUT);
48+
49+
attachInterrupt(digitalPinToInterrupt(PIN_RECONFIGURE),_pressedCallback, CHANGE);
50+
}
51+
52+
bool ResetInput::isEventFired() {
53+
if(_pressed){
54+
#if defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_SAMD_MKRWIFI1010)
55+
LEDFeedbackClass::getInstance().stop();
56+
#endif
57+
if(micros() - _startPressed > RESET_HOLD_TIME){
58+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_GIGA)
59+
digitalWrite(LED_RECONFIGURE, HIGH);
60+
#else
61+
digitalWrite(LED_RECONFIGURE, LOW);
62+
#endif
63+
}
64+
}
65+
66+
return _fireEvent;
67+
}
68+
69+
void ResetInput::setPinChangedCallback(void (*callback)()) {
70+
_pressedCustomCallback = callback;
71+
}
72+
73+
void ResetInput::setPin(uint32_t pin) {
74+
_pin = pin;
75+
}
76+
77+
void ResetInput::_pressedCallback() {
78+
#if defined(ARDUINO_NANO_RP2040_CONNECT)
79+
if(digitalRead(PIN_RECONFIGURE) == HIGH){
80+
#else
81+
if(digitalRead(PIN_RECONFIGURE) == LOW){
82+
#endif
83+
#if !defined(ARDUINO_NANO_RP2040_CONNECT) && !defined(ARDUINO_SAMD_MKRWIFI1010)
84+
LEDFeedbackClass::getInstance().stop();
85+
#endif
86+
_startPressed = micros();
87+
_pressed = true;
88+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_GIGA)
89+
digitalWrite(LED_RECONFIGURE, LOW);
90+
#else
91+
digitalWrite(LED_RECONFIGURE, HIGH);
92+
#endif
93+
} else {
94+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_GIGA)
95+
digitalWrite(LED_RECONFIGURE, HIGH);
96+
#else
97+
digitalWrite(LED_RECONFIGURE, LOW);
98+
#endif
99+
100+
_pressed = false;
101+
if(_startPressed != 0 && micros() - _startPressed > RESET_HOLD_TIME){
102+
_fireEvent = true;
103+
}else{
104+
LEDFeedbackClass::getInstance().restart();
105+
}
106+
_startPressed = 0;
107+
}
108+
109+
if (_pressedCustomCallback) {
110+
_pressedCustomCallback();
111+
}
112+
}

src/Utility/ResetInput/ResetInput.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright (c) 2024 Arduino SA
3+
4+
This Source Code Form is subject to the terms of the Mozilla Public
5+
License, v. 2.0. If a copy of the MPL was not distributed with this
6+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
9+
#pragma once
10+
11+
#include "Arduino.h"
12+
13+
class ResetInput{
14+
public:
15+
static ResetInput& getInstance();
16+
// Setup the interrupt pin
17+
void begin();
18+
// Monitor if the event is fired
19+
bool isEventFired();
20+
// Add a custom function to be called when the pin status changes. It must be set before calling the begin method
21+
void setPinChangedCallback(void (*callback)());
22+
// Set the pin to be monitored. It must be set before calling the begin method
23+
void setPin(uint32_t pin);
24+
private:
25+
ResetInput();
26+
static inline void (*_pressedCustomCallback)();
27+
uint32_t _pin;
28+
static inline volatile bool _pressed;
29+
static inline volatile bool _fireEvent;
30+
static inline volatile uint32_t _startPressed;
31+
static void _pressedCallback();
32+
};

0 commit comments

Comments
 (0)