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:
morris
2026-08-27 17:59:55 +08:00
3 changed files with 26 additions and 3 deletions

View File

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

View File

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

View File

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