Yeah, let me show what I’ve got so far. The relevant bits are:
#include <ArduinoLowPower.h>
#include <EEPROM.h>
#define SLEEP_TIMEOUT 8000
#define SLEEP_DURATION 120000 // 2 minutes
#define WAKE_STATE FALLING
#define WAKE_UP_BTN PA5
#define WAKE_UP_TILT PA5
#define MINIMUM_TILT 9
// on board Flush SPI_1 pins
#define CS1 PA6 // (21)
#define CLK1 PA0 // (17), D17
#define MOSI1 PB0 // (15), D15
#define MISO1 PB1 // (16), D16
// on board peripherals pins
#define IMU_EN PD5 // (19)
#define MIC_EN PC8 // (22)
#define VBAT_EN PD3 // (25)
#define RFSW_EN PB5 // (27)
// Flash commands
#define READ_DATA 0x03
#define WRITE_ENABLE 0x06
#define PAGE_PROGRAM 0x02
#define SECTOR_ERASE 0x20
uint32_t cause;
unsigned long startTimeoutTime = 0;
//-----------------------------------------------------------------------------
// Flash functions
void sendSPI(byte data) {
for (int i = 0; i < 8; i++) {
digitalWrite(MOSI1, data & 0x80);
data <<= 1;
digitalWrite(CLK1, HIGH);
delayMicroseconds(1);
digitalWrite(CLK1, LOW);
delayMicroseconds(1);
}
}
void writeEnable() {
digitalWrite(CS1, LOW);
sendSPI(WRITE_ENABLE);
digitalWrite(CS1, HIGH);
}
//-----------------------------------------------------------------------------
void setup() {
// on board flash pins
pinMode(CS1, OUTPUT);
pinMode(CLK1, OUTPUT);
pinMode(MOSI1, OUTPUT);
pinMode(MISO1, INPUT);
digitalWrite(CS1, HIGH);
// on board peripherals OFF
pinMode(IMU_EN, OUTPUT);
pinMode(MIC_EN, OUTPUT);
pinMode(VBAT_EN, OUTPUT);
pinMode(RFSW_EN, OUTPUT);
// digitalWrite(IMU_EN, LOW);
digitalWrite(MIC_EN, LOW); // MIC Power OFF
digitalWrite(VBAT_EN, LOW); // VBAT Power OFF
digitalWrite(RFSW_EN, LOW); // RFSW Power OFF
pinMode(WAKE_UP_BTN, INPUT_PULLUP);
cause = GPIO_EM4GetPinWakeupCause();
EEPROM.get(eeAddress, appState);
}
void loop() {
const float baseX = myIMU.readFloatAccelX();
const float baseY = myIMU.readFloatAccelY();
const float baseZ = myIMU.readFloatAccelZ();
const int angleZ = atan2(baseZ, sqrt(baseX * baseX + baseY * baseY)) * 180 / PI;
// if there is no tilt, but it's been woken up due to sleep timer
if (angleZ < appState.baseAngleZ + MINIMUM_TILT) {
if (appState.asleep == 1) {
// if the wake up cause was from the WAKE_UP_TILT pin, wake up and stay awake
if (cause & GPIO_IEN_EM4WUIEN0) {
wakeUp();
// else, go back to sleep
} else {
enterStandbySleep();
}
}
} else {
// wake up and stay awake
wakeUp();
}
// wait 8 seconds before going to sleep
if (startTimeoutTime > 0 && ((millis() - startTimeoutTime) > SLEEP_TIMEOUT)) {
startTimeoutTime = 0;
enterStandbySleep();
}
}
void wakeUp() {
startTimeoutTime = millis();
appState.asleep = 0;
appState.timeSpentSleeping = 0;
// this stuff is commented out because I'm not sure if this is right or even helpful
// digitalWrite(IMU_EN, HIGH); // IMU Power ON
// Flash power up
// digitalWrite(CS1, LOW);
// sendSPI(0xAB);
// digitalWrite(CS1, HIGH);
// delayMicroseconds(30);
}
void enterStandbySleep() {
// digitalWrite(IMU_EN, LOW); // IMU Power OFF
appState.asleep = 1;
EEPROM.put(eeAddress, appState);
delay(10);
// Flash Deep Power Down
// writeEnable();
// digitalWrite(CS1, LOW);
// sendSPI(0xB9);
// digitalWrite(CS1, HIGH);
// delay(1);
LowPower.attachInterruptWakeup(WAKE_UP_TILT, nullptr, WAKE_STATE);
LowPower.deepSleep(SLEEP_DURATION);
}
The EEPROM state I’m getting a putting is kind of an object with a dozen or so numbers to represent status of different things in the app.