cancel
Showing results for 
Search instead for 
Did you mean: 

Continuous DMA from memory to SPI

SoCalJim
Associate

We need to continuously DMA a single 16-bit word to the SPI transmitter. (Neither the memory address nor the peripheral address would increment.) Can this be done without intervention? I.e. do we have to use a DMA Complete interrupt to set a flag and call HAL_SPI_Transmit_DMA whenever the flag gets set, or can we configure HAL_SPI_Transmit_DMA to set and forget it?

16 REPLIES 16

Here's the relevant code:

 

MX_SPI2_Init

  hspi2.Instance = SPI2;

  hspi2.Init.Mode = SPI_MODE_MASTER;

  hspi2.Init.Direction = SPI_DIRECTION_2LINES;

  hspi2.Init.DataSize = SPI_DATASIZE_16BIT;

  hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;

  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;

  hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;

  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;

  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

  hspi2.Init.CRCPolynomial = 7;

  hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

  hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

 

HAL_SPI_MspInit

    /**SPI2 GPIO Configuration

    PC1     ------> SPI2_MOSI

    PB10     ------> SPI2_SCK

    PB12     ------> SPI2_NSS

    */

    GPIO_InitStruct.Pin = SPI2_MOSI;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF3_SPI2;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 

    // Remove SPI2_NSS_Pin

    GPIO_InitStruct.Pin = SPI2_CLK|SPI2_NSS;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 

Main

    HAL_StatusTypeDef status = HAL_SPI_Transmit_IT(&hspi2, (uint8_t *)&buf, 1);

 

As a sanity check, I set SPI2_NSS_Pin's mode to GPIO_MODE_OUTPUT_PP. In doing so I found I had to reduce the voltage scale. You can see that the SPI2_NSS is wired properly.

>   hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;

NSSP only works with CPHA=0, so change this to SPI_PHASE_1EDGE.

 

If you feel a post has answered your question, please click "Accept as Solution".

That worked! :) :) Thanks!

Now is there a way to invert that line, or do we have to do that in hardware?

What line do you want to invert? Probably needs to be done in hardware.

If you feel a post has answered your question, please click "Accept as Solution".

NSS

 

I don't think the STM32L4 can change the polarity of NSS internally.

The STM32H7 series (and probably other newer chips) can:

TDK_0-1736380951502.png

 

If you feel a post has answered your question, please click "Accept as Solution".