Spark Logic

SD only partially works.

RogerClark Sat Jun 06, 2015 6:06 am

I don’t know if this is just me, but SD seems really flakey

The cardinfo demo seems really reliable, but the other demo’s that read and write files seem pretty hit and miss.

I’m not sure if this is because the default speed for the SD Lib is HALF speed. But on STM32 that HALF speed on SPI may be too fast for some SD Cards, especially the cheap ones.

Has anyone else experienced problems reading and writing files to SD ?

Replies

madias Sat Jun 06, 2015 6:58 pm

As I can remember, the SD lib runs very fine to me. But(!!) not with all adapters! Some TFT build in SD-adapters didn’t work properly. I also found out that some SD-card adapters work better with specific MCU’s (PIC32, Tiva-TM4c123, STM32) and some do not. Sounds a little bit esoteric, but I didn’t have time why. So maybe use the same configuration with a other adapter first?

RogerClark Sat Jun 06, 2015 9:11 pm

Thanks Matthias

I think I can now make it work with one of my micro sd cards, but I can’t seem to make it work with a full size SD card (though a different adaptor)

It doesn’t seem to work with larger micro SD cards. I have a 4Gb , SanDisk branded HC card , which doesn’t work.

I have not researched this yet, but I have a feeling HC cards may not work.
I thought FAT was ok up to 4Gb so should work, but perhaps that’s wrong.

Two of my boards ( the F103VET and F103ZET) have an SD adaptor on the back of the board, but I don’t know what it’s connected to.
I suspect that as both processors support SDIO that its connected that way, rather than to SPI but I will need to use a continuity tester to try to work out how it’s connected.

martinayotte Sat Jun 06, 2015 9:44 pm

On my side, I still gtruggling to make SdFat/SPI working on my Netduino2Plus F405.
It is aborting almost right at the begining. Here are some trace I’ve enabled or added :
before sd.cardBegin !
SdSpiCard::begin / spiBegin() !
SPI configure_gpios / (nss=16, sck=42, miso=43, mosi=44)
spi_master_enable(48,0,768)
SdSpiCard::begin / spiInit() !
Bit order set to 1
SPI configure_gpios / (nss=16, sck=42, miso=43, mosi=44)
spi_master_enable(48,0,768)
Data mode set to 0
SPI configure_gpios / (nss=16, sck=42, miso=43, mosi=44)
spi_master_enable(48,0,768)
Clock divider set to 48
SPI configure_gpios / (nss=16, sck=42, miso=43, mosi=44)
spi_master_enable(48,0,768)
SdSpiCard::begin / 74clock spiSend() !
SdSpiCard::begin / cardCommand(CMD0) !
SdSpiCard::begin SD_CARD_ERROR_CMD0 !
SdSpiCard::begin FAIL !
SDCard initialization failed !

RogerClark Sat Jun 06, 2015 9:54 pm

Martin

Do you mean the SD lib is calling begin all other the place ?

I presume you are using the SD lib that’s part of the IDE like I am ?

I know victor has a revised / improved SDFat lib on his GitHub account, but Im not sure if it replaces SD or is a utility that SD uses

PS. I wonder how well SD a actually works on AVR, I suspect its just as flakey and depends on which adaptor and card you are using

martinayotte Sun Jun 07, 2015 12:14 am

Hi Roger,

RogerClark wrote:Do you mean the SD lib is calling begin all other the place ?

RogerClark Sun Jun 07, 2015 3:28 am

Martin

I suspect the Begin is being called because the hardware doesnt allow some things like the bitOrder or the clock divider to be changed when the SPI port is enabled (I remember you definitely can’t switch from 8 to 16 bit transfers when the SPI hardware is enabled)

It was probably me that put the calls into begin() into the code, but the alternative may just be to call

spi_master_enable(spi_d, (spi_baud_rate)clockDivider, (spi_mode)dataMode, flags);

plus the other code, but unless you can cut some of the code out, it almost seems logical to call begin() every time you change the settings

Albeit perhaps you don’t need to call configure GPIO

So I suspect a better approach would be to write a function called setSPISettings() which is called after you change bitOrder etc and also called from begin()

pico Sun Jun 07, 2015 6:17 am

RogerClark wrote:
I know victor has a revised / improved SDFat lib on his GitHub account, but Im not sure if it replaces SD or is a utility that SD uses

RogerClark Sun Jun 07, 2015 12:04 pm

I’ve tried Victors updated version of SdFat but it doesn’t seem to work at all for me :-(

The card won’t initialize.

So I”ve gone back to using the standard SD that is part of the IDE install.

However its ultra flakey :-( :-(

I know this is old news… But the SD lib seems to fail to read for no apparent reason, e.g. i call dataFile.read(buff,LEN); and it just returns -1 at random, which means its failed, and if you try to read again without leaving a long time delay e.g. 10ms it just keeps returning -1 :-(

Anyway, in terms of what I was trying to do, I’ve got something that sort of works, but isn’t reliable enough to be used.

It opens and reads a file from SD and plays it as an MP3 though a VS1003

I will repost the code to the VS1003 lib thread in case anyone with the same hardware wants to have a play with it

#include <VS1003_STM.h>
#include <SPI.h>
#include <SD.h>

VS1003 player(PC14, PB10, PA8, PA9, SPIClass(2)); // cs_pin, dcs_pin, dreq_pin, reset_pin

/*
* VS1003 development board connected by it's header pins the following way:
*
* GND - GND -
* XDCS - D6 - PB10
* DREQ - D7 - PA8
* XRES - D8 - PA9
* XCS - D9 - PC14
* SCLK - D13 - PA5
* SI - D11 - PA7
* SO - D12 - PA6
* GND - GND -
* 5V - 5V -
*/

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

// while (!Serial.available());/// Wait for key entry.. For debugging

// see if the card is present and can be initialized:
while (!SD.begin(PA4))
{
Serial.println("Card failed, or not present");// don't do anything more:
delay(100);
}
Serial.println("card initialized.");

player.begin();
player.modeSwitch(); //Change mode from MIDI to MP3 decoding (Vassilis Serasidis).
player.setVolume(64);
}

int currentFileNum = 0; // Hack because SD only allows one file handle open at a time :-(
void loop()
{
playFile("music.mp3");// Lets just play the music ;-)

delay(1000);
return;
}

#define BUFF_LEN 128

void playFile(char *fileName)
{
uint8_t buff[BUFF_LEN];
File dataFile;
int bytesRead;
int fileSize;
int totalBytesRead = 0;

dataFile = SD.open(fileName);

if (!dataFile)
{
Serial.println("Error opening file");
return;
}

Serial.print("Playing "); Serial.println(fileName);
fileSize = dataFile.size(); // need to know the size of the file

// loop until end of file
while (totalBytesRead != fileSize)
{
do
{
bytesRead = dataFile.read(buff, BUFF_LEN);// try to read a buffers worth
if (bytesRead == -1) // Oops. SD didnt manage to read anything ....
{
delay(10);// Workaround for problem in SD lib.
}
} while (bytesRead == -1);// loop around if last read failed

player.playChunk(buff, bytesRead);
totalBytesRead += bytesRead;// keep track of how much of the file we've played
}
dataFile.close();
}

pico Sun Jun 07, 2015 1:32 pm

RogerClark wrote:I’ve tried Victors updated version of SdFat but it doesn’t seem to work at all for me :-(

The card won’t initialize.

martinayotte Sun Jun 07, 2015 1:48 pm

In my case, I’ve tried Victor’s version, and this morning Bill Greiman’s one as well as default Arduino one.
They are all failing during command CMD0, so, I suspect more that my port of SPI from F1 to F4 doesn’t work, although there are not much differences.

mrburnette Sun Jun 07, 2015 1:51 pm

pico wrote:
<…>
I’m actually quite surprised by this — not so much the code doesn’t work (even back in the old days the libmaple guys had a hell of a time getting the SD code base to work on a maple for some reason), but the fact that it doesn’t work and Bill Greiman accepted the pull request! In my experience, he’s usually fairly conservative to the point of paranoia…

Given how far things have come with SdFatLib since those days, however, I’d be looking at the Teensy 3.x code as the place to start for a fresh stm32 port — similar speced processors, and I know Bill has put a lot of time into getting it to run right on that platform.

pico Sun Jun 07, 2015 2:26 pm

mrburnette wrote:
I cannot speak for Victor, but I have used Paul’s Teensy code in the past, sometimes it is enlightening … sometimes, just not anything but #ifdef’s.

mrburnette Sun Jun 07, 2015 2:55 pm

The changes for SdFatLib for Teensy 3.x were all due to Bill, not Paul — as I say, Bill tends to keep it pretty close to his chest when it comes to modifying the SdFatLib source.

Well, I do not really care how they got into the Teensy ecosystem, only that they did! (I am a Teensy3.1 owner) Bill has done a great job over the years and Paul has provided Arduino compatables that are a great value.

But as big-name companies change the Arduino hardware, the SD will look more and more abstract – like a flashcard in a PC.

Personally, I do not subscribe for using the main microprocessor for SD. A second, dedicated microcontroller is a more sensible datalogger. https://www.hackster.io/rayburne/sd-card-serial-logger If the design requires reading, parsing, writting and such: move to an rPi. On an 328 AVR, 512 Bytes are required for buffering write and 512 Bytes are required for read. IMO: just silly to try and mix this requirement with program logic.

As the STM32 bottom line is 20K SRAM, the effort to integrate SD into the main program logic is more tempting.

Ray

RogerClark Sun Jun 07, 2015 9:07 pm

Guys

I’ve not had time to test it yet, but it looks like the reason SdFat ( the latest version of SD) didn’t work for me, is that you can’t use PA4 as CS, and accidentally I used that pin as it happens to be next to the other SPI pins on my board which made the wiring easier.

If it works, I will add SdFat as a library, because using the old one supplied with the IDE

it could just be my particular hardware setup that doesn’t work well with the old SD lib, its hard to tell.

BTW. Mysteriously my Sandisk 4Gb micro SD card is started to work with the old SD lib when I was trying to get my MP3 player working yesterday , and my dodgy 2Gb SD stopped working.

Anyway, I will try SdFat again and report back on its stability for me, with a range of different cards.

mrburnette Sun Jun 07, 2015 9:14 pm

Anyway, I will try SdFat again and report back on its stability for me, with a range of different cards.

Bill once did this and published his results, but I cannot find the reference at this time. And his work was for the AVR 8-bit, so I do not know if the 32-bit hardware would affect the results beyond speed.

It will be interesting, anyway.

Ray

RogerClark Sun Jun 07, 2015 9:35 pm

Hi Ray

I will report back ;-)

The frustrating thing, is that SD is just one part of what of a test project (Mp3 player), it wasn’t supposed to be the problem area, the VS1003 was supposed to be the device I was getting to grips with ;-)

With the mp3 playback, getting data to the VS1003 in time is critical, as it only has a 5 k internal buffer, and doesn’t transfer that fast ( DIV 16 I think)

Git the SPI for the VS1003 working on SPI2, but as neither the SD or the VS1003 are using DMA it doesn’t give me any performance advantage.

I will look at using DMA for the VS1003, but I think I’d also need to use an interrupt on its DREQ input (data required), in order to kick off a 32 byte DMA block transfer, in order to make the whole thing a bit more multitasking in nature

mrburnette Sun Jun 07, 2015 9:39 pm


With the mp3 playback, getting data to the VS1003 in time is critical, as it only has a 5 k internal buffer, and doesn’t transfer that fast ( DIV 16 I think)

Maybe RTOS? Is not that what it is all about…

Ray

RogerClark Sun Jun 07, 2015 11:07 pm

Just a quick update, as I think I”m going to put this on hold as I have other STM32 stuff I need to look at…

I’ve tried changing the CS pin, I’ve even tried just pulling the CS pin to GND, and I still cant get the new lib to work with any of my micro SD cards

I’m beginning to wonder if this is a hardware e.g. voltage levels issue

I am using this micro SD adaptor and was running it from 3.3V

Image

However, looking at it, I can see its got a regulator on it.

So on my Red Pill board, I change the input voltage from 3.3 to 5V, and this seems to make my cheap / clone 2 Gb SD card more reliable on my Red Pill – but still doesn’t allow me to use SDFat.

I’ve tried downloading Bill’s repo, but it doesnt compile, as it gets errors because of missing definitions to SPI_DMAC_TX_CH

I don’t get these errors when using Victors version. So it looks like there is something out of sync betweeen Victors last pull request to Bill’s repo, and what victor has updated in the SPI with regards to DMA :-(

I’m not sure if Victor is reading this thread, so I will PM him about this.

RogerClark Mon Jun 08, 2015 2:03 am

Just a quick update.

It looks like the issue with the normal SD lib, is the same as for the new Lib

You can’t use PA4 as Chip select on SPI, because this is the NSS pin (hardware SPI Chip select).

By accident I tried just connecting CS to GND and I noticed that it seemed a lot more reliable, so I tried PA2 instead of PA4 as CS and it seems equally reliable,
I’m no longer getting -1 return from File.read(buff, length), also the card seems to init straight away.

So I think the status of the SD lib, is it does work, but only if you don’t use PA4 for CS

madias Mon Jun 08, 2015 8:32 am

Good found Roger!
I never had such a problem, because I always use a seperate CS pin (and not the HW NSS pin) since the “old Arduino days”, except I completely doing SPI “per hand”. But good to know that this “problem” still exists, even on STM32-duino.
When I have time, I’ll open a thread in the global section and post my results all my SD-cards + adapters in every combination. All I can say is that your adapter on the photo (with the 5V to 3.3V conversation) works on nearly every MCU (even on 3.3V) for me – drawback: mini SD-cards only:/

Sign in to reply