Skip to content

Commit d79a1f3

Browse files
authored
Add an aditional (void *) arg to the RMT callback (much like Ticker() et.al.). (#3345)
* Add an aditional (void *) arg to the RMT callback - to allow more flexible handling of the callback (e.g. by passing a private struct or a class pointer). Same pattern as used by the Ticker() and many others. Example updated & new example with a trapoline added. * Fix example for new API * Fix lint warnings * Add a second missed example. * Correct timeout & improve socket error handling.
1 parent 831f0ac commit d79a1f3

File tree

5 files changed

+111
-19
lines changed

5 files changed

+111
-19
lines changed

Diff for: cores/esp32/esp32-hal-rmt.c

+29-10
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct rmt_obj_s
9494
transaction_state_t tx_state;
9595
rmt_rx_data_cb_t cb;
9696
bool data_alloc;
97+
void * arg;
9798
};
9899

99100
/**
@@ -104,14 +105,14 @@ static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = {
104105
};
105106

106107
static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
107-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
108-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
109-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
110-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
111-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
112-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
113-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
114-
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
108+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
109+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
110+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
111+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
112+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
113+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
114+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
115+
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
115116
};
116117

117118
/**
@@ -324,6 +325,7 @@ bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
324325
return true;
325326
}
326327

328+
327329
bool rmtBeginReceive(rmt_obj_t* rmt)
328330
{
329331
if (!rmt) {
@@ -357,14 +359,15 @@ bool rmtReceiveCompleted(rmt_obj_t* rmt)
357359
}
358360
}
359361

360-
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb)
362+
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg)
361363
{
362364
if (!rmt && !cb) {
363365
return false;
364366
}
365367
int channel = rmt->channel;
366368

367369
RMT_MUTEX_LOCK(channel);
370+
rmt->arg = arg;
368371
rmt->intr_mode = E_RX_INTR;
369372
rmt->tx_state = E_FIRST_HALF;
370373
rmt->cb = cb;
@@ -391,6 +394,19 @@ bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb)
391394
return true;
392395
}
393396

397+
bool rmtEnd(rmt_obj_t* rmt) {
398+
if (!rmt) {
399+
return false;
400+
}
401+
int channel = rmt->channel;
402+
403+
RMT_MUTEX_LOCK(channel);
404+
RMT.conf_ch[channel].conf1.rx_en = 1;
405+
RMT_MUTEX_UNLOCK(channel);
406+
407+
return true;
408+
}
409+
394410
bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag, bool waitForData, uint32_t timeout)
395411
{
396412
if (!rmt) {
@@ -523,6 +539,8 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
523539
rmt->tx_not_rx = tx_not_rx;
524540
rmt->buffers =buffers;
525541
rmt->channel = channel;
542+
rmt->arg = NULL;
543+
526544
_initPin(pin, channel, tx_not_rx);
527545

528546
// 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)
544562
RMT.conf_ch[channel].conf1.idle_out_lv = 0; // signal level for idle
545563
RMT.conf_ch[channel].conf1.idle_out_en = 1; // enable idle
546564
RMT.conf_ch[channel].conf1.ref_always_on = 0; // base clock
565+
547566
RMT.apb_conf.fifo_mask = 1;
548567

549568
if (tx_not_rx) {
@@ -659,7 +678,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
659678
}
660679
if (g_rmt_objects[ch].cb) {
661680
// actually received data ptr
662-
(g_rmt_objects[ch].cb)(data_received, _rmt_get_mem_len(ch));
681+
(g_rmt_objects[ch].cb)(data_received, _rmt_get_mem_len(ch), g_rmt_objects[ch].arg);
663682

664683
// restart the reception
665684
RMT.conf_ch[ch].conf1.mem_owner = 1;

Diff for: cores/esp32/esp32-hal-rmt.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ typedef enum {
4040

4141
typedef struct rmt_obj_s rmt_obj_t;
4242

43-
typedef void (*rmt_rx_data_cb_t)(uint32_t *data, size_t len);
43+
typedef void (*rmt_rx_data_cb_t)(uint32_t *data, size_t len, void *arg);
4444

4545
typedef struct {
4646
union {
@@ -90,8 +90,13 @@ bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag
9090
* and callback with data from ISR
9191
*
9292
*/
93-
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb);
93+
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg);
9494

95+
/***
96+
* Ends async receive started with rmtRead(); but does not
97+
* rmtDeInit().
98+
*/
99+
bool rmtEnd(rmt_obj_t* rmt);
95100

96101
/* Additional interface */
97102

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "Arduino.h"
2+
#include "esp32-hal.h"
3+
4+
extern "C" void receive_trampoline(uint32_t *data, size_t len, void * arg);
5+
6+
class MyProcessor {
7+
private:
8+
rmt_obj_t* rmt_recv = NULL;
9+
float realNanoTick;
10+
uint32_t buff; // rolling buffer of most recent 32 bits.
11+
int at = 0;
12+
13+
public:
14+
MyProcessor(uint8_t pin, float nanoTicks) {
15+
assert((rmt_recv = rmtInit(21, false, RMT_MEM_192)));
16+
17+
realNanoTick = rmtSetTick(rmt_recv, nanoTicks);
18+
};
19+
void begin() {
20+
rmtRead(rmt_recv, receive_trampoline, this);
21+
};
22+
23+
void process(rmt_data_t *data, size_t len) {
24+
for (int i = 0; len; len--) {
25+
if (data[i].duration0 == 0)
26+
break;
27+
buff = (buff << 1) | (data[i].level0 ? 1 : 0);
28+
i++;
29+
30+
if (data[i].duration1 == 0)
31+
break;
32+
buff = (buff << 1) | (data[i].level1 ? 1 : 0);
33+
i++;
34+
};
35+
};
36+
uint32_t val() {
37+
return buff;
38+
}
39+
};
40+
41+
void receive_trampoline(uint32_t *data, size_t len, void * arg)
42+
{
43+
MyProcessor * p = (MyProcessor *)arg;
44+
p->process((rmt_data_t*) data, len);
45+
}
46+
47+
// Attach 3 processors to GPIO 4, 5 and 10 with different tick/speeds.
48+
MyProcessor mp1 = MyProcessor(4, 1000);
49+
MyProcessor mp2 = MyProcessor(5, 1000);
50+
MyProcessor mp3 = MyProcessor(10, 500);
51+
52+
void setup()
53+
{
54+
Serial.begin(115200);
55+
mp1.begin();
56+
mp2.begin();
57+
mp3.begin();
58+
}
59+
60+
void loop()
61+
{
62+
Serial.printf("GPIO 4: %08x 5: %08x 6: %08x\n", mp1.val(), mp2.val(), mp3.val());
63+
delay(500);
64+
}

Diff for: libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void parseRmt(rmt_data_t* items, size_t len, uint32_t* channels){
172172
}
173173
}
174174

175-
extern "C" void receive_data(uint32_t *data, size_t len)
175+
extern "C" void receive_data(uint32_t *data, size_t len, void * arg)
176176
{
177177
parseRmt((rmt_data_t*) data, len, channels);
178178
}
@@ -192,7 +192,7 @@ void setup()
192192
Serial.printf("real tick set to: %fns\n", realTick);
193193

194194
// Ask to start reading
195-
rmtRead(rmt_recv, receive_data);
195+
rmtRead(rmt_recv, receive_data, NULL);
196196
}
197197

198198
void loop()

Diff for: libraries/WiFiClientSecure/src/ssl_client.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,16 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
8080

8181
if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) {
8282
if(timeout <= 0){
83-
timeout = 30000;
83+
timeout = 30000; // Milli seconds.
8484
}
85-
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
86-
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
87-
lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
88-
lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
85+
timeval so_timeout = { .tv_sec = timeout / 1000, .tv_usec = (timeout % 1000) * 1000 };
86+
87+
#define ROE(x,msg) { if (((x)<0)) { log_e("LWIP Socket config of " msg " failed."); return -1; }}
88+
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &so_timeout, sizeof(so_timeout)),"SO_RCVTIMEO");
89+
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &so_timeout, sizeof(so_timeout)),"SO_SNDTIMEO");
90+
91+
ROE(lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)),"TCP_NODELAY");
92+
ROE(lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)),"SO_KEEPALIVE");
8993
} else {
9094
log_e("Connect to Server failed!");
9195
return -1;

0 commit comments

Comments
 (0)