µTasker Forum

µTasker Forum => µTasker general => Topic started by: Raffaele on October 15, 2020, 09:31:12 PM

Title: UART, SPI and PWM in low power modes
Post by: Raffaele on October 15, 2020, 09:31:12 PM
Hi,
I'm writing a task for the KL03 that generates a PWM and sometimes uses SPI master and UART. I need it to be as low power as possible.

1)
According to the KL manual* (page 84) in VLPS, UART and TPM can work as far as their clock sources are enabled (table pg 81). How do I enable them in utasker?

2) I want to use the function fnSetLowPowerMode but for it to be functional, the task    {"lowPower",  fnLowPower,   NO_QUEUE,  0, 0, UTASKER_GO} in taskConfig.c has to be enabled. Does it make sense?

3)
I'm using the function fnSetLowPowerMode(VLPS_MODE); to enter VLPS mode, but when I do it UART stops working, probably because of question (1). SPI also stops working but that's expected because SPI master works up to VLPW at 500kbps (table pg 84) correct?

4)
Is it possible to switch from VLPS_MODE to VLPW_MODE, for example, when I need to use the spi, and then back to VLPS?


* https://www.nxp.com/docs/en/reference-manual/KL03P24M48SF0RM.pdf
Title: Re: UART, SPI and PWM in low power modes
Post by: mark on October 17, 2020, 02:19:11 AM
Hi

There is no 'standard' method to achieving best power performance since it depends on specific requirements and what can be accepted by the application. This means that the designer (developer) needs to identify the possibilities and make compromises where and when necessary. These in return are also quite chip dependent, meaning that the designer needs to know details of the specific chip being used in some detail.

1. In VLPS the UART and TPM don't operate since their clock sources are stopped. However this doesn't mean that the are dead - they in fact are marked with "Async operation" which means that they can still react to (asynchronous) input changes that can wake the processor from the VLPS mode.
I made a report about using UARTs in VLPS here https://community.nxp.com/message/421247#421247 which explains that UART reception can wake the processor in order that it can sleep until needed to handle such incoming data. However it also explains that since clocks were stopped and it may take a certain amount of time for the processor to restart and clocks to be stabilise it tends to be limited to slower speeds. The exact details depend on which clock source is being used, whether PLLs are involved (which take longer to lock and stabilise) and thus requires decisions/compromises based on what can be tolerated.

2. It is the low power task that is controlling the move to the low power mode and so it is enabled when SUPPORT_LOW_POWER is set. fnSetLowPowerMode() doesn't enter the mode but instead it informs that it would like to enter the mode as soon as possible. It is then the low power task that decides when it if finally safe to make the change - this ensures that the processor doesn't sleep when there is still anther task needing to run and also when a peripheral is in the process of doing something that would be corrupted by the change (like a UART transmission byte being frozen half way through and so corrupting the output). The task also controls re-entry into the state after the processor is woken and thus if WAIT mode of operation is set the low power task ensures that the processor sleeps in the WAIT mode whenever possible and sets it back there automatically after each wake-up event.

3. In VLPS mode I actually expect the UART to wake on any Rx data edge. However, as explained in link in 1), it depends on its clocks being able to wake fast enough to allow the UART itself to correctly recognise the reception. Is is probable that it can't handle data rates of more that a few kBaud and, since it moves back to the VLPS mode afterwards (unless a new mode is commanded when it is woken) it looks to not work - maybe it echoes random data if the UART can't wake fast enough to synchronise to the incoming data.

4. It should be possible to switch between all modes (each with its own pros and cons) but once a certain low power mode is entered the processor will need to be woken again (via a certain event) before the code can command it to the next mode. VLPW state is a little more complicated because before being able to switch various system clock first need to be reduced in speed so that the mode can actually work - more likely it is used in systems instead of WAIT mode when the normal operating speeds can already be generally set to respect the limits (like generally running the system clock at max. 4MHz and the bus clock at max. 1MHz).
To ensure lower power consumption generally it is a good idea to try to reduce all clock rates to the lowest possible in RUN mode - if the application can be achieved at 1MHz system clock it may be better to use this instead of 48MHz to start with (although using WAIT mode may mean that the general RUN (with automatic WAIT mode whenever possible) may already optimise to give reasonable current savings at full speed).

Regards

Mark
Title: Re: UART, SPI and PWM in low power modes
Post by: Raffaele on October 17, 2020, 04:53:25 PM
Thank you so much Mark,
I'm going through your answer and testing.
As for the UART I was trying to send instead of receiving, that's probably why I couldn't make it work? I will try to rx and see what happens.

Besides all the functionalities (UART, SPI etc), at the moment I'm having trouble to actually enter a low power stop or low leakage state as my current consumption is always around 0.9mA or higher. It's like I'm always in WAIT mode.
I tried to run from HIRC or from LIRC with these configs

Code: [Select]
//#define RUN_FROM_HIRC                                                // clock from internal 48MHz RC clock
  #define RUN_FROM_LIRC                                                // clock from internal 8MHz/2MHz RC clock
    #if defined RUN_FROM_HIRC
        #define SYSTEM_CLOCK_DIVIDE  16                                   // 1..16
        #define BUS_CLOCK_DIVIDE     4                                   // 1..8 (valid for bus/flash and divisor is after the system clock divider)
    #elif defined RUN_FROM_LIRC
        #define RUN_FROM_LIRC_2M                                         // selet 2MHz rather than 8MHz
        #define SLOW_CLOCK_DIVIDE    2                                   // optionally divide the slow clock output (1, 2, 4, 8, 16, 32, 64 or 128)
        #define SYSTEM_CLOCK_DIVIDE  8                                   // 1..16
        #define BUS_CLOCK_DIVIDE     2                                   // 1..8 (valid for bus/flash and divisor is after the system clock divider)

Plus, I have
#define SUPPORT_LOW_POWER
#define SUPPORT_PORT_INTERRUPTS
(I will need it for LLWU)

{"lowPower",  fnLowPower,   NO_QUEUE,  0, 0, UTASKER_GO} is activated in taskConfig.c

As soon as I enter my TASK I run fnSetLowPowerMode(RUN_MODE) or WAIT_MODE, or VLPR_MODE (and it works), but after that all other modes like VLPS_MODE, VLLS0_MODE, I think are entered because I see the current decreasing, but it's no lower than 0.9mA.

Is there any other settings/define or wrong clock I am missing?

Title: Re: UART, SPI and PWM in low power modes
Post by: mark on October 18, 2020, 12:27:30 PM
Hi

You should be able to get into the uA consumption range in some low leakage modes - see also this video: https://www.youtube.com/watch?v=kWNlsAoMly4

Be careful to power cycle the board once before trying new low power firmware since there are some registers that are retained though warm resets and may block some modes if not reset with a power cycle.

Don't use the debugger when testing since it can interfere and consume additional power.

Finally, make sure that you have no inputs left in a floating state because these can oscillate and cause quite high current consumption even when the core itself is consuming only nA. A good test is to move to the low power mode and touch all pins on the processor - if the consumption changes depending on which pins are touched there are some that are floating and causing unnecessary consumption. If the consumption is stable it means the pins have defined, stable states, which is how they should be.

Regards

Mark
Title: Re: UART, SPI and PWM in low power modes
Post by: Raffaele on October 20, 2020, 02:59:18 AM
I'm getting there. My current consumption is high probably due to how the KL03 is connected to other stuff. From VLPS down to VLLSx's I always have the same current (0.66uA). I'll try with a fresh board and see if I can get the same current values discussed in this thread: https://www.utasker.com/forum/index.php?topic=1908.0

Meanwhile I have a couple of questions.

Q1)
In STOP/VLPS modes the MCG-Lite is static and the LIRC can be optionally enabled. In fact, I see that in STOP/VLPS, the PWM doesn't work (while it works in VLPW, VLPR etc). The KL03 manual says: "To enable LIRC in Stop mode, write 1b to MCG_C1[IREFSTEN] and MCG_C1[IRCLKEN] before entering Stop mode". How can I enable this behavior in uTasker? Is it implemented or do I have to write in those registers every time before entering VLPS?

Q2)
Since I'm trying to save power, I was wondering what are the other possibilities to generate the PWM and if the LPTMR might be useful in my scenario.
My scenario is this: I want to generate a sequence of pulses that is on all the time, and asynchronous UART or SPI from time to time (slow data rates in the order of kHz are acceptable). Furthermore, my PWM has a relatively low frequency and very low duty cycle. It is a 130Hz signal with about 30us pulses (so the highest source frequency needed for the pulses is 30-34kHz). If there is a solution to Q1 I can do this with LIRC in VLPS.
Alternatively, another strategy could be, keeping LIRC static and generating the pulses differently. Something like a periodic "wakeup" that about every 130ms generates a 30us pulse which might also save more power since the duty cycle is low? Or maybe there is another clock that I can use in VLLSx modes, in which case I could generate an LLWU interrupt and restart when I need to use SPI (https://www.utasker.com/kinetis/LLWU.html)
Title: Re: UART, SPI and PWM in low power modes
Post by: mark on October 20, 2020, 10:21:02 AM
Hi

Q1) Search for where the MCG_C1 is being configured in the code: this will depend on which clock source is being used for the main clock.
For example if using the HIRC (48MHz) it will be configured with
MCG_C1 = MCG_C1_CLKS_HIRC;                                           // select HIRC clock source
whereby if using LIRC with
MCG_C1 = (MCG_C1_IREFSTEN | MCG_C1_IRCLKEN | MCG_C1_CLKS_INTERN_CLK);// enable and select 4MHz IRC clock source and allow it to continue operating in STOP mode

It may also be set when configuring the TPM when not running the main clock from LIRC and the TPM is configured to be clocked for MCGIRCK.

After these configurations it won't be accessed any more so if you find that the  IREFSTEN is not set you can set it and that should ensure that it will always run in stop mode; it will not be necessary to do it each time the stop mode is entered.

Q2) The LPTMR allows the processor to be woken from a low leakage state with a resolution of about 1ms so it would be possible to set an output low and sleep for 130ms, wake up and set it high and wait 30us before setting low and sleeping again.
The 30us pulse could be generated by a HW timer and the processor sleep/wait.
This would probably give very low power during the 130ms and then a spike when the 30us pulse is generated - the overage consumption would still be fairly low as long as the spike is not too high.

You will need to see whether 1 or 2 gives best low power in actual operation.

Regards

Mark