Hi all,
We're trying to get low-power mode (specifically VLLS1) working on a K20FX512 part. We're running MQX as the operating system and using many peripherals. We're not attempting to use the MQX LPM driver, as we've written our own power management software. The problem is that we're unable to get the K20 to enter into any of the VLLSx modes.
I've read all of the application notes relating to low-power mode as well as the errata for our part (which has the production mask). The sequence we're following to enter VLLSx is as follows:
Now, what usually happens is that we don't enter stop mode. The STOPA bit of SMC_PMCTRL is set, so something is causing it to abort. I noted that there were a couple of interrupts still firing (FTM1 and SysTick). After disabling those, the micro tries to enter stop mode, but after ~1 second it resets. After the reset, the SACKERR bit of RCM_SRS1 is set.
Unfortunately the documentation gets a bit sparse at this point. It's clear that we're not entering stop mode due to at least one of the peripherals failing to acknowledge the stop request, but it isn't clear which peripherals are polled, and under what conditions they can fail to acknowledge. Has anyone here run into similar problems and if so, are there any tips on how to debug which peripheral is causing this?
For reference, we're using a lot of peripherals on the board (UART, SPI, eSDHC, CAN, GPIO, ADC, FTM). Prior to going into stop mode, our power manager will disable each peripheral, put its pins into a power-saving state (to ensure we don't draw current) and gate off the clock to the peripheral. Could it be this clock gating that is causing the failure to acknowledge the sleep request? Or that we haven't fully or correctly disabled all peripherals?
Thanks in advance for any input,
Dave
Solved! Go to Solution.
Hi Alejandro,
Thanks for your response -- I must have missed it. I decided to forego the LPM driver due to time constraints -- we use a lot of the peripherals on the K20, and most of them don't (yet) have implementations of the LPM interfaces. I went for something of a halfway house, by modifying init/deinit code and the BSP I/O configuration functions to gate off clocks and put pins into safe states. Hopefully if we do this again I'll have more time to put the infrastructure in place for the LPM driver.
I did get to the bottom of the problem in the end. I pared the application right back such that most of the peripherals were never enabled. I was then able to enter sleep VLLS1. I enabled the peripherals one-by-one, and it turned out that it was one of the SPI ports that was failing to acknowledge.
The particular SPI port was no longer required and I think the problem was that the pins were not in an idle state. I made sure the SPI port wasn't being enabled, and that solved the problem.
The next issue was that we have a bootloader which gets entered out of reset. The bootloader relocates the interrupt vector table to the application copy, but the LLWU interrupt was being taken in the bootloader's copy of the vector table. Not really a problem, but something I wasn't expecting.
Also, the bootloader uses PE setup code. As expected, after the wakeup reset, ACKISO was locking out I/O (including the oscillator). When PE tries setting up the oscillator, it fails to get a lock and hangs. I couldn't find any combination of settings for the K20 that would generate code to detect and correct this condition. So I had to add pre-initialisation code to clear ACKISO -- a bit limiting, but something I can live with.
Dave
Hi Alejandro,
Thanks for your response -- I must have missed it. I decided to forego the LPM driver due to time constraints -- we use a lot of the peripherals on the K20, and most of them don't (yet) have implementations of the LPM interfaces. I went for something of a halfway house, by modifying init/deinit code and the BSP I/O configuration functions to gate off clocks and put pins into safe states. Hopefully if we do this again I'll have more time to put the infrastructure in place for the LPM driver.
I did get to the bottom of the problem in the end. I pared the application right back such that most of the peripherals were never enabled. I was then able to enter sleep VLLS1. I enabled the peripherals one-by-one, and it turned out that it was one of the SPI ports that was failing to acknowledge.
The particular SPI port was no longer required and I think the problem was that the pins were not in an idle state. I made sure the SPI port wasn't being enabled, and that solved the problem.
The next issue was that we have a bootloader which gets entered out of reset. The bootloader relocates the interrupt vector table to the application copy, but the LLWU interrupt was being taken in the bootloader's copy of the vector table. Not really a problem, but something I wasn't expecting.
Also, the bootloader uses PE setup code. As expected, after the wakeup reset, ACKISO was locking out I/O (including the oscillator). When PE tries setting up the oscillator, it fails to get a lock and hangs. I couldn't find any combination of settings for the K20 that would generate code to detect and correct this condition. So I had to add pre-initialisation code to clear ACKISO -- a bit limiting, but something I can live with.
Dave
Hi,
I really recommend you to use the LPM driver of MQX.
The driver takes care of all the saving context of the Kernel, applications and other stuff. This is necessary because as far as I understand an exit of any VLLSx mode is through reset.
Anyway, if you are attempting to create your own power management driver. You can refer to the bareboard examples of the TWR-K20DX50. This example shows in a very simple way all the necessary to enter and exit to and from low power mode.
This examples are found at :
I hope that helps.