SPI problem

BangingBits
Posts: 2
Joined: Sun Feb 26, 2023 5:01 am

SPI problem

Postby BangingBits » Sun Feb 26, 2023 5:17 am

I have been trying for a few days to figure out how to get SPI to work and have had no luck.
Board is ESP32 Wrover Kit
Slave is AD7124 ADC chip
ESP-IDF v5.0

The ADC works with other platforms I have so there is not issues with it. I don't have a way to scope signals so I am stuck with debug printing or OpenOCD. With OpenOCD I haven't had much luck either. I am just trying to do a basic read and I'm getting back random results or just 0's. I have tried every way I can find examples of and it is commented out below some of what I have tried.

I have tried to keep it simple after I couldn't get my library to work.
What am I doing wrong?
  1. #include <stdio.h>
  2.  
  3. #include "freertos/FreeRTOS.h"
  4. #include "freertos/task.h"
  5.  
  6. #include "driver/spi_common.h"
  7. #include "driver/spi_master.h"
  8.  
  9. #include "esp_err.h"
  10. #include "esp_log.h"
  11.  
  12. #include "sdkconfig.h"
  13.  
  14. spi_device_handle_t handle;
  15.  
  16. uint8_t txData[4] = {0};
  17. //uint8_t rxData[4] = {0};
  18.  
  19. static void spi_init()
  20. {
  21.     spi_bus_config_t buscfg = {
  22.         .miso_io_num = 19, // 22, // 12,
  23.         .mosi_io_num = 23, // 21, // 13,
  24.         .sclk_io_num = 18, // 17, // 14,
  25.         .quadwp_io_num = -1,
  26.         .quadhd_io_num = -1,
  27.         .max_transfer_sz = 32,
  28.         .flags = 0,
  29.     };
  30.  
  31.     ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_DISABLED)); // SPI_DMA_CH_AUTO
  32.  
  33.     spi_device_interface_config_t devcfg = {
  34.         .address_bits = 0,//8, // set if using .addr in transaction
  35.         .command_bits = 0, // set if using .cmd in transaction
  36.         .dummy_bits = 0,
  37.         .mode = 3,
  38.         .duty_cycle_pos = 0,
  39.         .cs_ena_posttrans = 0,
  40.         .cs_ena_pretrans = 0,
  41.         .clock_speed_hz = 5000000,
  42.         .spics_io_num = -1,
  43.         .flags = 0, // SPI_DEVICE_HALFDUPLEX,
  44.         .queue_size = 1,
  45.         .pre_cb = NULL,
  46.         .post_cb = NULL,
  47.     };
  48.     ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &devcfg, &handle));
  49. };
  50.  
  51. static int spiRead(uint8_t *_data, int len)
  52. {
  53.     esp_err_t intError = 0;
  54.     spi_transaction_t trans_desc;
  55.     uint8_t rxData[4] = {0};
  56.     int32_t value = 0;
  57.  
  58.     printf("address %x\n", _data[0]);
  59.  
  60.     trans_desc.addr = 0,//_data[0];
  61.     trans_desc.cmd = 0;
  62.     trans_desc.flags = 0, // SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
  63.         trans_desc.user = NULL,
  64.     trans_desc.length = 8 * len; // total data bits, sent and received
  65.         //trans_desc.tx_buffer = NULL; // if using .addr
  66.     trans_desc.tx_buffer = _data;
  67.     //  trans_desc.tx_data[0] = _data[0];
  68.     //  trans_desc.tx_data[1] = _data[1];
  69.     //  trans_desc.tx_data[2] = _data[2];
  70.     //  trans_desc.tx_data[3] = _data[3];
  71.     trans_desc.rxlength = 8 * (len-1);
  72.     trans_desc.rx_buffer = rxData;
  73.     // trans_desc.rx_data = NULL;
  74.  
  75.     intError = spi_device_transmit(handle, &trans_desc);
  76.  
  77.     printf("rx data %x\n", rxData[0]);
  78.     // printf("rx data2 %x\n\n", trans_desc.rx_data[0]);
  79.  
  80.     /* Build the result */
  81.     for (int i = 0; i < len + 1; i++)
  82.     {
  83.         value <<= 8;
  84.         value += rxData[i];
  85.     }
  86.     printf("value %lx\n\n", value);
  87.  
  88.     if (intError != 0)
  89.     {
  90.         printf("error %d\n", intError);
  91.     }
  92.     return intError;
  93. }
  94.  
  95. static int spiWrite(uint8_t *_data)
  96. {
  97.     esp_err_t intError;
  98.     spi_transaction_t trans_desc;
  99.  
  100.     trans_desc.addr = 0;
  101.     trans_desc.cmd = 0;
  102.     trans_desc.flags = 0;
  103.     trans_desc.length = (8 * 4); // total data bits
  104.     trans_desc.tx_buffer = _data;
  105.     trans_desc.rxlength = 0;
  106.     trans_desc.rx_buffer = NULL;
  107.  
  108.     intError = spi_device_transmit(handle, &trans_desc);
  109.  
  110.     if (intError != 0)
  111.     {
  112.         printf("error %d\n", intError);
  113.     }
  114.     return intError;
  115. }
  116.  
  117. void reset()
  118. {
  119.     // need to write 64 1's to reset, can do this with address phase, command phase only supports 16 bit and write 32 bit?
  120.     uint8_t wr_buf[4] = {0xFF, 0xFF, 0xFF, 0xFF};
  121.     spiWrite(wr_buf);
  122.     spiWrite(wr_buf);
  123. }
  124. void app_main(void)
  125. {
  126.     spi_init();
  127.     vTaskDelay(1000 / portTICK_PERIOD_MS);
  128.  
  129.     // reset();
  130.     vTaskDelay(100 / portTICK_PERIOD_MS);
  131.  
  132.     txData[0] = 0x45;   // ID register
  133.     spiRead(txData, 1); // should return 0x14
  134.     vTaskDelay(100 / portTICK_PERIOD_MS);
  135.  
  136.     txData[0] = 0x40;   // COMMS register
  137.     spiRead(txData, 1); // should return 0x00
  138.     vTaskDelay(100 / portTICK_PERIOD_MS);
  139.  
  140.     txData[0] = 0x46;   // Error register
  141.     spiRead(txData, 3); // should return 0x00
  142.  
  143.     txData[0] = 0x49;   // CHANNEL_0 register
  144.     spiRead(txData, 2); // should return 0x8001
  145. }
Here are some of the results I get. AboveI have a comment on what I should get.
address 45
rx data ff
value ff00

address 40
rx data f7
value f700

address 46
rx data ff
value fffb0000

address 49
rx data ff
value ff0000

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: SPI problem

Postby ESP_Sprite » Sun Feb 26, 2023 5:40 am

Hard to say. For issues like this, you generally want to own at the very least a cheap logic analyzer, or they get very hard to debug.

MicroController
Posts: 1710
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: SPI problem

Postby MicroController » Sun Feb 26, 2023 4:02 pm

You code as-is cannot work.
E.g.: spiRead(txData, 1); // should return 0x14
In half-duplex mode, this would have the SPI send len=1 byte from txData and then receive (len-1)=0 bytes back.
In full-duplex mode, there's one bit received for every bit sent, so you'd have to send enough bits for the write+read, i.e. send 8 bits of data + e.g. 16 0-bits, receiving back 8+16=24 bits, of which you'd then just discard the first 8.

BangingBits
Posts: 2
Joined: Sun Feb 26, 2023 5:01 am

Re: SPI problem

Postby BangingBits » Sun Feb 26, 2023 9:34 pm

I am working on getting an analyzer so it'll be another week or so. In the mean time...

As for the half/full duplex thing. That makes sense and being this is full duplex it sounds like I should write 4 bytes if expecting 3 in return. Is that right? And I was playing with different len of settings for both with the -1 and not. Never got anything to work.

But, I changed these lines and got it working.
  1. trans_desc.length = 32,//8 * len;
  2. trans_desc.tx_buffer = _data;
  3. trans_desc.rxlength = 32; // 8 * len;
  4. trans_desc.rx_buffer = _data;
  5.  
  6. ...
  7.  
  8.  for (int i = 1; i < len + 1; i++) // changed i = 0 to 1
  9.  
  10. // keep this to use for building value adjust based on return size
  11. spiRead(txData, 1); // should return 0x14

Can't believe how many sites I have read and example code to be that easy. I didn't see that easy of an explanation anywhere.
So far so good and it works better with using the same _data array for send and receive as I was getting a few random values. Now it works like my other apps.

Who is online

Users browsing this forum: Baidu [Spider], Gaston1980 and 78 guests