Subversion Repositories NaviCtrl

Rev

Rev 1 | Rev 27 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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