T4.1 SerialFlash with soldered optional inboard flashship

Status
Not open for further replies.
[QUOTE = Frank B]Well, the original is here, I think:
https://github.com/littlefs-project/littlefs/

It shows version number:
#define LFS_VERSION 0x00020004 and is >9 month old

Yep you are right. The LittleFS base you pointed to in Github has not been updated for awhile. But the Teensy LittleFS is a wrapper for LittleFS that allows using different media (as you know) from a single library. Also its linked to FS.h class that provides the common thread through all the file systems. Does that make sense.

So yes it can get confusing when referring to LittleFS

No, makes no sense. It's an old copy of the original. This old copy has not all features and is not thread-safe. Where is the sense?
Is it somehow better to uses outdated copys?
 
No, makes no sense. It's an old copy of the original. This old copy has not all features and is not thread-safe. Where is the sense?

Thanks Frank - that piece didn't sink in - still on my first cup of coffee = I will take a look. Still early for me
 
No problem :)

In addition FS.h makes no sense at all, too.
You can ONLY use in a sketch, and ONLY if you don't need extended features of the underlying FS.

You just can't use it in a library, because it misses the most basic functions.

- it neither allows to block accesses to the underlying FS (in interrupts) or interfaces, nor does it do that itself - try to use SPI and a file on SPI (in interrupts)! You don't even know that the file is on SPI... FS does not know it.
- it does not even give any information about the underlying FS, so a library can't do this, too
- You can't use it to store files as fast as possible - no preallocate/truncate
- Not to speak of other useful functions.

It's more a thereotical thing - it exists - fine - but i think nobody ever used it ouside from short examples. There is just no real practical use, at the moment. Outside from most simple sketches.

So, it's not possible to use it. It's not posible to write i.e. a waveplayer or other useful things. SD works - yes.. because it handles these things. Now, try to record.
hehe, try to record to a SD on SPI and attach a SPI display .. without even knowing that your read() edit: ehh. sorry, write() :) uses SPI. It does not even know that it accesses SD.

No, if you want to get something useful working, you need to inlcude all existing filesystems and just ignore FS.h. That's how it is.
And even with that - you can block SPI only and only one SPI interface. No way to do that with SDIO. Or others, like QSPI.

Would be more easy with proven software like RTOSes. They provide ways.
 
Last edited:
And sorry, the problem ist not fixed.
LittleFS is still too slow with NAND and still not threadsafe.
 
Last edited:
@mjs513 : Maybe you can try to play the test software for longer than three times because a crash can happen at any time (quickly though).

I'm sorry as I can't execute the memory access time test during this week-end (no access to my teensy board).

Let it run until it stopped:
Code:
17
Proc = 0.32 (7.61),  Mem = 1 (4)
Proc = 0.32 (7.61),  Mem = 1 (4)
Proc = 6.36 (7.61),  Mem = 1 (4)
Proc = 5.13 (7.61),  Mem = 1 (4)
Proc = 0.32 (7.61),  Mem = 1 (4)
Proc = 0.22 (7.61),  Mem = 1 (4)
18
Proc = 0.26 (7.61),  Mem = 1 (4)  <== hung here

Can I ask a question though = you are continuingly opening a file in the file in the loop. Couldn't you
1. Open then once and then do a file.seek(0, SeekSet )
2. you are continuing to open the file but never closing it now sure if this is causing some problems
 
The problems are more the issues I mentioned.... it crashed in open() for me, it will crash for others, too.. :) even if the open() is way faster with NOR - the underlying problem remains.
 
Just changed the test using the builtin sdcard since we are making comparisons, hangs as well from the SD Card:
Code:
Proc = 17.39 (92.19),  Mem = 2 (5)
12
Proc = 0.32 (92.19),  Mem = 1 (5)
Proc = 0.33 (92.19),  Mem = 1 (5)
Proc = 0.32 (92.19),  Mem = 1 (5)
Proc = 17.90 (92.19),  Mem = 1 (5)
Proc = 17.12 (92.19),  Mem = 1 (5)
Proc = 0.22 (92.19),  Mem = 2 (5)
13
Proc = 0.32 (92.19),  Mem = 2 (5)
Proc = 17.13 (92.19),  Mem = 2 (5)
Proc = 0.32 (92.19),  Mem = 2 (5)
Proc = 0.33 (92.19),  Mem = 2 (5)
Proc = 0.33 (92.19),  Mem = 2 (5)
Proc = 0.16 (92.63),  Mem = 1 (5)  <== hangs here - on another run got to 20
So the issue is not just with NOR Flash - yes there is a problem with NAND and playing multiple files at the same time.
 
This morning, I did a speed test of my QSPI NAND with the soft from post #17 just with file name change according to my personal file.
result:

Code:
Added QSPI Flash
976 micros
2014 micros
1056 micros

So, not so bad....( less than 2.9ms ). and I tried it in a loop, never hangs,time never change.
 
So, since it doesn't seem possible to use the QSPI Nand flash with littlefs to play multiple wav files simultaneously, do you thinks it would be possible to store on SD and transfer on QSPI Nand flash files with raw audio samples (which I convert from my PC with wav2sketch).
As my looped samples are short (2-3 sec) and I know in advance which sample will be played, maybe I can load them on a psram ship just before using them and delete them afterwards.
 
So, since it doesn't seem possible to use the QSPI Nand flash with littlefs to play multiple wav files simultaneously, do you thinks it would be possible to store on SD and transfer on QSPI Nand flash files with raw audio samples (which I convert from my PC with wav2sketch).
As my looped samples are short (2-3 sec) and I know in advance which sample will be played, maybe I can load them on a psram ship just before using them and delete them afterwards.

Would have been nice to get *any* response re: the issues. So, we can't know if it ever get fixed, if it takes a year or two or some weeks or days.
Best is not to use Littlfs until then.

The waveplayer can play from SD, too. And it can play RAW.

I'm not sure.
If the problem is in the wrapper code - then it might work.
If the problem is in LittlFS - then it will crash sooner or later, too. Not as fast as with NAND - but if an interrupt hits open().. it does not help that NOR or RAM is faster. It only lowers the probability.

I probably have an other idea - have to test it. I'll try that (possibly tomorrow) and get back to you.
 
Hi, ok, I just wrote this:
Code:
// Simple WAV file player example
//
// This example code is in the public domain.
//
// Plays a file from PSRAM
//
//
#include <play_wav.h>

#include <MemFile.h> // https://github.com/FrankBoesing/MemFile/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlayWav             playWav;     //xy=323,171
AudioOutputPT8211        output;       //xy=828,169
AudioConnection          patchCord1(playWav, 0, output, 0);
AudioConnection          patchCord2(playWav, 1, output, 1);
// GUItool: end automatically generated code


const char *filename = "sine440.wav";

extern uint8_t external_psram_size;

MemFS  myfs;
File sdFile;
File memFile;

void setup() {
  Serial.begin(9600);
  if (CrashReport) {
    Serial.println(CrashReport);
    CrashReport.clear();
  }

  AudioMemory(20);

  //1. Copy the file from SD to PSRAM:

  if (!(SD.begin(BUILTIN_SDCARD))) {
    Serial.println("Unable to access the SD card");
    abort();
  }

  Serial.println("Copy file...");


  //File open
  sdFile = SD.open(filename);
  size_t len = sdFile.size();

  if (len == 0) {
    Serial.print(filename);
    Serial.println(" not readable");
    abort();
  }

  if (len > external_psram_size * 1024 * 1024) {
    Serial.print(filename);
    Serial.println(" is too large");
    abort();
  }

  //2. File copy
  char *p = (char *)0x70000000;
  sdFile.read(p, len);
  sdFile.close();

  //3. Play
  Serial.println("Playing...");
  memFile = myfs.open(p, len, FILE_READ);
  playWav.play(memFile);
}

void loop()
{
}
(Sorry for beeing faster ;)
Of course, instead of copying from SD, you can copy from LittleFS, too.

You'll need this lib: https://github.com/FrankBoesing/MemFile/
(It's only one file)

MemFile is just a "File wrapper" for a memory area.

You could also use a tool like bin2h or bin2c to convert the audio file to an array in PROGMEM, and use MemFile to play this. This way, you don't even need NAND or NOR QSPI if the files fit into the program flash.
(bin2c is here: https://www.segger.com/free-utilities/bin2c/ )
 
Last edited:
From PROGMEM, it looks like this:
Code:
// Simple WAV file player example
//
// This example code is in the public domain.
//
// Plays a file from program flash
//
//
#include <play_wav.h>

#include <MemFile.h> // https://github.com/FrankBoesing/MemFile/

#include "gong.h" // http://www.freesound.org/people/juskiddink/sounds/86773/ converted to AIFF u-law

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlayWav             playWav;     //xy=323,171
AudioOutputPT8211        output;       //xy=828,169
AudioConnection          patchCord1(playWav, 0, output, 0);
AudioConnection          patchCord2(playWav, 1, output, 1);
// GUItool: end automatically generated code

MemFS  myfs;
File memFile;

void setup() {
  Serial.begin(9600);
  if (CrashReport) {
    Serial.println(CrashReport);
    CrashReport.clear();
  }

  AudioMemory(20);

  Serial.println("Playing...");
  memFile = myfs.open((char*)&_ac86773__juskiddink__gong, sizeof(_ac86773__juskiddink__gong), FILE_READ);
  playWav.play(memFile);
}

void loop()
{
}

Pretty simple!

It plays a wave, converted to aiff- 8-bit u-law as PROGMEM array of char.
The adantage of using .wav or aiff is, that you don't need to convert to raw, and don't need to know the params, like bit-depth, channel-count etc. These are read from the (small) headers.
Full example here: https://github.com/FrankBoesing/Teensy-WavePlayer/tree/main/examples/WavFilePlayer_MemArray
 
Last edited:
Hi, ok, I just wrote this:
Code:
// Simple WAV file player example
//
// This example code is in the public domain.
//
// Plays a file from PSRAM
//
//
#include <play_wav.h>

#include <MemFile.h> // https://github.com/FrankBoesing/MemFile/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlayWav             playWav;     //xy=323,171
AudioOutputPT8211        output;       //xy=828,169
AudioConnection          patchCord1(playWav, 0, output, 0);
AudioConnection          patchCord2(playWav, 1, output, 1);
// GUItool: end automatically generated code


const char *filename = "sine440.wav";

extern uint8_t external_psram_size;

MemFS  myfs;
File sdFile;
File memFile;

void setup() {
  Serial.begin(9600);
  if (CrashReport) {
    Serial.println(CrashReport);
    CrashReport.clear();
  }

  AudioMemory(20);

  //1. Copy the file from SD to PSRAM:

  if (!(SD.begin(BUILTIN_SDCARD))) {
    Serial.println("Unable to access the SD card");
    abort();
  }

  Serial.println("Copy file...");


  //File open
  sdFile = SD.open(filename);
  size_t len = sdFile.size();

  if (len == 0) {
    Serial.print(filename);
    Serial.println(" not readable");
    abort();
  }

  if (len > external_psram_size * 1024 * 1024) {
    Serial.print(filename);
    Serial.println(" is too large");
    abort();
  }

  //2. File copy
  char *p = (char *)0x70000000;
  sdFile.read(p, len);
  sdFile.close();

  //3. Play
  Serial.println("Playing...");
  memFile = myfs.open(p, len, FILE_READ);
  playWav.play(memFile);
}

void loop()
{
}
(Sorry for beeing faster ;)
Of course, instead of copying from SD, you can copy from LittleFS, too.

You'll need this lib: https://github.com/FrankBoesing/MemFile/
(It's only one file)

MemFile is just a "File wrapper" for a memory area.

You could also use a tool like bin2h or bin2c to convert the audio file to an array in PROGMEM, and use MemFile to play this. This way, you don't even need NAND or NOR QSPI if the files fit into the program flash.
(bin2c is here: https://www.segger.com/free-utilities/bin2c/ )
Hi Frank,
I am still trying to learn all the intricacies of c++. Looking at your code above I could not see where
Code:
external_psram_size;
was set to any value. Can you explain for me.
Thanks.
 
Thanks Frank. I had got windows to search the teensy libraries but should have included the cores as well.
It was a bit worrying that there were 10 "TODO"s in the code.
 
Hi,

no, it works as it is.
You *may* have to change the output device (it's a PT8211 in the sample code)
, and if you're not using a Teensy with inbuilt SD some SPI settings.

The "PROGMEM" example is even easier and does not need extra chips.
 
Last edited:
Status
Not open for further replies.
Back
Top