2396105_en-US

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

2396105_en-US

2396105_en-US

CAN-FD maximum baud rate on KW47 and MCXW72

The clock tolerance for CAN FD at high baud rates is generally considered to be tight compared to lower baud rates, meaning that the clock frequency needs to be very precise to ensure reliable communication; this is due to the high data rate requiring precise bit timing.

CAN generally requires crystal or PLL clock source due to accuracy requirements, on KW45/7 that is limited to 32 MHz crystal (SOSC) since there is no PLL available.

However, the FRO192 (FIRC) can be fine trimmed to the SOSC crystal as reference, in a closed loop configuration. When operating in closed loop the FRO192 accuracy is +/-0.25%. The FRO192 when operating in open loop (default) will not be accurate enough for CAN-FD (+/-3%).

Closed loop operation is enabled while SCG0→FIRCCSR[FIRCTRUP] = 1 and SCG0→FIRCCSR[FIRCTREN] =1. The auto trim continues as long as those bits are set (for example if change in temperature causes the FRO192clock frequency to drift). Once locked, only the fine trim bits would be updated on subsequent corrections.

Refer to code snippet below for correct clock configuration:

#include "clock_config.h"
#include "fsl_clock.h"

const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN =
{
    .freq = 32000000U,                            /* System Oscillator frequency: 32000000Hz */
    .monitorMode = kSCG_SysOscMonitorDisable,     /* System OSC Clock Monitor is disabled */
    .enableMode = kSCG_SoscEnable,                /* System OSC Enable */
};

const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN =
{
    .divSlow = (uint32_t)kSCG_SysClkDivBy4,       /* Slow Clock Divider: divided by 4 */
    .divBus = (uint32_t)kSCG_SysClkDivBy1,        /* Bus Clock Divider: divided by 1 */
    .divCore = (uint32_t)kSCG_SysClkDivBy1,       /* Core Clock Divider: divided by 1 */
    .src=(uint32_t)kSCG_SysClkSrcFirc,          /* Fast IRC is selected as System Clock Source */
};

static const scg_firc_trim_config_t FircTrimConfig_BOARD_BootClockRUN =
{
    .trimMode = kSCG_FircTrimUpdate,              /* FIRC trim is enabled and trim value update is enabled */
    .trimsrc=kSCG_FircTrimSrcSysOsc,            /* Trim source is System OSC */
    .trimDiv = 31U,                               /* Divided by 32 */
    .trimCoar = 0U,                               /* Trim value, see Reference Manual for more information */
    .trimFine = 0U,                               /* Trim value, see Reference Manual for more information */
};

const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN =
{
    .enableMode = kSCG_FircEnable,                /* Fast IRC is enabled */
    .range = kSCG_FircRange96M,                   /* 96 Mhz FIRC clock selected */
    .trimConfig = &FircTrimConfig_BOARD_BootClockRUN,
};

/* Unlock FIRC and SOSC control status registers */
CLOCK_UnlockFircControlStatusReg();
CLOCK_UnlockSysOscControlStatusReg();

/* Init FIRC */
CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN);
/* Set SCG to FIRC mode */
CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN);
/* Wait for clock source switch finished */
do
{
    CLOCK_GetCurSysClkConfig(&curConfig);
} while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src);
/* Initializes SOSC according to board configuration */
(void)CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN);
/* Set the XTAL0 frequency based on board settings */
CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq);

/* For 6 mbps baud rate requires FRO192M as FlexCAN source clock */
CLOCK_SetIpSrc(kCLOCK_Can0, kCLOCK_IpSrcFro192M);
CLOCK_SetIpSrcDiv(kCLOCK_Can0, kSCG_SysClkDivBy1);

The maximum supported baud rate for KW47 and MCXW72 devices is 6 Mbps. Although higher rates may be achievable on some SoCs, 6 Mbps is the highest baud rate supported by the device clock specifications. 

For simplicity, the FlexCAN driver APIs can be used to configure the CAN FD baud rate, as shown in the following code snippet:
#include "fsl_flexcan.h"

#define EXAMPLE_CAN           CAN0
#define USE_CANFD             (1)
#define RX_MESSAGE_BUFFER_NUM (0)
#define TX_MESSAGE_BUFFER_NUM (1)
#define BYTES_IN_MB kFLEXCAN_64BperMB

/* For 6 Mbps use case. FRO192 must be selected as clock source */
#define EXAMPLE_CAN_CLK_FREQ       CLOCK_GetFreq(kCLOCK_ScgFircClk)
#define USE_IMPROVED_TIMING_CONFIG (1)

flexcan_config_t flexcanConfig;

/* Get FlexCAN module default Configuration. */
/*
* flexcanConfig.clksrc=kFLEXCAN_ClkSrc0;
* flexcanConfig.bitRate                = 1000000U;
* flexcanConfig.bitRateFD              = 2000000U;
* flexcanConfig.maxMbNum               = 16;
* flexcanConfig.enableLoopBack         = false;
* flexcanConfig.enableSelfWakeup       = false;
* flexcanConfig.enableIndividMask      = false;
* flexcanConfig.disableSelfReception   = false;
* flexcanConfig.enableListenOnlyMode   = false;
* flexcanConfig.enableDoze             = false;
*/
FLEXCAN_GetDefaultConfig(&flexcanConfig);
/* Manually override default CAN FD config to 1 Mbps for nominal rate and 6 Mbps for data rate */
flexcanConfig.bitRate               = 1000000U;
flexcanConfig.bitRateFD             = 6000000U;

#if (defined(USE_IMPROVED_TIMING_CONFIG) && USE_IMPROVED_TIMING_CONFIG)
flexcan_timing_config_t timing_config;
memset(&timing_config, 0, sizeof(flexcan_timing_config_t));

if (FLEXCAN_FDCalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate, flexcanConfig.bitRateFD, EXAMPLE_CAN_CLK_FREQ, &timing_config))
{
   /* Update the improved timing configuration*/
   memcpy(&(flexcanConfig.timingConfig), &timing_config, sizeof(flexcan_timing_config_t));
}
#endif

FLEXCAN_FDInit(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ, BYTES_IN_MB, true);


标记 (1)
无评分
版本历史
最后更新:
星期四
更新人: