Skip to content

Add an aditional (void *) arg to the RMT callback (much like Ticker() et.al.). #3345

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 5 commits into from
Oct 14, 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
39 changes: 29 additions & 10 deletions cores/esp32/esp32-hal-rmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct rmt_obj_s
transaction_state_t tx_state;
rmt_rx_data_cb_t cb;
bool data_alloc;
void * arg;
};

/**
Expand All @@ -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},
};

/**
Expand Down Expand Up @@ -309,6 +310,7 @@ bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
return true;
}


bool rmtBeginReceive(rmt_obj_t* rmt)
{
if (!rmt) {
Expand Down Expand Up @@ -342,14 +344,15 @@ 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;
}
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;
Expand All @@ -376,6 +379,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) {
Expand Down Expand Up @@ -508,6 +524,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:
Expand All @@ -529,6 +547,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) {
Expand Down Expand Up @@ -643,7 +662,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;
Expand Down
9 changes: 7 additions & 2 deletions cores/esp32/esp32-hal-rmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -84,8 +84,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 */

Expand Down
64 changes: 64 additions & 0 deletions libraries/ESP32/examples/RMT/RMTCallback/RMTCallback.ino
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 2 additions & 2 deletions libraries/ESP32/examples/RMT/RMTReadXJT/RMTReadXJT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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()
Expand Down
14 changes: 9 additions & 5 deletions libraries/WiFiClientSecure/src/ssl_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,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;
Expand Down