From 660ff8e840d7af5ebc835e5dd1644eb46f6f5699 Mon Sep 17 00:00:00 2001 From: morris Date: Sun, 8 May 2022 19:30:41 +0800 Subject: [PATCH] rmt: declare RMTMEM as a block of memory --- components/driver/rmt/rmt_private.h | 8 +++++++- components/driver/rmt/rmt_rx.c | 2 +- components/driver/rmt/rmt_tx.c | 22 +++++++++++++++------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/components/driver/rmt/rmt_private.h b/components/driver/rmt/rmt_private.h index fb2fb0f1e3..19a80b028c 100644 --- a/components/driver/rmt/rmt_private.h +++ b/components/driver/rmt/rmt_private.h @@ -49,8 +49,14 @@ extern "C" { #define RMT_DMA_NODES_PING_PONG 2 // two nodes ping-pong #define RMT_PM_LOCK_NAME_LEN_MAX 16 +typedef struct { + struct { + rmt_symbol_word_t symbols[SOC_RMT_MEM_WORDS_PER_CHANNEL]; + } channels[SOC_RMT_CHANNELS_PER_GROUP]; +} rmt_block_mem_t; + // RMTMEM address is declared in .peripherals.ld -extern rmt_symbol_word_t RMTMEM; +extern rmt_block_mem_t RMTMEM; typedef enum { RMT_CHANNEL_DIRECTION_TX, diff --git a/components/driver/rmt/rmt_rx.c b/components/driver/rmt/rmt_rx.c index a4fc401cf4..380d63e30e 100644 --- a/components/driver/rmt/rmt_rx.c +++ b/components/driver/rmt/rmt_rx.c @@ -272,7 +272,7 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_ // initialize other members of rx channel rx_channel->base.direction = RMT_CHANNEL_DIRECTION_RX; rx_channel->base.fsm = RMT_FSM_INIT; - rx_channel->base.hw_mem_base = &RMTMEM + (channel_id + RMT_RX_CHANNEL_OFFSET_IN_GROUP) * SOC_RMT_MEM_WORDS_PER_CHANNEL; + rx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_RX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; rx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // polymorphic methods rx_channel->base.del = rmt_del_rx_channel; diff --git a/components/driver/rmt/rmt_tx.c b/components/driver/rmt/rmt_tx.c index 679148af67..239707ebcf 100644 --- a/components/driver/rmt/rmt_tx.c +++ b/components/driver/rmt/rmt_tx.c @@ -290,7 +290,7 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX; tx_channel->base.fsm = RMT_FSM_INIT; - tx_channel->base.hw_mem_base = &RMTMEM + (channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP) * SOC_RMT_MEM_WORDS_PER_CHANNEL; + tx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; tx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // polymorphic methods tx_channel->base.del = rmt_del_tx_channel; @@ -325,11 +325,11 @@ static esp_err_t rmt_del_tx_channel(rmt_channel_handle_t channel) esp_err_t rmt_new_sync_manager(const rmt_sync_manager_config_t *config, rmt_sync_manager_handle_t *ret_synchro) { +#if !SOC_RMT_SUPPORT_TX_SYNCHRO + ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "sync manager not supported"); +#else esp_err_t ret = ESP_OK; rmt_sync_manager_t *synchro = NULL; -#if !SOC_RMT_SUPPORT_TX_SYNCHRO - ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "sync manager not supported"); -#else ESP_GOTO_ON_FALSE(config && ret_synchro && config->tx_channel_array && config->array_size, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); synchro = heap_caps_calloc(1, sizeof(rmt_sync_manager_t) + sizeof(rmt_channel_handle_t) * config->array_size, RMT_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(synchro, ESP_ERR_NO_MEM, err, TAG, "no mem for sync manager"); @@ -381,7 +381,6 @@ esp_err_t rmt_new_sync_manager(const rmt_sync_manager_config_t *config, rmt_sync *ret_synchro = synchro; ESP_LOGD(TAG, "new sync manager at %p, with channel mask:%02x", synchro, synchro->channel_mask); return ESP_OK; -#endif // !SOC_RMT_SUPPORT_TX_SYNCHRO err: if (synchro) { @@ -391,6 +390,7 @@ err: free(synchro); } return ret; +#endif // !SOC_RMT_SUPPORT_TX_SYNCHRO } esp_err_t rmt_sync_reset(rmt_sync_manager_handle_t synchro) @@ -470,11 +470,15 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con rmt_tx_trans_desc_t *t = NULL; // acquire one transaction description from ready_queue or done_queue if (tx_chan->num_trans_inflight < tx_chan->queue_size) { - xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, portMAX_DELAY); + ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, portMAX_DELAY) == pdTRUE, + ESP_FAIL, TAG, "no transaction in the ready queue"); } else { - xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, portMAX_DELAY); + ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, portMAX_DELAY) == pdTRUE, + ESP_FAIL, TAG, "recycle transaction from done queue failed"); tx_chan->num_trans_inflight--; } + // sanity check + assert(t); // fill in the transaction descriptor memset(t, 0, sizeof(rmt_tx_trans_desc_t)); t->encoder = encoder; @@ -871,6 +875,8 @@ static bool IRAM_ATTR rmt_isr_handle_tx_done(rmt_tx_channel_t *tx_chan) } // fetch new transaction description from trans_queue if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { + // sanity check + assert(trans_desc); // update current transaction tx_chan->cur_trans = trans_desc; @@ -954,6 +960,8 @@ static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan) // fetch new transaction description from trans_queue if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { + // sanity check + assert(trans_desc); tx_chan->cur_trans = trans_desc; // clear the loop end status when we're sure there still remains transaction to handle rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id));