Subversion Repositories NaviCtrl

Rev

Rev 364 | Rev 366 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ingob 1
/*#######################################################################################*/
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
3
/*#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + www.MikroKopter.com
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 7
// + Software Nutzungsbedingungen (english version: see below)
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool 
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
1 ingob 13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand 
22
// + des Mitverschuldens offen.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
27
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
28
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
29
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
1 ingob 31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 32
// + Software LICENSING TERMS
1 ingob 33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware 
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
37
// + The Software may only be used with the Licensor's products.
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
40
// + agreement shall be the property of the Licensor.
41
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
42
// + features that can be used to identify the program may not be altered or defaced by the customer.
43
// + The customer shall be responsible for taking reasonable precautions
44
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
45
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
46
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
47
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
48
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
49
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
50
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
51
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
53
// + #### END OF LICENSING TERMS ####
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
1 ingob 55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 StephanB 56
#include <stdio.h>
57
#include <string.h>
58
#include "91x_lib.h"
41 ingob 59
#include "uart1.h"
24 StephanB 60
#include "sdc.h"
61
#include "ssc.h"
119 killagreg 62
#include "timer1.h"
1 ingob 63
#include "main.h"
24 StephanB 64
#include "crc16.h"
1 ingob 65
 
66
//________________________________________________________________________________________________________________________________________
24 StephanB 67
// Module name:                 sdc.c 
1 ingob 68
// Compiler used:               avr-gcc 3.4.5
24 StephanB 69
// Last Modifikation:   08.06.2008
70
// Version:                             1.07
71
// Authors:                             Stephan Busker, Gregor Stobrawa         
72
// Description:                 Source files for connecting to an sd-card using the SSC
1 ingob 73
//
74
//........................................................................................................................................
24 StephanB 75
// Functions:                   SD_Result_t     SDC_init(void);
76
//                                              u8                      SDC_PutCommand (u8 *cmd);
77
//                                              SD_Result_t     SDC_PutSector(u32 addr,u8 *Buffer);
78
//                                              SD_Result_t     SDC_GetSector(u32 addr,u8 *Buffer);
1 ingob 79
//
80
////........................................................................................................................................
81
// ext. functions:              extern void SSC_Init(void);
24 StephanB 82
//                                              extern u8   SSC_GetChar (void);
1 ingob 83
//                                              extern void SSC_PutChar (u8);
84
//                                              extern void SSC_Enable(void);
85
//                                              extern void SSC_Disable(void);
24 StephanB 86
//                                              extern void     SSC_ClearRxFifo();
1 ingob 87
//........................................................................................................................................
88
//
89
// URL:                                 www.Mikro-Control.de
90
// mailto:                              stephan.busker@mikro-control.de
91
//________________________________________________________________________________________________________________________________________
92
 
93
 
94
 
24 StephanB 95
#define CMD_GO_IDLE_STATE               0x00    /* CMD00: response R1 */
96
#define CMD_SEND_OP_COND                0x01    /* CMD01: response R1 */
97
#define CMD_SEND_IF_COND                0x08    /* CMD08: response R7 */
98
#define CMD_SEND_CSD                    0x09    /* CMD09: response R1 */
99
#define CMD_SEND_CID                    0x0A    /* CMD10: response R1 */
100
#define CMD_SEND_STATUS                 0x0D    /* CMD13: response R2 */
101
#define CMD_SET_BLOCKLEN                0x10    /* CMD16: arg0[31:0]: block length, response R1*/
102
#define CMD_READ_SINGLE_BLOCK   0x11    /* CMD17: arg0[31:0]: data address, response R1 */
103
#define CMD_WRITE_SINGLE_BLOCK  0x18    /* CMD24: arg0[31:0]: data address, response R1 */
104
#define CMD_APP_CMD                             0x37    /* CMD55: response R1 */
105
#define CMD_READ_OCR                    0x3A    /* CMD58: response R3 */
106
#define CMD_CRC_ON_OFF                  0x3B    /* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */                                                                         
107
#define ACMD_SEND_OP_COND               0x29    /* ACMD41: arg0[31]: stuff bits, arg0[30]: HCS, arg0[29:0] stuff bits*, response R1 */
1 ingob 108
 
24 StephanB 109
#define R1_NO_ERR                               0x00
110
#define R1_IDLE_STATE                   0x01
111
#define R1_ERASE_RESET                  0x02
112
#define R1_ILLEGAL_CMD                  0x04
113
#define R1_COM_CRC_ERR                  0x08
114
#define R1_ERASE_SEQUENCE_ERR   0x10
115
#define R1_ADDRESS_ERR                  0x20
116
#define R1_PARAMETER_ERR                0x40
117
#define R1_BAD_RESPONSE                 0x80
118
 
119
#define R2_NO_ERR                               0x00
120
#define R2_CARD_LOCKED                  0x01
121
#define R2_ERASE_WRITE_PROT_ERR 0x02
122
#define R2_UNKOWN_ERR                   0x04
123
#define R2_CARD_CTRL_ERR                0x08
124
#define R2_CARD_ECC_ERR             0x10
125
#define R2_WRITE_PROT_ERR               0x20
126
#define R2_ERASE_PARAM_ERR              0x40
127
#define R2_OUT_OF_RANGE_ERR             0x80
128
 
129
#define DATA_START_TOKEN                0xFE
130
#define DATA_RESPONSE_MASK              0x1F 
131
#define DATA_RESPONSE_OK                0x05
132
#define DATA_RESPONSE_CRC_ERR   0x0B
133
#define DATA_RESPONSE_WRITE_ERR 0x1D
134
 
135
volatile SDCardInfo_t SDCardInfo;
136
 
137
 
1 ingob 138
//________________________________________________________________________________________________________________________________________
24 StephanB 139
// Function:    CRC7(u8* cmd, u32 len);
1 ingob 140
// 
24 StephanB 141
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame. 
1 ingob 142
//                              
143
//
24 StephanB 144
// Returnvalue: the function returns the crc7 including bit 0 set to 1
1 ingob 145
//________________________________________________________________________________________________________________________________________
146
 
24 StephanB 147
u8 CRC7(u8 * cmd, u32 len)
1 ingob 148
{
24 StephanB 149
        u8 i, a;
150
        u8 crc, Data;
1 ingob 151
 
24 StephanB 152
        crc = 0; // init CRC buffer
153
        for (a = 0; a < len ;a++) // for every byte in the msg
154
        {
155
                Data = cmd[a];
156
                for (i=0;i<8;i++) // for every bit in the byte
157
                {
158
                        crc <<= 1; // shift crc
159
                        if ((Data & 0x80)^(crc & 0x80)) crc ^=0x09;       //xor
160
                        Data <<= 1;     // shift data  for next bit
161
                }
162
        }
163
        crc = (crc<<1)|1; // set terminating bit to 1
164
        return(crc);
165
}
1 ingob 166
 
41 ingob 167
u8 SDC_WaitForBusy(u32 timeout)
24 StephanB 168
{
169
        u8 rsp = 0;
41 ingob 170
        u32 timestamp = 0;
1 ingob 171
 
24 StephanB 172
        SSC_ClearRxFifo();
173
        SSC_Enable();                           // enable chipselect.
41 ingob 174
        timestamp = SetDelay(timeout);
24 StephanB 175
        do     
1 ingob 176
        {
24 StephanB 177
                rsp = SSC_GetChar();
41 ingob 178
                if(CheckDelay(timestamp)) break;
362 holgerb 179
        }while(rsp != 0xFF && (SD_WatchDog));           // wait while card is busy (data out low)
24 StephanB 180
        return(rsp);
181
}
182
 
183
 
184
 
185
//________________________________________________________________________________________________________________________________________
186
// Function:    SDC_SendCMDR1(u8 CmdNo, u32 arg);
187
// 
188
// Description: This function send a command frame to the SD-Card in spi-mode. 
189
//                              
190
//
191
// Returnvalue: The function returns the first response byte like for R1 commands
192
//________________________________________________________________________________________________________________________________________
193
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
194
{
195
        u8 r1;
41 ingob 196
        u16 timeout = 0;
24 StephanB 197
        u16 a;
198
        u8 cmd[6];
199
 
200
        SSC_ClearRxFifo();      // clear the rx fifo
201
        SSC_Enable();           // enable chipselect.
41 ingob 202
        SDC_WaitForBusy(500);   // wait 500ms until card is busy
24 StephanB 203
        SSC_ClearRxFifo();      // clear the rx fifo
204
        SSC_GetChar();      // dummy to sync
205
 
206
        cmd[0] = 0x40|CmdNo; // set command index
207
        cmd[1] = (arg & 0xFF000000)>>24;
208
        cmd[2] = (arg & 0x00FF0000)>>16;
209
        cmd[3] = (arg & 0x0000FF00)>>8;
210
        cmd[4] = (arg & 0x000000FF);
211
        cmd[5] = CRC7(cmd, 5); // update checksum 
212
        for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
213
        {      
214
                SSC_PutChar(cmd[a]);
1 ingob 215
        }
24 StephanB 216
        SSC_ClearRxFifo();      // clear the rx fifo to discard the bytes received during the transmission of the 6 command bytes
41 ingob 217
 
24 StephanB 218
        do                                     
1 ingob 219
        {
24 StephanB 220
                r1 = SSC_GetChar();       // get byte from sd-card
41 ingob 221
                if (timeout++ >500) break;
362 holgerb 222
        }while(r1 == 0xFF && (SD_WatchDog)); // wait for the response byte from sd-card.
24 StephanB 223
        return(r1);
1 ingob 224
}
225
 
226
 
24 StephanB 227
//________________________________________________________________________________________________________________________________________
228
// Function:    SDC_SendACMDR1(u8 CmdNo, u32 arg);
41 ingob 229
//                                         
24 StephanB 230
// Description: This function send a application command frame to the SD-Card in spi-mode. 
231
//                              
232
//
233
// Returnvalue: The function returns the first response byte like for R1 commands
234
//________________________________________________________________________________________________________________________________________
235
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
236
{
237
        u8 r1 = 0xFF;
238
        r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
239
        if(r1 & R1_BAD_RESPONSE) return(r1);
240
        r1 = SDC_SendCMDR1(CmdNo, arg);
241
        return(r1);
242
}
1 ingob 243
 
244
 
245
//________________________________________________________________________________________________________________________________________
24 StephanB 246
// Function:    SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
1 ingob 247
// 
24 StephanB 248
// Description: This function sneds cmd an reads a datablock of len from the sd-card
1 ingob 249
//                              
250
//
24 StephanB 251
// Returnvalue: SD_Result_t
1 ingob 252
//________________________________________________________________________________________________________________________________________
253
 
24 StephanB 254
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
1 ingob 255
{
24 StephanB 256
        u8 rsp;        
41 ingob 257
        u16 a, crc16;
146 killagreg 258
        u32 timeout;
24 StephanB 259
        SD_Result_t result = SD_ERROR_UNKNOWN;
1 ingob 260
 
365 holgerb 261
  if(SDCardInfo.Valid == 1)
262
  {
24 StephanB 263
        // send the command     
264
        rsp = SDC_SendCMDR1(CmdNo, addr);
265
        if (rsp != R1_NO_ERR)
1 ingob 266
        {
24 StephanB 267
                result = SD_ERROR_BAD_RESPONSE;
268
                goto end;
1 ingob 269
        }
270
        SSC_ClearRxFifo();
146 killagreg 271
        timeout = SetDelay(500);
24 StephanB 272
        do
1 ingob 273
        {
24 StephanB 274
                rsp = SSC_GetChar();
146 killagreg 275
                if( ( (rsp & 0xF0) == 0x00 ) || CheckDelay(timeout) ) // data error token or timeout 
1 ingob 276
                {
24 StephanB 277
                        result = SD_ERROR_READ_DATA;
278
                        goto end;
1 ingob 279
                }
362 holgerb 280
        }while(rsp != DATA_START_TOKEN && (SD_WatchDog));
24 StephanB 281
        // data start token received
282
        for (a = 0; a < len; a++)       // read the block from the SSC
283
        {
284
                Buffer[a] = SSC_GetChar();
1 ingob 285
        }
24 StephanB 286
        // Read two bytes CRC16-Data checksum
146 killagreg 287
        crc16 = SSC_GetChar(); // highbyte first        
41 ingob 288
        crc16 = (crc16<<8)|SSC_GetChar(); // lowbyte last
289
/*      if(crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
364 ingob 290
        else */
291
        result = SD_SUCCESS;
365 holgerb 292
   }   
24 StephanB 293
        end:
294
        if(result != SD_SUCCESS)
295
        {
296
                sprintf(text,"Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
110 killagreg 297
                UART1_PutString(text);
24 StephanB 298
        }
299
        return(result);
300
}
1 ingob 301
 
24 StephanB 302
 
303
//________________________________________________________________________________________________________________________________________
304
// Function:    SDC_PrintCID(u8 * pCID);
305
// 
306
// Description: This function prints the CIS register in a human readable format. 
307
//                              
308
//
309
// Returnvalue: the function returns nothing
310
//________________________________________________________________________________________________________________________________________
311
 
312
void SDC_PrintCID(u8 * pCID)
313
{
314
        u8 pn[6];
315
        u16 temp1, temp2;
316
 
41 ingob 317
        sprintf(text, "\r\n Manufacturer ID: %i\r\n", pCID[0]);
110 killagreg 318
        UART1_PutString(text);
24 StephanB 319
        memcpy(pn, &pCID[1], 2);
320
        pn[2] = '\0'; // terminate string
41 ingob 321
        sprintf(text, " Application ID: %s\r\n",pn);
110 killagreg 322
        UART1_PutString(text);
24 StephanB 323
        memcpy(pn, &pCID[3], 5);
324
        pn[5] = '\0'; // terminate string
41 ingob 325
        sprintf(text, " Product Name: %s\r\n",pn);
110 killagreg 326
        UART1_PutString(text);
41 ingob 327
        sprintf(text, " Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
110 killagreg 328
        UART1_PutString(text);
329
        UART1_PutString(" Serial No.: ");
24 StephanB 330
        for(temp1 = 0; temp1<4; temp1++)
331
        {
332
                sprintf(text,"%02X", pCID[9+temp1]);
110 killagreg 333
                UART1_PutString(text);
24 StephanB 334
        }
110 killagreg 335
        UART1_PutString("\r\n");
24 StephanB 336
        temp1 = pCID[14] & 0x0F;    // month 
337
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year 
41 ingob 338
        sprintf(text, " Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
110 killagreg 339
        UART1_PutString(text);
1 ingob 340
}
341
 
24 StephanB 342
//________________________________________________________________________________________________________________________________________
343
// Funtion:     SDC_GetCID(u8 * pCID);
344
// 
345
// Description: This function reads the CIS register form the sd card in spi mode. 
346
//                              
347
//
348
// Returnvalue: the function returns error state
349
//________________________________________________________________________________________________________________________________________
1 ingob 350
 
24 StephanB 351
SD_Result_t SDC_GetCID(u8 * pCID)
352
{
353
        return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
354
}
1 ingob 355
 
24 StephanB 356
//________________________________________________________________________________________________________________________________________
357
// Funtion:     SDC_GetCSD(u8 * pCSD);
358
// 
359
// Description: This function reads the CSD register form the sd card in spi mode. 
360
//                              
361
//
362
// Returnvalue: the function returns error state
363
//________________________________________________________________________________________________________________________________________
1 ingob 364
 
24 StephanB 365
SD_Result_t SDC_GetCSD(u8 * pCSD)
366
{
367
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
368
}
369
 
370
 
1 ingob 371
//________________________________________________________________________________________________________________________________________
24 StephanB 372
// Funtion:     SDC_Init(void);
1 ingob 373
// 
24 StephanB 374
// Description: This function initialises the SDCard to spi-mode. 
1 ingob 375
//                              
376
//
24 StephanB 377
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
1 ingob 378
//________________________________________________________________________________________________________________________________________
379
 
24 StephanB 380
SD_Result_t SDC_Init(void)
1 ingob 381
{
41 ingob 382
        u32 timeout = 0;
24 StephanB 383
        u8 rsp[6]; // SD-SPI response buffer
384
        SD_Result_t result = SD_ERROR_UNKNOWN;
385
 
386
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
387
        {
110 killagreg 388
                UART1_PutString("\r\n SSC init...");
24 StephanB 389
                SSC_Init();
110 killagreg 390
                UART1_PutString("ok");
41 ingob 391
 
110 killagreg 392
                UART1_PutString("\r\n SDC init...");
24 StephanB 393
                SDCardInfo.Valid = 0;
394
                /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
395
                start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
396
                mode, CS shall be held to high during 74 clock cycles. */
397
                SSC_Disable(); // set SD_CS high
398
                SSC_ClearRxFifo();      // clear the rx fifo
1 ingob 399
 
41 ingob 400
                for (timeout = 0; timeout < 15; timeout++)      // 15*8 = 120 cycles
24 StephanB 401
                {
402
                        SSC_PutChar(0xFF);
403
                }
404
 
405
                // switch to idle state
406
                while(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) != R1_IDLE_STATE)                                          
407
                {
41 ingob 408
                        if (timeout++ > 20)
24 StephanB 409
                        {
110 killagreg 410
                                UART1_PutString("reset timeout");
24 StephanB 411
                                result = SD_ERROR_RESET;
412
                                goto end;                                                                              
413
                        }
414
                }
415
            // enable crc feature
416
/*              if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
417
                {
41 ingob 418
                                sprintf(text,"Bad cmd59 R1=%02X.", rsp[0]);
110 killagreg 419
                                UART1_PutString(text);
24 StephanB 420
                                result = SD_ERROR_BAD_RESPONSE;
421
                                goto end;
422
                }*/
423
                // check for card hw version                                            
424
                // 2.7-3.6V Range = 0x01, check pattern 0xAA
425
                rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
426
                // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
427
                if(rsp[0] & R1_BAD_RESPONSE)
428
                {
41 ingob 429
                        sprintf(text,"Bad cmd8 R1=%02X.", rsp[0]);
110 killagreg 430
                        UART1_PutString(text);
24 StephanB 431
                        result = SD_ERROR_BAD_RESPONSE;
432
                        goto end;
433
                }
434
                if(rsp[0] & R1_ILLEGAL_CMD)
435
                {
436
                        //Ver1.X SD Memory Card or not a SD Memory Card
437
                        SDCardInfo.Version = VER_1X;                   
438
                }
439
                else
440
                {
441
                   // Ver2.00 or later SD Memory Card
442
                   // reading the remaining bytes of the R7 response
443
                   SDCardInfo.Version = VER_20;
41 ingob 444
                   for(timeout = 1; timeout < 5; timeout++)
24 StephanB 445
                   {
41 ingob 446
                                rsp[timeout] = SSC_GetChar();
24 StephanB 447
                   }
448
                   //check pattern
449
                   if(rsp[4]!= 0xAA)
450
                   {
110 killagreg 451
                                UART1_PutString("Bad cmd8 R7 check pattern.\r\n");
24 StephanB 452
                                result = SD_ERROR_BAD_RESPONSE;
453
                                goto end;
454
                   }
455
                   if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
456
                   {
457
 
110 killagreg 458
                                UART1_PutString("Card is incompatible to 3.3V.\r\n");
24 StephanB 459
                                result = SD_ERROR_BAD_VOLTAGE_RANGE;
460
                                goto end;              
461
                   }
462
                }
463
 
464
                rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
465
                // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
466
                if(rsp[0] & R1_BAD_RESPONSE)
467
                {
41 ingob 468
                        sprintf(text,"Bad cmd58 R1 %02x.", rsp[0]);
110 killagreg 469
                        UART1_PutString(text);
24 StephanB 470
                        result = SD_ERROR_BAD_RESPONSE;
471
                        goto end;
472
                }
473
                if(rsp[0] & R1_ILLEGAL_CMD)
474
                {
110 killagreg 475
                        UART1_PutString("Not an SD-CARD.");
24 StephanB 476
                        result = SD_ERROR_NO_SDCARD;
477
                        goto end;
478
                }
479
                // read 4 bytes of OCR register
41 ingob 480
                for(timeout = 1; timeout < 5; timeout++)
24 StephanB 481
                {
41 ingob 482
                        rsp[timeout] = SSC_GetChar();
24 StephanB 483
                }
484
                //      NavicCtrl uses 3.3 V,  therefore check for bit 20 & 21 
485
                if((rsp[2] & 0x30) != 0x30)
486
                {
487
                        // supply voltage is not supported by sd-card
110 killagreg 488
                        UART1_PutString("Card is incompatible to 3.3V.");
24 StephanB 489
                        result = SD_ERROR_BAD_VOLTAGE_RANGE;
490
                        goto end;
491
                }
492
 
493
                // Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
41 ingob 494
                timeout =  SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer) 
24 StephanB 495
                do
496
                {
497
                        rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
498
                        if(rsp[0] & R1_BAD_RESPONSE)
499
                        {
41 ingob 500
                                sprintf(text,"Bad Acmd41 R1=%02X.", rsp[0]);
110 killagreg 501
                                UART1_PutString(text);
24 StephanB 502
                                result = SD_ERROR_BAD_RESPONSE;
503
                                goto end;
504
                        }
41 ingob 505
                        if(CheckDelay(timeout))
24 StephanB 506
                        {
110 killagreg 507
                            UART1_PutString("Init timeout.");
24 StephanB 508
                                result = SD_ERROR_INITIALIZE;
509
                                goto end;
510
                        }
511
                } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
512
 
513
                if(rsp[0] != R1_NO_ERR)
514
                {
110 killagreg 515
                        UART1_PutString("Init error.");
24 StephanB 516
                        result = SD_ERROR_INITIALIZE;
517
                        goto end;      
518
                }
519
                /* set block size to 512 bytes */
520
        if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
521
        {
110 killagreg 522
                UART1_PutString("Error setting block length to 512.");
24 StephanB 523
                        result = SD_ERROR_SET_BLOCKLEN;
524
                        goto end;
525
        }
41 ingob 526
 
527
                //SSC_Disable(); // set SD_CS high                                                                       
24 StephanB 528
                // here is the right place to inrease the SPI boud rate to maximum              
529
                //SSC_Enable(); // set SD_CS high
530
 
531
                // read CID register
532
                result = SDC_GetCID((u8 *)&SDCardInfo.CID);
533
                if(result != SD_SUCCESS)
534
                {
110 killagreg 535
                        UART1_PutString("Error reading CID.\r\n");
24 StephanB 536
                        goto end;
537
                }
1 ingob 538
 
24 StephanB 539
                // read CSD register
540
                result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
541
                if(result != SD_SUCCESS)
542
                {
110 killagreg 543
                        UART1_PutString("Error reading CSD.");
24 StephanB 544
                        goto end;
545
                }
1 ingob 546
 
110 killagreg 547
                UART1_PutString("ok\r\n");
24 StephanB 548
 
549
                u8 c_size_mult, read_bl_len;
550
                u32 c_size;
551
 
552
                switch(SDCardInfo.CSD[0]>>6) // check CSD Version
553
                {
554
                case 0x00: // if CSD is V1.0 structure (2GB limit)
555
 
556
                        /*
557
                        memory capacity = BLOCKNR * BLOCK_LEN
558
                        BLOCKNR = (C_SIZE+1) * MULT
559
                        MULT = 2^(C_SIZE_MULT+2)
560
                        BLOCK_LEN = 2^READ_BL_LEN
561
 
562
                        C_SIZE      is 12 bits [73:62] in CSD register
563
                        C_SIZE_MULT is  3 bits [49:47] in CSD register
564
                        READ_BL_LEN is  4 bits [83:80] in CSD register
565
                        */
566
 
567
                        read_bl_len = (SDCardInfo.CSD[5] & 0x0F);               //CSD[05] -> [87:80]
568
                        c_size = ((u32)(SDCardInfo.CSD[6] & 0x03))<<10; //CSD[06] -> [79:72]
569
                        c_size |= ((u32)SDCardInfo.CSD[7])<<2;                  //CSD[07] -> [71:64]
570
                        c_size |= (u32)(SDCardInfo.CSD[8]>>6);                  //CSD[08] -> [63:56]
571
                        c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1;    //CSD[09] -> [55:48]
572
                        c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7;   //CSD[10] -> [47:40]
573
                        SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
574
                        break;
575
 
576
                case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB) 
577
 
578
                        /*
579
                        memory capacity = (C_SIZE+1) * 512K byte
580
                        C_SIZE is 22 bits [69:48] in CSR register
581
                        */
582
 
583
                        c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16; //CSD[07] -> [71:64]
584
                        c_size |= ((u32)SDCardInfo.CSD[8])<<8;                  //CSD[08] -> [63:56]
585
                        c_size |= (u32)SDCardInfo.CSD[9];                               //CSD[09] -> [55:48];
586
                        SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
41 ingob 587
                        break;
588
 
589
                default: //unknown CSD Version
24 StephanB 590
                        SDCardInfo.Capacity = 0;
591
                        break; 
592
                }
593
 
594
                switch(SDCardInfo.Version)
595
                {
596
                        case VER_1X:
149 killagreg 597
                                UART1_PutString(" SD-CARD V1.x");
24 StephanB 598
                                break;
599
                        case VER_20:
149 killagreg 600
                                UART1_PutString(" SD-CARD V2.0 or later");
24 StephanB 601
                        default:
602
                                break;
603
                }
604
                u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
149 killagreg 605
                sprintf(text, "\r\n Capacity = %i MB", mb_size);
110 killagreg 606
                UART1_PutString(text);
24 StephanB 607
 
41 ingob 608
                SDC_PrintCID((u8 *)&SDCardInfo.CID);
24 StephanB 609
                SDCardInfo.Valid = 1;
610
                // jump point for error condition before
611
                end:
612
                SSC_Disable();
613
        }
614
        else
1 ingob 615
        {
24 StephanB 616
                SSC_Deinit();
617
                SDCardInfo.Valid = 0;
618
                result = SD_ERROR_NOCARD;
110 killagreg 619
                UART1_PutString("No Card in Slot.");
1 ingob 620
        }
24 StephanB 621
        return(result);
1 ingob 622
}
623
 
624
 
625
//________________________________________________________________________________________________________________________________________
24 StephanB 626
// Funtion:     SDC_Deinit(void);
1 ingob 627
// 
24 StephanB 628
// Description: This function deinitialises the SDCard interface. 
1 ingob 629
//                              
630
//
324 killagreg 631
// Returnvalue: the function returns 0 if the deinitialisation was successfull otherwise the function returns an errorcode.
1 ingob 632
//________________________________________________________________________________________________________________________________________
633
 
24 StephanB 634
SD_Result_t SDC_Deinit(void)
635
{
110 killagreg 636
        UART1_PutString("\r\n SDC deinit...");
364 ingob 637
        // SSC_Deinit();
1 ingob 638
 
24 StephanB 639
        SDCardInfo.Valid = 0;
640
        SDCardInfo.Capacity = 0;
641
        SDCardInfo.Version = VER_UNKNOWN;
1 ingob 642
 
110 killagreg 643
        UART1_PutString("ok");
24 StephanB 644
        return(SD_SUCCESS);
1 ingob 645
}
646
 
647
 
648
//________________________________________________________________________________________________________________________________________
24 StephanB 649
// Funtion:     SDC_PutSector(void);
1 ingob 650
// 
24 StephanB 651
// Description: This function writes one sector of data to the SSC 
1 ingob 652
//                              
653
//
24 StephanB 654
// Returnvalue: SD_Result_t
1 ingob 655
//________________________________________________________________________________________________________________________________________
656
 
24 StephanB 657
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
658
{
659
        u8 rsp;
41 ingob 660
        u16 a, crc16;
24 StephanB 661
        u16 timeout = 0;
662
        SD_Result_t result = SD_ERROR_UNKNOWN;
663
 
664
        addr = addr << 9; // convert sectoradress to byteadress
665
        rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
666
        if (rsp != R1_NO_ERR)
1 ingob 667
        {
24 StephanB 668
                result = SD_ERROR_BAD_RESPONSE;
669
                goto end;
1 ingob 670
        }
671
        SSC_ClearRxFifo();             
24 StephanB 672
        for (a=0;a<20;a++)                                      // at least one byte
1 ingob 673
        {
24 StephanB 674
                SSC_GetChar();
1 ingob 675
        }
41 ingob 676
        crc16 = CRC16(Buffer, 512);         // calc checksum for data block
24 StephanB 677
        SSC_PutChar(DATA_START_TOKEN);          // send data start of header to the SSC 
1 ingob 678
 
24 StephanB 679
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
680
        {
681
                SSC_PutChar(Buffer[a]);
682
        }
683
        // write two bytes of crc16 to the sdcard
41 ingob 684
        SSC_PutChar((u8)(crc16>>8));            // write high byte first
685
        SSC_PutChar((u8)(0x00FF&crc16));        // lowbyte last
24 StephanB 686
        SSC_ClearRxFifo();
687
        do                                                                      // wait for data response token
688
        {
689
                rsp = SSC_GetChar();
41 ingob 690
                if(timeout++ > 500)
691
                {
692
                        result = SD_ERROR_TIMEOUT;
693
                        goto end;
694
                }
24 StephanB 695
        }while((rsp & 0x11) != 0x01 );
324 killagreg 696
 
24 StephanB 697
        // analyse data response token
698
        switch(rsp & DATA_RESPONSE_MASK)
699
        {
700
                case DATA_RESPONSE_OK:
701
                        result = SD_SUCCESS;
702
                        break;
703
                case DATA_RESPONSE_CRC_ERR:
704
                        result = SD_ERROR_CRC_DATA;
705
                        goto end;
706
                        break;
707
                case DATA_RESPONSE_WRITE_ERR:
708
                        result = SD_ERROR_WRITE_DATA;
709
                        goto end;
710
                        break;
711
                default:
712
                        result = SD_ERROR_UNKNOWN;
713
                        goto end;
714
                        break;
715
 
716
        }
41 ingob 717
        // wait 2 seconds until the sdcard is busy.
718
        rsp = SDC_WaitForBusy(2000);
24 StephanB 719
        if(rsp != 0xFF)
720
        {
41 ingob 721
                result =  SD_ERROR_TIMEOUT;
722
                goto end;
24 StephanB 723
        }
41 ingob 724
 
24 StephanB 725
        // check card status
726
        rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
41 ingob 727
        // first byte of R2 response is like R1 response
24 StephanB 728
        if(rsp != R1_NO_ERR)
729
        {
730
                result =  SD_ERROR_BAD_RESPONSE;
41 ingob 731
                SSC_GetChar(); // read out 2nd byte
24 StephanB 732
                goto end;
733
        }
734
        // 2nd byte of r2 response
735
        rsp = SSC_GetChar();
736
        if(rsp != R2_NO_ERR)
737
        {
738
                result =  SD_ERROR_WRITE_DATA;
739
                SSC_GetChar();
740
                goto end;
741
        }
742
        end:
743
        if(result != SD_SUCCESS)
744
        {
745
                sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
110 killagreg 746
                UART1_PutString(text);
24 StephanB 747
        }
362 holgerb 748
 
24 StephanB 749
        return(result);
41 ingob 750
}
24 StephanB 751
 
752
 
753
//________________________________________________________________________________________________________________________________________
754
// Funtion:     SDC_GetSector(u32 addr,u8 *Buffer);
755
// 
756
// Description: This function reads one sector of data from the SSC
757
//                              
758
//
759
// Returnvalue: SD_Result_t
760
//________________________________________________________________________________________________________________________________________
761
 
762
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
763
{
764
        addr = addr << 9; // convert sectoradress to byteadress
765
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
1 ingob 766
}
767
 
768
 
769