diff --git a/cores/esp32/esp32-hal-rmt.c b/cores/esp32/esp32-hal-rmt.c index 2a36a5e7..07750d96 100644 --- a/cores/esp32/esp32-hal-rmt.c +++ b/cores/esp32/esp32-hal-rmt.c @@ -94,6 +94,7 @@ struct rmt_obj_s transaction_state_t tx_state; rmt_rx_data_cb_t cb; bool data_alloc; + void * arg; }; /** @@ -104,14 +105,14 @@ static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = { }; static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = { - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, - { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, + { false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL}, }; /** @@ -324,6 +325,7 @@ bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size) return true; } + bool rmtBeginReceive(rmt_obj_t* rmt) { if (!rmt) { @@ -357,7 +359,7 @@ bool rmtReceiveCompleted(rmt_obj_t* rmt) } } -bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb) +bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg) { if (!rmt && !cb) { return false; @@ -365,6 +367,7 @@ bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb) int channel = rmt->channel; RMT_MUTEX_LOCK(channel); + rmt->arg = arg; rmt->intr_mode = E_RX_INTR; rmt->tx_state = E_FIRST_HALF; rmt->cb = cb; @@ -391,6 +394,19 @@ bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb) return true; } +bool rmtEnd(rmt_obj_t* rmt) { + if (!rmt) { + return false; + } + int channel = rmt->channel; + + RMT_MUTEX_LOCK(channel); + RMT.conf_ch[channel].conf1.rx_en = 1; + RMT_MUTEX_UNLOCK(channel); + + return true; +} + bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag, bool waitForData, uint32_t timeout) { if (!rmt) { @@ -523,6 +539,8 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize) rmt->tx_not_rx = tx_not_rx; rmt->buffers =buffers; rmt->channel = channel; + rmt->arg = NULL; + _initPin(pin, channel, tx_not_rx); // Initialize the registers in default mode: @@ -544,6 +562,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize) RMT.conf_ch[channel].conf1.idle_out_lv = 0; // signal level for idle RMT.conf_ch[channel].conf1.idle_out_en = 1; // enable idle RMT.conf_ch[channel].conf1.ref_always_on = 0; // base clock + RMT.apb_conf.fifo_mask = 1; if (tx_not_rx) { @@ -659,7 +678,7 @@ static void IRAM_ATTR _rmt_isr(void* arg) } if (g_rmt_objects[ch].cb) { // actually received data ptr - (g_rmt_objects[ch].cb)(data_received, _rmt_get_mem_len(ch)); + (g_rmt_objects[ch].cb)(data_received, _rmt_get_mem_len(ch), g_rmt_objects[ch].arg); // restart the reception RMT.conf_ch[ch].conf1.mem_owner = 1; diff --git a/cores/esp32/esp32-hal-rmt.h b/cores/esp32/esp32-hal-rmt.h index ff6da396..cce6c8c8 100644 --- a/cores/esp32/esp32-hal-rmt.h +++ b/cores/esp32/esp32-hal-rmt.h @@ -40,7 +40,7 @@ typedef enum { typedef struct rmt_obj_s rmt_obj_t; -typedef void (*rmt_rx_data_cb_t)(uint32_t *data, size_t len); +typedef void (*rmt_rx_data_cb_t)(uint32_t *data, size_t len, void *arg); typedef struct { union { @@ -90,8 +90,13 @@ bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag * and callback with data from ISR * */ -bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb); +bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg); +/*** + * Ends async receive started with rmtRead(); but does not + * rmtDeInit(). + */ +bool rmtEnd(rmt_obj_t* rmt); /* Additional interface */ diff --git a/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino b/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino new file mode 100644 index 00000000..6a4c63bc --- /dev/null +++ b/libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino @@ -0,0 +1,64 @@ +#include "Arduino.h" +#include "esp32-hal.h" + +extern "C" void receive_trampoline(uint32_t *data, size_t len, void * arg); + +class MyProcessor { + private: + rmt_obj_t* rmt_recv = NULL; + float realNanoTick; + uint32_t buff; // rolling buffer of most recent 32 bits. + int at = 0; + + public: + MyProcessor(uint8_t pin, float nanoTicks) { + assert((rmt_recv = rmtInit(21, false, RMT_MEM_192))); + + realNanoTick = rmtSetTick(rmt_recv, nanoTicks); + }; + void begin() { + rmtRead(rmt_recv, receive_trampoline, this); + }; + + void process(rmt_data_t *data, size_t len) { + for (int i = 0; len; len--) { + if (data[i].duration0 == 0) + break; + buff = (buff << 1) | (data[i].level0 ? 1 : 0); + i++; + + if (data[i].duration1 == 0) + break; + buff = (buff << 1) | (data[i].level1 ? 1 : 0); + i++; + }; + }; + uint32_t val() { + return buff; + } +}; + +void receive_trampoline(uint32_t *data, size_t len, void * arg) +{ + MyProcessor * p = (MyProcessor *)arg; + p->process((rmt_data_t*) data, len); +} + +// Attach 3 processors to GPIO 4, 5 and 10 with different tick/speeds. +MyProcessor mp1 = MyProcessor(4, 1000); +MyProcessor mp2 = MyProcessor(5, 1000); +MyProcessor mp3 = MyProcessor(10, 500); + +void setup() +{ + Serial.begin(115200); + mp1.begin(); + mp2.begin(); + mp3.begin(); +} + +void loop() +{ + Serial.printf("GPIO 4: %08x 5: %08x 6: %08x\n", mp1.val(), mp2.val(), mp3.val()); + delay(500); +} diff --git a/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino b/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino index 29ab824d..39978d26 100644 --- a/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino +++ b/libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino @@ -172,7 +172,7 @@ void parseRmt(rmt_data_t* items, size_t len, uint32_t* channels){ } } -extern "C" void receive_data(uint32_t *data, size_t len) +extern "C" void receive_data(uint32_t *data, size_t len, void * arg) { parseRmt((rmt_data_t*) data, len, channels); } @@ -192,7 +192,7 @@ void setup() Serial.printf("real tick set to: %fns\n", realTick); // Ask to start reading - rmtRead(rmt_recv, receive_data); + rmtRead(rmt_recv, receive_data, NULL); } void loop() diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/WiFiClientSecure/src/ssl_client.cpp index a1f7dca1..cf328b74 100644 --- a/libraries/WiFiClientSecure/src/ssl_client.cpp +++ b/libraries/WiFiClientSecure/src/ssl_client.cpp @@ -80,12 +80,16 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) { if(timeout <= 0){ - timeout = 30000; + timeout = 30000; // Milli seconds. } - lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); - lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); - lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + timeval so_timeout = { .tv_sec = timeout / 1000, .tv_usec = (timeout % 1000) * 1000 }; + +#define ROE(x,msg) { if (((x)<0)) { log_e("LWIP Socket config of " msg " failed."); return -1; }} + ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &so_timeout, sizeof(so_timeout)),"SO_RCVTIMEO"); + ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &so_timeout, sizeof(so_timeout)),"SO_SNDTIMEO"); + + ROE(lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY"); + ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE"); } else { log_e("Connect to Server failed!"); return -1;