Page 1 of 1

SPI not sending data correctly

Posted: Thu Mar 12, 2020 12:39 pm
by sravyts
Hello
I have two ESP32 boards and I want to send data from one to another using the SPI sender and receiver example(esp-idf/examples/peripherals/spi_slave). Using the example code this works for sending strings. However, I would like to send an integer array from the slave to the master (and afterwards process the received data). I have adapted the sample code a bit for my needs but I am facing two problems. 1) only my first int seems to be received by the master 2) there seems to be an error in the data I receive, it's shifted by 128. I tried to solve this by placing WORD_ALIGNED_ATTR before the int sendbuf[11] = {0}; and now I am getting closer but still not exactly equal to the send value.

Below you can find a snip of the code I altered:

MASTER:
...
int n=0;
//char sendbuf[128] = {0};
//char recvbuf[128] = {0};
int recvbuf[10] = {0};
spi_transaction_t t;
memset(&t, 0, sizeof(t));

//Create the semaphore.
rdySem=xSemaphoreCreateBinary();

//Set up handshake line interrupt.
gpio_config(&io_conf);
gpio_install_isr_service(0);
gpio_set_intr_type(GPIO_HANDSHAKE, GPIO_PIN_INTR_POSEDGE);
gpio_isr_handler_add(GPIO_HANDSHAKE, gpio_handshake_isr_handler, NULL);

//Initialize the SPI bus and add the device we want to send stuff to.
ret=spi_bus_initialize(SENDER_HOST, &buscfg, DMA_CHAN);
assert(ret==ESP_OK);
ret=spi_bus_add_device(SENDER_HOST, &devcfg, &handle);
assert(ret==ESP_OK);

//Assume the slave is ready for the first transmission: if the slave started up before us, we will not detect
//positive edge on the handshake line.
xSemaphoreGive(rdySem);

while(1) {
//int res = snprintf(sendbuf, sizeof(sendbuf),
// "This is master, transmission no. %04i. Last time, I received: \"%s\"", n, recvbuf);
//if (res >= sizeof(sendbuf)) {
// printf("Data truncated\n");
//}
t.length=sizeof(int)*8; //length is in bits and sizeof gives bytes
t.tx_buffer=NULL;//sendbuf;
t.rx_buffer=recvbuf;
//Wait for slave to be ready for next byte before sending
xSemaphoreTake(rdySem, portMAX_DELAY); //Wait until slave is ready
ret=spi_device_transmit(handle, &t);
//printf("Received: \t %i to %i \n",recvbuf[0],recvbuf[9]);
printf("Master received: \t %i, \t %i, \t %i, \t %i, \t %i, \t %i \n", recvbuf[0],recvbuf[1],recvbuf[2],recvbuf[5],recvbuf[8],recvbuf[9]);

n++;
}

//Never reached.
ret=spi_bus_remove_device(handle);
assert(ret==ESP_OK);
}

SLAVE:

//Main application
void app_main(void)
{
int n=0;
int j =0;
int i = 0;
esp_err_t ret;

//Configuration for the SPI bus
spi_bus_config_t buscfg={
.mosi_io_num=GPIO_MOSI,
.miso_io_num=GPIO_MISO,
.sclk_io_num=GPIO_SCLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};

//Configuration for the SPI slave interface
spi_slave_interface_config_t slvcfg={
.mode=0,
.spics_io_num=GPIO_CS,
.queue_size=3,
.flags=0,
.post_setup_cb=my_post_setup_cb,
.post_trans_cb=my_post_trans_cb
};

//Configuration for the handshake line
gpio_config_t io_conf={
.intr_type=GPIO_INTR_DISABLE,
.mode=GPIO_MODE_OUTPUT,
.pin_bit_mask=(1<<GPIO_HANDSHAKE)
};

//Configure handshake line as output
gpio_config(&io_conf);
//Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
gpio_set_pull_mode(GPIO_MOSI, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(GPIO_SCLK, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);

//Initialize SPI slave interface
//ret=spi_slave_initialize(RCV_HOST, &buscfg, &slvcfg, DMA_CHAN);
ret=spi_slave_initialize(RCV_HOST, &buscfg, &slvcfg, 0);

assert(ret==ESP_OK);

//WORD_ALIGNED_ATTR char sendbuf[129]="";
//WORD_ALIGNED_ATTR char recvbuf[129]="";
WORD_ALIGNED_ATTR int sendbuf[11] = {0};
//memset(recvbuf, 0, 33);
spi_slave_transaction_t t;
memset(&t, 0, sizeof(t));

while(1) {
//Clear receive buffer, set send buffer to something sane
//memset(recvbuf, 0xA5, 129);
//sprintf(sendbuf, "This is the slave with transmission number %04d.", n);
sendbuf = i+2;
//Set up a transaction of 128 bytes to send/receive
t.length=sizeof(int)*8;//128*8;
t.tx_buffer=sendbuf;
t.rx_buffer=NULL; // recvbuf;
/* This call enables the SPI slave interface to send/receive to the sendbuf and recvbuf. The transaction is
initialized by the SPI master, however, so it will not actually happen until the master starts a hardware transaction
by pulling CS low and pulsing the clock etc. In this specific example, we use the handshake line, pulled up by the
.post_setup_cb callback that is called as soon as a transaction is ready, to let the master know it is free to transfer
data.
*/
if(n==1000){
ret=spi_slave_transmit(RCV_HOST, &t, portMAX_DELAY);
printf("Slave has send: \t %i, \t %i, \t %i, \t %i, \t %i, \t %i \n", sendbuf[0],sendbuf[1],sendbuf[2],sendbuf[5],sendbuf[8],sendbuf[9]);
}

//spi_slave_transmit does not return until the master has done a transmission, so by here we have sent our data and
//received data from the master. Print it.
//n++;
n = (n+1)%1000000; // Adapted by SR on 2020_03_05
j = (j+1)%11;
i = (i+1)%10;
}

}

Re: SPI not sending data correctly

Posted: Thu Mar 19, 2020 8:42 am
by sravyts
Does someone have a clue of what I am doing wrong?

Re: SPI not sending data correctly

Posted: Sun Mar 22, 2020 11:48 am
by ESP_Sprite
On 1: take a long, hard look at what you wrote here. Note t.length is in bits.

Code: Select all

t.length=sizeof(int)*8;