Skip to content

Commit 23e45a4

Browse files
committed
initial version of rmt driver
1 parent c2a669f commit 23e45a4

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

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

+68-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include "freertos/FreeRTOS.h"
2+
#include "freertos/event_groups.h"
3+
14
#include "esp32-hal.h"
25
#include "esp8266-compat.h"
36
#include "soc/gpio_reg.h"
@@ -44,7 +47,7 @@ typedef enum {
4447
struct rmt_obj_s
4548
{
4649
bool allocated;
47-
intr_handle_t intr_handle;
50+
EventGroupHandle_t events;
4851
int pin;
4952
int channel;
5053
bool tx_not_rx;
@@ -61,8 +64,6 @@ static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
6164
};
6265

6366
static intr_handle_t intr_handle;
64-
static int state = 0;
65-
6667

6768
static bool periph_enabled = false;
6869

@@ -181,6 +182,11 @@ bool rmtReceive(rmt_obj_t* rmt, size_t idle_thres)
181182
}
182183
int channel = rmt->channel;
183184

185+
RMT.int_clr.val |= _INT_ERROR(channel);
186+
187+
RMT.int_ena.val |= _INT_ERROR(channel);
188+
189+
RMT.conf_ch[channel].conf1.mem_owner = 1;
184190
RMT.conf_ch[channel].conf0.idle_thres = idle_thres;
185191

186192
RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
@@ -190,6 +196,45 @@ bool rmtReceive(rmt_obj_t* rmt, size_t idle_thres)
190196
return true;
191197
}
192198

199+
bool rmtReceiveAsync(rmt_obj_t* rmt, size_t idle_thres, uint32_t* data, size_t size, void* eventFlag)
200+
{
201+
if (!rmt) {
202+
return false;
203+
}
204+
int channel = rmt->channel;
205+
206+
if (g_rmt_objects[channel].buffers < size/MAX_DATA_PER_CHANNEL) {
207+
return false;
208+
}
209+
210+
if (eventFlag) {
211+
xEventGroupClearBits(eventFlag, RMT_FLAGS_ALL);
212+
rmt->events = eventFlag;
213+
}
214+
215+
if (data && size>0) {
216+
rmt->remaining_ptr = data;
217+
rmt->remaining_to_send = size;
218+
}
219+
220+
rmt->intr_mode = e_rx_intr;
221+
222+
RMT.conf_ch[channel].conf1.mem_owner = 1;
223+
RMT.conf_ch[channel].conf0.idle_thres = idle_thres;
224+
225+
RMT.int_clr.val |= _INT_RX_END(channel);
226+
RMT.int_clr.val |= _INT_ERROR(channel);
227+
228+
RMT.int_ena.val |= _INT_RX_END(channel);
229+
RMT.int_ena.val |= _INT_ERROR(channel);
230+
231+
RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
232+
233+
RMT.conf_ch[channel].conf1.rx_en = 1;
234+
235+
return true;
236+
}
237+
193238

194239
bool rmtSend(rmt_obj_t* rmt, uint32_t* data, size_t size)
195240
{
@@ -354,10 +399,20 @@ static void IRAM_ATTR _rmt_isr(void* arg)
354399
if (intr_val&_INT_RX_END(ch)) {
355400
// clear the flag
356401
RMT.int_clr.val |= _INT_RX_END(ch);
357-
358402
//
359403
if ((g_rmt_objects[ch].intr_mode)&e_rx_intr) {
360-
// Not yet implemented
404+
405+
if (g_rmt_objects[ch].events) {
406+
xEventGroupSetBits(g_rmt_objects[ch].events, RMT_FLAG_RX_DONE);
407+
}
408+
if (g_rmt_objects[ch].remaining_ptr && g_rmt_objects[ch].remaining_to_send > 0) {
409+
size_t i;
410+
for (i = 0; i < g_rmt_objects[ch].remaining_to_send; i++ ) {
411+
*(g_rmt_objects[ch].remaining_ptr)++ = RMTMEM.chan[ch].data32[i].val;
412+
}
413+
}
414+
g_rmt_objects[ch].intr_mode &= ~e_rx_intr;
415+
361416
} else {
362417
// Report error and disable Rx interrupt
363418
ets_printf("Unexpected Rx interrupt!\n");
@@ -368,11 +423,18 @@ static void IRAM_ATTR _rmt_isr(void* arg)
368423
if (intr_val&_INT_ERROR(ch)) {
369424
// clear the flag
370425
RMT.int_clr.val |= _INT_ERROR(ch);
426+
RMT.int_ena.val &= ~_INT_ERROR(ch);
371427
// report error
372-
ets_printf("RMT Error!\n");
428+
ets_printf("RMT Error %d!\n", ch);
429+
if (g_rmt_objects[ch].events) {
430+
xEventGroupSetBits(g_rmt_objects[ch].events, RMT_FLAG_ERROR);
431+
}
373432

433+
// reset memory
374434
RMT.conf_ch[ch].conf1.mem_rd_rst = 1;
375435
RMT.conf_ch[ch].conf1.mem_rd_rst = 0;
436+
RMT.conf_ch[ch].conf1.mem_wr_rst = 1;
437+
RMT.conf_ch[ch].conf1.mem_wr_rst = 0;
376438
}
377439

378440
if (intr_val&_INT_TX_END(ch)) {

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

+17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
extern "C" {
44
#endif
55

6+
// notification flags
7+
#define RMT_FLAG_TX_DONE (1)
8+
#define RMT_FLAG_RX_DONE (2)
9+
#define RMT_FLAG_ERROR (4)
10+
#define RMT_FLAGS_ALL (RMT_FLAG_TX_DONE | RMT_FLAG_RX_DONE | RMT_FLAG_ERROR)
11+
612
struct rmt_obj_s;
713

814
typedef struct rmt_obj_s rmt_obj_t;
@@ -21,8 +27,19 @@ bool rmtSendQueued(rmt_obj_t* rmt, uint32_t* data, size_t size);
2127

2228
bool rmtReceive(rmt_obj_t* rmt, size_t idle_thres);
2329

30+
bool rmtReceiveAsync(rmt_obj_t* rmt, size_t idle_thres, uint32_t* data, size_t size, void* event_flags);
31+
2432
bool rmtWaitForData(rmt_obj_t* rmt, uint32_t* data, size_t size);
2533

34+
35+
// TODO:
36+
// * carrier interface
37+
// * mutexes
38+
// * uninstall interrupt when all channels are deinit
39+
// * send only-conti mode with circular-buffer
40+
// * put sanity checks to some macro or inlines
41+
// * doxy comments
42+
2643
#ifdef __cplusplus
2744
}
2845
#endif

0 commit comments

Comments
 (0)