diff --git a/components/driver/include/driver/rmt.h b/components/driver/include/driver/rmt.h index 79ac0e5d6..13d97b91c 100644 --- a/components/driver/include/driver/rmt.h +++ b/components/driver/include/driver/rmt.h @@ -119,6 +119,16 @@ typedef struct { typedef intr_handle_t rmt_isr_handle_t; +typedef void (*rmt_tx_end_fn_t)(rmt_channel_t channel, void *arg); + +/** + * @brief Structure encapsulating a RMT TX end callback + */ +typedef struct { + rmt_tx_end_fn_t function; /*!< Function which is called on RMT TX end */ + void *arg; /*!< Optional argument passed to function */ +} rmt_tx_end_callback_t; + /** * @brief Set RMT clock divider, channel clock is divided from source clock. * @@ -702,6 +712,21 @@ esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time); */ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t* buf_handle); +/** + * @brief Registers a callback that will be called when transmission ends. + * + * Called by rmt_driver_isr_default in interrupt context. + * + * @note Requires rmt_driver_install to install the default ISR handler. + * + * @param function Function to be called from the default interrupt handler or NULL. + * @param arg Argument which will be provided to the callback when it is called. + * + * @return the previous callback settings (members will be set to NULL if there was none) + */ +rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, void *arg); + + /* * ----------------EXAMPLE OF RMT INTERRUPT ------------------ * @code{c} diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 09cf94c14..8e7b2a1d0 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -75,6 +75,9 @@ typedef struct { rmt_obj_t* p_rmt_obj[RMT_CHANNEL_MAX] = {0}; +// Event called when transmission is ended +static rmt_tx_end_callback_t rmt_tx_end_callback; + static void rmt_set_tx_wrap_en(rmt_channel_t channel, bool en) { portENTER_CRITICAL(&rmt_spinlock); @@ -548,6 +551,9 @@ static void IRAM_ATTR rmt_driver_isr_default(void* arg) p_rmt->tx_len_rem = 0; p_rmt->tx_offset = 0; p_rmt->tx_sub_len = 0; + if(rmt_tx_end_callback.function != NULL) { + rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg); + } break; //RX_END case 1: @@ -771,3 +777,10 @@ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t* buf_han return ESP_OK; } +rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, void *arg) +{ + rmt_tx_end_callback_t previous = rmt_tx_end_callback; + rmt_tx_end_callback.function = function; + rmt_tx_end_callback.arg = arg; + return previous; +}