cancel
Showing results for 
Search instead for 
Did you mean: 

SPI in slave mode, auto receive

con3
Senior

Afternoon Everyone,

I'm using an stm32f722ze

I'm not sure if I'm doing something wrong or misunderstanding the working of the SPI (it could be either) but I have it up and running.

I've got a SPI implementation in slave mode with DMA, like this:

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_12BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
  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(__FILE__, __LINE__);
  }
 
}

And the DMA:

   hdma_spi1_rx.Instance = DMA2_Stream0;
    hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
    hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi1_rx.Init.Mode = DMA_NORMAL;
    hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
 
    __HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);

At this point, I'm calling the DMA receive function HAL_SPI_Receive_DMA(...) , although it seems weird that i have to call this whenever I want to receive data from the master. How should I change my implementation so that the SPI receives data automatically when the CS line goes low?

Also, I've noticed that adding a transfer complete callback seems to do nothing:

 hdma_spi1_rx.XferCpltCallback = completespi;

1 ACCEPTED SOLUTION

Accepted Solutions
con3
Senior

So two things happened, for some reason I had it in normal mode, where it should have been in circular. But less obvious to me was that there was coherency issues between data cache. So disabling data cache resolved the issue.

EDIT: If anyone falls into the same pit and receives data but it doesn't appear in the buffer(and you enabled Dcache) see this: https://www.st.com/content/ccc/resource/technical/document/application_note/group0/08/dd/25/9c/4d/83/43/12/DM00272913/files/DM00272913.pdf/jcr:content/translations/en.DM00272913.pdf

View solution in original post

2 REPLIES 2
con3
Senior

I think I messed up the DMA configuration, it was in normal mode, setting to circular and retesting now

con3
Senior

So two things happened, for some reason I had it in normal mode, where it should have been in circular. But less obvious to me was that there was coherency issues between data cache. So disabling data cache resolved the issue.

EDIT: If anyone falls into the same pit and receives data but it doesn't appear in the buffer(and you enabled Dcache) see this: https://www.st.com/content/ccc/resource/technical/document/application_note/group0/08/dd/25/9c/4d/83/43/12/DM00272913/files/DM00272913.pdf/jcr:content/translations/en.DM00272913.pdf