I have set up an interrupt that changes a boolean to true and in void loop(), I am constantly checking if the boolean is true like so:
TTGOClass *ttgo;
bool irq = false;
void setup()
{
Serial.begin(115200);
ttgo = TTGOClass::getWatch();
ttgo->begin();
ttgo->openBL();
ttgo->tft->fillScreen(TFT_BLACK);
ttgo->tft->drawString("T-Watch AXP202", 25, 50, 4);
ttgo->tft->setTextFont(4);
ttgo->tft->setTextColor(TFT_WHITE, TFT_BLACK);
pinMode(AXP202_INT, INPUT_PULLUP);
attachInterrupt(AXP202_INT, [] {
irq = true;
}, FALLING);
//!Clear IRQ unprocessed first
ttgo->power->enableIRQ(AXP202_PEK_SHORTPRESS_IRQ | AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_CHARGING_IRQ, true);
ttgo->power->clearIRQ();
}
void loop()
{
if (irq) {
irq = false;
ttgo->power->readIRQ();
if (ttgo->power->isVbusPlugInIRQ()) {
ttgo->tft->fillRect(20, 100, 200, 85, TFT_BLACK);
ttgo->tft->drawString("Power Plug In", 25, 100);
}
if (ttgo->power->isVbusRemoveIRQ()) {
ttgo->tft->fillRect(20, 100, 200, 85, TFT_BLACK);
ttgo->tft->drawString("Power Remove", 25, 100);
}
if (ttgo->power->isPEKShortPressIRQ()) {
ttgo->tft->fillRect(20, 100, 200, 85, TFT_BLACK);
ttgo->tft->drawString("PowerKey Press", 25, 100);
}
ttgo->power->clearIRQ();
}
delay(1000);
}
The t-watch 2020 (an esp32 smartwatch) runs on a battery and this weird method found in its example sketches (the code above is an example not the actual code because it is quite chaotic) wastes quite a lot of precious battery power. So I tried throwing the code from the if inside void loop() right into attachInterrupt(AXP202_INT, [] but... I needed to execute lengthy commands (I think that's the cause of the problem)such as Serial.print() and delay() (they are absolutely necesarry), the esp32 crashes returning the following error:
16:18:32.486 -> Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
16:18:32.486 -> Core 0 register dump:
16:18:32.486 -> PC : 0x4009947b PS : 0x00060233 A0 : 0x8009894f A1 : 0x3ffbd150
16:18:32.486 -> A2 : 0x3ffba5a8 A3 : 0x3ffbd2dc A4 : 0x00000001 A5 : 0x00000001
16:18:32.486 -> A6 : 0x00060223 A7 : 0x00000000 A8 : 0x00000000 A9 : 0x3ffba5a8
16:18:32.486 -> A10 : 0x3ffba5a8 A11 : 0x00060023 A12 : 0x00060021 A13 : 0x3ffc0910
16:18:32.486 -> A14 : 0x00000003 A15 : 0x00060023 SAR : 0x00000000 EXCCAUSE: 0x0000001c
16:18:32.519 -> EXCVADDR: 0x00000004 LBEG : 0x40093948 LEND : 0x40093964 LCOUNT : 0x00000000
16:18:32.519 ->
16:18:32.519 -> ELF file SHA256: 0000000000000000
16:18:32.519 ->
16:18:32.519 -> Backtrace: 0x4009947b:0x3ffbd150 0x4009894c:0x3ffbd170 0x4009726f:0x3ffbd190 0x400972fd:0x3ffbd1b0 0x40098fbe:0x3ffbd1d0 0x4009909f:0x3ffbd210 0x40096b06:0x3ffbd240
16:18:32.519 ->
16:18:32.519 -> Rebooting...
the code is like this:
TTGOClass *ttgo;
bool axpIrq = false; //axpIrq for button press and power plug in/remove events.
bool lenergy = false;
bool BLaudio = false;
bool keepAwake = false;
//some initializations
ttgo = TTGOClass::getWatch();
ttgo->begin();
ttgo->lvgl_begin();
pinMode(AXP202_INT, INPUT_PULLUP);
attachInterrupt(AXP202_INT, [] {
axpIrq = true;
ttgo->power->readIRQ();
if (ttgo->power->isPEKShortPressIRQ()) {
//ttgo->power->clearIRQ();
Serial.println("button pressed");
low_energy();
}
ttgo->power->clearIRQ();
}, FALLING);
low energy is defined in another file:
void low_energy() {
//portENTER_CRITICAL(&synch);
if (!keepAwake) {
if (ttgo->bl->isOn()) {
//Serial.println("backlight on, turning off");
ttgo->closeBL();
ttgo->stopLvglTick();
ttgo->bma->enableStepCountInterrupt(false);
ttgo->displaySleep();
//lenergy = true;
gpio_wakeup_enable ((gpio_num_t)AXP202_INT, GPIO_INTR_LOW_LEVEL);
gpio_wakeup_enable ((gpio_num_t)BMA423_INT1, GPIO_INTR_HIGH_LEVEL);
esp_sleep_enable_gpio_wakeup ();
if (!BLaudio) {
setCpuFrequencyMhz(20);
esp_light_sleep_start();
//Serial.println("BLaudio is off, light sleep starts");
} else {
//Serial.println("BLaudio is on, light sleep won't start");
}
//Serial.println("screen off");
} else {
//Serial.println("Waking up");
setCpuFrequencyMhz(160);
ttgo->startLvglTick();
ttgo->displayWakeup();
ttgo->rtc->syncToSystem();
lv_disp_trig_activity(NULL);
ttgo->openBL();
ttgo->bma->enableStepCountInterrupt();
displayTime(true);
}
}
//portEXIT_CRITICAL(&synch);
}
I've tried replacing bool axpIrq = false; with volatile bool axpIrq = false;, uncommenting portENTER_CRITICAL(&synch); and portEXIT_CRITICAL(&synch); and still no results. If I am right when I think that lengthy commands are the problem, how can I execute the commands while the CPU continues in void loop normally(make a callback executed on the second core? I don't know)? If I am not right, what's the actual problem and how can I solve it?