Skip to content

Commit 768a7a8

Browse files
committed
fix(driver_spi): master driver change esp32p4 default src to pll
1 parent 4a18951 commit 768a7a8

File tree

10 files changed

+45
-55
lines changed

10 files changed

+45
-55
lines changed

components/driver/test_apps/components/test_driver_utils/include/test_spi_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#define WIRE_DELAY 12.5
9090

9191
#else
92+
#define UNCONNECTED_PIN 8
9293
#define GPIO_DELAY 0
9394
#define ESP_SPI_SLAVE_TV 0
9495
#define WIRE_DELAY 12.5

components/esp_driver_spi/src/gpspi/spi_common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ static void bus_iomux_pins_set_quad(spi_host_device_t host, const spi_bus_config
515515
// check if the GPIO is already used by others
516516
static void s_spi_common_gpio_check_reserve(gpio_num_t gpio_num)
517517
{
518+
assert(GPIO_IS_VALID_GPIO(gpio_num)); //coverity check
518519
uint64_t orig_occupied_map = esp_gpio_reserve(BIT64(gpio_num));
519520
if (orig_occupied_map & BIT64(gpio_num)) {
520521
ESP_LOGW(SPI_TAG, "GPIO %d is conflict with others and be overwritten", gpio_num);
@@ -523,6 +524,7 @@ static void s_spi_common_gpio_check_reserve(gpio_num_t gpio_num)
523524

524525
static void s_spi_common_bus_via_gpio(gpio_num_t gpio_num, int in_sig, int out_sig, uint64_t *io_mask)
525526
{
527+
assert(GPIO_IS_VALID_GPIO(gpio_num)); //coverity check
526528
if (in_sig != -1) {
527529
gpio_input_enable(gpio_num);
528530
esp_rom_gpio_connect_in_signal(gpio_num, in_sig, false);
@@ -807,6 +809,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *
807809
ESP_RETURN_ON_ERROR(spicommon_bus_alloc(host_id, "spi master"), SPI_TAG, "alloc host failed");
808810
spi_bus_attr_t *bus_attr = (spi_bus_attr_t *)spi_bus_get_attr(host_id);
809811
spicommon_bus_context_t *ctx = __containerof(bus_attr, spicommon_bus_context_t, bus_attr);
812+
assert(bus_attr && ctx); //coverity check
810813
bus_attr->bus_cfg = *bus_config;
811814

812815
if (dma_chan != SPI_DMA_DISABLED) {

components/esp_driver_spi/src/gpspi/spi_master.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ We have two bits to control the interrupt:
157157
#define SPI_MASTER_PERI_CLOCK_ATOMIC()
158158
#endif
159159

160+
#define SPI_PERIPH_SRC_FREQ_MAX (80*1000*1000) //peripheral hardware limitation for clock source into peripheral
161+
160162
static const char *SPI_TAG = "spi_master";
161163
#define SPI_CHECK(a, str, ret_val, ...) ESP_RETURN_ON_FALSE_ISR(a, ret_val, SPI_TAG, str, ##__VA_ARGS__)
162164

@@ -395,6 +397,25 @@ int spi_get_freq_limit(bool gpio_is_used, int input_delay_ns)
395397
#endif
396398
}
397399

400+
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
401+
static uint32_t s_spi_find_clock_src_pre_div(uint32_t src_freq, uint32_t target_freq)
402+
{
403+
// pre division must be even and at least 2
404+
uint32_t min_div = ((src_freq / SPI_PERIPH_SRC_FREQ_MAX) + 1) & (~0x01UL);
405+
min_div = min_div < 2 ? 2 : min_div;
406+
407+
uint32_t total_div = src_freq / target_freq;
408+
// Loop the `div` to find a divisible value of `total_div`
409+
for (uint32_t pre_div = min_div; pre_div <= total_div; pre_div += 2) {
410+
if ((total_div % pre_div) || (total_div / pre_div) > SPI_LL_PERIPH_CLK_DIV_MAX) {
411+
continue;
412+
}
413+
return pre_div;
414+
}
415+
return min_div;
416+
}
417+
#endif //SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
418+
398419
/*
399420
Add a device. This allocates a CS line for the device, allocates memory for the device structure and hooks
400421
up the CS pin to whatever is specified.
@@ -416,34 +437,22 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
416437
spi_host_t *host = bus_driver_ctx[host_id];
417438
const spi_bus_attr_t* bus_attr = host->bus_attr;
418439
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);
440+
SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);
419441
#if SOC_SPI_SUPPORT_CLK_RC_FAST
420442
if (dev_config->clock_source == SPI_CLK_SRC_RC_FAST) {
421443
SPI_CHECK(periph_rtc_dig_clk8m_enable(), "the selected clock not available", ESP_ERR_INVALID_STATE);
422444
}
423445
#endif
424-
spi_clock_source_t clk_src = dev_config->clock_source ? dev_config->clock_source : SPI_CLK_SRC_DEFAULT;
425446
uint32_t clock_source_hz = 0;
426447
uint32_t clock_source_div = 1;
448+
spi_clock_source_t clk_src = dev_config->clock_source ? dev_config->clock_source : SPI_CLK_SRC_DEFAULT;
427449
SPI_CHECK(esp_clk_tree_enable_src(clk_src, true) == ESP_OK, "clock source enable failed", ESP_ERR_INVALID_STATE);
428450
esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz);
429451
#if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV
430-
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= MIN(clock_source_hz / 2, (80 * 1000000))), "invalid sclk speed", ESP_ERR_INVALID_ARG);
431-
432-
if (clock_source_hz / 2 > (80 * 1000000)) { //clock_source_hz beyond peripheral HW limitation, calc pre-divider
433-
hal_utils_clk_info_t clk_cfg = {
434-
.src_freq_hz = clock_source_hz,
435-
.exp_freq_hz = dev_config->clock_speed_hz * 2, //we have (hs_clk = 2*mst_clk), calc hs_clk first
436-
.round_opt = HAL_DIV_ROUND,
437-
.min_integ = 1,
438-
.max_integ = SPI_LL_CLK_SRC_PRE_DIV_MAX / 2,
439-
};
440-
hal_utils_calc_clk_div_integer(&clk_cfg, &clock_source_div);
441-
}
442-
clock_source_div *= 2; //convert to mst_clk function divider
443-
clock_source_hz /= clock_source_div; //actual freq enter to SPI peripheral
444-
#else
445-
SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= clock_source_hz), "invalid sclk speed", ESP_ERR_INVALID_ARG);
452+
clock_source_div = s_spi_find_clock_src_pre_div(clock_source_hz, dev_config->clock_speed_hz);
453+
clock_source_hz /= clock_source_div; //actual freq enter to SPI peripheral
446454
#endif
455+
SPI_CHECK(dev_config->clock_speed_hz <= clock_source_hz, "invalid sclk speed", ESP_ERR_INVALID_ARG);
447456
#ifdef CONFIG_IDF_TARGET_ESP32
448457
//The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
449458
//duplex mode does absolutely nothing on the ESP32.

components/esp_driver_spi/test_apps/components/spi_bench_mark/include/spi_performance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 54
6969

7070
#elif CONFIG_IDF_TARGET_ESP32P4
71-
#define IDF_TARGET_MAX_SPI_CLK_FREQ 20*1000*1000
71+
#define IDF_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000
7272
#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 44
7373
#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 28
7474
#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 26

components/esp_driver_spi/test_apps/master/main/test_spi_master.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]")
175175
#if !SOC_CLK_TREE_SUPPORTED
176176
time_tolerance *= 2; //cpu is executing too slow before clock supported
177177
#endif
178-
printf("real_freq %dk predict_cost %d real_cost_us %d diff %d tolerance %d us\n", real_freq_khz, trans_cost_us_predict, trans_cost, (trans_cost - trans_cost_us_predict), time_tolerance);
178+
printf("exp_freq %dk real_freq %dk predict_cost %d real_cost_us %d diff %d tolerance %d us\n", devcfg.clock_speed_hz / 1000, real_freq_khz, trans_cost_us_predict, trans_cost, (trans_cost - trans_cost_us_predict), time_tolerance);
179179

180180
TEST_ASSERT_LESS_THAN_UINT32(time_tolerance, abs(trans_cost - trans_cost_us_predict));
181181
TEST_ESP_OK(spi_bus_remove_device(handle));

components/esp_driver_spi/test_apps/param/main/test_spi_param.c

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
6+
#include <sys/param.h>
67
#include "esp_log.h"
78
#include "esp_attr.h"
89
#include "soc/spi_periph.h"
@@ -21,10 +22,6 @@
2122
#if (TEST_SPI_PERIPH_NUM >= 2)
2223
//These will only be enabled on chips with 2 or more SPI peripherals
2324

24-
#ifndef MIN
25-
#define MIN(a, b)((a) > (b)? (b): (a))
26-
#endif
27-
2825
/********************************************************************************
2926
* Test By Internal Connections
3027
********************************************************************************/
@@ -109,10 +106,6 @@ static void local_test_start(spi_device_handle_t *spi, int freq, const spitest_p
109106
devcfg.flags |= SPI_DEVICE_NO_DUMMY;
110107
}
111108

112-
#if CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-8313, update P4 defaulte clock source
113-
devcfg.clock_source = SPI_CLK_SRC_SPLL;
114-
#endif
115-
116109
//slave config
117110
slvcfg.mode = pset->mode;
118111
slave_pull_up(&buscfg, slvcfg.spics_io_num);
@@ -660,20 +653,10 @@ TEST_CASE("Slave receive correct data", "[spi]")
660653
}
661654
}
662655

663-
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3, ESP32C2)
664-
//These tests are ESP32 only due to lack of runners
656+
#else // #if (TEST_SPI_PERIPH_NUM >= 2)
657+
665658
/********************************************************************************
666-
* Test By Master & Slave (2 boards)
667-
*
668-
* Wiring:
669-
* | Master | Slave |
670-
* | ------ | ----- |
671-
* | 12 | 19 |
672-
* | 13 | 23 |
673-
* | 14 | 18 |
674-
* | 15 | 5 |
675-
* | GND | GND |
676-
*
659+
* Test By Master & Slave (2 boards) using burger runner
677660
********************************************************************************/
678661
static void test_master_init(void **context);
679662
static void test_master_deinit(void *context);
@@ -732,7 +715,7 @@ static void test_master_start(spi_device_handle_t *spi, int freq, const spitest_
732715
buspset.quadhd_io_num = UNCONNECTED_PIN;
733716
}
734717
spi_device_interface_config_t devpset = SPI_DEVICE_TEST_DEFAULT_CONFIG();
735-
devpset.spics_io_num = SPI2_IOMUX_PIN_NUM_CS;
718+
devpset.spics_io_num = PIN_NUM_CS;
736719
devpset.mode = pset->mode;
737720
const int cs_pretrans_max = 15;
738721
if (pset->dup == HALF_DUPLEX_MISO) {
@@ -876,7 +859,7 @@ static void timing_slave_start(int speed, const spitest_param_set_t *pset, spite
876859
slv_buscfg.quadhd_io_num = UNCONNECTED_PIN;
877860
}
878861
spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
879-
slvcfg.spics_io_num = SPI2_IOMUX_PIN_NUM_CS;
862+
slvcfg.spics_io_num = PIN_NUM_CS;
880863
slvcfg.mode = pset->mode;
881864
//Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
882865
slave_pull_up(&slv_buscfg, slvcfg.spics_io_num);
@@ -1261,9 +1244,6 @@ spitest_param_set_t mode_conf[] = {
12611244
},
12621245
};
12631246
TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "")
1264-
1265-
#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3, ESP32C2)
1266-
12671247
#endif // #if (TEST_SPI_PERIPH_NUM >= 2)
12681248

12691249
#define TEST_STEP_LEN 96
@@ -1273,9 +1253,7 @@ static int s_spi_bus_freq[] = {
12731253
IDF_TARGET_MAX_SPI_CLK_FREQ / 7,
12741254
IDF_TARGET_MAX_SPI_CLK_FREQ / 4,
12751255
IDF_TARGET_MAX_SPI_CLK_FREQ / 2,
1276-
#if !CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-8313, update P4 defaulte clock source
12771256
IDF_TARGET_MAX_SPI_CLK_FREQ,
1278-
#endif
12791257
};
12801258

12811259
//------------------------------------------- Full Duplex with DMA Freq test --------------------------------------

components/hal/esp32c5/include/hal/spi_ll.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ extern "C" {
3939
#define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)(data) << (32 - len))
4040
#define SPI_LL_GET_HW(ID) (((ID)==1) ? &GPSPI2 : NULL)
4141

42-
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
42+
#define SPI_LL_DMA_MAX_BIT_LEN SPI_MS_DATA_BITLEN
4343
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words
4444
#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized
4545
#define SPI_LL_SUPPORT_CLK_SRC_PRE_DIV 1 //clock source have divider before peripheral
46-
#define SPI_LL_CLK_SRC_PRE_DIV_MAX 256//div1(8bit)
46+
#define SPI_LL_PERIPH_CLK_DIV_MAX ((SPI_CLKCNT_N + 1) * (SPI_CLKDIV_PRE + 1)) //peripheral internal maxmum clock divider
4747

4848
/**
4949
* The data structure holding calculated clock configuration. Since the

components/hal/esp32c61/include/hal/spi_ll.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ extern "C" {
3939
#define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)(data) << (32 - len))
4040
#define SPI_LL_GET_HW(ID) (((ID)==1) ? &GPSPI2 : NULL)
4141

42-
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
42+
#define SPI_LL_DMA_MAX_BIT_LEN SPI_MS_DATA_BITLEN
4343
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words
4444
#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized
4545
#define SPI_LL_SUPPORT_CLK_SRC_PRE_DIV 1 //clock source have divider before peripheral
46-
#define SPI_LL_CLK_SRC_PRE_DIV_MAX 256//div1(8bit)
46+
#define SPI_LL_PERIPH_CLK_DIV_MAX ((SPI_CLKCNT_N + 1) * (SPI_CLKDIV_PRE + 1)) //peripheral internal maxmum clock divider
4747

4848
/**
4949
* The data structure holding calculated clock configuration. Since the

components/hal/esp32p4/include/hal/spi_ll.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ extern "C" {
3838
#define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)(data) << (32 - len))
3939
#define SPI_LL_GET_HW(ID) (((ID)==1) ? &GPSPI2 : (((ID)==2) ? &GPSPI3 : NULL))
4040

41-
#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits
41+
#define SPI_LL_DMA_MAX_BIT_LEN SPI_MS_DATA_BITLEN
4242
#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words
4343
#define SPI_LL_SUPPORT_CLK_SRC_PRE_DIV 1 //clock source have divider before peripheral
44-
#define SPI_LL_CLK_SRC_PRE_DIV_MAX 512//div1(8bit) * div2(8bit but set const 2)
44+
#define SPI_LL_PERIPH_CLK_DIV_MAX ((SPI_CLKCNT_N + 1) * (SPI_CLKDIV_PRE + 1)) //peripheral internal maxmum clock divider
4545
#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized
4646

4747
/**

components/soc/esp32p4/include/soc/clk_tree_defs.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,7 @@ typedef enum {
500500
SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
501501
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST_20M as SPI source clock */
502502
SPI_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SPLL as SPI source clock */
503-
// TODO: IDF-8313, use PLL as default
504-
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as default source clock */
503+
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_SPLL, /*!< Select SPLL as default source clock */
505504
} soc_periph_spi_clk_src_t;
506505

507506
/////////////////////////////////////////////////PSRAM////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)