cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 SPI DMA 16 bits. DON'T WORK!

Asantos
Senior
Posted on June 18, 2016 at 20:23

Hi,

change in the ''SPI_FullDuplex_ComDMA'' to work in 16bits mode.

change in the ''stm32l4xx_hal_msp.c'' file:

//**************************************************************

 hdma_tx.Instance                 = SPIx_TX_DMA_CHANNEL;

    hdma_tx.Init.Request             = SPIx_TX_DMA_REQUEST;

    hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;

    hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;

    hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;

    hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; 

    hdma_tx.Init.MemDataAlignment    = DMA_PDATAALIGN_HALFWORD; 

    hdma_tx.Init.Mode                = DMA_NORMAL;

    hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;

    HAL_DMA_Init(&hdma_tx);

    /* Associate the initialized DMA handle to the the SPI handle */

    __HAL_LINKDMA(hspi, hdmatx, hdma_tx);

    /* Configure the DMA handler for Transmission process */

    hdma_rx.Instance                 = SPIx_RX_DMA_CHANNEL;

    hdma_rx.Init.Request             = SPIx_RX_DMA_REQUEST;

    hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;

    hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;

    hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;

    hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; 

    hdma_rx.Init.MemDataAlignment    = DMA_PDATAALIGN_HALFWORD; 

    hdma_rx.Init.Mode                = DMA_NORMAL;

    hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;

    HAL_DMA_Init(&hdma_rx);

//***********************************************************

Change in the main.c file:

//****************************************************************

 SpiHandle.Instance               = SPIx;

  SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;

  SpiHandle.Init.Direction         = SPI_DIRECTION_2LINES;

  SpiHandle.Init.CLKPhase          = SPI_PHASE_1EDGE;

  SpiHandle.Init.CLKPolarity       = SPI_POLARITY_LOW;

  SpiHandle.Init.DataSize          = SPI_DATASIZE_16BIT;

  SpiHandle.Init.FirstBit          = SPI_FIRSTBIT_MSB;

  SpiHandle.Init.TIMode            = SPI_TIMODE_DISABLE;

  SpiHandle.Init.CRCCalculation    = SPI_CRCCALCULATION_DISABLE;

  SpiHandle.Init.CRCPolynomial     = 7;

  SpiHandle.Init.CRCLength         = SPI_CRC_LENGTH_8BIT;

  SpiHandle.Init.NSS               = SPI_NSS_SOFT;

  SpiHandle.Init.NSSPMode          = SPI_NSS_PULSE_DISABLE;

                          

   sTxBuf[0] = 0x54C2; 

  if(HAL_SPI_TransmitReceive_DMA(&SpiHandle, (uint8_t *)&sTxBuf[0], (uint8_t *)aRxBuffer, 1) != HAL_OK)

  {

     Error_Handler();

  }

      

   If the the length field is 1, like above. SPI line transmit 16 bits: 00C2

   If the length is 2, SPI line trasmit 32 bits: 00C20054.

   If I use:

   

   HAL_SPI_Transmit(&SpiHandle, (uint8_t*) &sTxBuf[0], 1,10);

  SPI line transmit correctly: 0x54C2

   

   I tried the same with the STM32F303RE and it transmits correctly in 16 bits using DMA or not.

  Should it be some bug in the STM32L4 hardware?

  

//****************************************************************

6 REPLIES 6
Posted on June 18, 2016 at 21:49

PDATA?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Asantos
Senior
Posted on June 19, 2016 at 00:13

clive1, what is PDATA?

the sTxBuf is 16 bits. 

And I would like to reiterate that the L4 transmits correctly in 16 bits without DMA, and the STM32F303 trasmits correctly with and without DMA, using the same setup.

Ari.

Posted on June 19, 2016 at 02:04

Peripheral Data, you should search your code and review your application of it.

Observation#2

DMA_PDATAALIGN_HALFWORD != DMA_MDATAALIGN_HALFWORD

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Asantos
Senior
Posted on June 20, 2016 at 18:30

Thanks clive1. 

Ari.

Thank you so much, I had the same problem and I was pulling my hair out for over a week! Of course it was a copy-paste mistake :D

What often helps in these cases - as it both breaks the "author's blindness", and also helps to refresh the intimate knowledge of the mcu's internals - is to read out content of related registers and check against description of all individual field in those registers' descriptions in RM.

JW