Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: Teensy 4.1 - Copy SDCard Data into Flash Memory

  1. #1
    Junior Member
    Join Date
    Apr 2022
    Posts
    16

    Teensy 4.1 - Copy SDCard Data into Flash Memory

    The Teensy 4.1 has 8MB Flash Memory. This is a lot.

    Can I transfer some data (2 MB or so) into it, while the Teensy is running? Because the 500Kb RAM memory is very small.


    I've found this: LittleFS library

    Is this a solution to transfer and use Data dynamically?

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,170
    Yes, you can use LittleFS_Program to have a filesystem that is saved at the upper part of the Flash Memory.

    With current releases of Teensyduino, This area will be preserved when you reprogram the Teensy. Note: There is a minimum area that will be erased. The size depends on a couple of things. If your Teensy is a locakable/locked Teensy, then 1MB else 512KB. Note we are only talking about T4.x including MicroMod. If your code is > than that amount, then your program rounded up to 64kb blocks.

    So you can add to your setup code. There is an example sketch (LittleFS_Program_Simple_Datalogger-dates). That shows how to setup and in some cases use the FS here.

    But note: This is not like RAM memory; in that it is relatively expensive to write to it. That is if the write requires a block to be erased that can take a bit of time.

  3. #3
    Junior Member
    Join Date
    Apr 2022
    Posts
    16
    That sounds very good. It is faster than the SDCard (read mode only)?

  4. #4
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,328

    Cool

    In addition to using the flash memory on the Teensy 4.1, the Teensy has two sets of solder pads underneath the Teensy. You can solder two memory chips to these pads:
    • One or two PSram chips, 8 megabytes or 16 megabytes. PSram is used like regular SRAM memory. It is cached and such, but outside of the cached part, it is slower than normal memory. PSram is generally not preserved across power cycling.
    • One flash chip (8 megabytes to 256 megabytes) of persistant memory
    • One PSram chip and one flash chip


    I suspect using PSram might be easier to use in your program, rather than using flash memory (either the standard flash memory or via the QSPI flash memory soldered under the Teensy). If your soldering skills are not up to soldering SMT chips to the Teensy, there is a company (protosupplies.com) that sells Teensy 4.1s in various configurations with the chips already soldered on.

    If you need the files to persist between power cycling, then you would want to use flash memory instead of PSram. Typically for flash memory, you would use it like you would with a SD card, i.e. it is organized as a file system. You would open up a file, read in chunks of memory, write chunks, etc.


  5. #5
    Junior Member
    Join Date
    Apr 2022
    Posts
    16
    Yes, this is also a good option :-)

    Thanks.

  6. #6
    Junior Member
    Join Date
    Dec 2020
    Location
    USA
    Posts
    5
    MichaelMeissner thanks for that good information, but how do I change the SS pin (chip-select), between "CS0" (48) and "CS1" (51), in the source code. What are the actual values (or symbol names) for these two pins, and in what library source file(s) may they be found?

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,170
    Having PSRAM soldered to bottom of the T4.1, is automatically handled by the Teensy startup code.
    And they are mapped into the memory space for the teensy:
    https://www.pjrc.com/store/teensy41.html#memory

    They are shown in the area marked PSRAM. Your code can address variables up in this area using the modifier EXTMEM on the declaration.
    Note: these can not be pre-iniitialized.

    There is also a malloc like allocator defined for using the unused area there.

  8. #8
    Junior Member
    Join Date
    Dec 2020
    Location
    USA
    Posts
    5
    OK, KurtE, thank you. I've got a QSPI Flash chip in the "PSRAM" spot so I need to change the chip-select (in the example flash code) from "CS1" to "CS0" and I can't figure out how. Maybe it is not possible to run flash from those pads?

  9. #9
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,328

    Cool

    Quote Originally Posted by snave View Post
    MichaelMeissner thanks for that good information, but how do I change the SS pin (chip-select), between "CS0" (48) and "CS1" (51), in the source code. What are the actual values (or symbol names) for these two pins, and in what library source file(s) may they be found?
    It depends on what you are doing. If you are accessing the PSram chips as normal volatile memory, you don't have to do anything, the Teensy setup code handles it. If you look at Teensy 4.1 product page (https://www.pjrc.com/store/teensy41.html), and scroll down to the memory section, you can see:

    • If you declare static/global variables with 'EXTMEM' it reserves space in the external memory area in the address space reserved for PSram. Note, the variables are not initialized -- you have to zero them yourself;
    • Otherwise you can call the 'extmem_malloc' function to allocate memory from PSram.


    If you have a flash memory chip soldered onto the larger pad, typically you would use the LIttleFS library to access it via read, write, etc. like you would with with a micro SD card. There are two different constructors to use for LittleFS flash file systems, depending on whether your flash memory is NOR or NAND flash. In addition, on the Teensy 4.1, most of the upper part of the 8 megabyte flash memory is reserved for LittleFS to use as a file system:

    • NOR flash: LittleFS_QSPIFlash;
    • NAND flash: LittleFS_QPINAND; (and)
    • Built-in flash memory: LittleFS_Program.


    Here is the code that I adapted from the MTP example code in Teensydunio 1.57 to get access to the NOR, NAND, Program flash regions as well as the SD card on my Teensy 4.1. I have tested it with two different Teensies that I got from protosupplies, one with NOR flash and the other with NAND flash.

    When you build this code with build option 'Serial + MTP (experimental)', it talks to your computer using MTP. On my Linux system, it brings up the file explorer program, and I can use it to drop files into the various memories, read them, etc. Presumably afterwards, you would just use the constructor to read files from the filesystem.

    Code:
    // From /shared/arduino/git/MTP_t4.git/trunk/examples/mtp-basic/mtp-basic.ino
    
    #include "SPI.h"
    #include "SD.h"
    #include "MTP.h"
    
    #if defined(ARDUINO_TEENSY41)
    // The Teensy 4.1 has two sets of solder pads underneath the Teensy that you
    // can solder either 2 PSram chips, 1 flash memory chip, or 1 flash memory chip
    // and a PSram chip.  The smaller flash chips tend to use NOR flash while the
    // larger flash chips tend to use NAND flash.
    #define USE_LFS_RAM			1	// T4.1 PSRAM (or RAM)
    #define USE_LFS_QSPI_NOR		1	// T4.1 QSPI NOR flash (16MB)
    #define USE_LFS_QSPI_NAND		1	// T4.1 QSPI NAND flash (128MB)
    
    #else
    #define USE_LFS_RAM			0	// T4.1 PSRAM (or RAM)
    #define USE_LFS_QSPI_NOR		0	// T4.1 QSPI NOR flash (16MB)
    #define USE_LFS_QSPI_NAND		0	// T4.1 QSPI NAND flash (128MB)
    #endif
    
    #if defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY41)
    // Teensy 4.0 and 4.1 can use the upper flash memory as a file system via
    // LittleFS.  The top bytes (64K for Teensy 4.0 and 256K for Teensy 4.1) of
    // this memory is reserved for EEPROM emulation and the LED blink restore
    // program.  On the Teensy 4.0 you have 1 megabyte - 64K of flash for a
    // filesystem.  On the Teensy 4.1, you have 7 megabytes - 256K of flash for the
    // filesystem.
    #define USE_LFS_PROGM			1	// T4.0/T4.1 Progam Flash
    #else
    #define USE_LFS_PROGM			0	// T4.0/T4.1 Progam Flash
    #endif
    
    #define USE_SD				1	// Use either the built-in micro SD card reader or the reader on pin 10 (audio adapter)
    #define USE_LFS_SPI			1	// SPI Flash (soldered to the audio adapter or the built-in flash on the prop shield)
    
    // If you use the audio adapter revision A through C on a Teensy LC, 3.2, 3.5,
    // or 3.6, it needs to remap the MOSI/SCK pins because those pins (11 and 13)
    // are also I2S pins used by the audio shield.  But the prop shield wants to
    // use the normal definitions.  In general, I've used the prop shield mostly on
    // the Teensy 3.2 and LC, while if I use it, I use the audio shield on the
    // Teensy 3.5 or Teensy 3.6.
    //
    // The Teensy 4.0 and 4.1 uses the audio adapter revision D, and it uses the
    // standard SPI pins.
    #if defined(ARDUINO_TEENSY35) || defined(ARDUINO_TEENSY36)
    #define USE_TEENSY3_AUDIO_SHIELD	1	// Whether to use the Audio shield MOSI/SCLK for Teensy 3.x processors
    #else
    #define USE_TEENSY3_AUDIO_SHIELD	0	// Use standard configuration
    #endif
    
    #if USE_EVENTS==1
      extern "C" int usb_init_events(void);
    #else
      int usb_init_events(void) {}
    #endif
    
    #if USE_LFS_RAM==1 ||  USE_LFS_PROGM==1 || USE_LFS_QSPI_NOR==1 || USE_LFS_QSPI_NAND==1 || USE_LFS_SPI==1
      #include "LittleFS.h"
    #endif
    
    #if defined(__IMXRT1062__)
      // following only as long usb_mtp is not included in cores
      #if !__has_include("usb_mtp.h")
        #include "usb1_mtp.h"
      #endif
    #else
      #ifndef BUILTIN_SDCARD 
        #define BUILTIN_SDCARD 254
      #endif
      void usb_mtp_configure(void) {}
    #endif
    
    
    /****  Start device specific change area  ****/
    // SDClasses 
    #if USE_SD==1
      // edit SPI to reflect your configuration
    #if USE_TEENSY3_AUDIO_SHIELD
     // Teensy audio adapter for Teensy 3.2, 3.5, and 3.6 (revision A-C) needs to remap the MOSI and SCK pins
      #define SD_MOSI  7
      #define SD_MISO 12
      #define SD_SCK  14
    #else
     // Standard Teensy configuration
      #define SD_MOSI 11
      #define SD_MISO 12
      #define SD_SCK  13
    #endif
    
      #define SPI_SPEED SD_SCK_MHZ(33)				// adjust to sd card 
    
      #if defined (BUILTIN_SDCARD)
        const char *sd_str[]={"BUILTIN-SD", "AUDIO-SD"};		// edit to reflect your configuration
        const int cs[] = {BUILTIN_SDCARD, 10};			// edit to reflect your configuration
      #else
        const char *sd_str[]={"AUDIO-SD"};				// edit to reflect your configuration
        const int cs[] = {10};					// edit to reflect your configuration
      #endif
      const int nsd = sizeof(sd_str)/sizeof(const char *);
    
    SDClass sdx[nsd];
    #endif
    
    //LittleFS classes
    #if USE_LFS_RAM==1
      const char *lfs_ram_str[]	= {"RAM1","RAM2"};		// edit to reflect your configuration
      const int lfs_ram_size[]	= {2'000'000, 4'000'000};	// edit to reflect your configuration
      const int nfs_ram		= sizeof(lfs_ram_str)/sizeof(const char *);
    
      LittleFS_RAM ramfs[nfs_ram]; 
    #endif
    
    #if USE_LFS_QSPI_NOR==1
      const char *lfs_qspi_nor_str[]	= {"QSPI-NOR"};		// edit to reflect your configuration
      const int nfs_qspi_nor		= sizeof(lfs_qspi_nor_str)/sizeof(const char *);
    
      LittleFS_QSPIFlash qspifs_nor[nfs_qspi_nor]; 
    #endif
    
    #if USE_LFS_QSPI_NAND==1
      const char *lfs_qspi_nand_str[]	= {"QSPI-NAND"};	// edit to reflect your configuration
      const int nfs_qspi_nand		= sizeof(lfs_qspi_nand_str)/sizeof(const char *);
    
      LittleFS_QPINAND qspifs_nand[nfs_qspi_nand];
    #endif
    
    #if USE_LFS_PROGM==1
      const char *lfs_progm_str[]={"PROGRAM"};			// edit to reflect your configuration
      const int lfs_progm_size[] = {1'000'000};			// edit to reflect your configuration
      const int nfs_progm = sizeof(lfs_progm_str)/sizeof(const char *);
    
      LittleFS_Program progmfs[nfs_progm]; 
    #endif
    
    #if USE_LFS_SPI==1
      const char *lfs_spi_str[]={"SPI-FLASH"};			// edit to reflect your configuration
      const int lfs_cs[] = {6};					// edit to reflect your configuration
      const int nfs_spi = sizeof(lfs_spi_str)/sizeof(const char *);
    
    LittleFS_SPIFlash spifs[nfs_spi];
    #endif
    
    
    MTPStorage_SD storage;
    MTPD    mtpd(&storage);
    
    void storage_configure()
    {
      #if USE_SD==1
        #if defined SD_SCK
          SPI.setMOSI(SD_MOSI);
          SPI.setMISO(SD_MISO);
          SPI.setSCK(SD_SCK);
        #endif
    
        for(int ii=0; ii<nsd; ii++)
        { 
          #if defined(BUILTIN_SDCARD)
            if(cs[ii] == BUILTIN_SDCARD)
            {
              if(!sdx[ii].sdfs.begin(SdioConfig(FIFO_SDIO))) 
              { Serial.printf("SDIO Storage %d %d %s failed or missing",ii,cs[ii],sd_str[ii]);  Serial.println();
              }
              else
              {
                storage.addFilesystem(sdx[ii], sd_str[ii]);
                uint64_t totalSize = sdx[ii].totalSize();
                uint64_t usedSize  = sdx[ii].usedSize();
                Serial.printf("SDIO Storage %d %d %s ",ii,cs[ii],sd_str[ii]); 
                Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
              }
            }
            else if(cs[ii]<BUILTIN_SDCARD)
          #endif
          {
            pinMode(cs[ii],OUTPUT); digitalWriteFast(cs[ii],HIGH);
            if(!sdx[ii].sdfs.begin(SdSpiConfig(cs[ii], SHARED_SPI, SPI_SPEED))) 
            { Serial.printf("SD Storage %d %d %s failed or missing",ii,cs[ii],sd_str[ii]);  Serial.println();
            }
            else
            {
              storage.addFilesystem(sdx[ii], sd_str[ii]);
              uint64_t totalSize = sdx[ii].totalSize();
              uint64_t usedSize  = sdx[ii].usedSize();
              Serial.printf("SD Storage %d %d %s ",ii,cs[ii],sd_str[ii]); 
              Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
            }
          }
        }
        #endif
    
        #if USE_LFS_RAM==1
        for(int ii=0; ii<nfs_ram;ii++)
        {
          if(!ramfs[ii].begin(lfs_ram_size[ii])) 
          { Serial.printf("Ram Storage %d %s failed or missing",ii,lfs_ram_str[ii]); Serial.println();
          }
          else
          {
            storage.addFilesystem(ramfs[ii], lfs_ram_str[ii]);
            uint64_t totalSize = ramfs[ii].totalSize();
            uint64_t usedSize  = ramfs[ii].usedSize();
            Serial.printf("RAM Storage %d %s ",ii,lfs_ram_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
          }
        }
        #endif
    
        #if USE_LFS_PROGM==1
        for(int ii=0; ii<nfs_progm;ii++)
        {
          if(!progmfs[ii].begin(lfs_progm_size[ii])) 
          { Serial.printf("Program Storage %d %s failed or missing",ii,lfs_progm_str[ii]); Serial.println();
          }
          else
          {
            storage.addFilesystem(progmfs[ii], lfs_progm_str[ii]);
            uint64_t totalSize = progmfs[ii].totalSize();
            uint64_t usedSize  = progmfs[ii].usedSize();
            Serial.printf("Program Storage %d %s ",ii,lfs_progm_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
          }
        }
        #endif
    
        #if USE_LFS_QSPI_NOR==1
        for(int ii=0; ii<nfs_qspi_nor;ii++)
        {
          if(!qspifs_nor[ii].begin()) 
          { Serial.printf("QSPI Storage %d %s failed or missing",ii,lfs_qspi_nor_str[ii]); Serial.println();
          }
          else
          {
            storage.addFilesystem(qspifs_nor[ii], lfs_qspi_nor_str[ii]);
            uint64_t totalSize = qspifs_nor[ii].totalSize();
            uint64_t usedSize  = qspifs_nor[ii].usedSize();
            Serial.printf("QSPI NOR Storage %d %s ",ii,lfs_qspi_nor_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
          }
        }
        #endif
    
        #if USE_LFS_QSPI_NAND==1
        for(int ii=0; ii<nfs_qspi_nand;ii++)
        {
          if(!qspifs_nand[ii].begin()) 
          { Serial.printf("QSPI Storage %d %s failed or missing",ii,lfs_qspi_nand_str[ii]); Serial.println();
          }
          else
          {
            storage.addFilesystem(qspifs_nand[ii], lfs_qspi_nand_str[ii]);
            uint64_t totalSize = qspifs_nand[ii].totalSize();
            uint64_t usedSize  = qspifs_nand[ii].usedSize();
            Serial.printf("QSPI NAND Storage %d %s ",ii,lfs_qspi_nand_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
          }
        }
        #endif
    
        #if USE_LFS_SPI==1
        for(int ii=0; ii<nfs_spi;ii++)
        {
          if(!spifs[ii].begin(lfs_cs[ii])) 
          { Serial.printf("SPIFlash Storage %d %d %s failed or missing",ii,lfs_cs[ii],lfs_spi_str[ii]); Serial.println();
          }
          else
          {
            storage.addFilesystem(spifs[ii], lfs_spi_str[ii]);
            uint64_t totalSize = spifs[ii].totalSize();
            uint64_t usedSize  = spifs[ii].usedSize();
            Serial.printf("SPIFlash Storage %d %d %s ",ii,lfs_cs[ii],lfs_spi_str[ii]); Serial.print(totalSize); Serial.print(" "); Serial.println(usedSize);
          }
        }
        #endif
    }
    
    void setup()
    { 
      while (!Serial && millis () < 3000)
        ;
    
      Serial.println("MTP_test");
      Serial.printf ("USE_LFS_RAM              = %d\n", USE_LFS_RAM);
      Serial.printf ("USE_LFS_QSPI_NOR         = %d\n", USE_LFS_QSPI_NOR);
      Serial.printf ("USE_LFS_QSPI_NAND        = %d\n", USE_LFS_QSPI_NAND);
      Serial.printf ("USE_LFS_PROGM            = %d\n", USE_LFS_PROGM);
      Serial.printf ("USE_SD                   = %d\n", USE_SD);
      Serial.printf ("USE_LFS_SPI              = %d\n", USE_LFS_SPI);
      Serial.printf ("USE_TEENSY3_AUDIO_SHIELD = %d\n", USE_TEENSY3_AUDIO_SHIELD);
      Serial.println ("");
    
      #if USE_EVENTS==1
        usb_init_events();
      #endif
    
      #if !__has_include("usb_mtp.h")
        usb_mtp_configure();
      #endif
      storage_configure();
    
    }
    
    void loop()
    { 
      mtpd.loop();
    
    #if USE_EVENTS==1
      if(Serial.available())
      {
        char ch=Serial.read();
        Serial.println(ch);
        if(ch=='r') 
        {
          Serial.println("Reset");
          mtpd.send_DeviceResetEvent();
        }
      }
    #endif
    }
    If you want to get your hands dirty and access the two sets of PSram/flash, you may need to dig into the Teensydunio library. The usual suspects (defragger, mjs513, and KurtE) probably have examples of how to do it. For me, I am happy to let the libraries handle these details.

  10. #10
    Junior Member
    Join Date
    Dec 2020
    Location
    USA
    Posts
    5
    OK MichaelMeissner, thank you thus far. I installed another flash chip (GD25Q16) into the (proper) "Flash" area (the bigger footprint on the under side of the Teensy4.1 board). I am trying the "LittleFS" library example called: "Write_Speed_Test.ino" but I see it has the wrong chip select:

    #define chipSelect 6 // use pin 6 for access flash on audio or prop shield

    ...so I changed it:

    #define chipSelect 51

    That didn't work. Any ideas?

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,108
    GD25Q16 is not on the list of LittleFS (for Teensy) supported chips. Maybe it could work if it is similar enough to one of the Winbond chips, but that's just a guess. I really don't know anything about GD25Q16.

    The location on the bottom side of Teensy 4.1 uses 4 bit QSPI, not 1 bit SPI. To access QSPI, you need to use LittleFS_QSPIFlash. If you use ordinary LittleFS_SPIFlash, it can not work because 1 bit SPI is used.

    Probably not the answer you wanted, but at least you can know there are 2 separate problems here. Solving the QSPI vs SPI issue can let you focus on whether the chip can be recognized, or maybe try editing the list of known chips if it isn't.

  12. #12
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,328
    Quote Originally Posted by snave View Post
    OK MichaelMeissner, thank you thus far. I installed another flash chip (GD25Q16) into the (proper) "Flash" area (the bigger footprint on the under side of the Teensy4.1 board). I am trying the "LittleFS" library example called: "Write_Speed_Test.ino" but I see it has the wrong chip select:

    #define chipSelect 6 // use pin 6 for access flash on audio or prop shield

    ...so I changed it:

    #define chipSelect 51

    That didn't work. Any ideas?
    Yes, don't use that example directly since that is made for SPI flash. Assuming you are using a recent teensy dunio, you want to use the LittleFS_QSPIFlash constructor and not LittleFS_SPIFlash constructor. You would change the begin call not to take either chipSelect or SPI arguments.

    And as Paul says, you may need to expand the list of know chips.

  13. #13
    Junior Member
    Join Date
    Dec 2020
    Location
    USA
    Posts
    5
    OK, PaulStoffregen, and MichaelMeissner, thank you (again) for valuable information. I ordered my Teensy4.1 from Adafruit, and the QSPI Flash chip that they offer is the GD25Q16. I see it is not in the LittleFS::...known_chips list. Odd that the offer this one. But I turned-on some "printf"s in the begin() method, and I see that it is identifying itself:

    LittleFS Sustained Write Speed Test
    QSPI flash begin
    Flash ID: C8 40 15
    Error starting SPI FLASH

    So at least it is working (talking). I'll see if one of the "known chips" has the same communications interface and, then, modify that array (in LittleFS.cpp). Odd that Adafruit offers this chip since it is clearly not compatible?

  14. #14
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,328
    Adafruit sells that flash chip to attach to their QT PY M0 board. Adafruit only supports that one flash chip in their Circuit Python support for the board. They only mention the QT PY M0 as supporting SPI flash and not QSPI flash (in SPI flash only 1 bit is transferred at a time, while in QSPI flash, up to 4 bits are transferred). The GD25Q16 can run as standard SPI, dual SPI, or quad SPI.

    But since they know that the Teensy 4.1 has the pads for such boards, they added the Teensy 4.1 to the description. I would imagine the chip was added to Adafruit before the LittleFS stuff was incorporated, and it would be compatible if you wrote your own driver and such.

    For the Teensy's and audio adapters that I've soldered flash chips on to, I've only used the 16 megabyte Winbond W25Q128JVSIQ board that I got from Digikey:


    It would be helpful if the LittleFS driver could add the board. You may be the first person to test it. I would hope that both flash chips use the same programming, but I haven't dived into reading the data sheet.

    Given that LittleFS now has support for using the remainder of the Teensy 4.0/4.1's flash chip for a filesystem, you could use that space right now without having to modify LittleFS. You would use the LittleFS_Program constructor to access it. Good luck!

  15. #15
    Junior Member
    Join Date
    Dec 2020
    Location
    USA
    Posts
    5
    OK MichaelMeissner, I see that Winbond has a few of their chips in the "know_chips" list, and DigiKey has many in stock. If I get the GD25Q16 chip up and running I'll be sure to propagate the fix. Good tip on using the LittleFS_Program class instead, that could work too. Thank you for your help. Have a great day.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •