Teensyduino 1.21 Released

Status
Not open for further replies.
I've been pretty quiet the last couple days.... better SD caching that's interrupt safe is turning into quite a project!
 
If anyone's wondering where I've gone... well, I hope to catch up to many conversations on Monday. This weekend I'm working heavily on massive SD library improvement.
 
Paul: Any chance you are/will be testing the SD card SPI usage with this really cool color display for SPI sharing with its built in reader? https://www.pjrc.com/store/display_ili9341.html

It is in stock in case you don't have one and I'm sure you could get same day delivery - even on Sunday ;-) and you don't have to go back to work until Monday
 
Last edited:
Does the K20 have an SD interface peripheral on-chip (not SPI)? Enabling use of 1, 2, 3, 4 channels (one MOSI, 1-4 MISO) in SD mode, and similar in MMC mode?
 
Just another quick update... I'm still very actively working on this problem.

Over the last several days, I've ended up rewriting the entire SD+SdFat library. Well. most of it so far, but only reading, not writing to the card. Originally I wanted to just patch Bill's code, and I made a pretty good attempt at that last week. But there were just too many complex paths to analyze, especially in the directory parsing, to resolve all the ranges where pointers still depended on cached data. Bill's put a lot of work into reducing the AVR code size, and most of his code is still pretty readable, but it was never designed with a multi-sector, interrupt aware cache in mind, which needs to be notified when the filesystem is and isn't depending on buffers to remain fixed.

Ultimately, I started fresh. Fortunately, I'm pretty familiar with FAT filesystems, from the old MP3 player days when I wrote simpler filesystem code all in 8051 assembly.

This time around, I created a SDCache object, where the static cached sector buffers have usage counts of the number SDCache objects currently requiring them. I'm using the object destructor to manage when the cache can allow a buffer to be released back into the pool to be reused. By writing all the code fresh, I can structure things with these objects and pointers to allow the cache to properly serve multiple concurrent, interrupt-based and main program users.

This morning I got the new code playing the stress test, with 1, 2, 3, 4 all playing and without any chirps or audible artifacts (at least nothing I can hear within the noise floor on these samples using good over-ear headphones). There's still some bugs to work out, like a memory leak that eventually strikes, and quite a bit of the new code still needs to optimization.

Anyway, the good news is an excellent solution is in sight. Well, with the caveat that at least for quite some time, there will be a choice between the original SD library which can read and write, and this new one that's read-only. Eventually I'll add write support, but that's not going to happen this week.

I hope to have code to share in a day or two. This has been a really tough problem, but the end is finally in sight.
 
Last edited:
The new library allows playbackInterval to be set to any value, even zero. But below about 100 ms, the sounds don't finish enough of the word to be recognizable ("4" seems to be longer than the other three), before the loop repeats and starts the same object playing again from the beginning, so it all ends up being a big jumble of unintelligible sound.
 
Just another quick update... I'm still very actively working on this problem.

Over the last several days, I've ended up rewriting the entire SD+SdFat library. Well. most of it so far, but only reading, not writing to the card. Originally I wanted to just patch Bill's code, and I made a pretty good attempt at that last week. But there were just too many complex paths to analyze, especially in the directory parsing, to resolve all the ranges where pointers still depended on cached data. Bill's put a lot of work into reducing the AVR code size, and most of his code is still pretty readable, but it was never designed with a multi-sector, interrupt aware cache in mind, which needs to be notified when the filesystem is and isn't depending on buffers to remain fixed.

Ultimately, I started fresh. Fortunately, I'm pretty familiar with FAT filesystems, from the old MP3 player days when I wrote simpler filesystem code all in 8051 assembly.

This time around, I created a SDCache object, where the static cached sector buffers have usage counts of the number SDCache objects currently requiring them. I'm using the object destructor to manage when the cache can allow a buffer to be released back into the pool to be reused. By writing all the code fresh, I can structure things with these objects and pointers to allow the cache to properly serve multiple concurrent, interrupt-based and main program users.

This morning I got the new code playing the stress test, with 1, 2, 3, 4 all playing and without any chirps or audible artifacts (at least nothing I can hear within the noise floor on these samples using good over-ear headphones). There's still some bugs to work out, like a memory leak that eventually strikes, and quite a bit of the new code still needs to optimization.

Anyway, the good news is an excellent solution is in sight. Well, with the caveat that at least for quite some time, there will be a choice between the original SD library which can read and write, and this new one that's read-only. Eventually I'll add write support, but that's not going to happen this week.

I hope to have code to share in a day or two. This has been a really tough problem, but the end is finally in sight.

That is great news. I can't wait to show my product with these fixes, it's going to be awesome! I love the Teensy and Arduino IDE! I will test the new library as soon as you are ready. I know the audible chirp at high file numbers on the SD card was a problem shared by both version, but Does it also fix the issue with v106 to v161 where some of the files were skipped?
 
Ok, I've committed a pile of new code to github. This is still at a very early stage, but at least in a couple lengthy tests here it was looking really good.

The main thing is the SD library.

https://github.com/PaulStoffregen/SD

You'll need to edit SD_t3.h, line 30. By default, the normal SD library is used. You must uncomment that line to compile the new code.

The new SD code has quite a number of limitations. It can't parse pathnames, so you can only open files in the root directory. It can't write to the card. A few of the SD functions, like openNextFile() aren't implemented yet. I've only tested on 2 cards so far, both FAT32 format, so FAT16 (2GB or less) is utterly untested so far. Remember, this is a complete ground-up rewrite of the SD library. Expect some issues.....

But the larger cache and playing more than 1 file at a time while opening others works! Or at least it has on tests I've been doing here.

You'll also need the latest Audio library from github. It was disabling interrupts, as a not-so-great workaround for the SD library problems. This change removes that, so audio can play during the lengthy open while the library has to parse the huge directory with hundreds of files.

https://github.com/PaulStoffregen/Audio/commit/4c6e76e2b4b0888874fc9b60c843bfb9c4248b8a

The other minor thing, which probably doesn't matter (but I've done all my recent testing with it) is this little patch to kinetis.h:

https://github.com/PaulStoffregen/cores/commit/8cd4703817f4e0d143e4686b101c4f34614040bd

I've been doing all my testing on Arduino 1.6.3. In theory, any copy with Teensyduino 1.22 installed should give the same results. Well, except the old versions only run the compiler with code size optimization, so you probably want one of the newer version with speed optimization (in the Tools > CPU Speed menu).
 
For now, I'm working on the SerialFlash library, and a couple other projects. More changes are very unlikely, until you or others have some feedback... or until I get back to the audo library.
 
<SPIFlash.h>? Is there a generally best chip make for size/speed/reliability that you expect to work well - test against the most with best results?

... so little to do . . . so much time . . . < strike that, reverse it >
 
Until the last few days, I had only tested with the 16 MByte Winbond chip.

The 32+ MByte chips have many annoying incompatibilities. I'm working on adding code in SerialFlash to automatically detect and properly handle the differences. On my desk right now is a 64 and 128 Mbyte Micron chips, and a 16 Mbyte Spansion chip. I have a couple bigger Spansion chips coming from Digikey next week, I believe 32 and 64 Mbyte sizes.

If you want to play with something now that's the most compatible, use the Winbond W25Q128FV.

Eventually, I plan to make all (or almost all) of them "just work".

The one possible gotcha might be the Winbond W25Q256. It apparently has issues with certain write & erase commands in 32 bit addressing mode. I can't find a reputable distributor. I ordered a couple from Aliexpress merchants, but I'm not hopeful those will end up being genuine or even working chips.
 
I've used several sizes of Spansion and one of Micron - SPI mode. The only differences I have to deal with are

  • flash sector sizes - some have the default of some smaller sectors in low memory; you can one-time-program these to use uniform sized sectors if your app prefers that. In my driver, I have a compile-time constant of what chip ID is in use and whether uniform sector sizes are used and a table of sector sizes. So the library is compiled for a particular SPI flash chip and any number of same-sized chips, along with a table of chip selects for each chip if there are more than one.
  • Page buffer (RAM, on chip) sizes -smaller chips tend to have 256B and larger have 512B.

One could make these run-time choices for a given suite of chip alternatives. But I'm doing compile-time for 1-n of same-type SPI flash chips.

Now I've worked on SDIO and uSD chip driver... that's a bit easier. No chip selects. Fortunately the low level SDIO driver is from the MCU vendor's HAL support. Polling or DMA - because SDIO is a bit more complex that SPI. (not Freescale targets)
Complexity arises if you try to use 4 serial channels. So for now, I'm using just one channel at 24Mbps. The SD_CLK speed is the read/write constraint, assuming the SD chip is not an old/slow one.
 
Last edited:
Two dies, one package. For SPI, I did the low level code - low level meaning there's an SPI driver with both polling and DMA options.
I have older code originally for the AVR which uses no driver per se, just direct I/O with the SPI port and crude ppolling.

The code I did provides a block I/O read/write (auto-erase) and seamless addressing for read/write that cross sector and die/chip boundaries, I did. So the API can just deal with address ranges.

For the second project, I did use DMA (that code is in the HAL) so the CPU can do other things or sleep (lower power) during the DMA.

here forward, I think I'll prefer SDIO and either uSD cards or dies. With that HAL driver there's DMA and FATFS as plug and play.
This is all not freescale.

I recently tried out Kinetis Design Studio with the Freescale CMSIS/HAL but it is so far not usable for me, wheres the "other" is easy and comprehensive.
 
Last edited:
Ok, I've committed a pile of new code to github. This is still at a very early stage, but at least in a couple lengthy tests here it was looking really good.

The main thing is the SD library.

https://github.com/PaulStoffregen/SD

You'll need to edit SD_t3.h, line 30. By default, the normal SD library is used. You must uncomment that line to compile the new code.

The new SD code has quite a number of limitations. It can't parse pathnames, so you can only open files in the root directory. It can't write to the card. A few of the SD functions, like openNextFile() aren't implemented yet. I've only tested on 2 cards so far, both FAT32 format, so FAT16 (2GB or less) is utterly untested so far. Remember, this is a complete ground-up rewrite of the SD library. Expect some issues.....

But the larger cache and playing more than 1 file at a time while opening others works! Or at least it has on tests I've been doing here.

You'll also need the latest Audio library from github. It was disabling interrupts, as a not-so-great workaround for the SD library problems. This change removes that, so audio can play during the lengthy open while the library has to parse the huge directory with hundreds of files.

https://github.com/PaulStoffregen/Audio/commit/4c6e76e2b4b0888874fc9b60c843bfb9c4248b8a

The other minor thing, which probably doesn't matter (but I've done all my recent testing with it) is this little patch to kinetis.h:

https://github.com/PaulStoffregen/cores/commit/8cd4703817f4e0d143e4686b101c4f34614040bd

I've been doing all my testing on Arduino 1.6.3. In theory, any copy with Teensyduino 1.22 installed should give the same results. Well, except the old versions only run the compiler with code size optimization, so you probably want one of the newer version with speed optimization (in the Tools > CPU Speed menu).

Paul, this is still not working properly for me. I have multiple SD cards (4gb, 1gB sandisk class 4 and a samsung class 10, 16gb), they all still skip numbers at fast speeds.

I think the squeeks/pops are less, but I still get them at fast playbackInterval of 150ms or less. Also it still skips numbers at 500ms or less, which does not work for me. I'm not 100% sure I have the patch installed correct. I did a clean install of Arduino 1.63, teensyduino 1.22, audio library you linked, core update you linked, SD library you linked and I deleted the old libraries/cores. I uncommented the SD_t3.h, line 30. Am I missing a step or did you miss a step for me? I am really seeing no change, so I suspect something is up with directions on one of our sides. I am formatting with SDformatter v1.4 which turns to FAT32 cards, Code I am using:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>

//////////////////////////////////////////////////////////////////////////
//////////////////////// Audio Setup ///////////////////////////
AudioPlaySdRaw           raw4;       //channel 4 playback
AudioPlaySdRaw           raw3;       //channel 4 playback
AudioPlaySdRaw           raw2;       //channel 4 playback
AudioPlaySdRaw           raw1;       //channel 4 playback
AudioMixer4              mixer1;         //combines up to 4 channels, can play even more if needed by more mixers
AudioOutputI2S           i2s;           //I2S type playback (opposed to I2C etc)
AudioConnection          patchCord1(raw4, 0, mixer1, 3);
AudioConnection          patchCord2(raw3, 0, mixer1, 2);
AudioConnection          patchCord3(raw2, 0, mixer1, 1);
AudioConnection          patchCord4(raw1, 0, mixer1, 0);
AudioConnection          patchCord5(mixer1, 0, i2s, 0);
AudioControlSGTL5000     sgtl5000;     //audio codec chip
//////////////////////////////////////////////////////////////////////////
const float maxVolume = 0.1;//set speaker volume
const int   playbackInterval = 500; //time between files in milliseconds

void setup() 
{
  AudioMemory(30); //memory usage usually around 6-7, more mixers use more memory
  sgtl5000.enable();

  mixer1.gain(0, maxVolume); //channel, volume
  mixer1.gain(1, maxVolume);
  mixer1.gain(2, maxVolume);
  mixer1.gain(3, maxVolume); 

  SPI.setMOSI(7); //move from pin 6 to pin 7
  SPI.setSCK(14);  //move from pin 13 to pin 14 
  SD.begin(10); //set SD card cable pin select to pin (#10)
}

void loop() 
{
  raw1.play("300.RAW");
  delay(playbackInterval); //wait to open next file
  raw2.play("700.RAW");
  delay(playbackInterval); //wait to open next file
  raw3.play("600.RAW");
  delay(playbackInterval); //wait to open next file
  raw4.play("050.RAW");
  delay(playbackInterval); //wait to open next file
}
 
Also it still skips numbers at 500ms or less, which does not work for me. I'm not 100% sure I have the patch installed correct.

It's almost certainly not installed properly. :(

I know there's a lot of separate pieces to get right. Later this week I'll put together a beta installer. That's the way I can help.
 
It's almost certainly not installed properly. :(

I know there's a lot of separate pieces to get right. Later this week I'll put together a beta installer. That's the way I can help.

OK, well I tried installing clean w/o luck. I put the updated audio library, core and SD library into Teensyduino 1.20 and Arduino 1.06 (last version that works for me with multi-sound playback). Lose sound if I uncomment USE_TEENSY3_OPTIMIZED_CODE . Any idea what would cause the SD updated library not to work with that version?

Otherwise, the audio portion of our product is stuck for now.
 
Any idea what would cause the SD updated library not to work with that version?

Any of the many pieces not installed as intended....

Otherwise, the audio portion of our product is stuck for now.

As I said, I'll put together an installer later this week.

I've published all the raw source code. Packaging it up and testing the installers takes time... time I will put into this, but I can't do it immediately. It will come in a matter of only days.

If you can't get the many pieces put together, which admittedly isn't easy, just wait a little while for me to put in more work to make it easy to install.... and please understand generating the Teensyduino installers that automatically do so much to install thousands of files in exactly the right way so everything "just works" does indeed involve quite a lot of effort on my part.
 
... and supporting multiple OS platforms on multiple IDE versions for multiple hardware devices . . . with thousands of related files . . .
 
Any updates on this?

Here it is.

https://forum.pjrc.com/threads/28499-Teensyduino-1-23-Beta-1-Available

After installing, you MUST edit SD_t3.h. The new/experimental SD stuff is disabled by default. Read the comments near the top of that file to find the line to uncomment which enables it.

We are willing to make donations to keep wheels of progress spinning...

All this development is funded by sales of Teensy. Buying more Teensy, or recommending it to others is the way to donate!

A quick YouTube video, even with shakey-cam footage, but with some voice explanation of what it does, showing something awesome you've made with Teensy actually can help quite a lot.
 
The new SD code has quite a number of limitations. It can't parse pathnames, so you can only open files in the root directory. It can't write to the card. A few of the SD functions, like openNextFile() aren't implemented yet.

Paul -- any chance you'll implement the openNextFile() etc stuff any time soon? looking at dir_t3.cpp, it's quite beyond me.
 
Status
Not open for further replies.
Back
Top