I am experimenting with external Flash.
The value changes to HIGH or LOW depending on the bus state, but when the command “0xB9” or “0xAB” is output, WP# is definitely HIGH and there should be no problem.
I think the difference is that when SPI.transfer() is used, WP# is definitely fixed to HIGH by digitalWrite().
How do you verify if the flash responds to the commands 0xB9 and 0xAB?
Does it respond to other single byte commands?
The DPD command is checked by measuring the current.
Other commands, for example, outputting “0x9F” returns the chip ID “0xEF4018”.
The QSPI driver was released by Nordic but it cannot wake the flash up after deep sleep, as stated here.
The driver used by Adafruit core was based on earlier Nordic SDK and it will be not fixed since Nordic has migrated the SDK to a new version nRF Connect.
It took some time to re-experiment and summarize the data, then I found the following
- runCommand() can enter but cannot release. However, if the sleep time is less than 200mS, it can be released.
- SPI.transfer() can enter and release with no problem.
My hypothesis is that XIAO sends “0x05” to Flash in DeepPowerDown mode and waits for a reply, but Flash ignores it and times out, as described in post 17.
I will now read the Nordic information more carefully.
nRF52_XIAO_LightSleep_enter_release_begin.zip (1.5 KB)
Since the oonboard Flash cannot observe waveforms, I connected an external Flash to observe waveforms.
Thanks MS for the elaboration.
Never have imagined that a few years old library still got a bunch of basic operation issues. Anyway a hobby is both frustration and fun hahaha.
The patch for now seems to be SPI.transfer().
I have had a lot of fun this past week.
MS since you have an external flash module, are you able to measure the current passing through the flash?
I am wondering if the high current is caused by nRF52840 but not the flash after sending the 0xB9 command and 0xAB command.
Could you also replace the release command 0xAB by reset command 0x66 + 0x99?
Each flashTransport.begin() will send command 0x05, could you only “begin” one time in your code?
void flashReset()
{
flashTransport.runCommand(0x66);
flashTransport.runCommand(0x99);
}
The external Flash is W25Q128JV (Winbond), connected via SPI, with unused WP and HOLD pins pulled up.
The current flowing into the VCC pin is measured.
The command sequence is:
flash.begin() -->enter–>release–>flash.begin().
- Using SPI.transfr(),
5.7uA–>0.26uA–>5.7uA–>5.7uA - Using runCommand(),
5.7uA–>300uA–>600uA–>5.7uA
External Flash does not seem to execute runCommand() correctly. - “0x66”,“0x99” is used instead of “0xAB”, the result is the same as 2.
As you have stated previously, you visually noticed correct commands sent to the flash regardless of SPI.transfer or runCommand.
I read the JEDEC ID before & after sleep/release and the flash behaved the same regardless of the 2 methods. This experiment makes me think the flash sleeps and wakes properly.
However it is really hard to explain the difference in its current consumption.
In post 6, I did not know how to release the internal Flash from DeepPowerDown mode (DPD), so I used it without DPD. As a result, the current during the sleep period only dropped to 26uA.
Since post 7, we have discussed how to release from DPD, and I have confirmed that Flash will release from DPD using SPIClass.
Also, the BME280 breakout board had a mounted LDO and level shifter, which consumed current, so I changed to a breakout board that did not have these mounted.
With these measures, I was able to reduce the sleep current to 5uA. I think this value is almost the limit of the project using SystemONSleep mode and RTOS.
nRF52_XIAO_LightSleep_BME280_FlashSleep_LED_delay.zip (3.4 KB)
I observed the waveforms of the external Flash when runCommand() is issued: In the case of the QSPI connection, “0x05” is added and the status register is read, as in “0x05”+“0xB9” and “0x05”+“0xAB”. In the case of SPI connection, however, “0x05” is not added and only “0xB9” and “0xAB” are observed.
In both cases, the enter or release command will cause a large current to flow through the external Flash. I have no idea why the behavior is different between onboard Flash and external Flash.
Also, I am wondering if it is possible to use QSPI connection for the external Flash since the onboard Flash is already connected to QSPI.
It seems only one instance of QPSI is supported but 3 instances for SPI.
However for those single byte commands, they are transmitted as standard SPI signals regardless of SPI.transfer or runCommand.
0x05 seems to be querying if the flash is busy or not and should not cause adverse effects.
Congratulations to your latest achievement in the current consumption. Although there are still unknown questions, your example provides a workaround to drive nRF52840 to its extreme performance, well done !!
I eventually got a development board and an external flash. However I did not see obvious difference sending the deep sleep and wake up commands with SPI transfer and Flash Transport. The flash seemed to sleep and wake up properly. However the working current using SPI transfer seemed to be much lower. The graphs below showed the current passing through the external flash chip.
Here are my test sketches.
Flash_test.zip (1.4 KB)
I did a reproduction experiment.
As you can see in the attached data, Enter and Release seemed to be executed properly and the current was almost the same as your measurements. However, there was a big difference in the current value after the third read ID. Also, my external Flash has a capacitor mounted between VCC and GND, so there seems to be a difference in the current waveform.
XIAO_nRF52840_extFlash.zip (1017.1 KB)
Thanks MS for the re-test. Indeed the waveforms of our measurements are very much different. I have noticed long time ago that your measurements were always less noisy. Are you always using the highest sampling rate for your measurements?
The increase of current after reading the ID the 3rd time is a mystery. I think your measurement shows a more reasonable value. I shall imitate your setup and retry.
The sampling rate is always 100k samples/sec.
I installed a 1uF ceramic capacitor, although it was a bit too large. I think the current waveform is different with and without the capacitor.
Thanks for the advice. After adding the 1uF capacitor, I can repeat the same waveform as your measurement.
Regarding the current after the 3rd read, if capacitor added it shows the same value (~5uA) as per delay period. Without the capacitor, the current is always ~200uA unless I suspend the loop. I am unable to explain this. I can only say current measurement under RTOS environment is tricky and is different from traditional measurement.
Since the bypass capacitor was not mounted on the Flash breakout board, I mounted 1uF without much thought. I never thought it would affect the operation of Flash in such a way!