Eric_S,
I think 100uA is the limit for System_ON_Sleep. If you are looking for a lower current consumption, there is also a method called “System Off Sleep or Deep Sleep”. Search for “Deep Sleep” in this forum and you will find some useful threads.
@msfujino Hi, recently I achieved systemOn mode under the Mbed version, and the current is roughly 260 uA. But I am not sure if this value is correct (since on the NRF52840 datasheet, it also says system on mode with RAM costing 3 uA). Do you have any experience with that?
Hi Hao_Liu,
As you can see in post 1 and post 31, the sleep current for non-mbed using RTOS is less than 5uA. On the other hand, mbed is very disadvantageous with respect to sleep current reduction.
‘System_ON_Sleep of XIAO BLE’
‘System_ON_Sleep of XIAO BLE - #31 by msfujino’
Since Post 1, the following changes have been made to reduce the sleep current from 110uA to 26uA, and the battery state can be monitored for a long time.
- Instead of Sleep/Wake-up by RTC interrupt, use RTOS delay() which consumes less current.
- Do not let Flash sleep because we do not know how to recover from DeepPowerDown mode.
- Periodically display the battery voltage status with LEDs.
To recover the flash from DeepPowerDown, use the command 0xAB.
Reference:
PUYA P25Q16H p.44
Gigadevice GD25Q16C p.29
I’ve been working on this issue for about a month now, trying the command ABh, or command 66h,99h while measuring current with pppk2, but still can’t get it to release from DeepPowerDown. Maybe there is some condition that I have not thought of.
There is another example at the following link
‘Xiao nrf52 exit qspi flash deep sleep’
Do you mean after sending the command 0xAB, there is no change in the operating current and the flash also does not respond to further read/write operations?
0xAB is also a command to read the 8-bit electronic ID, below is not the exact code, just for illustration only:
SPI.transfer(0xAB);
SPI.transfer(0xFF);
SPI.transfer(0xFF);
SPI.transfer(0xFF);
byte id;
id = SPI.transfer(0xFF);
Could you verify if the flash accepts the command and returns the ID (0x14)?
Schematic description of the experiment so far,
#define PowerDownTime 285 // 285:OK 286:NG
flashTransport.runCommand(0xB9); // enter
delay(PowerDownTime);
flashTransport.runCommand(0xAB); // release
delay(500);
flashTransport.runCommand(0xB9); // enter
delay(PowerDownTime);
flashTransport.runCommand(0xAB); // release
delay(500);
flash.begin(&P25Q16H, 1); // initialize
If PowerDownTime is smaller than 285mS, it can be released; if it is larger than 286mS, it cannot be released. The current value is also measured, but if it cannot be released, an error occurs in flash.begin(). I can’t imagine why it is related to the length of DeepPowerDown at the moment.
The symptoms are strange. However since the pins are not exposed, probing with logic analyzer is not possible. Will need to run test codes specifically. By the way have you tried other libraries? I suppose there should be other libraries for generic serial/SPI flash on Github. We may also treat it as a simple SPI device and run SPI commands to test it.
Flash pin 1 => CS
Flash pin 2 => MISO
Flash pin 5 => MOSI
Flash pin 6 => SCLK
However I am unsure if the SPI port can be remapped.
The value of PowerDownTime when release is possible is not stable at all. However, if it is short, it can be released, and if it is long, it cannot be released. Somehow, it seems to be related to Serial.print().
I have ordered an external Flash so that the signal can be observed on a digital oscilloscope.
This is going to be a long term project.
An untested sketch which issues commands to the flash over SPI:
#include “SPI.h”
#include <Adafruit_TinyUSB.h>#define QSPI_IO3 29
#define QSPI_IO2 28
#define QSPI_IO1 27
#define QSPI_IO0 26
#define QSPI_SCK 24
#define QSPI_CS 25SPIClass SPI_2(NRF_SPIM2, QSPI_IO1, QSPI_SCK, QSPI_IO0);
void setup() {
Serial.begin(115200);
while ( !Serial ) delay(10);
Serial.println(“FLASH TESTING”);
pinMode(QSPI_CS, OUTPUT);
pinMode(QSPI_IO2, OUTPUT);
pinMode(QSPI_IO3, OUTPUT);
digitalWrite(QSPI_CS, HIGH);
digitalWrite(QSPI_IO2, HIGH);
digitalWrite(QSPI_IO3, HIGH);SPI_2.begin();
digitalWrite(QSPI_CS, LOW);
SPI_2.transfer(0xAB);
SPI_2.transfer(0xFF);
SPI_2.transfer(0xFF);
SPI_2.transfer(0xFF);
byte deviceID;
deviceID = SPI_2.transfer(0xFF);
digitalWrite(QSPI_CS, HIGH);
Serial.print("Device ID = ");
Serial.println(deviceID, HEX);SPI_2.end();
suspendLoop();
}
If it can print out the device ID then you may issue 0xB9, 0xAB, etc to see if it can wake up after deep sleep and perform read/write operation.
When I wrote directly in SPI, both “enter” and “release” worked. I also confirmed it with current. This is a report for now.
Maybe there is a problem with “flashTransport.runCommand()”. Because it often happens that this command hangs waiting for a response.
I will take some more time tomorrow to check.
The Adafruit library is too difficult for me. Anyway it supports QSPI mode and SPI mode. What if you use SPI mode and see if the results are the same?
//Adafruit_FlashTransport_QSPI flashTransport;
SPIClass SPI_2(NRF_SPIM2, PIN_QSPI_IO1, PIN_QSPI_SCK, PIN_QSPI_IO0);
Adafruit_FlashTransport_SPI flashTransport(PIN_QSPI_CS, SPI_2);
Adafruit_SPIFlash flash(&flashTransport);
I connected Flash externally and observed the SPI signal. This is still my imagination.
The roles of the three functions needed to send commands are
flashTransport.begin();
CS–>HIGH, CS–>LOW, OUT 0x05, IN StatusRegister, CS–>HIGH
flashTransport.runCommand();
CS–>LOW, OUT 0xAB, CS–>HIGH
flashTransport.end(); flashTransport.
CS–>OPEN
Flash only accepts command 0xAB if it is in Deep PowerDown mode.
See datasheet 10.30 Deep Power-down (DP)
“Once the DP instruction is set, all instructions will be ignored except the Release from Deep Power-down mode (RDP) and Read Electronic Signature (RES) instruction.”
The Adafruit library does not support either command 0xB9 or 0xAB. Flash may receive 0x05 and hang up.
SPI_2.transfer(0xAB); is working fine.
I have not yet gotten around to the tips and research you gave me.
I don’t have an external flash so I ran the test on a STM32 board with a Windbond memory chip. Although the test was in SPI mode, the same observation might appear in QSPI mode on nRF52840.
I used the “flash_speedtest” example sketch of Adafruit SPIFlash library. I noticed the clock was very strange. It was not steady and the duty cycle and speed varied drastically during the test. Below is the most “handsome” clock waveform and the speed was extremely low. Although the flash memory was recognized by the sketch, the erase test failed.
After changing the clock setting, the test passed and the clock waveform became much better.
flash.begin();
flashTransport.setClockSpeed(10000000, 10000000);
Would you change the speed and retry? nRF52840 supports up to 8MHz for SPI. I don’t know why the writing time looked more or less in the same range before and after changing the clock speed but at least the erase test passed. The library is beyond my capability to understand. Also the results from STM32 may not apply to nRF52840.
I spent all day today struggling with external Flash, but I only had more questions and did not get any good results.
The result is that both internal Flash and external Flash, DeepPowerDown mode works fine with SPI.transfer(), but not with flashTransport.runCommand(). I tried not outputting the command 0x05, which I was concerned about, and tried to make the SPI bus waveform the same as SPI.transfer(), but DeepPowerDown mode does not work.
The clock frequency was running at 2MHz until the initialization of release, begin, etc. and 16MHz after that.
The SerialFlash library you mentioned supports the DeepPowerDown command, so I loaded the Adafruit library with this as a reference, but it is too complicated for a holiday programmer.Tomorrow I will try to run the Adafruit library with SPI instead of QSPI.
Fortunately, the Adafruit library works fine if I use SPI.transfer() only with respect to DeepPowerDown.
Just take it easy, it is just a hobby anyway. Check this out. Go back to the basics and perhaps it can inspire you.
I don’t have the PPK2 with me but it seems the flash can accept the command regardless of QSPI or SPI mode.
#include <Adafruit_SPIFlash.h>
/*I have added Xiao flash chip to library so no need to define in the sketch*/
/*Map flash as QSPI, comment out below line if choose to map as SPI*/
//Adafruit_FlashTransport_QSPI flashTransport;
/*Map flash as custom SPI, comment out below 2 lines if choose to map as QSPI*/
SPIClass SPI_2(NRF_SPIM2, PIN_QSPI_IO1, PIN_QSPI_SCK, PIN_QSPI_IO0);
Adafruit_FlashTransport_SPI flashTransport(PIN_QSPI_CS, SPI_2);
Adafruit_SPIFlash flash(&flashTransport);
uint8_t three_byte_response[3] = {0};
void setup()
{
Serial.begin(115200);
while ( !Serial ) delay(10);
flash.begin();
/*Read ID*/
flashTransport.readCommand(0x9F, three_byte_response, 3);
Serial.print("Manufacture and Device ID before Sleep = ");
for (uint8_t k = 0; k < 3; k++)
{
Serial.print(three_byte_response[k], HEX);
Serial.print(" ");
}
Serial.println();
/*Clear response buffer*/
memset(three_byte_response, 0, sizeof(three_byte_response));
/*Enter deep sleep for 3s*/
flashTransport.runCommand(0xB9);
Serial.println("Flash enters deep sleep for 3s.");
delay(3000);
/*Release from deep sleep*/
flashTransport.runCommand(0xAB);
Serial.println("Flash wakes up.");
/*Read ID again*/
flashTransport.readCommand(0x9F, three_byte_response, 3);
Serial.print("Manufacture and Device ID after Sleep = ");
for (uint8_t k = 0; k < 3; k++)
{
Serial.print(three_byte_response[k], HEX);
Serial.print(" ");
}
Serial.println();
}
void loop()
{
// nothing to do
}
Tried QSPI and SPI modes with the Adafruit library and the SerialFlash library.
Both libraries could initialize the Flash and read the chip ID, but they did not respond to commands even though there were “0xB9” and “0xAB” signals on the SPI bus.
Then, when I use the SPI.transfer() function, it responds to the command as I want and I can use DeepPowerDown mode. Also, oddly enough, if the time between “enter” and “release” is short (less than 200mS), DPD mode works even with the Adafruit library.
I am almost out of my depth. I think this will be a theme to keep.