mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-20 10:46:02 -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 {
|
struct gdma_channel_t {
|
||||||
gdma_pair_t *pair; // which pair the channel belongs to
|
gdma_pair_t *pair; // which pair the channel belongs to
|
||||||
intr_handle_t intr; // per-channel interrupt handle
|
intr_handle_t intr; // per-channel interrupt handle
|
||||||
|
portMUX_TYPE spinlock; // channel level spinlock
|
||||||
gdma_channel_direction_t direction; // channel direction
|
gdma_channel_direction_t direction; // channel direction
|
||||||
int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel
|
int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel
|
||||||
size_t sram_alignment; // alignment for memory in SRAM
|
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 = &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",
|
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);
|
group->group_id, pair->pair_id, *ret_chan);
|
||||||
return ESP_OK;
|
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;
|
esp_err_t ret = ESP_OK;
|
||||||
gdma_pair_t *pair = NULL;
|
gdma_pair_t *pair = NULL;
|
||||||
gdma_group_t *group = 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;
|
pair = dma_chan->pair;
|
||||||
group = pair->group;
|
group = pair->group;
|
||||||
|
|
||||||
|
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
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_set_desc_addr(group->hal.dev, pair->pair_id, desc_base_addr);
|
||||||
gdma_ll_rx_start(group->hal.dev, pair->pair_id);
|
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_set_desc_addr(group->hal.dev, pair->pair_id, desc_base_addr);
|
||||||
gdma_ll_tx_start(group->hal.dev, pair->pair_id);
|
gdma_ll_tx_start(group->hal.dev, pair->pair_id);
|
||||||
}
|
}
|
||||||
|
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
@ -472,15 +476,17 @@ esp_err_t gdma_stop(gdma_channel_handle_t dma_chan)
|
|||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
gdma_pair_t *pair = NULL;
|
gdma_pair_t *pair = NULL;
|
||||||
gdma_group_t *group = 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;
|
pair = dma_chan->pair;
|
||||||
group = pair->group;
|
group = pair->group;
|
||||||
|
|
||||||
|
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||||
gdma_ll_rx_stop(group->hal.dev, pair->pair_id);
|
gdma_ll_rx_stop(group->hal.dev, pair->pair_id);
|
||||||
} else {
|
} else {
|
||||||
gdma_ll_tx_stop(group->hal.dev, pair->pair_id);
|
gdma_ll_tx_stop(group->hal.dev, pair->pair_id);
|
||||||
}
|
}
|
||||||
|
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
@ -491,15 +497,17 @@ esp_err_t gdma_append(gdma_channel_handle_t dma_chan)
|
|||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
gdma_pair_t *pair = NULL;
|
gdma_pair_t *pair = NULL;
|
||||||
gdma_group_t *group = 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;
|
pair = dma_chan->pair;
|
||||||
group = pair->group;
|
group = pair->group;
|
||||||
|
|
||||||
|
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||||
gdma_ll_rx_restart(group->hal.dev, pair->pair_id);
|
gdma_ll_rx_restart(group->hal.dev, pair->pair_id);
|
||||||
} else {
|
} else {
|
||||||
gdma_ll_tx_restart(group->hal.dev, pair->pair_id);
|
gdma_ll_tx_restart(group->hal.dev, pair->pair_id);
|
||||||
}
|
}
|
||||||
|
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
@ -510,15 +518,17 @@ esp_err_t gdma_reset(gdma_channel_handle_t dma_chan)
|
|||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
gdma_pair_t *pair = NULL;
|
gdma_pair_t *pair = NULL;
|
||||||
gdma_group_t *group = 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;
|
pair = dma_chan->pair;
|
||||||
group = pair->group;
|
group = pair->group;
|
||||||
|
|
||||||
|
portENTER_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
if (dma_chan->direction == GDMA_CHANNEL_DIRECTION_RX) {
|
||||||
gdma_ll_rx_reset_channel(group->hal.dev, pair->pair_id);
|
gdma_ll_rx_reset_channel(group->hal.dev, pair->pair_id);
|
||||||
} else {
|
} else {
|
||||||
gdma_ll_tx_reset_channel(group->hal.dev, pair->pair_id);
|
gdma_ll_tx_reset_channel(group->hal.dev, pair->pair_id);
|
||||||
}
|
}
|
||||||
|
portEXIT_CRITICAL_SAFE(&dma_chan->spinlock);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
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
|
* @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] 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)
|
* @param[in] desc_base_addr Base address of descriptors (usually the descriptors are chained into a link or ring)
|
||||||
* @return
|
* @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
|
* @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`
|
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK: Stop DMA engine successfully
|
* - 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
|
* @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.
|
* @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`
|
* @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
|
* @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
|
* @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`
|
* @param[in] dma_chan GDMA channel handle, allocated by `gdma_new_channel`
|
||||||
|
Loading…
Reference in New Issue
Block a user