Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
8 years, 10 months ago.
No response from SD card on FRDM-K64F
I'm trying to get Neil's SDFileSystem running on a FRDM-K64F (which I see others have done with at least some success), but it doesn't seem to be able to access the card.
I'm running SDFileSystem_HelloWorld as a starting point. I'm using PTE3, PTE1, PTE2, and PTE4 as the pins, which I know to be correct (see below). I tried using PTE6 as card detect, but it failed; possibly because I'm using the wrong SwitchType (I don't know which one is correct for the K64F), so I'm not specifying card detect. [EDIT: the correct SwitchType is SWITCH_POS_NO, and card detect now works fine.]
Anyway here's what happens: the program enters disk_initialize() -> commandTransaction(CMD0, 0x00000000) -> select() -> waitReady(). There the call m_Spi.write(0xFF) returns 0xFF (-1), and an error is sent down the stack and returned as CARD_UNKNOWN. I've tried this on three different cards and got the same result.
I've successfully gotten the classic SDFileSystem to access the sd card, using FRDMK64_SDCard, so I know my board and my SD pin selection are fine.
For anyone who has gotten this running on the K64F: did you use the SDFileSystem_HelloWorld project, or did you do something different? For anyone else: why would this fail? Might it be a driver error, a configuration problem, or what?
Question relating to:
3 Answers
8 years, 10 months ago.
If waitReady() is failing, it's usually because there's no pull-up resistor on MISO. For some reason breakout boards always get the pull-ups wrong... The old library works, because it runs slow enough that it doesn't have to check if the card is ready. My library should be enabling the internal pull-up on MISO, but it's possible that isn't working on your board.
P.S. The correct SwitchType for the FRDM-K64F is SWITCH_POS_NO.
I tried commenting out the line that enables the pull-up, changing the init clock rate to 100KHz, skipping the select() function, etc, and it still fails. (CMD0 sometimes returns 0xFF, sometimes 0x0, but never 0x1 as expected.) Basically I've tried to make it behave identically to the old library, but without success so far. Still working on it though.
posted by 15 Jan 2016Ok, I think I understand better what you're saying after more debugging and some modification to waitReady(). So what is the correct policy for a board with this problem? Is a slow driver the way to go, or is there a different way to wait for the hardware to be ready?
posted by 19 Jan 2016I would use a voltmeter to check if the internal pull-up resistor on MISO is working, because my library isn't going to work without it. Baring that, you could disable waitReady() to get my library to behave more or less like the old one.
posted by 19 Jan 2016Well, I finally got around to checking it with a voltmeter, and it looks like it actually does have a pull-up resistor.
After running pin_mode(miso, PullUp)
, I read the following values (measuring the voltage between pins in the SD card slot:
- VCC - VSS: 1.971V
- DAT0 (MISO) - VSS: 1.962V
- VCC - DAT0: 1.0mV
If I run pin_mode(miso, PullDown)
instead:
- VCC - VSS: 1.971 V
- DAT0 - VSS: 0.4 mV
- VCC - DAT0: 1.963 V
Unless I misunderstand something (which is quite possible), this looks like the hardware is behaving correctly.
posted by 26 Jan 2016Update! The initialization error was due to what I think was a slight error in waitReady()
, which uses a char
type for the resp
(response). At the end of the function, a positive resp
value indicate success.
On my compiler (KDE 3.0), char
is apparently signed, which means that 0xFF
is negative and treated as an error. However, according to a couple of sources (this microSD driver or the code in Niel's post here), 0xFF
is the expected response when the SD card is ready. I fixed this by changing the declaration to unsigned char resp;
.
Initialization now completes successfully, but now I need to diagnose a read error (0x4E
received instead of valid start block token).
Hi Aaron. That explains a few things, char should be unsigned for mbed. If char is a signed char on your compiler, then a LOT of code if going to break for you. Also, the voltages you posted before are fishy. The operating range for most SD cards is 2.7 to 3.6V, and the lower voltage ones need special initialization steps to switch to the lower voltage range.
posted by 30 Jan 2016Thanks for the response. Yes, since KDE uses GCC, all I needed to do was use the -funsigned-char
compiler flag and now the SDFileSystem appears to work fine. I'll investigate the voltage issue separately.
Since mbed tries to support exporting to environments that use GCC, it might be good to use portable types anyway; or maybe mbed should add the -funsigned-char
flag automatically when exporting projects (I have posted a question requesting this feature: https://developer.mbed.org/questions/67795/Set-funsigned-char-flag-when-exporting-t/).
Too bad I can't post an answer to this or mark a comment as an answer.
posted by 01 Feb 20168 years, 5 months ago.
I have the same board. Neil's library works fine once you figure out the SD card detect polarity. Here's a working example:
#include "mbed.h" #include "SDFileSystem.h" #include <wave_player.h> #define PC_BAUD 9600 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd", PTE6, SDFileSystem::SWITCH_POS_NO, 25000000); Serial pc(USBTX,USBRX); AnalogOut DACout(DAC0_OUT); wave_player waver(&DACout); int main() { //Configure CRC, small frames, and write validation sd.crc(true); sd.large_frames(false); // SPI 16 bits not supported ??? sd.write_validation(true); //waver.set_verbosity(1); FILE *wave_file; pc.baud(PC_BAUD); printf("\n\r\n\rGoing to open a file...\n\r"); wave_file=fopen("/sd/sp.wav","r"); printf("Opened a file. Will now play.\n\r"); waver.play(wave_file); printf("Did it play?\n\r"); fclose(wave_file); }