For the last week I've been pulling my hair out over this issue with my SD card. It works with my firmware if I burn it directly, but with the code in my bootloader which reads the firmware from the SD card, the SD card refuses to respond when sent CMD 0. Or more specifically, it hangs in the wait_ready() loop before it even sends the command, never getting the 0xFF byte that indicates that it's okay to start sending it commands.

I've compared the code line by line with the code in the firmware that works, and the only difference I can find is that the code in the working version just gives up after a while if the card refuses to send the 0xFF bytes it's looking for to indicate it is ready. I haven't quite figured out what it does after that, but I would assume that it doesn't simply ignore the failure. (the SD card code in the firmware is that which came with the WaveHC lib)

The thing is, as soon as I enable the pullup on MISO, everything works great. The bootloader searches for new firmware, it loads it, and the firmware runs.

But I'm concerned that pulling that MISO pin up to 5V is going to damage the 3.3V SD card. It is through a 50K resistor though, so maybe it's okay?

Anyway, here's the relevant functions in the bootloader. Maybe someone can at least spot where I've gone wrong?

The code hangs in that while loop when the booloader tries to send CMD 0 to the card. CMD 0 calls wait_ready() before it executes, and that's where it hangs. Unless I have that pullup enabled. Then everything works fine.

Some SDcards set miso (and others) open collector during the init sequence, so people indicate problems w/o a pullup (I've seen somewhere 30% cards need pullups). The internal 50k pullup (to +5V) is weak so the card's clamping diodes at the inputs will probably survive (will pass the current to the card's 3V3 thus limit input voltage to 3V3+Vfd). You may connect for example a schottky diode from miso (anode) to the card's 3V3 (cathode) to be on safe side.. Do not turn atmega's miso input to output - this may destroy the sdcard..

Some SDcards set miso (and others) open collector during the init sequence, so people indicate problems w/o a pullup (I've seen somewhere 30% cards need pullups). The internal 50k pullup (to +5V) is weak so the card's clamping diodes at the inputs will probably survive (will pass the current to the card's 3V3 thus limit input voltage to 3V3+Vfd).

So do you suppose I could enable the 50K pullup during the init sequence, and then disable it from that point on? Would that even be worthwhile, from the standpoint of trying to protect that diode? Which portion is considered the init sequence? Everything in power_on() up to and including the 80 dummy clocks perhaps?

Or you may simply put a 10k pullup from miso (at sdcard's side) to 3V3 and do not enable the pullup in atmega. That is probably the best approach.. Atmega is fine with 3V3 input when powered from 5V.

I've got a couple hundred boards already manufactured and I'd rather not have to apply yet another patch to them if I don't have to. I already had to turn the serial port USART1 into a third data bus for my leds because you can't stop sending data to the LED drivers in the middle of an update and that was forcing me to skip samples on the DAC resulting in static. :/

So you've got a 74LVC3G34 to level shift the 5V signals from the atmega to 3.3V for the SD card, however you haven't done any level shifting the other way round. This means that the high level signal voltage from the SD card to the atmega input is marginal. The pullup resistor will increase the high level input voltage to approximately 4V (the voltage at which the protection diode in the SD card conducts, and that probably explains why it fixes the problem.

You would be well advised to include a level-shifting circuit between the SD card and the atmega MISO pin. One simple option is a small signal diode (e.g. 1N4148), cathode to SD card output, anode to MISO pin, along with a pullup resistor of around 10K between MISO and +5V. This will still result some current flowing into the SD card pin protection diode. If you want to reduce that current, replace the diode by the base and emitter of PNP transistor with its collector connected to ground.

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

With that simple change it now seems to work. In fact, it works with n < 10, and probably even lower than that, but I did 255 just to be safe.

The idea here is that when the card is first powered up but before CMD 0 is issued, and possibly certain other init commands, the MISO pin may be in an open collector state. In that state I'll never read 0xFF for ready cause I guess the pin is floating? Anyway, this acts as a timeout and assumes the card is ready if it doesn't get 0xFF after a bunch of reads.

And it's working for me now. My firmware loaded fine.

Another thing which lends credence to the idea of this pin floating during init is that I found I could in fact enable that pullup only during the init sequence and then turn it off and the card would continue to work fine. But since I don't know that that pullup won't fry the card, this timeout solution is better.