From 1066c74b744e4b418168d3bb717adb73ca346171 Mon Sep 17 00:00:00 2001 From: Krzysztof Bociurko Date: Fri, 27 Oct 2017 15:23:07 +0200 Subject: [PATCH 1/2] rmt: Adds a simple handler that can be called when transmission ends. Merges https://github.com/espressif/esp-idf/pull/1174 --- components/driver/include/driver/rmt.h | 16 ++++++++++++++++ components/driver/rmt.c | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/components/driver/include/driver/rmt.h b/components/driver/include/driver/rmt.h index 79ac0e5d67..009041bfdb 100644 --- a/components/driver/include/driver/rmt.h +++ b/components/driver/include/driver/rmt.h @@ -119,6 +119,8 @@ typedef struct { typedef intr_handle_t rmt_isr_handle_t; +typedef void (*rmt_tx_end_t)(rmt_channel_t channel); + /** * @brief Set RMT clock divider, channel clock is divided from source clock. * @@ -702,6 +704,20 @@ 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 fn Function to be called from the default interrupt handler or NULL. + * + * @return the previous handler (or NULL if there was none) + */ +rmt_tx_end_t rmt_register_tx_end_callback(rmt_tx_end_t fn); + + /* * ----------------EXAMPLE OF RMT INTERRUPT ------------------ * @code{c} diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 09cf94c14a..eb102fc7ba 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_t rmt_tx_end_callback = NULL; + 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 != NULL) { + rmt_tx_end_callback(channel); + } break; //RX_END case 1: @@ -771,3 +777,9 @@ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t* buf_han return ESP_OK; } +rmt_tx_end_t rmt_register_tx_end_callback(rmt_tx_end_t handler) +{ + rmt_tx_end_t previous = rmt_tx_end_callback; + rmt_tx_end_callback = handler; + return previous; +} From 2227c4425464fcc6a545247137815daa74a02902 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Fri, 5 Jan 2018 17:10:37 +1100 Subject: [PATCH 2/2] rmt: Add void * argument for end-of-transmission callback Ref https://github.com/espressif/esp-idf/pull/1174 --- components/driver/include/driver/rmt.h | 17 +++++++++++++---- components/driver/rmt.c | 13 +++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/components/driver/include/driver/rmt.h b/components/driver/include/driver/rmt.h index 009041bfdb..13d97b91cd 100644 --- a/components/driver/include/driver/rmt.h +++ b/components/driver/include/driver/rmt.h @@ -119,7 +119,15 @@ typedef struct { typedef intr_handle_t rmt_isr_handle_t; -typedef void (*rmt_tx_end_t)(rmt_channel_t channel); +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. @@ -711,11 +719,12 @@ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t* buf_han * * @note Requires rmt_driver_install to install the default ISR handler. * - * @param fn Function to be called from the default interrupt handler or NULL. + * @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 handler (or NULL if there was none) + * @return the previous callback settings (members will be set to NULL if there was none) */ -rmt_tx_end_t rmt_register_tx_end_callback(rmt_tx_end_t fn); +rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, void *arg); /* diff --git a/components/driver/rmt.c b/components/driver/rmt.c index eb102fc7ba..8e7b2a1d01 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -76,7 +76,7 @@ typedef struct { rmt_obj_t* p_rmt_obj[RMT_CHANNEL_MAX] = {0}; // Event called when transmission is ended -static rmt_tx_end_t rmt_tx_end_callback = NULL; +static rmt_tx_end_callback_t rmt_tx_end_callback; static void rmt_set_tx_wrap_en(rmt_channel_t channel, bool en) { @@ -551,8 +551,8 @@ 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 != NULL) { - rmt_tx_end_callback(channel); + if(rmt_tx_end_callback.function != NULL) { + rmt_tx_end_callback.function(channel, rmt_tx_end_callback.arg); } break; //RX_END @@ -777,9 +777,10 @@ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t* buf_han return ESP_OK; } -rmt_tx_end_t rmt_register_tx_end_callback(rmt_tx_end_t handler) +rmt_tx_end_callback_t rmt_register_tx_end_callback(rmt_tx_end_fn_t function, void *arg) { - rmt_tx_end_t previous = rmt_tx_end_callback; - rmt_tx_end_callback = handler; + rmt_tx_end_callback_t previous = rmt_tx_end_callback; + rmt_tx_end_callback.function = function; + rmt_tx_end_callback.arg = arg; return previous; }