Subversion Repositories Projects

Rev

Rev 294 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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