diff --git a/components/driver/include/esp_private/spi_common_internal.h b/components/driver/include/esp_private/spi_common_internal.h index e3127d4831..83b9c1ad6b 100644 --- a/components/driver/include/esp_private/spi_common_internal.h +++ b/components/driver/include/esp_private/spi_common_internal.h @@ -227,7 +227,8 @@ int spicommon_irqdma_source_for_host(spi_host_device_t host); */ typedef void(*dmaworkaround_cb_t)(void *arg); - +#if CONFIG_IDF_TARGET_ESP32 +//This workaround is only for esp32 /** * @brief Request a reset for a certain DMA channel * @@ -274,6 +275,7 @@ void spicommon_dmaworkaround_idle(int dmachan); * be affected by a global SPI DMA reset, and a reset like that should not be attempted. */ void spicommon_dmaworkaround_transfer_active(int dmachan); +#endif //#if CONFIG_IDF_TARGET_ESP32 /******************************************************************************* * Bus attributes diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index aa2c05dd61..308875172e 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -913,11 +913,10 @@ static dmaworkaround_cb_t dmaworkaround_cb; static void *dmaworkaround_cb_arg; static portMUX_TYPE dmaworkaround_mux = portMUX_INITIALIZER_UNLOCKED; static int dmaworkaround_waiting_for_chan = 0; -#endif bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg) { -#if CONFIG_IDF_TARGET_ESP32 + int otherchan = (dmachan == 1) ? 2 : 1; bool ret; portENTER_CRITICAL_ISR(&dmaworkaround_mux); @@ -934,24 +933,15 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t } portEXIT_CRITICAL_ISR(&dmaworkaround_mux); return ret; -#else - //no need to reset - return true; -#endif } bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress(void) { -#if CONFIG_IDF_TARGET_ESP32 return (dmaworkaround_waiting_for_chan != 0); -#else - return false; -#endif } void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) { -#if CONFIG_IDF_TARGET_ESP32 portENTER_CRITICAL_ISR(&dmaworkaround_mux); dmaworkaround_channels_busy[dmachan-1] = 0; if (dmaworkaround_waiting_for_chan == dmachan) { @@ -963,14 +953,12 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) } portEXIT_CRITICAL_ISR(&dmaworkaround_mux); -#endif } void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan) { -#if CONFIG_IDF_TARGET_ESP32 portENTER_CRITICAL_ISR(&dmaworkaround_mux); dmaworkaround_channels_busy[dmachan-1] = 1; portEXIT_CRITICAL_ISR(&dmaworkaround_mux); -#endif } +#endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 71a51e90bf..6e696bcc53 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -632,10 +632,13 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) //Okay, transaction is done. const int cs = host->cur_cs; //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset. + +#if CONFIG_IDF_TARGET_ESP32 if (bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same spicommon_dmaworkaround_idle(bus_attr->tx_dma_chan); } +#endif //#if CONFIG_IDF_TARGET_ESP32 //cur_cs is changed to DEV_NUM_MAX here spi_post_trans(host); @@ -691,11 +694,13 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) if (trans_found) { spi_trans_priv_t *const cur_trans_buf = &host->cur_trans_buf; +#if CONFIG_IDF_TARGET_ESP32 if (bus_attr->dma_enabled && (cur_trans_buf->buffer_to_rcv || cur_trans_buf->buffer_to_send)) { //mark channel as active, so that the DMA will not be reset by the slave //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same spicommon_dmaworkaround_transfer_active(bus_attr->tx_dma_chan); } +#endif //#if CONFIG_IDF_TARGET_ESP32 spi_new_trans(device_to_send, cur_trans_buf); } // Exit of the ISR, handle interrupt re-enable (if sending transaction), retry (if there's coming BG), @@ -929,10 +934,14 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_acquire_bus(spi_device_t *device, TickT //configure the device ahead so that we don't need to do it again in the following transactions spi_setup_device(host->device[device->id]); //the DMA is also occupied by the device, all the slave devices that using DMA should wait until bus released. + +#if CONFIG_IDF_TARGET_ESP32 if (host->bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same spicommon_dmaworkaround_transfer_active(host->bus_attr->tx_dma_chan); } +#endif //#if CONFIG_IDF_TARGET_ESP32 + return ESP_OK; } @@ -946,11 +955,13 @@ void SPI_MASTER_ISR_ATTR spi_device_release_bus(spi_device_t *dev) assert(0); } +#if CONFIG_IDF_TARGET_ESP32 if (host->bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same spicommon_dmaworkaround_idle(host->bus_attr->tx_dma_chan); } //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset. +#endif //#if CONFIG_IDF_TARGET_ESP32 //allow clock to be lower than 80MHz when all tasks blocked #ifdef CONFIG_PM_ENABLE diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index c54c89d322..6ddc3369c6 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -358,11 +358,13 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_transmit(spi_host_device_t host, spi_slave_tr return ESP_OK; } +#if CONFIG_IDF_TARGET_ESP32 static void SPI_SLAVE_ISR_ATTR spi_slave_restart_after_dmareset(void *arg) { spi_slave_t *host = (spi_slave_t *)arg; esp_intr_enable(host->intr); } +#endif //#if CONFIG_IDF_TARGET_ESP32 //This is run in interrupt context and apart from initialization and destruction, this is the only code //touching the host (=spihost[x]) variable. The rest of the data arrives in queues. That is why there are @@ -385,10 +387,14 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) spi_slave_hal_store_result(hal); host->cur_trans->trans_len = spi_slave_hal_get_rcv_bitlen(hal); +#if CONFIG_IDF_TARGET_ESP32 + //This workaround is only for esp32 if (spi_slave_hal_dma_need_reset(hal)) { - //On ESP32 and ESP32S2, actual_tx_dma_chan and actual_rx_dma_chan are always same + //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same spicommon_dmaworkaround_req_reset(host->tx_dma_chan, spi_slave_restart_after_dmareset, host); } +#endif //#if CONFIG_IDF_TARGET_ESP32 + if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans); if(!(host->cfg.flags & SPI_SLAVE_NO_RETURN_RESULT)) { @@ -396,8 +402,11 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) } host->cur_trans = NULL; } + +#if CONFIG_IDF_TARGET_ESP32 + //This workaround is only for esp32 if (use_dma) { - //On ESP32 and ESP32S2, actual_tx_dma_chan and actual_rx_dma_chan are always same + //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same spicommon_dmaworkaround_idle(host->tx_dma_chan); if (spicommon_dmaworkaround_reset_in_progress()) { //We need to wait for the reset to complete. Disable int (will be re-enabled on reset callback) and exit isr. @@ -406,6 +415,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) return; } } +#endif //#if CONFIG_IDF_TARGET_ESP32 //Disable interrupt before checking to avoid concurrency issue. esp_intr_disable(host->intr); @@ -425,10 +435,13 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) hal->rx_buffer = trans->rx_buffer; hal->tx_buffer = trans->tx_buffer; +#if CONFIG_IDF_TARGET_ESP32 if (use_dma) { - //On ESP32 and ESP32S2, actual_tx_dma_chan and actual_rx_dma_chan are always same + //This workaround is only for esp32 + //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same spicommon_dmaworkaround_transfer_active(host->tx_dma_chan); } +#endif //#if CONFIG_IDF_TARGET_ESP32 spi_slave_hal_prepare_data(hal); diff --git a/components/hal/include/hal/spi_slave_hal.h b/components/hal/include/hal/spi_slave_hal.h index 14183a1da8..9d7ceec37e 100644 --- a/components/hal/include/hal/spi_slave_hal.h +++ b/components/hal/include/hal/spi_slave_hal.h @@ -142,6 +142,7 @@ void spi_slave_hal_store_result(spi_slave_hal_context_t *hal); */ uint32_t spi_slave_hal_get_rcv_bitlen(spi_slave_hal_context_t *hal); +#if CONFIG_IDF_TARGET_ESP32 /** * Check whether we need to reset the DMA according to the status of last transactions. * @@ -153,3 +154,4 @@ uint32_t spi_slave_hal_get_rcv_bitlen(spi_slave_hal_context_t *hal); * @return true if reset is needed, else false. */ bool spi_slave_hal_dma_need_reset(const spi_slave_hal_context_t *hal); +#endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/hal/spi_slave_hal_iram.c b/components/hal/spi_slave_hal_iram.c index d3a0e3924e..56288e134f 100644 --- a/components/hal/spi_slave_hal_iram.c +++ b/components/hal/spi_slave_hal_iram.c @@ -98,6 +98,8 @@ uint32_t spi_slave_hal_get_rcv_bitlen(spi_slave_hal_context_t *hal) return hal->rcv_bitlen; } +#if CONFIG_IDF_TARGET_ESP32 +//This workaround is only for esp32 bool spi_slave_hal_dma_need_reset(const spi_slave_hal_context_t *hal) { bool ret; @@ -114,3 +116,4 @@ bool spi_slave_hal_dma_need_reset(const spi_slave_hal_context_t *hal) } return ret; } +#endif //#if CONFIG_IDF_TARGET_ESP32