cancel
Showing results for 
Search instead for 
Did you mean: 

FDCAN->CKDIV vs FDCAN_CONFIG->CKDIV

Uwe Bonnes
Principal III

rm0456 describes CKDIV belonging to the FDCAN register structure, However the actual header in the cmsis_device_u5 repo make it a member of the FDCAN_Config_TypeDef. This is missleading!

 

Probably FDCAN_Config_TypeDef. is some structure found in the MCAN IP. There is no description of FDCAN_Config in the reference manual. A description is welcome,

7 REPLIES 7
Andrew Neil
Super User

@Uwe Bonnes wrote:

rm0456 describes CKDIV belonging to the FDCAN register structure, However the actual header in the cmsis_device_u5 repo make it a member of the FDCAN_Config_TypeDef. This is missleading!,


Is it?

The RM calls it "FDCAN CFG Clock Divider" - so FDCAN_Config_TypeDef doesn't seem an unreasonable name?

AndrewNeil_0-1762438490346.png

https://www.st.com/resource/en/reference_manual/rm0456-stm32u5-series-armbased-32bit-mcus-stmicroelectronics.pdf#page=3082

 


@Uwe Bonnes wrote:

Probably FDCAN_Config_TypeDef. is some structure found in the MCAN IP. ,


Use your IDE's 'Go To Definition' feature to find it.

 


@Uwe Bonnes wrote:

There is no description of FDCAN_Config in the reference manual. 


Well, the RM describes the hardware - not the software.

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

From 70.4.37, it could be expected that FDCAN1 -> CKDIV resolves against the device header. But it does not resolve:

...

#include <stm32u355xx.h>

...

FDCAN1 -> CKDIV = 0xa;

> arm-none_eabi_gcc ...

/devel/stm32u5_fdcan/lv2_splitter_u535/../fdcan.c:378:12: error: 'FDCAN_GlobalTypeDef' has no member named 'CKDIV'
378 | FDCAN1 -> CKDIV = 0xa; //divide by 20
       |                ^~

 

mƎALLEm
ST Employee

Hello,

I didn't find any definition called FDCAN_Config_TypeDef in the HAL.

Referring to the HAL implementation (HAL_FDCAN_Init()/stm32u5xx_hal_fdcan.c), this is what I can see:

  /* Configure Clock divider */
  FDCAN_CONFIG->CKDIV = hfdcan->Init.ClockDivider;

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
mƎALLEm
ST Employee

Ok I found it in stm32u385xx.h (nothing called stm32u355xx.h:(

typedef struct
{
  __IO uint32_t CKDIV;            /*!< FDCAN clock divider register,                            Address offset: 0x100 + 0x000 */
       uint32_t RESERVED1[128];   /*!< Reserved,                                                0x100 + 0x004 - 0x100 + 0x200 */
  __IO uint32_t OPTR;             /*!< FDCAN option register,                                   Address offset: 0x100 + 0x204 */
       uint32_t RESERVED2[58];    /*!< Reserved,                                                0x100 + 0x208 - 0x100 + 0x2EC */
  __IO uint32_t HWCFG;            /*!< FDCAN hardware configuration register,                   Address offset: 0x100 + 0x2F0 */
  __IO uint32_t VERR;             /*!< FDCAN IP version register,                               Address offset: 0x100 + 0x2F4 */
  __IO uint32_t IPIDR;            /*!< FDCAN IP ID register,                                    Address offset: 0x100 + 0x2F8 */
  __IO uint32_t SIDR;             /*!< FDCAN size ID register,                                  Address offset: 0x100 + 0x2FC */
} FDCAN_Config_TypeDef;

and:

#define FDCAN_CONFIG_BASE_NS (APB1PERIPH_BASE_NS + 0x0000A500UL)
#define FDCAN_CONFIG FDCAN_CONFIG_NS
#define FDCAN_CONFIG_NS ((FDCAN_Config_TypeDef *) FDCAN_CONFIG_BASE_NS)

PS sometimes you are speaking about STM32U3 sometimes STM32U5 .. need to keep talking about one device.

And in HAL_FDCAN_Init():

  /* Configure Clock divider */
  FDCAN_CONFIG->CKDIV = hfdcan->Init.ClockDivider;

So I didn't understand what is the issue?

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

Sorry for the typo. I mean <stm32u535xx.h>. U3 is not covered by rm0456.

Issue is that RM0456 talks about  FDCAN_DIV that is not defined in the device header To set the divisor FDCAN_CONFIG is needed, but this structure is not covered by rm0456. Device header and Reference manual should be in sync.


@Uwe Bonnes wrote:

Issue is that RM0456 talks about  FDCAN_DIV 


No, it talks about FDCAN_CKDIV:

AndrewNeil_1-1762451105453.png

 


@Uwe Bonnes wrote:

that is not defined in the device header 


CKDIV is in the header:

typedef struct
{
  __IO uint32_t CKDIV;  /*!< FDCAN clock divider register,                            Address offset: 0x100 + 0x000 */

 and the Address offset matches

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

Yes, CKDIV is in the headers but for the FDCAN_CONFIG register set. But the reference manual describes if for the FDCAN register set. 

  __IO uint32_t TXEFS;        /*!< FDCAN Tx Event FIFO Status register,                             Address offset: 0x0E4 */
  __IO uint32_t TXEFA;        /*!< FDCAN Tx Event FIFO Acknowledge register,                        Address offset: 0x0E8 */
} FDCAN_GlobalTypeDef;

/**
  * @brief FD Controller Area Network Configuration
  */
typedef struct
{
  __IO uint32_t CKDIV;        /*!< FDCAN clock divider register,                            Address offset: 0x100 + 0x000 */
       uint32_t RESERVED1[128];/*!< Reserved,                                               0x100 + 0x004 - 0x100 + 0x200 */
  __IO uint32_t OPTR;         /*!< FDCAN option register,                                   Address offset: 0x100 + 0x204 */
       uint32_t RESERVED2[58];/*!< Reserved,                                                0x100 + 0x208 - 0x100 + 0x2EC */
  __IO uint32_t HWCFG;        /*!< FDCAN hardware configuration register,                   Address offset: 0x100 + 0x2F0 */
  __IO uint32_t VERR;         /*!< FDCAN IP version register,                               Address offset: 0x100 + 0x2F4 */
  __IO uint32_t IPIDR;        /*!< FDCAN IP ID register,                                    Address offset: 0x100 + 0x2F8 */
  __IO uint32_t SIDR;         /*!< FDCAN size ID register,                                  Address offset: 0x100 + 0x2FC */
} FDCAN_Config_TypeDef;

 Either it is offset 0x100 of FDCAN_GlobalTypeDef or offset 0 of FDCAN_Config_TypeDef.