ILI9340 SD card, what on earth am I doing wrong?

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
rbandrews
 
Posts: 9
Joined: Tue Jul 10, 2012 4:19 pm

ILI9340 SD card, what on earth am I doing wrong?

Post by rbandrews »

I'm trying to get the SD card slot to work on my ILI9340-based TFT, using avr-gcc (not Arduino). I'm looking at the Adafurit SD library and trying to copy what it's doing.

Here's some code: https://gist.github.com/randrews/1d7f6bcdb63891b29fdb

I've got the SPI pins connected to the hardware SPI pins on the AVR (ATmega328p), the SDCS pin is B2 (Arduino pin 10). I'm pretty sure the wiring is correct because the display works perfectly (by the way, this display rocks).

What I do is, plug in an SD card, try to send it the "enter idle mode" command, and expect to read back 0x01. I've never gotten anything but 0xFF from the card, though, no matter what I send it.

I've tried different cards, different wires, different clock speeds, different SPI clock divs (it's at div 128 on this one, the slowest it can go, although the screen is totally reliable at full-speed SPI / 16 MHz. Did I mention I love this screen?). It's not the formatting because I can't even get it to respond to idle mode, but the format is FAT32.

What on earth am I doing wrong?

User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Re: ILI9340 SD card, what on earth am I doing wrong?

Post by Franklin97355 »

Are you connecting to an Arduino or a custom board? If you are using an Arduino you should make sure it all works with the example code first. Let me know.

User avatar
rbandrews
 
Posts: 9
Joined: Tue Jul 10, 2012 4:19 pm

Re: ILI9340 SD card, what on earth am I doing wrong?

Post by rbandrews »

It's a bare ATmega328 chip on a breadboard.

I can run the CardInfo sketch fine, so it's some problem with this code, but I can't figure out what.

User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Re: ILI9340 SD card, what on earth am I doing wrong?

Post by Franklin97355 »

Could you post your code here and a description or drawing of your connections between it all?
Please use the code button as shown below.
Code Button.jpg
Code Button.jpg (4.49 KiB) Viewed 676 times

User avatar
rbandrews
 
Posts: 9
Joined: Tue Jul 10, 2012 4:19 pm

Re: ILI9340 SD card, what on earth am I doing wrong?

Post by rbandrews »

Sure, the code is below.

The connections are: B3 / B4 / B5 on the chip are MOSI, MISO, and SCK. SDCS is B2. Since it works with the Arduino library I'm pretty sure the wiring is correct.

Code: Select all

#include <avr/io.h>
#include <util/delay.h>

// Some serial comms stuff; just using for debugging
#include "uart.h"

typedef unsigned char byte;

byte spi(byte b); // Send / receive one byte over SPI
void sd_select(int high); // Set SD CS pin high or low
int sd_command(byte cmd, uint32_t arg); // Send one command / arg pair to the SD card
byte sd_wait(); // Wait a max of 3 sec for the card not to be busy

int main(){
    initUSART();

    DDRB |= (1 << 2); // SD CS pin
    PORTB |= (1 << 2); /* start off not selected (high) */

    DDRB |= (1 << 3);  /* output on MOSI */
    PORTB |= (1 << 4); /* pullup on MISO */
    DDRB |= (1 << 5);  /* output on SCK */

    SPCR |= (1 << SPR0) | (1 << SPR1); /* div 128 */
    SPCR |= (1 << MSTR); /* clockmaster */
    SPCR |= (1 << SPE);  /* enable */

    while(1){
        receiveByte();

        // Throw a bunch of cycles with CS high at it
        sd_select(1);
        for(int k=0; k < 10; k++) spi(0xFF);

        sd_select(0); // Start the command

        printStringHex("Wait: ", sd_wait());
        printStringHex("Enter idle state: ", sd_command(0x00, 0));
        
        sd_select(1); // end command
    }

    return 0;
}

////////////////////////////////////////////////////////////

byte spi(byte b) {
    SPDR = b;
    loop_until_bit_is_set(SPSR, SPIF); /* wait until done */
    return SPDR; /* SPDR now contains the received byte */
}

void sd_select(int high){
    if(high) DDRB |=  (1 << 2);
    else     DDRB &= ~(1 << 2);
}

int sd_command(byte cmd, uint32_t arg){
    spi(cmd | 0x40);

    spi(arg >> 24);
    spi(arg >> 16);
    spi(arg >> 8);
    spi(arg);

    byte crc = 0xFF;
    if (cmd == 0x00) crc = 0x95;
    if (cmd == 0x08) crc = 0x87;
    spi(crc);

    int count = 0;
    while(1){
        byte status = spi(0xff);

        if(!(status & 0x80)) return status;
        if(count++ > 300) return status;
    }
}

byte sd_wait() {
    int count = 0;
    while(1) {
        if(spi(0xFF) == 0xFF) return 1;
        if(count++ > 300) return 0;
        _delay_ms(10);
    }
}

User avatar
rbandrews
 
Posts: 9
Joined: Tue Jul 10, 2012 4:19 pm

Re: ILI9340 SD card, what on earth am I doing wrong?

Post by rbandrews »

Okay, well, I figured out one stupid thing I was doing: I mixed up DDRB and PORTB, so instead of taking the bit in PORTB low to select the card, I was taking the bit in DDRB low.

Which I should have figured out two hours ago when I looked at the scope trace, but I didn't. So now it's responding to the idle command correctly, which means it's probably easy sailing from here.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”