AMB82-mini Deep Sleep: Is AON GPIO pin 21 unreadable after `PowerMode.begin()`? (Bus Fault observed)

Hi Ameba team and community,

We are building a battery-powered device on AMB82-mini (RTL8735B) that uses Deep Sleep mode (RETENTION = 0) to save power. The system wakes up from an external HIGH signal, runs while the signal is active, and goes back to deep sleep when the signal goes LOW.

Our initial idea (single-pin wake + read)

We hoped to use only pin 21 (PA2) for both:

  1. Wakeup source — configured via PowerMode.begin(DEEPSLEEP_MODE, 1, 0, 21)
  2. State reading — using digitalRead(21) after wakeup to know whether the external signal is still HIGH or already LOW

This would save one pin and one wire. Pin 21 is listed as GPIO/INT/ADC/UART1_TX in the pinout, so physically it is a normal GPIO.

Test code

To verify if this is possible, we wrote a minimal test sketch:

#include "PowerMode.h"

#define TEST_PIN 21

void setup() {
    Serial.begin(115200);
    while (!Serial) { ; }
    delay(500);

    Serial.println("==============================");
    Serial.println("AON GPIO Pin 21 Read Test");
    Serial.println("==============================");

    // Step 1: Configure pin 21 as Deep-Sleep AON wake source
    PowerMode.begin(DEEPSLEEP_MODE, 1, 0, TEST_PIN);
    Serial.println("[1] PowerMode.begin(DEEPSLEEP_MODE, 1, 0, 21) — OK");

    // Step 2: Try to re-configure pin 21 as regular INPUT_PULLUP
    pinMode(TEST_PIN, INPUT_PULLUP);
    Serial.println("[2] pinMode(21, INPUT_PULLUP) — OK");

    // Step 3: Read the pin
    int val = digitalRead(TEST_PIN);
    Serial.print("[3] digitalRead(21) = ");
    Serial.println(val == HIGH ? "HIGH" : "LOW");
}

void loop() {
    int live = digitalRead(TEST_PIN);
    Serial.print("Live digitalRead(21) = ");
    Serial.println(live == HIGH ? "HIGH" : "LOW");
    delay(2000);
}

Serial output (what we observed)

Pin 21 was physically wired to 3.3V (HIGH) during the test. Here is the Serial Monitor output:

==============================
AON GPIO Pin 21 Read Test
==============================
GPIO IRQ init OK!
[1] PowerMode.begin(DEEPSLEEP_MODE, 1, 0, 21) — OK

[MISC Err]Pin 0[2] is conflicted

[MISC Err]It's configured as GPIO now.

[MISC Err]It's using by peripheral F0000000
[2] pinMode(21, INPUT_PULLUP) — OK

Bus Fault: 
SCB Configurable Fault Status Reg = 0x00000400

Bus Fault Status: 
BusFault Address Reg is invalid(Asyn. BusFault)
Imprecise data bus error:
a data bus error has occurred, but the return address in the stack frame is not related to the instruction that caused the error.

S-domain exception from Thread mode, Standard Stack frame on S-PSP
Registers Saved to stack

Stacked: 
R0  = 0x7012c0e0
R1  = 0x00000099
R2  = 0xefdeadbe
R3  = 0x99a599a5
...

(The full register dump is attached below if needed.)

Our interpretation

Based on the output, we understand the situation as follows:

  1. PowerMode.begin(..., 21) locks pin 21 into the AON wake peripheral.
  2. Calling pinMode(21, INPUT_PULLUP) triggers a pin conflict ([MISC Err]Pin 0[2] is conflicted).
  3. The subsequent digitalRead(21) causes a Bus Fault / Hard Fault because the pin is still owned by the AON power-management peripheral and is not accessible as a regular GPIO.

Our current workaround

We now route the same external signal to two pins in parallel:

External signal HIGH/LOW
      │
      ├──► Pin 21 (PA2)  → AON wake source  → wakes the board from Deep Sleep
      │
      └──► Pin 20 (PD14) → regular GPIO      → read by firmware to decide stay-awake / sleep

This works reliably, but costs an extra pin and wire.

Questions for the community / Ameba team

  1. Is our interpretation correct?
    Once PowerMode.begin(DEEPSLEEP_MODE, ..., 21) is called, is pin 21 permanently reserved by the AON peripheral and therefore unusable for normal digitalRead()?

  2. Is there an official way to “release” pin 21 back to GPIO mode?
    For example, a de-init API, a register write, or a specific pinMode() sequence that safely transitions the pin from AON wake back to regular GPIO after the board has already woken up?

  3. Does the behavior change with RETENTION = 1?
    Our application uses RETENTION = 0 (full reboot on wakeup). If we used Standby or Sleep mode instead of Deep Sleep, would pin 21 remain readable?

  4. Is there any other single-pin solution?
    For instance, can PowerMode.begin() accept a different pin that is readable afterwards, or is there an SDK function to query the AON pin level without touching GPIO registers?

Any clarification or documentation pointers would be greatly appreciated. We want to make sure we are not missing a simpler single-pin solution before finalizing the hardware.

Thanks!

Attachments

  • Test sketch: pin21_gpio_test.ino (minimal reproducible example)
  • Full crash log: see Serial output above
    pin21_gpio_test.ino.zip (1.5 KB)

Hi @inxnik ,

  1. Yes, your interpretation is correct, a pin claimed by AON is not accessible via standard GPIO reads.

  2. There is an API called pinRemoveMode() in the SDK for GPIO de-init.

  3. The behaviour does not change with RETENTION = 1 setting. Pin21 will be readable as long as the pin is properly initialized under GPIO or AON driver.

  4. If you are looking for a single-pin solution, please refer to the implementation of the attached examples. We slightly modified the flow to avoid pin conflict.

Thank you.

pin21_gpio_aon.zip (1.4 KB)

pin21_gpio_aon_ret.zip (1.7 KB)