Przeglądaj źródła

Merge branch 'feature/rmt_end_transmission_callback' into 'master'

rmt: Adds a simple handler that can be called when transmission ends.

See merge request !1726

Angus Gratton 8 lat temu
rodzic
commit
e9ca1dc9b0
2 zmienionych plików z 38 dodań i 0 usunięć
  1. 25 0
      components/driver/include/driver/rmt.h
  2. 13 0
      components/driver/rmt.c

+ 25 - 0
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}

+ 13 - 0
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;
+}