]> granicus.if.org Git - esp-idf/commitdiff
Add test for spi clock, fix corner cases)
authorJeroen Domburg <jeroen@espressif.com>
Wed, 11 Jan 2017 08:13:33 +0000 (16:13 +0800)
committerJeroen Domburg <jeroen@espressif.com>
Wed, 11 Jan 2017 08:13:33 +0000 (16:13 +0800)
components/driver/spi_master.c
components/driver/test/test_spi_master.c

index 53be8b29de6df96ebe6402120b89dffc6c9e802f..6162edba3674dc5500f4e587a626bbe7c48487ff 100644 (file)
@@ -318,6 +318,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host, spi_device_interface_config
     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;
@@ -412,15 +413,15 @@ static void spi_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle) {
         //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;
index 119c94bc570ab4f7315511705234a34ecd94ad90..d54cc5a633f68972f053ba1f7c9368790920e312 100644 (file)
 #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]")
 {