mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8959 from VeijoPesonen/feature-esp8266_reset_pin
[ESP8266] Adds support for controlling HW reset of the modem from the…pull/9051/head
commit
08d1127729
|
@ -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;
|
||||
|
@ -224,6 +233,8 @@ bool ESP8266::startup(int mode)
|
|||
|
||||
bool ESP8266::reset(void)
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
_smutex.lock();
|
||||
set_timeout(ESP8266_CONNECT_TIMEOUT);
|
||||
|
||||
|
@ -231,15 +242,16 @@ bool ESP8266::reset(void)
|
|||
if (_parser.send("AT+RST")
|
||||
&& _parser.recv("OK\n")
|
||||
&& _parser.recv("ready")) {
|
||||
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
|
||||
_smutex.unlock();
|
||||
return true;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
|
||||
set_timeout();
|
||||
_smutex.unlock();
|
||||
|
||||
return false;
|
||||
return done;
|
||||
}
|
||||
|
||||
bool ESP8266::dhcp(bool enabled, int mode)
|
||||
|
@ -276,14 +288,14 @@ bool ESP8266::cond_enable_tcp_passive_mode()
|
|||
|
||||
nsapi_error_t ESP8266::connect(const char *ap, const char *passPhrase)
|
||||
{
|
||||
nsapi_error_t ret = NSAPI_ERROR_OK;
|
||||
|
||||
_smutex.lock();
|
||||
set_timeout(ESP8266_CONNECT_TIMEOUT);
|
||||
|
||||
_parser.send("AT+CWJAP_CUR=\"%s\",\"%s\"", ap, passPhrase);
|
||||
if (!_parser.recv("OK\n")) {
|
||||
if (_fail) {
|
||||
_smutex.unlock();
|
||||
nsapi_error_t ret;
|
||||
if (_connect_error == 1) {
|
||||
ret = NSAPI_ERROR_CONNECTION_TIMEOUT;
|
||||
} else if (_connect_error == 2) {
|
||||
|
@ -293,16 +305,15 @@ nsapi_error_t ESP8266::connect(const char *ap, const char *passPhrase)
|
|||
} else {
|
||||
ret = NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
_fail = false;
|
||||
_connect_error = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
set_timeout();
|
||||
_smutex.unlock();
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ESP8266::disconnect(void)
|
||||
|
|
|
@ -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,9 +52,9 @@ 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),
|
||||
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
||||
_conn_stat_cb(NULL),
|
||||
_global_event_queue(NULL),
|
||||
|
@ -67,15 +72,17 @@ ESP8266Interface::ESP8266Interface()
|
|||
_sock_i[i].open = false;
|
||||
_sock_i[i].sport = 0;
|
||||
}
|
||||
|
||||
_oob2global_event_queue();
|
||||
}
|
||||
#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),
|
||||
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
||||
_conn_stat_cb(NULL),
|
||||
_global_event_queue(NULL),
|
||||
|
@ -93,6 +100,8 @@ ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName r
|
|||
_sock_i[i].open = false;
|
||||
_sock_i[i].sport = 0;
|
||||
}
|
||||
|
||||
_oob2global_event_queue();
|
||||
}
|
||||
|
||||
ESP8266Interface::~ESP8266Interface()
|
||||
|
@ -100,6 +109,35 @@ ESP8266Interface::~ESP8266Interface()
|
|||
if (_oob_event_id) {
|
||||
_global_event_queue->cancel(_oob_event_id);
|
||||
}
|
||||
|
||||
// Power down the modem
|
||||
_rst_pin.rst_assert();
|
||||
}
|
||||
|
||||
ESP8266Interface::ResetPin::ResetPin(PinName rst_pin) : _rst_pin(mbed::DigitalOut(rst_pin, 1))
|
||||
{
|
||||
}
|
||||
|
||||
void ESP8266Interface::ResetPin::rst_assert()
|
||||
{
|
||||
if (_rst_pin.is_connected()) {
|
||||
_rst_pin = 0;
|
||||
tr_debug("HW reset asserted");
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266Interface::ResetPin::rst_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,
|
||||
|
@ -147,10 +185,6 @@ int ESP8266Interface::connect()
|
|||
return status;
|
||||
}
|
||||
|
||||
if (!_oob_event_id) {
|
||||
_oob2global_event_queue();
|
||||
}
|
||||
|
||||
if (get_ip_address()) {
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
}
|
||||
|
@ -159,22 +193,12 @@ int ESP8266Interface::connect()
|
|||
if (status != NSAPI_ERROR_OK) {
|
||||
return status;
|
||||
}
|
||||
_started = true;
|
||||
|
||||
if (!_esp.dhcp(true, 1)) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE;
|
||||
}
|
||||
|
||||
int connect_error = _esp.connect(ap_ssid, ap_pass);
|
||||
if (connect_error) {
|
||||
return connect_error;
|
||||
}
|
||||
|
||||
if (!get_ip_address()) {
|
||||
return NSAPI_ERROR_DHCP_FAILURE;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
return _esp.connect(ap_ssid, ap_pass);
|
||||
}
|
||||
|
||||
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)
|
|||
|
||||
int ESP8266Interface::disconnect()
|
||||
{
|
||||
_initialized = false;
|
||||
|
||||
if (_conn_stat == NSAPI_STATUS_DISCONNECTED)
|
||||
{
|
||||
return NSAPI_ERROR_NO_CONNECTION;
|
||||
|
@ -234,19 +260,23 @@ int ESP8266Interface::disconnect()
|
|||
if (ret == NSAPI_ERROR_OK) {
|
||||
// Try to lure the nw status update from ESP8266, might come later
|
||||
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
|
||||
// In case the status update arrives later
|
||||
_conn_stat = NSAPI_STATUS_DISCONNECTED;
|
||||
// In case the status update arrives later inform upper layers manually
|
||||
if (_conn_stat != NSAPI_STATUS_DISCONNECTED) {
|
||||
_conn_stat = NSAPI_STATUS_DISCONNECTED;
|
||||
if (_conn_stat_cb) {
|
||||
_conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Power down the modem
|
||||
_rst_pin.rst_assert();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *ESP8266Interface::get_ip_address()
|
||||
{
|
||||
if (!_started) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ip_buff = _esp.ip_addr();
|
||||
if (!ip_buff || strcmp(ip_buff, "0.0.0.0") == 0) {
|
||||
return NULL;
|
||||
|
@ -262,17 +292,17 @@ const char *ESP8266Interface::get_mac_address()
|
|||
|
||||
const char *ESP8266Interface::get_gateway()
|
||||
{
|
||||
return _started ? _esp.gateway() : NULL;
|
||||
return _conn_stat != NSAPI_STATUS_DISCONNECTED ? _esp.gateway() : NULL;
|
||||
}
|
||||
|
||||
const char *ESP8266Interface::get_netmask()
|
||||
{
|
||||
return _started ? _esp.netmask() : NULL;
|
||||
return _conn_stat != NSAPI_STATUS_DISCONNECTED ? _esp.netmask() : NULL;
|
||||
}
|
||||
|
||||
int8_t ESP8266Interface::get_rssi()
|
||||
{
|
||||
return _started ? _esp.rssi() : 0;
|
||||
return _esp.rssi();
|
||||
}
|
||||
|
||||
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
|
||||
|
@ -313,6 +343,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,9 +375,18 @@ nsapi_error_t ESP8266Interface::_init(void)
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void ESP8266Interface::_hw_reset()
|
||||
{
|
||||
_rst_pin.rst_assert();
|
||||
// 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);
|
||||
_rst_pin.rst_deassert();
|
||||
}
|
||||
|
||||
nsapi_error_t ESP8266Interface::_startup(const int8_t wifi_mode)
|
||||
{
|
||||
if (!_started) {
|
||||
if (_conn_stat == NSAPI_STATUS_DISCONNECTED) {
|
||||
if (!_esp.startup(wifi_mode)) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
@ -646,8 +687,13 @@ WiFiInterface *WiFiInterface::get_default_instance()
|
|||
|
||||
void ESP8266Interface::update_conn_state_cb()
|
||||
{
|
||||
nsapi_connection_status_t prev_stat = _conn_stat;
|
||||
_conn_stat = _esp.connection_status();
|
||||
|
||||
if (prev_stat == _conn_stat) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_conn_stat) {
|
||||
// Doesn't require changes
|
||||
case NSAPI_STATUS_CONNECTING:
|
||||
|
@ -655,16 +701,12 @@ void ESP8266Interface::update_conn_state_cb()
|
|||
break;
|
||||
// Start from scratch if connection drops/is dropped
|
||||
case NSAPI_STATUS_DISCONNECTED:
|
||||
_started = false;
|
||||
break;
|
||||
// Handled on AT layer
|
||||
case NSAPI_STATUS_LOCAL_UP:
|
||||
case NSAPI_STATUS_ERROR_UNSUPPORTED:
|
||||
default:
|
||||
_started = false;
|
||||
_initialized = false;
|
||||
_global_event_queue->cancel(_oob_event_id);
|
||||
_oob_event_id = 0;
|
||||
_conn_stat = NSAPI_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
|
@ -676,8 +718,6 @@ void ESP8266Interface::update_conn_state_cb()
|
|||
|
||||
void ESP8266Interface::proc_oob_evnt()
|
||||
{
|
||||
if (_initialized) {
|
||||
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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 rst_assert();
|
||||
void rst_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,7 +352,7 @@ private:
|
|||
int _initialized;
|
||||
bool _get_firmware_ok();
|
||||
nsapi_error_t _init(void);
|
||||
int _started;
|
||||
void _hw_reset();
|
||||
nsapi_error_t _startup(const int8_t wifi_mode);
|
||||
|
||||
//sigio
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue