Hi, I've noticed much higher than expected power usage and I've narrowed it down to PWM. I need to be able to turn off the PWMs when they're not needed.
I use all 4 PWMs (PWM0, PWM1, PWM2, PWM3)
I use this code to turn them off.
void nrf_pwm_stop()
{
NRF_PWM0->TASKS_STOP = 1 << PWM_TASKS_STOP_TASKS_STOP_Pos;
NRF_PWM1->TASKS_STOP = 1 << PWM_TASKS_STOP_TASKS_STOP_Pos;
NRF_PWM2->TASKS_STOP = 1 << PWM_TASKS_STOP_TASKS_STOP_Pos;
NRF_PWM3->TASKS_STOP = 1 << PWM_TASKS_STOP_TASKS_STOP_Pos;
do
{
} while (
(!NRF_PWM0->EVENTS_STOPPED) ||
(!NRF_PWM1->EVENTS_STOPPED) ||
(!NRF_PWM2->EVENTS_STOPPED) ||
(!NRF_PWM3->EVENTS_STOPPED));
NRF_PWM0->PSEL.OUT[0]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM0->PSEL.OUT[1]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM0->PSEL.OUT[2]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM0->PSEL.OUT[3]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM0->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
NRF_PWM1->PSEL.OUT[0]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM1->PSEL.OUT[1]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM1->PSEL.OUT[2]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM1->PSEL.OUT[3]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM1->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
NRF_PWM2->PSEL.OUT[0]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM2->PSEL.OUT[1]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM2->PSEL.OUT[2]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM2->PSEL.OUT[3]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM2->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
NRF_PWM3->PSEL.OUT[0]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM3->PSEL.OUT[1]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM3->PSEL.OUT[2]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM3->PSEL.OUT[3]=(PWM_PSEL_OUT_CONNECT_Disconnected<<PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM3->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos);
}
Here is my test main loop
void main()
{
int ret;
if (!device_is_ready(button0.port)) return false;
if (!device_is_ready(button1.port)) return false;
if (!device_is_ready(button2.port)) return false;
if (!device_is_ready(button3.port)) return false;
ret = gpio_pin_configure_dt(&button0, GPIO_INPUT);
ret = gpio_pin_configure_dt(&button1, GPIO_INPUT);
ret = gpio_pin_configure_dt(&button2, GPIO_INPUT);
ret = gpio_pin_configure_dt(&button3, GPIO_INPUT);
do
{
k_msleep(10000);
nrf_pwm_start();
nrf_pwm_stop();
}
while (true);
}
I've noticed an unexpected power draw 2 seconds after turning PWM off. My guess is that this is caused by the sequences ending because each takes 1 second.
Here is the power profiler output. As you can see I get 4uA current during k_msleep and then 2 seconds after nrf_pwm_stop() I see 3mA current draw. So it seems that my code to stop the PWM is wrong somehow.


Any help is greatly appreciated because I don't know what might be wrong with this.