I am trying to interface a 32 GB microSD card with PIC32MX795F512L using SPI communication. SPI communication is working fine as I have tested it by shorting the Data Input and Output line and receiving back the data which I sent. I am following the examples provided in Lucio de Jasio's book, Programming 32-bit Microcontrollers in C.
Following are the tasks I am performing:
1. Initializing the SPI Communication in initSPI(), setting the baudrate=76 (250 kHz)
2. Initializing the SD card
-> CS = 1
-> Sending 80 clock cycles to wake the card
-> CS = 0
-> Sending CMD0 command (0x40, 0x00, 0x00, 0x00, 0x00, 0x95)
But the problem is I am not receiving the R1
response from the card, instead I am receiving the 0xFF
. Following is the code:
#define FCY 77000000UL
#define FPB (FCY/2)
#define BAUDRATE 9600
#pragma config POSCMOD=HS,FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_3, FPLLMUL=MUL_21, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF
#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
#include <stdbool.h>
#define SDI _RC4
#define SDCS _RA9
#define enableSD() SDCS = 0
#define disableSD() SDCS = 1
#define readSPI() writeSPI(0xFF)
int main(int argc, char** argv)
{
TRISAbits.TRISA9 = 0; // CS as output
TRISCbits.TRISC4 = 1; // SDI as input
TRISDbits.TRISD0 = 0; // SDO as output
TRISDbits.TRISD10 = 0; // SCK as output
AD1PCFG = 0xFFFF;
DDPCONbits.JTAGEN = 0;
OpenUART1( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (FPB/16/BAUDRATE)-1 );
disableSD(); //CS PIN INITIALLY HIGH TO DISABLE CARD
initSPI();
initSD();
while(1)
{
}
return (EXIT_SUCCESS);
}
void initSPI( void)
{
SPI1BRG = 76; // FPB/154=250KHZ; (76+1)*2 = 154, so brg = 76
SPI1CONbits.MSTEN = 1; // MasterEnable
SPI1CONbits.CKE = 1; // CKE on
SPI1CONbits.ON = 1; // SPI Module ON
}
unsigned char writeSPI(unsigned int b)
{
SPI1BUF=b; // Write to buffer for TX
while( !SPI1STATbits.SPIRBF)
; // Wait transfer complete
return(SPI1BUF);
}
int initSD(void)
{
int i,r,rx;
int data;
// Step1: Disable SD card
disableSD();
// Step2: Send 80 clock cycles to wake up the card
for(i=0; i<=9; i++)
{
data = writeSPI(0xFF);
}
// Step3: Enable SD card
enableSD();
// Step4: Send CMD0 command to RESET
r = sendCMD0();
disableSD();
if(r!=1)
{
putsUART1("CMD reject\n");
}
}
int sendCMD0()
{
int i,r;
enableSD();
writeSPI(0x40);
writeSPI(0x00);
writeSPI(0x00);
writeSPI(0x00);
writeSPI(0x00);
writeSPI(0x95); //CMD0 Command
for( i=0; i<100; i++)
{
r = readSPI();
if ((r & 0x80) == 0)
break;
}
return ( r);
}
Here is the schematic:
I am not receiving the R1
response. It is stuck at step4 in initSD()
.
Is there a way I can know if the card has woken up or not after sending 80 clock pulses? After 80 clock pulses, the response from the card is 0xFF
.
Do I need to reduce the clock frequency? Currently it's 250 kHz.
Why is the card not initializing. How can I fix it?