diff --git a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp index 4efc314672..673cf1f888 100644 --- a/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp +++ b/components/wifi/esp8266-driver/ESP8266/ESP8266.cpp @@ -91,9 +91,18 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts) bool ESP8266::at_available() { + bool ready = false; + _smutex.lock(); - bool ready = _parser.send("AT") - && _parser.recv("OK\n"); + // Might take a while to respond after HW reset + for(int i = 0; i < 5; i++) { + ready = _parser.send("AT") + && _parser.recv("OK\n"); + if (ready) { + break; + } + tr_debug("waiting AT response"); + } _smutex.unlock(); return ready; diff --git a/components/wifi/esp8266-driver/ESP8266Interface.cpp b/components/wifi/esp8266-driver/ESP8266Interface.cpp index 10e8f7c4a2..dfa7bfdf26 100644 --- a/components/wifi/esp8266-driver/ESP8266Interface.cpp +++ b/components/wifi/esp8266-driver/ESP8266Interface.cpp @@ -27,6 +27,7 @@ #include "mbed_trace.h" #include "platform/Callback.h" #include "platform/mbed_debug.h" +#include "platform/mbed_wait_api.h" #ifndef MBED_CONF_ESP8266_DEBUG #define MBED_CONF_ESP8266_DEBUG false @@ -40,6 +41,10 @@ #define MBED_CONF_ESP8266_CTS NC #endif +#ifndef MBED_CONF_ESP8266_RST +#define MBED_CONF_ESP8266_RST NC +#endif + #define TRACE_GROUP "ESPI" // ESP8266 Interface using namespace mbed; @@ -47,6 +52,7 @@ using namespace mbed; #if defined MBED_CONF_ESP8266_TX && defined MBED_CONF_ESP8266_RX ESP8266Interface::ESP8266Interface() : _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS), + _rst_pin(MBED_CONF_ESP8266_RST), // Notice that Pin7 CH_EN cannot be left floating if used as reset _ap_sec(NSAPI_SECURITY_UNKNOWN), _initialized(false), _started(false), @@ -71,8 +77,9 @@ ESP8266Interface::ESP8266Interface() #endif // ESP8266Interface implementation -ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName rts, PinName cts) +ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName rts, PinName cts, PinName rst) : _esp(tx, rx, debug, rts, cts), + _rst_pin(rst), _ap_sec(NSAPI_SECURITY_UNKNOWN), _initialized(false), _started(false), @@ -102,6 +109,35 @@ ESP8266Interface::~ESP8266Interface() } } +ESP8266Interface::ResetPin::ResetPin(PinName rst_pin) : _rst_pin(mbed::DigitalOut(rst_pin, 1)) +{ +} + +void ESP8266Interface::ResetPin::assert() +{ + if (_rst_pin.is_connected()) { + _rst_pin = 0; + // If you happen to use Pin7 CH_EN as reset pin, not needed otherwise + // https://www.espressif.com/sites/default/files/documentation/esp8266_hardware_design_guidelines_en.pdf + wait_us(200); + tr_debug("HW reset asserted"); + } +} + +void ESP8266Interface::ResetPin::deassert() +{ + if (_rst_pin.is_connected()) { + // Notice that Pin7 CH_EN cannot be left floating if used as reset + _rst_pin = 1; + tr_debug("HW reset deasserted"); + } +} + +bool ESP8266Interface::ResetPin::is_connected() +{ + return _rst_pin.is_connected(); +} + int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security, uint8_t channel) { @@ -224,6 +260,8 @@ int ESP8266Interface::set_channel(uint8_t channel) int ESP8266Interface::disconnect() { + _initialized = false; + if (_conn_stat == NSAPI_STATUS_DISCONNECTED) { return NSAPI_ERROR_NO_CONNECTION; @@ -313,6 +351,8 @@ bool ESP8266Interface::_get_firmware_ok() nsapi_error_t ESP8266Interface::_init(void) { if (!_initialized) { + _hw_reset(); + if (!_esp.at_available()) { return NSAPI_ERROR_DEVICE_ERROR; } @@ -343,6 +383,12 @@ nsapi_error_t ESP8266Interface::_init(void) return NSAPI_ERROR_OK; } +void ESP8266Interface::_hw_reset() +{ + _rst_pin.assert(); + _rst_pin.deassert(); +} + nsapi_error_t ESP8266Interface::_startup(const int8_t wifi_mode) { if (!_started) { diff --git a/components/wifi/esp8266-driver/ESP8266Interface.h b/components/wifi/esp8266-driver/ESP8266Interface.h index fadee0375b..a89e92a307 100644 --- a/components/wifi/esp8266-driver/ESP8266Interface.h +++ b/components/wifi/esp8266-driver/ESP8266Interface.h @@ -18,6 +18,7 @@ #define ESP8266_INTERFACE_H #if DEVICE_SERIAL && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_PRESENT) +#include "drivers/DigitalOut.h" #include "ESP8266/ESP8266.h" #include "events/EventQueue.h" #include "events/mbed_shared_queues.h" @@ -59,7 +60,7 @@ public: * @param rx RX pin * @param debug Enable debugging */ - ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC); + ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC, PinName rst = NC); /** * @brief ESP8266Interface default destructor @@ -320,6 +321,18 @@ private: ESP8266 _esp; void update_conn_state_cb(); + // HW reset pin + class ResetPin { + public: + ResetPin(PinName rst_pin); + void assert(); + void deassert(); + bool is_connected(); + private: + mbed::DigitalOut _rst_pin; + } _rst_pin; + + // Credentials static const int ESP8266_SSID_MAX_LENGTH = 32; /* 32 is what 802.11 defines as longest possible name */ char ap_ssid[ESP8266_SSID_MAX_LENGTH + 1]; /* The longest possible name; +1 for the \0 */ @@ -339,6 +352,7 @@ private: int _initialized; bool _get_firmware_ok(); nsapi_error_t _init(void); + void _hw_reset(); int _started; nsapi_error_t _startup(const int8_t wifi_mode); diff --git a/components/wifi/esp8266-driver/mbed_lib.json b/components/wifi/esp8266-driver/mbed_lib.json index 021d696e4a..28337d8077 100644 --- a/components/wifi/esp8266-driver/mbed_lib.json +++ b/components/wifi/esp8266-driver/mbed_lib.json @@ -17,6 +17,10 @@ "help": "CTS pin for serial connection, defaults to Not Connected", "value": null }, + "rst": { + "help": "RESET pin for the modem, defaults to Not Connected", + "value": null + }, "debug": { "help": "Enable debug logs. [true/false]", "value": false