32U4 microSD interface issues with Arduino 1.0 & SD/SDfat

Greetings,

I've designed and built a number of 328 based systems that suscessfully utilize both the SD & SDfat (depending on project) components. These systems interface the SD card directly for they are powered by 3.3V. The connections are direct between the SD card & microcontroller (ie. SS-->SS, MOSI-->MOSI, MISO-->MISO, SCK-->SCK....essentially utilizing the SPI port). These designs run flawlessly. However, recently I decided to dabble with the 32U4 processors and acquired a MattairTech breakout board. I installed the Leonardo bootloader which works remarkably well. It has served me well in my endeavors, until now. For some reason, I simply cannot get either SD (in Arduino 1.0) or SDFat (12/5/11 version compiled with Arduino 1.0) to initialize the microSD card.

I have connected the microSD card ports to the SPI port (as above) and setup the unit to be powered by a 3.3V source. The USB plug is NOT utilized for testing, but is used to load the sketch onto the unit for testing, then the VCC is sourced by a regulated 3.3V (from another board). Also the SD card is NEVER exposed to 5V for it is only inserted AFTER the wiring is switched over to 3.3V. I have a small LCD attached to the device that displays the activity of the system and persistently states the the SD intitialization fails. The same setup on a 328 based system works like a champ (even with Arduino 1.0). For reference the LCD does not link up to the SPI. Below is the code snippet that I'm using.

I simply cannot figure out why it persistently fails initialization. Any thought or suggestions?


#include <SD.h>

File myFile;

#define PIN_SCE 0 //F0
#define PIN_RESET 1 //F1
#define PIN_DC 4 //F4
#define PIN_SDIN 5 //F5
#define PIN_SCLK 6 //F6

#define LCD_C LOW
#define LCD_D HIGH

#define LCD_X 84
#define LCD_Y 48
#define LCD_CMD 0

const int LEDPin = 3; //D0

///...... bunch of LCD code

void setup(void)
{
LcdInitialise();
LcdClear();
//LcdString("Screen works");

if (!SD.begin()) {
LcdString("initialization failed!"); //<<------ This is where it fails every time with the 32U4 processor
return;
}
// re-open the file for reading:
myFile = SD.open("hello.txt");
if (myFile) {
LcdString("hello.txt:");

// read from the file until there's nothing else in it:
while (myFile.available()) {
LcdCharacter(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
LcdString("error opening hello.txt");
}
}

void loop(void)
{int j=0;
for (int i=0; i < 48; i++){
// just some LCD stuff here
analogWrite(LEDPin,j); /* fade the backlight */
j=j+5;
if (j>245)
{j=0;}
}
}

Two thoughts come to mind: your breakout board is doing something to those SPI pins that interfere, or a slight difference in hardware between the ATmega328's and the ATmega32U4 is enough to cause the SPI interface to the SD card to not work properly.

Perhaps you can lower the SPI clock frequency?

--
The Ruggeduino: compatible with Arduino UNO, 24V operation, all I/O's fused and protected

Very interesting thoughts.

  1. With SDfat, I attempted to run the SPI with the HALF_SPEED mode ... sd.init(SPI_HALF_SPEED, CSPin). Unfortunately, that failed as well.

  2. What you allude to with there being a difference between the 32U4 & 328 was one thought I had as well; however, I simply can't figure out what that difference might be. Could it be the Leonardo bootloader?

  3. As for the breakout board, I've reviewed the schematic & traced the wires. It all looks quite good, there does not appear to be any stray connections. Though, with the Leonardo bootloader, I believe the RX LED is powered by the SS pin. To ameliorate that issue, I redefined the CS to another pin like D0 to no avail either.

I was thinking more of a hardware pin-driver difference between the 32U4 and 328, not a software/bootloader one.

What about actual wiring. How is the system laid out? How much "wire" is there from the microcontroller to the SD card?

--
The Rugged Circuits Yellowjacket: 802.11 WiFi module with ATmega328P microcontroller, only 1.6" x 1.2", bootloader

No, there isn't anything between the actual pins on the semiconductor and the breakout pins. I tested each one (and reviewed the schematic) and all seemed straightforward, clean and direct. In fact, I wondered the same so I created a tiny "rig" that attached the MicroSD card to the ISP (that I know works fine with my JTAGICE II & AVRISP mkII) and it still failed. For reference, I did pull the CS pin out of the "rig" to attach to SS, D0, E6 or any other pin I could test with. To validate the "rig" I tried it out on the 328 based systems and again it worked like a charm, yet strangely failed on the 32U4 based system.

I am running both systems (328 & 32U4) at 16MHz and at 3.3V. So they are pretty similar in setups.

Alright, then it's time for the stupid questions. Do you have power and ground to the SD card? What exactly is holding the SD card, some kind of breakout board? Can you show us a picture of your setup?

Do you by chance have an oscilloscope that you can use to verify that the SS, SCLK, and MOSI lines are toggling when initialization should be taking place?

I'm still thinking hardware differences.

--
The QuadRAM shield: add 512 kilobytes of external RAM to your Arduino Mega/Mega2560

As for power getting to the SD card. Yes, I've checked and it does indeed appear to get power. Unfortunately, right now I don't have access to a scope but hopefully tomorrow I will.

I've attached photos of my setup & the "rig"/breakout board for the microSD. Again, the setup, though a bit unorthodox, works flawlessly on the 328 based systems.

32U4TestBoard.jpg

MicroSDBreakoutBoard.jpg

That's quite a nasty rig, signal-wise. I can believe that it works, but SPI signals are fast and have sharp edges, and wires this long will cause problems. It's quite possible the ATmega328 devices have gentler edges and cause fewer problems. Solution #1 is to trim those wires to be as short as possible. Solution #2 is to include series resistors on the SPI lines to try to have gentler edges (try 10 ohms, 33 ohms, etc. up to 100 ohms).

--
The QuadRAM shield: add 512 kilobytes of external RAM to your Arduino Mega/Mega2560

I wrote SdFat and defined a 32u4 to be a Teensy long before the Leonardo was planned. I will support the Leonardo in the future.

SdFat and SD.h which is a wrapper for an old version of SdFat assume a 32U4 is a Teensy. It is unlikely that the SPI pins will be initialized correctly for your setup.

RuggedCircuits,
thanks for the tips. I shortened the leads to where they were in parallel so it lessened crosstalk. That didn't work. I also added 10 & 100 Ohm resistor (all I had in my bin) in series. No luck. Couldn't get access to the

fat16lib,
Thank you for your insight. I also thank you for your efforts on the SdFat project, it is very much appreciated. Your explanation makes quite a bit more sense. Though, I did look into the Sd2PinMap.h in Arduino 1.0 and saw the following snippet which does coincide with ports B0-B3 on the 32U4 breakout board. I presume there are some other settings that need to be addressed to make the processor properly recognize the SD card?


#elif defined(AVR_ATmega32U4)
// Teensy 2.0

// Two Wire (aka I2C) ports
uint8_t const SDA_PIN = 6; // D1
uint8_t const SCL_PIN = 5; // D0

// SPI port
uint8_t const SS_PIN = 0; // B0
uint8_t const MOSI_PIN = 2; // B2
uint8_t const MISO_PIN = 3; // B3
uint8_t const SCK_PIN = 1; // B1

Just wanted to update this thread in case anyone else might have a similar problem. First, I am ecstatic that the issue is resolved. Secondly, I have to give a great big thank you to Bill (fat16lib) for releasing the recent beta version (20120327) that I believe has revised handling of the SPI pins. By simply utilizing the revised SdFat library (instead of the included SD library) in the Arduino 1.0 IDE, I was able to successfully access the SD card with the 32U4 processor and the Leonardo bootloader.

Again....thank you fat16lib!!!!!