Skip to content

ESP8266: Convert to Chrono #12433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions components/wifi/esp8266-driver/ESP8266/ESP8266.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@


using namespace mbed;
using namespace std::chrono;
using std::milli;

ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
: _sdk_v(-1, -1, -1),
Expand Down Expand Up @@ -275,12 +277,12 @@ bool ESP8266::startup(int mode)

bool ESP8266::reset(void)
{
static const int ESP8266_BOOTTIME = 10000; // [ms]
static const auto ESP8266_BOOTTIME = 10s;
bool done = false;

_smutex.lock();

unsigned long int start_time = rtos::Kernel::get_ms_count();
auto start_time = rtos::Kernel::Clock::now();
_reset_done = false;
set_timeout(ESP8266_RECV_TIMEOUT);
for (int i = 0; i < 2; i++) {
Expand All @@ -291,10 +293,10 @@ bool ESP8266::reset(void)

while (!_reset_done) {
_process_oob(ESP8266_RECV_TIMEOUT, true); // UART mutex claimed -> need to check for OOBs ourselves
if (_reset_done || (rtos::Kernel::get_ms_count() - start_time >= ESP8266_BOOTTIME)) {
if (_reset_done || rtos::Kernel::Clock::now() - start_time >= ESP8266_BOOTTIME) {
break;
}
rtos::ThisThread::sleep_for(100);
rtos::ThisThread::sleep_for(100ms);
}

done = _reset_done;
Expand Down Expand Up @@ -494,12 +496,12 @@ int8_t ESP8266::rssi()
return rssi;
}

int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned t_max, unsigned t_min)
int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, duration<unsigned, milli> t_max, duration<unsigned, milli> t_min)
{
_smutex.lock();

// Default timeout plus time spend scanning each channel
set_timeout(ESP8266_MISC_TIMEOUT + 13 * (t_max ? t_max : ESP8266_SCAN_TIME_MAX_DEFAULT));
set_timeout(ESP8266_MISC_TIMEOUT + 13 * (t_max != t_max.zero() ? t_max : duration<unsigned, milli>(ESP8266_SCAN_TIME_MAX_DEFAULT)));

_scan_r.res = res;
_scan_r.limit = limit;
Expand All @@ -508,7 +510,7 @@ int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned
bool ret_parse_send = true;

if (FW_AT_LEAST_VERSION(_at_v.major, _at_v.minor, _at_v.patch, 0, ESP8266_AT_VERSION_WIFI_SCAN_CHANGE)) {
ret_parse_send = _parser.send("AT+CWLAP=,,,%u,%u,%u", (mode == SCANMODE_ACTIVE ? 0 : 1), t_min, t_max);
ret_parse_send = _parser.send("AT+CWLAP=,,,%u,%u,%u", (mode == SCANMODE_ACTIVE ? 0 : 1), t_min.count(), t_max.count());
} else {
ret_parse_send = _parser.send("AT+CWLAP");
}
Expand Down Expand Up @@ -844,7 +846,7 @@ void ESP8266::_oob_packet_hdlr()
_packets_end = &packet->next;
}

void ESP8266::_process_oob(uint32_t timeout, bool all)
void ESP8266::_process_oob(duration<uint32_t, milli> timeout, bool all)
{
set_timeout(timeout);
// Poll for inbound packets
Expand All @@ -853,14 +855,14 @@ void ESP8266::_process_oob(uint32_t timeout, bool all)
set_timeout();
}

void ESP8266::bg_process_oob(uint32_t timeout, bool all)
void ESP8266::bg_process_oob(duration<uint32_t, milli> timeout, bool all)
{
_smutex.lock();
_process_oob(timeout, all);
_smutex.unlock();
}

int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout)
int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, duration<uint32_t, milli> timeout)
{
int32_t ret = NSAPI_ERROR_WOULD_BLOCK;

Expand Down Expand Up @@ -923,7 +925,7 @@ int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t
return ret;
}

int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, duration<uint32_t, milli> timeout)
{
if (_tcp_passive) {
return _recv_tcp_passive(id, data, amount, timeout);
Expand Down Expand Up @@ -981,7 +983,7 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
return NSAPI_ERROR_WOULD_BLOCK;
}

int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout)
int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, duration<uint32_t, milli> timeout)
{
_smutex.lock();
set_timeout(timeout);
Expand Down Expand Up @@ -1099,9 +1101,9 @@ bool ESP8266::close(int id)
return false;
}

void ESP8266::set_timeout(uint32_t timeout_ms)
void ESP8266::set_timeout(duration<uint32_t, milli> timeout)
{
_parser.set_timeout(timeout_ms);
_parser.set_timeout(timeout.count());
}

bool ESP8266::readable()
Expand Down Expand Up @@ -1172,7 +1174,7 @@ bool ESP8266::get_sntp_time(std::tm *t)
memset(buf, 0, 25);

bool done = _parser.send("AT+CIPSNTPTIME?")
&& _parser.scanf("+CIPSNTPTIME:%24c", &buf)
&& _parser.scanf("+CIPSNTPTIME:%24c", buf)
&& _parser.recv("OK\n");
_smutex.unlock();

Expand Down
37 changes: 21 additions & 16 deletions components/wifi/esp8266-driver/ESP8266/ESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,35 @@
#include "PinNames.h"
#include "platform/ATCmdParser.h"
#include "platform/Callback.h"
#include "platform/mbed_chrono.h"
#include "platform/mbed_error.h"
#include "rtos/Mutex.h"
#include "rtos/ThisThread.h"
#include "features/netsocket/SocketAddress.h"

// Various timeouts for different ESP8266 operations
// (some of these can't use literal form as they're needed for defaults in this header, where
// we shouldn't add a using directive for them. Defines only used in the C++ file can use literals).
#ifndef ESP8266_CONNECT_TIMEOUT
#define ESP8266_CONNECT_TIMEOUT 15000
#define ESP8266_CONNECT_TIMEOUT 15s
#endif
#ifndef ESP8266_SEND_TIMEOUT
#define ESP8266_SEND_TIMEOUT 2000
#define ESP8266_SEND_TIMEOUT 2s
#endif
#ifndef ESP8266_RECV_TIMEOUT
#define ESP8266_RECV_TIMEOUT 2000
#define ESP8266_RECV_TIMEOUT std::chrono::seconds(2)
#endif
#ifndef ESP8266_MISC_TIMEOUT
#define ESP8266_MISC_TIMEOUT 2000
#define ESP8266_MISC_TIMEOUT std::chrono::seconds(2)
#endif
#ifndef ESP8266_DNS_TIMEOUT
#define ESP8266_DNS_TIMEOUT 15000
#define ESP8266_DNS_TIMEOUT 15s
#endif

#define ESP8266_SCAN_TIME_MIN 0 // [ms]
#define ESP8266_SCAN_TIME_MAX 1500 // [ms]
#define ESP8266_SCAN_TIME_MIN_DEFAULT 120 // [ms]
#define ESP8266_SCAN_TIME_MAX_DEFAULT 360 // [ms]
#define ESP8266_SCAN_TIME_MIN 0ms
#define ESP8266_SCAN_TIME_MAX 1500ms
#define ESP8266_SCAN_TIME_MIN_DEFAULT 120ms
#define ESP8266_SCAN_TIME_MAX_DEFAULT 360ms

// Firmware version
#define ESP8266_SDK_VERSION 2000000
Expand Down Expand Up @@ -237,7 +240,9 @@ class ESP8266 {
* @return Number of entries in @a res, or if @a count was 0 number of available networks, negative on error
* see @a nsapi_error
*/
int scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned t_max, unsigned t_min);
int scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode,
std::chrono::duration<unsigned, std::milli> t_max,
std::chrono::duration<unsigned, std::milli> t_min);

/**Perform a dns query
*
Expand Down Expand Up @@ -292,7 +297,7 @@ class ESP8266 {
* @param amount number of bytes to be received
* @return the number of bytes received
*/
int32_t recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
int32_t recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, mbed::chrono::milliseconds_u32 timeout = ESP8266_RECV_TIMEOUT);

/**
* Receives stream data from an open TCP socket
Expand All @@ -302,7 +307,7 @@ class ESP8266 {
* @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, mbed::chrono::milliseconds_u32 timeout = ESP8266_RECV_TIMEOUT);

/**
* Closes a socket
Expand All @@ -317,7 +322,7 @@ class ESP8266 {
*
* @param timeout_ms timeout of the connection
*/
void set_timeout(uint32_t timeout_ms = ESP8266_MISC_TIMEOUT);
void set_timeout(mbed::chrono::milliseconds_u32 timeout = ESP8266_MISC_TIMEOUT);

/**
* Checks if data is available
Expand Down Expand Up @@ -454,7 +459,7 @@ class ESP8266 {
* @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);
void bg_process_oob(std::chrono::duration<uint32_t, std::milli> timeout, bool all);

/**
* Flush the serial port input buffers.
Expand Down Expand Up @@ -485,7 +490,7 @@ class ESP8266 {

// FW version specific settings and functionalities
bool _tcp_passive;
int32_t _recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout);
int32_t _recv_tcp_passive(int id, void *data, uint32_t amount, std::chrono::duration<uint32_t, std::milli> timeout);
mbed::Callback<void()> _callback;

// UART settings
Expand Down Expand Up @@ -518,7 +523,7 @@ class ESP8266 {
size_t _heap_usage; // (Socket data buffer usage)

// OOB processing
void _process_oob(uint32_t timeout, bool all);
void _process_oob(std::chrono::duration<uint32_t, std::milli> timeout, bool all);

// OOB message handlers
void _oob_packet_hdlr();
Expand Down
40 changes: 25 additions & 15 deletions components/wifi/esp8266-driver/ESP8266Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "platform/mbed_debug.h"
#include "rtos/ThisThread.h"

using namespace std::chrono;

#ifndef MBED_CONF_ESP8266_DEBUG
#define MBED_CONF_ESP8266_DEBUG false
#endif
Expand Down Expand Up @@ -196,7 +198,7 @@ void ESP8266Interface::PowerPin::power_on()
if (_pwr_pin.is_connected()) {
_pwr_pin = MBED_CONF_ESP8266_POWER_ON_POLARITY;
tr_debug("power_on(): HW power-on.");
ThisThread::sleep_for(MBED_CONF_ESP8266_POWER_ON_TIME_MS);
ThisThread::sleep_for(milliseconds(MBED_CONF_ESP8266_POWER_ON_TIME_MS));
}
}

Expand All @@ -205,7 +207,7 @@ void ESP8266Interface::PowerPin::power_off()
if (_pwr_pin.is_connected()) {
_pwr_pin = !MBED_CONF_ESP8266_POWER_ON_POLARITY;
tr_debug("power_off(): HW power-off.");
ThisThread::sleep_for(MBED_CONF_ESP8266_POWER_OFF_TIME_MS);
ThisThread::sleep_for(milliseconds(MBED_CONF_ESP8266_POWER_OFF_TIME_MS));
}
}

Expand Down Expand Up @@ -260,14 +262,14 @@ void ESP8266Interface::_connect_async()
return;
}
_connect_retval = _esp.connect(ap_ssid, ap_pass);
int timeleft_ms = ESP8266_INTERFACE_CONNECT_TIMEOUT_MS - _conn_timer.read_ms();
auto timepassed = _conn_timer.elapsed_time();
if (_connect_retval == NSAPI_ERROR_OK
|| _connect_retval == NSAPI_ERROR_AUTH_FAILURE
|| _connect_retval == NSAPI_ERROR_NO_SSID
|| ((_if_blocking == true) && (timeleft_ms <= 0))) {
|| ((_if_blocking == true) && (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT))) {
_connect_event_id = 0;
_conn_timer.stop();
if (timeleft_ms <= 0 && _connect_retval != NSAPI_ERROR_OK) {
if (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT && _connect_retval != NSAPI_ERROR_OK) {
_connect_retval = NSAPI_ERROR_CONNECTION_TIMEOUT;
}
if (_connect_retval != NSAPI_ERROR_OK) {
Expand All @@ -279,7 +281,7 @@ void ESP8266Interface::_connect_async()
#endif
} else {
// Postpone to give other stuff time to run
_connect_event_id = _global_event_queue->call_in(ESP8266_INTERFACE_CONNECT_INTERVAL_MS,
_connect_event_id = _global_event_queue->call_in(ESP8266_INTERFACE_CONNECT_INTERVAL,
callback(this, &ESP8266Interface::_connect_async));
if (!_connect_event_id) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
Expand Down Expand Up @@ -411,11 +413,11 @@ void ESP8266Interface::_disconnect_async()
{
_cmutex.lock();
_disconnect_retval = _esp.disconnect() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
int timeleft_ms = ESP8266_INTERFACE_CONNECT_TIMEOUT_MS - _conn_timer.read_ms();
auto timepassed = _conn_timer.elapsed_time();

if (_disconnect_retval == NSAPI_ERROR_OK || ((_if_blocking == true) && (timeleft_ms <= 0))) {
if (_disconnect_retval == NSAPI_ERROR_OK || ((_if_blocking == true) && (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT))) {

if (timeleft_ms <= 0 && _connect_retval != NSAPI_ERROR_OK) {
if (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT && _connect_retval != NSAPI_ERROR_OK) {
_disconnect_retval = NSAPI_ERROR_CONNECTION_TIMEOUT;
} else {
if (_conn_stat != NSAPI_STATUS_DISCONNECTED) {
Expand All @@ -436,7 +438,7 @@ void ESP8266Interface::_disconnect_async()
} else {
// Postpone to give other stuff time to run
_disconnect_event_id = _global_event_queue->call_in(
ESP8266_INTERFACE_CONNECT_INTERVAL_MS,
ESP8266_INTERFACE_CONNECT_INTERVAL,
callback(this, &ESP8266Interface::_disconnect_async));
if (!_disconnect_event_id) {
MBED_ERROR(
Expand Down Expand Up @@ -612,10 +614,10 @@ int8_t ESP8266Interface::get_rssi()

int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
{
return scan(res, count, SCANMODE_ACTIVE, 0, 0);
return scan(res, count, SCANMODE_ACTIVE);
}

int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count, scan_mode mode, unsigned t_max, unsigned t_min)
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count, scan_mode mode, mbed::chrono::milliseconds_u32 t_max, mbed::chrono::milliseconds_u32 t_min)
{
if (t_max > ESP8266_SCAN_TIME_MAX) {
return NSAPI_ERROR_PARAMETER;
Expand Down Expand Up @@ -735,7 +737,15 @@ nsapi_error_t ESP8266Interface::_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
ThisThread::sleep_for(2); // Documentation says 200 us; need 2 ticks to get minimum 1 ms.
// First need to round up when converting to kernel ticks (eg 200us -> 1ms).
auto delay = duration_cast<Kernel::Clock::duration_u32>(200us);
if (delay < 200us) {
delay++;
}
// Then need to round the clock-resolution duration up; if we were at the end of a tick
// period, it might flip immediately.
delay++;
ThisThread::sleep_for(delay);
_esp.flush();
_rst_pin.rst_deassert();
} else {
Expand Down Expand Up @@ -898,7 +908,7 @@ int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
&& socket->proto == NSAPI_TCP
&& core_util_atomic_cas_u8(&_cbs[socket->id].deferred, &expect_false, true)) {
tr_debug("socket_send(...): Postponing SIGIO from the device.");
if (!_global_event_queue->call_in(50, callback(this, &ESP8266Interface::event_deferred))) {
if (!_global_event_queue->call_in(50ms, callback(this, &ESP8266Interface::event_deferred))) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
"socket_send(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");
}
Expand Down Expand Up @@ -1055,7 +1065,7 @@ void ESP8266Interface::event()
{
if (!_oob_event_id) {
// Throttles event creation by using arbitrary small delay
_oob_event_id = _global_event_queue->call_in(50, callback(this, &ESP8266Interface::proc_oob_evnt));
_oob_event_id = _global_event_queue->call_in(50ms, callback(this, &ESP8266Interface::proc_oob_evnt));
if (!_oob_event_id) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
"ESP8266Interface::event(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");
Expand Down
8 changes: 5 additions & 3 deletions components/wifi/esp8266-driver/ESP8266Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,16 @@
#include "features/netsocket/WiFiAccessPoint.h"
#include "features/netsocket/WiFiInterface.h"
#include "platform/Callback.h"
#include "platform/mbed_chrono.h"
#if MBED_CONF_RTOS_PRESENT
#include "rtos/ConditionVariable.h"
#endif
#include "rtos/Mutex.h"

#define ESP8266_SOCKET_COUNT 5

#define ESP8266_INTERFACE_CONNECT_INTERVAL_MS (5000)
#define ESP8266_INTERFACE_CONNECT_TIMEOUT_MS (2 * ESP8266_CONNECT_TIMEOUT + ESP8266_INTERFACE_CONNECT_INTERVAL_MS)
#define ESP8266_INTERFACE_CONNECT_INTERVAL 5s
#define ESP8266_INTERFACE_CONNECT_TIMEOUT (2 * ESP8266_CONNECT_TIMEOUT + ESP8266_INTERFACE_CONNECT_INTERVAL)

#ifdef TARGET_FF_ARDUINO
#ifndef MBED_CONF_ESP8266_TX
Expand Down Expand Up @@ -219,7 +220,8 @@ class ESP8266Interface : public NetworkStack, public WiFiInterface {
* see @a nsapi_error
*/
virtual int scan(WiFiAccessPoint *res, unsigned count, scan_mode mode = SCANMODE_PASSIVE,
unsigned t_max = 0, unsigned t_min = 0);
mbed::chrono::milliseconds_u32 t_max = mbed::chrono::milliseconds_u32(0),
mbed::chrono::milliseconds_u32 t_min = mbed::chrono::milliseconds_u32(0));

/** Translates a hostname to an IP address with specific version
*
Expand Down