Subversion Repositories NaviCtrl

Rev

Rev 24 | Rev 41 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 24 Rev 27
1
/*#######################################################################################*/
1
/*#######################################################################################*/
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
3
/*#######################################################################################*/
3
/*#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + Copyright (c) 2008 Ingo Busker, Holger Buss
5
// + Copyright (c) 2008 Ingo Busker, Holger Buss
6
// + Nur für den privaten Gebrauch
6
// + Nur für den privaten Gebrauch
7
// + FOR NON COMMERCIAL USE ONLY
7
// + FOR NON COMMERCIAL USE ONLY
8
// + www.MikroKopter.com
8
// + www.MikroKopter.com
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
10
// + Es gilt für das gesamte Projekt (Hardware, Software, Binärfiles, Sourcecode und Dokumentation), 
11
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
11
// + dass eine Nutzung (auch auszugsweise) nur für den privaten (nicht-kommerziellen) Gebrauch zulässig ist. 
12
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt 
12
// + Sollten direkte oder indirekte kommerzielle Absichten verfolgt werden, ist mit uns (info@mikrokopter.de) Kontakt 
13
// + bzgl. der Nutzungsbedingungen aufzunehmen. 
13
// + bzgl. der Nutzungsbedingungen aufzunehmen. 
14
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
14
// + Eine kommerzielle Nutzung ist z.B.Verkauf von MikroKoptern, Bestückung und Verkauf von Platinen oder Bausätzen,
15
// + Verkauf von Luftbildaufnahmen, usw.
15
// + Verkauf von Luftbildaufnahmen, usw.
16
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
17
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht, 
17
// + Werden Teile des Quellcodes (mit oder ohne Modifikation) weiterverwendet oder veröffentlicht, 
18
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
18
// + unterliegen sie auch diesen Nutzungsbedingungen und diese Nutzungsbedingungen incl. Copyright müssen dann beiliegen
19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
20
// + Sollte die Software (auch auszugesweise) oder sonstige Informationen des MikroKopter-Projekts
21
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
21
// + auf anderen Webseiten oder sonstigen Medien veröffentlicht werden, muss unsere Webseite "http://www.mikrokopter.de"
22
// + eindeutig als Ursprung verlinkt werden
22
// + eindeutig als Ursprung verlinkt werden
23
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
24
// + Keine Gewähr auf Fehlerfreiheit, Vollständigkeit oder Funktion
25
// + Benutzung auf eigene Gefahr
25
// + Benutzung auf eigene Gefahr
26
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
26
// + Wir übernehmen keinerlei Haftung für direkte oder indirekte Personen- oder Sachschäden
27
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
27
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
28
// + Die PORTIERUNG der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur 
28
// + Die PORTIERUNG der Software (oder Teile davon) auf andere Systeme (ausser der Hardware von www.mikrokopter.de) ist nur 
29
// + mit unserer Zustimmung zulässig
29
// + mit unserer Zustimmung zulässig
30
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
30
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
31
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
31
// + Die Funktion printf_P() unterliegt ihrer eigenen Lizenz und ist hiervon nicht betroffen
32
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
33
// + Redistributions of source code (with or without modifications) must retain the above copyright notice, 
33
// + Redistributions of source code (with or without modifications) must retain the above copyright notice, 
34
// + this list of conditions and the following disclaimer.
34
// + this list of conditions and the following disclaimer.
35
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
35
// +   * Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived
36
// +     from this software without specific prior written permission.
36
// +     from this software without specific prior written permission.
37
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permitted 
37
// +   * The use of this project (hardware, software, binary files, sources and documentation) is only permitted 
38
// +     for non-commercial use (directly or indirectly)
38
// +     for non-commercial use (directly or indirectly)
39
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted 
39
// +     Commercial use (for excample: selling of MikroKopters, selling of PCBs, assembly, ...) is only permitted 
40
// +     with our written permission
40
// +     with our written permission
41
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be 
41
// +   * If sources or documentations are redistributet on other webpages, out webpage (http://www.MikroKopter.de) must be 
42
// +     clearly linked as origin 
42
// +     clearly linked as origin 
43
// +   * PORTING this software (or part of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
43
// +   * PORTING this software (or part of it) to systems (other than hardware from www.mikrokopter.de) is NOT allowed
44
//
44
//
45
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
45
// +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
// +  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47
// +  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
48
// +  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49
// +  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50
// +  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51
// +  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
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>
57
#include <stdio.h>
58
#include <string.h>
58
#include <string.h>
59
#include "91x_lib.h"
59
#include "91x_lib.h"
60
#include "uart.h"
60
#include "uart.h"
61
#include "sdc.h"
61
#include "sdc.h"
62
#include "ssc.h"
62
#include "ssc.h"
63
#include "timer.h"
63
#include "timer.h"
64
#include "main.h"
64
#include "main.h"
65
#include "crc16.h"
65
#include "crc16.h"
66
 
66
 
67
//________________________________________________________________________________________________________________________________________
67
//________________________________________________________________________________________________________________________________________
68
// Module name:                 sdc.c 
68
// Module name:                 sdc.c 
69
// Compiler used:               avr-gcc 3.4.5
69
// Compiler used:               avr-gcc 3.4.5
70
// Last Modifikation:   08.06.2008
70
// Last Modifikation:   08.06.2008
71
// Version:                             1.07
71
// Version:                             1.07
72
// Authors:                             Stephan Busker, Gregor Stobrawa         
72
// Authors:                             Stephan Busker, Gregor Stobrawa         
73
// Description:                 Source files for connecting to an sd-card using the SSC
73
// Description:                 Source files for connecting to an sd-card using the SSC
74
//
74
//
75
//........................................................................................................................................
75
//........................................................................................................................................
76
// Functions:                   SD_Result_t     SDC_init(void);
76
// Functions:                   SD_Result_t     SDC_init(void);
77
//                                              u8                      SDC_PutCommand (u8 *cmd);
77
//                                              u8                      SDC_PutCommand (u8 *cmd);
78
//                                              SD_Result_t     SDC_PutSector(u32 addr,u8 *Buffer);
78
//                                              SD_Result_t     SDC_PutSector(u32 addr,u8 *Buffer);
79
//                                              SD_Result_t     SDC_GetSector(u32 addr,u8 *Buffer);
79
//                                              SD_Result_t     SDC_GetSector(u32 addr,u8 *Buffer);
80
//
80
//
81
////........................................................................................................................................
81
////........................................................................................................................................
82
// ext. functions:              extern void SSC_Init(void);
82
// ext. functions:              extern void SSC_Init(void);
83
//                                              extern u8   SSC_GetChar (void);
83
//                                              extern u8   SSC_GetChar (void);
84
//                                              extern void SSC_PutChar (u8);
84
//                                              extern void SSC_PutChar (u8);
85
//                                              extern void SSC_Enable(void);
85
//                                              extern void SSC_Enable(void);
86
//                                              extern void SSC_Disable(void);
86
//                                              extern void SSC_Disable(void);
87
//                                              extern void     SSC_ClearRxFifo();
87
//                                              extern void     SSC_ClearRxFifo();
88
//........................................................................................................................................
88
//........................................................................................................................................
89
//
89
//
90
// URL:                                 www.Mikro-Control.de
90
// URL:                                 www.Mikro-Control.de
91
// mailto:                              stephan.busker@mikro-control.de
91
// mailto:                              stephan.busker@mikro-control.de
92
//________________________________________________________________________________________________________________________________________
92
//________________________________________________________________________________________________________________________________________
93
 
93
 
94
 
94
 
95
 
95
 
96
#define CMD_GO_IDLE_STATE               0x00    /* CMD00: response R1 */
96
#define CMD_GO_IDLE_STATE               0x00    /* CMD00: response R1 */
97
#define CMD_SEND_OP_COND                0x01    /* CMD01: response R1 */
97
#define CMD_SEND_OP_COND                0x01    /* CMD01: response R1 */
98
#define CMD_SEND_IF_COND                0x08    /* CMD08: response R7 */
98
#define CMD_SEND_IF_COND                0x08    /* CMD08: response R7 */
99
#define CMD_SEND_CSD                    0x09    /* CMD09: response R1 */
99
#define CMD_SEND_CSD                    0x09    /* CMD09: response R1 */
100
#define CMD_SEND_CID                    0x0A    /* CMD10: response R1 */
100
#define CMD_SEND_CID                    0x0A    /* CMD10: response R1 */
101
#define CMD_SEND_STATUS                 0x0D    /* CMD13: response R2 */
101
#define CMD_SEND_STATUS                 0x0D    /* CMD13: response R2 */
102
#define CMD_SET_BLOCKLEN                0x10    /* CMD16: arg0[31:0]: block length, response R1*/
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 */
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 */
104
#define CMD_WRITE_SINGLE_BLOCK  0x18    /* CMD24: arg0[31:0]: data address, response R1 */
105
#define CMD_APP_CMD                             0x37    /* CMD55: response R1 */
105
#define CMD_APP_CMD                             0x37    /* CMD55: response R1 */
106
#define CMD_READ_OCR                    0x3A    /* CMD58: response R3 */
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 */                                                                         
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 */
108
#define ACMD_SEND_OP_COND               0x29    /* ACMD41: arg0[31]: stuff bits, arg0[30]: HCS, arg0[29:0] stuff bits*, response R1 */
109
 
109
 
110
#define R1_NO_ERR                               0x00
110
#define R1_NO_ERR                               0x00
111
#define R1_IDLE_STATE                   0x01
111
#define R1_IDLE_STATE                   0x01
112
#define R1_ERASE_RESET                  0x02
112
#define R1_ERASE_RESET                  0x02
113
#define R1_ILLEGAL_CMD                  0x04
113
#define R1_ILLEGAL_CMD                  0x04
114
#define R1_COM_CRC_ERR                  0x08
114
#define R1_COM_CRC_ERR                  0x08
115
#define R1_ERASE_SEQUENCE_ERR   0x10
115
#define R1_ERASE_SEQUENCE_ERR   0x10
116
#define R1_ADDRESS_ERR                  0x20
116
#define R1_ADDRESS_ERR                  0x20
117
#define R1_PARAMETER_ERR                0x40
117
#define R1_PARAMETER_ERR                0x40
118
#define R1_BAD_RESPONSE                 0x80
118
#define R1_BAD_RESPONSE                 0x80
119
 
119
 
120
#define R2_NO_ERR                               0x00
120
#define R2_NO_ERR                               0x00
121
#define R2_CARD_LOCKED                  0x01
121
#define R2_CARD_LOCKED                  0x01
122
#define R2_ERASE_WRITE_PROT_ERR 0x02
122
#define R2_ERASE_WRITE_PROT_ERR 0x02
123
#define R2_UNKOWN_ERR                   0x04
123
#define R2_UNKOWN_ERR                   0x04
124
#define R2_CARD_CTRL_ERR                0x08
124
#define R2_CARD_CTRL_ERR                0x08
125
#define R2_CARD_ECC_ERR             0x10
125
#define R2_CARD_ECC_ERR             0x10
126
#define R2_WRITE_PROT_ERR               0x20
126
#define R2_WRITE_PROT_ERR               0x20
127
#define R2_ERASE_PARAM_ERR              0x40
127
#define R2_ERASE_PARAM_ERR              0x40
128
#define R2_OUT_OF_RANGE_ERR             0x80
128
#define R2_OUT_OF_RANGE_ERR             0x80
129
 
129
 
130
#define DATA_START_TOKEN                0xFE
130
#define DATA_START_TOKEN                0xFE
131
#define DATA_RESPONSE_MASK              0x1F 
131
#define DATA_RESPONSE_MASK              0x1F 
132
#define DATA_RESPONSE_OK                0x05
132
#define DATA_RESPONSE_OK                0x05
133
#define DATA_RESPONSE_CRC_ERR   0x0B
133
#define DATA_RESPONSE_CRC_ERR   0x0B
134
#define DATA_RESPONSE_WRITE_ERR 0x1D
134
#define DATA_RESPONSE_WRITE_ERR 0x1D
135
 
135
 
136
typedef enum
136
typedef enum
137
{
137
{
138
        VER_UNKNOWN,
138
        VER_UNKNOWN,
139
        VER_1X,
139
        VER_1X,
140
        VER_20
140
        VER_20
141
} SDVersion_t;
141
} SDVersion_t;
142
 
142
 
143
typedef struct
143
typedef struct
144
{
144
{
145
  u8 Valid;
145
  u8 Valid;
146
  SDVersion_t Version;  // HW-Version 
146
  SDVersion_t Version;  // HW-Version 
147
  u32 Capacity;                 // Memory capacity  in bytes
147
  u32 Capacity;                 // Memory capacity  in bytes
148
  u8 CID[16];                   // CID register
148
  u8 CID[16];                   // CID register
149
  u8 CSD[16];                   // CSD register
149
  u8 CSD[16];                   // CSD register
150
} __attribute__((packed)) SDCardInfo_t;
150
} __attribute__((packed)) SDCardInfo_t;
151
 
151
 
152
volatile SDCardInfo_t SDCardInfo;
152
volatile SDCardInfo_t SDCardInfo;
153
 
153
 
154
 
154
 
155
//________________________________________________________________________________________________________________________________________
155
//________________________________________________________________________________________________________________________________________
156
// Function:    CRC7(u8* cmd, u32 len);
156
// Function:    CRC7(u8* cmd, u32 len);
157
// 
157
// 
158
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame. 
158
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame. 
159
//                              
159
//                              
160
//
160
//
161
// Returnvalue: the function returns the crc7 including bit 0 set to 1
161
// Returnvalue: the function returns the crc7 including bit 0 set to 1
162
//________________________________________________________________________________________________________________________________________
162
//________________________________________________________________________________________________________________________________________
163
 
163
 
164
u8 CRC7(u8 * cmd, u32 len)
164
u8 CRC7(u8 * cmd, u32 len)
165
{
165
{
166
        u8 i, a;
166
        u8 i, a;
167
        u8 crc, Data;
167
        u8 crc, Data;
168
 
168
 
169
        crc = 0; // init CRC buffer
169
        crc = 0; // init CRC buffer
170
        for (a = 0; a < len ;a++) // for every byte in the msg
170
        for (a = 0; a < len ;a++) // for every byte in the msg
171
        {
171
        {
172
                Data = cmd[a];
172
                Data = cmd[a];
173
                for (i=0;i<8;i++) // for every bit in the byte
173
                for (i=0;i<8;i++) // for every bit in the byte
174
                {
174
                {
175
                        crc <<= 1; // shift crc
175
                        crc <<= 1; // shift crc
176
                        if ((Data & 0x80)^(crc & 0x80)) crc ^=0x09;       //xor
176
                        if ((Data & 0x80)^(crc & 0x80)) crc ^=0x09;       //xor
177
                        Data <<= 1;     // shift data  for next bit
177
                        Data <<= 1;     // shift data  for next bit
178
                }
178
                }
179
        }
179
        }
180
        crc = (crc<<1)|1; // set terminating bit to 1
180
        crc = (crc<<1)|1; // set terminating bit to 1
181
        return(crc);
181
        return(crc);
182
}
182
}
183
 
183
 
184
u8 SDC_WaitForBusy()
184
u8 SDC_WaitForBusy()
185
{
185
{
186
        u8 rsp = 0;
186
        u8 rsp = 0;
187
        u16 timeout=0;
187
        u16 timeout=0;
188
 
188
 
189
        SSC_ClearRxFifo();
189
        SSC_ClearRxFifo();
190
        SSC_Enable();                           // enable chipselect.
190
        SSC_Enable();                           // enable chipselect.
191
        do     
191
        do     
192
        {
192
        {
193
                rsp = SSC_GetChar();
193
                rsp = SSC_GetChar();
194
                if(timeout++>500) break;
194
                if(timeout++>500) break;
195
        }while(rsp != 0xFF);            // wait while card is busy (data out low)
195
        }while(rsp != 0xFF);            // wait while card is busy (data out low)
196
        return(rsp);
196
        return(rsp);
197
}
197
}
198
 
198
 
199
 
199
 
200
 
200
 
201
//________________________________________________________________________________________________________________________________________
201
//________________________________________________________________________________________________________________________________________
202
// Function:    SDC_SendCMDR1(u8 CmdNo, u32 arg);
202
// Function:    SDC_SendCMDR1(u8 CmdNo, u32 arg);
203
// 
203
// 
204
// Description: This function send a command frame to the SD-Card in spi-mode. 
204
// Description: This function send a command frame to the SD-Card in spi-mode. 
205
//                              
205
//                              
206
//
206
//
207
// Returnvalue: The function returns the first response byte like for R1 commands
207
// Returnvalue: The function returns the first response byte like for R1 commands
208
//________________________________________________________________________________________________________________________________________
208
//________________________________________________________________________________________________________________________________________
209
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
209
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
210
{
210
{
211
        u8 r1;
211
        u8 r1;
212
        u16 Timeout = 0;
212
        u16 Timeout = 0;
213
        u16 a;
213
        u16 a;
214
        u8 cmd[6];
214
        u8 cmd[6];
215
 
215
 
216
        SSC_ClearRxFifo();      // clear the rx fifo
216
        SSC_ClearRxFifo();      // clear the rx fifo
217
        SSC_Enable();           // enable chipselect.
217
        SSC_Enable();           // enable chipselect.
218
        SDC_WaitForBusy();
218
        SDC_WaitForBusy();
219
        SSC_ClearRxFifo();      // clear the rx fifo
219
        SSC_ClearRxFifo();      // clear the rx fifo
220
        SSC_GetChar();      // dummy to sync
220
        SSC_GetChar();      // dummy to sync
221
 
221
 
222
        /* Send cmd10 (SEND_CID) */;
222
        /* Send cmd10 (SEND_CID) */;
223
        cmd[0] = 0x40|CmdNo; // set command index
223
        cmd[0] = 0x40|CmdNo; // set command index
224
        cmd[1] = (arg & 0xFF000000)>>24;
224
        cmd[1] = (arg & 0xFF000000)>>24;
225
        cmd[2] = (arg & 0x00FF0000)>>16;
225
        cmd[2] = (arg & 0x00FF0000)>>16;
226
        cmd[3] = (arg & 0x0000FF00)>>8;
226
        cmd[3] = (arg & 0x0000FF00)>>8;
227
        cmd[4] = (arg & 0x000000FF);
227
        cmd[4] = (arg & 0x000000FF);
228
        cmd[5] = CRC7(cmd, 5); // update checksum 
228
        cmd[5] = CRC7(cmd, 5); // update checksum 
229
        for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
229
        for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
230
        {      
230
        {      
231
                SSC_PutChar(cmd[a]);
231
                SSC_PutChar(cmd[a]);
232
        }
232
        }
233
        SSC_ClearRxFifo();      // clear the rx fifo to discard the bytes received during the transmission of the 6 command bytes
233
        SSC_ClearRxFifo();      // clear the rx fifo to discard the bytes received during the transmission of the 6 command bytes
234
        do                                     
234
        do                                     
235
        {
235
        {
236
                r1 = SSC_GetChar();       // get byte from sd-card
236
                r1 = SSC_GetChar();       // get byte from sd-card
237
                if (Timeout++ > 500) return(r1);
237
                if (Timeout++ > 500) return(r1);
238
        }while(r1 == 0xFF); // wait for the response byte from sd-card.
238
        }while(r1 == 0xFF); // wait for the response byte from sd-card.
239
        return(r1);
239
        return(r1);
240
}
240
}
241
 
241
 
242
 
242
 
243
//________________________________________________________________________________________________________________________________________
243
//________________________________________________________________________________________________________________________________________
244
// Function:    SDC_SendACMDR1(u8 CmdNo, u32 arg);
244
// Function:    SDC_SendACMDR1(u8 CmdNo, u32 arg);
245
// 
245
// 
246
// Description: This function send a application command frame to the SD-Card in spi-mode. 
246
// Description: This function send a application command frame to the SD-Card in spi-mode. 
247
//                              
247
//                              
248
//
248
//
249
// Returnvalue: The function returns the first response byte like for R1 commands
249
// Returnvalue: The function returns the first response byte like for R1 commands
250
//________________________________________________________________________________________________________________________________________
250
//________________________________________________________________________________________________________________________________________
251
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
251
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
252
{
252
{
253
        u8 r1 = 0xFF;
253
        u8 r1 = 0xFF;
254
        r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
254
        r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
255
        if(r1 & R1_BAD_RESPONSE) return(r1);
255
        if(r1 & R1_BAD_RESPONSE) return(r1);
256
        r1 = SDC_SendCMDR1(CmdNo, arg);
256
        r1 = SDC_SendCMDR1(CmdNo, arg);
257
        return(r1);
257
        return(r1);
258
}
258
}
259
 
259
 
260
 
260
 
261
//________________________________________________________________________________________________________________________________________
261
//________________________________________________________________________________________________________________________________________
262
// Function:    SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
262
// Function:    SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
263
// 
263
// 
264
// Description: This function sneds cmd an reads a datablock of len from the sd-card
264
// Description: This function sneds cmd an reads a datablock of len from the sd-card
265
//                              
265
//                              
266
//
266
//
267
// Returnvalue: SD_Result_t
267
// Returnvalue: SD_Result_t
268
//________________________________________________________________________________________________________________________________________
268
//________________________________________________________________________________________________________________________________________
269
 
269
 
270
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
270
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
271
{
271
{
272
        u8 rsp;        
272
        u8 rsp;        
273
        u16 timeout;
273
        u16 timeout;
274
        u16 a, Crc16;
274
        u16 a, Crc16;
275
        SD_Result_t result = SD_ERROR_UNKNOWN;
275
        SD_Result_t result = SD_ERROR_UNKNOWN;
276
 
276
 
277
        // send the command     
277
        // send the command     
278
        rsp = SDC_SendCMDR1(CmdNo, addr);
278
        rsp = SDC_SendCMDR1(CmdNo, addr);
279
        if (rsp != R1_NO_ERR)
279
        if (rsp != R1_NO_ERR)
280
        {
280
        {
281
                result = SD_ERROR_BAD_RESPONSE;
281
                result = SD_ERROR_BAD_RESPONSE;
282
                goto end;
282
                goto end;
283
        }
283
        }
284
        SSC_ClearRxFifo();
284
        SSC_ClearRxFifo();
285
        do
285
        do
286
        {
286
        {
287
                rsp = SSC_GetChar();
287
                rsp = SSC_GetChar();
288
                if((rsp & 0xF0) == 0x00) // data error token 
288
                if((rsp & 0xF0) == 0x00) // data error token 
289
                {
289
                {
290
                        result = SD_ERROR_READ_DATA;
290
                        result = SD_ERROR_READ_DATA;
291
                        goto end;
291
                        goto end;
292
                }
292
                }
293
//              if(timeout++>500) break;
293
//              if(timeout++>500) break;
294
        }while(rsp != DATA_START_TOKEN);
294
        }while(rsp != DATA_START_TOKEN);
295
        // data start token received
295
        // data start token received
296
        for (a = 0; a < len; a++)       // read the block from the SSC
296
        for (a = 0; a < len; a++)       // read the block from the SSC
297
        {
297
        {
298
                Buffer[a] = SSC_GetChar();
298
                Buffer[a] = SSC_GetChar();
299
        }
299
        }
300
        // Read two bytes CRC16-Data checksum
300
        // Read two bytes CRC16-Data checksum
301
        Crc16 = SSC_GetChar(); // highbyte fisrt        
301
        Crc16 = SSC_GetChar(); // highbyte fisrt        
302
        Crc16 = (Crc16<<8)|SSC_GetChar(); // lowbyte last
302
        Crc16 = (Crc16<<8)|SSC_GetChar(); // lowbyte last
303
//      if(Crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
303
//      if(Crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
304
/*      else */result = SD_SUCCESS;
304
/*      else */result = SD_SUCCESS;
305
       
305
       
306
        end:
306
        end:
307
        //SSC_Disable();        // disable sdcard.
307
        //SSC_Disable();        // disable sdcard.
308
        if(result != SD_SUCCESS)
308
        if(result != SD_SUCCESS)
309
        {
309
        {
310
                sprintf(text,"Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
310
                sprintf(text,"Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
311
                SerialPutString(text);
311
                SerialPutString(text);
312
        }
312
        }
313
        return(result);
313
        return(result);
314
}
314
}
315
 
315
 
316
 
316
 
317
//________________________________________________________________________________________________________________________________________
317
//________________________________________________________________________________________________________________________________________
318
// Function:    SDC_PrintCID(u8 * pCID);
318
// Function:    SDC_PrintCID(u8 * pCID);
319
// 
319
// 
320
// Description: This function prints the CIS register in a human readable format. 
320
// Description: This function prints the CIS register in a human readable format. 
321
//                              
321
//                              
322
//
322
//
323
// Returnvalue: the function returns nothing
323
// Returnvalue: the function returns nothing
324
//________________________________________________________________________________________________________________________________________
324
//________________________________________________________________________________________________________________________________________
325
 
325
 
326
void SDC_PrintCID(u8 * pCID)
326
void SDC_PrintCID(u8 * pCID)
327
{
327
{
328
        u8 text[50];
328
        u8 text[50];
329
        u8 pn[6];
329
        u8 pn[6];
330
        u16 temp1, temp2;
330
        u16 temp1, temp2;
331
 
331
 
332
        sprintf(text, "\r\nManufacturer ID: %i\r\n", pCID[0]);
332
        sprintf(text, "\r\nManufacturer ID: %i\r\n", pCID[0]);
333
        SerialPutString(text);
333
        SerialPutString(text);
334
        memcpy(pn, &pCID[1], 2);
334
        memcpy(pn, &pCID[1], 2);
335
        pn[2] = '\0'; // terminate string
335
        pn[2] = '\0'; // terminate string
336
        sprintf(text, "Application ID: %s\r\n",pn);
336
        sprintf(text, "Application ID: %s\r\n",pn);
337
        SerialPutString(text);
337
        SerialPutString(text);
338
        memcpy(pn, &pCID[3], 5);
338
        memcpy(pn, &pCID[3], 5);
339
        pn[5] = '\0'; // terminate string
339
        pn[5] = '\0'; // terminate string
340
        sprintf(text, "Product Name: %s\r\n",pn);
340
        sprintf(text, "Product Name: %s\r\n",pn);
341
        SerialPutString(text);
341
        SerialPutString(text);
342
        sprintf(text, "Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
342
        sprintf(text, "Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
343
        SerialPutString(text);
343
        SerialPutString(text);
344
        SerialPutString("Serial No.: ");
344
        SerialPutString("Serial No.: ");
345
        for(temp1 = 0; temp1<4; temp1++)
345
        for(temp1 = 0; temp1<4; temp1++)
346
        {
346
        {
347
                sprintf(text,"%02X", pCID[9+temp1]);
347
                sprintf(text,"%02X", pCID[9+temp1]);
348
                SerialPutString(text);
348
                SerialPutString(text);
349
        }
349
        }
350
        SerialPutString("\r\n");
350
        SerialPutString("\r\n");
351
        temp1 = pCID[14] & 0x0F;    // month 
351
        temp1 = pCID[14] & 0x0F;    // month 
352
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year 
352
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year 
353
        sprintf(text, "Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
353
        sprintf(text, "Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
354
        SerialPutString(text);
354
        SerialPutString(text);
355
}
355
}
356
 
356
 
357
//________________________________________________________________________________________________________________________________________
357
//________________________________________________________________________________________________________________________________________
358
// Funtion:     SDC_GetCID(u8 * pCID);
358
// Funtion:     SDC_GetCID(u8 * pCID);
359
// 
359
// 
360
// Description: This function reads the CIS register form the sd card in spi mode. 
360
// Description: This function reads the CIS register form the sd card in spi mode. 
361
//                              
361
//                              
362
//
362
//
363
// Returnvalue: the function returns error state
363
// Returnvalue: the function returns error state
364
//________________________________________________________________________________________________________________________________________
364
//________________________________________________________________________________________________________________________________________
365
 
365
 
366
SD_Result_t SDC_GetCID(u8 * pCID)
366
SD_Result_t SDC_GetCID(u8 * pCID)
367
{
367
{
368
        return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
368
        return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
369
}
369
}
370
 
370
 
371
//________________________________________________________________________________________________________________________________________
371
//________________________________________________________________________________________________________________________________________
372
// Funtion:     SDC_GetCSD(u8 * pCSD);
372
// Funtion:     SDC_GetCSD(u8 * pCSD);
373
// 
373
// 
374
// Description: This function reads the CSD register form the sd card in spi mode. 
374
// Description: This function reads the CSD register form the sd card in spi mode. 
375
//                              
375
//                              
376
//
376
//
377
// Returnvalue: the function returns error state
377
// Returnvalue: the function returns error state
378
//________________________________________________________________________________________________________________________________________
378
//________________________________________________________________________________________________________________________________________
379
 
379
 
380
SD_Result_t SDC_GetCSD(u8 * pCSD)
380
SD_Result_t SDC_GetCSD(u8 * pCSD)
381
{
381
{
382
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
382
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
383
}
383
}
384
 
384
 
385
 
385
 
386
//________________________________________________________________________________________________________________________________________
386
//________________________________________________________________________________________________________________________________________
387
// Funtion:     SDC_Init(void);
387
// Funtion:     SDC_Init(void);
388
// 
388
// 
389
// Description: This function initialises the SDCard to spi-mode. 
389
// Description: This function initialises the SDCard to spi-mode. 
390
//                              
390
//                              
391
//
391
//
392
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
392
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
393
//________________________________________________________________________________________________________________________________________
393
//________________________________________________________________________________________________________________________________________
394
 
394
 
395
SD_Result_t SDC_Init(void)
395
SD_Result_t SDC_Init(void)
396
{
396
{
397
        u32 Timeout = 0;
397
        u32 Timeout = 0;
398
        u8 text[50];
398
        u8 text[50];
399
        u8 rsp[6]; // SD-SPI response buffer
399
        u8 rsp[6]; // SD-SPI response buffer
400
        SD_Result_t result = SD_ERROR_UNKNOWN;
400
        SD_Result_t result = SD_ERROR_UNKNOWN;
401
               
401
               
402
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
402
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
403
        {
403
        {
404
                SerialPutString("\r\n  SSC init...");  
404
                SerialPutString("\r\n  SSC init...");  
405
                SSC_Init();
405
                SSC_Init();
406
                SerialPutString("ok");
406
                SerialPutString("ok");
407
       
407
       
408
                SerialPutString("\r\n  SDC init...");  
408
                SerialPutString("\r\n  SDC init...");  
409
                SDCardInfo.Valid = 0;
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
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
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. */
412
                mode, CS shall be held to high during 74 clock cycles. */
413
                SSC_Disable(); // set SD_CS high
413
                SSC_Disable(); // set SD_CS high
414
                SSC_ClearRxFifo();      // clear the rx fifo
414
                SSC_ClearRxFifo();      // clear the rx fifo
415
       
415
       
416
                for (Timeout = 0; Timeout < 15; Timeout++)      // 15*8 = 120 cycles
416
                for (Timeout = 0; Timeout < 15; Timeout++)      // 15*8 = 120 cycles
417
                {
417
                {
418
                        SSC_PutChar(0xFF);
418
                        SSC_PutChar(0xFF);
419
                }
419
                }
420
       
420
       
421
                // switch to idle state
421
                // switch to idle state
422
                while(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) != R1_IDLE_STATE)                                          
422
                while(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) != R1_IDLE_STATE)                                          
423
                {
423
                {
424
                        if (Timeout++ > 20)
424
                        if (Timeout++ > 20)
425
                        {
425
                        {
426
                                SerialPutString("reset timeout");
426
                                SerialPutString("reset timeout");
427
                                result = SD_ERROR_RESET;
427
                                result = SD_ERROR_RESET;
428
                                goto end;                                                                              
428
                                goto end;                                                                              
429
                        }
429
                        }
430
                }
430
                }
431
            // enable crc feature
431
            // enable crc feature
432
/*              if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
432
/*              if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
433
                {
433
                {
434
                                sprintf(text,"Bad cmd59 R1=%02X.\r\n", rsp[0]);
434
                                sprintf(text,"Bad cmd59 R1=%02X.\r\n", rsp[0]);
435
                                SerialPutString(text);
435
                                SerialPutString(text);
436
                                result = SD_ERROR_BAD_RESPONSE;
436
                                result = SD_ERROR_BAD_RESPONSE;
437
                                goto end;
437
                                goto end;
438
                }*/
438
                }*/
439
                // check for card hw version                                            
439
                // check for card hw version                                            
440
                // 2.7-3.6V Range = 0x01, check pattern 0xAA
440
                // 2.7-3.6V Range = 0x01, check pattern 0xAA
441
                rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
441
                rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
442
                // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
442
                // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
443
                if(rsp[0] & R1_BAD_RESPONSE)
443
                if(rsp[0] & R1_BAD_RESPONSE)
444
                {
444
                {
445
                        sprintf(text,"Bad cmd8 R1=%02X.\r\n", rsp[0]);
445
                        sprintf(text,"Bad cmd8 R1=%02X.\r\n", rsp[0]);
446
                        SerialPutString(text);
446
                        SerialPutString(text);
447
                        result = SD_ERROR_BAD_RESPONSE;
447
                        result = SD_ERROR_BAD_RESPONSE;
448
                        goto end;
448
                        goto end;
449
                }
449
                }
450
                if(rsp[0] & R1_ILLEGAL_CMD)
450
                if(rsp[0] & R1_ILLEGAL_CMD)
451
                {
451
                {
452
                        //Ver1.X SD Memory Card or not a SD Memory Card
452
                        //Ver1.X SD Memory Card or not a SD Memory Card
453
                        SDCardInfo.Version = VER_1X;                   
453
                        SDCardInfo.Version = VER_1X;                   
454
                }
454
                }
455
                else
455
                else
456
                {
456
                {
457
                   // Ver2.00 or later SD Memory Card
457
                   // Ver2.00 or later SD Memory Card
458
                   // reading the remaining bytes of the R7 response
458
                   // reading the remaining bytes of the R7 response
459
                   SDCardInfo.Version = VER_20;
459
                   SDCardInfo.Version = VER_20;
460
                   for(Timeout = 1; Timeout < 5; Timeout++)
460
                   for(Timeout = 1; Timeout < 5; Timeout++)
461
                   {
461
                   {
462
                                rsp[Timeout] = SSC_GetChar();
462
                                rsp[Timeout] = SSC_GetChar();
463
                   }
463
                   }
464
                   //check pattern
464
                   //check pattern
465
                   if(rsp[4]!= 0xAA)
465
                   if(rsp[4]!= 0xAA)
466
                   {
466
                   {
467
                                SerialPutString("Bad cmd8 R7 check pattern.\r\n");
467
                                SerialPutString("Bad cmd8 R7 check pattern.\r\n");
468
                                result = SD_ERROR_BAD_RESPONSE;
468
                                result = SD_ERROR_BAD_RESPONSE;
469
                                goto end;
469
                                goto end;
470
                   }
470
                   }
471
                   if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
471
                   if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
472
                   {
472
                   {
473
                               
473
                               
474
                                SerialPutString("Card is incompatible to 3.3V.\r\n");
474
                                SerialPutString("Card is incompatible to 3.3V.\r\n");
475
                                result = SD_ERROR_BAD_VOLTAGE_RANGE;
475
                                result = SD_ERROR_BAD_VOLTAGE_RANGE;
476
                                goto end;              
476
                                goto end;              
477
                   }
477
                   }
478
                }
478
                }
479
       
479
       
480
                rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
480
                rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
481
                // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
481
                // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
482
                if(rsp[0] & R1_BAD_RESPONSE)
482
                if(rsp[0] & R1_BAD_RESPONSE)
483
                {
483
                {
484
                        sprintf(text,"Bad cmd58 R1 %02x.\r\n", rsp[0]);
484
                        sprintf(text,"Bad cmd58 R1 %02x.\r\n", rsp[0]);
485
                        SerialPutString(text);
485
                        SerialPutString(text);
486
                        result = SD_ERROR_BAD_RESPONSE;
486
                        result = SD_ERROR_BAD_RESPONSE;
487
                        goto end;
487
                        goto end;
488
                }
488
                }
489
                if(rsp[0] & R1_ILLEGAL_CMD)
489
                if(rsp[0] & R1_ILLEGAL_CMD)
490
                {
490
                {
491
                        SerialPutString("Not an SD-CARD.\r\n");
491
                        SerialPutString("Not an SD-CARD.\r\n");
492
                        result = SD_ERROR_NO_SDCARD;
492
                        result = SD_ERROR_NO_SDCARD;
493
                        goto end;
493
                        goto end;
494
                }
494
                }
495
                // read 4 bytes of OCR register
495
                // read 4 bytes of OCR register
496
                for(Timeout = 1; Timeout < 5; Timeout++)
496
                for(Timeout = 1; Timeout < 5; Timeout++)
497
                {
497
                {
498
                        rsp[Timeout] = SSC_GetChar();
498
                        rsp[Timeout] = SSC_GetChar();
499
                }
499
                }
500
                //      NavicCtrl uses 3.3 V,  therefore check for bit 20 & 21 
500
                //      NavicCtrl uses 3.3 V,  therefore check for bit 20 & 21 
501
                if((rsp[2] & 0x30) != 0x30)
501
                if((rsp[2] & 0x30) != 0x30)
502
                {
502
                {
503
                        // supply voltage is not supported by sd-card
503
                        // supply voltage is not supported by sd-card
504
                        SerialPutString("Card is incompatible to 3.3V.\r\n");
504
                        SerialPutString("Card is incompatible to 3.3V.\r\n");
505
                        result = SD_ERROR_BAD_VOLTAGE_RANGE;
505
                        result = SD_ERROR_BAD_VOLTAGE_RANGE;
506
                        goto end;
506
                        goto end;
507
                }
507
                }
508
               
508
               
509
                // Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
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) 
510
                Timeout =  SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer) 
511
                do
511
                do
512
                {
512
                {
513
                        rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
513
                        rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
514
                        if(rsp[0] & R1_BAD_RESPONSE)
514
                        if(rsp[0] & R1_BAD_RESPONSE)
515
                        {
515
                        {
516
                                sprintf(text,"Bad Acmd41 R1=%02X.\r\n", rsp[0]);
516
                                sprintf(text,"Bad Acmd41 R1=%02X.\r\n", rsp[0]);
517
                                SerialPutString(text);
517
                                SerialPutString(text);
518
                                result = SD_ERROR_BAD_RESPONSE;
518
                                result = SD_ERROR_BAD_RESPONSE;
519
                                goto end;
519
                                goto end;
520
                        }
520
                        }
521
                        if(CheckDelay(Timeout))
521
                        if(CheckDelay(Timeout))
522
                        {
522
                        {
523
                            SerialPutString("Init timeout.\r\n");
523
                            SerialPutString("Init timeout.\r\n");
524
                                result = SD_ERROR_INITIALIZE;
524
                                result = SD_ERROR_INITIALIZE;
525
                                goto end;
525
                                goto end;
526
                        }
526
                        }
527
                } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
527
                } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
528
               
528
               
529
                if(rsp[0] != R1_NO_ERR)
529
                if(rsp[0] != R1_NO_ERR)
530
                {
530
                {
531
                        SerialPutString("Init error.\r\n");
531
                        SerialPutString("Init error.\r\n");
532
                        result = SD_ERROR_INITIALIZE;
532
                        result = SD_ERROR_INITIALIZE;
533
                        goto end;      
533
                        goto end;      
534
                }
534
                }
535
                /* set block size to 512 bytes */
535
                /* set block size to 512 bytes */
536
        if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
536
        if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
537
        {
537
        {
538
                SerialPutString("Error setting block length to 512.\r\n");
538
                SerialPutString("Error setting block length to 512.\r\n");
539
                        result = SD_ERROR_SET_BLOCKLEN;
539
                        result = SD_ERROR_SET_BLOCKLEN;
540
                        goto end;
540
                        goto end;
541
        }
541
        }
542
 
542
 
543
 
543
 
544
                //SSC_Disable(); // set SD_CS high                                               
544
                //SSC_Disable(); // set SD_CS high                                               
545
                // here is the right place to inrease the SPI boud rate to maximum              
545
                // here is the right place to inrease the SPI boud rate to maximum              
546
                //SSC_Enable(); // set SD_CS high
546
                //SSC_Enable(); // set SD_CS high
547
 
547
 
548
                // read CID register
548
                // read CID register
549
                result = SDC_GetCID((u8 *)&SDCardInfo.CID);
549
                result = SDC_GetCID((u8 *)&SDCardInfo.CID);
550
                if(result != SD_SUCCESS)
550
                if(result != SD_SUCCESS)
551
                {
551
                {
552
                        SerialPutString("Error reading CID.\r\n");
552
                        SerialPutString("Error reading CID.\r\n");
553
                        goto end;
553
                        goto end;
554
                }
554
                }
555
       
555
       
556
                // read CSD register
556
                // read CSD register
557
                result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
557
                result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
558
                if(result != SD_SUCCESS)
558
                if(result != SD_SUCCESS)
559
                {
559
                {
560
                        SerialPutString("Error reading CSD.\r\n");
560
                        SerialPutString("Error reading CSD.\r\n");
561
                        goto end;
561
                        goto end;
562
                }
562
                }
563
       
563
       
564
                SerialPutString("ok\r\n");
564
                SerialPutString("ok\r\n");
565
       
565
       
566
                u8 c_size_mult, read_bl_len;
566
                u8 c_size_mult, read_bl_len;
567
                u32 c_size;
567
                u32 c_size;
568
       
568
       
569
                switch(SDCardInfo.CSD[0]>>6) // check CSD Version
569
                switch(SDCardInfo.CSD[0]>>6) // check CSD Version
570
                {
570
                {
571
                case 0x00: // if CSD is V1.0 structure (2GB limit)
571
                case 0x00: // if CSD is V1.0 structure (2GB limit)
572
       
572
       
573
                        /*
573
                        /*
574
                        memory capacity = BLOCKNR * BLOCK_LEN
574
                        memory capacity = BLOCKNR * BLOCK_LEN
575
                        BLOCKNR = (C_SIZE+1) * MULT
575
                        BLOCKNR = (C_SIZE+1) * MULT
576
                        MULT = 2^(C_SIZE_MULT+2)
576
                        MULT = 2^(C_SIZE_MULT+2)
577
                        BLOCK_LEN = 2^READ_BL_LEN
577
                        BLOCK_LEN = 2^READ_BL_LEN
578
               
578
               
579
                        C_SIZE      is 12 bits [73:62] in CSD register
579
                        C_SIZE      is 12 bits [73:62] in CSD register
580
                        C_SIZE_MULT is  3 bits [49:47] 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
581
                        READ_BL_LEN is  4 bits [83:80] in CSD register
582
                        */
582
                        */
583
       
583
       
584
                        read_bl_len = (SDCardInfo.CSD[5] & 0x0F);               //CSD[05] -> [87:80]
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]
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]
586
                        c_size |= ((u32)SDCardInfo.CSD[7])<<2;                  //CSD[07] -> [71:64]
587
                        c_size |= (u32)(SDCardInfo.CSD[8]>>6);                  //CSD[08] -> [63:56]
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]
588
                        c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1;    //CSD[09] -> [55:48]
589
                        c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7;   //CSD[10] -> [47:40]
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);
590
                        SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
591
                        break;
591
                        break;
592
       
592
       
593
                case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB) 
593
                case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB) 
594
       
594
       
595
                        /*
595
                        /*
596
                        memory capacity = (C_SIZE+1) * 512K byte
596
                        memory capacity = (C_SIZE+1) * 512K byte
597
                        C_SIZE is 22 bits [69:48] in CSR register
597
                        C_SIZE is 22 bits [69:48] in CSR register
598
                        */
598
                        */
599
       
599
       
600
                        c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16; //CSD[07] -> [71:64]
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]
601
                        c_size |= ((u32)SDCardInfo.CSD[8])<<8;                  //CSD[08] -> [63:56]
602
                        c_size |= (u32)SDCardInfo.CSD[9];                               //CSD[09] -> [55:48];
602
                        c_size |= (u32)SDCardInfo.CSD[9];                               //CSD[09] -> [55:48];
603
                        SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
603
                        SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
604
                        break;
604
                        break; 
605
       
-
 
606
                default: //unknown CSD Version
605
                 default: //unknown CSD Version
607
                        SDCardInfo.Capacity = 0;
606
                        SDCardInfo.Capacity = 0;
608
                        break; 
607
                        break; 
609
                }
608
                }
610
       
609
       
611
                switch(SDCardInfo.Version)
610
                switch(SDCardInfo.Version)
612
                {
611
                {
613
                        case VER_1X:
612
                        case VER_1X:
614
                                SerialPutString("  SD-CARD V1.x");
613
                                SerialPutString("  SD-CARD V1.x");
615
                                break;
614
                                break;
616
                        case VER_20:
615
                        case VER_20:
617
                                SerialPutString("  SD-CARD V2.0 or later");
616
                                SerialPutString("  SD-CARD V2.0 or later");
618
                        default:
617
                        default:
619
                                break;
618
                                break;
620
                }
619
                }
621
                u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
620
                u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
622
                sprintf(text, "\r\n  Capacity = %i MB", mb_size);
621
                sprintf(text, "\r\n  Capacity = %i MB", mb_size);
623
                SerialPutString(text);
622
                SerialPutString(text);
624
       
623
       
625
//              SDC_PrintCID((u8 *)&SDCardInfo.CID);
624
//              SDC_PrintCID((u8 *)&SDCardInfo.CID);
626
                SDCardInfo.Valid = 1;
625
                SDCardInfo.Valid = 1;
627
                       
626
                       
628
                // jump point for error condition before
627
                // jump point for error condition before
629
                end:
628
                end:
630
                SSC_Disable();
629
                SSC_Disable();
631
        }
630
        }
632
        else
631
        else
633
        {
632
        {
634
                //SerialPutString("\r\nNo Card in Slot.");
633
                //SerialPutString("\r\nNo Card in Slot.");
635
                SSC_Deinit();
634
                SSC_Deinit();
636
                SDCardInfo.Valid = 0;
635
                SDCardInfo.Valid = 0;
637
                result = SD_ERROR_NOCARD;
636
                result = SD_ERROR_NOCARD;
638
        }
637
        }
639
        if(result != SD_SUCCESS)                SerialPutString("nok");
638
//      if(result != SD_SUCCESS)                SerialPutString("nok ");
640
 
639
 
641
        return(result);
640
        return(result);
642
}
641
}
643
 
642
 
644
 
643
 
645
//________________________________________________________________________________________________________________________________________
644
//________________________________________________________________________________________________________________________________________
646
// Funtion:     SDC_Deinit(void);
645
// Funtion:     SDC_Deinit(void);
647
// 
646
// 
648
// Description: This function deinitialises the SDCard interface. 
647
// Description: This function deinitialises the SDCard interface. 
649
//                              
648
//                              
650
//
649
//
651
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
650
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
652
//________________________________________________________________________________________________________________________________________
651
//________________________________________________________________________________________________________________________________________
653
 
652
 
654
SD_Result_t SDC_Deinit(void)
653
SD_Result_t SDC_Deinit(void)
655
{
654
{
656
        SerialPutString("SDC deinit...");
655
        SerialPutString("SDC deinit...");
657
        SSC_Deinit();
656
        SSC_Deinit();
658
 
657
 
659
        SDCardInfo.Valid = 0;
658
        SDCardInfo.Valid = 0;
660
        SDCardInfo.Capacity = 0;
659
        SDCardInfo.Capacity = 0;
661
        SDCardInfo.Version = VER_UNKNOWN;
660
        SDCardInfo.Version = VER_UNKNOWN;
662
 
661
 
663
        SerialPutString("ok\r\n");
662
        SerialPutString("ok\r\n");
664
        return(SD_SUCCESS);
663
        return(SD_SUCCESS);
665
}
664
}
666
 
665
 
667
 
666
 
668
//________________________________________________________________________________________________________________________________________
667
//________________________________________________________________________________________________________________________________________
669
// Funtion:     SDC_PutSector(void);
668
// Funtion:     SDC_PutSector(void);
670
// 
669
// 
671
// Description: This function writes one sector of data to the SSC 
670
// Description: This function writes one sector of data to the SSC 
672
//                              
671
//                              
673
//
672
//
674
// Returnvalue: SD_Result_t
673
// Returnvalue: SD_Result_t
675
//________________________________________________________________________________________________________________________________________
674
//________________________________________________________________________________________________________________________________________
676
 
675
 
677
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
676
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
678
{
677
{
679
        u8 rsp;
678
        u8 rsp;
680
        u16 timeout = 0;
679
        u16 timeout = 0;
681
        u16 a, Crc16;
680
        u16 a, Crc16;
682
        //u32 Timeout = 0;
681
        //u32 Timeout = 0;
683
        SD_Result_t result = SD_ERROR_UNKNOWN;
682
        SD_Result_t result = SD_ERROR_UNKNOWN;
684
 
683
 
685
        addr = addr << 9; // convert sectoradress to byteadress
684
        addr = addr << 9; // convert sectoradress to byteadress
686
        rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
685
        rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
687
        if (rsp != R1_NO_ERR)
686
        if (rsp != R1_NO_ERR)
688
        {
687
        {
689
                result = SD_ERROR_BAD_RESPONSE;
688
                result = SD_ERROR_BAD_RESPONSE;
690
                goto end;
689
                goto end;
691
        }
690
        }
692
        SSC_ClearRxFifo();             
691
        SSC_ClearRxFifo();             
693
        for (a=0;a<20;a++)                                      // at least one byte
692
        for (a=0;a<20;a++)                                      // at least one byte
694
        {
693
        {
695
                SSC_GetChar();
694
                SSC_GetChar();
696
        }
695
        }
697
        Crc16 = CRC16(Buffer, 512);         // calc checksum for data block
696
        Crc16 = CRC16(Buffer, 512);         // calc checksum for data block
698
        SSC_PutChar(DATA_START_TOKEN);          // send data start of header to the SSC 
697
        SSC_PutChar(DATA_START_TOKEN);          // send data start of header to the SSC 
699
       
698
       
700
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
699
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
701
        {
700
        {
702
                SSC_PutChar(Buffer[a]);
701
                SSC_PutChar(Buffer[a]);
703
        }
702
        }
704
        // write two bytes of crc16 to the sdcard
703
        // write two bytes of crc16 to the sdcard
705
        SSC_PutChar((u8)(Crc16>>8));            // write high byte first
704
        SSC_PutChar((u8)(Crc16>>8));            // write high byte first
706
        SSC_PutChar((u8)(0x00FF&Crc16));        // lowbyte last
705
        SSC_PutChar((u8)(0x00FF&Crc16));        // lowbyte last
707
        SSC_ClearRxFifo();
706
        SSC_ClearRxFifo();
708
        do                                                                      // wait for data response token
707
        do                                                                      // wait for data response token
709
        {
708
        {
710
                rsp = SSC_GetChar();
709
                rsp = SSC_GetChar();
711
                if(timeout++>500) break;
710
                if(timeout++>500) break;
712
        }while((rsp & 0x11) != 0x01 );
711
        }while((rsp & 0x11) != 0x01 );
713
        // analyse data response token
712
        // analyse data response token
714
        switch(rsp & DATA_RESPONSE_MASK)
713
        switch(rsp & DATA_RESPONSE_MASK)
715
        {
714
        {
716
                case DATA_RESPONSE_OK:
715
                case DATA_RESPONSE_OK:
717
                        result = SD_SUCCESS;
716
                        result = SD_SUCCESS;
718
                        break;
717
                        break;
719
                case DATA_RESPONSE_CRC_ERR:
718
                case DATA_RESPONSE_CRC_ERR:
720
                        result = SD_ERROR_CRC_DATA;
719
                        result = SD_ERROR_CRC_DATA;
721
                        goto end;
720
                        goto end;
722
                        break;
721
                        break;
723
                case DATA_RESPONSE_WRITE_ERR:
722
                case DATA_RESPONSE_WRITE_ERR:
724
                        result = SD_ERROR_WRITE_DATA;
723
                        result = SD_ERROR_WRITE_DATA;
725
                        goto end;
724
                        goto end;
726
                        break;
725
                        break;
727
                default:
726
                default:
728
                        result = SD_ERROR_UNKNOWN;
727
                        result = SD_ERROR_UNKNOWN;
729
                        goto end;
728
                        goto end;
730
                        break;
729
                        break;
731
 
730
 
732
        }
731
        }
733
        // wait until the sdcard is busy.
732
        // wait until the sdcard is busy.
734
        rsp = SDC_WaitForBusy();
733
        rsp = SDC_WaitForBusy();
735
        if(rsp != 0xFF)
734
        if(rsp != 0xFF)
736
        {
735
        {
737
                result =  SD_ERROR_TIMEOUT;
736
                result =  SD_ERROR_TIMEOUT;
738
                goto end;
737
                goto end;
739
        }
738
        }
740
        // check card status
739
        // check card status
741
        rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
740
        rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
742
        if(rsp != R1_NO_ERR)
741
        if(rsp != R1_NO_ERR)
743
        {
742
        {
744
                result =  SD_ERROR_BAD_RESPONSE;
743
                result =  SD_ERROR_BAD_RESPONSE;
745
                SSC_GetChar();
744
                SSC_GetChar();
746
                goto end;
745
                goto end;
747
        }
746
        }
748
        // 2nd byte of r2 response
747
        // 2nd byte of r2 response
749
        rsp = SSC_GetChar();
748
        rsp = SSC_GetChar();
750
        if(rsp != R2_NO_ERR)
749
        if(rsp != R2_NO_ERR)
751
        {
750
        {
752
                result =  SD_ERROR_WRITE_DATA;
751
                result =  SD_ERROR_WRITE_DATA;
753
                SSC_GetChar();
752
                SSC_GetChar();
754
                goto end;
753
                goto end;
755
        }
754
        }
756
        end:
755
        end:
757
        //SSC_Disable();                                                // disable sdcard.
756
        //SSC_Disable();                                                // disable sdcard.
758
        if(result != SD_SUCCESS)
757
        if(result != SD_SUCCESS)
759
        {
758
        {
760
                sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
759
                sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
761
                SerialPutString(text);
760
                SerialPutString(text);
762
        }
761
        }
763
        return(result);
762
        return(result);
764
}
763
}
765
 
764
 
766
 
765
 
767
//________________________________________________________________________________________________________________________________________
766
//________________________________________________________________________________________________________________________________________
768
// Funtion:     SDC_GetSector(u32 addr,u8 *Buffer);
767
// Funtion:     SDC_GetSector(u32 addr,u8 *Buffer);
769
// 
768
// 
770
// Description: This function reads one sector of data from the SSC
769
// Description: This function reads one sector of data from the SSC
771
//                              
770
//                              
772
//
771
//
773
// Returnvalue: SD_Result_t
772
// Returnvalue: SD_Result_t
774
//________________________________________________________________________________________________________________________________________
773
//________________________________________________________________________________________________________________________________________
775
 
774
 
776
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
775
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
777
{
776
{
778
        addr = addr << 9; // convert sectoradress to byteadress
777
        addr = addr << 9; // convert sectoradress to byteadress
779
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
778
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
780
}
779
}
781
 
780
 
782
 
781
 
783
 
782
 
784
 
783