Turn off peripherals!
In this episode, we continue our series on power debugging with some thoughts on how to handle power-hungry peripherals, and how you can use the power debugging features to minimize unnecessary power consumption. In many systems, peripherals consume the major part of the power and the CPU only consumes a minor part. Exercising strict control of how peripherals are being used is a fundamental approach to minimizing power consumption.
The basic problem is that peripheral units in an embedded system could consume a lot of power even when they are not actively in use. If you are designing for low power, it is vital that you disable them and not just leave them unattended when they are not in use. But for different reasons, a peripheral can be left with its power supply on; it can be a careful and correct design decision, or it can be an inadequate design or just a mistake. If not the first case, then more power than expected will be consumed by the system.
In many cases, it is enough to disable the peripheral when it is inactive, for example by turning off its clock which in most cases will shut down its power consumption completely.
There are some cases where clock gating will not be enough though. Analog peripherals like converters or comparators can consume a substantial amount of power even when the clock is turned off. In this case you need to turn the peripheral off completely.
So far it is pretty straightforward, and good coding practices will help you avoid most power leaks of this kind, but the problems could be more complex than this. Let us take a look at an example of an event-driven system where it becomes more difficult to avoid unnecessary peripheral power consumption.
Consider a system where one task uses an analog comparator while executing but is suspended by a higher-priority task. Ideally, the comparator should be turned off when the task is suspended and then turned on again once the task is resumed. This would minimize the power being consumed during the execution of the high priority task.
Figure below shows a schematic diagram of the power consumption of the system where at t0 it is in an inactive mode and the current is i0. At t1 the system is activated and the comparator is started whereby the current rises to i2. At t2 the higher priority task suspends the first task, but the comparator is not turned off. Instead, more peripheral devices are activated by the new task, resulting in an increase in current to i3 between t2 and t3 where control is handed back to the task with lower priority to finish the execution.
The functionality of the system could be excellent and it can be well optimized in terms of execution speed and code size. But in the power domain, more optimizations can be done. The blue area represents the power that could have been saved if the comparator had been turned off between t2 and t3. In a case like this, it is not always worth the added code required to turn off or on a peripheral, and you might have timing and availability constraints that have to be carefully considered.
There are also cases where it is possible to save power by turning off the CPU and leaving the peripherals on, but that is another story that we will come back to in the next episode.