New SdFat library (with and without DMA)

victor_pv
Mon Apr 27, 2015 7:11 pm
***Latest Update 04/10/2017***
The code in the official repo from Bill Greyman has now the support for the libmaple based core (stm32duino) integrated in it. So no need to download it from my repo any more.

Official SD-Fat library repository:
https://github.com/greiman/SdFat

===============================================================

UPDATE TO THIS WARNING. SHOULD BE SOLVED IN THE LATEST REPO. If you have problems using pin 7 for CS, make sure you are in sync with Roger’s master STM32Duino repo.
WARNING!!
I was just testing an SD card with one of the sketches, and noticed that you CAN NOT use pin 7 in the maple mini (the stm32f103 native SS pin for spi1) for CS. I have not looked at how the library manages CS and how that pin is setup in out SPI library, but I guess there is a conflict in the pin mode. So the work around at the moment is to use a different pin for CS.
– Updated 06/04/2015-

– New update on 07/10/2015 – Small code changes to the library and specially to the SPI library, which should go to Roger’s master repo soon.

So as I posted before in the forum, I modified the latest SdFat library from Greiman.
I had submitted him changes for a previous version, but had issues. Now all the issues seem to be corrected in my latest version.
It is available here:
https://github.com/victorpv/SdFat

It seems to work fine for me for the few examples I have tested.
If you want the best performance for large transfers, can use DMA mode.

DMA would be advantageous for large transfers, but doesn’t help at all, and may even have a penalty, if you are just reading a few bytes to a log and things like that. Now if you transfer images or mp3 files from the sdcard, DMA can improve performance greatly, anything involving big blocks at once.

DMA can be enabled or disabled editing SdSpiSTM32F1.cpp, there is one #define line:
/** Use STM32 DMAC if nonzero */
#define USE_STM32F1_DMAC 1

Comment that line or change the 1 for 0, and DMA transfers will not be used.

RECOMMENDATIONS FOR SPEED:
Use DMA mode.
Set a bigger buffer, ideally 4KB

Read speeds without DMA, 4KB buffer:
read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
676.29,8189,5927,6056
676.38,7467,5927,6054
676.38,7468,5927,6054
676.38,7469,5926,6054
676.38,7472,5926,6054


madias
Mon Apr 27, 2015 8:16 pm
Dear Victor,
does it matter, if you post some examples written by you? It would be easier for us…
thanks!

victor_pv
Tue Apr 28, 2015 2:35 am
Madias, I have not written any example for that library, basically because I have not use for it at the moment.
I ported it mostly just to test the sdcard connector in the back of my display, in case I needed it in the future.

From the examples included in the library I have tested:
ReadWriteSdfat
Bench
Sdinfo
Printbenchmark

The only thing I may use it for, will be to hold small images for the display, but have not tested it for that yet.


skyng22003
Thu Apr 30, 2015 7:10 pm
Hi Victor,

I updated the SPI library (with DMA off) to the one you posted and the new SdFat library you posted cannot detect my card?

Says SD card initialisation failed with the quick start example, even though I’ve tried different CS pin values.

However, It works fine with the SD card library bundled with the Arduino IDE, I can see the text file written to the card, any ideas?

Using STM32F103 RET6

Thanks,
Sky


madias
Thu Apr 30, 2015 7:32 pm
skyng/victor: is the SPI clock div still at 128? This was my problem with the library and nothing worked.

skyng22003
Thu Apr 30, 2015 7:44 pm
madias: Is that in the SPI library or in the SdFat library?

victor_pv
Fri May 01, 2015 3:35 pm
Skyng I thought I had corrected the issues with the DIV values in the latest version in my repo, but perhaps there is still an issue with it.
in the quick start example the SPI speed is set on this line:
const uint8_t spiSpeed = SPI_HALF_SPEED;

Change that to:
const uint8_t spiSpeed = SPI_CLOCK_DIV4;

Make sure you set the SPI to DIV2 to DIV8, they work pretty good for most sdcards.
Some slower cards may have problems with the fastest speed, but DIV4 pr DIV8 should for for most.

Let me know if you still have problems.


Phono
Fri May 08, 2015 4:21 pm
I have tested the library from the repository which link is in an earlier post.
I have failed for SPI.h was missing.
I haved included SPI, and then I get the following compile error :

In file included from sketch_may08a.ino:11:0:
C:\Users\Jean-Marc\Documents\Arduino\libraries\SdFat/SdVolume.h:25:2: error: #error SdVolume is deperacated. Remove this line to continue using this class.
#error SdVolume is deperacated. Remove this line to continue using this class.

What should I do?


mrburnette
Sat May 09, 2015 5:57 pm
Phono wrote:I have tested the library from the repository which link is in an earlier post.
I have failed for SPI.h was missing.
I haved included SPI, and then I get the following compile error :

In file included from sketch_may08a.ino:11:0:
C:\Users\Jean-Marc\Documents\Arduino\libraries\SdFat/SdVolume.h:25:2: error: #error SdVolume is deperacated. Remove this line to continue using this class.
#error SdVolume is deperacated. Remove this line to continue using this class.

What should I do?


Phono
Mon May 11, 2015 9:01 pm
Ok, but this came by default. How can I make by default the compiler seek the libraries in the hardware section?

mrburnette
Tue May 12, 2015 11:34 am
Phono wrote:Ok, but this came by default. How can I make by default the compiler seek the libraries in the hardware section?

madias
Thu Jun 25, 2015 8:57 pm
Anyone who had luck with this library (maple mini)?
I gave it another try and there is no chance to get it working, equal which settings I use (different SS pin (1,9,8, NOT 7..), different spi speeds, dma on/off…..) I always got in the quicktest example
SD initialization failed.
Do not reformat the card!
Is the card correctly inserted?
Is chipSelect set to the correct value?
Does another SPI device need to be disabled?
Is there a wiring/soldering problem?

errorCode: 0x1, errorData: 0x0


RogerClark
Thu Jun 25, 2015 9:15 pm
Matthias

Last time i downloaded it, about 2 weeks ago, SDFat would not even compile.

i think Victor send a Pull Request to the author, which only worked with the modified code that victor has on his machine.

I tried downloading Victors version from GitHub, but that did not work either ;-(

So I am currently using the old lib. The old lib seems mainly ok, but i do occasionally get a glitch when trying to play MP3 files from SD to VS1053.
But i have not had time to find the cause, because sometimes it can run for many hours without a problem


victor_pv
Thu Jun 25, 2015 9:33 pm
RogerClark wrote:Matthias

Last time i downloaded it, about 2 weeks ago, SDFat would not even compile.

i think Victor send a Pull Request to the author, which only worked with the modified code that victor has on his machine.

I tried downloading Victors version from GitHub, but that did not work either ;-(

So I am currently using the old lib. The old lib seems mainly ok, but i do occasionally get a glitch when trying to play MP3 files from SD to VS1053.
But i have not had time to find the cause, because sometimes it can run for many hours without a problem


RogerClark
Thu Jun 25, 2015 9:44 pm
Hi Victor,

i will clone your repo again and see if it works.

it could just have been that PA4 SS issue, but i cant really remember as it was some time ago (but i thought one of my test rigs used PB5 for SS)


madias
Thu Jun 25, 2015 9:55 pm
Victor: I remember, I got your library working some months ago… Maybe the lib doesn’t like every sd-card adapter and/or SD-card. I’m going to search all of my modules and cards and try the combinations…

madias
Thu Jun 25, 2015 10:09 pm
Bingo!
Working:
The old LC-soft adapter (big one) is working http://img.dxcdn.com/productimages/sku_142121_1.jpg

Not working (but with the SD-library)
The micro one for the UNO (with the 5V multi-converter chip) http://img.alibaba.com/img/pb/659/697/9 … 59_679.jpg

SD cards tested: Transcend 4GB microSD: not working, 2GB micro SD (no brand) working. Maybe a formatting problem?

Edit with the successful combination (LC soft adapter + 2GB) the quickstart example works even with SPI_CLOCK_DIV2 and DMA enabled.
Bench speed is like a turtle: 88kb/s even with DMA enabled (more things to try out….)


RogerClark
Thu Jun 25, 2015 10:36 pm
Matthias,

Which repo are you using for SDFat ? Victors one ?


martinayotte
Fri Jun 26, 2015 2:29 am
The old LC-soft adapter (big one) is working http://img.dxcdn.com/productimages/sku_142121_1.jpg

That’s the adaptor I’m using too, but with the old SD. (I’ve didn’t retried SdFat from Victor since when I tried it on Netduino2Plus, it wasn’t working at that time few weeks ago)

On MapleMini, the LC-soft works well with plain SPI, but I’ve struggled to make it run with SPI(2). I wish SPI.SelectDev() will become handy soon … ;)


madias
Fri Jun 26, 2015 6:34 am
Which repo are you using for SDFat ? Victors one ?
Yes, the direct one from Victor’s github account.

RogerClark
Fri Jun 26, 2015 6:43 am
Thanks

I’ll try it again this weekend


Tiago
Sun Jun 28, 2015 8:17 pm
To enable DMA in mini maple generates this error:

/home//Arduino/libraries/SdFat/SdSpiSTM32F1.cpp: In member function 'uint8_t SdSpi::receive(uint8_t*, size_t)':
/home//Arduino/libraries/SdFat/SdSpiSTM32F1.cpp:172:7: error: 'class SPIClass' has no member named 'dmaTransfer'
SPI.dmaTransfer(0, const_cast<uint8*>(buf), n);
^
/home//Arduino/libraries/SdFat/SdSpiSTM32F1.cpp: In member function 'void SdSpi::send(const uint8_t*, size_t)':
/home//Arduino/libraries/SdFat/SdSpiSTM32F1.cpp:208:7: error: 'class SPIClass' has no member named 'dmaSend'
SPI.dmaSend(const_cast<uint8*>(buf), n);
^


madias
Mon Jun 29, 2015 9:06 am
Your repo isn’t up to date.
see SPI.h —-> https://github.com/rogerclarkmelbourne/ … maTransfer
At least you must update the SPI library, but it’s better to update everything, because many innovations are linked together.

The whole dma stuff (like ‘dmaTransfer’) is for a some weeks within the SPI.h/.cpp itself and not in the individual libraries.


tj_style
Wed Jul 01, 2015 1:08 pm
I think some problem is related on level converter on sdcard module/shield.
I have test using sdcard module without using leevel converter, and it work fine.
but it not work when using sd card module that have level converter.

mrburnette
Thu Jul 02, 2015 12:39 pm
tj_style wrote:I think some problem is related on level converter on sdcard module/shield.
I have test using sdcard module without using leevel converter, and it work fine.
but it not work when using sd card module that have level converter.

victor_pv
Thu Jul 02, 2015 1:33 pm
mrburnette wrote:tj_style wrote:I think some problem is related on level converter on sdcard module/shield.
I have test using sdcard module without using leevel converter, and it work fine.
but it not work when using sd card module that have level converter.

mrburnette
Thu Jul 02, 2015 1:51 pm
victor_pv wrote:
I haven’t been using an extra capacitor for SDCards, but it makes much sense, I’ll start using it from now on anytime I see any problem.

ahull
Thu Jul 02, 2015 9:26 pm
victor_pv wrote:
EDIT: Just to add that personally I have used the SDCard slot in the back of an ili9341 board, which seems to work “mostly” fine, and also the adapter Madias linked before: http://img.dxcdn.com/productimages/sku_142121_1.jpg
That one works great all the time so far.

victor_pv
Thu Jul 02, 2015 11:15 pm
I have used all of them separately, but never tried all 3 at the same time.
I also used the screen+touch at the same time, but never a combination of the 3 of them.

tj_style
Sat Jul 04, 2015 10:24 pm
Strange result,
I was try to using CS pin in different pin.
using pin 8 and 9 is not working but when i use pin 1 and oin 2 is working
Using example Sketch.

Micro SD Sandisk 2GB, some test using DMA:
write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
1052.47,106079,2898,3888
1071.19,19437,2900,3820
1073.50,22139,2901,3813
1068.67,33005,2902,3829
1067.76,34606,2901,3833
1063.90,36557,2902,3845
1070.51,38904,2901,3823
1070.28,42891,2899,3824
1065.94,59471,2900,3838
1061.64,44357,2900,3855

Starting read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
1562.09,4049,2607,2621
1563.07,3180,2606,2619
1562.58,3183,2606,2620
1562.58,3183,2605,2619
1562.58,3183,2607,2619


victor_pv
Fri Jul 10, 2015 1:17 pm
tj_style wrote:Strange result,
I was try to using CS pin in different pin.
using pin 8 and 9 is not working but when i use pin 1 and oin 2 is working


victor_pv
Sun Jul 26, 2015 4:28 pm
Quick update. I have noticed that if I “begin” the sdcard without the speed, just the chip select pin, it fails some times, such as:
sd.begin(SD_ChipSelectPin);

But if I add the parameter for the speed, it works fine:
sd.begin(SD_ChipSelectPin, SPI_CLOCK_DIV2)

Maybe the card, may be the default speed, I don’t have time to check it out right now, just wanted to post it in case it helps someone.


e-dredon
Sun Aug 30, 2015 9:13 am
Hello
I’m getting an error during compiling any of the exemples
‘SPI_DMAC_TX_CH’ was not declared in this scope

I’m working with a bluepill STM32F103C8T6 board.

I tried with both the stable branch on the github and the beta repository.

I had a quick look at the SdSpiSTM31F1.cpp and i’ve found definition for SPI1_DMAC_TX_CH but not for SPI_DMAC_TX_CH

#define SPI1_DMAC_RX_CH DMA_CH2
/** DMAC transmit channel */
#define SPI1_DMAC_TX_CH DMA_CH3

Is it possible to fix it ?

Regards,

\%user%\Documents\Arduino\libraries\SdFat\src\SdSpiCard\SdSpiSTM32F1.cpp: In function 'void SPI_DMA_TX_Event()':
\%user%\Documents\Arduino\libraries\SdFat\src\SdSpiCard\SdSpiSTM32F1.cpp:40:21: error: 'SPI_DMAC_TX_CH' was not declared in this scope
dma_disable(DMA1, SPI_DMAC_TX_CH);
^
\%user%\Documents\Arduino\libraries\SdFat\src\SdSpiCard\SdSpiSTM32F1.cpp: In member function 'uint8_t SdSpi::receive(uint8_t*, size_t)':
\%user%\Documents\Arduino\libraries\SdFat\src\SdSpiCard\SdSpiSTM32F1.cpp:148:28: error: 'SPI_DMAC_RX_CH' was not declared in this scope
dmac_channel_disable(SPI_DMAC_RX_CH);
^
\%user%\Documents\Arduino\libraries\SdFat\src\SdSpiCard\SdSpiSTM32F1.cpp:149:28: error: 'SPI_DMAC_TX_CH' was not declared in this scope
dmac_channel_disable(SPI_DMAC_TX_CH);


RogerClark
Sun Aug 30, 2015 10:30 am
What version of SD lib are you using?

e-dredon
Sun Aug 30, 2015 2:24 pm
If i’m not mistaken i use the official release from greiman
https://github.com/greiman/SdFat

Regards,


victor_pv
Sun Aug 30, 2015 2:28 pm
e-dredon wrote:If i’m not mistaken i use the official release from greiman
https://github.com/greiman/SdFat

Regards,


e-dredon
Sun Aug 30, 2015 2:37 pm
Oops… I just saw the first post at the same time you answered. I thought greiman repo was up to date. Thank for the super fast answer. The 2 variables are defined in your version. Obviously It now compiles nicely. Now i can focus on making a demo for the ILI9341 TFT display, with PicoJPEG and your lib. Thank you. I’m using SPI1 for the ILI9341. Do i need to set a dedicated SPI (MISO/MOSI) for the SDcard reader or shall I just use a dedicated CS pin ?

victor_pv
Sun Aug 30, 2015 5:32 pm
e-dredon wrote:Oops… I just saw the first post at the same time you answered. I thought greiman repo was up to date. Thank for the super fast answer. The 2 variables are defined in your version. Obviously It now compiles nicely. Now i can focus on making a demo for the ILI9341 TFT display, with PicoJPEG and your lib. Thank you. I’m using SPI1 for the ILI9341. Do i need to set a dedicated SPI (MISO/MOSI) for the SDcard reader or shall I just use a dedicated CS pin ?

e-dredon
Sat Sep 05, 2015 6:15 am
Thanks for your answer.

I’m now having issues to get the SDreader module working. Even I connect it alone for now on any of the 3 SPIs, SdFat won’t find it. My ILI9341 board comes with a 5 pins connector for the SDcard (F_CS, SD_SCK, SD_MISO, SD_MOSI, SD_CS). If I’m not mistaken, F_CS should be left unconnected as I don’t have the U3 SPI flash populated. I tried with a microSD module made for 5V VCC (just bypassing the 3.3 voltage regulator) and it works. Well I’ll put it on hold for now as i have other issues to address first with the bootloader.

Best regards,


bubulindo
Wed Sep 16, 2015 10:10 am
Hello,

I have an Olimexino board with an SD card attached and I find that the SD libraries assume that there is only one SPI peripheral when in fact we have two (on the olimexino, it’s on SPI2 that the SD card is connected).

Do you think this could be changed in the library?


martinayotte
Wed Sep 16, 2015 2:46 pm
The SdFat can be configured into different flavours in libraries/SdFat/SdFatConfig.h.
SD_SPI_CONFIGURATION is the define that let you choose if you rely on Hardware or Software SPI, or even a custom one.
In my case, for Netduino2Plus, a F405, the SDCard is hooked up on SPI3 and is working marvellously. ;)

bubulindo
Fri Sep 18, 2015 7:55 am
Ups… found it.

Although, it is a bit clunky having to dig through the library files to find which SPI was configured. Since the CS pin is possible to configure, it would make sense to be able to configure which SPI peripheral to use. But… that’s just my opinion.


victor_pv
Fri Sep 18, 2015 11:42 am
bubulindo wrote:Ups… found it.

Although, it is a bit clunky having to dig through the library files to find which SPI was configured. Since the CS pin is possible to configure, it would make sense to be able to configure which SPI peripheral to use. But… that’s just my opinion.


bubulindo
Fri Sep 18, 2015 5:13 pm
Hello,

In my case, I need to change to SPI2 as my board has the SD card wired into SPI2 (nothing I can do about it)… considering that another user has it on SPI3, it’s already two people that had to change the library because it’s not “possible” to use SPI1.

I remember testing an SdFat library about two years ago and we passed an SPI object for it to run the SD functions on. It was just a little bit more transparent, I guess.

Still, thanks. I’ve tested one of the examples and it recognized the card.

If I wanted to log AD values into the SD, what would be my maximum achievable frequency? Any numbers off the top of your heads?


stevech
Fri Sep 18, 2015 6:21 pm
PJRC’s open source “SPI transactions” allows for coordinated sharing of an SPI port among multiple slave devices.
It does NOT though allow for a real time device like an always-on telemetry radio using SPI – because it needs to have the RX on all the time and that can create an interrupt at any time, and the ISR uses the SPI.

For SD cards, etc, SPI transactions is fine


e-dredon
Mon Sep 28, 2015 10:51 am
Good afternoon all.

I didn’t have any success yet with the SD module of my ILI9341 LCD display, and the optimized SdFat library.

To be sure It’s not an hardware issue with my ILI9341, I’ve tried with a Teensy 3.1.
Paul PaulStoffregen spent some time doing similar improvements to the teensy 3.xx Sd library.
I can get read/write working only when I disable the optimization flag in the library configuration file (optimization flag doesn’t work with any of my microSD (512MB, 2GB class 4, 8GB class 4, 16GB class 12), or should it be because the module doesn’t have the SPI RAM populated on the board.
Here is a link on our talk on the PJRC forum :
https://forum.pjrc.com/threads/29331-TF … #post81454

Now with my STM32F103C8T6 (bluepill)
I tried EVERY digital pins for the SD_CS line.
I’ve disabled the DMA optimization for initial tests in the config file SdSpiSTM32F1.cpp
#define USE_STM32F1_DMAC 0

I’ve tried to use SPI1 for both the ILI9341 display and SD module, with a dedicated CS pin for the SD_CS.
I’ve tried the latest SPI library with the new SPI.setModule(2); in the setup section of my code. In that case I hooked the SD miso/mosi/sck on the SPI2, and specified the SD_CS (I tried the SS of the SPI2 and other pins like 0, 1 because I’ve seen some users got success with a mapple mini with that configuration)
Last but not least, I’ve tried various DIV_CLOCK settings (2, 4, 8) with no success too.
const uint8_t spiSpeed = SPI_CLOCK_DIV8;

If I define a pin with the STM32F103C8 naming scheme (PAxx/PBxx/PCxx, etc…), the display works, but, if i compile the sdinfo test sketch, I have a different numbering on the serial monitoring. For exemple, my PB13 has the pin number 33 shown on the serial monitor.

I don’t know what else to do now…

here is the code i use:

#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <ILI_SdSpi.h>
#include <ILI_SdFatConfig.h>
#include <ILI9341_due_gText.h>
#include <ILI9341_due.h>

// CS and DC for the LCD
#define LCD_DC PA1
#define LCD_CS PA4
#define LCD_RST PA0

#define SD_CS PB12 // Chip Select for SD card

#define BUFFPIXELCOUNT 320 // size of the buffer in pixels
#define SD_SPI_SPEED SPI_HALF_SPEED // SD card SPI speed, try SPI_FULL_SPEED
const uint8_t spiSpeed = SPI_CLOCK_DIV8;
SdFat sd; // set filesystem
SdFile bmpFile; // set filesystem
//ArduinoOutStream cout(Serial);

ILI9341_due tft(LCD_CS, LCD_DC, LCD_RST);

// store error strings in flash to save RAM
#define error(s) sd.errorHalt_P(PSTR(s))

void setup()
{
Serial.begin(9600);

SPI.setModule(2);
tft.begin();
tft.setRotation(iliRotation270); // landscape
progmemPrint(PSTR("Initializing SD card..."));

if (!sd.begin(SD_CS, SD_SPI_SPEED)){
progmemPrintln(PSTR("failed!"));
return;
}
progmemPrintln(PSTR("OK!"));
}


stevestrong
Mon Oct 19, 2015 8:43 pm
Hello all,
I have a problem with my SD card connected to a Maple mini clone.
I run the SdInfo sketch combined with the RawWrite sketch and it seems that no data can be written to the SD card.
Installed the latest versions from victorpv/SdFat and from the rogerclarkmelbourne/Arduino_STM32 github.
I am using SPI 2 with SPI_CLOCK_DIV8.
Reading from the SD card works. The card was formatted with SdFormatter.
A serial log looks like this:
SdFat version: 20150321

Assuming the SD is the only SPI device.
Edit DISABLE_CHIP_SELECT to disable another device.

Assuming the SD chip select pin is: 31
Edit SD_CHIP_SELECT to change the SD chip select pin.

type any character to start

init time: 1 ms

Card type: SD2

Manufacturer ID: 2
OEM ID: TM
Product: SA02G
Version: 0.3
Serial number: A07C6B9C
Manufacturing date: 12/2008

cardSize: 1973.42 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 80FF8000

SD Partition Table
part,boot,type,start,length
1,0,6,135,3854201
2,0,0,0,0
3,0,0,0,0
4,0,0,0,0

Volume is FAT16
blocksPerCluster: 64
clusterCount: 60214
freeClusters: 60212
freeSpace: 1973.03 MB (MB = 1,000,000 bytes)
fatStartBlock: 136
fatCount: 2
blocksPerFat: 236
rootDirStart: 608
dataStartBlock: 640

Starting RawWrite...
removing RAW.TXT...
creating contiguous...
createContiguous failed
SD errorCode: 13
SD errorData: FF


RogerClark
Mon Oct 19, 2015 9:04 pm
Welcome Steve…

Did you try on SPI1

SPI.setModule() is a fairly new feature, and I can’t recall if anyone fully tested it with SD cards


stevestrong
Mon Oct 19, 2015 9:28 pm
I just finished to try with SPI 1, first with SPI.setModule(1); and second with this line commented out, in both cases keeping the same SS line (31).
In both cases I get cardBegin error 0x02 0xFF.
What am I doing wrong?

madias
Mon Oct 19, 2015 9:42 pm
I only got the new SdFat library running with a specific card holder (without voltage converters, even useless for our 3.3V boards…) and specific SD-cards, does it work with the “standard” SD library?

stevestrong
Mon Oct 19, 2015 9:58 pm
Well, I haven’t tried with the standard lib.
But I have some news.
I tried to visualize the SPI CLK signal on my oscilloscope and – voila – it started to work on SPI 1!
But not on SPI 2.
It seems that the impedance on the SCK line is critical.

Can any of you acknowledge this?


RogerClark
Mon Oct 19, 2015 10:18 pm
Steve

You don’t need to call setModule(1) for SPI 1, its only required if you need to move the SPI class to use SPI2 or on some boards SPI3

Re: SCLK

I’ve not tried this on the Maple mini

I did build a simple audio player that read wav’s from a SD card on SPI1 and played them out a SPI audio interface on SPI2 and that worked reasonably well, but I did get occasional gitches on reading the SD card.

But the original SD card lib that the Arduino uses was not that good, and I recall that there has been some work done recently to improve it.

I think @victorPV may be the person who knows the most about this, as he wrote the DMA support for SPI and had it working with SD cards at one point.


stevestrong
Mon Oct 19, 2015 10:26 pm
Roger, thanks, I’m going to spend more time analyzing the signals with the scope, and compare SPI 1 to SPI 2 signals.
For SPI 1, it’s true, setModule(1) has no influence.
I’ll post later some results.

victor_pv
Mon Oct 19, 2015 10:52 pm
stevestrong wrote:Hello all,
I have a problem with my SD card connected to a Maple mini clone.
I run the SdInfo sketch combined with the RawWrite sketch and it seems that no data can be written to the SD card.
Installed the latest versions from victorpv/SdFat and from the rogerclarkmelbourne/Arduino_STM32 github.
I am using SPI 2 with SPI_CLOCK_DIV8.
Reading from the SD card works. The card was formatted with SdFormatter.
A serial log looks like this:
SdFat version: 20150321

Assuming the SD is the only SPI device.
Edit DISABLE_CHIP_SELECT to disable another device.

Assuming the SD chip select pin is: 31
Edit SD_CHIP_SELECT to change the SD chip select pin.

type any character to start

init time: 1 ms

Card type: SD2

Manufacturer ID: 2
OEM ID: TM
Product: SA02G
Version: 0.3
Serial number: A07C6B9C
Manufacturing date: 12/2008

cardSize: 1973.42 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 80FF8000

SD Partition Table
part,boot,type,start,length
1,0,6,135,3854201
2,0,0,0,0
3,0,0,0,0
4,0,0,0,0

Volume is FAT16
blocksPerCluster: 64
clusterCount: 60214
freeClusters: 60212
freeSpace: 1973.03 MB (MB = 1,000,000 bytes)
fatStartBlock: 136
fatCount: 2
blocksPerFat: 236
rootDirStart: 608
dataStartBlock: 640

Starting RawWrite...
removing RAW.TXT...
creating contiguous...
createContiguous failed
SD errorCode: 13
SD errorData: FF


RogerClark
Mon Oct 19, 2015 11:24 pm
The uno will feed 5v, so all is fine, but you may be feeding 3.3V form the mini to a regulator on board the sdcard module…

On the Maple mini, I think you can get the incoming 5V from the USB input via the VIN pin. But I can’t remember if its via a diode from USB power, and when I tested on one of my Maple minis it showed 4.8V

Just check whatever you feed your SD card module with, that it does seem to give 3.3V to the SD card, as I’ve noticed that some USB outputs are as low as 4.75V and sometimes the regulators won’t work unless you supply around 5V


stevestrong
Tue Oct 20, 2015 11:12 am
The maple mini clone (Baite) is fed from USB 5V and it has its own 3.3V regulator (LM1117-3.3V) on board. All components are fed with this 3.3V.
The SD card module has no regulator, and gets the 3.3V from the mini board. So no level converters are involved.
The card has class 10.
But I find strange that in order to work, the SCK line (SPI 1) had to be connected to the scope probe.
What does it actually mean? Wrong impedance?
Are the wires from Maple mini board to SD card module too long? Or too short?
Of course, the shorter the better, one would say. But the same length had no effect on Pro Mini with 8MHz SPI clock, fed from 3.3V supplied by a USB-serial converter board.
Maple mini SPI clock is 12 MHz according to the scope (DIV4). Is this 4MHz more than Pro Mini making so huge issues? Or is rather the shape of the signal?
Or is CPOL and/or CPHA issue? Or maybe NSS pin management related?
This is the direction I want to make more scope recordings, I think this would give answer to some users here in forum.
What do you think?
Does it make sense?
Meanwhile I will try to put an extra 10uF filtering capacitor to the 3.3V line and check whether it makes a difference or not.

Oh yes, I would like to finally have the SD card working on SPI 2 since I need the analog input pins 0…9 for my project.


ahull
Tue Oct 20, 2015 3:11 pm
stevestrong wrote:The maple mini clone (Baite) is fed from USB 5V and it has its own 3.3V regulator (LM1117-3.3V) on board. All components are fed with this 3.3V.
The SD card module has no regulator, and gets the 3.3V from the mini board. So no level converters are involved.
The card has class 10.
But I find strange that in order to work, the SCK line (SPI 1) had to be connected to the scope probe.
What does it actually mean? Wrong impedance?
Are the wires from Maple mini board to SD card module too long? Or too short?
Of course, the shorter the better, one would say. But the same length had no effect on Pro Mini with 8MHz SPI clock, fed from 3.3V supplied by a USB-serial converter board.
Maple mini SPI clock is 12 MHz according to the scope (DIV4). Is this 4MHz more than Pro Mini making so huge issues? Or is rather the shape of the signal?
Or is CPOL and/or CPHA issue? Or maybe NSS pin management related?
This is the direction I want to make more scope recordings, I think this would give answer to some users here in forum.
What do you think?
Does it make sense?
Meanwhile I will try to put an extra 10uF filtering capacitor to the 3.3V line and check whether it makes a difference or not.

Oh yes, I would like to finally have the SD card working on SPI 2 since I need the analog input pins 0…9 for my project.


stevestrong
Tue Oct 20, 2015 3:21 pm
Andy, I will try resistor and then capacitor as load in parallel.
I rather think that the probe actually introduces flatness (filtering instead of inducing noise) and/or phase shift to the signal.
The SCK signal on the scope display was quite ok, no spikes, sinusoidal shape.
I will post some more results later.

zmemw16
Tue Oct 20, 2015 3:35 pm
isn’t the scope probe just slowing the rise time?
stephen

RogerClark
Tue Oct 20, 2015 8:01 pm
What length of wire are you using between the Maple mini and the SD module.

Its always amazed me that running clocks and data at 10s of megahertz , down bits or normal wire or ribbon cable, works at all ;-)

These sorts of frequencies would have been considered “High Frequency” RF about 30 years ago.

To get sharp edges on square waves actually requires bandwidths of many hundred of Mhz.

Anyway.. I have experienced issues with crosstalk on ribbon cables on SPI, in the past,

So i suspect you are experiencing something similar, or ringing of the SPI clock or data lines.


stevestrong
Tue Oct 20, 2015 10:25 pm
Here are my first recordings.

The sketch is started, and the recording is triggered by the very first rising edge of the SPI 1 clock SCK.
Yellow is the SPI 1 SCK (pin 6), blue is CS chip select (pin 31 in my case, which belongs to CS of SPI 2).

A successful start – only the first millisecond – I suppose this is the introducing part with “sd.cardBegin()”:

Image

red is the first zoom in:

Image

yes, clock pulses are activated before an active chip select!
and yes, the first 4 (as well as following consecutive group of 3) rising edges are slow.
and here the second zoom in (green rectangular form the first image):

Image

There are 2 kind of pulse trains: smaller (left side of the CS high period) and larger (right side of CS high period).
The smaller are (let’s call them) “high-frequency” pulses (27MHz), here the last train generated after CS goes “high” !!!

Image

and the larger are low-frequency (9MHz) pulses:

Image

I think, these are the right pulses, how they always should be. But they aren’t, specially not at the beginning, where 27MHz pulses are generated.
Then after some condition, the CS is generated correctly before SCK (second falling CS edge), and the SCK pulses are also ok, the frequency goes down to 9MHz, which was actually selected by the sketch with SPI_CLOCK_DIV8:

Image

a better zoom in:

Image

And, at the end, after second rising CS edge, again, there are some additional clock pulses generated:

Image

Well, I don’t know what exactly is happening here, but it definitely strange.
Can someone explain these?

EDIT:
It looks like I managed to solve the probe issue, I soldered a 10uF capacitor directly onto the SD card module (Vcc-GND).
Now the sketch works on SPI 1 without the probe contact on SCK.
Probably the cross-talk has been decreased.
But the recorded signals still remained same as posted above.
TODO: record signals on SPI 2.


victor_pv
Wed Oct 21, 2015 12:10 am
I don’t remember all the details, but SD cards use some tricks in the initialization with the control signals, that may explain CS activating before clock, may be totally intentional. You could check the library code and see what it does. I really haven’t look at anything except the SPI functions to send data, which is the part I adapted to the mini, but I have not clue about the whole sdcard protocol except little snipets from reading here and there.

stevestrong
Wed Oct 21, 2015 8:58 am
OK, the pulse train generated while CS is inactive (“1”) looks similar to a well known technique applied on I2C-bus to avoid hang-up of any slave device.
But what about the 27MHz frequency pulses on SCK? Are they also deliberately generated? For this I cannot find any meaningful explanation.
For me it looks like the SW tries to access the SPI bus before the correct frequency was set up.
And how about the funny behavior of the SCK before the 27MHz pulses come? The signal goes to “0” and after a while slowly back to “1”, seems like push-pull is not activated. What is the reasoning behind?
I have to take a deeper look into the SPI driver part used by the SdFat lib.

RogerClark
Wed Oct 21, 2015 9:40 am
Which pin are you using for SS / Chip Select ?

If you are using the one on the Maple Mini, labelled as SS, (I think its Pin 7) try using another one.

There is a known issue with the SS pin not behaving. Its a fault / feature of the STM32 its self, and there wasnt a lot we could do about it.

I recall we tried to put in a work-around for this pin missbehaving, but I can’t remember precisely what the issue was or what the work-around was.

I’m sure someone one the forum will remember the details ;-)


mrburnette
Wed Oct 21, 2015 12:01 pm
RogerClark wrote:<…>
I’m sure someone one the forum will remember the details ;-)

stevestrong
Wed Oct 21, 2015 2:22 pm
As stated above, I am using the NSS port of SPI 2, pin 31, or PB12.
Does this pin behave the same or have same bug as PA4?

mrburnette
Wed Oct 21, 2015 3:21 pm
stevestrong wrote:As stated above, I am using the NSS port of SPI 2, pin 31, or PB12.
Does this pin behave the same or have same bug as PA4?

victor_pv
Thu Oct 22, 2015 4:47 am
This is what I remember, without looking for the thread:
1.- We found the part of the core in which the NSS pin is set to AF (to be controller by the SPI peripheral itself)
2.- We removed that line, so NSS remains as GPIO.
3.- From that point on the core allows to keep using the NSS pin as GPIO after an SPI port has been started. It is not under direct control of the SPI peripheral when you start the SPI port.

The above applies to any SPI port, 1 to 3 (in devices with 3 ports). So any code using controlling the CS pin as any normal GPIO pin can use the NSS pin for CS, or anything else for that matter. It is not NSS anymore in our core unless Roger reverted that change at some point, which I don’t remember reading.

EDIT:
Regarding the sck pulses when CS remains low, I am almost certain that is part of the normal way of communicating with the SD card. Do a search in google for SD card in spi mode, and you should find all the details, but I remember reading about a bunch of tricks that are done will all the control lines in the SD card to set them up. I just don’t remember the exact things that were done, but google is your friend ;)
There it is all explained about those pulses:
http://elm-chan.org/docs/mmc/mmc_e.html


stevestrong
Thu Oct 22, 2015 8:26 am
Thanks you all for your answers.

I have also found the place where the 74 or more SCK pulses (needed for SD card init) are generated while SS is high (inactive). However, these pulses are generated with a 27MHz clock (line 132 of SdSpiCard.cpp, using SPI_SCK_INIT_DIVISOR). Shouldn’t here already the input parameter “sckDivisor” be used? At least in the case where the SD card does not support 27MHz.

Another issue is the 3 slow and wide SCK pulses before the normal data transfer pulses. Did I understand correctly: this is a bug in the silicon and will be generated by the HW when the SPI CR register is written (e.g. data mode, bit order and clock divider)?
Can anyone confirm this?

A third topic (low prio) would be that it seems that spi_init() is superfluously called in line 133 of SdSpiCard.cpp. The init routine will be called anyway in chipSelectLow() (line 207), at the beginning of each card command. Btw, isn’t any faster option to set/clear the SS pin other than digitalWrite() – lines 296 and 279?

[Off topic: how can be generated a function call graph in the easiest way?
Maybe automatically generated and checked in once after each code change?]

RogerClark
Thu Oct 22, 2015 9:00 am
I’d try writing some basic code calling SPI transfer etc and see if you get the same results.

The problem with the SD card lib, is that from what I’ve seen, its code that has evolved over a number of years and I suspect there are lots of legacy calls which end up doing the same setup more than once.

In our SPI lib, it takes a cautious approach, so its quite possible that it re-inits more than it needs to, but this generally means that we don’t have that much trouble with it.

Re: faster methods than digitalWrite

Yes, plenty of faster ways.

There are internal gpio calls in libmaple that could be called directly

Or the hardware registers can be manipulated directly, and you could cache the CS port and mask details.

However on the whole, this isnt a big issue either, unless the code is setting and resetting CS every time a byte is transferred.

But really thats a issue with the higher level code, ie the library that is using SPI


stevestrong
Thu Oct 22, 2015 9:46 am
Roger, I agree with you, robustness may be more important than code optimization.
Anyway, as I told, is not a big issue, and this place seems really not to be very critical since is one time action for transferring several bytes.

Still, the other issue with those 3 wide pulses on SCK line before the normal data transfer pulses really bothers me, they should not be there. And I am not sure whether they cause any problems when accessing the SD card, specially when they occur while SS is active low.
I think it is important to find out why are they there. I need to dig deeper…


RogerClark
Thu Oct 22, 2015 9:58 am
Thanks Steve

I agree, we should not have extra pulses.

I think several people have looked at the SPI, with logic analysers and scopes, over the last 6 months or more, and I don’t remember anyone seeing any extra pulses, so this problem may be specific to the SD lib

Anyway. Thanks for investigating this strange phenomenon


mrburnette
Thu Oct 22, 2015 12:11 pm
stevestrong wrote:<…>
I think it is important to find out why are they there. I need to dig deeper…

stevestrong
Thu Oct 22, 2015 9:26 pm
So, here you have a plot taken with SPI_CLOCK_DIV4. This is what I call a clean signal :).

Image

The SPI speed has not much influence on the run-time performance, DIV4 or DIV8 gives pretty much the same results, so I would suggest use DIV8 to keep on the safe side. DIV2 (full speed) haven´t tried yet.

The changes:
SdSpiCard:
– ::begin() – swapped call sequence between spiBegin() and spiInit(). I think it is normal that the initialization should be done before the interface is started (begin).
– chip_select_low() – remove the line with spiInit(), which has been already called in begin(), no need to call it all over again.
SPI.cpp
– remove the call of this.begin() from the functions setClockDivider(), setBitOrder() and SetDataMode(). Same reasoning, the SPI::begin already executed before.

After these changes the funny wide pulses are gone, no more pulses with 27MHz, the card behaves very robustly, no more scope probe problem at all!

The only small issue is a problem with the serial interface, some data sent with Serial.print() is sometimes not displayed, and other times is displayed doubled or tripled in the COM window. I am not sure whether my changes have influenced the DFU behavior or is just my PC which was not rebooted since a week…

Attached my local copy of these files.

The setup consists of only one SD card module on SPI 1, SS is maple mini pin 31, or PB12.
The same sketch as in my first post.

EDIT:
Here is the serial output:
SdFat version: ******* the version number for some reason will not be displayed ******
init time: 0 ms

Card type: SD2

Manufacturer ID: 2
OEM ID: TM
Product: SA02G
Version: 0.3
Serial number: A07C6B9C
Manufacturing date: 12/2008

cardSize: 1973.42 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 80FF8000

SD Partition Table
part,boot,type,start,length
1,0,6,135,3854201
2,0,0,0,0
3,0,0,0,0
4,0,0,0,0

Volume is FAT16
blocksPerCluster: 64
clusterCount: 60214
freeClusters: 60207
freeSpace: 1972.86 MB (MB = 1,000,000 bytes)
fatStartBlock: 136
fatCount: 2
blocksPerFat: 236
rootDirStart: 608
dataStartBlock: 640

Starting RawWrite...
removing RAW.TXT...
creating contiguous file...
getting contiguous range...
Start raw write of 51200 bytes at
51200 bytes per second
Please wait 1 seconds
RawWrite done
Elapsed time: 1.00 seconds
Max write time: 557 micros
Overruns: 0

type any character to start


RogerClark
Thu Oct 22, 2015 10:36 pm
SPI.cpp
– remove the call of this.begin() from the functions setClockDivider(), setBitOrder() and SetDataMode().

I’m surprised this works.

if you look in setClockDivider, all it does is set a property called _currentSetting->clockDivider, it doesnt actually change the hardware

The reason it calls begin(), is because begin calls

spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags);

Which actually sets up the hardware, and to do this it has to disable the SPI hardware and then make those changes and then re-enable the SPI hardware

It has to do this because some changes (I think bit order is one of them), can’t be changed if the SPI interface is active.

You could try writing a loop to call

spi_peripheral_disable(dev);
spi_peripheral_enable(dev);


stevestrong
Thu Oct 22, 2015 10:54 pm
Roger, the function spi_master_enable() is actually called already by spiBegin() from the beginning of SdSpiCard::begin(), after spiInit() – in my version.
spiBegin() calls SPI.begin(), which calls spi_master_enable() after executing spi_init() and configure_gpios().
So I think the HW will be correctly initialised and started… that’s why is working… I guess…

RogerClark
Thu Oct 22, 2015 11:06 pm
Steve

I expect the default SPI config for some things like byte order, is fine for the SD card, which is why its working.

But if you remove the calls to begin() from the setByteOrder etc, some other devices will not work.

Can you test if its the act of disabling and re-enbling the SPI hardware that’s causing the glitch

It could also be that the code is returning the SPI pins to GPIO mode (probably inputs), which cause the glitches


stevestrong
Fri Oct 23, 2015 8:33 am
But if you remove the calls to begin() from the setByteOrder etc, some other devices will not work.
I see what you mean, I also had some thoughts about it.

I checked the whole STM32 repo, there are quite few places (only 7 files!) where these functions are called.
In those cases the SPI.begin() is always called before.
I think this is generally not quite ok. In my view, begin() is not init(), and init() should come first.
I assume, the setByteOrder() and similar functions belong to init part, right?
That means, the working parameters should be setup first, and only afterwards call begin().

On the other side, the function SPI.begin() also calls the function spi_init(), which executes an RCC enable and reset. Hence, each time begin() is called, beside calling spi_master_enable(), the RCC is reset. I think the repeated RCC reset and master enable makes no sense and therefore should be avoided. Maybe this is the reason why what I got rid of glitches by applying my changes.

I know, one try to avoid changes which could affect other libs. But I think with these changes we could really improve the lib.
As an alternative to remove lines which call begin(), I would maybe introduce a semaphore variable to monitor whether begin() was called before, and don’t call it again if it is the case.

What is your opinion?

EDIT:
The reason it calls begin(), is because begin calls

spi_master_enable(_currentSetting->spi_d, (spi_baud_rate)_currentSetting->clockDivider, (spi_mode)_currentSetting->dataMode, flags);

Which actually sets up the hardware, and to do this it has to disable the SPI hardware and then make those changes and then re-enable the SPI hardware
Because of this, without changing the calling order of init() and begin(), the idea with semaphore variable won’t work.


RogerClark
Fri Oct 23, 2015 10:03 am
Hi Steve,

The code for the SPI lib was inherited from the original Leaflabs libmaple libraries. We made some changes to it, but I don’t recall changing begin();

I don’t know why Leaflabs needed to call rcc_clk_enable or rcc_reset_dev, (unfortunately they have not responded to questions on github etc for well over a year, and they have not participated on the old leaflabs forum for several years (as far as I can tell).)

But I’d guess that you have to setup the rcc_clk and reset the SPI device before you can use it at all.

If some libs call begin multiple times, we could probably put flags into spi_init() so that it doesnt re-init if its already been inited, but I suspect that the reason that the is done on every call to begin() is in case someone decides to set the pinMode of on of the SPI pins, between calling one begin() on one transfer and another begin() on another transfer

Re: setBitOrder being called ??

I’m not sure what you mean. As far as I can see setBitOrder is only called in SPI.cpp from beginTransaction

If another lib or a sketch calls this, its out of our control

setBitOrder can be called at any time, before or after SPI.begin(), so I can’t see how the code can do anything but disable the spi hardware, change the setting, and re-enable the hardware

Albeit, it does this by calling spi.begin() but even if I copied the code from spi.begin() into setBitOrder, it would be the same code.

We can probably make some improvement by changing

void SPIClass::setBitOrder(BitOrder bitOrder)
{
#ifdef SPI_DEBUG
Serial.print("Bit order set to "); Serial.println(bitOrder);
#endif
_currentSetting->bitOrder = bitOrder;
this->begin();
}


stevestrong
Fri Oct 23, 2015 11:27 am
I’m not sure what you mean. As far as I can see setBitOrder is only called in SPI.cpp from beginTransaction

If another lib or a sketch calls this, its out of our control

you can check it here: https://github.com/rogerclarkmelbourne/ … etBitOrder
Usually setBitOrder, setClockDivider and setDatMode are called sequentially after each other.
For example: https://github.com/rogerclarkmelbourne/ … _ports.ino.
void setup() {

// Setup SPI 1
SPI.begin(); //Initialize the SPI_1 port.
SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
SPI.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
SPI.setClockDivider(SPI_CLOCK_DIV16); // Slow speed (72 / 16 = 4.5 MHz SPI_1 speed)
pinMode(SPI1_NSS_PIN, OUTPUT);

// Setup SPI 2
SPI_2.begin(); //Initialize the SPI_2 port.
SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
SPI_2.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
SPI_2.setClockDivider(SPI_CLOCK_DIV16); // Use a different speed to SPI 1
pinMode(SPI2_NSS_PIN, OUTPUT);

}


mrburnette
Fri Oct 23, 2015 12:13 pm
I think before too many cycles are expended in init() and begin() one should go back to the Arduino core and itemize how these functions are being utilized (or Teensy3 for that matter.) A state diagram of the called functions may shed light on this issue as I do not know if ‘initialize’ and ‘begin’ are actually being used as the name-definition suggests.

One needs to recognize, also, that the Leaflabs core was written prior to Arduino 1.0 which was a huge architectural and structural change for Arduino libraries.

Ray


stevestrong
Fri Oct 23, 2015 12:46 pm
A simple analysis:
SPI.cpp
original function :

void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
{
#ifdef SPI_DEBUG
Serial.println("SPIClass::beginTransaction");
#endif
//_SSPin=pin;
//pinMode(_SSPin,OUTPUT);
//digitalWrite(_SSPin,LOW);
setBitOrder(settings.bitOrder);
setDataMode(settings.dataMode);
setClockDivider(determine_baud_rate(spi_d, settings.clock));
begin();
#if 0
// code from SAM core
uint8_t mode = interruptMode;
if (mode > 0) {
if (mode < 16) {
if (mode & 1) PIOA->PIO_IDR = interruptMask[0];
if (mode & 2) PIOB->PIO_IDR = interruptMask[1];
if (mode & 4) PIOC->PIO_IDR = interruptMask[2];
if (mode & 8) PIOD->PIO_IDR = interruptMask[3];
} else {
interruptSave = interruptsStatus();
noInterrupts();
}
}
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
bitOrder[ch] = settings.border;
SPI_ConfigureNPCS(spi, ch, settings.config);
//setBitOrder(pin, settings.border);
//setDataMode(pin, settings.datamode);
//setClockDivider(pin, settings.clockdiv);
#endif
}


victor_pv
Fri Oct 23, 2015 1:00 pm
Steve it seems that putting them in that order makes sense.
I don’t think anyone has put much effort in rewriting examples except if they didn’t work. There is loads of code that’s really old and difficult to keep track on who did what and why.

I would suggest that in the examples that you have corrected and verified, open a new thread to comment, in case other people can test them to have more reassurance, and then send a pull request to Roger.
We have Roger always busy doing changes, while he still needs to tend his actual obligations, so anything we can do to save his time is good.
Sending a pull request saves him from having to go to those files and rewrite them personally.

About the sdFat library, Greyman has it as a work in progress in github, and has commented that there is loads of old code he needs to go thru. For changes that improve his library stability, I would suggest you tell him, so he is aware, and he can even add them to the library if he sees the benefit.

My copy was meant to be only temporary, I actually need to send him a new pull request as the one I initially sent him had the wrong files by accident.

Now, about removing begin() from those 3 functions, the question is, does the official arduino library call begin on those?
if it does, it is very likely that removing it in our core will break compatibility with other libraries that may not call begin in the order you suggest, because they rely on those functions calling it.
As Roger commented, those functions in our core set a parameter, but do not apply it to the hardware, so unless begin is called by either the function or the code using it, the setting would not be effectively applied.
If you want to remove begin() from those, I would suggest that you check what part of begin() applies each of those settings to the hardware, and modify those functions so they actually apply the setting besides saving the parameter.


stevestrong
Fri Oct 23, 2015 6:35 pm
OK, so now it looks that the things are not so simple as I thought.
I wanted to be conform to and therefore read about the SPI reference on Arduino reference homepage. A total mess…
There is written:
setClockDivider()
Description
This function should not be used in new projects. Use SPISettings with SPI.beginTransaction() to configure SPI parameters.

Now, should we keep backwards compatibility to older libs with these three small extra functions or not?

In my opinion we should adapt the new interface to SPI lib, via beginTransaction() and SPISettings.
The users could always easily adapt their sketches to be conform to latest SPI changes, but not the custom libs.
However, I think most custom libs have already switched to the transaction-based API, so it seems normal to follow that way.

But going one step further, the site https://www.arduino.cc/en/Reference/DueExtendedSPI suggest a special usage form, without beginTransaction(), by simply using the pin number as parameter for transferring data. Hmmm.
On the top, the beginTransaction() example (https://www.arduino.cc/en/Tutorial/SPITransaction) uses again another approach, suggesting the user to manage the settings by its own.

Now, which example should we take as reference? All of them should be supported?
This is important to decide because the development depends on this decision.


RogerClark
Fri Oct 23, 2015 10:14 pm
Now, should we keep backwards compatibility to older libs with these three small extra functions or not?

There are so many legacy libraries and so much code out there which uses the old functions, we can’t simply not support them.

Re: Due Extended functionality

I think this is very SAM specific, where they can move the hardware CS pins to alternates.

We can’t even use the hardware CS because of issues with the way ST think it should work, i.e as has been posted in this thread, most people have a problem with the way the hardware CS on the STMF103 etc work, and end up just using GPIO for CS

So there is no point in attempting to mimic Due specific stuff..

IMHO, the Due never caught on. I have 2 of them, and have never used either. As far as I can tell not many people use the Due.
The new Arduino Zero (which also uses a SAM type MCU) may be a different story, only time will tell
But I’m not sure if it supports the Due Extended SPI either.. As its a SAMD chip, so may not have the same capabilities as the Due.

Re: Transactional SPI

I made a stab at adding the transactional SPI code (as it wasn’t in the original LeafLabs code)
But I’ve never thoroughly tested it, because not many libs use it.

I just did a google search to see how may places SPI.begintransaction( occurs e.g.

Search google for

"SPI.beginTransaction("


mrburnette
Fri Oct 23, 2015 11:42 pm
… in terms of what people are likely to want. The old style far outweighs the transactional.

The entire transactional approach was implemented by Paul for Teensy 3.x Now, we hashed this once regarding the STM32duino months ago and while many libs (Adafruit’s and Teensy3.x) were updated, most non-commercially distributed were not. So, we have a legitimate concern. If we change the core approach … things will break. “Working vs Proper but broken” is little use to noobies. I think this is one of those situations where “improvements” would bite someone in the arse.

I have not looked at Paul’s stuff in ages…
http://www.pjrc.com/teensy/td_libs_SPI.html

Ray


stevestrong
Sat Oct 24, 2015 9:05 am
OK, so let’s go the conservative way, at least with regard to the SPI lib, which is used in many custom libs.
Following Roger’s idea to toggle spi_master_enable/disable, it seems that this works. The glitches are still there but in very reduced form, so it seems that they are not disturbing anymore.

Regarding SPI 2, I reported already that the data reading was working but the writing not. Well, it seems to be a bug in SdSpiSMT32F1.cpp.
https://github.com/victorpv/SdFat/blob/ … TM32F1.cpp
In function “void SdSpi::send(const uint8_t* buf , size_t n)”, lines 92-94, there is SPI 1 device used as fixed parameter, so there is no chance for SPI 2 to work. :)
if (spi_is_rx_nonempty(SPI1)) {
uint8_t b = spi_rx_reg(SPI1);
}


zmemw16
Sat Oct 24, 2015 12:39 pm
i suppose the classic way would be to fork it, or as in the title newSPI and NewSd* or add _STM as per Adafruit_GFX

i can’t see many libraries being ported back to AVR, but if required as multi-platform we already test
for _STM32F1_ etc.

stephen


victor_pv
Sat Oct 24, 2015 1:16 pm
Regarding those 3 lines, I don’t completely remember anymore.
They were in the version for the SAM, and maybe in the version for the Arduino. I am sure I tested with and without them, but left them just to avoid deviating much from the SAM version.

All it does is just empty the last byte from the RX buffer.
I would have to go and read the SPI library and the datasheet to see how the actual transfer function works, but I dont have time.

Now this is what I remember, although may be wrong. When we do a transfer, the MCU will be reading incoming bytes to the RX buffer.
Once we write the last byte to the TX buffer and the peripheral sends it out, it still reads one more byte to the RX buffer.
If the SPI library write function manages that correctly so that last incoming byte does not go as the first read value the next time you do a transfer, all is good. But if the byte is instead left waiting in the RX buffer, and the SPI functions read and return it as if it was the first read value, then it needs to be discarded.

I believe at some point I took it out, then I added it again because of some issues, that most likely were not really caused by that, but could be. You can either test with and without it, or check the SPI library to make sure a byte read in the last previous transfer is not going to be provided as the first read in the next transfer.

EDIT:
The fact that those lines using SPI1 prevent the write to function correctly in SPI2, seems to indicate those lines are actually necessary. They just need to use the correct port thought and not just read from SPI1 always.

EDIT2:
Just had a look at the write function in SPI.cpp
It goes to read from the RX buffer if there is anything waiting on it.
I believe the datasheet explains that when you send a byte, the MCU will always read what’s coming from the MISO line. In which case any read or transfer may leave a byte waiting in the RX buffer which could wrongly be picked up by the next read. I think it would be better to actually modify the functions that send data out to make sure they leave an empty RX buffer on exit.

I see I did that with the dmaTransfer functions, but did not add it to the existing ones. I would think it should be added to the write and transfer functions that do not have it yet.


stevestrong
Sat Oct 24, 2015 3:14 pm
The fact that those lines using SPI1 prevent the write to function correctly in SPI2, seems to indicate those lines are actually necessary. They just need to use the correct port thought and not just read from SPI1 always.
Exactly my opinion.
Victor, I would suggest you update SPI.cpp and SPI.h in your github repo.

stevestrong
Mon Oct 26, 2015 12:15 pm
@ Roger,
I made two pull requests regarding the SPI.cpp, please disregard the first one, it is wrong, the change should have been inserted into line 349.
The second one is to solve the glitches before the SCK real pulses.

@Victor, I made a pull request to solve the bugfix regarding SPI 2 writing problem.
And another pull request to change the calling sequence between init() and begin().


RogerClark
Mon Oct 26, 2015 5:13 pm
steve

ok I will close the first PR and test the second one.


victor_pv
Sat Nov 07, 2015 1:24 am
Steve I have been away from the forums for a while due to lack of time. I believe you sent some pull request with changes to the sdFat library.
Is it all tested and stable now, or do you need to add any other change before I merge?

stevestrong
Sat Nov 07, 2015 7:58 pm
Hi Victor,
I have tested it as much as I could, used the RawWrite example to record analog data sampled in dual channel simultaneous mode.
So far everything looks fine.
Of course, it would be better when more people could be involved in testing, but i still would apply the PR.

robca
Wed Dec 02, 2015 9:14 am
In this page https://github.com/rogerclarkmelbourne/ … /Libraries

Latest SdFat, modified version from https://github.com/victorpv/SdFat seems to work fine. If you want the best performance for large transfers, can use DMA mode, but that requires the latest SPI Library from https://github.com/victorpv/Arduino_STM … raries/SPI . Does not need the updated SPI files if you don’t use DMA mode. DMA can be enabled or disabled editing SdSpiSTM32F1.cpp, read the file to know what to modify.

Is that info still correct?

If I download https://github.com/rogerclarkmelbourne/ … master.zip I see that the files are from Nov 21. Would that contain all the fixes discussed in this thread?


RogerClark
Wed Dec 02, 2015 10:31 am
PM @stevestrong

He was the last person to have a good look at this.

I’m sure he will be able to tell you the best lib to use


stevestrong
Sun Dec 06, 2015 3:37 pm
I think the part Does not need the updated SPI files if you don’t use DMA mode. is wrong.
The new files are needed for a smooth SPI operation, at least on SPI 2, check out my latest PR.
However, I only tested w/o DMA. AS Victor said that between w/ and w/o DMA the difference is not that huge, I keep using the standard non-DMA way.

robca
Sun Dec 06, 2015 10:01 pm
Hello Steve, what version of the libraries and core files have you used to make everything work?

Is the info I posted (below) correct?

Latest SdFat, modified version from https://github.com/victorpv/SdFat seems to work fine. If you want the best performance for large transfers, can use DMA mode, but that requires the latest SPI Library from https://github.com/victorpv/Arduino_STM … raries/SPI . Does not need the updated SPI files if you don’t use DMA mode. DMA can be enabled or disabled editing SdSpiSTM32F1.cpp, read the file to know what to modify.


stevestrong
Sun Dec 06, 2015 10:27 pm
Hi Roger, honestly, I’m not quite sure about the core version.
I use Github for Windows, I synchronized, and I could see all the PRs from your development and master branch, and the Github GUI tells me that it would be the STM32 master branch… So I only can hope that it is indeed the STM32 master branch, since all my “Github” knowledge reduces to commit and sync…and sometimes, by chance, to a real PR :)
Can you see what I have changed? Only 2 files are involved.
The SdFat version is from Victor’s repo + my PR from there.

Regarding the info, as I told, didn’ test the DMA. And for the “normal” SPI2 (w/o DMA) to work, and to make the glitches gone, my changes would be mandatory.


RogerClark
Mon Dec 07, 2015 12:35 am
I generally use the git shell

then CD into the Arduino_STM32 folder and type

git checkout development


Manny
Wed Dec 09, 2015 5:29 pm
Finally got this to work on my Olimexino with its integrated sd card on SPI 2. The library is about twice as fast as the old Sdfat ported to libmaple.
Did a few of the examples and not got any errors, DMA seams like a worthwhile boost specially in read with a 85% increase.

The bench example with card on full speed DMA on.
Free RAM: 11783
Type is FAT32
Card size: 31.91 GB (GB = 1E9 bytes)

Manufacturer ID: 0X3
OEM ID: SD
Product: SL32G
Version: 8.0
Serial number: 0X55BA300
Manufacturing date: 2/2015

File size 5 MB
Buffer size 512 bytes
Starting write test, please wait.

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
255.46,75601,1523,2002
262.07,61258,1518,1951
257.48,67833,1524,1986
256.38,72433,1526,1995
257.68,60078,1525,1985
258.06,81216,1510,1982
251.27,69162,1535,2036
257.68,68508,1525,1985
252.89,77578,1525,2022
256.22,73986,1518,1996

Starting read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
1060.15,1281,477,482
1059.70,1281,477,482
1059.70,1277,478,482
1060.15,1278,477,481
1059.70,1276,478,482

Done


robca
Sun Dec 20, 2015 10:35 pm
I need help in figuring out what I’m doing wrong.

I have a standard SD Card reader, which I tested with a 3.3V Arduino Pro Mini: it works with a Patriot test card, both using the Arduino SD library and the newer SDFat one

I can’t make it work on the Maple Mini. According to viewtopic.php?f=28&t=37&start=10#p723 I connected MOSI to pin4, MISO to 5, SCK to 6. I tried both 7 and 10 as CS, with no difference.

I’m using a new download of the Master repository (hence I have the latest SPI files), and downloaded and installed as library Victor’s port of SdFat (https://github.com/victorpv/SdFat). I’m using the code below:

#define SD_CS_PIN 10
#include <SPI.h>
#include <SdFat.h>
SdFat SD;

File myFile;

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);

pinMode(7, OUTPUT);
pinMode(10, OUTPUT);

if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");

// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);

// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}

// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");

// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}

void loop() {
// nothing happens after setup
}


Manny
Sun Dec 20, 2015 11:09 pm
I would use a schematic for the board attached to work out which pins go to what header.

stevestrong
Mon Dec 21, 2015 7:56 am
I would use SCK divider in SD init, because the default one may be to high:
#define CS PA4
sd.begin(CS, SPI_CLOCK_DIV8)

robca
Mon Dec 21, 2015 4:16 pm
Thanks Steve.

I tried pretty much all the divisor values possible, but still won’t initialize (this is similar to a problem reported in another thread). The PA4 vs Pin 7 doesn’t seem to make any difference, either

I connected a Saleae clone with SPI protocol, and I can see that the Arduino board uses a slow signal. But even if I divide the clock enough to be in the same range as the Arduino, the card still won’t initialize. I can see that chip select correctly goes low both using PA4 and pin 7

On the other hand, I can use the standard Arduino SD card library. What I noticed is that the initialization routine for the old card uses a very slow clock (~250kHz), while the new library (even when using 128 as a divider in SdFatConfig.h) uses ~500kHz. I can actually use the full SPI speed with my Class6 card when reading and writing with the old library (at a full 2.5MHz)

Lastly I noticed that there is a SdSpiSTM32F1.cpp file in the library, but the library always uses SdSpiCard.cpp and doesn’t seem to use the F1 version (I added Serial.print statements in all functions, and none was used). Is that a configuration error on my side?

Do you mind sharing the SdFatConfig.h file you are using?

My experience is similar to previous reports, where some people can use the standard SD card library, but not the new one… I wonder if there’s still a bug somewhere, in the SPI implementation (I have checked, btw, and my SPI code is identical to the one in Victor’s repository)

As an aside: what do people use to debug? I have an STLink, and would prefer debugging thru it, than having to add serial.print everywhere


stevestrong
Mon Dec 21, 2015 5:04 pm
@robca,
I am using the default files of the SdFat lib, didn’t make any change.
I spent a lot of time in order to make SPI2 work, but honestly I didn’t spend to much time to work with SPI1, only shortly checked and it worked.
However, u should consider to check out the “development” branch, as there are some sensitive changes committed regarding SPI needed by SdFat to work on SPI2, and it may be relevant also for SPI1.

The file SdSpiSTM32F1.cpp should be in use, for example the function init(). The rest of functions are mostly thin wrapper for calling functions of SPI.cpp.
Finally, if nothing else helps, please check the selected board type in Arduino.
Is your board a Baite-clone or an original one?


RogerClark
Mon Dec 21, 2015 9:17 pm
Try the development branch of the repo, instead of the Master

The development branch has Steve’s latest fixes, but I have not had time to merge the development back into Master and test it..


robca
Mon Dec 21, 2015 9:34 pm
stevestrong wrote:@robca,
I am using the default files of the SdFat lib, didn’t make any change.
I spent a lot of time in order to make SPI2 work, but honestly I didn’t spend to much time to work with SPI1, only shortly checked and it worked.
However, u should consider to check out the “development” branch, as there are some sensitive changes committed regarding SPI needed by SdFat to work on SPI2, and it may be relevant also for SPI1.

The file SdSpiSTM32F1.cpp should be in use, for example the function init(). The rest of functions are mostly thin wrapper for calling functions of SPI.cpp.
Finally, if nothing else helps, please check the selected board type in Arduino.
Is your board a Baite-clone or an original one?


zmemw16
Tue Dec 22, 2015 2:35 am
daft idea, but could this manifest itself as display flicker on the tft ili9341 displays i’ve been trying to get to work?
i get a white screen, with the shade of white changing in sync with test mode changing.
the working one, now one and a bit as something waggled with a second and it showed bits of the test display with much flickering.
i was beginning to think it might be timing in the init sequence for the controller.

stephen


stevestrong
Tue Dec 22, 2015 12:43 pm
doesn’t belong this topic to another thread? It can maybe related to SPI, but not to SdFat lib.

zmemw16
Tue Dec 22, 2015 12:55 pm
apols, i agree.
i’ll re-post in problems with libraries.

it was the mention of ‘tight’ timings and the cs signal being applied earlier that woke me up.
anyways i off to get the devel branch and try it out … …

stephen


racemaniac
Sun Apr 17, 2016 6:21 pm
I’ve recently been playing around with DMA to offload my cpu for an IO intensive project i’m working on, and so far wrote some small libraries of my own so when the DMA is running, i can do other work while it’s doing its thing.

I’ve also been playing around with this library, and was wondering if we could make it even more powerful than it already is by allowing you to do other things while the DMA is working.

My simplest thought so far is: what if you can pass a method it has to loop for you while you’re waiting for DMA (could be the main loop method of your arduino project). It hardly takes any changes at all to the library (just allow the user to set that method, and put the call to that method in the loops where you’re waiting for the DMA to finish, and you’re done). This may not be the most efficient way of doing it, but you’ll probably get 80% of the result for 1% of the work :).

Ideally you would start a call, and it would do its thing in the background, and use interrupts to see state changes & react on them, and you can periodically poll it to see if it’s done yet and then read your result, but that would be a big redesign of the library :). And it probably won’t gain that much compared to the simple solution :).


rexnanet
Mon Jun 13, 2016 10:05 am
e-dredon wrote:Good afternoon all.

I didn’t have any success yet with the SD module of my ILI9341 LCD display, and the optimized SdFat library.

Now with my STM32F103C8T6 (bluepill)
I tried EVERY digital pins for the SD_CS line.
I’ve disabled the DMA optimization for initial tests in the config file SdSpiSTM32F1.cpp
#define USE_STM32F1_DMAC 0

I’ve tried to use SPI1 for both the ILI9341 display and SD module, with a dedicated CS pin for the SD_CS.
I’ve tried the latest SPI library with the new SPI.setModule(2); in the setup section of my code. In that case I hooked the SD miso/mosi/sck on the SPI2, and specified the SD_CS (I tried the SS of the SPI2 and other pins like 0, 1 because I’ve seen some users got success with a mapple mini with that configuration)
Last but not least, I’ve tried various DIV_CLOCK settings (2, 4, 8) with no success too.
const uint8_t spiSpeed = SPI_CLOCK_DIV8;

If I define a pin with the STM32F103C8 naming scheme (PAxx/PBxx/PCxx, etc…), the display works, but, if i compile the sdinfo test sketch, I have a different numbering on the serial monitoring. For exemple, my PB13 has the pin number 33 shown on the serial monitor.

I don’t know what else to do now…


stevestrong
Mon Jun 13, 2016 11:18 am
It looks like issues are observed with SdFat together with ILI9341 lib.
Shouldn’t one start a separate thread for this?
I mean, here I would discuss issues related only to SdFat. Wouldn’t make sense?

VadimEL
Sun Aug 21, 2016 5:00 pm
how to replace one char in position ???

I have 70Kb file f.txt, like
1234567890qwertyiopasdfghjkl


martinayotte
Sun Aug 21, 2016 6:56 pm
file.seekSet(10);

VadimEL
Sun Aug 21, 2016 8:01 pm
martinayotte

ok, thanks work fine, then I change to 1 ” #define SD_SPI_CONFIGURATION 1″
I can write to file and SeekSet is work

but led PB1 is lights, and all work fine….

pinMode(SD_CS, OUTPUT);
if (!SD.begin(SD_CS))
{
Serial.println("initialization failed!");

pinMode(PB1, OUTPUT);
digitalWrite(PB1, HIGH); // turn the LED on (HIGH is the voltage level)

return;
}
Serial.println("initialization done.");


martinayotte
Mon Aug 22, 2016 1:03 pm
What do you mean ?
Do you mean it was working with SD_SPI_CONFIGURATION to zero and stop working when 1 ?

VadimEL
Tue Aug 23, 2016 12:02 pm
#include <SD.h> has no seekSet function, and #include <SdFat.h> has not working with ” #define SD_SPI_CONFIGURATION 1″
I change to ” #define SD_SPI_CONFIGURATION 1″ and it work.

martinayotte
Wed Aug 24, 2016 12:28 pm
First, the SD library and SdFat library are not the same.
In the first one, the function is simply named seek(), while in the second it is named seekSet().

Of course, for SdFat, you need SD_SPI_CONFIGURATION=1 since it will use the standard SPI.


Pito
Wed Sep 14, 2016 11:06 am
FYI – the latest SdFat-beta (MMini, 36MHz SPI) and the “bench” with 512bytes buffer size and new SdFatEX class:
Type any character to start
FreeStack: 14444
Type is FAT32
Card size: 8.03 GB (GB = 1E9 bytes)

Manufacturer ID: 0X1B
OEM ID: SM
Product: 00000
Version: 1.0
Serial number: 0X8D172C54
Manufacturing date: 1/2015

File size 5 MB
Buffer size 512 bytes
Starting write test, please wait.

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
3528.36,22171,135,143
3654.74,7632,135,138

Starting read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
3280.63,1512,154,154
3282.78,1429,154,154

Done
Type any character to start


RogerClark
Wed Sep 14, 2016 8:49 pm
Re:SDIO

This may be possible with the Arduino Core that STM are developing.

I have asked them to put SDIO on their ToDo list, but at the momemt I dont know if they have the resources to create a SDIO lib for their core.

( see my announcement post in the announcements section)


stevestrong
Thu Sep 15, 2016 7:34 am
Anyway, SDIO is not relevant for F103 family with less than 768kB flash, such as current blue and red pills.
For any other, specially Arch max, is more than welcome :)

Pito
Thu Sep 15, 2016 8:05 am
Yea, SDIO is available on bigger chips only, also I’ve read somewhere ie. the 407 SDIO is buggy, the first well working on 446.
I did some naive experiments years back on 407 and chibios, I did 6MB/sec with 32kB blocks and a cheapo sdcard, not sure it was set up properly, however :?
Anyway, 3.5MB/sec with only a 512bytes large buffer on the MapleMini SPI is an impressive number, sure..
That is so close to the theoretical limit with 36MHz SPI clock.. Unbelievable :shock:

stevestrong
Thu Sep 15, 2016 8:52 am
Hmm, write speed (3.5) higher than read speed (3.2) ? Is this really OK?
Anyway, just for the record, I found the SDIO bug discussion on ST forum.
Their benchmark: 2.8 write, 9.4 read using FatFS & SDIO 4 bit mode on STM32F4 disco.

Pito
Sat Sep 17, 2016 10:26 am
Hmm, write speed (3.5) higher than read speed (3.2) ? Is this really OK?
Anyway, just for the record, I found the SDIO bug discussion on ST forum.
Their benchmark: 2.8 write, 9.4 read using FatFS & SDIO 4 bit mode on STM32F4 disco.

The write speed is higher as the modern cards have got an large ram buffer inside, so the writes are buffered somehow.. (Info: BillG, author of the SdFat).
On Teensy 3.6 Bill did 19/20MB/sec with SDIO and the latest SdFat-beta, he claims:
https://forum.pjrc.com/threads/36737-Tr … post115239

PS: Mind he runs Teensy 3.6 @240MHz :shock:
https://www.kickstarter.com/projects/pa … -35-and-36


RogerClark
Sat Sep 17, 2016 11:03 am
Pito wrote:

PS: Mind he runs Teensy 3.6 @240MHz :shock:
https://www.kickstarter.com/projects/pa … -35-and-36

Phono
Thu Sep 22, 2016 7:31 pm
So let me jump into the bandwagon, and tell me the status of SDFat? Where can I find it? Is it now possible to select the SPI to be used, so that I can avail myself of the SD slot of the Olimex boards ?

Pito
Fri Sep 23, 2016 10:28 am
https://github.com/greiman/SdFat-beta

You can assign what you want, I think it supports two SPIs with two cards in parallel now..


VadimEL
Thu Sep 29, 2016 9:23 pm
Need example, replace chars in file.

I have file like
12345 434 3
fg23r 34f3
2g42h 34 3
h3443 f34 43f


stevestrong
Fri Sep 30, 2016 7:15 am
– open the file as O_RD_WR
– file.rewind();
while(file pointer not at end) {
– peek the char (read pointer will not be incremented) – I think it is the function: file.peek();
– if (char==’3′) then: file.write(‘1’); // pointer will be incremented
– else: increment file pointer
}

VadimEL
Fri Sep 30, 2016 1:38 pm
stevestrong thanks it’s work.
while (myFile.available())
{
check = myFile.peek();
if (check == '2')
{
myFile.write('1');
}
myFile.read();
}
myFile.close();

stevestrong
Fri Sep 30, 2016 1:43 pm
Welcome ;)

Manny
Mon Oct 10, 2016 6:29 pm
Pito wrote:https://github.com/greiman/SdFat-beta
You can assign what you want, I think it supports two SPIs with two cards in parallel now..

RogerClark
Mon Oct 10, 2016 8:58 pm
Manny

which file has the typo? and on what line number?


Manny
Mon Oct 10, 2016 10:54 pm
RogerClark wrote:Manny

which file has the typo? and on what line number?


RogerClark
Tue Oct 11, 2016 2:06 am
Ah OK

Not in my code then ;-)


stevestrong
Tue Oct 11, 2016 9:14 am
Manny wrote:The typo is in SdFat-Beta, line 29 in SpiDriver/SdSpiSTM32F1.cpp

Manny
Tue Oct 11, 2016 4:06 pm
stevestrong wrote:Manny wrote:The typo is in SdFat-Beta, line 29 in SpiDriver/SdSpiSTM32F1.cpp

SanjuPrakash
Sun Oct 30, 2016 8:34 am
Hello.

I have tried executing most of the codes present in the victor_pv github page on my STM32F103C8T6 Minimum Development Board. I got SdInfo,Bench and PrintBenchmark working well. LowLatencyLogger compiles and uploads well but nothing gets displayed on the Serial monitor. Could you point out what could be going wrong?

And also could someone tell me what are the other SD codes that are running well on STM32F103C8T6 as i have been stuck on deciphering what to do to get the board to log data onto an SD card as fast as possible.


stevestrong
Sun Oct 30, 2016 9:40 am
I suggest to use as basis the “RawWrite” example, this is suitable for fast SD card writing, with or without FAT support.
The latest SDFat-beta from greiman should also work, but not tried yet.
I am currently working with a modified version of it, DMA-based double-buffered analog acquisition and storage (while DMA writes the data from ADCs to one buffer, the other buffer being written onto SD card, I think I already posted somewhere an example).
I achieve ~350kBps (4 analog channels, dual simultaneous conversion using ADC1 and ADC2 in parallel, 12bits/channel, 44.1kHz sampling frequency, 1 second) without losing a byte, but without FAT support.
Now struggling to achieve fast read out speed from the card without DMA…

SanjuPrakash
Sun Oct 30, 2016 11:08 am
stevestrong wrote:I suggest to use as basis the “RawWrite” example, this is suitable for fast SD card writing, with or without FAT support.
The latest SDFat-beta from greiman should also work, but not tried yet.
I am currently working with a modified version of it, DMA-based double-buffered analog acquisition and storage (while DMA writes the data fro ADCs to one buffer, the other buffer being written onto SD card, I think I already posted somewhere an example).
I achieve ~350kBps (4 analog channels, dual simultaneous conversion using ADC1 and ADC2 in parallel, 12bits/channel, 44.1kHz sampling frequency, 1 second) without losing a byte, but without FAT support.
Now struggling to achieve fast read out speed from the card without DMA…

stevestrong
Mon Oct 31, 2016 9:16 am
Here is an older but still working version, good for getting accommodated with the basics.
There is an “issue” in the (older) SDfat lib, because if you want to go without FAT or any other file system, the sd.begin() function returns an error.
You just have to disregard this error, and it will work fine only using cacheClear, writeStart, writeData, writeStop functions (also see the SDFat lib reference documents). This way you write the data directly to card block-wise in an incremental way.
For block-wise incremental raw reading (w/o FAT) I use readStart, readData, readStop functions.
I will soon update the file when I get the upload (from SD card to PC over USB serial) running as fast as possible.

sherinkapotein
Fri Apr 14, 2017 10:01 pm
Having come from the Arduino lineup, had always read about how the DMA could improve some mundane but necessary tasks as logging data to SD card. Finally being handed over with a bluePill along with 3V3 SD card module (gawd why are they so tough to get) I’d thought why don’t give it a try.
Now that the course of the evening was decided I thought might as well document my findings here.

Following are the results from example file bench of the SdFat library by Bill Grieman.

SD card = SanDisk Class 10 32GB (02/2015)
Size of file to be written = 10MB
Tested with varying buffer sizes from 512B to 16KB (yes I did try that too ) with and without DMA.

The card was formatted after every run using the SD formatter utility developed by SD association and SPI speed set to Full speed.
The figures are averaged out over two runs for each test

As can clearly be seen that DMA does accelerate the process for a sufficiently sized buffer reaching speeds upto 3.2MBPS. Even the implementation without DMA for an 8KB buffer gave 3x performance beyond which the law of diminishing returns kicked in.

sped_wR.PNG
sped_wR.PNG (21.18 KiB) Viewed 1119 times

sherinkapotein
Fri Apr 14, 2017 10:17 pm
dma_disT.PNG
dma_disT.PNG (22.2 KiB) Viewed 1118 times

Pito
Fri Apr 14, 2017 10:58 pm
I did 3.5MB/sec @36MHz SPI with only 512bytes large buffer. Reported somewhere in this thread..
viewtopic.php?f=13&t=20&start=120#p17911

sherinkapotein
Fri Apr 14, 2017 11:06 pm
pito wrote:I did 3.5MB/sec @36MHz SPI with only 512bytes large buffer. Reported somewhere in this thread..

Pito
Sat Apr 15, 2017 8:11 am
You need the latest SdFat-beta and also do mind to enable the EX mode in SdFatConfig.h..

stevestrong
Sat Apr 15, 2017 8:13 am
What is EX bringing more than the “normal” beta?

Pito
Sat Apr 15, 2017 8:17 am
Xtimes faster wr/rd speed.. sherinkapotein will test it :)

nicolas_soundforce
Sun Aug 06, 2017 5:35 pm
I want to read 2 files at the same time. Can I just file.open() 2 files in parallel ? I am having problems at the moment and it doesn’t work as expected.

stevestrong
Sun Aug 06, 2017 6:31 pm
Would you be able to help if you read what you have written? I dont owm any magic ball…

victor_pv
Mon Aug 07, 2017 2:04 am
[nicolas_soundforce – Sun Aug 06, 2017 5:35 pm] –
I want to read 2 files at the same time. Can I just file.open() 2 files in parallel ? I am having problems at the moment and it doesn’t work as expected.

you need to declare 2 “file” objects, for example file1 and file2, then you can work on each separately:
file1.open()
file2.open()
file2.read...


nicolas_soundforce
Tue Aug 08, 2017 9:02 pm
Thanks Victor, that worked without any problems.

stevestrong
Mon Sep 18, 2017 8:12 pm
Just fyi, I added support for F4 (SPI and SDIO) to SdFat library from Greiman: https://github.com/stevstrong/SdFat
PR is ongoing: https://github.com/greiman/SdFat/pull/69

Leave a Reply

Your email address will not be published. Required fields are marked *