Skip to main content
con3
Senior
Aug 13, 2018 11:46 AM UTC
Solved

SPI in slave mode, auto receive

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;

This topic has been closed for replies.
con3
con3Best answer
Senior
Aug 17, 2018 7:10 AM UTC

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

2 replies

con3
con3Author
Senior
Aug 13, 2018 12:38 PM UTC

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

con3
con3AuthorBest answer
Senior
Aug 17, 2018 7:10 AM UTC

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