Skip to content

Commit 876a397

Browse files
author
Veijo Pesonen
committed
ESP8266: handles reset ready as OOB
Makes possible to recover from spurious resets addiotionally to planned ones.
1 parent f2abdcb commit 876a397

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

components/wifi/esp8266-driver/ESP8266/ESP8266.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "PinNames.h"
2626
#include "platform/Callback.h"
2727
#include "platform/mbed_error.h"
28+
#include "rtos/Kernel.h"
2829

2930
#define TRACE_GROUP "ESPA" // ESP8266 AT layer
3031

@@ -51,6 +52,8 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
5152
_sock_already(false),
5253
_closed(false),
5354
_busy(false),
55+
_reset_check(_rmutex),
56+
_reset_done(false),
5457
_conn_status(NSAPI_STATUS_DISCONNECTED)
5558
{
5659
_serial.set_baud(ESP8266_DEFAULT_BAUD_RATE);
@@ -71,6 +74,7 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
7174
_parser.oob("UNLINK", callback(this, &ESP8266::_oob_socket_close_err));
7275
_parser.oob("ALREADY CONNECTED", callback(this, &ESP8266::_oob_conn_already));
7376
_parser.oob("ERROR", callback(this, &ESP8266::_oob_err));
77+
_parser.oob("ready", callback(this, &ESP8266::_oob_reset));
7478
// Don't expect to find anything about the watchdog reset in official documentation
7579
//https://techtutorialsx.com/2017/01/21/esp8266-watchdog-functions/
7680
_parser.oob("wdt reset", callback(this, &ESP8266::_oob_watchdog_reset));
@@ -234,20 +238,31 @@ bool ESP8266::startup(int mode)
234238

235239
bool ESP8266::reset(void)
236240
{
241+
static const int ESP8266_BOOTTIME = 10000; // [ms]
237242
bool done = false;
238243

239244
_smutex.lock();
240-
set_timeout(ESP8266_CONNECT_TIMEOUT);
241245

242-
for (int i = 0; i < 2; i++) {
243-
if (_parser.send("AT+RST")
244-
&& _parser.recv("OK\n")
245-
&& _parser.recv("ready")) {
246-
done = true;
247-
break;
248-
}
246+
unsigned long int start_time = rtos::Kernel::get_ms_count();
247+
_reset_done = false;
248+
set_timeout(ESP8266_RECV_TIMEOUT);
249+
if (!_parser.send("AT+RST") || !_parser.recv("OK\n")) {
250+
tr_debug("reset(): AT+RST failed or no response");
251+
goto EXIT;
249252
}
250253

254+
_rmutex.lock();
255+
while ((rtos::Kernel::get_ms_count() - start_time < ESP8266_BOOTTIME) && !_reset_done) {
256+
_process_oob(ESP8266_RECV_TIMEOUT, true); // UART mutex claimed -> need to check for OOBs ourselves
257+
_reset_check.wait_for(100); // Arbitrary relatively short delay
258+
}
259+
260+
done = _reset_done;
261+
_rmutex.unlock();
262+
263+
tr_debug("reset(): done: %s", done ? "OK" : "FAIL");
264+
265+
EXIT:
251266
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
252267
set_timeout();
253268
_smutex.unlock();
@@ -963,6 +978,25 @@ void ESP8266::_oob_watchdog_reset()
963978
"_oob_watchdog_reset() modem watchdog reset triggered\n");
964979
}
965980

981+
void ESP8266::_oob_reset()
982+
{
983+
984+
_rmutex.lock();
985+
_reset_done = true;
986+
_reset_check.notify_all();
987+
_rmutex.unlock();
988+
989+
for (int i = 0; i < SOCKET_COUNT; i++) {
990+
_sock_i[i].open = false;
991+
}
992+
993+
// Makes possible to reinitialize
994+
_conn_status = NSAPI_STATUS_ERROR_UNSUPPORTED;
995+
_conn_stat_cb();
996+
997+
tr_debug("_oob_reset(): reset detected");
998+
}
999+
9661000
void ESP8266::_oob_busy()
9671001
{
9681002
char status[5];

components/wifi/esp8266-driver/ESP8266/ESP8266.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "platform/ATCmdParser.h"
2828
#include "platform/Callback.h"
2929
#include "platform/mbed_error.h"
30+
#include "rtos/ConditionVariable.h"
3031
#include "rtos/Mutex.h"
3132

3233
// Various timeouts for different ESP8266 operations
@@ -396,6 +397,7 @@ class ESP8266 {
396397
PinName _serial_rts;
397398
PinName _serial_cts;
398399
rtos::Mutex _smutex; // Protect serial port access
400+
rtos::Mutex _rmutex; // Reset protection
399401

400402
// AT Command Parser
401403
mbed::ATCmdParser _parser;
@@ -435,6 +437,7 @@ class ESP8266 {
435437
void _oob_watchdog_reset();
436438
void _oob_busy();
437439
void _oob_tcp_data_hdlr();
440+
void _oob_reset();
438441

439442
// OOB state variables
440443
int _connect_error;
@@ -444,6 +447,8 @@ class ESP8266 {
444447
bool _closed;
445448
bool _error;
446449
bool _busy;
450+
rtos::ConditionVariable _reset_check;
451+
bool _reset_done;
447452

448453
// Modem's address info
449454
char _ip_buffer[16];

components/wifi/esp8266-driver/ESP8266Interface.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@ int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
577577
return NSAPI_ERROR_NO_SOCKET;
578578
}
579579

580+
if (!_sock_i[socket->id].open) {
581+
return NSAPI_ERROR_CONNECTION_LOST;
582+
}
583+
580584
if (!size) {
581585
// Firmware limitation
582586
return socket->proto == NSAPI_TCP ? 0 : NSAPI_ERROR_UNSUPPORTED;
@@ -604,6 +608,10 @@ int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
604608
return NSAPI_ERROR_NO_SOCKET;
605609
}
606610

611+
if (!_sock_i[socket->id].open) {
612+
return NSAPI_ERROR_CONNECTION_LOST;
613+
}
614+
607615
int32_t recv;
608616
if (socket->proto == NSAPI_TCP) {
609617
recv = _esp.recv_tcp(socket->id, data, size);
@@ -791,6 +799,10 @@ void ESP8266Interface::update_conn_state_cb()
791799
default:
792800
_initialized = false;
793801
_conn_stat = NSAPI_STATUS_DISCONNECTED;
802+
for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
803+
_sock_i[i].open = false;
804+
_sock_i[i].sport = 0;
805+
}
794806
}
795807

796808
// Inform upper layers

0 commit comments

Comments
 (0)