cancel
Showing results for 
Search instead for 
Did you mean: 

Explanation/Problem with HAL_SPI_Receive_DMA() for half duplex.

jerman
Associate
Posted on April 21, 2016 at 14:22

IC: STM32F072CBT6

RTOS: FreeRTOSV8.2.1 IDE: Visual Studio 2015 (Visual GDB) ST-Link v 2.0 DMA Settings:

hdma_spi1_rx.Instance = DMA1_Channel2;
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_MEDIUM;
HAL_DMA_Init(&hdma_spi1_rx);
__HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
HAL_DMA_Init(&hdma_spi1_tx);
__HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);

SPI Settings:

hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_1LINE;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
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;
HAL_SPI_Init(&hspi1);

I am attempting to initiate a half duplex communication with an external SPI device. Let me preface by sayingHAL_SPI_Transmit_DMA() works beautifully. I have a problem withHAL_SPI_Receive_DMA(). When attempting to use this function in while SPI1 is configured in

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

theHAL_SPI_Receive_DMA() jumps into theHAL_SPI_TransmitReceive_DMA(). The issue is that the same buffer that is passed into the Receive only function is passed as a parameter into the TransmitReceive function both as the input and the output buffer. The data received in such a way is corrupted as I cannot receive the expected output. IfI use theHAL_SPI_TransmitReceive_DMA() directly for receiving, and if I allocate memory for a separate transmit buffer to be passed (the contents of which I don't care for) - then the data I receive is correct. But I do not like this solution - if for nothing else, because I have limited stack memory and cannot afford to have a large memory space allocated unnecessarily. I have attempted to clear the buffer space using

memset(pBuf, 0x00, len);

before calling the HAL_SPI_Receive_DMA()but this does not seem to have any effect. When SPI1 is configured:

hspi1.Init.Direction = SPI_DIRECTION_1LINE;

then the next line blocks the execution of the program after a receive attempt (DMA remains forever busy):

while
(HAL_DMA_GetState(&hdma_spi1_rx) == HAL_DMA_STATE_BUSY) {}

It is clear to me that I am hitting a brick wall because I seem to misunderstand the SPI peripheral. I have already spent too much time trying to get this to work and I cannot afford to stumble around in the dark.
0 REPLIES 0