mirror of https://github.com/ARMmbed/mbed-os.git
Calculate FDCAN_clk instead of assuming fix 10MHz
- The FDCAN_clk is calculated on runtime from the according RCC-registerspull/13565/head
parent
f32efe4c28
commit
08ce2f2de8
|
@ -57,6 +57,62 @@ int can_internal_init(can_t *obj)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Calculate the fdcan-core-clk value for accurate calculation of the quantum timing
|
||||||
|
*
|
||||||
|
* !Attention Not all bitrates can be covered with all fdcan-core-clk values. When a clk
|
||||||
|
* does not work for the desired bitrate, change system_clock settings for PLLQ
|
||||||
|
*
|
||||||
|
* !Attention For now, PCLK is not supported (PLLQ is selected always anyways)
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* core_frequency when successful
|
||||||
|
* -1 when error / not supported
|
||||||
|
*/
|
||||||
|
static int _can_get_core_frequency( void )
|
||||||
|
{
|
||||||
|
int clk_sel = (RCC->CCIPR & RCC_CCIPR_FDCANSEL_Msk) >> RCC_CCIPR_FDCANSEL_Pos;
|
||||||
|
|
||||||
|
switch (clk_sel){
|
||||||
|
case 0: //! HSE clock selected as FDCAN clock
|
||||||
|
{
|
||||||
|
return HSE_VALUE;
|
||||||
|
}
|
||||||
|
case 1: //! PLL "Q" clock selected as FDCAN clock
|
||||||
|
{
|
||||||
|
int pll_source_clk;
|
||||||
|
|
||||||
|
int pll_source = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC_Msk);
|
||||||
|
if (pll_source == RCC_PLLCFGR_PLLSRC_HSE){
|
||||||
|
pll_source_clk = HSE_VALUE;
|
||||||
|
} else if (pll_source == RCC_PLLCFGR_PLLSRC_HSI){
|
||||||
|
pll_source_clk = HSI_VALUE;
|
||||||
|
} else {
|
||||||
|
MBED_ERROR(
|
||||||
|
MBED_MAKE_ERROR(MBED_MODULE_DRIVER_CAN, MBED_ERROR_CODE_CONFIG_UNSUPPORTED),
|
||||||
|
"PLL source must be HSI or HSE");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM_Msk) >> RCC_PLLCFGR_PLLM_Pos) + 1;
|
||||||
|
int plln = (RCC->PLLCFGR & RCC_PLLCFGR_PLLN_Msk) >> RCC_PLLCFGR_PLLN_Pos;
|
||||||
|
int pllq = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ_Msk) >> RCC_PLLCFGR_PLLQ_Pos) + 1;
|
||||||
|
pllq = pllq * 2;
|
||||||
|
int fdcan_freq = ((pll_source_clk / pllm) * plln) / pllq;
|
||||||
|
|
||||||
|
return fdcan_freq;
|
||||||
|
}
|
||||||
|
case 2: //! PCLK Clk selected as FDCAN clock
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
MBED_ERROR(
|
||||||
|
MBED_MAKE_ERROR(MBED_MODULE_DRIVER_CAN, MBED_ERROR_CODE_CONFIG_UNSUPPORTED),
|
||||||
|
"Wrong clk_source configuration");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if STATIC_PINMAP_READY
|
#if STATIC_PINMAP_READY
|
||||||
#define CAN_INIT_FREQ_DIRECT can_init_freq_direct
|
#define CAN_INIT_FREQ_DIRECT can_init_freq_direct
|
||||||
void can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz)
|
void can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz)
|
||||||
|
@ -123,7 +179,8 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz
|
||||||
Phase_segment_2 | 30 tq | <nts2> = <n_tq> - 1 - <nts1>
|
Phase_segment_2 | 30 tq | <nts2> = <n_tq> - 1 - <nts1>
|
||||||
Synchronization_Jump_width | 30 tq | <nsjw> = <nts2>
|
Synchronization_Jump_width | 30 tq | <nsjw> = <nts2>
|
||||||
*/
|
*/
|
||||||
int ntq = 10000000 / hz;
|
|
||||||
|
int ntq = _can_get_core_frequency() / hz;
|
||||||
|
|
||||||
obj->CanHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
|
obj->CanHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
|
||||||
obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL;
|
obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL;
|
||||||
|
@ -254,7 +311,7 @@ int can_frequency(can_t *obj, int f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See can_init_freq function for calculation details */
|
/* See can_init_freq function for calculation details */
|
||||||
int ntq = 10000000 / f;
|
int ntq = _can_get_core_frequency() / f;
|
||||||
obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1
|
obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1
|
||||||
obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2
|
obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2
|
||||||
obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width
|
obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width
|
||||||
|
|
Loading…
Reference in New Issue