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

System.sleep(): support for multiple wake up pins #1405

Merged
merged 4 commits into from Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions hal/inc/core_hal.h
Expand Up @@ -139,6 +139,7 @@ void HAL_Notify_Button_State(uint8_t button, uint8_t state);
void HAL_Core_Enter_Safe_Mode(void* reserved);
void HAL_Core_Enter_Bootloader(bool persist);
void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds);
int32_t HAL_Core_Enter_Stop_Mode_Ext(const uint16_t* pins, size_t pins_count, const InterruptMode* mode, size_t mode_count, long seconds, void* reserved);
void HAL_Core_Execute_Stop_Mode(void);
void HAL_Core_Enter_Standby_Mode(uint32_t seconds, void* reserved);
void HAL_Core_Execute_Standby_Mode(void);
Expand Down
1 change: 1 addition & 0 deletions hal/inc/hal_dynalib_core.h
Expand Up @@ -76,6 +76,7 @@ DYNALIB_FN(30, hal_core, HAL_Core_Led_Mirror_Pin, void(uint8_t, pin_t, uint32_t,
DYNALIB_FN(31, hal_core, HAL_Core_Led_Mirror_Pin_Disable, void(uint8_t, uint8_t, void*))

DYNALIB_FN(32, hal_core, HAL_Set_Event_Callback, void(HAL_Event_Callback, void*))
DYNALIB_FN(33, hal_core, HAL_Core_Enter_Stop_Mode_Ext, int32_t(const uint16_t*, size_t, const InterruptMode*, size_t, long, void*))

DYNALIB_END(hal_core)

Expand Down
6 changes: 6 additions & 0 deletions hal/src/core/core_hal.c
Expand Up @@ -278,6 +278,12 @@ void HAL_Core_Enter_Bootloader(bool persist)
HAL_Core_System_Reset();
}

int32_t HAL_Core_Enter_Stop_Mode_Ext(const uint16_t* pins, size_t pins_count, const InterruptMode* mode, size_t mode_count, long seconds, void* reserved)
{
HAL_Core_Enter_Stop_Mode(pins != NULL && pins_count > 0 ? *pins : TOTAL_PINS, mode != NULL && mode_count > 0 ? (uint16_t)(*mode) : 0xffff, seconds);
return 0;
}

void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds)
{
if (seconds > 0) {
Expand Down
6 changes: 6 additions & 0 deletions hal/src/gcc/core_hal.cpp
Expand Up @@ -238,6 +238,12 @@ void HAL_Core_Execute_Stop_Mode(void)
MSG("Stop mode not implemented.");
}

int32_t HAL_Core_Enter_Stop_Mode_Ext(const uint16_t* pins, size_t pins_count, const InterruptMode* mode, size_t mode_count, long seconds, void* reserved)
{
MSG("Stop mode not implemented.");
return -1;
}

void HAL_Core_Enter_Standby_Mode(uint32_t seconds, void* reserved)
{
MSG("Standby mode not implemented.");
Expand Down
Binary file modified hal/src/photon/lib/FreeRTOS/STM32F2xx_Peripheral_Drivers.a
Binary file not shown.
52 changes: 44 additions & 8 deletions hal/src/stm32f2xx/core_hal_stm32f2xx.c
Expand Up @@ -598,10 +598,34 @@ void HAL_Core_Enter_Safe_Mode(void* reserved)
HAL_Core_System_Reset_Ex(RESET_REASON_SAFE_MODE, 0, NULL);
}

void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds)
int32_t HAL_Core_Enter_Stop_Mode_Ext(const uint16_t* pins, size_t pins_count, const InterruptMode* mode, size_t mode_count, long seconds, void* reserved)
{
if (!((wakeUpPin < TOTAL_PINS) && (wakeUpPin >= 0) && (edgeTriggerMode <= FALLING)) && seconds <= 0)
return;
// Initial sanity check
if ((pins_count == 0 || mode_count == 0 || pins == NULL || mode == NULL) && seconds <= 0) {
return -1;
}

// Validate pins and modes
if ((pins_count > 0 && pins == NULL) || (pins_count > 0 && mode_count == 0) || (mode_count > 0 && mode == NULL)) {
return -1;
}

for (unsigned i = 0; i < pins_count; i++) {
if (pins[i] >= TOTAL_PINS) {
return -1;
}
}

for (unsigned i = 0; i < mode_count; i++) {
switch(mode[i]) {
case RISING:
case FALLING:
case CHANGE:
break;
default:
return -1;
}
}

SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;

Expand All @@ -624,9 +648,10 @@ void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long
// Suspend all EXTI interrupts
HAL_Interrupts_Suspend();

/* Configure EXTI Interrupt : wake-up from stop mode using pin interrupt */
if ((wakeUpPin < TOTAL_PINS) && (edgeTriggerMode <= FALLING))
{
for (unsigned i = 0; i < pins_count; i++) {
pin_t wakeUpPin = pins[i];
InterruptMode edgeTriggerMode = (i < mode_count) ? mode[i] : mode[mode_count - 1];

PinMode wakeUpPinMode = INPUT;
/* Set required pinMode based on edgeTriggerMode */
switch(edgeTriggerMode)
Expand Down Expand Up @@ -680,8 +705,11 @@ void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long
HAL_Core_Execute_Stop_Mode();

if (exit_conditions & STOP_MODE_EXIT_CONDITION_PIN) {
/* Detach the Interrupt pin */
HAL_Interrupts_Detach_Ext(wakeUpPin, 1, NULL);
for (unsigned i = 0; i < pins_count; i++) {
pin_t wakeUpPin = pins[i];
/* Detach the Interrupt pin */
HAL_Interrupts_Detach_Ext(wakeUpPin, 1, NULL);
}
}

if (exit_conditions & STOP_MODE_EXIT_CONDITION_RTC) {
Expand All @@ -700,6 +728,14 @@ void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

HAL_USB_Attach();

return 0;
}

void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds)
{
InterruptMode m = (InterruptMode)edgeTriggerMode;
HAL_Core_Enter_Stop_Mode_Ext(&wakeUpPin, 1, &m, 1, seconds, NULL);
}

void HAL_Core_Execute_Stop_Mode(void)
Expand Down
5 changes: 5 additions & 0 deletions hal/src/template/core_hal.cpp
Expand Up @@ -74,6 +74,11 @@ void HAL_Core_Enter_Stop_Mode(uint16_t wakeUpPin, uint16_t edgeTriggerMode)
{
}

int32_t HAL_Core_Enter_Stop_Mode_Ext(const uint16_t* pins, size_t pins_count, const InterruptMode* mode, size_t mode_count, long seconds, void* reserved)
{
return -1;
}

void HAL_Core_Execute_Stop_Mode(void)
{
}
Expand Down
1 change: 1 addition & 0 deletions system/inc/system_dynalib.h
Expand Up @@ -96,6 +96,7 @@ DYNALIB_FN(BASE_IDX + 12, system, system_ctrl_set_result, void(ctrl_request*, in

DYNALIB_FN(BASE_IDX + 13, system, system_pool_alloc, void*(size_t, void*))
DYNALIB_FN(BASE_IDX + 14, system, system_pool_free, void(void*, void*))
DYNALIB_FN(BASE_IDX + 15, system, system_sleep_pins, int32_t(const uint16_t*, size_t, const InterruptMode*, size_t, long, uint32_t, void*))

DYNALIB_END(system)

Expand Down
3 changes: 3 additions & 0 deletions system/inc/system_sleep.h
Expand Up @@ -21,6 +21,8 @@
#define SYSTEM_SLEEP_H

#include <stdint.h>
#include <stddef.h>
#include "interrupts_hal.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -42,6 +44,7 @@ enum class SystemSleepNetwork
*/
void system_sleep(Spark_Sleep_TypeDef mode, long seconds, uint32_t param, void* reserved);
void system_sleep_pin(uint16_t pin, uint16_t mode, long seconds, uint32_t param, void* reserved);
int32_t system_sleep_pins(const uint16_t* pins, size_t pins_count, const InterruptMode* modes, size_t modes_count, long seconds, uint32_t param, void* reserved);

#ifdef __cplusplus
}
Expand Down
17 changes: 12 additions & 5 deletions system/src/system_sleep.cpp
Expand Up @@ -153,9 +153,9 @@ int system_sleep_impl(Spark_Sleep_TypeDef sleepMode, long seconds, uint32_t para
return 0;
}

int system_sleep_pin_impl(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds, uint32_t param, void* reserved)
int system_sleep_pin_impl(const uint16_t* pins, size_t pins_count, const InterruptMode* modes, size_t modes_count, long seconds, uint32_t param, void* reserved)
{
SYSTEM_THREAD_CONTEXT_SYNC(system_sleep_pin_impl(wakeUpPin, edgeTriggerMode, seconds, param, reserved));
SYSTEM_THREAD_CONTEXT_SYNC(system_sleep_pin_impl(pins, pins_count, modes, modes_count, seconds, param, reserved));
// If we're connected to the cloud, make sure all
// confirmable UDP messages are sent before sleeping
if (spark_cloud_flag_connected()) {
Expand All @@ -177,8 +177,8 @@ int system_sleep_pin_impl(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long sec

led_set_update_enabled(0, nullptr); // Disable background LED updates
LED_Off(LED_RGB);
system_power_management_sleep();
HAL_Core_Enter_Stop_Mode(wakeUpPin, edgeTriggerMode, seconds);
system_power_management_sleep();
HAL_Core_Enter_Stop_Mode_Ext(pins, pins_count, modes, modes_count, seconds, nullptr);
led_set_update_enabled(1, nullptr); // Enable background LED updates

#if PLATFORM_ID==PLATFORM_ELECTRON_PRODUCTION
Expand Down Expand Up @@ -212,11 +212,18 @@ void system_sleep_pin(uint16_t wakeUpPin, uint16_t edgeTriggerMode, long seconds
{
// Cancel current connection attempt to unblock the system thread
network.connect_cancel(true);
system_sleep_pin_impl(wakeUpPin, edgeTriggerMode, seconds, param, reserved);
InterruptMode m = (InterruptMode)edgeTriggerMode;
system_sleep_pin_impl(&wakeUpPin, 1, &m, 1, seconds, param, reserved);
}

void system_sleep(Spark_Sleep_TypeDef sleepMode, long seconds, uint32_t param, void* reserved)
{
network.connect_cancel(true);
system_sleep_impl(sleepMode, seconds, param, reserved);
}

int32_t system_sleep_pins(const uint16_t* pins, size_t pins_count, const InterruptMode* modes, size_t modes_count, long seconds, uint32_t param, void* reserved)
{
network.connect_cancel(true);
return system_sleep_pin_impl(pins, pins_count, modes, modes_count, seconds, param, reserved);
}
185 changes: 185 additions & 0 deletions user/tests/app/sleep_multiple_pins/application.cpp
@@ -0,0 +1,185 @@
#include "application.h"

SYSTEM_MODE(MANUAL);

/* Pins by Source
*
* GPIO_PinSource0: A7 (WKP), P1S0, P1S2, B2, B4
* GPIO_PinSource1: RGBR, P1S1, P1S5, B3, B5
* GPIO_PinSource2: A2, RGBG, C0, PWR_UC
* GPIO_PinSource3: D4, A1, RGBB
* GPIO_PinSource4: D3, A6 (DAC/DAC1), P1S3, RESET_UC
* GPIO_PinSource5: D2, A0, A3 (DAC2)
* GPIO_PinSource6: D1, A4, B1
* GPIO_PinSource7: D0, A5, SETUP_BUTTON
* GPIO_PinSource8: B0, C5, PM_SCL_UC
* GPIO_PinSource9: TX, C4, PM_SDA_UC
* GPIO_PinSource10: RX, C3, TXD_UC
* GPIO_PinSource11: C2, RXD_UC
* GPIO_PinSource12: C1, RI_UC
* GPIO_PinSource13: D7, P1S4, CTS_UC, LOW_BAT_UC
* GPIO_PinSource14: D6, RTS_UC
* GPIO_PinSource15: D5, LVLOE_UC
*/

/* COMMON TO PHOTON, P1 and ELECTRON */
/* D0 - 00 { GPIOB, GPIO_Pin_7, GPIO_PinSource7, NONE, NONE, TIM4, TIM_Channel_2, PIN_MODE_NONE, 0, 0 }, */
/* D1 - 01 { GPIOB, GPIO_Pin_6, GPIO_PinSource6, NONE, NONE, TIM4, TIM_Channel_1, PIN_MODE_NONE, 0, 0 }, */
/* D2 - 02 { GPIOB, GPIO_Pin_5, GPIO_PinSource5, NONE, NONE, TIM3, TIM_Channel_2, PIN_MODE_NONE, 0, 0 }, */
/* D3 - 03 { GPIOB, GPIO_Pin_4, GPIO_PinSource4, NONE, NONE, TIM3, TIM_Channel_1, PIN_MODE_NONE, 0, 0 }, */
/* D4 - 04 { GPIOB, GPIO_Pin_3, GPIO_PinSource3, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* D5 - 05 { GPIOA, GPIO_Pin_15, GPIO_PinSource15, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* D6 - 06 { GPIOA, GPIO_Pin_14, GPIO_PinSource14, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* D7 - 07 { GPIOA, GPIO_Pin_13, GPIO_PinSource13, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* NOT USED - 08 { NULL, NONE, NONE, NONE, NONE, NULL, NONE, NONE, NONE, NONE }, */
/* NOT USED - 09 { NULL, NONE, NONE, NONE, NONE, NULL, NONE, NONE, NONE, NONE }, */
/* A0 - 10 { GPIOC, GPIO_Pin_5, GPIO_PinSource5, ADC_Channel_15, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* A1 - 11 { GPIOC, GPIO_Pin_3, GPIO_PinSource3, ADC_Channel_13, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* A2 - 12 { GPIOC, GPIO_Pin_2, GPIO_PinSource2, ADC_Channel_12, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* DAC2, A3 - 13 { GPIOA, GPIO_Pin_5, GPIO_PinSource5, ADC_Channel_5, DAC_Channel_2, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* A4 - 14 { GPIOA, GPIO_Pin_6, GPIO_PinSource6, ADC_Channel_6, NONE, TIM3, TIM_Channel_1, PIN_MODE_NONE, 0, 0 }, */
/* A5 - 15 { GPIOA, GPIO_Pin_7, GPIO_PinSource7, ADC_Channel_7, NONE, TIM3, TIM_Channel_2, PIN_MODE_NONE, 0, 0 }, */
/* DAC, DAC1, A6 - 16 { GPIOA, GPIO_Pin_4, GPIO_PinSource4, ADC_Channel_4, DAC_Channel_1, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* WKP, A7 - 17 { GPIOA, GPIO_Pin_0, GPIO_PinSource0, ADC_Channel_0, NONE, TIM5, TIM_Channel_1, PIN_MODE_NONE, 0, 0 }, */
/* RX - 18 { GPIOA, GPIO_Pin_10, GPIO_PinSource10, NONE, NONE, TIM1, TIM_Channel_3, PIN_MODE_NONE, 0, 0 }, */
/* TX - 19 { GPIOA, GPIO_Pin_9, GPIO_PinSource9, NONE, NONE, TIM1, TIM_Channel_2, PIN_MODE_NONE, 0, 0 }, */
/* SETUP BUTTON - 20 { GPIOC, GPIO_Pin_7, GPIO_PinSource7, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* RGBR - 21 { GPIOA, GPIO_Pin_1, GPIO_PinSource1, NONE, NONE, TIM2, TIM_Channel_2, PIN_MODE_NONE, 0, 0 }, */
/* RGBG - 22 { GPIOA, GPIO_Pin_2, GPIO_PinSource2, NONE, NONE, TIM2, TIM_Channel_3, PIN_MODE_NONE, 0, 0 }, */
/* RGBB - 23 { GPIOA, GPIO_Pin_3, GPIO_PinSource3, NONE, NONE, TIM2, TIM_Channel_4, PIN_MODE_NONE, 0, 0 } */
#if PLATFORM_ID == 8 // P1
/* P1S0 - 24 ,{ GPIOB, GPIO_Pin_0, GPIO_PinSource0, ADC_Channel_8, NONE, TIM3, TIM_Channel_3, PIN_MODE_NONE, 0, 0 }, */
/* P1S1 - 25 { GPIOB, GPIO_Pin_1, GPIO_PinSource1, ADC_Channel_9, NONE, TIM3, TIM_Channel_4, PIN_MODE_NONE, 0, 0 }, */
/* P1S2 - 26 { GPIOC, GPIO_Pin_0, GPIO_PinSource0, ADC_Channel_10, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* P1S3 - 27 { GPIOC, GPIO_Pin_4, GPIO_PinSource4, ADC_Channel_14, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* P1S4 - 28 { GPIOC, GPIO_Pin_13, GPIO_PinSource13, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* P1S5 - 29 { GPIOC, GPIO_Pin_1, GPIO_PinSource1, ADC_Channel_11, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* P1S6 - 30 { GPIOA, GPIO_Pin_8, GPIO_PinSource8, NONE, NONE, TIM1, TIM_Channel_1, PIN_MODE_NONE, 0, 0 }, */
#endif

#if PLATFORM_ID == 10 // Electron
/* B0 - 24 ,{ GPIOC, GPIO_Pin_8, GPIO_PinSource8, NONE, NONE, TIM8, TIM_Channel_3, PIN_MODE_NONE, 0, 0 }, */
/* B1 - 25 { GPIOC, GPIO_Pin_6, GPIO_PinSource6, NONE, NONE, TIM8, TIM_Channel_1, PIN_MODE_NONE, 0, 0 }, */
/* B2 - 26 { GPIOB, GPIO_Pin_0, GPIO_PinSource0, ADC_Channel_8, NONE, TIM3, TIM_Channel_3, PIN_MODE_NONE, 0, 0 }, */
/* B3 - 27 { GPIOB, GPIO_Pin_1, GPIO_PinSource1, ADC_Channel_9, NONE, TIM3, TIM_Channel_4, PIN_MODE_NONE, 0, 0 }, */
/* B4 - 28 { GPIOC, GPIO_Pin_0, GPIO_PinSource0, ADC_Channel_10, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* B5 - 29 { GPIOC, GPIO_Pin_1, GPIO_PinSource1, ADC_Channel_11, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* C0 - 30 { GPIOD, GPIO_Pin_2, GPIO_PinSource2, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* C1 - 31 { GPIOC, GPIO_Pin_12, GPIO_PinSource12, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* C2 - 32 { GPIOC, GPIO_Pin_11, GPIO_PinSource11, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* C3 - 33 { GPIOC, GPIO_Pin_10, GPIO_PinSource10, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* C4 - 34 { GPIOB, GPIO_Pin_9, GPIO_PinSource9, NONE, NONE, TIM4, TIM_Channel_4, PIN_MODE_NONE, 0, 0 }, */
/* C5 - 35 { GPIOB, GPIO_Pin_8, GPIO_PinSource8, NONE, NONE, TIM4, TIM_Channel_3, PIN_MODE_NONE, 0, 0 }, */
/* TXD_UC - 36 { GPIOB, GPIO_Pin_10, GPIO_PinSource10, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* RXD_UC - 37 { GPIOB, GPIO_Pin_11, GPIO_PinSource11, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* RI_UC - 38 { GPIOB, GPIO_Pin_12, GPIO_PinSource12, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* CTS_UC - 39 { GPIOB, GPIO_Pin_13, GPIO_PinSource13, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* RTS_UC - 40 { GPIOB, GPIO_Pin_14, GPIO_PinSource14, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* PWR_UC - 41 { GPIOB, GPIO_Pin_2, GPIO_PinSource2, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* RESET_UC - 42 { GPIOC, GPIO_Pin_4, GPIO_PinSource4, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* LVLOE_UC - 43 { GPIOB, GPIO_Pin_15, GPIO_PinSource15, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* PM_SDA_UC - 44 { GPIOC, GPIO_Pin_9, GPIO_PinSource9, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* PM_SCL_UC - 45 { GPIOA, GPIO_Pin_8, GPIO_PinSource8, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
/* LOW_BAT_UC - 46 { GPIOC, GPIO_Pin_13, GPIO_PinSource13, NONE, NONE, NULL, NONE, PIN_MODE_NONE, 0, 0 }, */
#endif

const pin_t pins[] = {
A7,
#if PLATFORM_ID == 10
B3,
#endif
#if PLATFORM_ID == 8
P1S1,
#endif
A2,
D4,
D3,
D2,
D1,
BTN,
#if PLATFORM_ID == 10
B0,
#endif
TX,
RX,
#if PLATFORM_ID == 10
C2,
C1,
#endif
#if PLATFORM_ID == 8
P1S4,
#endif
D6,
D5
};

const char* pin_names[] = {
"A7",
#if PLATFORM_ID == 10
"B3",
#endif
#if PLATFORM_ID == 8
"P1S1",
#endif
"A2",
"D4",
"D3",
"D2",
"D1",
"SETUP button",
#if PLATFORM_ID == 10
"B0",
#endif
"TX",
"RX",
#if PLATFORM_ID == 10
"C2",
"C1",
#endif
#if PLATFORM_ID == 8
"P1S4"
#endif
"D6",
"D5"
};

const size_t pinCount = sizeof(pins)/sizeof(*pins);

InterruptMode mode[pinCount];

void setup() {
for (unsigned i = 0; i < sizeof(mode)/sizeof(*mode); i++) {
mode[i] = (pins[i] == BTN ? FALLING : (i % 2 == 0 ? RISING : FALLING));
}
}

void countdown(int c) {
Serial.printf("Going into STOP mode in ");
while (c > 0) {
Serial.printf("%d", c--);
delay(333);
Serial.print(".");
delay(333);
Serial.print(".");
delay(333);
}
}

void loop() {
waitUntil(Serial.isConnected);
Serial.println("Press any key to enter STOP mode");
Serial.println("You should be able to wake up your device using any of these pins:");
for (unsigned i = 0; i < sizeof(pins)/sizeof(*pins); i++) {
Serial.printlnf("%s: %s", pin_names[i], mode[i] == RISING ? "RISING" : "FALLING");
}
Serial.println();
Serial.println("The device will also automatically wake up after 60 seconds");
while(Serial.available() <= 0) {
Particle.process();
}
while(Serial.available() > 0) {
Serial.read();
}
countdown(3);
System.sleep(pins, pinCount, mode, pinCount, 60);
}