diff --git a/components/driver/include/driver/spi_master.h b/components/driver/include/driver/spi_master.h index d62af1c403..8c1d140d2d 100644 --- a/components/driver/include/driver/spi_master.h +++ b/components/driver/include/driver/spi_master.h @@ -175,6 +175,7 @@ typedef struct spi_device_t *spi_device_handle_t; ///< Handle for a device on a * @return * - ESP_ERR_INVALID_ARG if parameter is invalid or configuration combination is not supported (e.g. * `dev_config->post_cb` isn't set while flag `SPI_DEVICE_NO_RETURN_RESULT` is enabled) + * - ESP_ERR_INVALID_STATE if selected clock source is unavailable or spi bus not initialized * - ESP_ERR_NOT_FOUND if host doesn't have any free CS slots * - ESP_ERR_NO_MEM if out of memory * - ESP_OK on success diff --git a/components/driver/include/esp_private/spi_slave_internal.h b/components/driver/include/esp_private/spi_slave_internal.h index d6fb3d0815..01de22fee6 100644 --- a/components/driver/include/esp_private/spi_slave_internal.h +++ b/components/driver/include/esp_private/spi_slave_internal.h @@ -75,3 +75,8 @@ esp_err_t spi_slave_queue_reset_isr(spi_host_device_t host); * - ESP_OK on success */ esp_err_t spi_slave_queue_trans_isr(spi_host_device_t host, const spi_slave_transaction_t *trans_desc); + + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 8474571ab5..84263fe192 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -114,6 +114,7 @@ We have two bits to control the interrupt: #include "esp_private/spi_common_internal.h" #include "driver/spi_master.h" #include "clk_tree.h" +#include "clk_ctrl_os.h" #include "esp_log.h" #include "esp_ipc.h" #include "freertos/task.h" @@ -355,6 +356,11 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa spi_host_t *host = bus_driver_ctx[host_id]; const spi_bus_attr_t* bus_attr = host->bus_attr; SPI_CHECK(dev_config->spics_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num), "spics pin invalid", ESP_ERR_INVALID_ARG); +#if SOC_SPI_SUPPORT_CLK_RC_FAST + if (dev_config->clock_source == SPI_CLK_SRC_RC_FAST) { + SPI_CHECK(periph_rtc_dig_clk8m_enable(), "the selected clock not available", ESP_ERR_INVALID_STATE); + } +#endif spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; uint32_t clock_source_hz = 0; if (dev_config->clock_source) { @@ -495,6 +501,12 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle) SPI_CHECK(uxQueueMessagesWaiting(handle->ret_queue)==0, "Have unfinished transactions", ESP_ERR_INVALID_STATE); } +#if SOC_SPI_SUPPORT_CLK_RC_FAST + if (handle->cfg.clock_source == SPI_CLK_SRC_RC_FAST) { + periph_rtc_dig_clk8m_disable(); + } +#endif + //return int spics_io_num = handle->cfg.spics_io_num; if (spics_io_num >= 0) spicommon_cs_free_io(spics_io_num); diff --git a/components/driver/test_apps/spi/master/main/test_spi_master.c b/components/driver/test_apps/spi/master/main/test_spi_master.c index 7f05bf71ef..74ff872dcb 100644 --- a/components/driver/test_apps/spi/master/main/test_spi_master.c +++ b/components/driver/test_apps/spi/master/main/test_spi_master.c @@ -57,7 +57,9 @@ static void check_spi_pre_n_for(spi_clock_source_t clock_source, int clk, int pr spi_dev_t *hw = spi_periph_signal[TEST_SPI_HOST].hw; - printf("Checking clk rate %dHz. expect pre %d n %d, got pre %d n %d\n", clk, pre, n, hw->clock.clkdiv_pre + 1, hw->clock.clkcnt_n + 1); + int real_freq_khz; + spi_device_get_actual_freq(handle, &real_freq_khz); + printf("Checking clk rate %dHz. expect pre %d n %d, got pre %d n %d, real_freq %d kHZ\n", clk, pre, n, hw->clock.clkdiv_pre + 1, hw->clock.clkcnt_n + 1, real_freq_khz); TEST_ASSERT(hw->clock.clkcnt_n + 1 == n); TEST_ASSERT(hw->clock.clkdiv_pre + 1 == pre); diff --git a/docs/en/api-reference/peripherals/spi_master.rst b/docs/en/api-reference/peripherals/spi_master.rst index 646ced1d18..9d9218f9cf 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -538,7 +538,7 @@ SPI Clock Frequency Clock source of the GPSPI peripherals can be selected by setting :cpp:member:`spi_device_handle_t::cfg::clock_source`. You can refer to :cpp:type:`spi_clock_source_t` to know the supported clock sources. By default driver will set :cpp:member:`spi_device_handle_t::cfg::clock_source` to `SPI_CLK_SRC_DEFAULT`. This usually stands for the highest frequency among GPSPI clock sources. Its value will be different among chips. -Actual clock frequency of a device may not be exactly equal to the number you set, it will be re-calculated by the driver to the nearest hardware compatible number, and not larger than the clock frequency of the clock source. You can call :cpp:func:`spi_device_get_actual_freq` or use :cpp:member:`spi_device_handle_t::real_clk_freq_hz` directly to know the actual frequency computed by the driver. +Actual clock frequency of a device may not be exactly equal to the number you set, it will be re-calculated by the driver to the nearest hardware compatible number, and not larger than the clock frequency of the clock source. You can call :cpp:func:`spi_device_get_actual_freq` to know the actual frequency computed by the driver. Theoretical maximum transfer speed of Write or Read phase can be calculated according to the table below: