Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE cannot restart advertising when it is asleep. #2155

Merged
merged 2 commits into from
Jul 20, 2020
Merged

Conversation

XuGuohui
Copy link
Member

Problem

BLE cannot restart advertising when disconnected by peer device if sleep mode is enabled

Steps to Test

  1. Build and flash the below example application.
  2. Connect to device using mobile App, e.g. LightBlue.
  3. Disconnect from device using mobile App.
  4. Device should restart advertising automatically.

Example App

#include "Particle.h"

SYSTEM_MODE(MANUAL);

void setup() {
    BLE.advertise();
}

void loop() {
    delay(1000);
    System.sleep(SystemSleepConfiguration().mode(SystemSleepMode::STOP).gpio(D0, RISING).ble());
}

Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

@XuGuohui XuGuohui added this to the 2.0.0 milestone Jul 20, 2020
@XuGuohui XuGuohui requested a review from avtolstoy July 20, 2020 09:09
@@ -379,6 +387,10 @@ static void fpu_sleep_prepare(void) {
SPARK_ASSERT((fpscr & 0x07) == 0);
}

#ifdef DEBUG_BUILD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is here only for going through this function more easily with a debugger. Let's remove it.

@@ -590,6 +602,22 @@ static int enterStopBasedSleep(const hal_sleep_config_t* config, hal_wakeup_sour
// we are still under the effect of HAL_disable_irq that masked all but SoftDevice interrupts using BASEPRI
__enable_irq();

/*
* SD_EVT_IRQn is set pending after __enable_irq() and SoftDevice interrupts being executed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's reword this, I had to read it multiple times and ask additional questions to understand how this works:

Wake-up on BLE events relies mainly on SD_EVT_IRQn interrupt, which will be disabled through NVIC (not masked) when entering sd_nvic_critical_region_enter(). Normally on BLE activity we would be woken up by other high-priority SoftDevice interrupts (e.g. timers, radio events etc), however SD_EVT_IRQn would be set as pending only after we unmask high-priority SoftDevice interrupts (__enable_irq()) and after the appropriate SoftDevice interrupt handlers finish executing. We would then immediately go back to sleep and wouldn't notice this change in SD_EVT_IRQn state. As a workaround, for the duration of the sleep, we'll be bumping the priority of SD_EVT_IRQn, so that it can wake us up from stop mode (WFI) as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, I think it might be viable to simply move pending IRQ checks under __enable_irq().

@XuGuohui XuGuohui requested a review from avtolstoy July 20, 2020 10:11
@XuGuohui XuGuohui merged commit 01ef3c4 into develop Jul 20, 2020
@XuGuohui XuGuohui deleted the fix/ble/ch57499 branch July 20, 2020 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants