cancel
Showing results for 
Search instead for 
Did you mean: 

SPI: losing data when alternating receive / transmit

ph_zupancic
Associate II
Posted on February 24, 2016 at 14:59

Hi,

I am using SPI to send data between an STM32F411RE and a Raspberry Pi 2, using the HAL library on the STM and the Python frontend of spidev on the Pi. With this I can send or receive arbitrary amounts of data between the two. However, when I switch between transmitting and receiving, the two communicators get out of sync by one byte, and I have been trying to figure out why.

The following code should send the same array of 20 numbers back and forth between the STM (slave) and the Pi (master):

in main():

uint8_t buffer[20];

while (1)

  {

        HAL_SPI_Receive(&hspi1, buffer, 20, 1000000);

        HAL_SPI_Transmit(&hspi1, buffer, 20, 1000000);

  }

void MX_SPI1_Init(void)

{

  hspi1.Instance = SPI1;

  hspi1.Init.Mode = SPI_MODE_SLAVE;

  hspi1.Init.Direction = SPI_DIRECTION_2LINES;

  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

  hspi1.Init.NSS = SPI_NSS_SOFT;

  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

  hspi1.Init.TIMode = SPI_TIMODE_DISABLED;

  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;

  hspi1.Init.CRCPolynomial = 10;

  HAL_SPI_Init(&hspi1);

}

on the Pi:

import time

import spidev

spi = spidev.SpiDev()

spi.open(0,0)

spi.max_speed_hz = 100000

spi.mode = 0b00

data = range(0,20)

while True:

    print data

    spi.writebytes(data)

    data = spi.readbytes(20)

    time.sleep(0.5)

When I run this, I always get

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 17]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]

[0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]

[0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]

[0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]

[0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]

[0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]

[0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

though I would expect infinite repetitions of the first line.

Unfortunately, I cannot be certain whether the issue is on the STM or the Pi. Have you seen this behavior before and/or can you explain it?

#no-hablo-hal #spi
1 REPLY 1
Posted on February 24, 2016 at 15:18

Even with a simple echo it takes one byte time for the data to clock out completely and be received at the other end.

There could be some other issues deeper in the HAL (TXE/RXNE). I'd start be sending a fixed pattern back, and look at how the CS line can be used to synchronize the starting point.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..