1     // SPI information obtained from SanDisk's SD card manual
2     // http://www.sandisk.com/pdf/oem/ProdManualSDCardv1.9.pdf
3
4     /*
5         Portions of this code were adapted and used from
6         Radig Ulrich <mail@ulrichradig.de>
7     */
8
9     #define TRUE  (0x1)
10    #define FALSE (0x0)
11
12    #define R1_IN_IDLE_STATE    (0x1)   // The card is in idle state and running initializing process.
13    #define R1_ERASE_RESET      (0x2)   // An erase sequence was cleared before executing because of an out of erase sequence command was received.
14    #define R1_ILLEGAL_COMMAND  (0x4)   // An illegal command code was detected
15    #define R1_COM_CRC_ERROR    (0x8)   // The CRC check of the last command failed.
16    #define R1_ERASE_SEQ_ERROR  (0x10)  // An error in the sequence of erase commands occured.
17    #define R1_ADDRESS_ERROR    (0x20)  // A misaligned address, which did not match the block length was used in the command.
18    #define R1_PARAMETER        (0x40)  // The command's argument (e.g. address, block length) was out of the allowed range for this card.
19
20    #define READ_START_BLOCK            (0b11111110)
21    #define WRITE_SINGLE_START_BLOCK    (0b11111110)
22    #define WRITE_MULTIPLE_START_BLOCK  (0b11111100)
23    #define WRITE_MULTIPLE_STOP_TRAN    (0b11111101)
24    #define MMC_DR_MASK                 0x1F
25    #define MMC_DR_ACCEPT               0x05
26
27    #define MSTR                4
28    #define SPR0                0
29    #define SPR1                1
30    #define SPE                 6
31    #define SPI2X               0
32    #define SPIF                7
33
34    #define MMC_Write           PORTB
35    #define MMC_Read            PINB
36    #define MMC_Direction_REG   DDRB
37
38    #define SPI_DI              6
39    #define SPI_DO              5
40    #define SPI_Clock           7
41    #define MMC_Chip_Select     0
42    #define SPI_SS              4
43
44    #define nop()               #asm("nop")
45
46    //set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv)
47    #define MMC_Disable() MMC_Write|= (1<<MMC_Chip_Select);
48
49    //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
50    #define MMC_Enable() MMC_Write&=~(1<<MMC_Chip_Select);
51
52
53    inline void Write_Byte_MMC(UCHAR Byte)
54    {
55        SPDR = Byte;
56        while(!(SPSR & (1<<SPIF)));
57    }
58    inline UCHAR Read_Byte_MMC(void)
59    {
60        UCHAR Byte;
61        SPDR = 0xff;
62
63        while(!(SPSR & (1<<SPIF)));
64
65        Byte = SPDR;
66        return (Byte);
67    }
68
69    UCHAR Write_Command_MMC(UCHAR *CMD)
70    {
71        UCHAR a;
72        UCHAR tmp = 0xff;
73        UCHAR Timeout = 0;
74
75        // Raise chip select
76        MMC_Disable();
77
78        // Send an 8 bit pulse
79        Write_Byte_MMC(0xFF);
80
81        // Lower chip select
82        MMC_Enable();
83
84        // Send the 6 byte command
85        for (a = 0;a<0x06;a++)
86        {
87            Write_Byte_MMC(*CMD++);
88        }
89
90        // Wait for the response
91        while (tmp == 0xff)
92        {
93            tmp = Read_Byte_MMC();
94            if (Timeout++ > 100)
95            {
96                break;
97            }
98        }
99        // for some reason we need to delay here
100       delay_ms(1);
101
102       return(tmp);
103   }
104
105   UCHAR MmcInit()
106   {
107       UCHAR a,b, retry;
108       UCHAR CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
109
110       // Set certain pins to inputs and others to outputs
111       // Only SPI_DI (data in) is an input
112       MMC_Direction_REG &=~(1<<SPI_DI);
113       MMC_Direction_REG |= (1<<SPI_Clock);
114       MMC_Direction_REG |= (1<<SPI_DO);
115       MMC_Direction_REG |= (1<<MMC_Chip_Select);
116       MMC_Direction_REG |= (1<<SPI_SS);
117       MMC_Write |= (1<<MMC_Chip_Select);
118
119       // We need to wait for the MMC_Direction_REG to be ready
120       for(a=0;a<200;a++)
121       {
122           nop();
123       };
124
125       // Enable SPI in Master Mode with IDLE low and clock at 16E6/128
126       SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
127       SPSR = (0<<SPI2X);
128
129       // We need to give the card about a hundred cycles to load
130       for (b = 0; b < 0x0f; ++b)
131       {
132               Write_Byte_MMC(0xff);
133       }
134
135       // Send the initialization commands to the card
136       retry = 0;
137
138       // Note, many examples check for (Write_Command_MMC(CMD) == R1_IN_IDLE_STATE)
139       // However, with our setup the card was in IDLE state and returning another command
140       while((Write_Command_MMC(CMD) & R1_IN_IDLE_STATE) == 0)
141       {
142           // fail and return
143           if (retry++ > 50)
144           {
145               return 1;
146           }
147       }
148
149       // Send the 2nd command
150       retry = 0;
151       CMD[0] = 0x41;
152       CMD[5] = 0xFF;
153       while( Write_Command_MMC (CMD) != 0)
154       {
155           if (retry++ > 50)
156               {
157               return 2;
158               }
159       }
160       // Set the SPI bus to full speed
161       SPCR = SPCR|(0<<SPR0)|(0<<SPR1);
162       SPSR = SPSR|(1<<SPI2X);
163
164       // Raise Chip Select
165       MMC_Disable();
166
167       return 0;
168   }
169
170   UCHAR mmc_write_sector (unsigned long addr,UCHAR *Buffer)
171   {
172       UCHAR tmp;
173       UINT a;
174
175       // Command to write a block to the memory card
176       UCHAR CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
177
178       // Encode the address to a 32-bit address
179       // Ignore the bottom byte of the address as we give the address of the sector
180       CMD[1] = ((addr & 0xFF000000) >> 24);
181       CMD[2] = ((addr & 0x00FF0000) >> 16);
182       CMD[3] = ((addr & 0x0000FF00) >> 8);
183
184       // Send the write command
185       tmp = Write_Command_MMC (CMD);
186       if (tmp != 0)
187       {
188           return(tmp);
189       }
190
191       // Wait a little bit
192       for (a = 0; a < 100; ++a)
193       {
194           Read_Byte_MMC();
195       }
196
197       // Send the start byte
198       Write_Byte_MMC(0xFE);
199
200       // Send all 512 bytes in the buffer
201       for (a = 0; a < 512; ++a)
202       {
203           Write_Byte_MMC(*Buffer++);
204       }
205
206       // Write CRC byte
207       Write_Byte_MMC(0xFF);
208       Write_Byte_MMC(0xFF);
209
210       // Wait for the write to complete
211       while (Read_Byte_MMC() != 0xff);
212
213       // Set MMC_Chip_Select to high
214       MMC_Disable();
215
216       return(0);
217   }
218
219   void MMC_Read_Block(UCHAR *CMD,UCHAR *Buffer,UINT Bytes)
220   {
221       UINT a;
222
223       // Send the read command
224       if (Write_Command_MMC(CMD) != 0)
225       {
226           return;
227       }
228
229       // Send the start byte
230       while (Read_Byte_MMC() != 0xfe);
231
232       // Read off all the bytes in the block
233       for (a = 0; a < Bytes; ++a)
234       {
235           *Buffer++ = Read_Byte_MMC();
236       }
237
238       // Read CRC byte
239       Read_Byte_MMC();
240       Read_Byte_MMC();
241
242       // Set MMC_Chip_Select to high
243       MMC_Disable();
244
245       return;
246   }
247
248   UCHAR mmc_read_sector (unsigned long addr, UCHAR *Buffer)
249   {
250       // Command to read a 512-byte sector
251       UCHAR CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
252
253
254       // Encode the address to a 32-bit address
255       // Ignore the bottom byte of the address as we give the address of the sector
256
257       //addr = addr << 9; //addr = addr * 512
258
259       CMD[1] = ((addr & 0xFF000000) >> 24);
260       CMD[2] = ((addr & 0x00FF0000) >> 16);
261       CMD[3] = ((addr & 0x0000FF00) >> 8);
262
263       MMC_Read_Block(CMD,Buffer,512);
264
265       return(0);
266   }