Two STM32F103C8´s connected by SPI. Master is sending data=3 as test, Slave STM received the data, HAL_SPI_RxCpltCallback is fire, but HAL_SPI_ErrorCallback is fire too, HAL_SPI_GetError=4 (overload)
Hi all.
I am trying to connect 2 STM32F103C8 (blue pill board).
I run a test using just ONE STM32 using SPI1 as Master and SPI2 as Slave, all configurations were working fine (FullDuplex, Master Transmite. receive only Slave....every test was fine (allways using TX and RX with interruption), this test was performed in order to check if conifiguration is ok....
as all test were ok y decide to interconnect 2 STMs and I have an issue in Slave STM:
Master SPI sent only one data (3), in Slave STM HAL_SPI_RxCpltCallback is fire, so I can see the Data received (3), it is save into an array, but HAL_SPI_ErrorCallback is fire too if Master send more than one word (16 bist).
Data from Master is ok, please check the figure below:
Here is Slave configuration:
#include "main.h"
volatile uint16_t SPI_Datos_RX[5000];
volatile uint8_t SPI_NumElementos=1;
volatile uint8_t SPI_RX_Data_Available=0;
volatile uint16_t SPI_INDEX_RXED=0;
volatile uint16_t SPI_DATA_RXed;
volatile uint16_t INT_TMP=0;
SPI_HandleTypeDef hspi2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
void Pasivar_SPI_SS()
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, 1);
}
void Activar_SPI_SS()
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, 0);
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
SPI_Datos_RX[SPI_INDEX_RXED]=SPI_DATA_RXed;
SPI_INDEX_RXED++;
HAL_SPI_Receive_IT(&hspi2, &SPI_DATA_RXed, SPI_NumElementos);
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
int a;
a=HAL_SPI_GetError(&hspi2);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI2_Init();
HAL_SPI_MspInit(&hspi2);
__HAL_SPI_ENABLE(&hspi2);
HAL_SPI_Receive_IT(&hspi2, &SPI_DATA_RXed, SPI_NumElementos);
while (1)
{
for (int a=0; a<1000;a++);
if ((SPI_Datos_RX[INT_TMP]!=0) & (SPI_INDEX_RXED!=0) & (INT_TMP!=0) & (SPI_INDEX_RXED>=4999) )
{
SPI_INDEX_RXED=0;
INT_TMP=0;
}
INT_TMP++;
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
static void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_SLAVE;
hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
hspi2.Init.DataSize = SPI_DATASIZE_16BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_INPUT;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
}
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */
this is SPI2 Register:
at this point, HAL_SPI_Receive_IT(&hspi2, &SPI_DATA_RXed, SPI_NumElementos);
was executed, Slave SPI Board is waiting for data from master side.
and this is the register when data from master arrived.
After the HAL_SPI_RxCpltCallback was fire and data was saved, as I am suing debuging tool I can see that HardFault_Handler is called......in stm32f1xx_it.c file.
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
int a;
a=HAL_SPI_GetError(&hspi2);
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
when HAL_SPI_GetError is used, ti got 0 value, as there isn´t any error...but for some reason HardFault_Handlerwas called.....
this is SPI2 configuration from CubeIDE:

In few words: Slave recibe SPI data, 16 bits, after move the data to an array, HardFault_Handler is called, after that if Master send data again, Slave can handle (HAL_SPI_RxCpltCallback is not fire any more)
I need your help, any commment/advice is welcome.
br
Alfredo