Wake on Detection of Power

I am implementing a feature in our firmware that will allow our device (based around the Electron) to wake when external power is applied.

I started with the following code:

System.sleep(46, FALLING, SLEEP_NETWORK_STANDBY, timeToSleep);
System.reset();

But this was waking too often, as the PMIC issues the INT when charge is complete.

To counteract this, I put the following code in place:

retained uint32_t sleepTimer; // initialized before code runs

sleepTimer = Time.now();
uint32_t timeToSleep = seconds;
do {
  System.sleep(46, FALLING, SLEEP_NETWORK_STANDBY, timeToSleep);
  if(!pmic.isPowerGood()) { break; }
  timeToSleep = seconds - (Time.now() - sleepTimer);
  if(timeToSleep > seconds || timeToSleep <= 0) { break; }
} while(Time.now() - sleepTimer < seconds);
System.reset();

Which seems to solve the issue, except when it locks my application. When digging into why it would lock my application, I’ve found that the Electron is communicating with the cloud between when the PMIC wakes the Electron and when it goes back to sleep. When in debug mode, I can see messages, such as:

  • AWAKE
  • ASLEEP
  • AWAKE
    • 0000040035 [comm] INFO: Waiting for Confirmed messages to be sent.
    • 0000041085 [comm.protocol] INFO: rcv’d message type=13
  • ASLEEP
  • AWAKE
    • 0000043158 [comm] INFO: Waiting for Confirmed messages to be sent.
    • 0000044198 [comm.protocol] INFO: rcv’d message type=13
  • ASLEEP
  • AWAKE
    • 0000043158 [comm] INFO: Waiting for Confirmed messages to be sent.
    • 0000044198 [comm.protocol] INFO: rcv’d message type=13
  • ASLEEP
  • AWAKE
    • 0000045880 [comm.protocol] INFO: rcv’d message type=13
    • 00000458
  • ASLEEP
  • AWAKE
    • 0000051767 [comm.protocol] INFO: rcv’d message type=13
    • 0000051767 [comm] INFO: All Confirmed messages sent: client(yes) server(
  • ASLEEP

I’m not sure this is the root cause of the lock, but I am sure I don’t want the Electron to be communicating with Particle in this loop. I don’t care whether Particle received confirmable messages, etc.

So my question is – what is the right way to prevent this? It seems that this is what SINGLE_THREADED_BLOCK is for, but I am not sure how its intended to work with sleeping and whatnot.

You are using the LOW_BAT_UC pin?

#define LOW_BAT_UC 46

Also heed the warning :wink:

// The following pins are only defined for easy access during development.
// Will be removed later as they are internal I/O and users
// should not have too easy of access or bad code could do harm.

Yes – I’m using the LOW_BAT_UC pin #46. Hoping that Particle won’t for some reason make it impossible to access this pin.

I’m not sure what the harm in accessing this pin via an application could be?

I cannot get my Electron to sleep in SINGLE_THREADED_BLOCK() {}. I imagine it has something to do with some calls not making it to the other parts of the RTOS when in single threaded mode.

It seems like in order to avoid communication with the Particle cloud when waking in this loop, I am going to have to disconnect from the Particle cloud before going to sleep. New code looks like:

// System.sleep(SLEEP_MODE_DEEP, seconds, SLEEP_NETWORK_STANDBY);
// 46 = LOW_BAT_UC = INT pin on bq24195
sleepTimer = Time.now();
uint32_t timeToSleep = seconds;
if(Particle.connected()) {
  Particle.disconnect();
  waitFor(Particle.disconnected, 60000);
}
do {
  System.sleep(46, FALLING, SLEEP_NETWORK_STANDBY, timeToSleep);
  if(!pmic.isPowerGood()) { break; }
  timeToSleep = seconds - (Time.now() - sleepTimer);
  if(timeToSleep > seconds || timeToSleep <= 0) { break; }
} while(Time.now() - sleepTimer < seconds);
System.reset();

This seems to fix my issue, but comes with two new questions:

  • I’m using the undocumented function Particle.disconnected. This is a little worrying, but it seems to work.
  • What penalty do I incur by issuing a Particle.disconnect() when later reconnecting after waking up? It seems, per the logs below, the device is restoring its status without going through the full 5k handshake. Is that correct?
0000014083 [comm.protocol.handshake] INFO: Establish secure connection
0000014113 [comm.dtls] INFO: (CMPL,RENEG,NO_SESS,ERR) restoreStatus=0
0000014115 [comm.dtls] INFO: out_ctr 0,1,0,0,0,0,0,135, next_coap_id=73
0000014115 [comm.dtls] INFO: app state crc: 96efa765, expected: e17ef99
0000014117 [comm.dtls] INFO: restored session from persisted session data. next_msg_id=115
0000014117 [comm.dtls] INFO: session cmd (CLS,DIS,MOV,LOD,SAV): 2