I posted this same question on the Arduino forums, but have not got any responses yet. Hopefully I could get some insight on this forum.
I am running into some issues interfacing an SD card reader with the ATmega32U4. The SD card does not initialise.
At this stage I am suspecting it's a hardware related issue.
This project involves a PCB and doesn't use the Arduino type SD card breakout.
In the microcontroller schematic I have ticked in red marker the connections from the microcontroller to the SD card aspect.
I am using the original chip select pin SS (CS_1) for the SD card, and PB4 (CS_2) as the chip select for a CAN controller.
I am fairly sure the SPI interface is working OK because the CAN controller initialises.
The SD card schematic is also attached. Basically CS_1 from the micro goes to HC4050, and this is level shifted (CS_µ) to the SD card reader. Similarly for MOSI and SCLK. I have not level shifted the MISO line because a schematic I found online earlier did not do so either (but I have forgotten which schematic it is now...) I did check the adafruit SD card breakout schematic and they don't appear to level shift MISO.
Both the SD card reader and the HC4050 receive 3.3V when tested with a multimeter. For further testing I borrowed an Arduino MICRO from a friend and hooked up an Arduino style SD card breakout, ran the same code and it worked fine.
I used an Arduino MICRO for testing because the microcontroller on the PCB has the same bootloader flashed through the Arduino IDE.
Code for initialising the SD card is as below, I am using the SD.h library.
I also tried using the following command to pull-up the MISO line to 3.3V, and MISO does get pulled up, but the SD card still does not initialise.
When you have problems with SPI there's nothing quite like a digital scope or a logic analyser for exploring what's happening on the MOSI/MISO/SCK wires!
An alternative (for a software only approach) is to try a completely different FAT software stack and see if that shows the same issues (which then rules out issues in the software you are using). The obvious candidate in this case would be to ditch the Arudino stuff completely and instead making an implementation using the (easy to use) Chan's FatFs.
Unfortunately I don't have a breakout directly for SPI on the PCB, so I may have to solder some wires onto the HC4050 chip pins to see what's going on.
I will leave that as a last resort, I want to avoid butchering the PCB. Also, I want to make sure the way I have made the connections are correct in the first place!
I cannot really do a new implementation because the software was done through the Arduino IDE and it would involve rewriting code for the CAN controller, as well as other things.
Not sure what Chan's FatFs is, but I will read up on it.
I'm not suggesting re-implementing the entire project. Simply that you put together a standalone FatFS based test that does nothing more than open a file and read a byte and see if that has any more success than what you are trying.
OK, so I realised that I have a logic analyser lying around that I've never used.
Soldered some hook-up wire to the relevant pins, but I'm not sure how to interpret what I'm seeing.
The chip select pin goes LOW.
MISO appears to be HIGH the whole time.
What you really need is to attach to a system where the card does work and compare the transaction in the do/don't cases.
which gives an idea of the data dialog you should expect to see.
You might want to move the display along a bit to see the rest of the outgoing command and the reply. But what you've shown looks right for the initial command.
Based on the link provided by clawson, and what Brian just said...it appears I may have an issue with MISO.
It's basically HIGH the whole time. It never goes LOW...so I guess there's just no response?
The link shows that MISO needs a pull-up. I didn't include one on the PCB explicitly for it.
So I enabled the AT32U4's internal pull-up for the MISO line...could this be causing the issue? Would it be somehow different from using an external pull-up resistor?
I'd have to fundamentally change the PCB design to fix it.
When deselected, EVERY SPI slave MUST float its MISO pin; that is a requirement for multi-slave systems, which is one of the key requirements for SPI. If there is no pull-up on the MISO line, then it COULD be anything after it switches to float. Often, that line will stay at the last logic state for a long time (just due to capacitance); when this happens, it can change to a new value when a new slave is selected.
Thus, the fact that the MISO line might appear to be in an unexpected state after the other slave is deselected should not be a surprise.
This also leads to the question of why a multiplexer is used? SPI bus is designed to work with multiple slaves, as it is. Just supply the chip select to the slave you want to communicate with, and it will be good to go.
So maybe I don't need to change anything drastically on the PCB just yet...however if a pull-up is all that's needed, I have enabled the internal pull-up for MISO on the microcontroller.
I changed the chip select line for the CAN controller in the code to see if it shows an error, and indeed it indicated an initialisation error, so the SPI bus appears to be working.
Since the MISO is a shared line between CAN and the SD card (MOSI/CLK have been level shifted for the SD card) I don't understand why I can't see any activity on the line, but the CAN controller intialises whilst the SD card doesn't.
I also tried to take a capture immediately after uploading the normal code, and it shows some other interesting activity that I didn't see before.
One thing I didn't check before is whether there was continuity from the solder pads to the internal terminals of the SD card reader.
I used a fine gauge wire and checked the resistance. There is roughly 30 ohms from each of the 8 solder pads to the corresponding internal terminals.
I can't find anything online that shows whether this is normal or not.
You DO NOT need a pullup on MISO line. The only reason I suggested that is to explain why the MISO line might seem to be in an anomalous state (but not really).
Some SPI devices mirror the MOSI input out onto the MISO line to allow for a daisy-chain type arrangement. That is not very common, though. Devices that do not do this will NOT have any activity on the MISO line unless the operation requires it.
Also, don't forget that the slave often sends data AFTER a command. The master must keep providing clocks during the expected data time. If you stop the clock at the end of a command and deselect it, you will never see anything on MISO.
Thanks for confirming. I have now disabled the pull-up. This is one less thing I have to keep toggling ON and OFF whilst debugging.
While the chip enabled is LOW (for about 2.5 seconds) the clock is active and MOSI keeps repeating the same command. So I guess this is plenty of time for a response.
I am not manually manipulating this bus as I'm using the provided Arduino libraries, which worked on an Atmega328P and also an Arduino Micro using the same Atmega32u4 chip I'm using on the PCB.
SD.begin () automatically grabs the standard SS line for the AT32U4 which the SD card is connected to, so it doesn't matter whether I put 17 as an argument or not.
What I see is that intermittently the card does initialise now. Which means the clock speed may have been too quick for the card. The MISO line from the microcontroller to the CAN controller is about 1 inch away.
The same MISO line going through to the SD card via some bends is probably about 6 inches long.
I am now wondering whether a really long thin copper trace for the MISO is the reason for the initialisation problems?
Even though it initialises sometimes, it's just not stable enough to do any file operations. SD card is at the top right hand side.
6" is probably NOT a problem. You do need to be careful to use the proper SPI mode and to change it, if it needs dynamic changes, BEFORE you select the chip.
How well decoupled is the sd card?
I believe these are all handled by the libraries. I have used them on the Arduino UNO and Arduino MICRO breakout boards without any issues.
Based on the logic analyser trace I think they are doing what is asked for.
One capacitor "C8" which is 0.1µF across Vcc and GND. Not sure if that's sufficient.
Turned out to be a bad connection between the SD card holder and the PCB. Not sure which pin it was, but I re-soldered all pins and the issue went away.
Kemp you seem to be flogging that display, are you the seller? If so please post ONCE in the marketplace or your account may end end being locked as a spammer.