SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(spihost[host]!=NULL, "host not initialized", ESP_ERR_INVALID_STATE);
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);
+ SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);
for (freecs=0; freecs<NO_CS; freecs++) {
//See if this slot is free; reserve if it is by putting a dummy pointer in the slot. We use an atomic compare&swap to make this thread-safe.
if (__sync_bool_compare_and_swap(&spihost[host]->device[freecs], NULL, (spi_device_t *)1)) break;
//with the higher n.
int bestn=-1;
int bestpre=-1;
- int besterr=hz;
+ int besterr=0;
int errval;
for (n=1; n<=64; n++) {
//Effectively, this does pre=round((fapb/n)/hz).
pre=((fapb/n)+(hz/2))/hz;
- if (pre<0) pre=0;
+ if (pre<=0) pre=1;
if (pre>8192) pre=8192;
errval=abs(spi_freq_for_pre_n(fapb, pre, n)-hz);
- if (errval<=besterr) {
+ if (bestn==-1 || errval<=besterr) {
besterr=errval;
bestn=n;
bestpre=pre;
#include "freertos/xtensa_api.h"
#include "unity.h"
#include "driver/spi_master.h"
+#include "soc/dport_reg.h"
+#include "soc/spi_reg.h"
+#include "soc/spi_struct.h"
+static void check_spi_pre_n_for(int clk, int pre, int n)
+{
+ esp_err_t ret;
+ spi_device_handle_t handle;
+
+ spi_device_interface_config_t devcfg={
+ .command_bits=0,
+ .address_bits=0,
+ .dummy_bits=0,
+ .clock_speed_hz=clk,
+ .duty_cycle_pos=128,
+ .mode=0,
+ .spics_io_num=21,
+ .queue_size=3
+ };
+ char sendbuf[16]="";
+ spi_transaction_t t;
+ memset(&t, 0, sizeof(t));
+
+ ret=spi_bus_add_device(HSPI_HOST, &devcfg, &handle);
+ TEST_ASSERT(ret==ESP_OK);
+
+ t.length=16*8;
+ t.tx_buffer=sendbuf;
+ ret=spi_device_transmit(handle, &t);
+
+ printf("Checking clk rate %dHz. expect pre %d n %d, got pre %d n %d\n", clk, pre, n, SPI2.clock.clkdiv_pre+1, SPI2.clock.clkcnt_n+1);
+
+ TEST_ASSERT(SPI2.clock.clkcnt_n+1==n);
+ TEST_ASSERT(SPI2.clock.clkdiv_pre+1==pre);
+
+ ret=spi_bus_remove_device(handle);
+ TEST_ASSERT(ret==ESP_OK);
+}
+
+
+TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
+{
+ spi_bus_config_t buscfg={
+ .mosi_io_num=4,
+ .miso_io_num=16,
+ .sclk_io_num=25,
+ .quadwp_io_num=-1,
+ .quadhd_io_num=-1
+ };
+ esp_err_t ret;
+ ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
+ TEST_ASSERT(ret==ESP_OK);
+
+ check_spi_pre_n_for(8000000, 1, 10);
+ check_spi_pre_n_for(800000, 2, 50);
+ check_spi_pre_n_for(100000, 16, 50);
+ check_spi_pre_n_for(333333, 4, 60);
+ check_spi_pre_n_for(1, 8192, 64); //Actually should generate the minimum clock speed, 152Hz
+
+ ret=spi_bus_free(HSPI_HOST);
+ TEST_ASSERT(ret==ESP_OK);
+}
+
TEST_CASE("SPI Master test", "[spi]")
{