Skip to main content
gerardo
Associate III
February 13, 2015
Question

IWDG with LSI on STM32L0

  • February 13, 2015
  • 4 replies
  • 920 views
Posted on February 13, 2015 at 09:55

Hi all,

I´m trying to implement a Independent Watchdog functionality on my STM32L0.

In HAL description pdf I´ve read the following sentence that give me some doubts on me:

STM32L0xx devices provide the capability to measure the

LSI frequency (LSI clock connected internally to TIM5 CH4 input capture). The measured

value can be used to have an IWDG timeout with an acceptable accuracy.

1.- Has anyone the code example to do that?

2.- Can I use the LSI clock only to IWDG while I am using the HSE with my application?

Best regards
    This topic has been closed for replies.

    4 replies

    Tomáš Juřena
    Senior
    December 16, 2016
    Posted on December 16, 2016 at 17:32

    Hi,

    a sample code you can find in ST examples (ex. STM32Cube_FW_F0_V1.7.0/Projects/STM32F042K6-Nucleo/Examples/IWDG/IWDG_Reset/). Basically, you need to configure the timer as input capture, then measure two rising edges and compute the frequency. In the example is it nicely shown. I use Cube generator for the basic code structure so here is generated output:

    tim.c

    void MX_TIM21_Init(void)
    {
     TIM_MasterConfigTypeDef sMasterConfig;
     TIM_IC_InitTypeDef sConfigIC;
     htimInstance = TIM21;
     htimInit.Prescaler = 0;
     htimInit.CounterMode = TIM_COUNTERMODE_UP;
     htimInit.Period = 65535;
     htimInit.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     if (HAL_TIM_IC_Init(&htim21) != HAL_OK)
     {
     Error_Handler();
     }
     sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
     if (HAL_TIMEx_MasterConfigSynchronization(&htim21, &sMasterConfig) != HAL_OK)
     {
     Error_Handler();
     }
     sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
     sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
     sConfigIC.ICPrescaler = TIM_ICPSC_DIV8;
     sConfigIC.ICFilter = 0;
     if (HAL_TIM_IC_ConfigChannel(&htim21, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
     {
     Error_Handler();
     }
     if (HAL_TIMEx_RemapConfig(&htim21, TIM21_TI1_MCO) != HAL_OK)
     {
     Error_Handler();
     }
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    The interrupt is in msp file.

    Computation is done in TIM_IC_CaptureCallback like this

    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    {
     uint32_t lsiperiod = 0;
     /* Get the Input Capture value */
     tmpCC4[uwCaptureNumber++] = HAL_TIM_ReadCapturedValue(&Input_Handle, TIM_CHANNEL_1);
     if (uwCaptureNumber >= 2)
     {
     /* Compute the period length */
     lsiperiod = (uint16_t)(0xFFFF - tmpCC4[0] + tmpCC4[1] + 1);
     /* Frequency computation */ 
     uwLsiFreq = (uint32_t) SystemCoreClock / lsiperiod;
     uwLsiFreq *= 8;
     }
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    Required variables for computation are defined as

    uint16_t tmpCC4[2] = {0, 0};
    __IO uint32_t uwLsiFreq = 0;
    __IO uint32_t uwCaptureNumber = 0;�?�?�?

    And finally start the timer to measure the frequency

    HAL_TIM_IC_Start_IT(&Input_Handle, TIM_CHANNEL_1);
    while(uwCaptureNumber < 2);
    HAL_TIM_IC_Stop_IT(&Input_Handle, TIM_CHANNEL_1);�?�?�?

    Tesla DeLorean
    Guru
    December 20, 2016
    Posted on December 20, 2016 at 16:26

    Just a math tip here, but you can get better precision like this

    uint16_t lsiperiod; // 16-bit

    /* Compute the period length */

    lsiperiod = tmpCC4[1] - tmpCC4[0]; // math wraps itself

    /* Frequency computation */

    uwLsiFreq = (SystemCoreClock * 8) / (uint32_t)lsiperiod;
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Jaroslav BECKA
    ST Employee
    December 20, 2016
    Posted on December 20, 2016 at 16:09

    Hi,

    the LSI is the only clock source option for the IWDG, because it has to be independent on the core frequency and its source. Thus it will be working even if the main clock fails. With HSE and timer combination you will measure the LSI frequency very precisely.

    Tesla DeLorean
    Guru
    December 20, 2016
    Posted on December 20, 2016 at 16:29

    With HSE and timer combination you will measure the LSI frequency very precisely.

    Agreed, however I seen several ST examples where doing the *8 at the end results in the loss of 3-bits of precision. They'll always be zeros.

    For example this SPL code, the multiplication ideally needs to occur before the division when working with integers, though you should watch the scale of the source clock. This is an example where the use of doubles might be more appropriate.

    STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Project\STM32F4xx_StdPeriph_Examples\RTC\RTC_LSI\main.c

     /* Get PCLK1 prescaler */
     if ((RCC->CFGR & RCC_CFGR_PPRE1) == 0)
     {
     /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */
     return ((RCC_ClockFreq.PCLK1_Frequency / uwPeriodValue) * 8);
     }
     else
     { /* PCLK1 prescaler different from 1 => TIMCLK = 2 * PCLK1 */
     return (((2 * RCC_ClockFreq.PCLK1_Frequency) / uwPeriodValue) * 8) ;
     }�?�?�?�?�?�?�?�?�?�?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..