From f7031738983c40c7e0497f91852b448551780cf3 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 25 Nov 2024 14:28:09 +0100 Subject: [PATCH 1/2] Add support for Nicla Vision --- .../Standby_WakeFromPin.ino | 4 +- .../Standby_WakeFromRTC_H7.ino | 2 +- .../Standby_WakeFromRTC_NiclaVision.ino | 61 +++++++++++++++++++ library.properties | 2 +- src/Board.cpp | 32 ++++++++-- src/Board.h | 6 +- 6 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 examples/Standby_WakeFromRTC_NiclaVision/Standby_WakeFromRTC_NiclaVision.ino diff --git a/examples/Standby_WakeFromPin/Standby_WakeFromPin.ino b/examples/Standby_WakeFromPin/Standby_WakeFromPin.ino index 3f27d41..497abc9 100644 --- a/examples/Standby_WakeFromPin/Standby_WakeFromPin.ino +++ b/examples/Standby_WakeFromPin/Standby_WakeFromPin.ino @@ -48,7 +48,7 @@ Board board; void setup() { // When uploading this sketch to the M4 core, it just goes to standby mode. - #if defined(ARDUINO_GENERIC_STM32H747_M4) + #if defined(CORE_CM4) board.standByUntilWakeupEvent(); return; #endif @@ -69,7 +69,7 @@ void setup() { // On Portenta C33, you can specify which pin to use to wake up the device from sleep mode // Please read the documentation to understand which pins can be used to wake up the device. board.enableWakeupFromPin(PORTENTA_C33_WAKEUP_PIN, FALLING); - #elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_GENERIC_STM32H747_M4) || defined(ARDUINO_NICLA_VISION) + #elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_GENERIC_STM32H747_M4) // On Portenta only pin GPIO0 can be used to wake up the device from sleep mode board.enableWakeupFromPin(); #endif diff --git a/examples/Standby_WakeFromRTC_H7/Standby_WakeFromRTC_H7.ino b/examples/Standby_WakeFromRTC_H7/Standby_WakeFromRTC_H7.ino index 8ac9f00..67ccf3f 100644 --- a/examples/Standby_WakeFromRTC_H7/Standby_WakeFromRTC_H7.ino +++ b/examples/Standby_WakeFromRTC_H7/Standby_WakeFromRTC_H7.ino @@ -33,7 +33,7 @@ void blinkLed(int ledPin, int delayTime = 1000){ void setup() { // When uploading this sketch to the M4 core, it just goes to standby mode. - #if defined(ARDUINO_GENERIC_STM32H747_M4) + #if defined(CORE_CM4) board.standByUntilWakeupEvent(); return; #endif diff --git a/examples/Standby_WakeFromRTC_NiclaVision/Standby_WakeFromRTC_NiclaVision.ino b/examples/Standby_WakeFromRTC_NiclaVision/Standby_WakeFromRTC_NiclaVision.ino new file mode 100644 index 0000000..774ddf5 --- /dev/null +++ b/examples/Standby_WakeFromRTC_NiclaVision/Standby_WakeFromRTC_NiclaVision.ino @@ -0,0 +1,61 @@ +/* +Standby Wake from RTC Demo for Nicla Vision +This example demonstrates how to wake up the Nicla Vision from standby mode using the included RTC (Real Time Clock). +The device will stay awake for ~5 seconds, then go to sleep for 10 second. When the device is awake you will see the board's blue LED turned on. +Effectively, you will get the same effect as with blink. + +The example also turns off the peripherals before going to sleep and turns them back on after waking up. +Usage: + - Make sure you are running the latest version of the Nicla Vision core. + - Select the Nicla Vision board from the Tools menu + - Select the Nicla Vision USB port from the Tools menu + - Upload the code to your Nicla Vision + +Note: You need to upload this sketch to both cores, the M7 and the M4 for it to work. + You can do so by selecting the M7 core and then the M4 core from the Tools menu in the "Target core" section. + +Initial authors: +Sebastian Romero (s.romero@arduino.cc) +*/ + +#include "Arduino_PowerManagement.h" + +Board board; + +void blinkLed(int ledPin, int delayTime = 1000){ + digitalWrite(ledPin, LOW); + delay(delayTime); + digitalWrite(ledPin, HIGH); + delay(delayTime); +} + +void setup() { + // When uploading this sketch to the M4 core, it just goes to standby mode. + #if defined(CORE_CM4) + board.standByUntilWakeupEvent(); + return; + #endif + + pinMode(LEDR, OUTPUT); // Used to indicate errors + digitalWrite(LEDR, HIGH); // Turn off the red LED + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); // Turn on the built-in LED to show that the board is awake + + if(!board.begin()){ + // If the board fails to initialize, it will blink the red LED + while (true){ + blinkLed(LEDR); + } + } + + delay(10000); // keep the board awake for 10 seconds, so we can se it working + board.shutDownFuelGauge(); + + // The LED should go off when the board goes to sleep + board.setAllPeripheralsPower(false); + + board.enableWakeupFromRTC(0, 0, 10); // Go to standby for 10 seconds + board.standByUntilWakeupEvent(); +} + +void loop() {} \ No newline at end of file diff --git a/library.properties b/library.properties index d0f62ae..8109a74 100644 --- a/library.properties +++ b/library.properties @@ -8,4 +8,4 @@ category=Device Control url=https://github.com/arduino-libraries/Arduino_PowerManagement architectures=renesas_portenta, mbed_portenta, mbed_nicla includes=Arduino_PowerManagement.h -depends=Arduino_PF1550,Arduino_LowPowerPortentaC33,Arduino_LowPowerPortentaH7 \ No newline at end of file +depends=Arduino_PF1550,Arduino_LowPowerPortentaC33,Arduino_LowPowerPortentaH7,Arduino_LowPowerNiclaVision \ No newline at end of file diff --git a/src/Board.cpp b/src/Board.cpp index 3182aad..e614242 100644 --- a/src/Board.cpp +++ b/src/Board.cpp @@ -58,7 +58,7 @@ Board::~Board() { } bool Board::begin() { - #if defined(ARDUINO_PORTENTA_H7_M7) + #if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) if (CM7_CPUID == HAL_GetCurrentCPUID()){ if (LowPowerReturnCode::success != LowPower.checkOptionBytes()){ LowPower.prepareOptionBytes(); @@ -146,7 +146,7 @@ bool Board::enableWakeupFromRTC(uint32_t hours, uint32_t minutes, uint32_t secon #endif -#if defined(ARDUINO_PORTENTA_H7) +#if defined(ARDUINO_PORTENTA_H7) || defined(ARDUINO_NICLA_VISION) bool Board::enableWakeupFromRTC(uint32_t hours, uint32_t minutes, uint32_t seconds){ standbyType |= StandbyType::untilTimeElapsed; wakeupDelayHours = hours; @@ -165,9 +165,9 @@ void Board::sleepUntilWakeupEvent(){ void Board::standByUntilWakeupEvent(){ #if defined(ARDUINO_PORTENTA_C33) lowPower -> deepSleep(); - #elif defined(ARDUINO_GENERIC_STM32H747_M4) + #elif defined(CORE_CM4) LowPower.standbyM4(); - #elif defined(ARDUINO_PORTENTA_H7_M7) + #elif defined(ARDUINO_PORTENTA_H7_M7) RTCWakeupDelay rtcWakeupDelay = RTCWakeupDelay(wakeupDelayHours, wakeupDelayMinutes, wakeupDelaySeconds); if(standbyType == StandbyType::untilEither) LowPower.standbyM7(LowPowerStandbyType::untilPinActivity | LowPowerStandbyType::untilTimeElapsed, rtcWakeupDelay); @@ -175,6 +175,9 @@ void Board::standByUntilWakeupEvent(){ LowPower.standbyM7(LowPowerStandbyType::untilPinActivity); else if (standbyType == StandbyType::untilTimeElapsed) LowPower.standbyM7(LowPowerStandbyType::untilTimeElapsed, rtcWakeupDelay); + #elif defined(ARDUINO_NICLA_VISION) && defined(CORE_CM7) + RTCWakeupDelay rtcWakeupDelay = RTCWakeupDelay(wakeupDelayHours, wakeupDelayMinutes, wakeupDelaySeconds); + LowPower.standbyM7(rtcWakeupDelay); #endif } @@ -185,7 +188,7 @@ void Board::setAllPeripheralsPower(bool on){ this -> setCommunicationPeripheralsPower(on); this -> setExternalPowerEnabled(on); this -> setAnalogDigitalConverterPower(on); - #else if defined(ARDUINO_PORTENTA_H7) + #elif defined(ARDUINO_PORTENTA_H7) // On the H7 several chips need different voltages, so we cannot turn the lanes that are dependent on each other separately. // This should only be used when going into standby mode, as turning off the USB-C PHY, Ethernet or Video bridge might cause undefined behaviour. if(on){ @@ -199,6 +202,23 @@ void Board::setAllPeripheralsPower(bool on){ PMIC.getControl() -> turnLDO3Off(Ldo3Mode::Normal); PMIC.getControl() -> turnSw1Off(Sw1Mode::Normal); } + + #elif defined(ARDUINO_NICLA_VISION) + if(on){ + PMIC.getControl() -> turnLDO2On(Ldo2Mode::Normal); // Camera + PMIC.getControl() -> turnLDO1On(Ldo1Mode::Normal); // ToF sensor / Camera + PMIC.getControl() -> turnLDO3On(Ldo3Mode::Normal); // VDDA - Analog components, e.g. ADC + PMIC.getControl() -> turnSw2On(Sw2Mode::Normal); // USB, 25 MHz crystal, 32 kHz crystal + // TODO: Not supported yet by PMIC library + // PMIC.getControl() -> turnSw3On(Sw3Mode::Normal); // External power VDDIO_EXT + } else { + PMIC.getControl() -> turnLDO2Off(Ldo2Mode::Normal); // Camera + PMIC.getControl() -> turnLDO1Off(Ldo1Mode::Normal); // ToF sensor / Camera + PMIC.getControl() -> turnLDO3Off(Ldo3Mode::Normal); // VDDA - Analog components, e.g. ADC + PMIC.getControl() -> turnSw2Off(Sw2Mode::Normal); // USB, 25 MHz crystal, 32 kHz crystal + // TODO: Not supported yet by PMIC library + // PMIC.getControl() -> turnSw3Off(Sw3Mode::Normal); // External power VDDIO_EXT + } #endif } // @@ -270,7 +290,7 @@ bool Board::setReferenceVoltage(float voltage) { void Board::shutDownFuelGauge() { #if defined(ARDUINO_PORTENTA_C33) MAX1726Driver fuelGauge(&Wire3); - #elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_GENERIC_STM32H747_M4) + #elif defined(ARDUINO_PORTENTA_H7) MAX1726Driver fuelGauge(&Wire1); #elif defined(ARDUINO_NICLA_VISION) MAX1726Driver fuelGauge(&Wire1); diff --git a/src/Board.h b/src/Board.h index 0209427..22c03c0 100644 --- a/src/Board.h +++ b/src/Board.h @@ -17,6 +17,8 @@ // but in this library we can turn of the Ethernet interface using the PMIC, so we set the NO_ETHERNET_TURN_OFF flag to avoid turning off the Ethernet interface from both sides. #define NO_ETHERNET_TURN_OFF #include "Arduino_LowPowerPortentaH7.h" +#elif defined(ARDUINO_NICLA_VISION) + #include "Arduino_LowPowerNiclaVision.h" #endif #define CONTEXT_LDO2 2 // LDO regulator: 1.8 V to 3.3 V, 400 mA @@ -110,7 +112,9 @@ class Board { * The pin is only accessible via high-density connectors. */ void enableWakeupFromPin(); + #endif + #if defined(ARDUINO_PORTENTA_H7) || defined(ARDUINO_NICLA_VISION) /** * Enables sleep mode when the board is idle. */ @@ -153,7 +157,7 @@ class Board { bool enableWakeupFromRTC(uint32_t hours, uint32_t minutes, uint32_t seconds, RTClock * rtc = &RTC); #endif - #if defined(ARDUINO_PORTENTA_H7) + #if defined(ARDUINO_PORTENTA_H7) || defined(ARDUINO_NICLA_VISION) /** * Enables wake-up of the device from the RTC. * @param hours The number of hours to sleep. From f4ac3795e1f3f81396cbdcc1a511047c67fd498f Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 25 Nov 2024 14:31:52 +0100 Subject: [PATCH 2/2] Fix compile examples workflow --- .github/workflows/compile-examples.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 5ee2080..ed6f331 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -59,6 +59,8 @@ jobs: platforms: | - name: arduino:mbed_nicla artifact-name-suffix: arduino-mbed_nicla-nicla_vision + additional-sketch-paths: | + - examples/Standby_WakeFromRTC_NiclaVision steps: - name: Checkout repository @@ -74,7 +76,8 @@ jobs: - source-path: ./ - name: Arduino_PF1550 - name: Arduino_LowPowerPortentaH7 - - source-url: https://github.com/arduino-libraries/Arduino_LowPowerPortentaC33.git + - name: Arduino_LowPowerPortentaC33 + - source-url: https://github.com/arduino-libraries/Arduino_LowPowerNiclaVision.git sketch-paths: | ${{ env.UNIVERSAL_SKETCH_PATHS }} ${{ matrix.board.additional-sketch-paths }}