Skip to content

Commit 08d1127

Browse files
authored
Merge pull request #8959 from VeijoPesonen/feature-esp8266_reset_pin
[ESP8266] Adds support for controlling HW reset of the modem from the…
2 parents 85a741e + e4de165 commit 08d1127

File tree

4 files changed

+115
-47
lines changed

4 files changed

+115
-47
lines changed

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,18 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
9191

9292
bool ESP8266::at_available()
9393
{
94+
bool ready = false;
95+
9496
_smutex.lock();
95-
bool ready = _parser.send("AT")
96-
&& _parser.recv("OK\n");
97+
// Might take a while to respond after HW reset
98+
for(int i = 0; i < 5; i++) {
99+
ready = _parser.send("AT")
100+
&& _parser.recv("OK\n");
101+
if (ready) {
102+
break;
103+
}
104+
tr_debug("waiting AT response");
105+
}
97106
_smutex.unlock();
98107

99108
return ready;
@@ -224,22 +233,25 @@ bool ESP8266::startup(int mode)
224233

225234
bool ESP8266::reset(void)
226235
{
236+
bool done = false;
237+
227238
_smutex.lock();
228239
set_timeout(ESP8266_CONNECT_TIMEOUT);
229240

230241
for (int i = 0; i < 2; i++) {
231242
if (_parser.send("AT+RST")
232243
&& _parser.recv("OK\n")
233244
&& _parser.recv("ready")) {
234-
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
235-
_smutex.unlock();
236-
return true;
245+
done = true;
246+
break;
237247
}
238248
}
249+
250+
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
239251
set_timeout();
240252
_smutex.unlock();
241253

242-
return false;
254+
return done;
243255
}
244256

245257
bool ESP8266::dhcp(bool enabled, int mode)
@@ -276,14 +288,14 @@ bool ESP8266::cond_enable_tcp_passive_mode()
276288

277289
nsapi_error_t ESP8266::connect(const char *ap, const char *passPhrase)
278290
{
291+
nsapi_error_t ret = NSAPI_ERROR_OK;
292+
279293
_smutex.lock();
280294
set_timeout(ESP8266_CONNECT_TIMEOUT);
281295

282296
_parser.send("AT+CWJAP_CUR=\"%s\",\"%s\"", ap, passPhrase);
283297
if (!_parser.recv("OK\n")) {
284298
if (_fail) {
285-
_smutex.unlock();
286-
nsapi_error_t ret;
287299
if (_connect_error == 1) {
288300
ret = NSAPI_ERROR_CONNECTION_TIMEOUT;
289301
} else if (_connect_error == 2) {
@@ -293,16 +305,15 @@ nsapi_error_t ESP8266::connect(const char *ap, const char *passPhrase)
293305
} else {
294306
ret = NSAPI_ERROR_NO_CONNECTION;
295307
}
296-
297308
_fail = false;
298309
_connect_error = 0;
299-
return ret;
300310
}
301311
}
312+
302313
set_timeout();
303314
_smutex.unlock();
304315

305-
return NSAPI_ERROR_OK;
316+
return ret;
306317
}
307318

308319
bool ESP8266::disconnect(void)

components/wifi/esp8266-driver/ESP8266Interface.cpp

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "mbed_trace.h"
2828
#include "platform/Callback.h"
2929
#include "platform/mbed_debug.h"
30+
#include "platform/mbed_wait_api.h"
3031

3132
#ifndef MBED_CONF_ESP8266_DEBUG
3233
#define MBED_CONF_ESP8266_DEBUG false
@@ -40,16 +41,20 @@
4041
#define MBED_CONF_ESP8266_CTS NC
4142
#endif
4243

44+
#ifndef MBED_CONF_ESP8266_RST
45+
#define MBED_CONF_ESP8266_RST NC
46+
#endif
47+
4348
#define TRACE_GROUP "ESPI" // ESP8266 Interface
4449

4550
using namespace mbed;
4651

4752
#if defined MBED_CONF_ESP8266_TX && defined MBED_CONF_ESP8266_RX
4853
ESP8266Interface::ESP8266Interface()
4954
: _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS),
55+
_rst_pin(MBED_CONF_ESP8266_RST), // Notice that Pin7 CH_EN cannot be left floating if used as reset
5056
_ap_sec(NSAPI_SECURITY_UNKNOWN),
5157
_initialized(false),
52-
_started(false),
5358
_conn_stat(NSAPI_STATUS_DISCONNECTED),
5459
_conn_stat_cb(NULL),
5560
_global_event_queue(NULL),
@@ -67,15 +72,17 @@ ESP8266Interface::ESP8266Interface()
6772
_sock_i[i].open = false;
6873
_sock_i[i].sport = 0;
6974
}
75+
76+
_oob2global_event_queue();
7077
}
7178
#endif
7279

7380
// ESP8266Interface implementation
74-
ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
81+
ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName rts, PinName cts, PinName rst)
7582
: _esp(tx, rx, debug, rts, cts),
83+
_rst_pin(rst),
7684
_ap_sec(NSAPI_SECURITY_UNKNOWN),
7785
_initialized(false),
78-
_started(false),
7986
_conn_stat(NSAPI_STATUS_DISCONNECTED),
8087
_conn_stat_cb(NULL),
8188
_global_event_queue(NULL),
@@ -93,13 +100,44 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r
93100
_sock_i[i].open = false;
94101
_sock_i[i].sport = 0;
95102
}
103+
104+
_oob2global_event_queue();
96105
}
97106

98107
ESP8266Interface::~ESP8266Interface()
99108
{
100109
if (_oob_event_id) {
101110
_global_event_queue->cancel(_oob_event_id);
102111
}
112+
113+
// Power down the modem
114+
_rst_pin.rst_assert();
115+
}
116+
117+
ESP8266Interface::ResetPin::ResetPin(PinName rst_pin) : _rst_pin(mbed::DigitalOut(rst_pin, 1))
118+
{
119+
}
120+
121+
void ESP8266Interface::ResetPin::rst_assert()
122+
{
123+
if (_rst_pin.is_connected()) {
124+
_rst_pin = 0;
125+
tr_debug("HW reset asserted");
126+
}
127+
}
128+
129+
void ESP8266Interface::ResetPin::rst_deassert()
130+
{
131+
if (_rst_pin.is_connected()) {
132+
// Notice that Pin7 CH_EN cannot be left floating if used as reset
133+
_rst_pin = 1;
134+
tr_debug("HW reset deasserted");
135+
}
136+
}
137+
138+
bool ESP8266Interface::ResetPin::is_connected()
139+
{
140+
return _rst_pin.is_connected();
103141
}
104142

105143
int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
@@ -147,10 +185,6 @@ int ESP8266Interface::connect()
147185
return status;
148186
}
149187

150-
if (!_oob_event_id) {
151-
_oob2global_event_queue();
152-
}
153-
154188
if (get_ip_address()) {
155189
return NSAPI_ERROR_IS_CONNECTED;
156190
}
@@ -159,22 +193,12 @@ int ESP8266Interface::connect()
159193
if (status != NSAPI_ERROR_OK) {
160194
return status;
161195
}
162-
_started = true;
163196

164197
if (!_esp.dhcp(true, 1)) {
165198
return NSAPI_ERROR_DHCP_FAILURE;
166199
}
167200

168-
int connect_error = _esp.connect(ap_ssid, ap_pass);
169-
if (connect_error) {
170-
return connect_error;
171-
}
172-
173-
if (!get_ip_address()) {
174-
return NSAPI_ERROR_DHCP_FAILURE;
175-
}
176-
177-
return NSAPI_ERROR_OK;
201+
return _esp.connect(ap_ssid, ap_pass);
178202
}
179203

180204
int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
@@ -224,6 +248,8 @@ int ESP8266Interface::set_channel(uint8_t channel)
224248

225249
int ESP8266Interface::disconnect()
226250
{
251+
_initialized = false;
252+
227253
if (_conn_stat == NSAPI_STATUS_DISCONNECTED)
228254
{
229255
return NSAPI_ERROR_NO_CONNECTION;
@@ -234,19 +260,23 @@ int ESP8266Interface::disconnect()
234260
if (ret == NSAPI_ERROR_OK) {
235261
// Try to lure the nw status update from ESP8266, might come later
236262
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
237-
// In case the status update arrives later
238-
_conn_stat = NSAPI_STATUS_DISCONNECTED;
263+
// In case the status update arrives later inform upper layers manually
264+
if (_conn_stat != NSAPI_STATUS_DISCONNECTED) {
265+
_conn_stat = NSAPI_STATUS_DISCONNECTED;
266+
if (_conn_stat_cb) {
267+
_conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat);
268+
}
269+
}
239270
}
240271

272+
// Power down the modem
273+
_rst_pin.rst_assert();
274+
241275
return ret;
242276
}
243277

244278
const char *ESP8266Interface::get_ip_address()
245279
{
246-
if (!_started) {
247-
return NULL;
248-
}
249-
250280
const char *ip_buff = _esp.ip_addr();
251281
if (!ip_buff || strcmp(ip_buff, "0.0.0.0") == 0) {
252282
return NULL;
@@ -262,17 +292,17 @@ const char *ESP8266Interface::get_mac_address()
262292

263293
const char *ESP8266Interface::get_gateway()
264294
{
265-
return _started ? _esp.gateway() : NULL;
295+
return _conn_stat != NSAPI_STATUS_DISCONNECTED ? _esp.gateway() : NULL;
266296
}
267297

268298
const char *ESP8266Interface::get_netmask()
269299
{
270-
return _started ? _esp.netmask() : NULL;
300+
return _conn_stat != NSAPI_STATUS_DISCONNECTED ? _esp.netmask() : NULL;
271301
}
272302

273303
int8_t ESP8266Interface::get_rssi()
274304
{
275-
return _started ? _esp.rssi() : 0;
305+
return _esp.rssi();
276306
}
277307

278308
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
@@ -313,6 +343,8 @@ bool ESP8266Interface::_get_firmware_ok()
313343
nsapi_error_t ESP8266Interface::_init(void)
314344
{
315345
if (!_initialized) {
346+
_hw_reset();
347+
316348
if (!_esp.at_available()) {
317349
return NSAPI_ERROR_DEVICE_ERROR;
318350
}
@@ -343,9 +375,18 @@ nsapi_error_t ESP8266Interface::_init(void)
343375
return NSAPI_ERROR_OK;
344376
}
345377

378+
void ESP8266Interface::_hw_reset()
379+
{
380+
_rst_pin.rst_assert();
381+
// If you happen to use Pin7 CH_EN as reset pin, not needed otherwise
382+
// https://www.espressif.com/sites/default/files/documentation/esp8266_hardware_design_guidelines_en.pdf
383+
wait_us(200);
384+
_rst_pin.rst_deassert();
385+
}
386+
346387
nsapi_error_t ESP8266Interface::_startup(const int8_t wifi_mode)
347388
{
348-
if (!_started) {
389+
if (_conn_stat == NSAPI_STATUS_DISCONNECTED) {
349390
if (!_esp.startup(wifi_mode)) {
350391
return NSAPI_ERROR_DEVICE_ERROR;
351392
}
@@ -646,25 +687,26 @@ WiFiInterface *WiFiInterface::get_default_instance()
646687

647688
void ESP8266Interface::update_conn_state_cb()
648689
{
690+
nsapi_connection_status_t prev_stat = _conn_stat;
649691
_conn_stat = _esp.connection_status();
650692

693+
if (prev_stat == _conn_stat) {
694+
return;
695+
}
696+
651697
switch (_conn_stat) {
652698
// Doesn't require changes
653699
case NSAPI_STATUS_CONNECTING:
654700
case NSAPI_STATUS_GLOBAL_UP:
655701
break;
656702
// Start from scratch if connection drops/is dropped
657703
case NSAPI_STATUS_DISCONNECTED:
658-
_started = false;
659704
break;
660705
// Handled on AT layer
661706
case NSAPI_STATUS_LOCAL_UP:
662707
case NSAPI_STATUS_ERROR_UNSUPPORTED:
663708
default:
664-
_started = false;
665709
_initialized = false;
666-
_global_event_queue->cancel(_oob_event_id);
667-
_oob_event_id = 0;
668710
_conn_stat = NSAPI_STATUS_DISCONNECTED;
669711
}
670712

@@ -676,8 +718,6 @@ void ESP8266Interface::update_conn_state_cb()
676718

677719
void ESP8266Interface::proc_oob_evnt()
678720
{
679-
if (_initialized) {
680721
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
681-
}
682722
}
683723
#endif

components/wifi/esp8266-driver/ESP8266Interface.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define ESP8266_INTERFACE_H
1919

2020
#if DEVICE_SERIAL && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_PRESENT)
21+
#include "drivers/DigitalOut.h"
2122
#include "ESP8266/ESP8266.h"
2223
#include "events/EventQueue.h"
2324
#include "events/mbed_shared_queues.h"
@@ -59,7 +60,7 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
5960
* @param rx RX pin
6061
* @param debug Enable debugging
6162
*/
62-
ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC);
63+
ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC, PinName rst = NC);
6364

6465
/**
6566
* @brief ESP8266Interface default destructor
@@ -320,6 +321,18 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
320321
ESP8266 _esp;
321322
void update_conn_state_cb();
322323

324+
// HW reset pin
325+
class ResetPin {
326+
public:
327+
ResetPin(PinName rst_pin);
328+
void rst_assert();
329+
void rst_deassert();
330+
bool is_connected();
331+
private:
332+
mbed::DigitalOut _rst_pin;
333+
} _rst_pin;
334+
335+
323336
// Credentials
324337
static const int ESP8266_SSID_MAX_LENGTH = 32; /* 32 is what 802.11 defines as longest possible name */
325338
char ap_ssid[ESP8266_SSID_MAX_LENGTH + 1]; /* The longest possible name; +1 for the \0 */
@@ -339,7 +352,7 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
339352
int _initialized;
340353
bool _get_firmware_ok();
341354
nsapi_error_t _init(void);
342-
int _started;
355+
void _hw_reset();
343356
nsapi_error_t _startup(const int8_t wifi_mode);
344357

345358
//sigio

0 commit comments

Comments
 (0)