LPTIMER & LPUART support?

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

alexblack
Posts: 251
Joined: Mon Sep 24, 2012 3:52 pm
Location: Donetsk
Been thanked: 29 times
Contact:

LPTIMER & LPUART support?

Postby alexblack » Tue Dec 20, 2016 10:03 am

Are any plans to make support for LowPower TIMER and Low Power Uart for STM32L0xx devices ?

User avatar
Giovanni
Site Admin
Posts: 13125
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 769 times
Been thanked: 653 times
Contact:

Re: LPTIMER & LPUART support?

Postby Giovanni » Tue Dec 20, 2016 10:07 am

Hi,

Yes but it is not high priority. LPTIM would be probably used by the ST/GPT drivers, LPUART by the serial driver.

Giovanni

alexblack
Posts: 251
Joined: Mon Sep 24, 2012 3:52 pm
Location: Donetsk
Been thanked: 29 times
Contact:

Re: LPTIMER & LPUART support?

Postby alexblack » Tue Dec 20, 2016 10:51 am

It is make sense to do all ST as virtual 32 bit timers, because 16 bit give small maximum delays. I made port for EFM32 and made such enhancement - it is enough simple.

User avatar
Giovanni
Site Admin
Posts: 13125
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 769 times
Been thanked: 653 times
Contact:

Re: LPTIMER & LPUART support?

Postby Giovanni » Tue Dec 20, 2016 11:28 am

LPTIM would be useful for ST because it is the only timer that can be clocked by the internal oscillator and is independent from PLL settings, very useful if you want to change CPU frequency dynamically.

Giovanni

alexblack
Posts: 251
Joined: Mon Sep 24, 2012 3:52 pm
Location: Donetsk
Been thanked: 29 times
Contact:

Re: LPTIMER & LPUART support?

Postby alexblack » Wed Aug 09, 2017 12:27 pm

Hi.
I made the LPTIM ST driver and software 32 bit emulation for any 16-bit timers.
I checked it on STM32L051 mcu.
I added extra option in chconf.h file for this mode

Code: Select all

/**
 * @brief   System time counter resolution implementation.
 *          If selected TRUE, then 32 bit software emulation will be used.
 * @note    Perfomance will be less if software mode selected.
 */
#define CH_CFG_ST_SOFT_32BITS               TRUE

Also to choose the LPTIM it is necessary to include this settings in mcuconf.h file

Code: Select all

/*
 * ST driver system settings.
 */
#define STM32_ST_USE_LPTIMER                TRUE
#define STM32_ST_IRQ_PRIORITY               3
#define STM32_ST_USE_TIMER                  1

And I added the corresponding definitions in stm32_registry.h

Because LPTIM hardware in STM is very bad realised it is recomeded to setup high frequency for CH_CFG_ST_FREQUENCY, i.e. LSICLK/2 or LSECLK/2.
The CH_CFG_ST_TIMEDELTA must be at least 6. Recomended is 8.
Also I was forced to step back from the datasheet in the part of the writing to register IER, which can be changed only when the timer is off, and I do it with it turned on - it works.

Code: Select all

/**
 * @brief   System time counter resolution.
 * @note    Allowed values are 16 or 32 bits.
 */
#define CH_CFG_ST_RESOLUTION                32

/**
 * @brief   System time counter resolution implementation.
 *          If selected TRUE, then 32 bit software emulation will be used.
 * @note    Perfomance will be less if software mode selected.
 */
#define CH_CFG_ST_SOFT_32BITS               TRUE

/**
 * @brief   System tick frequency.
 * @details Frequency of the system timer that drives the system ticks. This
 *          setting also defines the system tick time unit.
 */
#define CH_CFG_ST_FREQUENCY                 19000

/**
 * @brief   Time delta constant for the tick-less mode.
 * @note    If this value is zero then the system uses the classic
 *          periodic tick. This value represents the minimum number
 *          of ticks that is safe to specify in a timeout directive.
 *          The value one is not valid, timeouts are rounded up to
 *          this value.
 */
#define CH_CFG_ST_TIMEDELTA                 6

I included patch files for:
\ChibiOS\os\hal\ports\STM32\LLD\TIMv1\hal_st_lld.c
\ChibiOS\os\hal\ports\STM32\LLD\TIMv1\hal_st_lld.h
\ChibiOS\os\hal\ports\STM32\STM32L0xx\stm32_registry.h
The test results are:

Code: Select all

STM32L051xx ultra-low-power MCU, XTAL = 4MHz
RTC CLOCK = 38000Hz
Compiled Aug  9 2017 14:17:15
ChibiOS Version: 4.0.0

*** ChibiOS/RT Test Suite
***
*** Compiled:     Aug  9 2017 - 14:17:08
*** Platform:     STM32L051xx ultra-low-power MCU

----------------------------------------------------------------------------
--- Test Case 1.1 (System integrity functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 1.2 (Critical zones functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 1.3 (Interrupts handling functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 1.4 (System Tick Counter functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.1 (Thread Sleep functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.2 (Ready List functionality, threads priority order)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.3 (Priority change test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.1 (Suspend and Resume functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.1 (Semaphore primitives, no state change)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.2 (Semaphore enqueuing test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.3 (Semaphore timeout test)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.4 (Testing chSemAddCounterI() functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.5 (Testing chSemWaitSignal() functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 4.6 (Testing Binary Semaphores special case)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.1 (Events registration)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.2 (Event Flags dispatching)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.3 (Events Flags wait using chEvtWaitOne())
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.4 (Events Flags wait using chEvtWaitAny())
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.5 (Events Flags wait using chEvtWaitAll())
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.6 (Events Flags wait timeouts)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 5.7 (Broadcasting using chEvtBroadcast())
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.1 (Context Switch performance)
--- Score : 18952 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.2 (Threads performance, full cycle)
--- Score : 893 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.3 (Threads performance, create/exit only)
--- Score : 938 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.4 (Mass reschedule performance)
--- Score : 1574 reschedules/S, 9444 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.5 (Round-Robin voluntary reschedule)
--- Score : 12180 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.6 (Virtual Timers set/reset performance)
--- Score : 6334 timers/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.7 (Semaphores wait/signal performance)
--- Score : 29240 wait+signal/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 6.8 (RAM Footprint)
--- System: 72 bytes
--- Thread: 32 bytes
--- Timer : 20 bytes
--- Semaph: 12 bytes
--- EventS: 4 bytes
--- EventL: 20 bytes
--- Result: SUCCESS
----------------------------------------------------------------------------

Final result: SUCCESS
Attachments
stm32_lptimer_and_soft32bit.zip
(4.68 KiB) Downloaded 68 times

User avatar
Giovanni
Site Admin
Posts: 13125
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 769 times
Been thanked: 653 times
Contact:

Re: LPTIMER & LPUART support?

Postby Giovanni » Wed Aug 09, 2017 1:53 pm

Hi,

32bits emulation sounds interesting but I am worried about potential race conditions. What if reading the counter after an overflow but before the IRQ is serviced? it could happen if done in critical zones.

Giovanni

alexblack
Posts: 251
Joined: Mon Sep 24, 2012 3:52 pm
Location: Donetsk
Been thanked: 29 times
Contact:

Re: LPTIMER & LPUART support?

Postby alexblack » Wed Aug 09, 2017 4:44 pm

Yes, I understood what you about.
Hmmm... I do not know what to do in this situations. Perhaps it is not critical because it is impact only for precision of time delay functions. Also may be it is masked by VirtualTimer implementation because I used such mehanism over 2 years without problems. I need analize this snenario more deeper.
Thank you for your comment.

User avatar
Giovanni
Site Admin
Posts: 13125
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 769 times
Been thanked: 653 times
Contact:

Re: LPTIMER & LPUART support?

Postby Giovanni » Wed Aug 09, 2017 5:25 pm

Yes, hard choices...

Any implementation must ensure that the counter is strictly monotonic except for the transition from 0xFFFF.. to 0.

Anyway, don't worry too much about timers resolution, I am thinking to introduce an chThdSleepLong(uint64_t/uint32_t usec) in some next version, slicing will be performed into the function using repeated sleeps so no need to mess with timers.

Giovanni

alexblack
Posts: 251
Joined: Mon Sep 24, 2012 3:52 pm
Location: Donetsk
Been thanked: 29 times
Contact:

Re: LPTIMER & LPUART support?

Postby alexblack » Wed Aug 09, 2017 5:39 pm

Simple test program give bad results of my implementation:

Code: Select all

  for (;;) {
    uint32_t time = chVTGetSystemTime();
    uint32_t prev;
    uint32_t diff;
    while (true) {
      prev = time;
      time = chVTGetSystemTime();
      diff = time - prev;
      if (diff > 100) {
        break;
      }
    }
    DEBUG_TRACE("Race condition detected!\r\n");
    DEBUG_TRACE("prev = %08X, current = %08X, diff = %08X\r\n", prev, time, diff);
  }

result:

Code: Select all

MAIN: > STM32L051xx ultra-low-power MCU, XTAL = 4MHz
MAIN: > Board version 1.1
MAIN: > RTC CLOCK = 38000Hz
MAIN: > Compiled Aug  9 2017 19:31:57
MAIN: > ChibiOS Version: 4.0.0


MAIN: > Race condition detected!
MAIN: > prev = 0008FFFE, current = 00080000, diff = FFFF0002
MAIN: > Race condition detected!
MAIN: > prev = 000AFFFE, current = 000A0000, diff = FFFF0002

For variant with critical section helps simple test in reading:

Code: Select all

/**
 * @brief   Returns the time counter value.
 *
 * @return              The counter value.
 *
 * @notapi
 */
static inline systime_t st_lld_get_counter(void) {

  systime_t cnt = (systime_t)STM32_ST_TIM->CNT;
 
  #if STM32_ST_USE_LPTIMER 
  while (true) {
    systime_t prev_cnt = cnt;
    cnt = (systime_t)STM32_ST_TIM->CNT;
    if (prev_cnt == cnt) {
      break;
    }
  }
  #endif
 
  #if CH_CFG_ST_SOFT_32BITS
  cnt |= (systime_t)ST_TIMER_HCNT << 16U;
  if (STM32_ST_TIM->ISR & LPTIM_ISR_ARRM) {
    cnt += 0x10000;
  }
  #endif
 
  return cnt;
}

But now I understanding that the problem will be with calling this function not in critical section. I will check else.
About future function with long time, I need also timeouts and virtual timers with big ranges.

alexblack
Posts: 251
Joined: Mon Sep 24, 2012 3:52 pm
Location: Donetsk
Been thanked: 29 times
Contact:

Re: LPTIMER & LPUART support?

Postby alexblack » Wed Aug 09, 2017 6:12 pm

I solved both problems (for LPTIM now, later will do for the regular TIMs).
I read counters several times and exit when the results are equal. What do think about this?

Code: Select all

/**
 * @brief   Returns the time counter value.
 *
 * @return              The counter value.
 *
 * @notapi
 */
static inline systime_t st_lld_get_counter(void) {

  systime_t cnt = (systime_t)STM32_ST_TIM->CNT;
  #if CH_CFG_ST_SOFT_32BITS
  cnt |= (systime_t)ST_TIMER_HCNT << 16U;
  if (STM32_ST_TIM->ISR & LPTIM_ISR_ARRM) {
    cnt += 0x10000;
  }
  #endif
 
  #if STM32_ST_USE_LPTIMER
  while (true) {
    systime_t prev_cnt = cnt;
    cnt = (systime_t)STM32_ST_TIM->CNT;
    #if CH_CFG_ST_SOFT_32BITS
    cnt |= (systime_t)ST_TIMER_HCNT << 16U;
    if (STM32_ST_TIM->ISR & LPTIM_ISR_ARRM) {
      cnt += 0x10000;
    }
    #endif
    if (prev_cnt == cnt) {
      break;
    }
  }
  #endif
 
  return cnt;
}


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 7 guests