greiman / SdFat

Arduino FAT16/FAT32 exFAT Library
MIT License
1.08k stars 504 forks source link

problem with intilizing sd card. #122

Open MaxBoyman opened 5 years ago

MaxBoyman commented 5 years ago

there was a common problem with your library and all of the programs which i wrote in the past and that was problem initilizing sd card in first definition step. if (!SD.begin(SD_CS_PIN)) {} was randomly true. i had tested this situation with lots of SD card modules and arduino boards. for example Mega 2560, Uno, Due. after lots of searches i found the problem can be solved with adding a simple delay(150) to the file SdSpiCard.cpp in line 141 which is : while (cardCommand(CMD0, 0) != R1_IDLE_STATE) { delay(150); //Added line if (isTimedOut(t0, SD_INIT_TIMEOUT)) { error(SD_CARD_ERROR_CMD0); goto fail; } } this solved the whole problem. please investigate this and add the line if it's true.

greiman commented 5 years ago

I tried a number of SD cards and found problems with older cards.

Your delay helps with some cards but not others. I made several mods including your delay and all the older cards I have seem to initialize now.

greiman commented 5 years ago

I have done more testing and found the real problem.

An SD card indicates busy, when not doing a data transfer, by holding MISO low. Before some older cards are initialized, they hold MISO low or they tri-state MISO and it may appear low.

SdFat has a test for busy which causes a long delay for these cards. An SD card will accept CMD0, the software reset command, even if it is busy.

At about line 212 of SdSpiCard.cpp I added a test for CMD0:

  // wait if busy unless CMD0
  if (cmd != CMD0) {
    waitNotBusy(SD_CMD_TIMEOUT);
  }

I removed the delay that I added at about line 146.

// delayMS(SD_CMD0_DELAY);

I tested with about 20 old cards. They all Initialize as fast or faster than with the delay. None of the cards fail to initialize.

Please try this mod and let me know if it works with your cards.

MaxBoyman commented 5 years ago

i'm testing new version 1.0.12. are these new lines changed in version 1.0.12?

greiman commented 5 years ago

The new lines are changes to 1.0.12.

greiman commented 5 years ago

I have been testing SD shields and breakouts. It has been years since I did this.

Most don't comply with the SD spec:

RDAT and RCMD are pull-up resistors protecting the CMD and the DAT lines against bus floating when no card is inserted or when all card drivers are in a high-impedance mode. The host shall pull-up all DAT0-3 lines by RDAT, even if the host uses the SD Memory Card as 1 bit-mode only in SD mode. Also, the host shall pull-up all "RSV" lines in SPI mode, even though they are not used.

RDAT/RCMD should be 10-100 kΩ.

Without the pull-up resistors, some cards appear busy before being initialized since all DAT lines are floating. Also when no card is inserted, the lines may look like a busy card.

Without pull-ups, cards may not go into low power idle mode and draw excess current. Normally an idle card draws about 100 micro-amps while active cards draw 20 or more ma.

Edit: Most of the problems can avoided by adding a pull-up on MISO like this: spicon

See this article.

MaxBoyman commented 5 years ago

I will check if my SD module have it on the board.

greiman commented 5 years ago

I have posted 1.0.13. It has two subtle changes that are a workaround for the MISO pull-up problem.

These changes also seem to help with cards that don't strictly follow the SD spec.

I no longer need a loop for the CMD0 reset or CMD8 to enable SDHC cards.

I built a test SD module with switchable pull-ups and instrumented the code plus used a hardware logic analyzer to understand the problem.

I hope I have not introduced new problems.

MaxBoyman commented 5 years ago

i checked the module for the resistor which you told that it should be at MISO. it is there, but the problem is exists in some cases. i used your library for 5 industerial grade projects and this problem is the only one i have in these projects. this library is good but please help me fix this problem.

greiman commented 5 years ago

Do you have any other SPI devices?

Does your SD module have level shifters? You should only use level shifters with 5V AVR boards.

Be sure to use SdFat 1.0.13 for the following.

Run the SdInfo example and post the error codes if it fails.

Also run the SdInfo example with no SD. It should produce this result:

type any character to start error: cardBegin failed SD errorCode: 0X20,0XFF

The 0XFF shows that the MISO pull-up is working.

With a MISO pull-down the result is:

type any character to start error: cardBegin failed SD errorCode: 0X20,0X0

greiman commented 5 years ago

I added one more improvement to card initialization in 1.0.14.

Some older cards will not reinitialize if they are in transfer mode. I added retry with code to end transfer mode.

Have you tried the SdInfo test?

MaxBoyman commented 5 years ago

Yes i tried sdinfo without sdcard in module. And the result was: 0x20,0x0 What's it means?

greiman commented 5 years ago

The 0X0 with no card means that something is holding MISO low while the CMD0 response is read.

MISO may be floating low. Few SD modules have a MISO pullup.

What SD module/shield are you using?

What Arduino or third party board are you using?

MaxBoyman commented 5 years ago

Arduino Mega2560. can't find the sd card brand but i am trying to add a pull-up resistor. what is the resistor amount which can suit it best? because you said 10-100k which is better?

greiman commented 5 years ago

First, do you have other SPI devices? These can interfere with the SD module.

There are some SD modules that have a level shifter on MISO. A pull-up will not help with these.

Most modules with pull-ups use 10k.

You can do a test by adding an external resistor from MISO to V3.3 or V5. It should change the result of SdInfo to 0X20, 0XFF.

You probably no longer will need the pull-up on MISO with SdFat 1.0.14. I have tried to provide workarounds in the code.

MaxBoyman commented 5 years ago

no there is no spi devices other than sd module. i am updating the library and testing. i will let you know if problem fixed.

greiman commented 5 years ago

What board are you using Due, Mega, Uno, Zero, other?

MaxBoyman commented 5 years ago

im using mega. but im also testing with uno. the good news is it seems that the problem is fixed temporary. but i should test it on my others projects too. they are installed on different automation systems in suburbs. i will tell you about results. also im working on a system to update programs from internet. it will help me to deploy newly edited programs faster and also it helps me to test things faster. do you have any idea on this one. for example one of my projects is installed on a distance of 100 miles from me and i should get there to update the program with new library. having a platform or library to update programs online is a briliant idea.

greiman commented 5 years ago

Arduino is a poor solution for remote update.

I like systems like Particle Argon or Particle Boron for OTA (Over The Air) update. You can update these boards easily over the internet using WiFi or LTE.

Other companies are producing similar boards.

anatom74 commented 4 years ago

I also have constant problem with one type of SD cards. While all Kingston's SD cards are working fine, I have a problem with SanDisk SDHC UHS-I Cards (bought several of them), also from 2 different suppliers.

SDinfo from Kingston:

init time: 47 ms

Card type: SDHC

Manufacturer ID: 0X2
OEM ID: TM
Product: SA16G
Version: 5.7
Serial number: 0X72860929
Manufacturing date: 2/2013

cardSize: 15476.98 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 0XC0FF8000

SD Partition Table
part,boot,type,start,length
1,0X0,0XC,8192,30220288
2,0X0,0X0,0,0
3,0X0,0X0,0,0
4,0X0,0X0,0,0

Volume is FAT32
blocksPerCluster: 64
clusterCount: 472064
freeClusters: 472060
freeSpace: 15468.46 MB (MB = 1,000,000 bytes)
fatStartBlock: 9006
fatCount: 2
blocksPerFat: 3689
rootDirStart: 2
dataStartBlock: 16384

SDInfo of SanDisk:

init time: 136 ms

Card type: SDHC

Manufacturer ID: 0X3
OEM ID: SD
Product: SC16G
Version: 8.0
Serial number: 0X6EB532B8
Manufacturing date: 9/2013

cardSize: 15931.54 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true
OCR: 0XC0FF8000
error: read MBR failed
SD errorCode: 0X50,0X0

type any character to start

Note that I lowered SPI speed to 4, to be able to have Sandisk init at all...

Is there anything else I could test?

greiman commented 4 years ago

You may have fake SanDisk cards. It takes too long to init and fails on the first simple block read command. SanDisk cards usually init in 60-85 ms. I init cards at very low SPI speed. The first read happens after I switch to the requested speed.

Often fake cards fail on SPI operations. Most cards are used in 4-bit SDIO mode.

16 GB SanDisk cards are one of the most common counterfeit SDs.

I have even had fakes sold by Amazon itself, not even one of it's sellers. Unless you buy them from very well known sellers for full price, they may be fake.

Since the Kingston card works, your wiring and card module is OK. I use dozens of SanDisk cards and have no problems.

anatom74 commented 4 years ago

You may have fake SanDisk cards. It takes too long to init and fails on the first simple block read command. SanDisk cards usually init in 60-85 ms. I init cards at very low SPI speed. The first read happens after I switch to the requested speed.

Often fake cards fail on SPI operations. Most cards are used in 4-bit SDIO mode.

16 GB SanDisk cards are one of the most common counterfeit SDs.

I have even had fakes sold by Amazon itself, not even one of it's sellers. Unless you buy them from very well known sellers for full price, they may be fake.

Since the Kingston card works, your wiring and card module is OK. I use dozens of SanDisk cards and have no problems.

I formatted 2 Sandisk cards in SDformatter from examples (16GB and 32GB card) and then checked with SDinfo, which all seems OK (see below), but in my app, writing files on those cards fails (while ther cards, like Kingston work ok):

--- edit My app fails at mkdir() with SanDisk cards. As it seems that instead of creating folder it creates empty file with dir name...

8:03:21.358> init time: 138 ms
8:03:21.358> 
8:03:21.358> Card type: SDHC
8:03:21.358> 
8:03:21.358> Manufacturer ID: 0X3
8:03:21.358> OEM ID: SD
8:03:21.358> Product: SC32G
8:03:21.358> Version: 8.0
8:03:21.358> Serial number: 0X6B1592AC
8:03:21.358> Manufacturing date: 7/2012
8:03:21.358> 
8:03:21.358> cardSize: 31914.98 MB (MB = 1,000,000 bytes)
8:03:21.358> flashEraseSize: 128 blocks
8:03:21.358> eraseSingleBlock: true
8:03:21.358> OCR: 0XC0FF8000
8:03:21.358> 
8:03:21.358> SD Partition Table
8:03:21.358> part,boot,type,start,length
8:03:21.358> 1,0X0,0XC,8192,62325760
8:03:21.358> 2,0X0,0X0,0,0
8:03:21.358> 3,0X0,0X0,0,0
8:03:21.358> 4,0X0,0X0,0,0
8:03:21.358> 
8:03:21.358> Volume is FAT32
8:03:21.358> blocksPerCluster: 64
8:03:21.358> clusterCount: 973584
8:03:38.796> freeClusters: 973583
8:03:38.796> freeSpace: 31902.37 MB (MB = 1,000,000 bytes)
8:03:38.796> fatStartBlock: 9362
8:03:38.796> fatCount: 2
8:03:38.796> blocksPerFat: 7607
8:03:38.796> rootDirStart: 2
8:03:38.796> dataStartBlock: 24576
8:03:38.796> 
8:03:38.796> type any character to start
8:05:10.668> 
8:05:10.668> init time: 136 ms
8:05:10.668> 
8:05:10.668> Card type: SDHC
8:05:10.668> 
8:05:10.668> Manufacturer ID: 0X3
8:05:10.668> OEM ID: SD
8:05:10.668> Product: SC16G
8:05:10.668> Version: 8.0
8:05:10.668> Serial number: 0XCB84DD39
8:05:10.668> Manufacturing date: 8/2013
8:05:10.668> 
8:05:10.668> cardSize: 15931.54 MB (MB = 1,000,000 bytes)
8:05:10.668> flashEraseSize: 128 blocks
8:05:10.668> eraseSingleBlock: true
8:05:10.668> OCR: 0XC0FF8000
8:05:10.668> 
8:05:10.668> SD Partition Table
8:05:10.668> part,boot,type,start,length
8:05:10.668> 1,0X0,0XC,8192,31108096
8:05:10.668> 2,0X0,0X0,0,0
8:05:10.668> 3,0X0,0X0,0,0
8:05:10.668> 4,0X0,0X0,0,0
8:05:10.668> 
8:05:10.668> Volume is FAT32
8:05:10.668> blocksPerCluster: 64
8:05:10.668> clusterCount: 485936
8:05:19.230> freeClusters: 485935
8:05:19.230> freeSpace: 15923.12 MB (MB = 1,000,000 bytes)
8:05:19.230> fatStartBlock: 8790
8:05:19.230> fatCount: 2
8:05:19.230> blocksPerFat: 3797
8:05:19.230> rootDirStart: 2
8:05:19.230> dataStartBlock: 16384
greiman commented 4 years ago

I can't help you since I don't have your card and I have no problems with the many SanDisk cards I use.

Does the bench example run with your card?

anatom74 commented 4 years ago

The strange thing is that if I manualy create Folder on Sandisk card, then app write normally all files underneath that folder.

So the problem is why on SanDisk card, instead of folder, it creates file?

greiman commented 4 years ago

I can't help. I don't have your card and I have no idea what your app does.

Also, I don't have your hardware so it is impossible to reproduce your problem.

anatom74 commented 4 years ago

Does the bench example run with your card?

No, it fails: 9:56:18.935> Starting test 9:56:37.683> fopen fail

However, I could temporarily fixed issue by formatting SD card with SDFormatter app with Alignment option ON. But afrer formatting with SDFormatter from your examples, again the same error appears.

So does this indicate to fake SD's (although all test programs I have used do not show that)? I know that you cannot give exact answers as you cannot reproduce error, but I just anted some clues with solving problem I have.

greiman commented 4 years ago

I said run the bench example, not the SdioBench example. The bench example prints error codes.

I use the bench example to verify SdFat for read/write performance. I have tested about 20 types of SanDisk cards with bench and they all pass.

I tried three models of 16 GB and six models of 32GB SanDisk cards with bench and they all pass the bench test.

Here is a typical result for a 32GB card. on an Uno

Type any character to start
chipSelect: 10
FreeStack: 570
Type is FAT32
Card size: 31.91 GB (GB = 1E9 bytes)

Manufacturer ID: 0X3
OEM ID: SD
Product: SU32G
Version: 8.0
Serial number: 0X45773607
Manufacturing date: 5/2013

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
227.70,28976,1812,2241
227.07,28100,1808,2248

Starting read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
516.12,1980,972,985
516.12,1964,972,985

I have tested on many other boards with this version of SdFat and have no failures.

What SanDisk models are you using, micoSD or standard size, class 2, 4, 6, 10, type name, Ultra, Extreme, etc?

What hardware are you using, board type, SD module/shield, other SPI devices, etc?

I used Arduino IDE 18.12.

I only test with the Arduino IDE so your IDE must be compatible with 18.10 or newer. I will not test with other IDEs so you are on your own to find problems with a non-Arduino IDE.