Unverified Commit 7eb1ce89 authored by Rodrigo Garcia's avatar Rodrigo Garcia Committed by GitHub

Adds RMT End of Transmission Level API (#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: default avatarJan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>

* Update cores/esp32/esp32-hal-rmt.c
Co-authored-by: default avatarJan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>

* Update cores/esp32/esp32-hal-rmt.c
Co-authored-by: default avatarJan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>

---------
Co-authored-by: default avatarJan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com>
parent 90036a2c
......@@ -61,6 +61,7 @@ struct rmt_obj_s {
bool rmt_ch_is_looping; // Is this RMT TX Channel in LOOPING MODE?
size_t *num_symbols_read; // Pointer to the number of RMT symbol read by IDF RMT RX Done
uint32_t frequency_Hz; // RMT Frequency
uint8_t rmt_EOT_Level; // RMT End of Transmission Level - default is LOW
#if !CONFIG_DISABLE_HAL_LOCKS
SemaphoreHandle_t g_rmt_objlocks; // Channel Semaphore Lock
......@@ -185,6 +186,20 @@ static bool _rmtDetachBus(void *busptr)
Public method definitions
*/
bool rmtSetEOT(int pin, uint8_t EOT_Level)
{
rmt_bus_handle_t bus = _rmtGetBus(pin, __FUNCTION__);
if (bus == NULL) {
return false;
}
if (!_rmtCheckDirection(pin, RMT_TX_MODE, __FUNCTION__)) {
return false;
}
bus->rmt_EOT_Level = EOT_Level > 0 ? 1 : 0;
return true;
}
bool rmtSetCarrier(int pin, bool carrier_en, bool carrier_level, uint32_t frequency_Hz, float duty_percent)
{
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
rmt_enable(bus->rmt_channel_h);
bus->rmt_ch_is_looping = false; // not looping anymore
}
// sets the End of Transmission level to HIGH if the user has requested so
if (bus->rmt_EOT_Level) {
transmit_cfg.flags.eot_level = 1; // EOT is HIGH
}
if (loopCancel) {
// just resets and releases the channel, maybe, already done above, then exits
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_
// store the RMT Freq to check Filter and Idle valid values in the RMT API
bus->frequency_Hz = frequency_Hz;
// pulses with width smaller than min_ns will be ignored (as a glitch)
bus->signal_range_min_ns = 0; // disabled
//bus->signal_range_min_ns = 0; // disabled --> not necessary CALLOC set all to ZERO.
// RMT stops reading if the input stays idle for longer than max_ns
bus->signal_range_max_ns = (1000000000 / frequency_Hz) * RMT_LL_MAX_IDLE_VALUE; // maximum possible
// creates the event group to control read_done and write_done
......
......@@ -76,6 +76,20 @@ typedef union {
*/
bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t memsize, uint32_t frequency_Hz);
/**
Sets the End of Transmission level to be set for the <pin> when the RMT transmission ends.
This function affects how rmtWrite(), rmtWriteAsync() or rmtWriteLooping() will set the pin after writing the data.
The default EOT level is LOW, in case this function isn't used before RMT Writing.
This level can be set for each RMT pin and can be changed between writings to the same pin.
<EOT_Level> shall be Zero (LOW) or non-zero (HIGH) value.
It only affects the transmission process, therefore, it doesn't affect any IDLE LEVEL before starting the RMT transmission.
The pre-transmission idle level can be set manually calling, for instance, digitalWrite(pin, Level).
Returns <true> when EOT has been correctly set for <pin>, <false> otherwise.
*/
bool rmtSetEOT(int pin, uint8_t EOT_Level);
/**
Sending data in Blocking Mode.
<rmt_symbol> is a 32 bits structure as defined by rmt_data_t type.
......
#define BLINK_GPIO 2
#define EOT_INITIAL_STATE_TIME_MS 1000
// BLINK_GPIO shall start at RMT_EOT (HIGH or LOW) as initial state for EOT_INITIAL_STATE_TIME_MS,
// BLINK: 1 second ON, 1 second OFF and then return/stay to RMT_EOT level at the end.
#define RMT_EOT HIGH
// RMT is at 400KHz with a 2.5us tick
// This RMT data sends a 0.5Hz pulse with 1s High and 1s Low signal
rmt_data_t blink_1s_rmt_data[] = {
// 400,000 x 2.5us = 1 second ON
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
{25000, 1, 25000, 1,},
// 400,000 x 2.5us = 1 second OFF
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
{25000, 0, 25000, 0,},
// Looping mode needs a Zero ending data to mark the EOF
{0, 0, 0, 0}
};
void setup() {
Serial.begin(115200);
Serial.println("Starting Blink testing...");
Serial.flush();
// 1 RMT Block has 64 RMT_SYMBOLS (ESP32|ESP32S2) or 48 RMT_SYMBOLS (ESP32C3|ESP32S3)
if (!rmtInit(BLINK_GPIO, RMT_TX_MODE, RMT_MEM_NUM_BLOCKS_1, 400000)) { //2.5us tick
Serial.println("===> rmtInit Error!");
}
// sets the End of Transmission Level to HIGH, after writing to the pin. DEFAULT is LOW.
rmtSetEOT(BLINK_GPIO, RMT_EOT);
// set initial RMT state by writing a single RMT data
rmt_data_t initStateSetup_rmt_data[] = { {1, RMT_EOT, 0, 0} };
rmtWrite(BLINK_GPIO, initStateSetup_rmt_data, RMT_SYMBOLS_OF(initStateSetup_rmt_data), RMT_WAIT_FOR_EVER);
Serial.printf("\nLED GPIO%d start in the inital level %s\n", BLINK_GPIO, RMT_EOT == LOW ? "LOW" : "HIGH");
delay(EOT_INITIAL_STATE_TIME_MS); // set initial state of the LED is set by RMT_EOT.
// Send the data and wait until it is done - set EOT level to HIGH
Serial.printf("\nLED GPIO%d Blinks 1 second HIGH - 1 second LOW.\n", BLINK_GPIO);
if (!rmtWrite(BLINK_GPIO, blink_1s_rmt_data, RMT_SYMBOLS_OF(blink_1s_rmt_data) - 2, RMT_WAIT_FOR_EVER)) {
Serial.println("===> rmtWrite Blink 1s Error!");
}
Serial.printf("\nLED GPIO%d goes to the EOT level %s\n", BLINK_GPIO, RMT_EOT == LOW ? "LOW" : "HIGH");
}
void loop(){}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment