mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
gdma: add spin lock for gdma channel
... because we allow several control functions to be runable under ISR context
This commit is contained in:
parent
7071506033
commit
2f1393ad53
@ -87,6 +87,7 @@ struct gdma_pair_t {
|
||||
struct gdma_channel_t {
|
||||
gdma_pair_t *pair; // which pair the channel belongs to
|
||||
intr_handle_t intr; // per-channel interrupt handle
|
||||
portMUX_TYPE spinlock; // channel level spinlock
|
||||
gdma_channel_direction_t direction; // channel direction
|
||||
int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel
|
||||
size_t sram_alignment; // alignment for memory in SRAM
|
||||
@ -200,6 +201,7 @@ search_done:
|
||||
*ret_chan = &alloc_rx_channel->base; // return the installed channel
|
||||
}
|
||||
|
||||
(*ret_chan)->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||
ESP_LOGD(TAG, "new %s channel (%d,%d) at %p", (config->direction == GDMA_CHANNEL_DIRECTION_TX) ? "tx" : "rx",
|
||||
group->group_id, pair->pair_id, *ret_chan);
|
||||
return ESP_OK;
|
||||
@ -451,10 +453,11 @@ esp_err_t gdma_start(gdma_channel_handle_t dma_chan, intptr_t desc_base_addr)
|
||||
esp_err_t ret = ESP_OK;
|
||||
gdma_pair_t *pair = NULL;
|
||||
gdma_group_t *group = NULL;
|
||||
ESP_GOTO_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
ESP_GOTO_ON_FALSE_ISR(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
pair = dma_chan->pair;
|
||||
group = pair->group;
|
||||
|
||||
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
gdma_ll_rx_set_desc_addr(group->hal.dev, pair->pair_id, desc_base_addr);
|
||||
gdma_ll_rx_start(group->hal.dev, pair->pair_id);
|
||||
@ -462,6 +465,7 @@ esp_err_t gdma_start(gdma_channel_handle_t dma_chan, intptr_t desc_base_addr)
|
||||
gdma_ll_tx_set_desc_addr(group->hal.dev, pair->pair_id, desc_base_addr);
|
||||
gdma_ll_tx_start(group->hal.dev, pair->pair_id);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
@ -472,15 +476,17 @@ esp_err_t gdma_stop(gdma_channel_handle_t dma_chan)
|
||||
esp_err_t ret = ESP_OK;
|
||||
gdma_pair_t *pair = NULL;
|
||||
gdma_group_t *group = NULL;
|
||||
ESP_GOTO_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
ESP_GOTO_ON_FALSE_ISR(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
pair = dma_chan->pair;
|
||||
group = pair->group;
|
||||
|
||||
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
gdma_ll_rx_stop(group->hal.dev, pair->pair_id);
|
||||
} else {
|
||||
gdma_ll_tx_stop(group->hal.dev, pair->pair_id);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
@ -491,15 +497,17 @@ esp_err_t gdma_append(gdma_channel_handle_t dma_chan)
|
||||
esp_err_t ret = ESP_OK;
|
||||
gdma_pair_t *pair = NULL;
|
||||
gdma_group_t *group = NULL;
|
||||
ESP_GOTO_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
ESP_GOTO_ON_FALSE_ISR(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
pair = dma_chan->pair;
|
||||
group = pair->group;
|
||||
|
||||
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
gdma_ll_rx_restart(group->hal.dev, pair->pair_id);
|
||||
} else {
|
||||
gdma_ll_tx_restart(group->hal.dev, pair->pair_id);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
@ -510,15 +518,17 @@ esp_err_t gdma_reset(gdma_channel_handle_t dma_chan)
|
||||
esp_err_t ret = ESP_OK;
|
||||
gdma_pair_t *pair = NULL;
|
||||
gdma_group_t *group = NULL;
|
||||
ESP_GOTO_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
ESP_GOTO_ON_FALSE_ISR(dma_chan, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
|
||||
pair = dma_chan->pair;
|
||||
group = pair->group;
|
||||
|
||||
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||
gdma_ll_rx_reset_channel(group->hal.dev, pair->pair_id);
|
||||
} else {
|
||||
gdma_ll_tx_reset_channel(group->hal.dev, pair->pair_id);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
|
@ -269,6 +269,9 @@ esp_err_t gdma_register_rx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_
|
||||
/**
|
||||
* @brief Set DMA descriptor address and start engine
|
||||
*
|
||||
* @note This function is allowed to run within ISR context
|
||||
* @note This function is also allowed to run when Cache is disabled, if `CONFIG_GDMA_CTRL_FUNC_IN_IRAM` is enabled
|
||||
*
|
||||
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||
* @param[in] desc_base_addr Base address of descriptors (usually the descriptors are chained into a link or ring)
|
||||
* @return
|
||||
@ -281,6 +284,9 @@ esp_err_t gdma_start(gdma_channel_handle_t dma_chan, intptr_t desc_base_addr);
|
||||
/**
|
||||
* @brief Stop DMA engine
|
||||
*
|
||||
* @note This function is allowed to run within ISR context
|
||||
* @note This function is also allowed to run when Cache is disabled, if `CONFIG_GDMA_CTRL_FUNC_IN_IRAM` is enabled
|
||||
*
|
||||
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||
* @return
|
||||
* - ESP_OK: Stop DMA engine successfully
|
||||
@ -291,6 +297,9 @@ esp_err_t gdma_stop(gdma_channel_handle_t dma_chan);
|
||||
|
||||
/**
|
||||
* @brief Make the appended descriptors be aware to the DMA engine
|
||||
*
|
||||
* @note This function is allowed to run within ISR context
|
||||
* @note This function is also allowed to run when Cache is disabled, if `CONFIG_GDMA_CTRL_FUNC_IN_IRAM` is enabled
|
||||
* @note This API could also resume a paused DMA engine, make sure new descriptors have been appended to the descriptor chain before calling it.
|
||||
*
|
||||
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||
@ -303,6 +312,9 @@ esp_err_t gdma_append(gdma_channel_handle_t dma_chan);
|
||||
|
||||
/**
|
||||
* @brief Reset DMA channel FIFO and internal finite state machine
|
||||
*
|
||||
* @note This function is allowed to run within ISR context
|
||||
* @note This function is also allowed to run when Cache is disabled, if `CONFIG_GDMA_CTRL_FUNC_IN_IRAM` is enabled
|
||||
* @note Resetting a DMA channel won't break the connection with the target peripheral
|
||||
*
|
||||
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||
|
Loading…
x
Reference in New Issue
Block a user