STM32 RS485 Communication does not work as expected - stm32

I have a weight cell which replies to specific frames over RS485 (cell contains its own communication protocol). Manufacturer has a software to test the cell so I connect it to my pc using a RS485 to USB converter and I am able to connect to the cell and send/receive frames. Here are the parameters I use and you can see TX-RX frames below:
Now I want to manage this protocol with a STM32 board but I am not receiving frames properly. I am using NUCLEO-F401RE and RS485 CAN Shield from Waveshare (https://www.waveshare.com/wiki/RS485_CAN_Shield). Here is what I do and my UART configuration:
Main program
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
MX_USART1_UART_Init();
MX_USART2_UART_Init();
printf("NUCLEOF401RE - RS485 RX\r\n");
while (1)
{
// Activate sending status
HAL_GPIO_WritePin (GPIOA, GPIO_PIN_8, 1);
txBuffer[0] = 0x44; // SOF
txBuffer[1] = 0x01; // DIR
txBuffer[2] = 0x00; // ERR
txBuffer[3] = 0x25; // CMD
txBuffer[4] = 0x00; // DATOS0
txBuffer[5] = 0x00; // DATOS1
txBuffer[6] = 0x00; // DATOS2
txBuffer[7] = 0x00; // DATOS3
txBuffer[8] = txBuffer[1] ^ txBuffer[2] ^ txBuffer[3] ^ txBuffer[4] ^ txBuffer[5] ^ txBuffer[6] ^ txBuffer[7]; // CRC
txBuffer[9] = 0x0A; // EOF
printf("TX - Sending frame\r\n");
HAL_UART_Transmit(&UART_RS485, txBuffer, framelength, 1000);
// Activate receiving status
HAL_GPIO_WritePin (GPIOA, GPIO_PIN_8, 0);
HAL_UART_Receive(&UART_RS485, rxBuffer, framelength, 1000);
printf("RX - Reception Completed:\r\n");
for(int j=0; j<framelength; j++)
{
printf("Byte %d: %02X\r\n", j, rxBuffer[j]);
}
HAL_Delay(3000);
}
UART Configuration
static void MX_USART1_UART_Init(void)
{
UART_RS485.Instance = USART1;
UART_RS485.Init.BaudRate = 115200;
UART_RS485.Init.WordLength = UART_WORDLENGTH_8B;
UART_RS485.Init.StopBits = UART_STOPBITS_1;
UART_RS485.Init.Parity = UART_PARITY_NONE;
UART_RS485.Init.Mode = UART_MODE_TX_RX;
UART_RS485.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UART_RS485.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UART_RS485) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1)
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
I should be receiving a frame starting with 0x44 and ending with 0x0A based on the cell protocol. However, this is what I receive:
I have tried many different UART parameters, many different pin configurations and tried using a 120 ohm and 220 ohm resistors between A and B lines but nothing works.
What am I missing?

I suggest you to see: Uart Status Register of you STM32 uc (because you could see UART errors like parity error, frame error and buffer overflow). In my work UART errors very often were related to buffer overflow because uc usually have a very small buffer (for ATmega 32 - 2 bytes).
Also i suggest you to use mode with parity bit, because it a data check in any case.
Also have you calculate you UART error (depends on you clock frequency and UART speed). You also could select UART speed with 0 % of errors.
You could see article about status register and baud rate here: http://www.micromouseonline.com/2009/12/31/stm32-usart-basics/

Related

Transmitting 255 bytes of data using stm32 i2c dma lower level driver example

I am currently using STM32L0538 Discovery board. In my project i have to use lower level drivers to interface i2c with slave device (ST25DV) using DMA.
I ported LL example to STM32L0538 DISCO board by referring the LL example project available for NUCLEO-L073RZ in the firmware repo (STM32Cube_FW_L0_V1.12.1).
The issue with example is i am only able to transmit 4-bytes of data (slave addr. + 3bytes of 8bit data), afterwards i2c generates stop condition although the number of data to be transmitted is more than 4 bytes both in DMA and I2C register. I think the issue is with DMA, as it accepts uint32_t type source memory addr. but my data is of uint8_t type. I have tried typecasting as shown in the demo LL example but it doesn't work.
**Can anyone please tell me how can i transmit more than just 4bytes of data or where i am going wrong. ** Thanks in advance.
Here is the sample code ported from STM32L0 Firmware repo which only send 4 bytes of data:
uint8_t aLedOn[5] = {0x12,0x34,0x56,0x77,88};
__IO uint8_t ubNbDataToTransmit = sizeof(aLedOn);
uint8_t* pTransmitBuffer = (uint8_t*)aLedOn;
__IO uint8_t ubTransferComplete = 0;
#define SLAVE_OWN_ADDRESS 0xAE
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
/* Configure the system clock */
SystemClock_Config();
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
Configure_DMA();
Configure_I2C_Master();
LL_mDelay(1000);
Handle_I2C_Master();
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
}
void Configure_DMA(void)
{
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0);
NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);
LL_DMA_ConfigTransfer(DMA1, LL_DMA_CHANNEL_4, LL_DMA_DIRECTION_MEMORY_TO_PERIPH | \
LL_DMA_PRIORITY_HIGH | \
LL_DMA_MODE_NORMAL | \
LL_DMA_PERIPH_NOINCREMENT | \
LL_DMA_MEMORY_INCREMENT | \
LL_DMA_PDATAALIGN_BYTE | \
LL_DMA_MDATAALIGN_BYTE);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_4, ubNbDataToTransmit);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_4, (uint32_t)pTransmitBuffer, (uint32_t)LL_I2C_DMA_GetRegAddr(I2C2, LL_I2C_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4));
LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_4, LL_DMA_REQUEST_7);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_4);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_4);
}
void Configure_I2C_Master(void)
{
LL_I2C_InitTypeDef I2C_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Enable the peripheral clock of GPIOC */
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_14;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2);
LL_I2C_SetTiming(I2C2, 0x00100E16);
LL_I2C_SetOwnAddress1(I2C2, 0x00, LL_I2C_OWNADDRESS1_7BIT);
LL_I2C_DisableOwnAddress1(I2C2);
LL_I2C_EnableClockStretching(I2C2);
LL_I2C_SetDigitalFilter(I2C2, 0x00);
LL_I2C_EnableAnalogFilter(I2C2);
LL_I2C_EnableGeneralCall(I2C2);
LL_I2C_SetOwnAddress2(I2C2, 0x00, LL_I2C_OWNADDRESS2_NOMASK);
LL_I2C_DisableOwnAddress2(I2C2);
LL_I2C_SetMasterAddressingMode(I2C2, LL_I2C_ADDRESSING_MODE_7BIT);
LL_I2C_SetMode(I2C2, LL_I2C_MODE_I2C);
// (4) Enable DMA transmission requests a
LL_I2C_EnableDMAReq_TX(I2C2);
LL_I2C_Enable(I2C2);
}
void Handle_I2C_Master(void)
{
ubTransferComplete = 0;
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);
LL_I2C_HandleTransfer(I2C2, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubNbDataToTransmit, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
/* Loop until DMA transfer complete event */
while(!ubTransferComplete)
{
}
/* Loop until STOP flag is raised */
while(!LL_I2C_IsActiveFlag_STOP(I2C2))
{
}
LL_I2C_ClearFlag_STOP(I2C2);
}

Regarding STM32 interrupts -The Interrupt triggering for Switch-2, when the Switch-2 is in idle while operating with Switch-1:

I am using STM32L072CZ microcontroller for my development purpose.
I am integrating STM32L072CZ with LoRa communication for our project. I wrote the application layer on the base firmware of LoRa LSN50-V2(node with integrated STM32 and Lora chip)
In that I configure the 2 interrupt pins in both rising and falling edge.
I configure the pin In such way which i mentioned below, and also i am using macros for the pins, pin's clock and pin's port
pin Initialization and Configuration and Deinitialization
void mainInit( void )
{
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_MAIN_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_MAIN_PIN;
GPIO_InitStruct.Mode =GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
HW_GPIO_Init( GPIO_MAIN_PORT, GPIO_MAIN_PIN, &GPIO_InitStruct );
/* Enable and set EXTI lines 4 to 15 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
void dgInit( void )
{
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_DG_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_DG_PIN;
GPIO_InitStruct.Mode =GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
HW_GPIO_Init( GPIO_DG_PORT, GPIO_DG_PIN, &GPIO_InitStruct );
/* Enable and set EXTI lines 4 to 15 Interrupt to the lowest priority */
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
void mainIoDeInit( void )
{
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Mode =GPIO_MODE_IT_RISING_FALLING;
HW_GPIO_Init( GPIO_MAIN_PORT, GPIO_MAIN_PIN, &GPIO_InitStruct );
}
void dgIoDeInit( void )
{
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Mode =GPIO_MODE_IT_RISING_FALLING;
HW_GPIO_Init( GPIO_DG_PORT, GPIO_DG_PIN, &GPIO_InitStruct );
}
/* IRQ handler functionality*/
//HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_14 );
if (joined_flags==1)
{
if(__HAL_GPIO_EXTI_GET_IT(GPIO_DG_PIN)!=RESET)
{
HAL_Delay(30);
mainStreamer=0;
dgStreamer=1;
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_DG_PIN);
HAL_GPIO_EXTI_IRQHandler(GPIO_DG_PIN);
}
//HAL_GPIO_EXTI_IRQHandler( GPIO_PIN_15 );
if(__HAL_GPIO_EXTI_GET_IT(GPIO_MAIN_PIN)!=RESET)
{
HAL_Delay(30);
mainStreamer=1;
dgStreamer=0;
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_MAIN_PIN);
HAL_GPIO_EXTI_IRQHandler(GPIO_MAIN_PIN);
}
}
I used PB14 and PB15 as a interrupt pin.
PB14-Switch-1
PB15-Switch-2
Most of the times the interrupt with proper switch status is updated. But sometimes there was a issue.
The issue is when the Switch-2 is in idle state, i am controlling the Switch 1 alone, in that sometimes i observed that the Switch-2 interrupt ISR happens instead of Switch 1 ISR.
what is the reason for that?

Uart doesn't work after waking up from stop mode in stm32f4

I am using STOP mode to save power and also deinitialize GPIO to achieve maximum power saving. In this case current consumption goes below 1mA. I am using UART Rx pin as external interrupt to wake up board from STOP mode. The board does wake up but UART or other peripheral like DCMI doesn't work. Following is my code.
void MX_GPIO_Deinit()
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
}
void stopMode(void)
{
HAL_SuspendTick();
MX_GPIO_Deinit();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
void resumeStopMode(void)
{
SystemClock_Config();
HAL_ResumeTick();
MX_GPIO_Init();
HAL_UART_MspInit(&huart4);
HAL_I2C_MspInit(&hi2c2);
HAL_DCMI_MspInit(&hdma_dcmi);
HAL_TIM_MspPostInit(&htim1);
MX_DMA_Init();
MX_UART4_Init();
MX_I2C2_Init();
MX_DCMI_Init();
MX_TIM1_Init();
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
int getChar()
{
uint8_t InputData = 0;
TimmingDelay = 50000;
while (TimmingDelay !=0)
{
if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_ORE))
__HAL_UART_CLEAR_OREFLAG(&huart4);
if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_RXNE))
{
InputData = huart4.Instance->DR & 0x1FF;
return InputData;
}
}
return -1;
}
void main(void)
{
stopMode()
resumeStopMode() /* woken up by uart interrupt*/
int receivedByte = 0;
receivedByte = getChar() /* This line doesn't work after waking it goes into stop mode */
}
Since I deinitialize all GPIO I am not able to to debug. How can I make UART work properly after waking up from STOP mode.
There is a wake-up latency associated with STOP mode to allow the HSI RC oscillator to wake up and potentially flash and the internal regulator. If the first byte is corrupt then it is most likely that it is a result of this latency.
This is my solution.
HAL_UART_MspInit(&huart4);
__HAL_UART_DISABLE(&huart4);
__HAL_UART_ENABLE(&huart4);
but following do not work.
HAL_UART_Init(&huart4);
I ran into almost this exact same issue and here was my solution (keep in mind I'm using UART2):
HAL_UART_MspInit(&huart2);
MX_USART2_UART_Init();
The reason that just calling the normal MX_USART2_UART_Init() function doesn't work is because the UART peripheral has state and wont re-initialize clocks if its state doesn't think it needs to:
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c
308 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
309 {
.
.
.
327 if (huart->gState == HAL_UART_STATE_RESET)
328 {
.
.
.
343 /* Init the low level hardware : GPIO, CLOCK */
344 HAL_UART_MspInit(huart);

STM32 MBED stop mode - timer not working after wakeup

I'm using MBED on STM32F437 MCU (my own target) and trying to properly reach STOP mode. This MCU doesn't have LPTIM (low power timer) so I'm trying to configure RTC (or WKUP pin PA0) to wakeup MCU a few seconds after STOP. So far so good. But there is problem after wakeup. MCU is running, serial printf is working, but MBED Ticker and Timer are not running as expected. Here's the deal - Ticker doesn't call attached interrupt and Timer probably overflows after wakeup.
// mcu start
Timer t;
t.start();
Thread::wait(10000); // sleep is enabled 10 seconds after MCU is powered ON
-> t = 10002
// wakeup timer for 10 seconds configured
// stop mode enabled
// this happens after wakeup
-> t = 4294783
-> t = 4295784
-> t = 4296785
-> t = 4297786
-> t = 4298787
For wakeup i'm using this library
https://os.mbed.com/users/Sissors/code/WakeUp/
And in Stop routine, there is code like
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Allow access to Backup */
HAL_PWR_EnableBkUpAccess();
/* Disable all used wakeup sources: Pin1(PA.0) */
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
/* Clear all related wakeup flags */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
/* Re-enable all used wakeup sources: Pin1(PA.0) */
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
/* FLASH Deep Power Down Mode enabled */
HAL_PWREx_EnableFlashPowerDown();
/* Enter Stop Mode */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
/* Configures system clock after wake-up from STOP: enable HSE, PLL and select
PLL as system clock source (HSE and PLL are disabled in STOP mode) */
SetSysClock();
and this is how my clock init (SetSysClock) looks like. It's called both after MCU start and MCU wakeup.
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
// Enable HSE oscillator and activate PLL with HSE as source
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
if (bypass == 0) {
RCC_OscInitStruct.HSEState = RCC_HSE_ON; // External 8 MHz xtal on OSC_IN/OSC_OUT
} else {
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // External 8 MHz clock on OSC_IN
}
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
#if (CLOCK_SOURCE_USB)
RCC_OscInitStruct.PLL.PLLN = 336;
#else
RCC_OscInitStruct.PLL.PLLN = 336;
#endif
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // 180 MHz or 168 MHz if CLOCK_SOURCE_USB defined
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
return 0; // FAIL
}
// Activate the OverDrive to reach the 180 MHz Frequency
if (HAL_PWREx_EnableOverDrive() != HAL_OK) {
return 0; // FAIL
}
// Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 180 or 168 MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // 45 or 42 MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // 90 or 84 MHz
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
return 0; // FAIL
}
// HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_3);
return 1;
}
#endif

CAN RX interrupt freezing on STM32

I have a problem that my RX interrupt callback doesn't trigger after some time of running state (sometimes 30 seconds, sometimes 10 minutes...), and I don't know any more where to look for the failure.
I am using a CANopen stack from Emtas, but this stack doesn't enable nor disable interrupts according to fa. Emtas, and I am also not using IT disables. The CPU doesn't freeze; it runs in the loop even after the RX freeze.
INFO: CPU-STM32f429, EMTAS CANOpen, Atollic lite, HAL libraries.
Code flow:
while(1){
CanOpenTask();
SPI1communicatin(); // Polled
CanOpenTask();
SPI3communicatin(); // Polled
CanOpenTask();
SPI6communicatin(); // Polled
}
CAN settings:
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(CAN1_TX_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 6;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_12TQ;
hcan1.Init.BS2 = CAN_BS2_2TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
Where/how do I search for the reason of this problem?