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:
- Wakeup source — configured via
PowerMode.begin(DEEPSLEEP_MODE, 1, 0, 21) - 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:
PowerMode.begin(..., 21)locks pin 21 into the AON wake peripheral.- Calling
pinMode(21, INPUT_PULLUP)triggers a pin conflict ([MISC Err]Pin 0[2] is conflicted). - 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
-
Is our interpretation correct?
OncePowerMode.begin(DEEPSLEEP_MODE, ..., 21)is called, is pin 21 permanently reserved by the AON peripheral and therefore unusable for normaldigitalRead()? -
Is there an official way to “release” pin 21 back to GPIO mode?
For example, a de-init API, a register write, or a specificpinMode()sequence that safely transitions the pin from AON wake back to regular GPIO after the board has already woken up? -
Does the behavior change with
RETENTION = 1?
Our application usesRETENTION = 0(full reboot on wakeup). If we used Standby or Sleep mode instead of Deep Sleep, would pin 21 remain readable? -
Is there any other single-pin solution?
For instance, canPowerMode.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)