Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
426 killagreg 1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <string.h>
4
#include "sdc.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;
70
 
71
//________________________________________________________________________________________________________________________________________
72
// Function:    CRC7(uint8_t* cmd, uint32_t len);
73
//
74
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame.
75
//
76
//
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();
111
                if(CheckDelay(timestamp)) break;
112
        }while(rsp != 0xFF);            // wait while card is busy (data out low)
113
        return(rsp);
114
}
115
 
116
//________________________________________________________________________________________________________________________________________
117
// Function:    SDC_SendCMDR1(uint8_t CmdNo, uint32_t arg);
118
//
119
// Description: This function send a command frame to the SD-Card in spi-mode.
120
//
121
//
122
// Returnvalue: The function returns the first response byte like for R1 commands
123
//________________________________________________________________________________________________________________________________________
124
uint8_t SDC_SendCMDR1(uint8_t CmdNo, uint32_t arg)
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));
139
        #endif
140
        SSC_Disable();                  // disable chipselect.
141
        SSC_PutChar(0xFF);      // dummy to sync
142
        SSC_Enable();                   // enable chipselect.
143
 
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++ > 500) 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
}
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
 
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
 
189
SD_Result_t SDC_GetData(uint8_t CmdNo, uint32_t addr, uint8_t *Buffer, uint32_t len)
190
{
191
        uint8_t rsp;
192
        uint16_t a, crc16;
193
        SD_Result_t result = SD_ERROR_UNKNOWN;
194
 
195
        // send the command
196
        rsp = SDC_SendCMDR1(CmdNo, addr);
197
        if (rsp != R1_NO_ERR)
198
        {
199
                result = SD_ERROR_BAD_RESPONSE;
200
                goto end;
201
        }
202
 
203
        do
204
        {
205
                rsp = SSC_GetChar();
206
                if((rsp & 0xF0) == 0x00) // data error token
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();
216
        }
217
        // Read two bytes CRC16-Data checksum
218
        crc16 = SSC_GetChar(); // highbyte first
219
        crc16 = (crc16<<8)|SSC_GetChar(); // lowbyte last
220
/*      if(crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
221
        else */result = SD_SUCCESS;
222
 
223
        end:
224
        if(result != SD_SUCCESS)
225
        {
226
                printf("Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
227
        }
228
        return(result);
229
}
230
 
231
 
232
//________________________________________________________________________________________________________________________________________
233
// Function:    SDC_PrintCID(u8 * pCID);
234
//
235
// Description: This function prints the CIS register in a human readable format.
236
//
237
//
238
// Returnvalue: the function returns nothing
239
//________________________________________________________________________________________________________________________________________
240
 
241
void SDC_PrintCID(uint8_t * pCID)
242
{
243
        uint8_t pn[6];
244
        uint16_t temp1, temp2;
245
 
246
        printf("\r\n  Manufacturer ID: %i\r\n", pCID[0]);
247
        memcpy(pn, &pCID[1], 2);
248
        pn[2] = '\0'; // terminate string
249
        printf("  Application ID: %s\r\n",pn);
250
        memcpy(pn, &pCID[3], 5);
251
        pn[5] = '\0'; // terminate string
252
        printf("  Product Name: %s\r\n",pn);
253
        printf("  Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
254
        printf("  Serial No.: ");
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
261
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year
262
        printf("  Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
263
}
264
 
265
//________________________________________________________________________________________________________________________________________
266
// Function:    SDC_GetCID(uint8_t * pCID);
267
//
268
// Description: This function reads the CIS register form the sd card in spi mode.
269
//
270
//
271
// Returnvalue: the function returns error state
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
//
285
// Returnvalue: the function returns error state
286
//________________________________________________________________________________________________________________________________________
287
 
288
SD_Result_t SDC_GetCSD(uint8_t * pCSD)
289
{
290
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
291
}
292
 
293
 
294
//________________________________________________________________________________________________________________________________________
295
// Function:    SDC_Init(void);
296
//
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.
301
//________________________________________________________________________________________________________________________________________
302
 
303
SD_Result_t SDC_Init(void)
304
{
305
        uint16_t timeout = 0;
306
        uint8_t rsp[6]; // SD-SPI response buffer
307
        SD_Result_t result = SD_ERROR_UNKNOWN;
308
 
309
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
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("\r\n  SD-CARD V1.x");
522
                                break;
523
                        case VER_20:
524
                                printf("\r\n  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
534
                end:
535
                SSC_Disable();
536
        }
537
        else
538
        {
539
                SSC_Deinit();
540
                SDCardInfo.Valid = 0;
541
                result = SD_ERROR_NOCARD;
542
                printf("No Card in Slot.");
543
        }
544
        return(result);
545
}
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);
568
}
569
 
570
//________________________________________________________________________________________________________________________________________
571
// Function:    SDC_PutSector(uint32_t addr, const uint8_t *Buffer)
572
//
573
// Description: This function writes one sector of data to the SSC
574
//
575
//
576
// Returnvalue: SD_Result_t
577
//________________________________________________________________________________________________________________________________________
578
 
579
SD_Result_t SDC_PutSector(uint32_t addr, const uint8_t *Buffer)
580
{
581
        uint8_t rsp;
582
        uint16_t a, crc16;
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
 
601
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
602
        {
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)
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:
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;
662
        }
663
        end:
664
        if(result != SD_SUCCESS)
665
        {
666
                printf("Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
667
        }
668
        return(result);
669
}
670
 
671
 
672
 
673
 
674
//________________________________________________________________________________________________________________________________________
675
// Function:    SDC_GetSector(uint32_t addr,uint8_t *Buffer);
676
//
677
// Description: This function reads one sector of data from the SSC
678
//
679
//
680
// Returnvalue: SD_Result_t
681
//________________________________________________________________________________________________________________________________________
682
 
683
SD_Result_t SDC_GetSector(uint32_t addr,uint8_t *Buffer)
684
{
685
        addr = addr << 9; // convert sectoradress to byteadress
686
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
687
}
688