rmt: declare RMTMEM as a block of memory

This commit is contained in:
morris 2022-05-08 19:30:41 +08:00
parent 4d9930888a
commit 660ff8e840
3 changed files with 23 additions and 9 deletions

View File

@ -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 <target>.peripherals.ld
extern rmt_symbol_word_t RMTMEM;
extern rmt_block_mem_t RMTMEM;
typedef enum {
RMT_CHANNEL_DIRECTION_TX,

View File

@ -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;

View File

@ -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));