cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476 SPI slave mode with DMA repeated first character

LM.2
Associate II

I have a STM32L476 operating in spi slave mode and an embedded linux master. It is meant to offload the contents of a file stored on an SD card. I do this in 2052 byte bursts (2048 data + 4 byte checksum). The very first transfer I send duplicates the 1st character and I have no idea why. If I read 2053 bytes and offset the checksum calculation on the linux side by 1 byte on the 1st transmission then the checksum passes. I have no idea why this is happening though. What is the proper way of initialising SPI in slave mode over DMA?

The SPI initi code generated by cybeMX

static void MX_SPI1_Init(void)
{
  /* SPI1 parameter configuration*/
  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_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
 
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
}

The code to begin the transfer

//read data from file to buffer
fres = f_read(&Log_fil, spi_buff, SPI_BUFF_SIZE, &bytesread);
 
/*
 * Calculate the CRC for the data read from SD card
 * append the CRC to buffer
 */
 
crc=singletable_crc32c(crc, spi_buff, SPI_BUFF_SIZE);
memcpy(&spi_buff[SPI_BUFF_SIZE],&crc,sizeof(uint32_t));
 
// Start the SPi transfer
spi_status=HAL_SPI_Transmit_DMA(&hspi1, (uint8_t*) spi_buff,SPI_BUFF_SIZE+4); 
 

I also briefly toggle a GPIO which lets the Linux side know that new data is available.

Note my spi_buff is a char array of SPI_BUFF_SIZE+4 length. While debugging I can view the contents of spi_buff and see that the 1st character is not repeated for example 0x54, 0x60, 0x20 but it will send 0x54 0x54 0x60 0x20...

I can see the duplicated byte on a logic analyser as well so it's not an issue with receiving on the linux side.

any help would be appreciated thanks.

3 REPLIES 3

Observe the SPI signals, maybe it's duplicated by the master.

JW

I'm currently ignoring anything sent by the master on the data line, the only thing that matters is the clock. Currently 10MHz but I experience the same issue when lowered to 1MHz

LM.2
Associate II

I'm still looking for a reason as to why this is happening.

Interestingly I noticed that it only happens on the 1st transfer after a reboot. I had to reset and reinitiaise the peripheral after each transmission as the BSY flag was not resetting (this is mentioned in the errata sheet). These resets do not result in any duplicated characters.