Subversion Repositories NaviCtrl

Rev

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