Skip to main content
Explorer II
April 12, 2022
Question

Question about LL CRS initialization generated by MX (USB L4+ or G4)

  • April 12, 2022
  • 2 replies
  • 983 views

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

    This topic has been closed for replies.

    2 replies

    Graduate II
    April 12, 2022

    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?

    Nikita91Author
    Explorer II
    April 13, 2022

    @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:

    Graduate II
    April 16, 2022

    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)) )