mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8689 from VeijoPesonen/esp8266-driver_v1.7
Add ESP8266 driver v1.7pull/8836/head
commit
ab1a723611
File diff suppressed because it is too large
Load Diff
|
@ -17,9 +17,16 @@
|
|||
#ifndef ESP8266_H
|
||||
#define ESP8266_H
|
||||
|
||||
#include "ATCmdParser.h"
|
||||
#include "nsapi_types.h"
|
||||
#include "rtos.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#include "drivers/UARTSerial.h"
|
||||
#include "features/netsocket/nsapi_types.h"
|
||||
#include "features/netsocket/WiFiAccessPoint.h"
|
||||
#include "PinNames.h"
|
||||
#include "platform/ATCmdParser.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_error.h"
|
||||
#include "rtos/Mutex.h"
|
||||
|
||||
// Various timeouts for different ESP8266 operations
|
||||
#ifndef ESP8266_CONNECT_TIMEOUT
|
||||
|
@ -35,21 +42,81 @@
|
|||
#define ESP8266_MISC_TIMEOUT 2000
|
||||
#endif
|
||||
|
||||
// Firmware version
|
||||
#define ESP8266_SDK_VERSION 2000000
|
||||
#define ESP8266_SDK_VERSION_MAJOR ESP8266_SDK_VERSION/1000000
|
||||
|
||||
#define ESP8266_AT_VERSION 1000000
|
||||
#define ESP8266_AT_VERSION_MAJOR ESP8266_AT_VERSION/1000000
|
||||
#define ESP8266_AT_VERSION_TCP_PASSIVE_MODE 1070000
|
||||
#define ESP8266_AT_VERSION_WIFI_SCAN_CHANGE 1060000
|
||||
|
||||
#define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
|
||||
(((MAJOR)*1000000+(MINOR)*10000+(PATCH)*100) >= REF ? true : false)
|
||||
|
||||
/** ESP8266Interface class.
|
||||
This is an interface to a ESP8266 radio.
|
||||
*/
|
||||
class ESP8266
|
||||
{
|
||||
class ESP8266 {
|
||||
public:
|
||||
ESP8266(PinName tx, PinName rx, bool debug=false);
|
||||
ESP8266(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC);
|
||||
|
||||
/**
|
||||
* Check firmware version of ESP8266
|
||||
* ESP8266 firmware SDK version
|
||||
*
|
||||
* @return integer firmware version or -1 if firmware query command gives outdated response
|
||||
* @param major Major version number
|
||||
* @param minor Minor version number
|
||||
* @param patch Patch version number
|
||||
*/
|
||||
int get_firmware_version(void);
|
||||
|
||||
struct fw_sdk_version {
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
fw_sdk_version(int major, int minor, int patch) : major(major), minor(minor), patch(patch) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* ESP8266 firmware AT version
|
||||
*
|
||||
* @param major Major version number
|
||||
* @param minor Minor version number
|
||||
* @param patch Patch version number
|
||||
*/
|
||||
struct fw_at_version {
|
||||
int major;
|
||||
int minor;
|
||||
int patch;
|
||||
fw_at_version(int major, int minor, int patch) : major(major), minor(minor), patch(patch) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check AT command interface of ESP8266
|
||||
*
|
||||
* @return true if ready to respond on AT commands
|
||||
*/
|
||||
bool at_available(void);
|
||||
|
||||
/**
|
||||
* Disable echo - required for OOB processing to work
|
||||
*
|
||||
* @return true if echo was successfully disabled
|
||||
*/
|
||||
bool echo_off(void);
|
||||
|
||||
/**
|
||||
* Check sdk version from which firmware is created
|
||||
*
|
||||
* @return fw_sdk_version which tells major, minor and patch version
|
||||
*/
|
||||
struct fw_sdk_version sdk_version(void);
|
||||
|
||||
/**
|
||||
* Check AT instruction set version from which firmware is created
|
||||
*
|
||||
* @return fw_at_version which tells major, minor and patch version
|
||||
*/
|
||||
struct fw_at_version at_version(void);
|
||||
|
||||
/**
|
||||
* Startup the ESP8266
|
||||
*
|
||||
|
@ -79,7 +146,7 @@ public:
|
|||
*
|
||||
* @param ap the name of the AP
|
||||
* @param passPhrase the password of AP
|
||||
* @return NSAPI_ERROR_OK only if ESP8266 is connected successfully
|
||||
* @return NSAPI_ERROR_OK in success, negative error code in failure
|
||||
*/
|
||||
nsapi_error_t connect(const char *ap, const char *passPhrase);
|
||||
|
||||
|
@ -95,34 +162,34 @@ public:
|
|||
*
|
||||
* @return null-teriminated IP address or null if no IP address is assigned
|
||||
*/
|
||||
const char *getIPAddress(void);
|
||||
const char *ip_addr(void);
|
||||
|
||||
/**
|
||||
* Get the MAC address of ESP8266
|
||||
*
|
||||
* @return null-terminated MAC address or null if no MAC address is assigned
|
||||
*/
|
||||
const char *getMACAddress(void);
|
||||
const char *mac_addr(void);
|
||||
|
||||
/** Get the local gateway
|
||||
*
|
||||
* @return Null-terminated representation of the local gateway
|
||||
* or null if no network mask has been recieved
|
||||
*/
|
||||
const char *getGateway();
|
||||
/** Get the local gateway
|
||||
*
|
||||
* @return Null-terminated representation of the local gateway
|
||||
* or null if no network mask has been recieved
|
||||
*/
|
||||
const char *gateway();
|
||||
|
||||
/** Get the local network mask
|
||||
*
|
||||
* @return Null-terminated representation of the local network mask
|
||||
* @return Null-terminated representation of the local network mask
|
||||
* or null if no network mask has been recieved
|
||||
*/
|
||||
const char *getNetmask();
|
||||
const char *netmask();
|
||||
|
||||
/* Return RSSI for active connection
|
||||
*
|
||||
* @return Measured RSSI
|
||||
*/
|
||||
int8_t getRSSI();
|
||||
int8_t rssi();
|
||||
|
||||
/** Scan for available networks
|
||||
*
|
||||
|
@ -132,7 +199,7 @@ public:
|
|||
* see @a nsapi_error
|
||||
*/
|
||||
int scan(WiFiAccessPoint *res, unsigned limit);
|
||||
|
||||
|
||||
/**Perform a dns query
|
||||
*
|
||||
* @param name Hostname to resolve
|
||||
|
@ -150,9 +217,9 @@ public:
|
|||
* @param addr the IP address of the destination
|
||||
* @param port the port on the destination
|
||||
* @param local_port UDP socket's local port, zero means any
|
||||
* @return true only if socket opened successfully
|
||||
* @return NSAPI_ERROR_OK in success, negative error code in failure
|
||||
*/
|
||||
nsapi_error_t open_udp(int id, const char* addr, int port, int local_port = 0);
|
||||
nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0);
|
||||
|
||||
/**
|
||||
* Open a socketed connection
|
||||
|
@ -163,9 +230,9 @@ public:
|
|||
* @param addr the IP address of the destination
|
||||
* @param port the port on the destination
|
||||
* @param tcp_keepalive TCP connection's keep alive time, zero means disabled
|
||||
* @return true only if socket opened successfully
|
||||
* @return NSAPI_ERROR_OK in success, negative error code in failure
|
||||
*/
|
||||
bool open_tcp(int id, const char* addr, int port, int keepalive = 0);
|
||||
nsapi_error_t open_tcp(int id, const char *addr, int port, int keepalive = 0);
|
||||
|
||||
/**
|
||||
* Sends data to an open socket
|
||||
|
@ -185,7 +252,7 @@ public:
|
|||
* @param amount number of bytes to be received
|
||||
* @return the number of bytes received
|
||||
*/
|
||||
int32_t recv_udp(int id, void *data, uint32_t amount, uint32_t timeout=ESP8266_RECV_TIMEOUT);
|
||||
int32_t recv_udp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
|
||||
|
||||
/**
|
||||
* Receives stream data from an open TCP socket
|
||||
|
@ -195,7 +262,7 @@ public:
|
|||
* @param amount number of bytes to be received
|
||||
* @return the number of bytes received
|
||||
*/
|
||||
int32_t recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout=ESP8266_RECV_TIMEOUT);
|
||||
int32_t recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
|
||||
|
||||
/**
|
||||
* Closes a socket
|
||||
|
@ -210,7 +277,7 @@ public:
|
|||
*
|
||||
* @param timeout_ms timeout of the connection
|
||||
*/
|
||||
void setTimeout(uint32_t timeout_ms=ESP8266_MISC_TIMEOUT);
|
||||
void set_timeout(uint32_t timeout_ms = ESP8266_MISC_TIMEOUT);
|
||||
|
||||
/**
|
||||
* Checks if data is available
|
||||
|
@ -236,26 +303,33 @@ public:
|
|||
* @param method pointer to the member function to call
|
||||
*/
|
||||
template <typename T, typename M>
|
||||
void sigio(T *obj, M method) {
|
||||
void sigio(T *obj, M method)
|
||||
{
|
||||
sigio(mbed::Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a function to call whenever network state has changed
|
||||
* Attach a function to call whenever network state has changed.
|
||||
*
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
*/
|
||||
void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
void attach(mbed::Callback<void()> status_cb);
|
||||
|
||||
template <typename T, typename M>
|
||||
void attach(T *obj, M method)
|
||||
{
|
||||
attach(mbed::Callback<void()>(obj, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read default Wifi mode from flash
|
||||
*
|
||||
* return Station, SoftAP or SoftAP+Station - 0 on failure
|
||||
*/
|
||||
int8_t get_default_wifi_mode();
|
||||
int8_t default_wifi_mode();
|
||||
|
||||
/**
|
||||
* Write default Wifi mode to flash
|
||||
* Default Wifi mode written to flash only if changes
|
||||
*/
|
||||
bool set_default_wifi_mode(const int8_t mode);
|
||||
|
||||
|
@ -263,7 +337,34 @@ public:
|
|||
*
|
||||
* @return The connection status according to ConnectionStatusType
|
||||
*/
|
||||
nsapi_connection_status_t get_connection_status() const;
|
||||
nsapi_connection_status_t connection_status() const;
|
||||
|
||||
/**
|
||||
* Start board's and ESP8266's UART flow control
|
||||
*
|
||||
* @return true if started
|
||||
*/
|
||||
bool start_uart_hw_flow_ctrl();
|
||||
|
||||
/**
|
||||
* Stop board's and ESP8266's UART flow control
|
||||
*
|
||||
* @return true if started
|
||||
*/
|
||||
bool stop_uart_hw_flow_ctrl();
|
||||
|
||||
/*
|
||||
* From AT firmware v1.7.0.0 onwards enables TCP passive mode
|
||||
*/
|
||||
bool cond_enable_tcp_passive_mode();
|
||||
|
||||
/**
|
||||
* For executing OOB processing on background
|
||||
*
|
||||
* @param timeout AT parser receive timeout
|
||||
* @param if TRUE, process all OOBs instead of only one
|
||||
*/
|
||||
void bg_process_oob(uint32_t timeout, bool all);
|
||||
|
||||
static const int8_t WIFIMODE_STATION = 1;
|
||||
static const int8_t WIFIMODE_SOFTAP = 2;
|
||||
|
@ -271,39 +372,87 @@ public:
|
|||
static const int8_t SOCKET_COUNT = 5;
|
||||
|
||||
private:
|
||||
// FW version
|
||||
struct fw_sdk_version _sdk_v;
|
||||
struct fw_at_version _at_v;
|
||||
|
||||
// FW version specific settings and functionalities
|
||||
bool _tcp_passive;
|
||||
int32_t _recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout);
|
||||
mbed::Callback<void()> _callback;
|
||||
|
||||
// UART settings
|
||||
mbed::UARTSerial _serial;
|
||||
mbed::ATCmdParser _parser;
|
||||
PinName _serial_rts;
|
||||
PinName _serial_cts;
|
||||
rtos::Mutex _smutex; // Protect serial port access
|
||||
|
||||
// AT Command Parser
|
||||
mbed::ATCmdParser _parser;
|
||||
|
||||
// Wifi scan result handling
|
||||
bool _recv_ap(nsapi_wifi_ap_t *ap);
|
||||
|
||||
// Socket data buffer
|
||||
struct packet {
|
||||
struct packet *next;
|
||||
int id;
|
||||
uint32_t len;
|
||||
uint32_t len; // Remaining length
|
||||
uint32_t alloc_len; // Original length
|
||||
// data follows
|
||||
} *_packets, **_packets_end;
|
||||
void _packet_handler();
|
||||
void _connect_error_handler();
|
||||
bool recv_ap(nsapi_wifi_ap_t *ap);
|
||||
void _oob_socket0_closed_handler();
|
||||
void _oob_socket1_closed_handler();
|
||||
void _oob_socket2_closed_handler();
|
||||
void _oob_socket3_closed_handler();
|
||||
void _oob_socket4_closed_handler();
|
||||
void _connection_status_handler();
|
||||
void _oob_socket_close_error();
|
||||
} *_packets, * *_packets_end;
|
||||
void _clear_socket_packets(int id);
|
||||
int _sock_active_id;
|
||||
|
||||
// Memory statistics
|
||||
size_t _heap_usage; // (Socket data buffer usage)
|
||||
|
||||
// OOB processing
|
||||
void _process_oob(uint32_t timeout, bool all);
|
||||
|
||||
// OOB message handlers
|
||||
void _oob_packet_hdlr();
|
||||
void _oob_connect_err();
|
||||
void _oob_conn_already();
|
||||
void _oob_err();
|
||||
void _oob_socket0_closed();
|
||||
void _oob_socket1_closed();
|
||||
void _oob_socket2_closed();
|
||||
void _oob_socket3_closed();
|
||||
void _oob_socket4_closed();
|
||||
void _oob_connection_status();
|
||||
void _oob_socket_close_err();
|
||||
void _oob_watchdog_reset();
|
||||
void _oob_busy();
|
||||
void _oob_tcp_data_hdlr();
|
||||
|
||||
// OOB state variables
|
||||
int _connect_error;
|
||||
bool _fail;
|
||||
bool _sock_already;
|
||||
bool _closed;
|
||||
bool _error;
|
||||
bool _busy;
|
||||
|
||||
// Modem's address info
|
||||
char _ip_buffer[16];
|
||||
char _gateway_buffer[16];
|
||||
char _netmask_buffer[16];
|
||||
char _mac_buffer[18];
|
||||
|
||||
int _connect_error;
|
||||
bool _fail;
|
||||
bool _closed;
|
||||
int _socket_open[SOCKET_COUNT];
|
||||
nsapi_connection_status_t _connection_status;
|
||||
mbed::Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
|
||||
// Modem's socket info
|
||||
struct _sock_info {
|
||||
bool open;
|
||||
nsapi_protocol_t proto;
|
||||
char *tcp_data;
|
||||
int32_t tcp_data_avbl; // Data waiting on modem
|
||||
int32_t tcp_data_rcvd;
|
||||
};
|
||||
struct _sock_info _sock_i[SOCKET_COUNT];
|
||||
|
||||
// Connection state reporting
|
||||
nsapi_connection_status_t _conn_status;
|
||||
mbed::Callback<void()> _conn_stat_cb; // ESP8266Interface registered
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,80 +14,118 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ESP8266.h"
|
||||
#include "ESP8266Interface.h"
|
||||
#include "mbed_debug.h"
|
||||
#include "nsapi_types.h"
|
||||
#include "events/EventQueue.h"
|
||||
#include "events/mbed_shared_queues.h"
|
||||
#include "features/netsocket/nsapi_types.h"
|
||||
#include "mbed_trace.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_debug.h"
|
||||
|
||||
|
||||
#ifndef MBED_CONF_ESP8266_TX
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#define MBED_CONF_ESP8266_TX D1
|
||||
#else
|
||||
#define MBED_CONF_ESP8266_TX NC
|
||||
#endif
|
||||
#ifndef MBED_CONF_ESP8266_DEBUG
|
||||
#define MBED_CONF_ESP8266_DEBUG false
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_ESP8266_RX
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#define MBED_CONF_ESP8266_RX D0
|
||||
#else
|
||||
#define MBED_CONF_ESP8266_RX NC
|
||||
#endif
|
||||
#ifndef MBED_CONF_ESP8266_RTS
|
||||
#define MBED_CONF_ESP8266_RTS NC
|
||||
#endif
|
||||
|
||||
// Firmware version
|
||||
#define ESP8266_VERSION 2
|
||||
#ifndef MBED_CONF_ESP8266_CTS
|
||||
#define MBED_CONF_ESP8266_CTS NC
|
||||
#endif
|
||||
|
||||
#define TRACE_GROUP "ESPI" // ESP8266 Interface
|
||||
|
||||
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),
|
||||
: _esp(MBED_CONF_ESP8266_TX, MBED_CONF_ESP8266_RX, MBED_CONF_ESP8266_DEBUG, MBED_CONF_ESP8266_RTS, MBED_CONF_ESP8266_CTS),
|
||||
_ap_sec(NSAPI_SECURITY_UNKNOWN),
|
||||
_initialized(false),
|
||||
_started(false)
|
||||
_started(false),
|
||||
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
||||
_conn_stat_cb(NULL),
|
||||
_global_event_queue(NULL),
|
||||
_oob_event_id(0)
|
||||
{
|
||||
memset(_ids, 0, sizeof(_ids));
|
||||
memset(_cbs, 0, sizeof(_cbs));
|
||||
memset(ap_ssid, 0, sizeof(ap_ssid));
|
||||
memset(ap_pass, 0, sizeof(ap_pass));
|
||||
memset(_local_ports, 0, sizeof(_local_ports));
|
||||
ap_sec = NSAPI_SECURITY_UNKNOWN;
|
||||
|
||||
_esp.sigio(this, &ESP8266Interface::event);
|
||||
_esp.setTimeout();
|
||||
_esp.set_timeout();
|
||||
_esp.attach(this, &ESP8266Interface::update_conn_state_cb);
|
||||
|
||||
for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
|
||||
_sock_i[i].open = false;
|
||||
_sock_i[i].sport = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// ESP8266Interface implementation
|
||||
ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug)
|
||||
: _esp(tx, rx, debug),
|
||||
ESP8266Interface::ESP8266Interface(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
|
||||
: _esp(tx, rx, debug, rts, cts),
|
||||
_ap_sec(NSAPI_SECURITY_UNKNOWN),
|
||||
_initialized(false),
|
||||
_started(false)
|
||||
_started(false),
|
||||
_conn_stat(NSAPI_STATUS_DISCONNECTED),
|
||||
_conn_stat_cb(NULL),
|
||||
_global_event_queue(NULL),
|
||||
_oob_event_id(0)
|
||||
{
|
||||
memset(_ids, 0, sizeof(_ids));
|
||||
memset(_cbs, 0, sizeof(_cbs));
|
||||
memset(ap_ssid, 0, sizeof(ap_ssid));
|
||||
memset(ap_pass, 0, sizeof(ap_pass));
|
||||
memset(_local_ports, 0, sizeof(_local_ports));
|
||||
ap_sec = NSAPI_SECURITY_UNKNOWN;
|
||||
|
||||
_esp.sigio(this, &ESP8266Interface::event);
|
||||
_esp.setTimeout();
|
||||
_esp.set_timeout();
|
||||
_esp.attach(this, &ESP8266Interface::update_conn_state_cb);
|
||||
|
||||
for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
|
||||
_sock_i[i].open = false;
|
||||
_sock_i[i].sport = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ESP8266Interface::~ESP8266Interface()
|
||||
{
|
||||
if (_oob_event_id) {
|
||||
_global_event_queue->cancel(_oob_event_id);
|
||||
}
|
||||
}
|
||||
|
||||
int ESP8266Interface::connect(const char *ssid, const char *pass, nsapi_security_t security,
|
||||
uint8_t channel)
|
||||
uint8_t channel)
|
||||
{
|
||||
if (channel != 0) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int err = set_credentials(ssid, pass, security);
|
||||
if(err) {
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return connect();
|
||||
}
|
||||
|
||||
void ESP8266Interface::_oob2global_event_queue()
|
||||
{
|
||||
_global_event_queue = mbed_event_queue();
|
||||
_oob_event_id = _global_event_queue->call_every(ESP8266_RECV_TIMEOUT, callback(this, &ESP8266Interface::proc_oob_evnt));
|
||||
|
||||
if (!_oob_event_id) {
|
||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
|
||||
"ESP8266::_oob2geq: unable to allocate OOB event");
|
||||
}
|
||||
}
|
||||
|
||||
int ESP8266Interface::connect()
|
||||
{
|
||||
nsapi_error_t status;
|
||||
|
@ -96,23 +134,27 @@ int ESP8266Interface::connect()
|
|||
return NSAPI_ERROR_NO_SSID;
|
||||
}
|
||||
|
||||
if (ap_sec != NSAPI_SECURITY_NONE) {
|
||||
if (_ap_sec != NSAPI_SECURITY_NONE) {
|
||||
if (strlen(ap_pass) < ESP8266_PASSPHRASE_MIN_LENGTH) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
status = _init();
|
||||
if(status != NSAPI_ERROR_OK) {
|
||||
if (status != NSAPI_ERROR_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if(get_ip_address()) {
|
||||
if (!_oob_event_id) {
|
||||
_oob2global_event_queue();
|
||||
}
|
||||
|
||||
if (get_ip_address()) {
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
}
|
||||
|
||||
status = _startup(ESP8266::WIFIMODE_STATION);
|
||||
if(status != NSAPI_ERROR_OK) {
|
||||
if (status != NSAPI_ERROR_OK) {
|
||||
return status;
|
||||
}
|
||||
_started = true;
|
||||
|
@ -135,7 +177,7 @@ int ESP8266Interface::connect()
|
|||
|
||||
int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_security_t security)
|
||||
{
|
||||
ap_sec = security;
|
||||
_ap_sec = security;
|
||||
|
||||
if (!ssid) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
|
@ -144,14 +186,14 @@ int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_
|
|||
int ssid_length = strlen(ssid);
|
||||
|
||||
if (ssid_length > 0
|
||||
&& ssid_length <= ESP8266_SSID_MAX_LENGTH) {
|
||||
&& ssid_length <= ESP8266_SSID_MAX_LENGTH) {
|
||||
memset(ap_ssid, 0, sizeof(ap_ssid));
|
||||
strncpy(ap_ssid, ssid, sizeof(ap_ssid));
|
||||
} else {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
if (ap_sec != NSAPI_SECURITY_NONE) {
|
||||
if (_ap_sec != NSAPI_SECURITY_NONE) {
|
||||
|
||||
if (!pass) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
|
@ -159,7 +201,7 @@ int ESP8266Interface::set_credentials(const char *ssid, const char *pass, nsapi_
|
|||
|
||||
int pass_length = strlen(pass);
|
||||
if (pass_length >= ESP8266_PASSPHRASE_MIN_LENGTH
|
||||
&& pass_length <= ESP8266_PASSPHRASE_MAX_LENGTH ) {
|
||||
&& pass_length <= ESP8266_PASSPHRASE_MAX_LENGTH) {
|
||||
memset(ap_pass, 0, sizeof(ap_pass));
|
||||
strncpy(ap_pass, pass, sizeof(ap_pass));
|
||||
} else {
|
||||
|
@ -180,20 +222,26 @@ int ESP8266Interface::set_channel(uint8_t channel)
|
|||
|
||||
int ESP8266Interface::disconnect()
|
||||
{
|
||||
_started = false;
|
||||
_initialized = false;
|
||||
int ret = _esp.disconnect() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
|
||||
|
||||
return _esp.disconnect() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
|
||||
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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *ESP8266Interface::get_ip_address()
|
||||
{
|
||||
if(!_started) {
|
||||
if (!_started) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ip_buff = _esp.getIPAddress();
|
||||
if(!ip_buff || std::strcmp(ip_buff, "0.0.0.0") == 0) {
|
||||
const char *ip_buff = _esp.ip_addr();
|
||||
if (!ip_buff || std::strcmp(ip_buff, "0.0.0.0") == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -202,22 +250,22 @@ const char *ESP8266Interface::get_ip_address()
|
|||
|
||||
const char *ESP8266Interface::get_mac_address()
|
||||
{
|
||||
return _esp.getMACAddress();
|
||||
return _esp.mac_addr();
|
||||
}
|
||||
|
||||
const char *ESP8266Interface::get_gateway()
|
||||
{
|
||||
return _started ? _esp.getGateway() : NULL;
|
||||
return _started ? _esp.gateway() : NULL;
|
||||
}
|
||||
|
||||
const char *ESP8266Interface::get_netmask()
|
||||
{
|
||||
return _started ? _esp.getNetmask() : NULL;
|
||||
return _started ? _esp.netmask() : NULL;
|
||||
}
|
||||
|
||||
int8_t ESP8266Interface::get_rssi()
|
||||
{
|
||||
return _started ? _esp.getRSSI() : 0;
|
||||
return _started ? _esp.rssi() : 0;
|
||||
}
|
||||
|
||||
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
|
||||
|
@ -225,12 +273,12 @@ int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
|
|||
nsapi_error_t status;
|
||||
|
||||
status = _init();
|
||||
if(status != NSAPI_ERROR_OK) {
|
||||
if (status != NSAPI_ERROR_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _startup(ESP8266::WIFIMODE_STATION);
|
||||
if(status != NSAPI_ERROR_OK) {
|
||||
if (status != NSAPI_ERROR_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -239,43 +287,50 @@ int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
|
|||
|
||||
bool ESP8266Interface::_get_firmware_ok()
|
||||
{
|
||||
if (_esp.get_firmware_version() != ESP8266_VERSION) {
|
||||
debug("ESP8266: ERROR: Firmware incompatible with this driver.\
|
||||
\r\nUpdate to v%d - https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update\r\n",ESP8266_VERSION);
|
||||
return false;
|
||||
ESP8266::fw_at_version at_v = _esp.at_version();
|
||||
if (at_v.major < ESP8266_AT_VERSION_MAJOR) {
|
||||
debug("ESP8266: ERROR: AT Firmware v%d incompatible with this driver.", at_v.major);
|
||||
debug("Update at least to v%d - https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update\n", ESP8266_AT_VERSION_MAJOR);
|
||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_UNSUPPORTED), "Too old AT firmware");
|
||||
}
|
||||
ESP8266::fw_sdk_version sdk_v = _esp.sdk_version();
|
||||
if (sdk_v.major < ESP8266_SDK_VERSION_MAJOR) {
|
||||
debug("ESP8266: ERROR: Firmware v%d incompatible with this driver.", sdk_v.major);
|
||||
debug("Update at least to v%d - https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update\n", ESP8266_SDK_VERSION_MAJOR);
|
||||
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_UNSUPPORTED), "Too old SDK firmware");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ESP8266Interface::_disable_default_softap()
|
||||
{
|
||||
static int disabled = false;
|
||||
|
||||
if (disabled || _esp.get_default_wifi_mode() == ESP8266::WIFIMODE_STATION) {
|
||||
disabled = true;
|
||||
return true;
|
||||
}
|
||||
if (_esp.set_default_wifi_mode(ESP8266::WIFIMODE_STATION)) {
|
||||
disabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nsapi_error_t ESP8266Interface::_init(void)
|
||||
{
|
||||
if (!_initialized) {
|
||||
if (!_esp.at_available()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (!_esp.stop_uart_hw_flow_ctrl()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (!_esp.reset()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (!_esp.echo_off()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (!_esp.start_uart_hw_flow_ctrl()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (!_get_firmware_ok()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (_disable_default_softap() == false) {
|
||||
if (!_esp.set_default_wifi_mode(ESP8266::WIFIMODE_STATION)) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (!_esp.cond_enable_tcp_passive_mode()) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
return NSAPI_ERROR_OK;
|
||||
|
@ -305,9 +360,9 @@ int ESP8266Interface::socket_open(void **handle, nsapi_protocol_t proto)
|
|||
int id = -1;
|
||||
|
||||
for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
|
||||
if (!_ids[i]) {
|
||||
if (!_sock_i[i].open) {
|
||||
id = i;
|
||||
_ids[i] = true;
|
||||
_sock_i[i].open = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -343,8 +398,8 @@ int ESP8266Interface::socket_close(void *handle)
|
|||
}
|
||||
|
||||
socket->connected = false;
|
||||
_ids[socket->id] = false;
|
||||
_local_ports[socket->id] = 0;
|
||||
_sock_i[socket->id].open = false;
|
||||
_sock_i[socket->id].sport = 0;
|
||||
delete socket;
|
||||
return err;
|
||||
}
|
||||
|
@ -358,18 +413,18 @@ int ESP8266Interface::socket_bind(void *handle, const SocketAddress &address)
|
|||
}
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if(address.get_addr().version != NSAPI_UNSPEC) {
|
||||
if (address.get_addr().version != NSAPI_UNSPEC) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
for(int id = 0; id < ESP8266_SOCKET_COUNT; id++) {
|
||||
if(_local_ports[id] == address.get_port() && id != socket->id) { // Port already reserved by another socket
|
||||
for (int id = 0; id < ESP8266_SOCKET_COUNT; id++) {
|
||||
if (_sock_i[id].sport == address.get_port() && id != socket->id) { // Port already reserved by another socket
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
} else if (id == socket->id && socket->connected) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
_local_ports[socket->id] = address.get_port();
|
||||
_sock_i[socket->id].sport = address.get_port();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -391,18 +446,14 @@ int ESP8266Interface::socket_connect(void *handle, const SocketAddress &addr)
|
|||
}
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
ret = _esp.open_udp(socket->id, addr.get_ip_address(), addr.get_port(), _local_ports[socket->id]);
|
||||
if (ret != NSAPI_ERROR_OK) {
|
||||
return ret;
|
||||
}
|
||||
ret = _esp.open_udp(socket->id, addr.get_ip_address(), addr.get_port(), _sock_i[socket->id].sport);
|
||||
} else {
|
||||
if (!_esp.open_tcp(socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive)) {
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
ret = _esp.open_tcp(socket->id, addr.get_ip_address(), addr.get_port(), socket->keepalive);
|
||||
}
|
||||
|
||||
socket->connected = true;
|
||||
return 0;
|
||||
socket->connected = (ret == NSAPI_ERROR_OK) ? true : false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ESP8266Interface::socket_accept(void *server, void **socket, SocketAddress *addr)
|
||||
|
@ -453,7 +504,7 @@ int ESP8266Interface::socket_sendto(void *handle, const SocketAddress &addr, con
|
|||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
if((strcmp(addr.get_ip_address(), "0.0.0.0") == 0) || !addr.get_port()) {
|
||||
if ((strcmp(addr.get_ip_address(), "0.0.0.0") == 0) || !addr.get_port()) {
|
||||
return NSAPI_ERROR_DNS_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -499,7 +550,7 @@ void ESP8266Interface::socket_attach(void *handle, void (*callback)(void *), voi
|
|||
}
|
||||
|
||||
nsapi_error_t ESP8266Interface::setsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, const void *optval, unsigned optlen)
|
||||
int optname, const void *optval, unsigned optlen)
|
||||
{
|
||||
struct esp8266_socket *socket = (struct esp8266_socket *)handle;
|
||||
|
||||
|
@ -512,7 +563,7 @@ nsapi_error_t ESP8266Interface::setsockopt(nsapi_socket_t handle, int level,
|
|||
if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) {
|
||||
switch (optname) {
|
||||
case NSAPI_KEEPALIVE: {
|
||||
if(socket->connected) {// ESP8266 limitation, keepalive needs to be given before connecting
|
||||
if (socket->connected) { // ESP8266 limitation, keepalive needs to be given before connecting
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -544,7 +595,7 @@ nsapi_error_t ESP8266Interface::getsockopt(nsapi_socket_t handle, int level, int
|
|||
if (level == NSAPI_SOCKET && socket->proto == NSAPI_TCP) {
|
||||
switch (optname) {
|
||||
case NSAPI_KEEPALIVE: {
|
||||
if(*optlen > sizeof(int)) {
|
||||
if (*optlen > sizeof(int)) {
|
||||
*optlen = sizeof(int);
|
||||
}
|
||||
memcpy(optval, &(socket->keepalive), *optlen);
|
||||
|
@ -566,21 +617,59 @@ void ESP8266Interface::event()
|
|||
}
|
||||
}
|
||||
|
||||
void ESP8266Interface::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
void ESP8266Interface::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
_esp.attach(status_cb);
|
||||
_conn_stat_cb = status_cb;
|
||||
}
|
||||
|
||||
nsapi_connection_status_t ESP8266Interface::get_connection_status() const
|
||||
{
|
||||
return _esp.get_connection_status();
|
||||
return _conn_stat;
|
||||
}
|
||||
|
||||
#if MBED_CONF_ESP8266_PROVIDE_DEFAULT
|
||||
|
||||
WiFiInterface *WiFiInterface::get_default_instance() {
|
||||
WiFiInterface *WiFiInterface::get_default_instance()
|
||||
{
|
||||
static ESP8266Interface esp;
|
||||
return &esp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ESP8266Interface::update_conn_state_cb()
|
||||
{
|
||||
_conn_stat = _esp.connection_status();
|
||||
|
||||
switch (_conn_stat) {
|
||||
// Doesn't require changes
|
||||
case NSAPI_STATUS_CONNECTING:
|
||||
case NSAPI_STATUS_GLOBAL_UP:
|
||||
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;
|
||||
}
|
||||
|
||||
// Inform upper layers
|
||||
if (_conn_stat_cb) {
|
||||
_conn_stat_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _conn_stat);
|
||||
}
|
||||
}
|
||||
|
||||
void ESP8266Interface::proc_oob_evnt()
|
||||
{
|
||||
if (_initialized) {
|
||||
_esp.bg_process_oob(ESP8266_RECV_TIMEOUT, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,30 +17,53 @@
|
|||
#ifndef ESP8266_INTERFACE_H
|
||||
#define ESP8266_INTERFACE_H
|
||||
|
||||
#include "mbed.h"
|
||||
#include "ESP8266.h"
|
||||
|
||||
#include "ESP8266/ESP8266.h"
|
||||
#include "events/EventQueue.h"
|
||||
#include "events/mbed_shared_queues.h"
|
||||
#include "features/netsocket/NetworkInterface.h"
|
||||
#include "features/netsocket/NetworkStack.h"
|
||||
#include "features/netsocket/nsapi_types.h"
|
||||
#include "features/netsocket/SocketAddress.h"
|
||||
#include "features/netsocket/WiFiAccessPoint.h"
|
||||
#include "features/netsocket/WiFiInterface.h"
|
||||
#include "platform/Callback.h"
|
||||
|
||||
#define ESP8266_SOCKET_COUNT 5
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_ESP8266_TX
|
||||
#define MBED_CONF_ESP8266_TX D1
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_ESP8266_RX
|
||||
#define MBED_CONF_ESP8266_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
/** ESP8266Interface class
|
||||
* Implementation of the NetworkStack for the ESP8266
|
||||
*/
|
||||
class ESP8266Interface : public NetworkStack, public WiFiInterface
|
||||
{
|
||||
class ESP8266Interface : public NetworkStack, public WiFiInterface {
|
||||
public:
|
||||
#if defined MBED_CONF_ESP8266_TX && defined MBED_CONF_ESP8266_RX
|
||||
/**
|
||||
* @brief ESP8266Interface default constructor
|
||||
* Will use values defined in mbed_lib.json
|
||||
*/
|
||||
ESP8266Interface();
|
||||
#endif
|
||||
|
||||
/** ESP8266Interface lifetime
|
||||
* @param tx TX pin
|
||||
* @param rx RX pin
|
||||
* @param debug Enable debugging
|
||||
*/
|
||||
ESP8266Interface(PinName tx, PinName rx, bool debug = false);
|
||||
ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC);
|
||||
|
||||
/**
|
||||
* @brief ESP8266Interface default destructor
|
||||
*/
|
||||
virtual ~ESP8266Interface();
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
|
@ -62,7 +85,7 @@ public:
|
|||
* @return 0 on success, or error code on failure
|
||||
*/
|
||||
virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE,
|
||||
uint8_t channel = 0);
|
||||
uint8_t channel = 0);
|
||||
|
||||
/** Set the WiFi network credentials
|
||||
*
|
||||
|
@ -98,11 +121,11 @@ public:
|
|||
*/
|
||||
virtual const char *get_mac_address();
|
||||
|
||||
/** Get the local gateway
|
||||
*
|
||||
* @return Null-terminated representation of the local gateway
|
||||
* or null if no network mask has been recieved
|
||||
*/
|
||||
/** Get the local gateway
|
||||
*
|
||||
* @return Null-terminated representation of the local gateway
|
||||
* or null if no network mask has been recieved
|
||||
*/
|
||||
virtual const char *get_gateway();
|
||||
|
||||
/** Get the local network mask
|
||||
|
@ -156,12 +179,12 @@ public:
|
|||
/** @copydoc NetworkStack::setsockopt
|
||||
*/
|
||||
virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, const void *optval, unsigned optlen);
|
||||
int optname, const void *optval, unsigned optlen);
|
||||
|
||||
/** @copydoc NetworkStack::getsockopt
|
||||
*/
|
||||
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level, int optname,
|
||||
void *optval, unsigned *optlen);
|
||||
void *optval, unsigned *optlen);
|
||||
|
||||
/** Register callback for status reporting
|
||||
*
|
||||
|
@ -292,31 +315,49 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
// AT layer
|
||||
ESP8266 _esp;
|
||||
void update_conn_state_cb();
|
||||
|
||||
// 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 */
|
||||
static const int ESP8266_PASSPHRASE_MAX_LENGTH = 63; /* The longest allowed passphrase */
|
||||
static const int ESP8266_PASSPHRASE_MIN_LENGTH = 8; /* The shortest allowed passphrase */
|
||||
char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1]; /* The longest possible passphrase; +1 for the \0 */
|
||||
nsapi_security_t _ap_sec;
|
||||
|
||||
ESP8266 _esp;
|
||||
bool _ids[ESP8266_SOCKET_COUNT];
|
||||
// Drivers's socket info
|
||||
struct _sock_info {
|
||||
bool open;
|
||||
uint16_t sport;
|
||||
};
|
||||
struct _sock_info _sock_i[ESP8266_SOCKET_COUNT];
|
||||
|
||||
// Driver's state
|
||||
int _initialized;
|
||||
int _started;
|
||||
|
||||
char ap_ssid[ESP8266_SSID_MAX_LENGTH + 1]; /* 32 is what 802.11 defines as longest possible name; +1 for the \0 */
|
||||
nsapi_security_t ap_sec;
|
||||
uint8_t ap_ch;
|
||||
char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1];
|
||||
uint16_t _local_ports[ESP8266_SOCKET_COUNT];
|
||||
|
||||
bool _disable_default_softap();
|
||||
void event();
|
||||
bool _get_firmware_ok();
|
||||
nsapi_error_t _init(void);
|
||||
int _started;
|
||||
nsapi_error_t _startup(const int8_t wifi_mode);
|
||||
|
||||
//sigio
|
||||
struct {
|
||||
void (*callback)(void *);
|
||||
void *data;
|
||||
} _cbs[ESP8266_SOCKET_COUNT];
|
||||
void event();
|
||||
|
||||
// Connection state reporting to application
|
||||
nsapi_connection_status_t _conn_stat;
|
||||
mbed::Callback<void(nsapi_event_t, intptr_t)> _conn_stat_cb;
|
||||
|
||||
// Background OOB processing
|
||||
// Use global EventQueue
|
||||
events::EventQueue *_global_event_queue;
|
||||
int _oob_event_id;
|
||||
void proc_oob_evnt();
|
||||
void _oob2global_event_queue();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,10 +4,97 @@ The Mbed OS driver for the ESP8266 WiFi module.
|
|||
|
||||
## Firmware version
|
||||
|
||||
ESP8266 modules come in different shapes and formats, but the most important factor is the firmware version in it. To make sure that the firmware in your module is compatible with Mbed OS, follow the [Update guide](https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update).
|
||||
ESP8266 modules come in different shapes and formats, but the firmware version is the most important factor. To
|
||||
make sure that the firmware in your module is compatible with Mbed OS, follow the
|
||||
[Update guide](https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update).
|
||||
|
||||
This driver supports AT firmware versions 1.3.0 to 1.7.0. We advise updating the
|
||||
[AT firmware](https://www.espressif.com/en/support/download/at?keys=) to at least version 1.7.0.
|
||||
|
||||
## Restrictions
|
||||
|
||||
- The ESP8266 WiFi module does not allow the TCP client to bind on a specific port.
|
||||
- Setting up a UDP server is not possible.
|
||||
- The serial port does not have hardware flow control enabled. The AT command set does not either have a way to limit the download rate. Therefore, downloading anything larger than the serial port input buffer is unreliable. An application should be able to read fast enough to stay ahead of the network. This affects mostly the TCP protocol where data would be lost with no notification. On UDP, this would lead to only packet losses which the higher layer protocol should recover from.
|
||||
* The ESP8266 Wi-Fi module does not allow the TCP client to bind to a specific port.
|
||||
* Setting up a UDP server is not possible.
|
||||
* The serial port does not have hardware flow control enabled by default. Additionally, the AT command set does not have a method for limiting the download rate. Therefore, downloading anything larger than the serial port input buffer is unreliable
|
||||
unless you use [AT firmware](https://www.espressif.com/en/support/download/at?keys=) version 1.7.0 or later. With older
|
||||
firmware, an application should be able to read fast enough to stay ahead of the network. This applies mostly to TCP
|
||||
protocol, where data would be lost without notification. On UDP using all firmware versions, the higher-layer protocol should recover from packet loss.
|
||||
|
||||
## Mandatory configuration
|
||||
|
||||
 configuration assumes Arduino form factor. Please adjust according to your board. You can override parameters from your app config file.
|
||||
|
||||
At minimum, check the following configuration parameters:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"name": "esp8266",
|
||||
"config": {
|
||||
"tx": {
|
||||
"help": "TX pin for serial connection",
|
||||
"value": null <- 'D1' by default if Arduino, adjust based on your board
|
||||
},
|
||||
"rx": {
|
||||
"help": "RX pin for serial connection",
|
||||
"value": null <- 'D0' by default if Arduino, adjust based on your board
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide default WifiInterface. [true/false]",
|
||||
"value": false <- Set to 'true' if this is the interface you are using
|
||||
},
|
||||
"socket-bufsize": {
|
||||
"help": "Max socket data heap usage",
|
||||
"value": 8192 <- Without HW flow control more is better. Once the limit is reached packets are
|
||||
dropped - does not matter is it TCP or UDP.
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## UART HW flow control
|
||||
|
||||
UART HW flow control requires you to additionally wire the CTS and RTS flow control pins between your board and your
|
||||
ESP8266 module. After this, remember to add the configuration option for flow control to your app configuration file. This example uses the [ST NUCLEO-F429ZI](https://os.mbed.com/platforms/ST-Nucleo-F429ZI/) board and
|
||||
[ESPBee XBee Module](https://www.cascologix.com/product/espbee/).
|
||||
|
||||
**Note:** Not all modules expose ESP8266's RTS and CTS pins, so choose modules carefully.
|
||||
|
||||
Once you have your hardware set up, add a configuration like the following to your app configuration file. Arduino pins D1 and D0 are used as TX and RX:
|
||||
|
||||
``` javascript
|
||||
"target_overrides": {
|
||||
"NUCLEO_F429ZI": {
|
||||
"esp8266.rts": "PG_12",
|
||||
"esp8266.cts": "PG_15"
|
||||
}
|
||||
```
|
||||
|
||||
### Example board pins
|
||||
|
||||
* TX: D1 (Arduino Uno Revision 3 connectivity headers)
|
||||
* RX: D0 (Arduino Uno Revision 3 connectivity headers)
|
||||
* RTS: PG_12 (STMicroelectronics Morpho extension pin headers)
|
||||
* CTS: PG_15 (STMicroelectronics Morpho extension pin headers)
|
||||
|
||||
### Example ESP8266 pins
|
||||
|
||||
* TX: D1 (Arduino Wireless Protoshield headers)/ TX (ESPBee XBee headers)
|
||||
* RX: D0 (Arduino Wireless Protoshield headers)/ RX (ESPBee XBee headers)
|
||||
* RTS: RTS (ESPBee XBee headers)
|
||||
* CTS: CTS (ESPBee XBee headers)
|
||||
|
||||
### Connections
|
||||
|
||||
With these pictures only consider the green and yellow wires which are connected to ESP8266. The pink wire is for reset and
|
||||
the rest are for firmware update. TX and RX go through Arduino pins D1 and D0.
|
||||
|
||||
**Note:** Pull down GPIO15(ESPBee RTS) during startup to **boot from flash**, instead of **firmware update** or
|
||||
**boot from SD card**. Once the software is running, the same pin is used as the RTS pin:
|
||||
|
||||
* Board TX: ESP8266 RX
|
||||
* Board RX: ESP8266 TX
|
||||
* Board RTS (grey): ESP8266 CTS(yellow)
|
||||
* Board CTS (white): ESP8266 RTS(green)
|
||||
|
||||

|
||||

|
||||
|
|
|
@ -2,20 +2,32 @@
|
|||
"name": "esp8266",
|
||||
"config": {
|
||||
"tx": {
|
||||
"help": "TX pin for serial connection",
|
||||
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"rx": {
|
||||
"help": "RX pin for serial connection",
|
||||
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise",
|
||||
"value": null
|
||||
},
|
||||
"rts": {
|
||||
"help": "RTS pin for serial connection, defaults to Not Connected",
|
||||
"value": null
|
||||
},
|
||||
"cts": {
|
||||
"help": "CTS pin for serial connection, defaults to Not Connected",
|
||||
"value": null
|
||||
},
|
||||
"debug": {
|
||||
"help": "Enable debug logs",
|
||||
"help": "Enable debug logs. [true/false]",
|
||||
"value": false
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide default WifiInterface. [true/false]",
|
||||
"value": false
|
||||
},
|
||||
"socket-bufsize": {
|
||||
"help": "Max socket data heap usage",
|
||||
"value": 8192
|
||||
}
|
||||
},
|
||||
"target_overrides": {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.1 MiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 MiB |
Loading…
Reference in New Issue