Seeed Studio Grove Base for XIAO (SPI Solution) SUCCESS!

This is a Very Nice board (maybe)


and I recommend anyone planning on getting started use this.
(or if you want the other AWESOME expansion board with display) Expansion Board Base for XIAO
That being said.

To whom it may concern,

The link for documentation is broken in the WIKI? Can someone fix that and provide me the Proper documentation link and/or schematic, etc.
I need to know 2 things:

  1. What is the part no. for the SOIC SPI FLASH chip on the Bottom. Please provide ALL pertinent information for implementing this feature.
  2. is it possible to read the battery level of the, “on-board battery management chip and battery bonding pad, you could easily power your Seeed Studio XIAO with lithium 3.7V battery and recharge it, making your projects, especially wearables ones, more flexible and in portable”

I look forward to your replies and wait with baited breath to explore the product and claims, Gladly providing my test results to the forum.

GL :slight_smile: PJ
:pray:

So , I figured I’d print a holder with the battery bellow,

Rev2 is stretched longer to accomodate a display
Waiting on the answer of the chip part no# and a couple questions so why not :smile:
BUMP
GL :slight_smile: PJ

Grabbed (3) more. :wink: :ok_hand:


and my cat is eyeing that grove push-button :smile: :v:


GL :slight_smile: PJ

Hello… Need to know below?
TIA :grin:

Hi, I’m sorry I’m late.

Thank you very much for your feedback. We will update the Wiki as soon as possible. Here is the link to the file you requested: https://files.seeedstudio.com/wiki/Grove-Shield-for-Seeeduino-XIAO/res/Grove_Shield_for_Seeeduino_XIAO_v1.0.rar

In fact, there is an online schematic preview in the wiki.

  1. Regarding the SOIC SPI FLASH chip you mentioned, I will need to search the files about datasheet before getting back to you.
  2. Currently, this product cannot read the battery level. It does not have a built-in battery gauge.

We greatly appreciate your enthusiasm for our product!

Great, Thank you. Looking forward to adding a flash chip to it.
the online viewer works well.
GL :slight_smile: PJ

Hello,

I understand that currently the Flash chip is not pre-installed on the Grove Base for XIAO. And I’m sorry to tell you that there are no current plans to add at the factory.

According to the online documentation, the specific Flash chip used in that location is the W25X80.

1 Like

Hi there, Yes Thank you I have ordered a couple to try.
:wink: :+1:
GL :slight_smile: PJ

1 Like

Hi there,
Just to share I have received the flash chips and as soon as I solder it on I’ll post the results.




HTH
GL :slight_smile: PJ

Got ut soldered up, did two units, wonder if i need the pull up resistor for the CS, anyone have an idea on how to test its jedec type id.
Can’t seem to read anything from it, but on-board 2M QSPI shows up ?
aok.?




So board layout has is as DNP… Do Not Populate.

I added the chip to the flashDevice.h file and the Base file too.(attached files)
It compiles but no chip is Identified. I’ll break out the scope and check the CS,
Any advice on which SPI lib works the best. SPIMemory.h or, adafruit_SPIflash.h

Too bad no examples exist on the wiki, the W25Q80DV: 8M-bit/1M-byte (1,048,576) Flash memory with current consumption as low as 1µA for power-down. ADDS a big BUMP in space for Grove ready projects. Who needs an SD card. :innocent:
HTH
GL :slight_smile: PJ
flash_devices&SPIFlashBase.zip (7.8 KB)

This code runs, but I can’t get the second EXTERNAL flash with the A1/D1(pin2) as CS
to go or show ? ANy suggestions please? The Adafruit_SPIFlash library is difficult to understand IMO
I can’t seem to get any other SPI’s to go i.e. SPI1 or SPI2 or 3 .

This code works on the External Onboard 2 Meg Flash .

// Adafruit SPI Flash Example
// Author: PJG
//
//----------------------------------------------------------------------------------------------
// BSP : Seeed nRF52 Borads 1.1.1
// Board : Seeed nRF52 Borads / Seeed XIAO nRF52840 Sense
//----------------------------------------------------------------------------------------------
// SdFat - Adafruit Fork@2.2.1
// Adafruit SPIFlash@4.3.0
//
// Tested AOK onboard External Flash.
// 12/9/2023 

#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_SPIFlash.h>

const int chipSelect = 2;  // CS pin for Expansionflash on Grove PCboard
#define expFlashCS D1
// Built from the P25Q16H datasheet.
// https://gitlab.com/arduino5184213/seeed_xiao_nrf52840/flash_speedtest/-/tree/master
SPIFlash_Device_t const P25Q16H {
  .total_size = (1UL << 21), // 2MiB
  .start_up_time_us = 10000, // Don't know where to find that value
  .manufacturer_id = 0x85,
  .memory_type = 0x60,
  .capacity = 0x15,
  .max_clock_speed_mhz = 55,
  .quad_enable_bit_mask = 0x02, // Datasheet p. 27
  .has_sector_protection = 1,   // Datasheet p. 27
  .supports_fast_read = 1,      // Datasheet p. 29
  .supports_qspi = 1,           // Obviously
  .supports_qspi_writes = 1,    // Datasheet p. 41
  .write_status_register_split = 1, // Datasheet p. 28
  .single_status_byte = 0,      // 2 bytes
  .is_fram = 0,                 // Flash Memory
};


Adafruit_FlashTransport_QSPI flashTransport;
Adafruit_SPIFlash flash(&flashTransport);

void setup() {
  
  while (!Serial) delay(2100);
  
  Serial.println(F("SPI Flash ID"));
  pinMode(2, OUTPUT); // set CS as output in lew of DNP on board, teting with and with out.

  // Initialize flash library and check its chip ID.
  if (!flash.begin(&P25Q16H, 1)) {
    Serial.println(F("Error, failed to initialize flash chip!"));
    while(1) yield();
  }

  Serial.print(F("Flash chip JEDEC ID: 0x")); Serial.println(flash.getJEDECID(), HEX);
  Serial.print(F("Flash size: ")); Serial.print(flash.size() / 1024); Serial.println(F(" KB"));
  Serial.println(F("Flash chip successfully ID'd!"));

}

void loop() {
  // Nothing to be done in the main loop.
}

here’s the output;

SPI Flash ID
Flash chip JEDEC ID: 0x856015
Flash size: 2048 KB
Flash chip successfully ID'd!

TIA :wink: :v:
GL :slight_smile: PJ

Hi so,
Now it looks like an SPI issue?
Any input from the great Hive mind here :wink: :v:

// Adafruit Grand Central M4 QSPI Flash and SD Card Setup Example
// Author: Joshua Scoggins
//
// This is an example of how to bring up both the QSPI Flash and SD Card found
// on the Adafruit Grand Central M4. This example will setup both the QSPI
// Flash and SD card (if present) and display information about the QSPI flash.
//

#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_SPIFlash.h>


// for flashTransport definition
#include "flash_config.h"

Adafruit_SPIFlash onboardFlash(&flashTransport);
SdFat onboardSdCard;

SPIClass SPI_2(NRF_SPIM2, D9, D8, D10);   // MISO, SCK, MOSI
Adafruit_FlashTransport_SPI expflashTransport(2, &SPI_2);
Adafruit_SPIFlash expFlash(&expflashTransport);
constexpr int getSDCardPin() noexcept {
#ifdef SDCARD_SS_PIN
  return SDCARD_SS_PIN;
#else
  // modify to fit your needs
  // by default, pin 4 is the SD_CS pin used by the Adafruit 1.8" TFT SD Shield
  return 4;
#endif
}
void setup() {
  pinMode(D1, OUTPUT);        // CS
  digitalWrite(D1, HIGH);
    Serial.begin(9600);
  while (!Serial) {
    // wait for native usb
    delay(2100);
  }
 Serial.print("Starting up onboard QSPI Flash...");
  onboardFlash.begin(&P25Q16H,1);
  Serial.println("Done");
  Serial.println("Onboard Flash information");
  Serial.print("JEDEC ID: 0x");
  Serial.println(onboardFlash.getJEDECID(), HEX);
  Serial.print("Flash size: ");
  Serial.print(onboardFlash.size() / 1024);
  Serial.println(" KB");
 Serial.print("Starting up Grove Expansion SPI Flash...");
  //expFlash.begin(&W25Q80DV,1);
  Serial.println("Done");
  Serial.println("Expansion board Flash information");
  Serial.print("JEDEC ID: 0x");
  Serial.println(expFlash.getJEDECID(), HEX);
  Serial.print("Flash size: ");
  Serial.print(expFlash.size() / 1024);
  Serial.println(" KB");
  Serial.print("Starting up SD Card...");
  if (!onboardSdCard.begin(getSDCardPin())) {
    Serial.println("No card found (is one inserted?)");
  } else {
    Serial.println("Card found!");
  }
}

void loop() {
  // nothing to do
}

No go? here’s the output.

Adafruit SPI Flash FatFs Format Example
Error, failed to initialize flash chip!

Thank you in advance for your support.
GL :slight_smile: PJ

flash_config.h—below—

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2022 Ha Thach (tinyusb.org) for Adafruit Industries
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef FLASH_CONFIG_H_
#define FLASH_CONFIG_H_

SPIFlash_Device_t const P25Q16H {
  .total_size = (1UL << 21), // 2MiB
  .start_up_time_us = 10000, // Don't know where to find that value
  .manufacturer_id = 0x85,
  .memory_type = 0x60,
  .capacity = 0x15,
  .max_clock_speed_mhz = 55,
  .quad_enable_bit_mask = 0x02, // Datasheet p. 27
  .has_sector_protection = 1,   // Datasheet p. 27
  .supports_fast_read = 1,      // Datasheet p. 29
  .supports_qspi = 1,           // Obviously
  .supports_qspi_writes = 1,    // Datasheet p. 41
  .write_status_register_split = 1, // Datasheet p. 28
  .single_status_byte = 0,      // 2 bytes
  .is_fram = 0,                 // Flash Memory
};

/*SPIFlash_Device_t const W25Q80DV {
  .total_size = (1UL << 20), // 2MiB
  .start_up_time_us = 5000, // Don't know where to find that value
  .manufacturer_id = 0xEF,
  .memory_type = 0x40,
  .capacity = 0x14,
  .max_clock_speed_mhz = 104,
  .quad_enable_bit_mask = 0x02, // Datasheet p. 27
  .has_sector_protection = 0,   // Datasheet p. 27
  .supports_fast_read = 1,      // Datasheet p. 29
  .supports_qspi = 1,           // Obviously
  .supports_qspi_writes = 0,    // Datasheet p. 41
  .write_status_register_split = 0, // Datasheet p. 28
  .single_status_byte = 0,      // 2 bytes
  .is_fram = 0,                 // Flash Memory
};
*/

// Un-comment to run example with custom SPI and SS e.g with FRAM breakout
//#define CUSTOM_CS D1
//#define CUSTOM_SPI SPI

#if defined(CUSTOM_CS) && defined(CUSTOM_SPI)
Adafruit_FlashTransport_SPI expflashTransport(CUSTOM_CS, CUSTOM_SPI);

#elif defined(ARDUINO_ARCH_ESP32)

// ESP32 use same flash device that store code for file system.
// SPIFlash will parse partition.cvs to detect FATFS partition to use
Adafruit_FlashTransport_ESP32 flashTransport;

#elif defined(ARDUINO_ARCH_RP2040)

// RP2040 use same flash device that store code for file system. Therefore we
// only need to specify start address and size (no need SPI or SS)
// By default (start=0, size=0), values that match file system setting in
// 'Tools->Flash Size' menu selection will be used.
Adafruit_FlashTransport_RP2040 flashTransport;

// To be compatible with CircuitPython partition scheme (start_address = 1 MB,
// size = total flash - 1 MB) use const value (CPY_START_ADDR, CPY_SIZE) or
// subclass Adafruit_FlashTransport_RP2040_CPY. Un-comment either of the
// following line:
//  Adafruit_FlashTransport_RP2040
//    flashTransport(Adafruit_FlashTransport_RP2040::CPY_START_ADDR,
//                   Adafruit_FlashTransport_RP2040::CPY_SIZE);
//  Adafruit_FlashTransport_RP2040_CPY flashTransport;

#else

// On-board external flash (QSPI or SPI) macros should already
// defined in your board variant if supported
//EXTERNAL_FLASH_USE_QSPI
//EXTERNAL_FLASH_USE_CS
//EXTERNAL_FLASH_USE_SPI


#if defined(EXTERNAL_FLASH_USE_QSPI)

Adafruit_FlashTransport_QSPI flashTransport;

#elif defined(EXTERNAL_FLASH_USE_SPI)

Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS,
                                           EXTERNAL_FLASH_USE_SPI);

#elif defined(__AVR__)

// Use stand SPI/SS for avr port.
// Note cache will be disable due to lack of memory.

Adafruit_FlashTransport_SPI flashTransport(SS, SPI);

#else
#error No (Q)SPI flash are defined for your board !
#endif

#endif

#endif

:man_bowing:

I’m sorry to keep you wait. I will ask my colleague for more details and contact you as soon as I have any results

1 Like

I wish i could help boss, but i got no experience on this one… but keep up the good work!

1 Like

Hello,
I have confirmed with my colleagues that this DNP pad has been tested and the flash chip functionality is working.
Here is the code we used to test the flash chip functionality. Perhaps you can give it a try.
grove_base_for_xiao-FLASH.rar (36.8 KB)

Hello There, Seeed_Seraphina… :smile:
Thank you for providing me the library and examples. However there was no Flash profile present for the W25Q80DV that was needed by SFUD_FLASH_CHIP_TABLE for any of the examples to work.
However, I was able after much trial and error , many cups of coffee and some minor epiphanies along the way. Discover the original "Serial Flash Universal Driver " library that the Seeed SFUD 1.0.0 version is based on, and has some hints on the configuration not in the Seeed Version.
I was able to add the lines to the necessary files, i.e the Type of flash installed/ called out does NOT support the SFUD_SFDP and will give errors if enabled by default.

{"W25Q80BV", SFUD_MF_ID_WINBOND, 0x40, 0x14, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},

the above was added to the Flash_chip_table. and some adds to the sfud_cfg header.
I’m attaching the same ARChive in Zip format with all the edits included and working with this Hardware.
grove_base_for_xiao-FLASH.zip (32.4 KB)

As a BONUS I was able to also unravel the mystery (at least to me) how the Xiao and Nordic map the SPI and QSPI interfaces as related to the NRF_SPIMx . and adafruit_SPIFlash.h WOW what a spin Cycle.
The Included Flash speed test verifies the operation of Both Onboard QSPI flash and The Expansion board SPI flash. (uncomment).Includes “flash_devices.h” with w25Q80dv added.
Sketch_grove_flash_speedTest.zip (5.8 KB)
Last item is Basic test to identify and check if flash works. with output and compiler info.

// 12/16/2023  Grove Expansion Board Flash Chip Test Code //
// // Adafruit_SPIFlash Example
// Author: PJG
//
//----------------------------------------------------------------------------------------------
// BSP : Seeed nRF52 Boards 1.1.1
// Board : Seeed XIAO nRF52840 Sense
//----------------------------------------------------------------------------------------------
// SdFat - Adafruit Fork@ 2.2.3
// Adafruit SPIFlash@ 4.1.3
// Adafruit TinyUSB Library@1.7.0
//
// This tests and Identifies the Onboard Xiao QSPI Flash Chip 
// and Expansion Flash Chip on Grove Board Hardwired to A1/D1 (pin 1) on Xiao 
// for the Flash chipSelect CS or SS 
// Adafruit_SPIFlash is set with SPI class mthod. You can mix QSPI mode and SPI class are possible.
// The trick is the Nordic NRF_SPIM0, NRF_SPIM1, NRF_SPIM2, NRF_SPIM3 for which mode or method.
// HTH
// 

#include <Wire.h>
#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_SPIFlash.h>

SPIFlash_Device_t const p25q16h {   // You can Declare the chip you choose this way or add it to the flash_devices
  // Configuration for W25Q80DV flash chip from the Data Sheet.
  .total_size = (1UL << 21), // 2MiB
  .start_up_time_us = 10000,
  .manufacturer_id = 0x85,
  .memory_type = 0x60,
  .capacity = 0x15,
  .max_clock_speed_mhz = 55,
  .quad_enable_bit_mask = 0x02,
  .has_sector_protection = 1,
  .supports_fast_read = 1,
  .supports_qspi = 1,
  .supports_qspi_writes = 1,
  .write_status_register_split = 1,
  .single_status_byte = 0,
  .is_fram = 0,
};
SPIFlash_Device_t const w25q80 {  // Also seemsto be case sensative lower case preferred
  // Configuration for W25Q80DV flash chip from the Data Sheet.
  .total_size = (1UL << 20), // 1MiB
  .start_up_time_us = 5000,
  .manufacturer_id = 0xEF,
  .memory_type = 0x40,
  .capacity = 0x14,
  .max_clock_speed_mhz = 104,
  .quad_enable_bit_mask = 0x02, 
  .has_sector_protection = 0,  
  .supports_fast_read = 1,     
  .supports_qspi = 1,           
  .supports_qspi_writes = 0,    
  .write_status_register_split = 0, 
  .single_status_byte = 0,     
  .is_fram = 0,                 
};

#define SS_SPI0 1  // seems to default to Pin 7 if you don't declare it as the CS for the Flash Chip A1/D1 pin1 on the Xiao
#define SS_SPI1 25

SPIClass SPI_2(NRF_SPIM0, PIN_QSPI_IO1, PIN_QSPI_SCK, PIN_QSPI_IO0); // Onboard QSPI Flash chip
Adafruit_FlashTransport_SPI QflashTransport(PIN_QSPI_CS, SPI_2);     // CS for QSPI Flash

Adafruit_SPIFlash Qflash(&QflashTransport);

SPIClass SPI_1(NRF_SPIM3, D9, D8, D10);   // MISO, SCK, MOSI /EXPANSION FLASH// CS pin D1 (hardwired)
Adafruit_FlashTransport_SPI EflashTransport(SS_SPI0, SPI_1);  // Flash Type

Adafruit_SPIFlash Eflash(&EflashTransport); 


void setup() {
  Serial.begin(9600);
  while (!Serial) delay(2100);
  
  Serial.println();
  Serial.println(" Program " __FILE__ " compiled on " __DATE__ " at " __TIME__ );
  Serial.println("----RESET----");
  pinMode(D6, INPUT_PULLUP);  // /WP
  pinMode(D7, INPUT_PULLUP);  // /HOLD
  pinMode(SS_SPI0, OUTPUT); // CS for flash
  digitalWrite(SS_SPI0, HIGH); // <-- Set CS pin HIGH to deselect
  
  Serial.println("--------------");
  Serial.println(SS_SPI0);
  Serial.println(MOSI); // master out, slave in
  Serial.println(MISO); // master in, slave out
  Serial.println(SCK);  // clock
  Serial.println("--------------");

  Serial.println("Onboard QSPI Flash Testing");
  Serial.println(F("QSPI Flash ID P25Q16H"));
   // Initialize QSPI flash library and check its chip ID.
 if (!Qflash.begin(&p25q16h, 1)) {
   Serial.println(F("Error, failed to initialize QSPI flash chip!"));
   while(1);
  }
  Serial.print(F("QFlash chip JEDEC ID: 0x")); Serial.println(Qflash.getJEDECID(), HEX);
  Serial.print(F("Flash size: ")); Serial.print(Qflash.size() / 1024); Serial.println(F(" KB"));
  Serial.println(F("QFlash chip successfully ID'd!"));
  delay (1500);
  Serial.println();
  Serial.println("Expansion Flash testing!!");
  digitalWrite(SS_SPI0, HIGH); // <-- Set CS pin HIGH to deselect
  Serial.println(F("SPI Flash ID W25Q80DV"));
   // Initialize W25Q80DV flash library and check its chip ID.
 if (!Eflash.begin(&w25q80)) {
   Serial.println(F("Error, failed to initialize W25Q80DV flash chip!"));
   while(1);
  }
  Serial.print(F("W25Q80DV chip JEDEC ID: 0x")); Serial.println(Eflash.getJEDECID(), HEX);
  Serial.print(F("Flash size: ")); Serial.print(Eflash.size() / 1024); Serial.println(F(" KB"));
  Serial.println(F("SPI Flash chip successfully ID'd!"));
  
}

void loop() {
//delay(500); // Your code here
}

compiler output.

Zip created at C:\Users\Dude\AppData\Local\Temp\arduino\sketches\A25B9D6E2C523EB8A1B4ECDC58048CC7/GroveFlash_Final.ino.zip

Using library Wire at version 1.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\Wire 
Using library SPI at version 1.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\SPI 
Using library SdFat - Adafruit Fork at version 2.2.3 in folder: D:\Arduino_projects\libraries\SdFat_-_Adafruit_Fork 
Using library Adafruit SPIFlash at version 4.1.3 in folder: D:\Arduino_projects\libraries\Adafruit_SPIFlash 
Using library Adafruit TinyUSB Library at version 1.7.0 in folder: C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1\libraries\Adafruit_TinyUSB_Arduino 
"C:\\Users\\Dude\\AppData\\Local\\Arduino15\\packages\\Seeeduino\\tools\\arm-none-eabi-gcc\\9-2019q4/bin/arm-none-eabi-size" -A "C:\\Users\\Dude\\AppData\\Local\\Temp\\arduino\\sketches\\A25B9D6E2C523EB8A1B4ECDC58048CC7/GroveFlash_Final.ino.elf"
Sketch uses 56544 bytes (6%) of program storage space. Maximum is 811008 bytes.
Global variables use 7784 bytes (3%) of dynamic memory, leaving 229784 bytes for local variables. Maximum is 237568 bytes.
Performing 1200-bps touch reset on serial port COM12
Waiting for upload port...
Upload port found on COM6
"C:\Users\Dude\AppData\Local\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.1/tools/adafruit-nrfutil/win32/adafruit-nrfutil.exe" --verbose dfu serial -pkg "C:\Users\Dude\AppData\Local\Temp\arduino\sketches\A25B9D6E2C523EB8A1B4ECDC58048CC7/GroveFlash_Final.ino.zip" -p COM6 -b 115200 --singlebank
Upgrading target on COM6 with DFU package C:\Users\Dude\AppData\Local\Temp\arduino\sketches\A25B9D6E2C523EB8A1B4ECDC58048CC7\GroveFlash_Final.ino.zip. Flow control is disabled, Single bank, Touch disabled
Opened serial port COM6
Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 56552
Sending DFU start packet
Sending DFU init packet
Sending firmware file
########################################
########################################
###############################
Activating new firmware

DFU upgrade took 3.736424684524536s
Device programmed.

Serial Output after reset…


 Program D:\Arduino_projects\GroveFlash_Final\GroveFlash_Final.ino compiled on Dec 17 2023 at 03:17:24
----RESET----
--------------
1
10
9
8
--------------
Onboard QSPI Flash Testing
QSPI Flash ID P25Q16H
QFlash chip JEDEC ID: 0x856015
Flash size: 2048 KB
QFlash chip successfully ID'd!

Expansion Flash testing!!
SPI Flash ID W25Q80DV
W25Q80DV chip JEDEC ID: 0xEF4014
Flash size: 1024 KB
SPI Flash chip successfully ID'd!

GroveFlash_Final.zip (1.8 KB)

HTH :+1:
AMA
GL :slight_smile: PJ

Here it is working aok. :grinning: :v:
Grove Expansion Video.
HTH
GL :slight_smile: PJ