Skip to main content
cbardou
Associate II
March 24, 2016
Question

LPtimer : modify register on the fly

  • March 24, 2016
  • 6 replies
  • 1379 views
Posted on March 24, 2016 at 16:03

Hi,

I'm using the STM32L4 with the low power timer (LPTIM1).

I'm using it with the LSE clock in counter mode with IT (the counter count until reaching AutoReload value, then it goes into interruption ...).

I'd like to know if the AutoReload register can be modified on the fly ?

I tried to modify it inside the IRQ_handle and it seems to work (I can generate a PWM signal this way).

But when I modify it outside of the IRQ_handle (in my while(1) for example) it doesn't work.

When I stop my program in debug mode, I see AutoReload set to the good value and the counter exceeding AutoReload (instead of going into interruption).

Does anybody know if modifying the register on the fly is doable ?

Thanks
    This topic has been closed for replies.

    6 replies

    waclawek.jan
    Super User
    March 24, 2016
    Posted on March 24, 2016 at 16:57

    > When I stop my program in debug mode, I see AutoReload set to the good value and the counter exceeding AutoReload (instead of going into interruption).

    This is what happens if you set the autoreload value below the current counter value.

    JW
    cbardou
    cbardouAuthor
    Associate II
    March 25, 2016
    Posted on March 25, 2016 at 10:50

    My bad, I forgot to freeze the timer in debug mode and I was watching wrong values.

    But no, I don't set autoreload with a value below counter. Here is a simple program I did to test it :

    int
    main (
    void
    ){
    /* Initialisation and all ... */
    /* My test program */
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, SET);
    timer_start(500); 
    // Start the timer in continuous mode with AutoReload set to 500ms
    if
    (HAL_LPTIM_ReadCounter(&lptim1_handle) <= 0x1333) 
    // Check that counter is not below the future AutoReload value
    {
    timer_change(150); 
    //Modify AutoReload to 150ms
    }
    while
    (1);
    }
    void
    LPTIM1_IRQHandler(
    void
    )
    {
    __HAL_LPTIM_CLEAR_FLAG(&lptim1_handle, LPTIM_FLAG_ARRM);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_10, RESET);
    timer_stop();
    }

    As you can see the program is simple : - I SET PIN10 - Start the timer and modify AutoReload value - I RESET the PIN10 in the irq_handle When I watch PIN10 with an oscilloscope it's being reseted after 200us (instead of 150ms). And of course, it's modifying the AutoReload that causes the problem. If I don't modify it, everything works fine (the PIN is reseted after 500ms). Here is a capture of my timer's registers at 2 differents breakpoint (to me everyting seems fine): - one after the start of the timer - one after modifying AutoReload

    http://www.hostingpics.net/viewer.php?id=197131test.jpg

    cbardou
    cbardouAuthor
    Associate II
    March 25, 2016
    Posted on March 25, 2016 at 11:48

    I found a solution to make it works : stop and re-start the timer :

    HAL_LPTIM_Counter_Stop_IT( .. )

    HAL_LPTIM_Counter_Start_IT(... )

    The counter is reset to 0 and I start all over again, but it seems to work for my application.

    Walid FTITI_O
    Visitor II
    March 25, 2016
    Posted on March 25, 2016 at 12:39

    Hi Klem,

    AS mentionned in the STM32L4x6 reference Manual

    http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00083560.pdf

    :

    in page 1024: chapter LPTIM/ section register update

    “

    The LPTIMx_ARR register and LPTIMx_CMP register are updated immediately after the

    APB bus write operation, or at the end of the current period if the timer is already started.�

    -

             

    So it is allowed to update immediately the ARR value.

    “

    When the PRELOAD bit is reset to ‘0’, the LPTIMx_ARR and the LPTIMx_CMP

    registers are immediately updated after any write access.�

    -

             

    You should ensure that your preload bit is reset to 0

    “

    After a write to the LPTIMx_ARR register or the LPTIMx_CMP register, a new write

    operation to the same register can only be performed when the previous write operation is

    completed. Any successive write before respectively the ARROK flag or the CMPOK flag be

    set, will lead to unpredictable results.�

    -

             

    You should check the ARROk flad is set before any new update

     

     

    -Hannibal -

    cbardou
    cbardouAuthor
    Associate II
    March 25, 2016
    Posted on March 25, 2016 at 18:01

    Hey thanks a lot, it's working.

    Now I check the ARROK flag and reset it after the start of the timer.

    My new AutoReload value is set.

    Walid FTITI_O
    Visitor II
    March 28, 2016
    Posted on March 28, 2016 at 13:23

    Hi Klem,

    It's nice to hear that. Keep up the good work.

    -Hannibal-