SPI Slave: Example not work with other devices

mauriciofarina
Posts: 2
Joined: Wed Apr 03, 2019 11:39 am

SPI Slave: Example not work with other devices

Postby mauriciofarina » Wed Apr 03, 2019 11:54 am

Greetings,

I'm having some trouble implementing a SPI communication between the ESP32 (SLAVE) and the nrf51-dk (MASTER).

Basically, what I'm trying to do is sending a char array from the nrf51 to the ESP32. In order to do so, I'm running a Mbed SPI Master example and trying to receive the array with the esp-idf example (peripherals/spi_slave/receiver). Unfortunately, after the transmission is done, no valid information is received. I also notice that, in most of the cases, my RX buffer is empty or with just a random value on the first element of the array. I've tried connecting the MISO pin on the MOSI pin on each board, and, in both cases, the boards got able to send and receive their own transmissions.


The NRF51 mbed Code:
  1. #include <mbed.h>
  2.  
  3.  
  4. Serial pc(USBTX, USBRX);  //UART
  5. SPI spi(SPI_PSELMOSI0,SPI_PSELMISO0,SPI_PSELSCK0);//SPI
  6. DigitalIn handshake(p23); //SPI Handshake Pin
  7. DigitalOut cs(SPI_PSELSS0); //SPI Chip Select
  8.  
  9.  
  10. int main() {
  11.  
  12.  
  13.     cs = 1; //Disable Slave
  14.  
  15.     pc.baud(9600);  //UART Init
  16.     pc.printf("Starting...\n\r");
  17.  
  18.     spi.format(8,3);  //SPI 8 bits, Mode 3
  19.     spi.frequency(1000000); // 1 MHz clock
  20.  
  21.    
  22.  
  23.     while(1) {
  24.        
  25.       //RX TX Buffers
  26.       char tx_buffer[128] = {"MASTER TX BUFFER"};
  27.       char tx_length = 128;
  28.       char rx_buffer[128] = {"MASTER RX BUFFER"};
  29.       char rx_length = 128;
  30.      
  31.      
  32.       cs = 0; //Enable Slave
  33.  
  34.       while(!handshake){} // Wait for slave to be available
  35.  
  36.       spi.write(tx_buffer, tx_length, rx_buffer, rx_length);  //Transmission
  37.  
  38.       cs = 1; // Disable Slave
  39.  
  40.  
  41.       pc.printf("String:\n\r"); //Print RX Buffer
  42.       for(i = 0; i < 128 ; i++){
  43.         pc.printf("%c", rx_buffer[i]);
  44.       }
  45.       pc.printf("\n\r");
  46.      
  47.      
  48.       wait(5); // Wait
  49.  
  50.     }
  51. }


On the ESP32 I'm running the SPI_Slave (Receiver) example with a few changes:

- SPI mode 3
- Added the Attribute WORD_ALIGNED_ATTR to recvbuf and sendbuf
- Changed the transmission String

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stddef.h>
  4. #include <string.h>
  5.  
  6. #include "freertos/FreeRTOS.h"
  7. #include "freertos/task.h"
  8. #include "freertos/semphr.h"
  9. #include "freertos/queue.h"
  10.  
  11. #include "lwip/sockets.h"
  12. #include "lwip/dns.h"
  13. #include "lwip/netdb.h"
  14. #include "lwip/igmp.h"
  15.  
  16. #include "esp_wifi.h"
  17. #include "esp_system.h"
  18. #include "esp_event.h"
  19. #include "esp_event_loop.h"
  20. #include "nvs_flash.h"
  21. #include "soc/rtc_cntl_reg.h"
  22. #include "esp32/rom/cache.h"
  23. #include "driver/spi_slave.h"
  24. #include "esp_log.h"
  25. #include "esp_spi_flash.h"
  26.  
  27.  
  28.  
  29. #define GPIO_HANDSHAKE 2
  30. #define GPIO_MOSI 12
  31. #define GPIO_MISO 13
  32. #define GPIO_SCLK 15
  33. #define GPIO_CS 14
  34.  
  35.  
  36. void my_post_setup_cb(spi_slave_transaction_t *trans) {
  37.     WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1<<GPIO_HANDSHAKE));
  38. }
  39.  
  40. void my_post_trans_cb(spi_slave_transaction_t *trans) {
  41.     WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1<<GPIO_HANDSHAKE));
  42. }
  43.  
  44. void app_main()
  45. {
  46.     int n=0;
  47.     esp_err_t ret;
  48.  
  49.     spi_bus_config_t buscfg={
  50.         .mosi_io_num=GPIO_MOSI,
  51.         .miso_io_num=GPIO_MISO,
  52.         .sclk_io_num=GPIO_SCLK
  53.     };
  54.  
  55.     spi_slave_interface_config_t slvcfg={
  56.         .mode=3,    // Changed to mode 3
  57.         .spics_io_num=GPIO_CS,
  58.         .queue_size=3,
  59.         .flags=0,
  60.         .post_setup_cb=my_post_setup_cb,
  61.         .post_trans_cb=my_post_trans_cb
  62.     };
  63.  
  64.     gpio_config_t io_conf={
  65.         .intr_type=GPIO_INTR_DISABLE,
  66.         .mode=GPIO_MODE_OUTPUT,
  67.         .pin_bit_mask=(1<<GPIO_HANDSHAKE)
  68.     };
  69.  
  70.     gpio_config(&io_conf);
  71.  
  72.     gpio_set_pull_mode(GPIO_MOSI, GPIO_PULLUP_ONLY);
  73.     gpio_set_pull_mode(GPIO_SCLK, GPIO_PULLUP_ONLY);
  74.     gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);
  75.  
  76.     ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1);
  77.     assert(ret==ESP_OK);
  78.  
  79.     WORD_ALIGNED_ATTR char sendbuf[129]=""; // Added the WORD ALIGNED Attribute
  80.     WORD_ALIGNED_ATTR char recvbuf[129]="";
  81.     memset(recvbuf, 0, 33);
  82.     spi_slave_transaction_t t;
  83.     memset(&t, 0, sizeof(t));
  84.  
  85.     while(1) {
  86.         memset(recvbuf, 0xA5, 129);
  87.         sprintf(sendbuf, "SLAVE TX BUFFER"); // Changed String
  88.  
  89.         t.length=128*8;
  90.         t.tx_buffer=sendbuf;
  91.         t.rx_buffer=recvbuf;
  92.        
  93.         ret=spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
  94.  
  95.         printf("Received: %s\n", recvbuf);
  96.         n++;
  97.     }
  98.  
  99. }
Any ideas of what I'm doing wrong?

JL1946
Posts: 11
Joined: Mon Feb 25, 2019 3:46 pm

Re: SPI Slave: Example not work with other devices

Postby JL1946 » Wed Nov 27, 2019 10:06 pm

By now, you have figured out that the error is in the Tx_length which is supposed to indicate the number of BITS being transmitted. You indicate a char of 128 bytes and a length of 128 - this should be 128*8 (Bytes*Bits). That is why your Receive Buffer is almost Empty - the sender is transmitting just 16 Bytes (16*8 = 128).

Who is online

Users browsing this forum: MikeMyhre and 111 guests