mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'feat/gdma_tx_done_teof_v6.1' into 'release/v6.1'
feat(gdma): add tx done and total_eof callbacks (v6.1) See merge request espressif/esp-idf!51845
This commit is contained in:
@@ -61,7 +61,9 @@ typedef bool (*gdma_event_callback_t)(gdma_channel_handle_t dma_chan, gdma_event
|
||||
* @note The callbacks are all running under ISR environment
|
||||
*/
|
||||
typedef struct {
|
||||
gdma_event_callback_t on_trans_done; /*!< Invoked when TX engine finishes one descriptor */
|
||||
gdma_event_callback_t on_trans_eof; /*!< Invoked when TX engine meets EOF descriptor */
|
||||
gdma_event_callback_t on_trans_total_eof; /*!< Invoked when TX engine reaches the end of the descriptor chain */
|
||||
gdma_event_callback_t on_descr_err; /*!< Invoked when DMA encounters a descriptor error */
|
||||
gdma_event_callback_t on_link_switch; /*!< Invoked when TX link list switches to a new descriptor chain */
|
||||
} gdma_tx_event_callbacks_t;
|
||||
|
||||
@@ -572,10 +572,18 @@ esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_
|
||||
}
|
||||
|
||||
if (dma_chan->flags.isr_cache_safe) {
|
||||
if (cbs->on_trans_done) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_done), ESP_ERR_INVALID_ARG,
|
||||
TAG, "on_trans_done not in IRAM");
|
||||
}
|
||||
if (cbs->on_trans_eof) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_eof), ESP_ERR_INVALID_ARG,
|
||||
TAG, "on_trans_eof not in IRAM");
|
||||
}
|
||||
if (cbs->on_trans_total_eof) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_total_eof), ESP_ERR_INVALID_ARG,
|
||||
TAG, "on_trans_total_eof not in IRAM");
|
||||
}
|
||||
if (cbs->on_descr_err) {
|
||||
ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_descr_err), ESP_ERR_INVALID_ARG,
|
||||
TAG, "on_descr_err not in IRAM");
|
||||
@@ -595,8 +603,12 @@ esp_err_t gdma_register_tx_event_callbacks(gdma_channel_handle_t dma_chan, gdma_
|
||||
|
||||
// enable/disable GDMA interrupt events for TX channel
|
||||
esp_os_enter_critical(&pair->spinlock);
|
||||
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_DONE,
|
||||
cbs->on_trans_done != NULL);
|
||||
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_EOF,
|
||||
cbs->on_trans_eof != NULL);
|
||||
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_TOTAL_EOF,
|
||||
cbs->on_trans_total_eof != NULL);
|
||||
gdma_hal_enable_intr(hal, pair->pair_id, GDMA_CHANNEL_DIRECTION_TX, GDMA_LL_EVENT_TX_DESC_ERROR,
|
||||
cbs->on_descr_err != NULL);
|
||||
#if GDMA_LL_EVENT_TX_LINK_SWITCH
|
||||
@@ -1045,6 +1057,9 @@ void gdma_default_tx_isr(void *args)
|
||||
uint32_t intr_status = gdma_hal_read_intr_status(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, false);
|
||||
gdma_hal_clear_intr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, intr_status);
|
||||
|
||||
if ((intr_status & GDMA_LL_EVENT_TX_DONE) && tx_chan->cbs.on_trans_done) {
|
||||
need_yield |= tx_chan->cbs.on_trans_done(&tx_chan->base, NULL, tx_chan->user_data);
|
||||
}
|
||||
if ((intr_status & GDMA_LL_EVENT_TX_EOF) && tx_chan->cbs.on_trans_eof) {
|
||||
uint32_t eof_addr = gdma_hal_get_eof_desc_addr(hal, pair_id, GDMA_CHANNEL_DIRECTION_TX, true);
|
||||
gdma_event_data_t edata = {
|
||||
@@ -1053,6 +1068,9 @@ void gdma_default_tx_isr(void *args)
|
||||
};
|
||||
need_yield |= tx_chan->cbs.on_trans_eof(&tx_chan->base, &edata, tx_chan->user_data);
|
||||
}
|
||||
if ((intr_status & GDMA_LL_EVENT_TX_TOTAL_EOF) && tx_chan->cbs.on_trans_total_eof) {
|
||||
need_yield |= tx_chan->cbs.on_trans_total_eof(&tx_chan->base, NULL, tx_chan->user_data);
|
||||
}
|
||||
if ((intr_status & GDMA_LL_EVENT_TX_DESC_ERROR) && tx_chan->cbs.on_descr_err) {
|
||||
need_yield |= tx_chan->cbs.on_descr_err(&tx_chan->base, NULL, tx_chan->user_data);
|
||||
}
|
||||
|
||||
@@ -263,11 +263,14 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
|
||||
//Append mode
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
// config gmda event callback for gdma supported chip
|
||||
gdma_rx_event_callbacks_t txrx_cbs = {
|
||||
gdma_tx_event_callbacks_t tx_cbs = {
|
||||
.on_trans_eof = s_spi_slave_hd_append_gdma_isr,
|
||||
};
|
||||
gdma_rx_event_callbacks_t rx_cbs = {
|
||||
.on_recv_eof = s_spi_slave_hd_append_gdma_isr,
|
||||
};
|
||||
gdma_register_tx_event_callbacks(host->dma_ctx->tx_dma_chan, (gdma_tx_event_callbacks_t *)&txrx_cbs, host);
|
||||
gdma_register_rx_event_callbacks(host->dma_ctx->rx_dma_chan, &txrx_cbs, host);
|
||||
gdma_register_tx_event_callbacks(host->dma_ctx->tx_dma_chan, &tx_cbs, host);
|
||||
gdma_register_rx_event_callbacks(host->dma_ctx->rx_dma_chan, &rx_cbs, host);
|
||||
#else
|
||||
//On ESP32S2, `cmd7` and `cmd8` are designed as all `spi_dma` events, so use `dma_src` only
|
||||
ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), bus_config->intr_flags, s_spi_slave_hd_append_legacy_isr,
|
||||
|
||||
Reference in New Issue
Block a user