SWAN FlexPowerControl support?

I’m looking for examples or guidance on programming lower power (i.e. STOP mode) modes for the SWAN, to be awakened by external event interrupts or internal timer. Ideally with C++ on VS Code/PlatformIO programming environment.
Zak Fields “Sleepy sensor” approach of controlling the EN pin of a MCU doesn’t fit my application.
Thanks!

Hey @JimM,

The demos we have on our documentation mostly use the EN pin approach, but there are a few examples in the STM32duino GitHub repo that you might find useful: STM32LowPower/examples at main · stm32duino/STM32LowPower · GitHub.

Also, @zfields is at an event right now, but he’ll probably have some ideas when he gets back :slightly_smiling_face:

TJ

@tjvantoll TJ, thanks for the pointers to some STM32 examples!

@tjvantoll @zfields I am trying the stm32duino/STM32LowPower approach on the SWAN with some success. I am able to programmatically put the SWAN to sleep and have it awake by either a timer, or an event on a pin. However, upon awaking, the Serial.print statements no longer work as the serial port on the Swan does not seem to be reactivating upon being awoken. Other functions (reading pins, sending data to a radio module, etc. seem to execute fine, just an inactive serial port after being put to sleep and awoken). I am not using the deepSleep, just the “sleep” option. Thanks for getting me this far!

I also tried the “deepSleep” mode with same results of no serial port functionality upon reawakening the SWAN. Nice power reduction, but have yet to see how to reenable the USB serial port.

@tjvantoll @zfields Some followup on low power consumption of the SWAN. The STM32duino/STM32 Low Power library works with the SWAN. Interestingly, I get the same low level of current (~650-700 uA per Current Ranger with Battery power) for both the DeepSleep and ShutDown modes.

Correction. DeepSleep works, but the LowPower.shutdown function does NOT seem to put SWAN in any low power state.

Hey @JimM,

That’s super cool that you got that working, and thanks for sharing it here!

Can you share the minimal code snippet it takes to get that running, so I can play with it as well?

Thanks,
Zak

@zfields Sorry, I should have been more specific. For gauging the SWAN sleep power levels, I used the example code in the library STM32duino/STM32 Low Power. Specifically the TimedWakeup example and AlarmTimedWakeup . I am using PlatformIO extension in VS Code to upload to the SWAN, then power the SWAN via battery with Current Ranger. Note, using the library in my application (using C++ directly in VS Code), the serial monitor of VS Code fails to reconnect when the SWAN awakes from sleep. I had the same issue with PlatformIO or Arduino IDE. My suspicion is the SWAN serial port is not reactiving after sleeping?

The lowest SWAN power state I am seeing is 650-700 uA).

Hello,

We are using the SWAN in a low power application as well. We have also tried out the STM32duino/STM32 Low Power library but it is not working in deep sleep modes and outright does not support STOP modes on the L4 target.

Are there any example projects that demonstrate putting the SWAN into STOP mode in stm32cubeide or similar?

Thank you,

1 Like

Hi @jascha,

I don’t know if you’re using an STLink programmer, but deepSleep won’t work while it is connected. USB has to be unplugged, Swan has to be powered by a battery, and you must use a digitalWrite before you go into sleep mode to disable the Swan’s dedicated regulator that powers the 3V3 pin output.

Internally someone just sent me this code that works on Swan:

// This code is a modified version of the ExternalWakeup.ino example from the
// STM32LowPower Arduino library.

#include "STM32LowPower.h"

void setup() {
  // Set up LED.
  pinMode(LED_BUILTIN, OUTPUT);
  // Set up USER button.
  pinMode(USER_BTN, INPUT_PULLUP);
  // Configure low power.
  LowPower.begin();
  LowPower.attachInterruptWakeup(USER_BTN, NULL, RISING, DEEP_SLEEP_MODE);
}

void loop() {
  // Turn the LED on for a second.
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);

  // Enter deep sleep until the USER button is pressed again.
  LowPower.deepSleep();
}
1 Like

@RobLauer Please clarify how to disable the Swan’s dedicated 3V3 regulator. The only digitalWrite command I see in your shared example code is for the LED? Is just turning off the LED sufficient to disable the internal 3V3 pin regulator?

Hi @RobLauer

This example does not appear to disable the onboard regulators. We have modified the example below to shut down the regulators with the SWAN 3.0 device only connected to a battery. This configuration consumes about 33uA in the sleep state which is still not great. Do you have any examples that put the device into deeper sleep modes such as STOP or STOP2?

// This code is a modified version of the ExternalWakeup.ino example from the
// STM32LowPower Arduino library.

#include "STM32LowPower.h"

void setup() {
  // Set up LED.
  pinMode(LED_BUILTIN, OUTPUT);
  // Shut down Swan 3V3 regulator
  pinMode(PE4, OUTPUT);
  digitalWrite(PE4, LOW);
  // Set up USER button.
  pinMode(USER_BTN, INPUT_PULLUP);
  // Configure low power.
  LowPower.begin();
//   LowPower.attachInterruptWakeup(USER_BTN, NULL, RISING, DEEP_SLEEP_MODE);
}

void loop() {
  // Turn the LED on for a second.
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
//   delay(1000);

  // Enter deep sleep until the USER button is pressed again.
//   LowPower.deepSleep();
  // Enter deep sleep until timeout.
  LowPower.deepSleep(1000);
}
1 Like

You may find these links useful:
Swan schematic

Adafruit feather power spec

TPS62748YFPT

To disable the +3.3VDC regulator on an Adafruit Feather board, you can use the EN (enable) pin. This pin is connected to the enable input of the 3V3 regulator. By default, this pin is pulled high (enabled). The EN pin and GND pins on the SWAN are marked with silkscreen. You can solder a jumper wire between the two in order to “disable” the regulator

*Please note that disabling the 3.3V regulator will turn off the board’s microcontroller and all other onboard circuitry that relies on the 3.3V power rail. However, the BAT and USB pins will still be powered, allowing you to charge a connected LiPo battery while the board is off


The Notecard has a power management feature that allows you to regulate modem activity based on the available energy. It also offers a host power management feature that allows the Notecard to shut the host processor (SWAN or other) down completely for significant power savings.
This requires an additional physical connection between the Notecard and the host beyond the default I2C or Serial connection for communication.

Here is how you can put the Notecard into a low-power mode:

Sleep Mode
In this mode, the Notecard can hold data in memory on behalf of the host in the form of a Base64-encoded string. This is useful if nonvolatile memory is at a premium or nonexistent on the host. Here is an example of how to put the Notecard into sleep mode for 3600 seconds (1 hour):

   J *req = NoteNewRequest("card.attn");
   JAddStringToObject(req, "mode", "sleep");
   JAddNumberToObject(req, "seconds", 3600);
   JAddStringToObject(req, "payload", "ewogICJpbnRlcnZhbHMiOiI2MCwxMiwxNCIKfQ==");
   NoteRequest(req);

When the host reawakens, the payload is retrieved by setting start to true in a card.attn request:

   J *req = NoteNewRequest("card.attn");
   JAddBoolToObject(req, "start", true);
   NoteRequest(req);

We use our Notecard firmware to put the SWAN into STOP2 mode using RTC and have tested STOP2 mode (using RTC and GPIO wakeups) and verified that the current drain is ~8uA when in that mode AND when the onboard 3V3 regulator is manually shut down prior to entering sleep.

If you raise AUX-EN, this will wake the SWAN up from STOP2 mode.

If you poke around the forum a bit, I’m sure you’ll come across a few threads with Joulscope/CurrentRanger photos and additional related information to go along with it. I’ll be back (or someone will for me :P) to edit a thing or two above, but hopefully this is enough to point you in the right direction for now.

-Wojo

3 Likes

Hello @twojo ,

Thanks for the reply. However, there appear to be several points in your reply that I am not quite following.

  1. Regulator Details: You mentioned that disabling the main +3.3VDC regulator on the SWAN can be achieved through the EN (enable) pin. However, it’s important to note that the on-board regulator is actually more complex than just a 3.3V regulator. It’s a two-stage system featuring a 1.8V buck connected to the feather EN pin, followed by a 3.3V boost. Disabling this entire system using the EN pin would cut power to the whole microcontroller, thereby losing all volatile state stored in any sleep mode of the SWAN. This is completely separate from the auxiliary “3V3 OUT BUCKBOOST” which is controlled by the SWAN MCU on PE4 and not the feather EN pin, as shown in my above code example.

  2. Soldering EN to GND: On the subject of soldering a jumper wire between the EN pin and GND to disable the buck regulator—this would effectively shut off the microcontroller permanently, rendering it inoperable. It’s a step that should be avoided unless the objective is to fully disable the board.

  3. Notecard Sleep Mode: While the Notecard’s sleep mode is certainly interesting, the main focus for many users is likely to be putting the MCU into a low-power state, from which it can wake itself up and then interact with the Notecard. So, discussing sleep mode for the Notecard itself might not be directly pertinent to the objective of conserving power on the host MCU?

  4. SWAN deep sleep I am not following the mention of putting the SWAN into STOP2 using the notecard firmware? What firmware is being discussed and is there a link to it? Do you have any examples, besides what I provided above, that disable the auxiliary “3V3 OUT BUCKBOOST” during deep sleep?

Would it be possible to clarify concerning the above points, and provide further complete program source code examples as requested?

Thanks!

1 Like

@jascha have you taken a look at https://www.st.com/resource/en/application_note/an2606-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf

Those are excellent points! Thank you for correcting me. The TPS62748YFPT drops our VMAIN to +1V8
image

image

The SWAN’s STM32 MCU offers several sleep modes that can be used to reduce power consumption. Take a look at the STM32 Intro to Low Power documentation as a starting point.

Our note-stm32l4 provides an example of how to use the Notecard and the note-c library with the native STM32 SDK. This example also implements a working instance of the STM32’s extremely low-power STOP2 mode. *Please note that when you are in the debugger, the STM32 will never enter STOP2 mode, else the debugger would halt github.com :stuck_out_tongue: Please refer to our Note-C repo for additional info.

With SWAN, you can use the STM32Cube or STM32duino libraries to enter various low-power modes. Here’s an example of how to put the MCU into sleep mode:

#include "STM32LowPower.h"
void setup() {
  LowPower.begin();
}
void loop() {
  LowPower.sleep();
}

Configuring wakeup sources and reinitializing peripherals after waking up from a low-power mode in any STM32 MCU involves using various functions provided by the STM32 HAL library. Here’s an example (untested, obviously) config for external wakeup interrupt

// Assume that GPIO_PIN_X is connected to your external interrupt source
#define WAKEUP_PIN    GPIO_PIN_X

void setup() {
  // Initialize the wakeup pin as input with an interrupt
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = WAKEUP_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // Trigger interrupt on rising edge
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  // Enable and set EXTI line interrupt to the lowest priority
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 3, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

You might also find these links useful:

2 Likes