LPTIMER & LPUART support?
Moderators: RoccoMarco, barthess
-
- Posts: 276
- Joined: Mon Sep 24, 2012 3:52 pm
- Location: Donetsk
- Been thanked: 32 times
- Contact:
LPTIMER & LPUART support?
Are any plans to make support for LowPower TIMER and Low Power Uart for STM32L0xx devices ?
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: LPTIMER & LPUART support?
Hi,
Yes but it is not high priority. LPTIM would be probably used by the ST/GPT drivers, LPUART by the serial driver.
Giovanni
Yes but it is not high priority. LPTIM would be probably used by the ST/GPT drivers, LPUART by the serial driver.
Giovanni
-
- Posts: 276
- Joined: Mon Sep 24, 2012 3:52 pm
- Location: Donetsk
- Been thanked: 32 times
- Contact:
Re: LPTIMER & LPUART support?
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.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: LPTIMER & LPUART support?
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
Giovanni
-
- Posts: 276
- Joined: Mon Sep 24, 2012 3:52 pm
- Location: Donetsk
- Been thanked: 32 times
- Contact:
Re: LPTIMER & LPUART support?
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
Also to choose the LPTIM it is necessary to include this settings in mcuconf.h file
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.
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:
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 210 times
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: LPTIMER & LPUART support?
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
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
-
- Posts: 276
- Joined: Mon Sep 24, 2012 3:52 pm
- Location: Donetsk
- Been thanked: 32 times
- Contact:
Re: LPTIMER & LPUART support?
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.
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.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: LPTIMER & LPUART support?
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
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
-
- Posts: 276
- Joined: Mon Sep 24, 2012 3:52 pm
- Location: Donetsk
- Been thanked: 32 times
- Contact:
Re: LPTIMER & LPUART support?
Simple test program give bad results of my implementation:
result:
For variant with critical section helps simple test in reading:
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.
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.
-
- Posts: 276
- Joined: Mon Sep 24, 2012 3:52 pm
- Location: Donetsk
- Been thanked: 32 times
- Contact:
Re: LPTIMER & LPUART support?
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?
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;
}
Who is online
Users browsing this forum: No registered users and 38 guests