2022-04-12 08:49 AM
Cube MX generate the following code:
LL_CRS_SetSyncDivider(LL_CRS_SYNC_DIV_1);
LL_CRS_SetSyncPolarity(LL_CRS_SYNC_POLARITY_RISING);
LL_CRS_SetSyncSignalSource(LL_CRS_SYNC_SOURCE_USB);
LL_CRS_SetReloadCounter(__LL_CRS_CALC_CALCULATE_RELOADVALUE(48000000,1000));
LL_CRS_SetFreqErrorLimit(34);
LL_CRS_SetHSI48SmoothTrimming(64);
In this code the CRS clock is not initialized and the CRS is not enabled. I can't find these actions elsewhere in the code.
If HAL is used, the CRS clock is started and the CRS is enabled
So I use this code
LL_APB1_GRP1_EnableClock (LL_APB1_GRP1_PERIPH_CRS) ;
LL_CRS_SetSyncDivider(LL_CRS_SYNC_DIV_1);
LL_CRS_SetSyncPolarity(LL_CRS_SYNC_POLARITY_RISING);
LL_CRS_SetSyncSignalSource(LL_CRS_SYNC_SOURCE_USB);
LL_CRS_SetReloadCounter(__LL_CRS_CALC_CALCULATE_RELOADVALUE(48000000,1000));
LL_CRS_SetFreqErrorLimit(34);
LL_CRS_SetHSI48SmoothTrimming(64);
LL_CRS_EnableAutoTrimming () ;
LL_CRS_EnableFreqErrorCounter () ;
Is this what CubeMX should generate?
Tested with G431 and L4R5
2022-04-12 03:37 PM
That bloatware initializes things that doesn't need it, because those are the default values anyway, and takes 30+ instructions. And here is a normal code with 3 instructions:
CRS->CR |= CRS_CR_AUTOTRIMEN | CRS_CR_CEN;
Or even better... 2 instructions:
CRS->CR = _VAL2FLD(CRS_CR_TRIM, 64) | CRS_CR_AUTOTRIMEN | CRS_CR_CEN;
In what alternate reality is a CubeMX generated code and endless fighting with it's stupidities better, faster or easier in any way than just writing a simple single line of code?
2022-04-13 02:56 AM
@Piranha This is not the code I am using but the one generated by MX. My code is much more compact.
In this MX generated code it seems to me that essential settings are missing, and therefore that the CRS does not work. I added LL statements only to be consistent with the generated code.
I did not know _VAL2FLD and I thank you for this elegant trick:thumbs_up:
2022-04-16 03:08 PM
I hope you saw the _FLD2VAL() also. In addition I can share some related macros from my own collection:
#define REG_MOD_FIELD(rReg, xFld, xVal) ( (rReg) = ((uint32_t)(rReg) & ~xFld##_Msk) | (((uint32_t)(xVal) << xFld##_Pos) & xFld##_Msk) )
#define REG_MOD_BITS(rReg, fClr, fSet, iPos) ( (rReg) = ((uint32_t)(rReg) & ~((uint32_t)(fClr) << (iPos))) | ((uint32_t)(fSet) << (iPos)) )