Skip to main content
Arrhenius
Associate III
March 15, 2022
Question

FDCAN_CCCR.Init bit is not getting cleared STM32H723ZG

  • March 15, 2022
  • 7 replies
  • 2496 views

Hi,

I am trying to initialize FDCAN for my project.

After the initialization I am clearing INIT bit in CCCR Register. The output what I can see is only CCE bit gets cleared but INIT bit is stuck at 1.

Below is my code snippet.

void Can_driver_init (void)

{

uint32_t StartAddress_l_u32 = CAN_RAM_OFFSET_CFG;

uint32_t RAMcounter_l_u32  = 0;

uint32_t ElementSize_l_u32 = (CAN_DATA_BYTES_CFG/4);

// Enable the peripheral clock for FDCAN

RCC->APB1HENR |= RCC_APB1HENR_FDCANEN;

// Exit from Sleep mode */

CAN->CCCR  &= ~FDCAN_CCCR_CSR;

// Wait till the CSR bit is set in CCCR */

while (CAN->CCCR == FDCAN_CCCR_CSR); // Wait timeout to be added

// Request initialization */

CAN->CCCR  |= FDCAN_CCCR_INIT;

// Wait until the INIT bit in CCCR register is set */

while ((CAN->CCCR & FDCAN_CCCR_INIT) != FDCAN_CCCR_INIT); // Wait timeout to be added

// Enable configuration change */

CAN->CCCR  |= FDCAN_CCCR_CCE;

// Enable automatic retransmission */

CAN->CCCR  &= ~FDCAN_CCCR_DAR;

// Disable transmit pause */

CAN->CCCR  &= ~FDCAN_CCCR_TXP;

// Disable Protocol Exception Handling */

CAN->CCCR  &= ~FDCAN_CCCR_PXHD;

// Set CAN Frame Format as CLASSIC*/

CAN->CCCR  |= CAN_FRAME_CFG;

// Configure CAN Operation Mode as normal */

CAN->CCCR  |= CAN_MODE_CFG;

// Set the nominal bit timing register for CAN Bit-rate*/

CAN->NBTP  = (NBTP_NSJW_VAL_CFG  << FDCAN_NBTP_NSJW_Pos)  |

  (NBTP_NTSEG1_VAL_CFG << FDCAN_NBTP_NTSEG1_Pos) |

  (NBTP_NTSEG2_VAL_CFG << FDCAN_NBTP_NTSEG2_Pos) |

  (NBTP_NBRP_VAL_CFG  << FDCAN_NBTP_NBRP_Pos);

// Configure number of dedicated transmit buffers. */

CAN->TXBC   = (NBR_OF_TXBUFFER_CFG << FDCAN_TXBC_NDTB_Pos);

// Configure Tx buffer element size */

CAN->TXESC  |= (ElementSize_l_u32 << FDCAN_TXESC_TBDS_Pos);//TBD

// Configure Rx buffer element size */

CAN->RXESC  |= (ElementSize_l_u32 << FDCAN_RXESC_RBDS_Pos);

//--------------------------------------------------------------------

//--------------------------------------------------------------------

 // Message RAM configuration:

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

 //      ________

 //   0x00 |________| Standard_filter[0]

 //     |________|

 //     |________|

 //      |||||||||| Rx_buffer[0]

 //      ||||||||||

 //      |||||||||| Rx_buffer[n]

 //      |________| Tx_buffer[0]

 //      |________|

 //      |________| Tx_buffer[n]

 //      ||||||||||

 //      ||||||||||

 //      |||||||||| FreeSpace

 //      ||||||||||

 //      ||||||||||

 //  @2560 ||||||||||

// Calculate each RAM block address

// -------------------------------

//  Block 0: Standard Filters

// -------------------------------

// Standard filter list start address

CAN->SIDFC  |= (StartAddress_l_u32 << FDCAN_SIDFC_FLSSA_Pos);

// Number of standard filter elements

CAN->SIDFC  |= (NBR_OF_STD_FILTERS << FDCAN_SIDFC_LSS_Pos);

StartAddress_l_u32 += NBR_OF_STD_FILTERS;

// -------------------------------

//  Block 1: Dedicated Rx Buffers

// -------------------------------

// Rx buffer list start address */

CAN->RXBC  |= (StartAddress_l_u32 << FDCAN_RXBC_RBSA_Pos);

StartAddress_l_u32 += (NBR_OF_RXBUFFER_CFG * CAN_DATA_BYTES_CFG);

// Note: No register field is defined for declaring

// number of dedicated Rx buffers in STM32H7

// -------------------------------

//  Block 2: Dedicated Tx Buffers

// --------------------------------

// Tx buffer list start address */

CAN->TXBC  |= (StartAddress_l_u32 <<FDCAN_TXBC_TBSA_Pos);

// Number of dedicated Tx buffers */

CAN->TXBC  |= (NBR_OF_TXBUFFER_CFG << FDCAN_TXBC_NDTB_Pos);

//--------------------------------

//--------------------------------

// Store the Addresses of different fields of CAN Message RAM

MsgRam.StandardFilterSA = SRAMCAN_BASE;

MsgRam.RxBufferSA    = MsgRam.StandardFilterSA + (NBR_OF_STD_FILTERS * 4);

MsgRam.TxBufferSA    = MsgRam.RxBufferSA + (NBR_OF_RXBUFFER_CFG * (CAN_DATA_BYTES_CFG * 4));

MsgRam.EndAddress    = MsgRam.TxBufferSA + (NBR_OF_TXBUFFER_CFG * (CAN_DATA_BYTES_CFG * 4));

  // Flush the allocated Message RAM area

for (RAMcounter_l_u32 = MsgRam.StandardFilterSA; RAMcounter_l_u32 < MsgRam.EndAddress; RAMcounter_l_u32 += 4U)

{

*(uint32_t *)(RAMcounter_l_u32) = 0x00000000;

}

/*--------------------------------------------------------------------

 *--------------------------------------------------------------------*/

// Configure filter elements

CanIf_filterInit();

// Enable the interrupts

Can_driver_enableInterrupts();

  // Request leave initialization

CAN->CCCR  &= ~FDCAN_CCCR_INIT;

}

7 replies

BHend.2
Visitor II
January 19, 2023

I am having the same issue with the INIT bit not clearing - did this get resolved?

KJona.2
Associate
February 20, 2023

Hi,

Any updates?

I am having the same issue but on STM32G431KBT6. I am using arm non eabi toolchain, assembly and cmsis copied from cube project + cmake.

I observed that the ARA bit is set just after enabling fdcan in rcc. The code to reproduce the issue:

 RCC->APB1ENR1 |= RCC_APB1ENR1_FDCANEN;  

 FDCAN1->CCCR |= FDCAN_CCCR_INIT;

//here the ARA bit =1

while ((FDCAN1->CCCR & FDCAN_CCCR_INIT) != FDCAN_CCCR_INIT); 

That happens only when using cmake to build target. I created a new empty project in STM32 cube IDE and added mentioned lines:

void main()

{

 RCC->APB1ENR1 |= RCC_APB1ENR1_FDCANEN;  

 FDCAN1->CCCR |= FDCAN_CCCR_INIT;

//here the ARA bit =1

while ((FDCAN1->CCCR & FDCAN_CCCR_INIT) != FDCAN_CCCR_INIT); 

}

The issue did not occur. I must not be doing something that STM32 Cube IDE is. I spent a lot of time trying to debug this issue...

Any ideas?

I found that somebody have the same issue:

STM32H743 FDCAN stuck in init mode - General Discussion - PlatformIO Community

Visitor II
July 26, 2023

Hello community

A little up for this subject because I have the same problem...

Does someone has any idea?

PPopo.1
Senior
July 25, 2024

Same issue with STM32H7S7L8H6H

Associate
June 10, 2026

I found the root cause in my case, and it is likely related to similar STM32 FDCAN/M_CAN controllers.

The FDCAN register block was readable and the basic register checks looked fine, but CCCR.INIT still did not clear.

The problem was the FDCAN kernel clock frequency. My original fdcan_ker_ck was about 74 MHz, which was too low. After reconfiguring the clock setup so that fdcan_ker_ck was above 80 MHz, the controller was able to leave INIT mode correctly.

I documented the investigation here:

https://github.com/Burkhardt-Braun/stm32mp1-fdcan-init-explanation

So my recommendation is: before looking too deeply into GPIO configuration, transceiver hardware, bit timing, or message RAM layout, verify the actual FDCAN kernel clock frequency.

Good luck,

Burkhardt Braun
 

Associate
August 12, 2026

I have now also runned into to this issue with a stm32u585vit6.

INIT bit is never cleared.

I have tried to change the freq without success. Tried to increase it, and also decrease it.

I have tried internal loop-back mode.

I have tried to disconnect the CAN-tranciver.

I check the ARA bit, but that bit is not set.

Any idea?

I can’t find anything related to this in errata.

 

 

Associate
August 12, 2026

One thing to be careful about: the bus clock and the FDCAN kernel clock are two different things.

Make sure you are actually checking the FDCAN kernel clock, and make sure its frequency is at least as high as required by the specification for your controller.

In my STM32MP1 case, this distinction between kernclock and bus-clock was the key to finding the problem.

Good luck
Burkhardt Braun