Skip to content

Commit 7eb1ce8

Browse files
Adds RMT End of Transmission Level API (espressif#9238)
* RMT (featt): adds a new function to set EOT level after RMT writing * RMT (feat): adds new feature to set the EOT level after writing RMT channel * adds return value to rmtSetEOT() * adds bool return to rmtSetEOT() * adds return value to the rmtSetEOT() function * FIX (rmt): fixes eot_level setting using flags in the TX structure * RMT(feat): Create RMT_EndOfTransmissionState.ino example * Update cores/esp32/esp32-hal-rmt.h Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> * Update cores/esp32/esp32-hal-rmt.c Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> * Update cores/esp32/esp32-hal-rmt.c Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> --------- Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
1 parent 90036a2 commit 7eb1ce8

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

cores/esp32/esp32-hal-rmt.c

+20-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct rmt_obj_s {
6161
bool rmt_ch_is_looping; // Is this RMT TX Channel in LOOPING MODE?
6262
size_t *num_symbols_read; // Pointer to the number of RMT symbol read by IDF RMT RX Done
6363
uint32_t frequency_Hz; // RMT Frequency
64+
uint8_t rmt_EOT_Level; // RMT End of Transmission Level - default is LOW
6465

6566
#if !CONFIG_DISABLE_HAL_LOCKS
6667
SemaphoreHandle_t g_rmt_objlocks; // Channel Semaphore Lock
@@ -185,6 +186,20 @@ static bool _rmtDetachBus(void *busptr)
185186
Public method definitions
186187
*/
187188

189+
bool rmtSetEOT(int pin, uint8_t EOT_Level)
190+
{
191+
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
192+
if (bus == NULL) {
193+
return false;
194+
}
195+
if (!_rmtCheckDirection(pin, RMT_TX_MODE, __FUNCTION__)) {
196+
return false;
197+
}
198+
199+
bus->rmt_EOT_Level = EOT_Level > 0 ? 1 : 0;
200+
return true;
201+
}
202+
188203
bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t frequency_Hz, float duty_percent)
189204
{
190205
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
@@ -316,6 +331,10 @@ static bool _rmtWrite(int pin, rmt_data_t* data, size_t num_rmt_symbols, bool bl
316331
rmt_enable(bus->rmt_channel_h);
317332
bus->rmt_ch_is_looping = false; // not looping anymore
318333
}
334+
// sets the End of Transmission level to HIGH if the user has requested so
335+
if (bus->rmt_EOT_Level) {
336+
transmit_cfg.flags.eot_level = 1; // EOT is HIGH
337+
}
319338
if (loopCancel) {
320339
// just resets and releases the channel, maybe, already done above, then exits
321340
bus->rmt_ch_is_looping = false;
@@ -487,7 +506,7 @@ bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_
487506
// store the RMT Freq to check Filter and Idle valid values in the RMT API
488507
bus->frequency_Hz = frequency_Hz;
489508
// pulses with width smaller than min_ns will be ignored (as a glitch)
490-
bus->signal_range_min_ns = 0; // disabled
509+
//bus->signal_range_min_ns = 0; // disabled --> not necessary CALLOC set all to ZERO.
491510
// RMT stops reading if the input stays idle for longer than max_ns
492511
bus->signal_range_max_ns = (1000000000 / frequency_Hz) * RMT_LL_MAX_IDLE_VALUE; // maximum possible
493512
// creates the event group to control read_done and write_done

cores/esp32/esp32-hal-rmt.h

+14
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ typedef union {
7676
*/
7777
bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t memsize, uint32_t frequency_Hz);
7878

79+
/**
80+
Sets the End of Transmission level to be set for the <pin> when the RMT transmission ends.
81+
This function affects how rmtWrite(), rmtWriteAsync() or rmtWriteLooping() will set the pin after writing the data.
82+
The default EOT level is LOW, in case this function isn't used before RMT Writing.
83+
This level can be set for each RMT pin and can be changed between writings to the same pin.
84+
85+
<EOT_Level> shall be Zero (LOW) or non-zero (HIGH) value.
86+
It only affects the transmission process, therefore, it doesn't affect any IDLE LEVEL before starting the RMT transmission.
87+
The pre-transmission idle level can be set manually calling, for instance, digitalWrite(pin, Level).
88+
89+
Returns <true> when EOT has been correctly set for <pin>, <false> otherwise.
90+
*/
91+
bool rmtSetEOT(int pin, uint8_t EOT_Level);
92+
7993
/**
8094
Sending data in Blocking Mode.
8195
<rmt_symbol> is a 32 bits structure as defined by rmt_data_t type.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#define BLINK_GPIO 2
2+
#define EOT_INITIAL_STATE_TIME_MS 1000
3+
4+
// BLINK_GPIO shall start at RMT_EOT (HIGH or LOW) as initial state for EOT_INITIAL_STATE_TIME_MS,
5+
// BLINK: 1 second ON, 1 second OFF and then return/stay to RMT_EOT level at the end.
6+
#define RMT_EOT HIGH
7+
8+
// RMT is at 400KHz with a 2.5us tick
9+
// This RMT data sends a 0.5Hz pulse with 1s High and 1s Low signal
10+
rmt_data_t blink_1s_rmt_data[] = {
11+
// 400,000 x 2.5us = 1 second ON
12+
{25000, 1, 25000, 1,},
13+
{25000, 1, 25000, 1,},
14+
{25000, 1, 25000, 1,},
15+
{25000, 1, 25000, 1,},
16+
{25000, 1, 25000, 1,},
17+
{25000, 1, 25000, 1,},
18+
{25000, 1, 25000, 1,},
19+
{25000, 1, 25000, 1,},
20+
// 400,000 x 2.5us = 1 second OFF
21+
{25000, 0, 25000, 0,},
22+
{25000, 0, 25000, 0,},
23+
{25000, 0, 25000, 0,},
24+
{25000, 0, 25000, 0,},
25+
{25000, 0, 25000, 0,},
26+
{25000, 0, 25000, 0,},
27+
{25000, 0, 25000, 0,},
28+
{25000, 0, 25000, 0,},
29+
// Looping mode needs a Zero ending data to mark the EOF
30+
{0, 0, 0, 0}
31+
};
32+
33+
void setup() {
34+
Serial.begin(115200);
35+
Serial.println("Starting Blink testing...");
36+
Serial.flush();
37+
38+
// 1 RMT Block has 64 RMT_SYMBOLS (ESP32|ESP32S2) or 48 RMT_SYMBOLS (ESP32C3|ESP32S3)
39+
if (!rmtInit(BLINK_GPIO, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 400000)) { //2.5us tick
40+
Serial.println("===> rmtInit Error!");
41+
}
42+
43+
// sets the End of Transmission Level to HIGH, after writing to the pin. DEFAULT is LOW.
44+
rmtSetEOT(BLINK_GPIO, RMT_EOT);
45+
// set initial RMT state by writing a single RMT data
46+
rmt_data_t initStateSetup_rmt_data[] = { {1, RMT_EOT, 0, 0} };
47+
rmtWrite(BLINK_GPIO, initStateSetup_rmt_data, RMT_SYMBOLS_OF(initStateSetup_rmt_data), RMT_WAIT_FOR_EVER);
48+
Serial.printf("\nLED GPIO%d start in the inital level %s\n", BLINK_GPIO, RMT_EOT == LOW ? "LOW" : "HIGH");
49+
delay(EOT_INITIAL_STATE_TIME_MS); // set initial state of the LED is set by RMT_EOT.
50+
51+
// Send the data and wait until it is done - set EOT level to HIGH
52+
Serial.printf("\nLED GPIO%d Blinks 1 second HIGH - 1 second LOW.\n", BLINK_GPIO);
53+
if (!rmtWrite(BLINK_GPIO, blink_1s_rmt_data, RMT_SYMBOLS_OF(blink_1s_rmt_data) - 2, RMT_WAIT_FOR_EVER)) {
54+
Serial.println("===> rmtWrite Blink 1s Error!");
55+
}
56+
Serial.printf("\nLED GPIO%d goes to the EOT level %s\n", BLINK_GPIO, RMT_EOT == LOW ? "LOW" : "HIGH");
57+
}
58+
59+
void loop(){}

0 commit comments

Comments
 (0)