From cf209fce4db47fe7ea9d9408b3d4888327cbc31f Mon Sep 17 00:00:00 2001 From: true Date: Mon, 28 Apr 2025 20:19:36 -0700 Subject: [PATCH] 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. --- .../.vs/HackSpaceCon_AS7/v14/.atsuo | Bin 74752 -> 74752 bytes fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp | 35 +++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/fw/HackSpaceCon_AS7/.vs/HackSpaceCon_AS7/v14/.atsuo b/fw/HackSpaceCon_AS7/.vs/HackSpaceCon_AS7/v14/.atsuo index 9059c35aa354aa2d52512e949d89949079163eb7..2c86507a1bc9fdbb146a5f2ace853c43539220cb 100644 GIT binary patch delta 412 zcmZoT!P0PoWkLX>=Egv2CRT<8h3s257c#A9)D>i4VBiO0Ng!4NVqPF-17Z#!<_2PI zApZCN|9>eUtu@(~C7kmwkf#C?otP-R`2forM%D`xXEJO78rRP_i9^K}*)%brI-v6Z zB0w5snm&{dG7Tgy0i>mYm<5Q1fcW3!L>6aBkPHmy0Y%|9Zr;lg%(z*A?*sEDJ_VM| z3NnuvH#3R+V_&4fv`CI^5|7Me86%y^=eFxiE-?z=FaT;b2IA=f%8VM5zX+Y5>?~=> z!@|hG@Bk}8pH}VX!B2Fc7Oa$(1FXj1ajr{}fr^VM=p%d!0!={S!2s7>j=p2_eCY~Z(WJsy;VQQ<2rVTM?Z53^;a7AZoKxof(y@*@)BKs>O`{N5i6IQdpF zP0OUo&&6@V1C9dG7hKtjfE@y|WD~-82lh|Gr-N?8O)--cG?7+g^WjqRn=elnDr5aIr$8x(3c pq5;r%yxcqOqokepP283l(+nc&=6}X)Nnu`?h5Se>4<#NhKLOtWsHp$| diff --git a/fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp b/fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp index 3cffe0a..edb92c8 100644 --- a/fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp +++ b/fw/HackSpaceCon_AS7/HSC_Wand/wand_program.cpp @@ -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"); } -void sleep_cpu() -{ - SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc | SLPCTRL_SEN_bm; - __asm("sleep"); -} - - // mcu init void setup() { // configure PA2 as falling edge interrupt for button @@ -120,19 +118,22 @@ void setup() { // mcu program 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) { - // __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; switch (run_rgbprog) { case RGB_INIT: { // just started running a program digitalWrite(PIN_LED_PWRENA, HIGH); // enable LED power supply, 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, if (rgbprog_idx >= PROG_COUNT) { @@ -144,7 +145,7 @@ void loop() { 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; } @@ -157,7 +158,7 @@ void loop() { 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; } @@ -166,7 +167,7 @@ void loop() { rgb.show(); // send final updates to the led 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; } @@ -176,7 +177,7 @@ void loop() { digitalWrite(PIN_LED_PWRENA, LOW); // disable LED power supply, 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; }