Merge branch 'bugfix/spi_clk_rc_fast_enable_disable' into 'master'

spi_master: fix clock source RC_FAST usage

See merge request espressif/esp-idf!22160
This commit is contained in:
Wan Lei 2023-02-06 18:25:23 +08:00
commit a49164b5ec
5 changed files with 22 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

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