AnsweredAssumed Answered

STM32CubeF4 - SPI Receiver doesn't work under HAL...

Question asked by Zaher on Mar 14, 2017
Latest reply on Mar 26, 2017 by KIC8462852 EPIC204278916

Hello everyone!

I was forced to move my project to HAL Libs for bunch of reasons beyond the scope of this discussion, and ever since, I ran into problems getting the SPI to work properly. I spent a tremendous time trying to get acquainted with the Std Periph Lib from ST, and I have been able to build several projects under that lib, until that TROUBLESOME HAL thing came out and changed everything, for the worst, in fact! I guess I'm not alone in reporting tons of bugs and issues moving from Std Periph Libs to HAL (Hell Always, not Hardware Abstraction Layer). 

 

Well, getting down to the problem, part of my project is to control a dSPIN device over SPI. I had a working code based on the Std.Periph.Libs and built with the AC6/GCC tools, where everything worked out as expected. I've been able to write and read the registers from the device, however, trying to do the same thing with HAL, keeping all settings for the SPI, RCC, GPIO has failed for no obvious reason. 

 

My problem lies in the receiving part of the SPI. Usually, the master sends a byte and the slave, dSPIN, sends response of 1~3 bytes long, depending on the command received. At the beginning, I noticed that there's no data being received by the master, STM32F429ZIT. The RXNE flag is never set and the program stuck in a while loop waiting for the RXNE flag forever. I tried everything possible, switched to another GPIO/SPI port, changed RCC settings, but all of that did not help in getting the response from the dSPIN/Slave. After almost two weeks of painful work modifying my code dozens of times, I managed to find out that the 2-Line Duplex mode was the reason the RX part did not work, thus the RXNE flag kept cleared. Although the same SPI configurations (2-Line Duplex) did the job very well for the old project that I built with the Std.PeriphLibs under the Eclipse-Based IDE. Now, after changing the SPI configurations from 2-Line to 1-Line, I started to receive data and the RXNE flag is set with each byte received, however, the data received seems to be a garbage and not related to any response from the dSPIN. I found out that others had similar issue with different series of STM32, and Flushing the RX FIFO is all they needed to get the correct data, but I believe the flushing function,RX_FIFO_flush() , is not available for the STM32F4 series. 

 

Below are some snippets from my project source code that had to do with the SPI:

 

/* SPI4 init function */
static void MX_SPI4_Init(void)
{

hspi4.Instance = SPI4;
hspi4.Init.Mode = SPI_MODE_MASTER;
hspi4.Init.Direction = SPI_DIRECTION_1LINE;
hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
hspi4.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi4.Init.NSS = SPI_NSS_SOFT;
hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi4.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi4) != HAL_OK)
{
Error_Handler();
}

}

 

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI4)
{
/* USER CODE BEGIN SPI4_MspInit 0 */

/* USER CODE END SPI4_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI4_CLK_ENABLE();

/**SPI4 GPIO Configuration
PE2 ------> SPI4_SCK
PE5 ------> SPI4_MISO
PE6 ------> SPI4_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6;
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_SPI4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

/* USER CODE BEGIN SPI4_MspInit 1 */

/* USER CODE END SPI4_MspInit 1 */
}

}

 

And here's my write function that write/reads a byte over SPI to/from a dSPIN slave:

 

/**
* @brief Transmits/Receives one byte to/from dSPIN over SPI.
* @param Transmited byte
* @retval Received byte
*/
uint8_t dSPIN_Write_Byte(uint8_t byte)
{
uint8_t Shifting_Byte = 0x00;
uint8_t Rx_Buffer[12] = 0;
uint8_t receivedbyte = 0;
uint8_t *Rx_Ptr;

/* nSS signal activation - low */
HAL_GPIO_WritePin(dSPIN_CS_GPIO_Port, dSPIN_CS_Pin, GPIO_PIN_RESET);
/* SPI byte send */
//HAL_Delay(10); /** Allow some time for CS **/

HAL_SPI_Transmit(&hspi4, (uint8_t*) &byte, 1, 100);
//HAL_SPI_TransmitReceive(&hspi4, (uint8_t*)&byte, Rx_Buffer, 1, 100);
/* Wait for SPIx Busy flag */
while(__HAL_SPI_GET_FLAG(&hspi4, SPI_FLAG_BSY) != RESET);
/* nSS signal deactivation - high */
HAL_GPIO_WritePin(dSPIN_CS_GPIO_Port, dSPIN_CS_Pin, GPIO_PIN_SET);

//HAL_SPI_Receive(&hspi4, &Rx_Buffer[0], 1, 100); /* Version 1 */

//HAL_SPI_Receive(&hspi4, (uint8_t*)&Resp, 1, 100); /* Version 2 */
//HAL_SPI_TransmitReceive(&hspi4, (uint8_t*)&Shifting_Byte,(uint8_t*) &receivedbyte, 1, 100); /* Version 3 */
HAL_SPI_Transmit(&hspi4, (uint8_t*) &Shifting_Byte, 2, 100);
//HAL_SPI_Receive(&hspi4, &receivedbyte, 1, 100 ); /* Version 4 */
//HAL_SPI_Receive(&hspi4, Rx_Ptr, 1, 100 ); /* Version 5 */
HAL_SPI_Receive(&hspi4, &Rx_Buffer[0], 1, 100 ); /* Version 6 */

/* Wait for SPIx Busy flag */
while(__HAL_SPI_GET_FLAG(&hspi4, SPI_FLAG_RXNE) != RESET);



//return Rx_Buffer[0];
//return (uint8_t)receivedbyte;
//return (uint8_t)*Rx_Ptr;
return Rx_Buffer[0];


}

 

As you can see above, I tried it in multitude of ways, but still can't get the correct response from the dSPIN. 

 

Hope someone has the solution for this! 

 

Regards,

 

 

Zaher

Outcomes