possibly fix wasted power in idle mode
arduino uses TCA timer to do its things. it doesn't need to do anything while the MCU is in low power sleep. disable TCA whenever entering sleep from user code. note that the prior "working" demo commented using the rgb_run_next sleep loop in the program. was still diagnosing issues with TCB0 interrupt. if there's still issues waking from idle with TCB interrupt, then things will still need to be addressed... this fix is untested.
This commit is contained in:
parent
4d58a3df74
commit
cf209fce4d
Binary file not shown.
|
@ -79,19 +79,17 @@ uint8_t rgbprog_idx = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void idle_cpu()
|
void sleep_cpu(uint8_t sleep_type)
|
||||||
{
|
{
|
||||||
SLPCTRL.CTRLA = SLPCTRL_SMODE_IDLE_gc | SLPCTRL_SEN_bm;
|
// TCA interrupt is used by arduino timing routines
|
||||||
|
// needs to be disabled while asleep to save power
|
||||||
|
TCA0.SPLIT.CTRLA &= ~TCA_SPLIT_ENABLE_bm;
|
||||||
|
|
||||||
|
// configure for idle mode, then idle
|
||||||
|
SLPCTRL.CTRLA = sleep_type | SLPCTRL_SEN_bm;
|
||||||
__asm("sleep");
|
__asm("sleep");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep_cpu()
|
|
||||||
{
|
|
||||||
SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc | SLPCTRL_SEN_bm;
|
|
||||||
__asm("sleep");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// mcu init
|
// mcu init
|
||||||
void setup() {
|
void setup() {
|
||||||
// configure PA2 as falling edge interrupt for button
|
// configure PA2 as falling edge interrupt for button
|
||||||
|
@ -120,19 +118,22 @@ void setup() {
|
||||||
|
|
||||||
// mcu program loop
|
// mcu program loop
|
||||||
void loop() {
|
void loop() {
|
||||||
|
// if something other than TCB0 or PA2 going low wakes us, we don't care
|
||||||
|
// sleep with prior sleep settings until we're ready to run next rgb prog step
|
||||||
while (!rgb_run_next) {
|
while (!rgb_run_next) {
|
||||||
// __asm("sleep");
|
__asm("sleep");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// re-enable TCA0 since arduino core uses it
|
||||||
|
TCA0.SPLIT.CTRLA |= TCA_SPLIT_ENABLE_bm;
|
||||||
|
|
||||||
|
// clear run flag for next go
|
||||||
rgb_run_next = 0;
|
rgb_run_next = 0;
|
||||||
|
|
||||||
switch (run_rgbprog) {
|
switch (run_rgbprog) {
|
||||||
case RGB_INIT: { // just started running a program
|
case RGB_INIT: { // just started running a program
|
||||||
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
|
digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply,
|
||||||
delay(15); // wait a moment for LEDs to stabilize,
|
delay(15); // wait a moment for LEDs to stabilize,
|
||||||
/*for (uint16_t i = 0; i < (8000000UL / 4 / 1000) * 20; i++) {
|
|
||||||
asm("nop");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
rgbprog_idx++; // select the next program in sequence,
|
rgbprog_idx++; // select the next program in sequence,
|
||||||
if (rgbprog_idx >= PROG_COUNT) {
|
if (rgbprog_idx >= PROG_COUNT) {
|
||||||
|
@ -144,7 +145,7 @@ void loop() {
|
||||||
|
|
||||||
enable_rgb_timer(); // then start the RGB program timebase.
|
enable_rgb_timer(); // then start the RGB program timebase.
|
||||||
|
|
||||||
idle_cpu(); // we can idle CPU after running the program
|
sleep_cpu(SLPCTRL_SMODE_IDLE_gc); // we can idle CPU after running the program
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +158,7 @@ void loop() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
idle_cpu(); // we can idle CPU after running the program
|
sleep_cpu(SLPCTRL_SMODE_IDLE_gc); // we can idle CPU after running the program
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +167,7 @@ void loop() {
|
||||||
rgb.show(); // send final updates to the led
|
rgb.show(); // send final updates to the led
|
||||||
run_rgbprog = RGB_IDLE;
|
run_rgbprog = RGB_IDLE;
|
||||||
|
|
||||||
idle_cpu(); // we can idle CPU after running the program
|
sleep_cpu(SLPCTRL_SMODE_IDLE_gc); // we can idle CPU after running the program
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +177,7 @@ void loop() {
|
||||||
digitalWrite(PIN_LED_PWRENA, LOW); // disable LED power supply,
|
digitalWrite(PIN_LED_PWRENA, LOW); // disable LED power supply,
|
||||||
run_rgbprog = RGB_IDLE; // and clear run_rgbprog.
|
run_rgbprog = RGB_IDLE; // and clear run_rgbprog.
|
||||||
|
|
||||||
sleep_cpu(); // finally, go to sleep in standby mode
|
sleep_cpu(SLPCTRL_SMODE_STDBY_gc); // finally, go to sleep in standby mode
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue