8 years, 3 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:

A re-written SDFileSystem library with improved compatibility, CRC support, and card removal/replacement support. fatfilesystem, MMC, SD, SD Card, SDHC, SDXC

3 Answers

8 years, 3 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 Aaron Campbell 15 Jan 2016

Ok, 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 Aaron Campbell 19 Jan 2016

I 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 Neil Thiessen 19 Jan 2016

Well, 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 Aaron Campbell 26 Jan 2016

Update! 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).

posted by Aaron Campbell 30 Jan 2016

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 Neil Thiessen 30 Jan 2016

Thanks 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 Aaron Campbell 01 Feb 2016
7 years, 11 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); 
}

Martin,

Do you know if this update will also fix I2C issues and the ability to access internal CPU registers?

posted by Kevin Braun 03 Jun 2016

i2c should , what about the latter one? can you provide more details?

posted by Martin Kojtal 06 Jun 2016
7 years, 11 months ago.

Go back to mbed lib v119. 120 is broken for the k64f

+1, there is a bugfix, will make it to the next revision

posted by Martin Kojtal 03 Jun 2016