spi driver, spi_get_trans_result stuck

veelox
Posts: 16
Joined: Tue Nov 03, 2020 4:21 pm

spi driver, spi_get_trans_result stuck

Postby veelox » Fri Dec 04, 2020 7:08 pm

Hi,

I am trying to write an SPI driver for my project, but cant seems to work. I've tried to use spi_device_transmit, spi_device_polling_transmit, queue_trans, get_trans but i never seem to be able to get it working. I've tried multiple different bus and device config. But it is always stuck, waiting for the slave device to answer.
  1. void initializeSPI(void)
  2. {
  3.     esp_err_t err;
  4.      
  5.     spi_bus_config_t buscfg;
  6.  
  7.     buscfg.miso_io_num=19;
  8.     buscfg.mosi_io_num=23;
  9.     buscfg.sclk_io_num=18;
  10.     buscfg.quadwp_io_num=-1;
  11.     buscfg.quadhd_io_num=-1;  
  12.     buscfg.max_transfer_sz=4094;
  13.  
  14.     err=spi_bus_initialize(SPI3_HOST, &buscfg, 1);    //return ESP_OK
  15.     printf("spi initialize err : %s\r\n", esp_err_to_name(err));
  16. }
  17.  
  18.  
  19. // SPI
  20. #define SPI_MAX_CS  34  // GPIO 33 is the last port that can be used as output
  21. #define BUFFER_SIZE  200
  22. spi_device_handle_t spi[SPI_MAX_CS] = { 0 };
  23. uint8_t _csPin_ = 21;
  24.  
  25. ICM_20948_SPI::ICM_20948_SPI()
  26. {
  27. }
  28.  
  29. ICM_20948_Status_e ICM_20948_SPI::begin(uint8_t csPin, uint32_t SPIFreq)
  30. {
  31.     esp_err_t err;
  32.     spi_device_interface_config_t devcfg;
  33.  
  34.     devcfg.clock_speed_hz=SPIFreq;
  35.     devcfg.mode=ICM_20948_SPI_DEFAULT_MODE;
  36.     devcfg.spics_io_num=_csPin_;
  37.     devcfg.queue_size=1;
  38.     devcfg.flags = 0;            
  39.     devcfg.command_bits = 0;       // no command bits used
  40.     devcfg.address_bits = 0;       // register address is first byte in MOSI
  41.     devcfg.dummy_bits = 0;          // no dummy bits used
  42.     devcfg.pre_cb =NULL;
  43.     devcfg.post_cb=NULL;
  44.  
  45.     spi[_csPin_] = (spi_device_handle_t)malloc(sizeof(spi_device_handle_t));
  46.  
  47.     err=spi_bus_add_device(SPI3_HOST, &devcfg, &spi[_csPin_]);      // return ESP_OK
  48.     printf("icm 20948 add device err : %s\r\n", esp_err_to_name(err));
  49.  
  50.     if (err != ESP_OK) free (spi[_csPin_]);
  51.  
  52.     // Set up the serif
  53.     _serif.write = ICM_20948_write_SPI;
  54.     _serif.read = ICM_20948_read_SPI;
  55.     _serif.user = (void *)this; // refer to yourself in the user field
  56.  
  57.     // Link the serif
  58.     _device._serif = &_serif;
  59.  
  60.     // Perform default startup
  61.     status = startupDefault();
  62.     if (status != ICM_20948_Stat_Ok)
  63.     {
  64.         return status;
  65.     }
  66.  
  67.     return ICM_20948_Stat_Ok;
  68. }
  69.  
  70. ICM_20948_Status_e ICM_20948_write_SPI(uint8_t reg, uint8_t *data, uint32_t len, void *user)
  71. {
  72.     static uint8_t mosi[BUFFER_SIZE];
  73.  
  74.     mosi[0] = reg;
  75.  
  76.     for (int i = 0; i < len; i++)
  77.         mosi[i+1] = data[i];
  78.  
  79.     if (!spi_transfer_pf (mosi, NULL, len+1))
  80.     {
  81.         return ICM_20948_Stat_Err;
  82.     }
  83.  
  84.     return ICM_20948_Stat_Ok;
  85. }
  86.  
  87. ICM_20948_Status_e ICM_20948_read_SPI(uint8_t reg, uint8_t *buff, uint32_t len, void *user)
  88. {
  89.     if (user == NULL)
  90.     {
  91.         return ICM_20948_Stat_ParamErr;
  92.     }
  93.  
  94.     static uint8_t mosi[BUFFER_SIZE];
  95.     static uint8_t miso[BUFFER_SIZE];
  96.  
  97.     memset (mosi, 0xff, BUFFER_SIZE);
  98.     memset (miso, 0xff, BUFFER_SIZE);
  99.  
  100.     mosi[0] = reg;
  101.  
  102.     if (!spi_transfer_pf (mosi, miso, len+1))
  103.     {
  104.         return ICM_20948_Stat_Err;
  105.     }
  106.  
  107.     for (int i=0; i < len; i++)
  108.       buff[i] = miso[i+1];
  109.  
  110.     return ICM_20948_Stat_Ok;
  111. }
  112.  
  113. uint32_t spi_transfer_pf (const uint8_t *mosi, uint8_t *miso, uint32_t len)
  114. {
  115.     spi_transaction_t spi_trans;
  116.  
  117.     memset(&spi_trans, 0, sizeof(spi_trans)); // zero out spi_trans;
  118.     spi_trans.tx_buffer = mosi;
  119.     spi_trans.rx_buffer = miso;
  120.     spi_trans.length=len*8;
  121.     spi_trans.user=(void*)0;
  122.  
  123.     // Stuck in here
  124.     if (spi_device_transmit(spi[_csPin_], &spi_trans) != ESP_OK)   //spi_device_polling_transmit trigger watchdog
  125.     {
  126.         printf("spi device transmit != ESP_OK\r\n");
  127.         return 0;
  128.     }
  129.  
  130.     printf("spi device transmit = ESP_OK\r\n");
  131.     return len;
  132. }
  133.  
The spi_device_transmit seems alive since it does not trigger my thread watchdog. Inside the function, spi_device_queue_trans return ESP_OK, it is stuck inside spi_get_trans_result.

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

Re: spi driver, spi_get_trans_result stuck

Postby ESP_Sprite » Sat Dec 05, 2020 2:57 am

One thing that might affect your setup: make sure to zero-initialize your config structs. Even if your current setup might not have any issues, uninitialized members can break your code later on. E.g.

Code: Select all

spi_device_interface_config_t devcfg={};
will work.

veelox
Posts: 16
Joined: Tue Nov 03, 2020 4:21 pm

Re: spi driver, spi_get_trans_result stuck

Postby veelox » Sat Dec 05, 2020 3:11 pm

Well yes its working, thank you!!

Who is online

Users browsing this forum: benrank and 128 guests