Subversion Repositories Projects

Rev

Rev 231 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 231 Rev 294
1
#include <avr/io.h>
1
#include <avr/io.h>
2
#include <util/delay.h>
2
#include <util/delay.h>
3
#include "fat16.h"
3
#include <string.h>
4
#include "sdc.h"
4
#include "sdc.h"
5
#include "ssc.h"
5
#include "ssc.h"
-
 
6
#include "timer0.h"
-
 
7
#include "printf_P.h"
-
 
8
#include "crc16.h"
-
 
9
 
-
 
10
#define _SD_DEBUG
-
 
11
 
-
 
12
#define CMD_GO_IDLE_STATE               0x00    /* CMD00: response R1 */
-
 
13
#define CMD_SEND_OP_COND                0x01    /* CMD01: response R1 */
-
 
14
#define CMD_SEND_IF_COND                0x08    /* CMD08: response R7 */
-
 
15
#define CMD_SEND_CSD                    0x09    /* CMD09: response R1 */
-
 
16
#define CMD_SEND_CID                    0x0A    /* CMD10: response R1 */
-
 
17
#define CMD_SEND_STATUS                 0x0D    /* CMD13: response R2 */
-
 
18
#define CMD_SET_BLOCKLEN                0x10    /* CMD16: arg0[31:0]: block length, response R1*/
-
 
19
#define CMD_READ_SINGLE_BLOCK   0x11    /* CMD17: arg0[31:0]: data address, response R1 */
-
 
20
#define CMD_WRITE_SINGLE_BLOCK  0x18    /* CMD24: arg0[31:0]: data address, response R1 */
-
 
21
#define CMD_APP_CMD                             0x37    /* CMD55: response R1 */
-
 
22
#define CMD_READ_OCR                    0x3A    /* CMD58: response R3 */
-
 
23
#define CMD_CRC_ON_OFF                  0x3B    /* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */
-
 
24
#define ACMD_SEND_OP_COND               0x29    /* ACMD41: arg0[31]: stuff bits, arg0[30]: HCS, arg0[29:0] stuff bits*, response R1 */
-
 
25
 
-
 
26
#define R1_NO_ERR                               0x00
-
 
27
#define R1_IDLE_STATE                   0x01
-
 
28
#define R1_ERASE_RESET                  0x02
-
 
29
#define R1_ILLEGAL_CMD                  0x04
-
 
30
#define R1_COM_CRC_ERR                  0x08
-
 
31
#define R1_ERASE_SEQUENCE_ERR   0x10
-
 
32
#define R1_ADDRESS_ERR                  0x20
-
 
33
#define R1_PARAMETER_ERR                0x40
-
 
34
#define R1_BAD_RESPONSE                 0x80
-
 
35
 
-
 
36
#define R2_NO_ERR                               0x00
-
 
37
#define R2_CARD_LOCKED                  0x01
-
 
38
#define R2_ERASE_WRITE_PROT_ERR 0x02
-
 
39
#define R2_UNKOWN_ERR                   0x04
-
 
40
#define R2_CARD_CTRL_ERR                0x08
-
 
41
#define R2_CARD_ECC_ERR             0x10
-
 
42
#define R2_WRITE_PROT_ERR               0x20
-
 
43
#define R2_ERASE_PARAM_ERR              0x40
-
 
44
#define R2_OUT_OF_RANGE_ERR             0x80
-
 
45
 
-
 
46
#define DATA_START_TOKEN                0xFE
-
 
47
#define DATA_RESPONSE_MASK              0x1F
-
 
48
#define DATA_RESPONSE_OK                0x05
-
 
49
#define DATA_RESPONSE_CRC_ERR   0x0B
-
 
50
#define DATA_RESPONSE_WRITE_ERR 0x1D
-
 
51
 
-
 
52
typedef enum
-
 
53
{
-
 
54
        VER_UNKNOWN,
-
 
55
        VER_1X,
-
 
56
        VER_20
-
 
57
} SDVersion_t;
-
 
58
 
-
 
59
typedef struct
-
 
60
{
-
 
61
  uint8_t Valid;
-
 
62
  SDVersion_t Version;  // HW-Version
-
 
63
  uint32_t Capacity;                    // Memory capacity in bytes
-
 
64
  uint8_t CID[16];                      // CID register
-
 
65
  uint8_t CSD[16];                      // CSD register
-
 
66
} __attribute__((packed)) SDCardInfo_t;
-
 
67
 
-
 
68
 
-
 
69
volatile SDCardInfo_t SDCardInfo;
6
 
70
 
7
//________________________________________________________________________________________________________________________________________
-
 
8
// Module name:                 mmc.c 
-
 
9
// Compiler used:               avr-gcc 3.4.5
-
 
10
// Last Modifikation:   24.07.2007
-
 
11
// Version:                             1.05
-
 
12
// Authors:                             Stephan Busker  
71
//________________________________________________________________________________________________________________________________________
13
// Description:                 Source files for connecting to an sdcard using the SSC
72
// Function:    CRC7(uint8_t* cmd, uint32_t len);
14
//
73
//
15
//........................................................................................................................................
-
 
16
// Functions:                   u8                      SDC_init(void);
-
 
17
//                                              u8 SDC_PutCommand (u8*CMD);
-
 
18
//                                              u8 SDC_PutSector(u32 addr,u8*Buffer);
-
 
19
//                                              u8 SDC_GetSector(u32 addr,u8*Buffer);
-
 
20
//                                              void SDC_GetBlock(u8*CMD,u8*Buffer,u16 Bytes);
74
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame.
21
//
-
 
22
////........................................................................................................................................
-
 
23
// ext. functions:              extern void SSC_Init(void);
-
 
24
//                                              extern u8 SSC_GetChar (void);
-
 
25
//                                              extern void SSC_PutChar (u8);
-
 
26
//                                              extern void SSC_Enable(void);
-
 
27
//                                              extern void SSC_Disable(void);
-
 
28
//........................................................................................................................................
75
//
29
//
-
 
30
// URL:                                 www.Mikro-Control.de
76
//
31
// mailto:                              stephan.busker@mikro-control.de
77
// Returnvalue: the function returns the crc7 including bit 0 set to 1
-
 
78
//________________________________________________________________________________________________________________________________________
-
 
79
 
-
 
80
uint8_t CRC7(uint8_t *cmd, uint32_t len)
-
 
81
{
-
 
82
        uint8_t i, a;
-
 
83
        uint8_t crc, Data;
-
 
84
 
-
 
85
        crc = 0; // init CRC buffer
-
 
86
        for (a = 0; a < len ;a++) // for every byte in the msg
-
 
87
        {
-
 
88
                Data = cmd[a];
-
 
89
                for (i=0;i<8;i++) // for every bit in the byte
-
 
90
                {
-
 
91
                        crc <<= 1; // shift crc
-
 
92
                        if ((Data & 0x80)^(crc & 0x80)) crc ^=0x09;       //xor
-
 
93
                        Data <<= 1;     // shift data  for next bit
-
 
94
                }
-
 
95
        }
-
 
96
        crc = (crc<<1)|1; // set terminating bit to 1
-
 
97
        return(crc);
-
 
98
}
-
 
99
 
-
 
100
 
-
 
101
uint8_t SDC_WaitForBusy(uint16_t timeout)
-
 
102
{
-
 
103
        uint8_t rsp = 0;
-
 
104
        uint16_t timestamp = 0;
-
 
105
 
-
 
106
        SSC_Enable();                           // enable chipselect.
-
 
107
        timestamp = SetDelay(timeout);
-
 
108
        do
-
 
109
        {
-
 
110
                rsp = SSC_GetChar();
32
//________________________________________________________________________________________________________________________________________
111
                if(CheckDelay(timestamp)) break;
33
 
112
        }while(rsp != 0xFF);            // wait while card is busy (data out low)
34
 
-
 
35
 
-
 
36
 
-
 
37
//________________________________________________________________________________________________________________________________________
113
        return(rsp);
-
 
114
}
-
 
115
 
-
 
116
//________________________________________________________________________________________________________________________________________
38
// Funtion:     SDC_Init(void);
117
// Function:    SDC_SendCMDR1(uint8_t CmdNo, uint32_t arg);
39
// 
118
//
40
// Description: This function initialises the SDCard to spi-mode. 
-
 
41
//                              
119
// Description: This function send a command frame to the SD-Card in spi-mode.
42
//
120
//
43
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
121
//
44
//________________________________________________________________________________________________________________________________________
122
// Returnvalue: The function returns the first response byte like for R1 commands
45
 
123
//________________________________________________________________________________________________________________________________________
46
u8 SDC_Init(void)
124
uint8_t SDC_SendCMDR1(uint8_t CmdNo, uint32_t arg)
47
{
125
{
-
 
126
        uint8_t r1;
-
 
127
        uint16_t timeout = 0;
-
 
128
        uint16_t a;
-
 
129
        uint8_t cmd[6];
-
 
130
 
-
 
131
        cmd[0] = 0x40|CmdNo;    // set command index
-
 
132
        cmd[1] = (arg & 0xFF000000)>>24;
-
 
133
        cmd[2] = (arg & 0x00FF0000)>>16;
-
 
134
        cmd[3] = (arg & 0x0000FF00)>>8;
-
 
135
        cmd[4] = (arg & 0x000000FF);
-
 
136
        cmd[5] = CRC7(cmd, 5); // update checksum
-
 
137
        #ifdef _SD_DEBUG
-
 
138
        printf("\r\nCmd=%02X, arg=%04X%04X", CmdNo, (uint16_t)(arg>>16), (uint16_t)(0xFFFF & arg));
48
        u8 Timeout = 0;
139
        #endif
-
 
140
        SSC_Disable();                  // disable chipselect.
-
 
141
        SSC_PutChar(0xFF);      // dummy to sync
-
 
142
        SSC_Enable();                   // enable chipselect.
-
 
143
        _delay_loop_2(200);
-
 
144
        //SDC_WaitForBusy(500); // wait 500ms until card is busy
-
 
145
 
-
 
146
        for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
-
 
147
        {
-
 
148
                SSC_PutChar(cmd[a]);
-
 
149
                _delay_loop_2(10);
-
 
150
        }
-
 
151
        // get response byte
-
 
152
        do
-
 
153
        {
-
 
154
                r1 = SSC_GetChar();       // get byte from sd-card
-
 
155
                if (timeout++ > 1000) break;
-
 
156
        }while(r1 == 0xFF); // wait for the response byte from sd-card.
-
 
157
        #ifdef _SD_DEBUG
-
 
158
        printf("-->R1=%02X", r1);
-
 
159
        #endif
-
 
160
        return(r1);
-
 
161
}
49
        u8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
162
 
-
 
163
//________________________________________________________________________________________________________________________________________
-
 
164
// Function:    SDC_SendACMDR1(uint8_t CmdNo, uint32_t arg);
-
 
165
//
-
 
166
// Description: This function send a application command frame to the SD-Card in spi-mode.
-
 
167
//
-
 
168
//
-
 
169
// Returnvalue: The function returns the first response byte like for R1 commands
-
 
170
//________________________________________________________________________________________________________________________________________
-
 
171
uint8_t SDC_SendACMDR1(uint8_t CmdNo, uint32_t arg)
-
 
172
{
-
 
173
        uint8_t r1 = 0xFF;
-
 
174
        r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
-
 
175
        if(r1 & R1_BAD_RESPONSE) return(r1);
-
 
176
        r1 = SDC_SendCMDR1(CmdNo, arg);
-
 
177
        return(r1);
-
 
178
}
-
 
179
 
50
        u16 a = 0;
180
//________________________________________________________________________________________________________________________________________
-
 
181
// Function:    SDC_GetData(uint8_t * cmd ,u8 *Buffer, u32 len);
-
 
182
//
-
 
183
// Description: This function sneds cmd an reads a datablock of len from the sd-card
-
 
184
//
-
 
185
//
-
 
186
// Returnvalue: SD_Result_t
-
 
187
//________________________________________________________________________________________________________________________________________
-
 
188
 
51
        u8      b = 0;
189
SD_Result_t SDC_GetData(uint8_t CmdNo, uint32_t addr, uint8_t *Buffer, uint32_t len)
52
 
190
{
53
        SSC_Init();                                                                                                             // Initialise SSC to transmit data to the sdcard.
191
        uint8_t rsp;
54
 
192
        uint16_t a, crc16;
55
 
-
 
56
        _delay_ms(10);                                                                                                  // before initialising the sdcard wait for 10ms
193
        SD_Result_t result = SD_ERROR_UNKNOWN;
57
 
-
 
58
 
-
 
59
        for (b=0;b<0x0f;b++)                                                                                    // sending 74Clocks brings the sdcard into spimode.
-
 
60
        {
-
 
61
                _delay_us(1);                                                                                           // wait at least 1us between the characters.
-
 
62
                SSC_PutChar(0xff);
194
 
63
        }
-
 
64
       
-
 
65
       
-
 
66
        while(SDC_PutCommand (CMD) !=1)                                                         // Sending CMD0 (Reset) to the sdcard.
-
 
67
        {
-
 
68
                if (Timeout++ > 200)
-
 
69
                {                      
195
        // send the command
70
                        return(1);                                                                             
196
        rsp = SDC_SendCMDR1(CmdNo, addr);
-
 
197
        if (rsp != R1_NO_ERR)
71
                }
198
        {
-
 
199
                result = SD_ERROR_BAD_RESPONSE;
72
        }
200
                goto end;
73
       
201
        }
-
 
202
 
-
 
203
        do
-
 
204
        {
-
 
205
                rsp = SSC_GetChar();
-
 
206
                if((rsp & 0xF0) == 0x00) // data error token
74
        Timeout = 0;
207
                {
-
 
208
                        result = SD_ERROR_READ_DATA;
-
 
209
                        goto end;
-
 
210
                }
-
 
211
        }while(rsp != DATA_START_TOKEN);
-
 
212
        // data start token received
-
 
213
        for (a = 0; a < len; a++)       // read the block from the SSC
-
 
214
        {
-
 
215
                Buffer[a] = SSC_GetChar();
75
        CMD[0] = 0x41;                                                                                                 
216
        }
-
 
217
        // Read two bytes CRC16-Data checksum
76
        CMD[5] = 0xFF;
218
        crc16 = SSC_GetChar(); // highbyte first
77
        while( SDC_PutCommand (CMD) !=0)                                                                // Sending CMD1 to the sdcard.
219
        crc16 = (crc16<<8)|SSC_GetChar(); // lowbyte last
78
        {
220
/*      if(crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
79
                if (Timeout++ > 100)
221
        else */result = SD_SUCCESS;
80
                {
222
 
81
                        return(2);
223
        end:
82
                }
224
        if(result != SD_SUCCESS)
83
        }
225
        {
84
 
226
                printf("Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
85
        SSC_Disable();                                                                                                  // disable sdcard.
227
        }
86
        return(0);
228
        return(result);
87
}
229
}
88
 
230
 
89
 
-
 
90
 
-
 
91
 
231
 
92
//________________________________________________________________________________________________________________________________________
232
//________________________________________________________________________________________________________________________________________
93
// Funtion:     SDC_PutCommand(* CMD);
-
 
94
// 
-
 
95
// Description: This function initialises the SDCard to spi-mode. 
-
 
96
//                              
233
// Function:    SDC_PrintCID(u8 * pCID);
97
//
234
//
-
 
235
// Description: This function prints the CIS register in a human readable format.
-
 
236
//
-
 
237
//
98
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
238
// Returnvalue: the function returns nothing
99
//________________________________________________________________________________________________________________________________________
239
//________________________________________________________________________________________________________________________________________
100
 
240
 
101
u8 SDC_PutCommand (u8*CMD)
241
void SDC_PrintCID(uint8_t * pCID)
102
{
242
{
103
        u8 tmp = 0xff;
-
 
104
        u8 Timeout = 0;
-
 
105
        u16 a = 0;
243
        uint8_t pn[6];
106
 
244
        uint16_t temp1, temp2;
107
 
245
 
108
        #ifdef SSC_RX_FIFO 
246
        printf("\r\n Manufacturer ID: %i\r\n", pCID[0]);
-
 
247
        memcpy(pn, &pCID[1], 2);
109
        SSC_ClearRxFifo();
248
        pn[2] = '\0'; // terminate string
110
        #endif
249
        printf(" Application ID: %s\r\n",pn);
111
        SSC_Disable();                                                                                                          // disable chipselect
-
 
112
        SSC_PutChar(0xFF);                                                                                                      // Send 8 Clocks to the sdcard while card is not selected.
250
        memcpy(pn, &pCID[3], 5);
113
        SSC_Enable();                                                                                                           // enable chipselect.
-
 
-
 
251
        pn[5] = '\0'; // terminate string
114
 
252
        printf(" Product Name: %s\r\n",pn);
115
    if (*CMD == 0x41) _delay_ms(10);                                                                    // if command is CMD0 generate a short delay. 
253
        printf(" Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
116
       
254
        printf(" Serial No.: ");
117
        for (a = 0;a<0x06;a++)                                                                                  // send the command sequence to the sdcard (6 bytes)
255
        for(temp1 = 0; temp1<4; temp1++)
-
 
256
        {
-
 
257
                printf("%02X", pCID[9+temp1]);
-
 
258
        }
-
 
259
        printf("\r\n");
-
 
260
        temp1 = pCID[14] & 0x0F;    // month
118
        {
-
 
-
 
261
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year
119
                SSC_PutChar(*CMD++);
262
        printf(" Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
120
        }
263
}
121
 
264
 
122
        #ifdef SSC_RX_FIFO 
265
//________________________________________________________________________________________________________________________________________
123
        SSC_ClearRxFifo();
-
 
124
        #endif
-
 
125
        while (tmp == 0xff)                                                                                                     // Wait for response from sdcard.
266
// Function:    SDC_GetCID(uint8_t * pCID);
126
        {
267
//
127
                tmp = SSC_GetChar();
-
 
128
                if (Timeout++ > 100)
-
 
-
 
268
// Description: This function reads the CIS register form the sd card in spi mode.
-
 
269
//
-
 
270
//
129
                {
271
// Returnvalue: the function returns error state
130
                        break;                                                                                                          // or timeout.
272
//________________________________________________________________________________________________________________________________________
-
 
273
 
-
 
274
SD_Result_t SDC_GetCID(uint8_t * pCID)
-
 
275
{
-
 
276
        return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
-
 
277
}
-
 
278
 
-
 
279
//________________________________________________________________________________________________________________________________________
-
 
280
// Function:    SDC_GetCSD(uint8_t * pCSD);
-
 
281
//
-
 
282
// Description: This function reads the CSD register form the sd card in spi mode.
-
 
283
//
-
 
284
//
131
                }
285
// Returnvalue: the function returns error state
132
        }
286
//________________________________________________________________________________________________________________________________________
133
 
287
 
134
        return(tmp);
288
SD_Result_t SDC_GetCSD(uint8_t * pCSD)
135
}
289
{
136
 
290
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
137
 
291
}
138
 
292
 
139
 
293
 
140
//________________________________________________________________________________________________________________________________________
294
//________________________________________________________________________________________________________________________________________
141
// Funtion:     SDC_PutSector(void);
295
// Function:    SDC_Init(void);
142
// 
-
 
143
// Description: This function writes one sector of data to the SSC 
-
 
144
//                              
-
 
145
//
296
//
146
// Returnvalue: none
297
// Description: This function initialises the SDCard to spi-mode.
-
 
298
//
-
 
299
//
-
 
300
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
147
//________________________________________________________________________________________________________________________________________
301
//________________________________________________________________________________________________________________________________________
148
 
302
 
149
u8 SDC_PutSector(u32 addr,u8*Buffer)
303
SD_Result_t SDC_Init(void)
150
{
304
{
151
        u8 tmp;
305
        uint16_t timeout = 0;
152
        u8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
-
 
153
       
-
 
154
        addr = addr << 9;                                                                                                       // convert sectoradress to byteadress
-
 
155
       
-
 
156
        CMD[1] = ((addr & 0xFF000000) >>24 );
-
 
157
        CMD[2] = ((addr & 0x00FF0000) >>16 );
306
        uint8_t rsp[6]; // SD-SPI response buffer
158
        CMD[3] = ((addr & 0x0000FF00) >>8 );
307
        SD_Result_t result = SD_ERROR_UNKNOWN;
159
 
-
 
160
        tmp = SDC_PutCommand (CMD);                                                                             // send command to sdcard.
308
 
-
 
309
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
161
        if (tmp != 0)
310
        {
-
 
311
                printf("\r\n SSC init...");
-
 
312
                SSC_Init();
-
 
313
                printf("ok");
-
 
314
 
-
 
315
                _delay_loop_2(1050);
-
 
316
 
-
 
317
                printf("\r\n SDC init...");
-
 
318
                SDCardInfo.Valid = 0;
-
 
319
                /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
-
 
320
                start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
-
 
321
                mode, CS shall be held to high during 74 clock cycles. */
-
 
322
                SSC_Disable(); // set SD_CS high
-
 
323
                for (timeout = 0; timeout < 15; timeout++)      // 15*8 = 120 cycles
-
 
324
                {
-
 
325
                        SSC_PutChar(0xFF);
-
 
326
                }
-
 
327
 
-
 
328
                // switch to idle state
-
 
329
                #ifdef _SD_DEBUG
-
 
330
                printf("\r\nGoing idle state..");
-
 
331
                #endif
-
 
332
                timeout = 0;
-
 
333
                do
-
 
334
                {
-
 
335
                        rsp[0] = SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL);
-
 
336
                        if (timeout++ > 500)
-
 
337
                        {
-
 
338
                                printf("reset timeout");
-
 
339
                                result = SD_ERROR_RESET;
-
 
340
                                goto end;
-
 
341
                        }
-
 
342
                }while(rsp[0] != R1_IDLE_STATE);
-
 
343
            // enable crc feature
-
 
344
/*              if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
-
 
345
                {
-
 
346
                                printf("Bad cmd59 R1=%02X.", rsp[0]);
-
 
347
                                result = SD_ERROR_BAD_RESPONSE;
-
 
348
                                goto end;
-
 
349
                }*/
-
 
350
                // check for card hw version
-
 
351
                // 2.7-3.6V Range = 0x01, check pattern 0xAA
-
 
352
                rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
-
 
353
                // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
-
 
354
                if(rsp[0] & R1_BAD_RESPONSE)
-
 
355
                {
-
 
356
                        printf("Bad cmd8 R1=%02X.", rsp[0]);
-
 
357
                        result = SD_ERROR_BAD_RESPONSE;
-
 
358
                        goto end;
-
 
359
                }
-
 
360
                if(rsp[0] & R1_ILLEGAL_CMD)
-
 
361
                {
-
 
362
                        //Ver1.X SD Memory Card or not a SD Memory Card
-
 
363
                        SDCardInfo.Version = VER_1X;
-
 
364
                }
-
 
365
                else
-
 
366
                {
-
 
367
                   // Ver2.00 or later SD Memory Card
-
 
368
                   // reading the remaining bytes of the R7 response
-
 
369
                   SDCardInfo.Version = VER_20;
-
 
370
                   for(timeout = 1; timeout < 5; timeout++)
-
 
371
                   {
-
 
372
                                rsp[timeout] = SSC_GetChar();
-
 
373
                   }
-
 
374
                   //check pattern
-
 
375
                   if(rsp[4]!= 0xAA)
-
 
376
                   {
-
 
377
                                printf("Bad cmd8 R7 check pattern.\r\n");
-
 
378
                                result = SD_ERROR_BAD_RESPONSE;
-
 
379
                                goto end;
-
 
380
                   }
-
 
381
                   if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
-
 
382
                   {
-
 
383
 
-
 
384
                                printf("Card is incompatible to 3.3V.\r\n");
-
 
385
                                result = SD_ERROR_BAD_VOLTAGE_RANGE;
-
 
386
                                goto end;
-
 
387
                   }
-
 
388
                }
-
 
389
 
-
 
390
                rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
-
 
391
                // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
-
 
392
                if(rsp[0] & R1_BAD_RESPONSE)
-
 
393
                {
-
 
394
                        printf("Bad cmd58 R1 %02x.", rsp[0]);
-
 
395
                        result = SD_ERROR_BAD_RESPONSE;
-
 
396
                        goto end;
-
 
397
                }
-
 
398
                if(rsp[0] & R1_ILLEGAL_CMD)
-
 
399
                {
-
 
400
                        printf("Not an SD-CARD.");
-
 
401
                        result = SD_ERROR_NO_SDCARD;
-
 
402
                        goto end;
-
 
403
                }
-
 
404
                // read 4 bytes of OCR register
-
 
405
                for(timeout = 1; timeout < 5; timeout++)
-
 
406
                {
-
 
407
                        rsp[timeout] = SSC_GetChar();
-
 
408
                }
-
 
409
                //      FollowMe & SD-Logger uses 3.3 V,  therefore check for bit 20 & 21
-
 
410
                if((rsp[2] & 0x30) != 0x30)
-
 
411
                {
-
 
412
                        // supply voltage is not supported by sd-card
-
 
413
                        printf("Card is incompatible to 3.3V.");
-
 
414
                        result = SD_ERROR_BAD_VOLTAGE_RANGE;
-
 
415
                        goto end;
-
 
416
                }
-
 
417
 
-
 
418
                // Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
-
 
419
                timeout =  SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer)
-
 
420
                do
-
 
421
                {
-
 
422
                        rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
-
 
423
                        if(rsp[0] & R1_BAD_RESPONSE)
-
 
424
                        {
-
 
425
                                printf("Bad Acmd41 R1=%02X.", rsp[0]);
-
 
426
                                result = SD_ERROR_BAD_RESPONSE;
-
 
427
                                goto end;
-
 
428
                        }
-
 
429
                        if(CheckDelay(timeout))
-
 
430
                        {
-
 
431
                            printf("Init timeout.");
-
 
432
                                result = SD_ERROR_INITIALIZE;
-
 
433
                                goto end;
-
 
434
                        }
-
 
435
                } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
-
 
436
 
-
 
437
                if(rsp[0] != R1_NO_ERR)
-
 
438
                {
-
 
439
                        printf("Init error.");
-
 
440
                        result = SD_ERROR_INITIALIZE;
-
 
441
                        goto end;
-
 
442
                }
-
 
443
                /* set block size to 512 bytes */
-
 
444
        if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
-
 
445
        {
-
 
446
                printf("Error setting block length to 512.");
-
 
447
                        result = SD_ERROR_SET_BLOCKLEN;
-
 
448
                        goto end;
-
 
449
        }
-
 
450
 
-
 
451
                //SSC_Disable(); // set SD_CS high
-
 
452
                // here is the right place to inrease the SPI baud rate to maximum
-
 
453
                //SSC_Enable(); // set SD_CS high
-
 
454
 
-
 
455
                // read CID register
-
 
456
                result = SDC_GetCID((uint8_t *)&SDCardInfo.CID);
-
 
457
                if(result != SD_SUCCESS)
-
 
458
                {
-
 
459
                        printf("Error reading CID.\r\n");
-
 
460
                        goto end;
-
 
461
                }
-
 
462
 
-
 
463
                // read CSD register
-
 
464
                result = SDC_GetCSD((uint8_t *)&SDCardInfo.CSD);
-
 
465
                if(result != SD_SUCCESS)
-
 
466
                {
-
 
467
                        printf("Error reading CSD.");
-
 
468
                        goto end;
-
 
469
                }
-
 
470
 
-
 
471
                printf("ok\r\n");
-
 
472
 
-
 
473
                uint8_t c_size_mult, read_bl_len;
-
 
474
                uint32_t c_size;
-
 
475
 
-
 
476
                switch(SDCardInfo.CSD[0]>>6) // check CSD Version
-
 
477
                {
-
 
478
                case 0x00: // if CSD is V1.0 structure (2GB limit)
-
 
479
 
-
 
480
                        /*
-
 
481
                        memory capacity = BLOCKNR * BLOCK_LEN
-
 
482
                        BLOCKNR = (C_SIZE+1) * MULT
-
 
483
                        MULT = 2^(C_SIZE_MULT+2)
-
 
484
                        BLOCK_LEN = 2^READ_BL_LEN
-
 
485
 
-
 
486
                        C_SIZE      is 12 bits [73:62] in CSD register
-
 
487
                        C_SIZE_MULT is  3 bits [49:47] in CSD register
-
 
488
                        READ_BL_LEN is  4 bits [83:80] in CSD register
-
 
489
                        */
-
 
490
 
-
 
491
                        read_bl_len = (SDCardInfo.CSD[5] & 0x0F);                               //CSD[05] -> [87:80]
-
 
492
                        c_size = ((uint32_t)(SDCardInfo.CSD[6] & 0x03))<<10;    //CSD[06] -> [79:72]
-
 
493
                        c_size |= ((uint32_t)SDCardInfo.CSD[7])<<2;                             //CSD[07] -> [71:64]
-
 
494
                        c_size |= (uint32_t)(SDCardInfo.CSD[8]>>6);                             //CSD[08] -> [63:56]
-
 
495
                        c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1;                    //CSD[09] -> [55:48]
-
 
496
                        c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7;                   //CSD[10] -> [47:40]
-
 
497
                        SDCardInfo.Capacity = (uint32_t)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
-
 
498
                        break;
-
 
499
 
-
 
500
                case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB)
-
 
501
 
-
 
502
                        /*
-
 
503
                        memory capacity = (C_SIZE+1) * 512K byte
-
 
504
                        C_SIZE is 22 bits [69:48] in CSR register
-
 
505
                        */
-
 
506
 
-
 
507
                        c_size = ((uint32_t)(SDCardInfo.CSD[7] & 0x3F))<<16;    //CSD[07] -> [71:64]
-
 
508
                        c_size |= ((uint32_t)SDCardInfo.CSD[8])<<8;                             //CSD[08] -> [63:56]
-
 
509
                        c_size |= (uint32_t)SDCardInfo.CSD[9];                                  //CSD[09] -> [55:48];
-
 
510
                        SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
-
 
511
                        break;
-
 
512
 
-
 
513
                default: //unknown CSD Version
-
 
514
                        SDCardInfo.Capacity = 0;
-
 
515
                        break;
-
 
516
                }
-
 
517
 
-
 
518
                switch(SDCardInfo.Version)
-
 
519
                {
-
 
520
                        case VER_1X:
-
 
521
                                printf("  SD-CARD V1.x");
-
 
522
                                break;
-
 
523
                        case VER_20:
-
 
524
                                printf("  SD-CARD V2.0 or later");
-
 
525
                        default:
-
 
526
                                break;
-
 
527
                }
-
 
528
                uint16_t mb_size = (uint16_t)(SDCardInfo.Capacity/(1024L*1024L));
-
 
529
                printf("\r\n  Capacity = %i MB", mb_size);
-
 
530
 
-
 
531
                SDC_PrintCID((uint8_t *)&SDCardInfo.CID);
-
 
532
                SDCardInfo.Valid = 1;
-
 
533
                // jump point for error condition before
162
        {
534
                end:
163
                return(tmp);
-
 
164
        }
-
 
165
                       
-
 
166
        #ifdef SSC_RX_FIFO  
535
                SSC_Disable();
167
        SSC_ClearRxFifo();
-
 
168
        #endif
536
        }
169
        for (u8 a=0;a<100;a++)                                                          // wait until sdcard is ready
537
        else
-
 
538
        {
-
 
539
                SSC_Deinit();
-
 
540
                SDCardInfo.Valid = 0;
170
        {
541
                result = SD_ERROR_NOCARD;
171
                SSC_GetChar();
-
 
172
        }
-
 
173
       
-
 
174
        SSC_PutChar(0xFE);                                                                                                      // send start of header to the SSC      
-
 
175
       
-
 
176
        for (u16 a=0;a<512;a++)                                                         // transmitt one sector (normaly 512bytes) of data to the sdcard.
-
 
177
        {
-
 
178
                SSC_PutChar(*Buffer++);
-
 
179
        }
-
 
180
       
-
 
181
        SSC_PutChar(0xFF);                                                                                                      // write two bytes of crc to the sdcard (not used in spi-mode)
-
 
182
        SSC_PutChar(0xFF);
-
 
183
        #ifdef SSC_RX_FIFO  
-
 
184
        SSC_ClearRxFifo();
-
 
185
        #endif
-
 
186
       
-
 
187
        while (SSC_GetChar() != 0xff){};                                                                        // wait untile the sdcard is ready.
-
 
188
       
-
 
189
        SSC_Disable();                                                                                                          // disable sdcard.
542
                printf("No Card in Slot.");
190
 
543
        }
191
        return(0);
544
        return(result);
192
}
545
}
193
 
546
 
-
 
547
 
-
 
548
//________________________________________________________________________________________________________________________________________
-
 
549
// Function:    SDC_Deinit(void);
-
 
550
//
-
 
551
// Description: This function deinitialises the SDCard interface.
-
 
552
//
-
 
553
//
-
 
554
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
-
 
555
//________________________________________________________________________________________________________________________________________
-
 
556
 
-
 
557
SD_Result_t SDC_Deinit(void)
-
 
558
{
-
 
559
        printf("\r\n SDC deinit...");
-
 
560
        SSC_Deinit();
-
 
561
 
-
 
562
        SDCardInfo.Valid = 0;
-
 
563
        SDCardInfo.Capacity = 0;
-
 
564
        SDCardInfo.Version = VER_UNKNOWN;
-
 
565
 
-
 
566
        printf("ok");
-
 
567
        return(SD_SUCCESS);
194
 
568
}
195
 
569
 
196
//________________________________________________________________________________________________________________________________________
570
//________________________________________________________________________________________________________________________________________
197
// Funtion:     SDC_GetSector(u32 addr,u8*Buffer);
571
// Function:    SDC_PutSector(uint32_t addr, const uint8_t *Buffer)
198
// 
572
//
199
// Description: This function reads one sector of data from the SSC
573
// Description: This function writes one sector of data to the SSC
200
//                              
574
//
201
//
575
//
202
// Returnvalue: none
576
// Returnvalue: SD_Result_t
203
//________________________________________________________________________________________________________________________________________
577
//________________________________________________________________________________________________________________________________________
-
 
578
 
-
 
579
SD_Result_t SDC_PutSector(uint32_t addr, const uint8_t *Buffer)
-
 
580
{
204
 
581
        uint8_t rsp;
205
u8 SDC_GetSector(u32 addr,u8*Buffer)
582
        uint16_t a, crc16;
206
{      
583
        uint16_t timeout = 0;
-
 
584
        SD_Result_t result = SD_ERROR_UNKNOWN;
-
 
585
 
-
 
586
        addr = addr << 9; // convert sectoradress to byteadress
-
 
587
        rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
-
 
588
        if (rsp != R1_NO_ERR)
-
 
589
        {
-
 
590
                result = SD_ERROR_BAD_RESPONSE;
-
 
591
                goto end;
-
 
592
        }
-
 
593
 
-
 
594
        for (a=0;a<20;a++)                                      // at least one byte
-
 
595
        {
-
 
596
                SSC_GetChar();
-
 
597
        }
-
 
598
        crc16 = CRC16(Buffer, 512);         // calc checksum for data block
-
 
599
        SSC_PutChar(DATA_START_TOKEN);          // send data start of header to the SSC
-
 
600
 
207
        u8 CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
601
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
-
 
602
        {
208
       
603
                SSC_PutChar(Buffer[a]);
-
 
604
        }
-
 
605
        // write two bytes of crc16 to the sdcard
-
 
606
        SSC_PutChar((uint8_t)(crc16>>8));               // write high byte first
-
 
607
        SSC_PutChar((uint8_t)(0x00FF&crc16));   // lowbyte last
-
 
608
 
-
 
609
        do                                                                      // wait for data response token
-
 
610
        {
-
 
611
                rsp = SSC_GetChar();
-
 
612
                if(timeout++ > 500)
209
        addr = addr << 9;                                                                                                       // convert sectoradress to byteadress.
613
                {
-
 
614
                        result = SD_ERROR_TIMEOUT;
-
 
615
                        goto end;
-
 
616
                }
-
 
617
        }while((rsp & 0x11) != 0x01 );
-
 
618
        // analyse data response token
-
 
619
        switch(rsp & DATA_RESPONSE_MASK)
-
 
620
        {
-
 
621
                case DATA_RESPONSE_OK:
-
 
622
                        result = SD_SUCCESS;
-
 
623
                        break;
-
 
624
                case DATA_RESPONSE_CRC_ERR:
-
 
625
                        result = SD_ERROR_CRC_DATA;
-
 
626
                        goto end;
-
 
627
                        break;
-
 
628
                case DATA_RESPONSE_WRITE_ERR:
-
 
629
                        result = SD_ERROR_WRITE_DATA;
-
 
630
                        goto end;
-
 
631
                        break;
-
 
632
                default:
210
 
633
                        result = SD_ERROR_UNKNOWN;
-
 
634
                        goto end;
-
 
635
                        break;
-
 
636
 
-
 
637
        }
-
 
638
        // wait 2 seconds until the sdcard is busy.
-
 
639
        rsp = SDC_WaitForBusy(2000);
-
 
640
        if(rsp != 0xFF)
-
 
641
        {
-
 
642
                result =  SD_ERROR_TIMEOUT;
-
 
643
                goto end;
-
 
644
        }
-
 
645
 
-
 
646
        // check card status
-
 
647
        rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
-
 
648
        // first byte of R2 response is like R1 response
-
 
649
        if(rsp != R1_NO_ERR)
-
 
650
        {
-
 
651
                result =  SD_ERROR_BAD_RESPONSE;
-
 
652
                SSC_GetChar(); // read out 2nd byte
-
 
653
                goto end;
-
 
654
        }
-
 
655
        // 2nd byte of r2 response
-
 
656
        rsp = SSC_GetChar();
-
 
657
        if(rsp != R2_NO_ERR)
-
 
658
        {
-
 
659
                result =  SD_ERROR_WRITE_DATA;
-
 
660
                SSC_GetChar();
-
 
661
                goto end;
211
        CMD[1] = ((addr & 0xFF000000) >>24 );
662
        }
212
        CMD[2] = ((addr & 0x00FF0000) >>16 );
663
        end:
213
        CMD[3] = ((addr & 0x0000FF00) >>8 );
664
        if(result != SD_SUCCESS)
214
 
665
        {
215
        SDC_GetBlock(CMD,Buffer,512);                                                                   // read specified sector from sdcard.
666
                printf("Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
216
 
667
        }
217
        return(0);
668
        return(result);
218
}
669
}
219
 
670
 
220
 
671
 
-
 
672
 
221
 
673
 
222
//________________________________________________________________________________________________________________________________________
674
//________________________________________________________________________________________________________________________________________
223
// Funtion:     SDC_GetBlock(void);
-
 
224
// 
-
 
225
// Description: This function reads one block of data of s16 bytes from the SSC.
-
 
226
//                              
675
// Function:    SDC_GetSector(uint32_t addr,uint8_t *Buffer);
227
//
676
//
-
 
677
// Description: This function reads one sector of data from the SSC
-
 
678
//
-
 
679
//
228
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
680
// Returnvalue: SD_Result_t
229
//________________________________________________________________________________________________________________________________________
681
//________________________________________________________________________________________________________________________________________
230
 
682
 
231
void SDC_GetBlock(u8*CMD,u8*Buffer,u16 Bytes)
683
SD_Result_t SDC_GetSector(uint32_t addr,uint8_t *Buffer)
232
{      
-
 
233
        if (SDC_PutCommand (CMD) != 0)                                                                          // Send command to the sdcard.
-
 
234
        {
-
 
235
                return;
-
 
236
        }
-
 
237
                       
-
 
238
        #ifdef SSC_RX_FIFO  
-
 
239
        SSC_ClearRxFifo();
-
 
240
        #endif
-
 
241
        while (SSC_GetChar() != 0xfe){};                                                                                // wait until the sdcard is ready to transmitt data.
-
 
242
       
-
 
243
        for (u16 a=0;a<Bytes;a++)                                                                       // read the block from the SSC (normaly 512Bytes)
-
 
244
        {
-
 
245
                *Buffer++ = SSC_GetChar();
-
 
246
        }
-
 
247
       
-
 
248
        SSC_GetChar();                                                                                                                  // Read two bytes CRC- checksum (not used in spi-mode)
684
{
249
        SSC_GetChar(); 
685
        addr = addr << 9; // convert sectoradress to byteadress
250
        SSC_Disable();                                                                                                                  // disable sdcard.
-
 
251
}
-
 
252
 
686
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
253
 
687
}
254
 
688
 
255
 
689