Skip to content

Commit db1f276

Browse files
authored
Merge pull request #2238 from particle-iot/fix/gen2_sleep20_blocked/ch68382
Gen2: platforms calling sleep20 API to enter stop/ulp mode may block user application.
2 parents 95d7fe9 + 9460e48 commit db1f276

File tree

5 files changed

+162
-53
lines changed

5 files changed

+162
-53
lines changed

hal/src/electron/modem/mdm_hal.cpp

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ void MDMParser::_incModemStateChangeCount(void) {
12421242
}
12431243
}
12441244

1245-
int MDMParser::getModemStateChangeCount(void) {
1245+
int MDMParser::getModemStateChangeCount(void) const {
12461246
return _mdm_state_change_count;
12471247
}
12481248

@@ -1253,6 +1253,13 @@ bool MDMParser::powerState(void) const {
12531253
// We are definitely powered on
12541254
return true;
12551255
}
1256+
// RI is low (so the modem is probably off)
1257+
// Check whether modem has seen a state change at least once
1258+
// and current power state, that only gets reset if we've confirmed that
1259+
// modem was reset with a condition below.
1260+
if (getModemStateChangeCount() > 0 && !_pwr) {
1261+
return false;
1262+
}
12561263
// We are still not sure whether we are off or not,
12571264
// because RI may be held low for over a second under some conditions
12581265
// Sleeping for 1.1s and checking again
@@ -1306,7 +1313,6 @@ bool MDMParser::powerOff(void)
13061313
_resetFailureAttempts = 0;
13071314
bool ok = false;
13081315
bool continue_cancel = false;
1309-
bool check_ri = false;
13101316

13111317
MDM_INFO("%s = = = = = = = = = = = = = =", POWER_OFF_MSG);
13121318

@@ -1315,7 +1321,8 @@ bool MDMParser::powerOff(void)
13151321
resume(); // make sure we can use the AT parser
13161322
}
13171323

1318-
check_ri = true;
1324+
bool power_state = true;
1325+
13191326
if (!softPowerOff()) {
13201327
if (_dev.dev == DEV_SARA_R410) {
13211328
// If memory issue is present, ensure we don't force a power off too soon
@@ -1347,7 +1354,7 @@ bool MDMParser::powerOff(void)
13471354
}
13481355
}
13491356
// Skip power off sequence if power is already off
1350-
if (powerState() && _dev.dev != DEV_SARA_G350) {
1357+
if (_dev.dev != DEV_SARA_G350 && (power_state = powerState())) {
13511358
MDM_INFO("%s Modem not responsive, trying PWR_UC...", POWER_OFF_MSG);
13521359
HAL_GPIO_Write(PWR_UC, 0);
13531360
// >1.5 seconds on SARA R410M
@@ -1358,25 +1365,19 @@ bool MDMParser::powerOff(void)
13581365
}
13591366
}
13601367

1361-
// Verify power off, or delay
1362-
if (check_ri) {
1363-
system_tick_t t0 = HAL_Timer_Get_Milli_Seconds();
1364-
bool power_state = true;
1365-
while ((power_state = powerState()) && !TIMEOUT(t0, 15000)) {
1366-
HAL_Delay_Milliseconds(1); // just wait
1367-
}
1368-
// if V_INT is low, indicate power is off
1369-
if (!power_state) {
1370-
_pwr = false;
1371-
MDM_INFO("%s took %lu ms", POWER_OFF_MSG, HAL_Timer_Get_Milli_Seconds() - t0);
1372-
} else {
1373-
MDM_INFO("%s failed", POWER_OFF_MSG);
1374-
}
1375-
} else {
1368+
// Verify power off
1369+
system_tick_t t0 = HAL_Timer_Get_Milli_Seconds();
1370+
// NOTE: initial power_state value is checked here first
1371+
while (power_state && !TIMEOUT(t0, 15000)) {
1372+
HAL_Delay_Milliseconds(1); // just wait
1373+
power_state = powerState();
1374+
}
1375+
// if V_INT is low, indicate power is off
1376+
if (!power_state) {
13761377
_pwr = false;
1377-
// todo - add if these are automatically done on power down
1378-
//_activated = false;
1379-
//_attached = false;
1378+
MDM_INFO("%s took %lu ms", POWER_OFF_MSG, HAL_Timer_Get_Milli_Seconds() - t0);
1379+
} else {
1380+
MDM_INFO("%s failed", POWER_OFF_MSG);
13801381
}
13811382
HAL_Delay_Milliseconds(1000); // give peace a chance
13821383
// Increment the state change counter to show that the modem has been powered on -> off

hal/src/electron/modem/mdm_hal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class MDMParser
152152
which can be used to invalidate previous assumptions about the state of the modem.
153153
\return _pwr_off_count value
154154
*/
155-
int getModemStateChangeCount(void);
155+
int getModemStateChangeCount(void) const;
156156

157157
/** Power on the MT if necessary and then try powering off using AT command. This function has to be called prior to
158158
switching off the supply.

system/src/system_sleep.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ static bool system_sleep_network_suspend(network_interface_index index) {
5555
network_disconnect(index, NETWORK_DISCONNECT_REASON_SLEEP, NULL);
5656
resume = true;
5757
}
58+
#if PLATFORM_GEN == 2
59+
if (!SPARK_WLAN_SLEEP) {
60+
resume = true;
61+
}
62+
#endif
5863
// Turn off the modem
5964
network_off(index, 0, 0, NULL);
6065
LOG(TRACE, "Waiting interface to be off...");
@@ -64,8 +69,16 @@ static bool system_sleep_network_suspend(network_interface_index index) {
6469
}
6570

6671
static int system_sleep_network_resume(network_interface_index index) {
72+
#if PLATFORM_GEN == 2
73+
/* On Gen2, calling network_on() and network_connect() will block until the connection is established
74+
* if single threaded, or this function is invoked synchronously by the system thread if system threading
75+
* is enabled. In both case, that would block the user application. Setting a flag here to unblock the user
76+
* application and restore the connection later. */
77+
SPARK_WLAN_SLEEP = 0;
78+
#else
6779
network_on(index, 0, 0, nullptr);
6880
network_connect(index, 0, 0, nullptr);
81+
#endif
6982
return SYSTEM_ERROR_NONE;
7083
}
7184

@@ -183,7 +196,6 @@ int system_sleep_ext(const hal_sleep_config_t* config, hal_wakeup_source_base_t*
183196

184197
#if HAL_PLATFORM_WIFI
185198
if (wifiResume) {
186-
SPARK_WLAN_SLEEP = 0;
187199
system_sleep_network_resume(NETWORK_INTERFACE_WIFI_STA);
188200
}
189201
#endif // HAL_PLATFORM_WIFI

system/src/system_sleep_compat.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,15 @@ int system_sleep_impl(Spark_Sleep_TypeDef sleepMode, long seconds, uint32_t para
171171
RESET_REASON_NONE, seconds);
172172
}
173173

174+
#if HAL_PLATFORM_SETUP_BUTTON_UX
175+
bool networkTurnedOff = false;
176+
#endif // HAL_PLATFORM_SETUP_BUTTON_UX
177+
174178
if (network_sleep_flag(param) || SLEEP_MODE_WLAN == sleepMode) {
175179
network_suspend();
180+
#if HAL_PLATFORM_SETUP_BUTTON_UX
181+
networkTurnedOff = true;
182+
#endif // HAL_PLATFORM_SETUP_BUTTON_UX
176183
}
177184

178185
switch (sleepMode)
@@ -193,17 +200,14 @@ int system_sleep_impl(Spark_Sleep_TypeDef sleepMode, long seconds, uint32_t para
193200
break;
194201

195202
case SLEEP_MODE_DEEP:
196-
if (network_sleep_flag(param))
197-
{
198-
network_disconnect(0, NETWORK_DISCONNECT_REASON_SLEEP, NULL);
199-
network_off(0, 0, 0, NULL);
200-
}
201203
return system_sleep_enter_standby_compat(seconds, param);
202204

203205
#if HAL_PLATFORM_SETUP_BUTTON_UX
204206
case SLEEP_MODE_SOFTPOWEROFF:
205-
network_disconnect(0, NETWORK_DISCONNECT_REASON_SLEEP, NULL);
206-
network_off(0, 0, 0, NULL);
207+
if (!networkTurnedOff) {
208+
network_disconnect(0, NETWORK_DISCONNECT_REASON_SLEEP, NULL);
209+
network_off(0, 0, 0, NULL);
210+
}
207211
return system_sleep_enter_standby_compat(seconds, param);
208212
#endif
209213
}

0 commit comments

Comments
 (0)