Subversion Repositories NaviCtrl

Rev

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

Rev 109 Rev 171
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 / NON-COMMERCIAL USE ONLY
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 oder Nutzung 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 the sources to other systems or using the software on other systems (except 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 "uart1.h"
60
#include "uart1.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(u32 timeout)
184
u8 SDC_WaitForBusy(u32 timeout)
185
{
185
{
186
        u8 rsp = 0;
186
        u8 rsp = 0;
187
        u32 timestamp = 0;
187
        u32 timestamp = 0;
188
 
188
 
189
        SSC_ClearRxFifo();
189
        SSC_ClearRxFifo();
190
        SSC_Enable();                           // enable chipselect.
190
        SSC_Enable();                           // enable chipselect.
191
        timestamp = SetDelay(timeout);
191
        timestamp = SetDelay(timeout);
192
        do     
192
        do     
193
        {
193
        {
194
                rsp = SSC_GetChar();
194
                rsp = SSC_GetChar();
195
                if(CheckDelay(timestamp)) break;
195
                if(CheckDelay(timestamp)) break;
196
        }while(rsp != 0xFF);            // wait while card is busy (data out low)
196
        }while(rsp != 0xFF);            // wait while card is busy (data out low)
197
        return(rsp);
197
        return(rsp);
198
}
198
}
199
 
199
 
200
 
200
 
201
 
201
 
202
//________________________________________________________________________________________________________________________________________
202
//________________________________________________________________________________________________________________________________________
203
// Function:    SDC_SendCMDR1(u8 CmdNo, u32 arg);
203
// Function:    SDC_SendCMDR1(u8 CmdNo, u32 arg);
204
// 
204
// 
205
// Description: This function send a command frame to the SD-Card in spi-mode. 
205
// Description: This function send a command frame to the SD-Card in spi-mode. 
206
//                              
206
//                              
207
//
207
//
208
// Returnvalue: The function returns the first response byte like for R1 commands
208
// Returnvalue: The function returns the first response byte like for R1 commands
209
//________________________________________________________________________________________________________________________________________
209
//________________________________________________________________________________________________________________________________________
210
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
210
u8 SDC_SendCMDR1(u8 CmdNo, u32 arg)
211
{
211
{
212
        u8 r1;
212
        u8 r1;
213
        u16 timeout = 0;
213
        u16 timeout = 0;
214
        u16 a;
214
        u16 a;
215
        u8 cmd[6];
215
        u8 cmd[6];
216
 
216
 
217
        SSC_ClearRxFifo();      // clear the rx fifo
217
        SSC_ClearRxFifo();      // clear the rx fifo
218
        SSC_Enable();           // enable chipselect.
218
        SSC_Enable();           // enable chipselect.
219
        SDC_WaitForBusy(500);   // wait 500ms until card is busy
219
        SDC_WaitForBusy(500);   // wait 500ms until card is busy
220
        SSC_ClearRxFifo();      // clear the rx fifo
220
        SSC_ClearRxFifo();      // clear the rx fifo
221
        SSC_GetChar();      // dummy to sync
221
        SSC_GetChar();      // dummy to sync
222
 
222
 
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
 
234
 
235
        do                                     
235
        do                                     
236
        {
236
        {
237
                r1 = SSC_GetChar();       // get byte from sd-card
237
                r1 = SSC_GetChar();       // get byte from sd-card
238
                if (timeout++ >500) break;
238
                if (timeout++ >500) break;
239
        }while(r1 == 0xFF); // wait for the response byte from sd-card.
239
        }while(r1 == 0xFF); // wait for the response byte from sd-card.
240
        return(r1);
240
        return(r1);
241
}
241
}
242
 
242
 
243
 
243
 
244
//________________________________________________________________________________________________________________________________________
244
//________________________________________________________________________________________________________________________________________
245
// Function:    SDC_SendACMDR1(u8 CmdNo, u32 arg);
245
// Function:    SDC_SendACMDR1(u8 CmdNo, u32 arg);
246
//                                         
246
//                                         
247
// Description: This function send a application command frame to the SD-Card in spi-mode. 
247
// Description: This function send a application command frame to the SD-Card in spi-mode. 
248
//                              
248
//                              
249
//
249
//
250
// Returnvalue: The function returns the first response byte like for R1 commands
250
// Returnvalue: The function returns the first response byte like for R1 commands
251
//________________________________________________________________________________________________________________________________________
251
//________________________________________________________________________________________________________________________________________
252
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
252
u8 SDC_SendACMDR1(u8 CmdNo, u32 arg)
253
{
253
{
254
        u8 r1 = 0xFF;
254
        u8 r1 = 0xFF;
255
        r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
255
        r1 = SDC_SendCMDR1(CMD_APP_CMD, 0UL);
256
        if(r1 & R1_BAD_RESPONSE) return(r1);
256
        if(r1 & R1_BAD_RESPONSE) return(r1);
257
        r1 = SDC_SendCMDR1(CmdNo, arg);
257
        r1 = SDC_SendCMDR1(CmdNo, arg);
258
        return(r1);
258
        return(r1);
259
}
259
}
260
 
260
 
261
 
261
 
262
//________________________________________________________________________________________________________________________________________
262
//________________________________________________________________________________________________________________________________________
263
// Function:    SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
263
// Function:    SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
264
// 
264
// 
265
// Description: This function sneds cmd an reads a datablock of len from the sd-card
265
// Description: This function sneds cmd an reads a datablock of len from the sd-card
266
//                              
266
//                              
267
//
267
//
268
// Returnvalue: SD_Result_t
268
// Returnvalue: SD_Result_t
269
//________________________________________________________________________________________________________________________________________
269
//________________________________________________________________________________________________________________________________________
270
 
270
 
271
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
271
SD_Result_t SDC_GetData(u8 CmdNo, u32 addr, u8 *Buffer, u32 len)
272
{
272
{
273
        u8 rsp;        
273
        u8 rsp;        
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
        }while(rsp != DATA_START_TOKEN);
293
        }while(rsp != DATA_START_TOKEN);
294
        // data start token received
294
        // data start token received
295
        for (a = 0; a < len; a++)       // read the block from the SSC
295
        for (a = 0; a < len; a++)       // read the block from the SSC
296
        {
296
        {
297
                Buffer[a] = SSC_GetChar();
297
                Buffer[a] = SSC_GetChar();
298
        }
298
        }
299
        // Read two bytes CRC16-Data checksum
299
        // Read two bytes CRC16-Data checksum
300
        crc16 = SSC_GetChar(); // highbyte fisrt        
300
        crc16 = SSC_GetChar(); // highbyte fisrt        
301
        crc16 = (crc16<<8)|SSC_GetChar(); // lowbyte last
301
        crc16 = (crc16<<8)|SSC_GetChar(); // lowbyte last
302
/*      if(crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
302
/*      if(crc16 != CRC16(Buffer, len)) result = SD_ERROR_CRC_DATA;
303
        else */result = SD_SUCCESS;
303
        else */result = SD_SUCCESS;
304
       
304
       
305
        end:
305
        end:
306
        if(result != SD_SUCCESS)
306
        if(result != SD_SUCCESS)
307
        {
307
        {
308
                sprintf(text,"Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
308
                sprintf(text,"Error %02X reading data from sd card (R1=%02X).\r\n", result, rsp);
309
                SerialPutString(text);
309
                SerialPutString(text);
310
        }
310
        }
311
        return(result);
311
        return(result);
312
}
312
}
313
 
313
 
314
 
314
 
315
//________________________________________________________________________________________________________________________________________
315
//________________________________________________________________________________________________________________________________________
316
// Function:    SDC_PrintCID(u8 * pCID);
316
// Function:    SDC_PrintCID(u8 * pCID);
317
// 
317
// 
318
// Description: This function prints the CIS register in a human readable format. 
318
// Description: This function prints the CIS register in a human readable format. 
319
//                              
319
//                              
320
//
320
//
321
// Returnvalue: the function returns nothing
321
// Returnvalue: the function returns nothing
322
//________________________________________________________________________________________________________________________________________
322
//________________________________________________________________________________________________________________________________________
323
 
323
 
324
void SDC_PrintCID(u8 * pCID)
324
void SDC_PrintCID(u8 * pCID)
325
{
325
{
326
        u8 pn[6];
326
        u8 pn[6];
327
        u16 temp1, temp2;
327
        u16 temp1, temp2;
328
 
328
 
329
        sprintf(text, "\r\n Manufacturer ID: %i\r\n", pCID[0]);
329
        sprintf(text, "\r\n Manufacturer ID: %i\r\n", pCID[0]);
330
        SerialPutString(text);
330
        SerialPutString(text);
331
        memcpy(pn, &pCID[1], 2);
331
        memcpy(pn, &pCID[1], 2);
332
        pn[2] = '\0'; // terminate string
332
        pn[2] = '\0'; // terminate string
333
        sprintf(text, " Application ID: %s\r\n",pn);
333
        sprintf(text, " Application ID: %s\r\n",pn);
334
        SerialPutString(text);
334
        SerialPutString(text);
335
        memcpy(pn, &pCID[3], 5);
335
        memcpy(pn, &pCID[3], 5);
336
        pn[5] = '\0'; // terminate string
336
        pn[5] = '\0'; // terminate string
337
        sprintf(text, " Product Name: %s\r\n",pn);
337
        sprintf(text, " Product Name: %s\r\n",pn);
338
        SerialPutString(text);
338
        SerialPutString(text);
339
        sprintf(text, " Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
339
        sprintf(text, " Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
340
        SerialPutString(text);
340
        SerialPutString(text);
341
        SerialPutString(" Serial No.: ");
341
        SerialPutString(" Serial No.: ");
342
        for(temp1 = 0; temp1<4; temp1++)
342
        for(temp1 = 0; temp1<4; temp1++)
343
        {
343
        {
344
                sprintf(text,"%02X", pCID[9+temp1]);
344
                sprintf(text,"%02X", pCID[9+temp1]);
345
                SerialPutString(text);
345
                SerialPutString(text);
346
        }
346
        }
347
        SerialPutString("\r\n");
347
        SerialPutString("\r\n");
348
        temp1 = pCID[14] & 0x0F;    // month 
348
        temp1 = pCID[14] & 0x0F;    // month 
349
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year 
349
        temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year 
350
        sprintf(text, " Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
350
        sprintf(text, " Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
351
        SerialPutString(text);
351
        SerialPutString(text);
352
}
352
}
353
 
353
 
354
//________________________________________________________________________________________________________________________________________
354
//________________________________________________________________________________________________________________________________________
355
// Funtion:     SDC_GetCID(u8 * pCID);
355
// Funtion:     SDC_GetCID(u8 * pCID);
356
// 
356
// 
357
// Description: This function reads the CIS register form the sd card in spi mode. 
357
// Description: This function reads the CIS register form the sd card in spi mode. 
358
//                              
358
//                              
359
//
359
//
360
// Returnvalue: the function returns error state
360
// Returnvalue: the function returns error state
361
//________________________________________________________________________________________________________________________________________
361
//________________________________________________________________________________________________________________________________________
362
 
362
 
363
SD_Result_t SDC_GetCID(u8 * pCID)
363
SD_Result_t SDC_GetCID(u8 * pCID)
364
{
364
{
365
        return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
365
        return SDC_GetData(CMD_SEND_CID, 0UL, pCID, 16);
366
}
366
}
367
 
367
 
368
//________________________________________________________________________________________________________________________________________
368
//________________________________________________________________________________________________________________________________________
369
// Funtion:     SDC_GetCSD(u8 * pCSD);
369
// Funtion:     SDC_GetCSD(u8 * pCSD);
370
// 
370
// 
371
// Description: This function reads the CSD register form the sd card in spi mode. 
371
// Description: This function reads the CSD register form the sd card in spi mode. 
372
//                              
372
//                              
373
//
373
//
374
// Returnvalue: the function returns error state
374
// Returnvalue: the function returns error state
375
//________________________________________________________________________________________________________________________________________
375
//________________________________________________________________________________________________________________________________________
376
 
376
 
377
SD_Result_t SDC_GetCSD(u8 * pCSD)
377
SD_Result_t SDC_GetCSD(u8 * pCSD)
378
{
378
{
379
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
379
        return SDC_GetData(CMD_SEND_CSD, 0UL, pCSD, 16);
380
}
380
}
381
 
381
 
382
 
382
 
383
//________________________________________________________________________________________________________________________________________
383
//________________________________________________________________________________________________________________________________________
384
// Funtion:     SDC_Init(void);
384
// Funtion:     SDC_Init(void);
385
// 
385
// 
386
// Description: This function initialises the SDCard to spi-mode. 
386
// Description: This function initialises the SDCard to spi-mode. 
387
//                              
387
//                              
388
//
388
//
389
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
389
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
390
//________________________________________________________________________________________________________________________________________
390
//________________________________________________________________________________________________________________________________________
391
 
391
 
392
SD_Result_t SDC_Init(void)
392
SD_Result_t SDC_Init(void)
393
{
393
{
394
        u32 timeout = 0;
394
        u32 timeout = 0;
395
        u8 rsp[6]; // SD-SPI response buffer
395
        u8 rsp[6]; // SD-SPI response buffer
396
        SD_Result_t result = SD_ERROR_UNKNOWN;
396
        SD_Result_t result = SD_ERROR_UNKNOWN;
397
               
397
               
398
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
398
        if(SD_SWITCH) // init only if the SD-Switch is indicating a card in the slot
399
        {
399
        {
400
                SerialPutString("\r\n SSC init...");
400
                SerialPutString("\r\n SSC init...");
401
                SSC_Init();
401
                SSC_Init();
402
                SerialPutString("ok");
402
                SerialPutString("ok");
403
 
403
 
404
                SerialPutString("\r\n SDC init...");
404
                SerialPutString("\r\n SDC init...");
405
                SDCardInfo.Valid = 0;
405
                SDCardInfo.Valid = 0;
406
                /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
406
                /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
407
                start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
407
                start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
408
                mode, CS shall be held to high during 74 clock cycles. */
408
                mode, CS shall be held to high during 74 clock cycles. */
409
                SSC_Disable(); // set SD_CS high
409
                SSC_Disable(); // set SD_CS high
410
                SSC_ClearRxFifo();      // clear the rx fifo
410
                SSC_ClearRxFifo();      // clear the rx fifo
411
       
411
       
412
                for (timeout = 0; timeout < 15; timeout++)      // 15*8 = 120 cycles
412
                for (timeout = 0; timeout < 15; timeout++)      // 15*8 = 120 cycles
413
                {
413
                {
414
                        SSC_PutChar(0xFF);
414
                        SSC_PutChar(0xFF);
415
                }
415
                }
416
       
416
       
417
                // switch to idle state
417
                // switch to idle state
418
                while(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) != R1_IDLE_STATE)                                          
418
                while(SDC_SendCMDR1(CMD_GO_IDLE_STATE, 0UL) != R1_IDLE_STATE)                                          
419
                {
419
                {
420
                        if (timeout++ > 20)
420
                        if (timeout++ > 20)
421
                        {
421
                        {
422
                                SerialPutString("reset timeout");
422
                                SerialPutString("reset timeout");
423
                                result = SD_ERROR_RESET;
423
                                result = SD_ERROR_RESET;
424
                                goto end;                                                                              
424
                                goto end;                                                                              
425
                        }
425
                        }
426
                }
426
                }
427
            // enable crc feature
427
            // enable crc feature
428
/*              if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
428
/*              if(SDC_SendCMDR1(CMD_CRC_ON_OFF, 1UL) != R1_IDLE_STATE)
429
                {
429
                {
430
                                sprintf(text,"Bad cmd59 R1=%02X.", rsp[0]);
430
                                sprintf(text,"Bad cmd59 R1=%02X.", rsp[0]);
431
                                SerialPutString(text);
431
                                SerialPutString(text);
432
                                result = SD_ERROR_BAD_RESPONSE;
432
                                result = SD_ERROR_BAD_RESPONSE;
433
                                goto end;
433
                                goto end;
434
                }*/
434
                }*/
435
                // check for card hw version                                            
435
                // check for card hw version                                            
436
                // 2.7-3.6V Range = 0x01, check pattern 0xAA
436
                // 2.7-3.6V Range = 0x01, check pattern 0xAA
437
                rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
437
                rsp[0] = SDC_SendCMDR1(CMD_SEND_IF_COND, 0x000001AA);
438
                // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
438
                // answer to cmd58 is an R7 response (R1+ 4Byte IFCond)
439
                if(rsp[0] & R1_BAD_RESPONSE)
439
                if(rsp[0] & R1_BAD_RESPONSE)
440
                {
440
                {
441
                        sprintf(text,"Bad cmd8 R1=%02X.", rsp[0]);
441
                        sprintf(text,"Bad cmd8 R1=%02X.", rsp[0]);
442
                        SerialPutString(text);
442
                        SerialPutString(text);
443
                        result = SD_ERROR_BAD_RESPONSE;
443
                        result = SD_ERROR_BAD_RESPONSE;
444
                        goto end;
444
                        goto end;
445
                }
445
                }
446
                if(rsp[0] & R1_ILLEGAL_CMD)
446
                if(rsp[0] & R1_ILLEGAL_CMD)
447
                {
447
                {
448
                        //Ver1.X SD Memory Card or not a SD Memory Card
448
                        //Ver1.X SD Memory Card or not a SD Memory Card
449
                        SDCardInfo.Version = VER_1X;                   
449
                        SDCardInfo.Version = VER_1X;                   
450
                }
450
                }
451
                else
451
                else
452
                {
452
                {
453
                   // Ver2.00 or later SD Memory Card
453
                   // Ver2.00 or later SD Memory Card
454
                   // reading the remaining bytes of the R7 response
454
                   // reading the remaining bytes of the R7 response
455
                   SDCardInfo.Version = VER_20;
455
                   SDCardInfo.Version = VER_20;
456
                   for(timeout = 1; timeout < 5; timeout++)
456
                   for(timeout = 1; timeout < 5; timeout++)
457
                   {
457
                   {
458
                                rsp[timeout] = SSC_GetChar();
458
                                rsp[timeout] = SSC_GetChar();
459
                   }
459
                   }
460
                   //check pattern
460
                   //check pattern
461
                   if(rsp[4]!= 0xAA)
461
                   if(rsp[4]!= 0xAA)
462
                   {
462
                   {
463
                                SerialPutString("Bad cmd8 R7 check pattern.\r\n");
463
                                SerialPutString("Bad cmd8 R7 check pattern.\r\n");
464
                                result = SD_ERROR_BAD_RESPONSE;
464
                                result = SD_ERROR_BAD_RESPONSE;
465
                                goto end;
465
                                goto end;
466
                   }
466
                   }
467
                   if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
467
                   if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
468
                   {
468
                   {
469
                               
469
                               
470
                                SerialPutString("Card is incompatible to 3.3V.\r\n");
470
                                SerialPutString("Card is incompatible to 3.3V.\r\n");
471
                                result = SD_ERROR_BAD_VOLTAGE_RANGE;
471
                                result = SD_ERROR_BAD_VOLTAGE_RANGE;
472
                                goto end;              
472
                                goto end;              
473
                   }
473
                   }
474
                }
474
                }
475
       
475
       
476
                rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
476
                rsp[0] = SDC_SendCMDR1(CMD_READ_OCR, 0UL);
477
                // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
477
                // answer to cmd58 is an R3 response (R1 + 4Byte OCR)
478
                if(rsp[0] & R1_BAD_RESPONSE)
478
                if(rsp[0] & R1_BAD_RESPONSE)
479
                {
479
                {
480
                        sprintf(text,"Bad cmd58 R1 %02x.", rsp[0]);
480
                        sprintf(text,"Bad cmd58 R1 %02x.", rsp[0]);
481
                        SerialPutString(text);
481
                        SerialPutString(text);
482
                        result = SD_ERROR_BAD_RESPONSE;
482
                        result = SD_ERROR_BAD_RESPONSE;
483
                        goto end;
483
                        goto end;
484
                }
484
                }
485
                if(rsp[0] & R1_ILLEGAL_CMD)
485
                if(rsp[0] & R1_ILLEGAL_CMD)
486
                {
486
                {
487
                        SerialPutString("Not an SD-CARD.");
487
                        SerialPutString("Not an SD-CARD.");
488
                        result = SD_ERROR_NO_SDCARD;
488
                        result = SD_ERROR_NO_SDCARD;
489
                        goto end;
489
                        goto end;
490
                }
490
                }
491
                // read 4 bytes of OCR register
491
                // read 4 bytes of OCR register
492
                for(timeout = 1; timeout < 5; timeout++)
492
                for(timeout = 1; timeout < 5; timeout++)
493
                {
493
                {
494
                        rsp[timeout] = SSC_GetChar();
494
                        rsp[timeout] = SSC_GetChar();
495
                }
495
                }
496
                //      NavicCtrl uses 3.3 V,  therefore check for bit 20 & 21 
496
                //      NavicCtrl uses 3.3 V,  therefore check for bit 20 & 21 
497
                if((rsp[2] & 0x30) != 0x30)
497
                if((rsp[2] & 0x30) != 0x30)
498
                {
498
                {
499
                        // supply voltage is not supported by sd-card
499
                        // supply voltage is not supported by sd-card
500
                        SerialPutString("Card is incompatible to 3.3V.");
500
                        SerialPutString("Card is incompatible to 3.3V.");
501
                        result = SD_ERROR_BAD_VOLTAGE_RANGE;
501
                        result = SD_ERROR_BAD_VOLTAGE_RANGE;
502
                        goto end;
502
                        goto end;
503
                }
503
                }
504
               
504
               
505
                // Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
505
                // Initialize the sd-card sending continously ACMD_SEND_OP_COND (only supported by SD cards)
506
                timeout =  SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer) 
506
                timeout =  SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer) 
507
                do
507
                do
508
                {
508
                {
509
                        rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
509
                        rsp[0] = SDC_SendACMDR1(ACMD_SEND_OP_COND, 0UL);
510
                        if(rsp[0] & R1_BAD_RESPONSE)
510
                        if(rsp[0] & R1_BAD_RESPONSE)
511
                        {
511
                        {
512
                                sprintf(text,"Bad Acmd41 R1=%02X.", rsp[0]);
512
                                sprintf(text,"Bad Acmd41 R1=%02X.", rsp[0]);
513
                                SerialPutString(text);
513
                                SerialPutString(text);
514
                                result = SD_ERROR_BAD_RESPONSE;
514
                                result = SD_ERROR_BAD_RESPONSE;
515
                                goto end;
515
                                goto end;
516
                        }
516
                        }
517
                        if(CheckDelay(timeout))
517
                        if(CheckDelay(timeout))
518
                        {
518
                        {
519
                            SerialPutString("Init timeout.");
519
                            SerialPutString("Init timeout.");
520
                                result = SD_ERROR_INITIALIZE;
520
                                result = SD_ERROR_INITIALIZE;
521
                                goto end;
521
                                goto end;
522
                        }
522
                        }
523
                } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
523
                } while(rsp[0] & R1_IDLE_STATE); // loop until idle state
524
               
524
               
525
                if(rsp[0] != R1_NO_ERR)
525
                if(rsp[0] != R1_NO_ERR)
526
                {
526
                {
527
                        SerialPutString("Init error.");
527
                        SerialPutString("Init error.");
528
                        result = SD_ERROR_INITIALIZE;
528
                        result = SD_ERROR_INITIALIZE;
529
                        goto end;      
529
                        goto end;      
530
                }
530
                }
531
                /* set block size to 512 bytes */
531
                /* set block size to 512 bytes */
532
        if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
532
        if(SDC_SendCMDR1(CMD_SET_BLOCKLEN, 512UL) != R1_NO_ERR)
533
        {
533
        {
534
                SerialPutString("Error setting block length to 512.");
534
                SerialPutString("Error setting block length to 512.");
535
                        result = SD_ERROR_SET_BLOCKLEN;
535
                        result = SD_ERROR_SET_BLOCKLEN;
536
                        goto end;
536
                        goto end;
537
        }
537
        }
538
               
538
               
539
                //SSC_Disable(); // set SD_CS high                                                                       
539
                //SSC_Disable(); // set SD_CS high                                                                       
540
                // here is the right place to inrease the SPI boud rate to maximum              
540
                // here is the right place to inrease the SPI boud rate to maximum              
541
                //SSC_Enable(); // set SD_CS high
541
                //SSC_Enable(); // set SD_CS high
542
 
542
 
543
                // read CID register
543
                // read CID register
544
                result = SDC_GetCID((u8 *)&SDCardInfo.CID);
544
                result = SDC_GetCID((u8 *)&SDCardInfo.CID);
545
                if(result != SD_SUCCESS)
545
                if(result != SD_SUCCESS)
546
                {
546
                {
547
                        SerialPutString("Error reading CID.\r\n");
547
                        SerialPutString("Error reading CID.\r\n");
548
                        goto end;
548
                        goto end;
549
                }
549
                }
550
       
550
       
551
                // read CSD register
551
                // read CSD register
552
                result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
552
                result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
553
                if(result != SD_SUCCESS)
553
                if(result != SD_SUCCESS)
554
                {
554
                {
555
                        SerialPutString("Error reading CSD.");
555
                        SerialPutString("Error reading CSD.");
556
                        goto end;
556
                        goto end;
557
                }
557
                }
558
       
558
       
559
                SerialPutString("ok\r\n");
559
                SerialPutString("ok\r\n");
560
       
560
       
561
                u8 c_size_mult, read_bl_len;
561
                u8 c_size_mult, read_bl_len;
562
                u32 c_size;
562
                u32 c_size;
563
       
563
       
564
                switch(SDCardInfo.CSD[0]>>6) // check CSD Version
564
                switch(SDCardInfo.CSD[0]>>6) // check CSD Version
565
                {
565
                {
566
                case 0x00: // if CSD is V1.0 structure (2GB limit)
566
                case 0x00: // if CSD is V1.0 structure (2GB limit)
567
       
567
       
568
                        /*
568
                        /*
569
                        memory capacity = BLOCKNR * BLOCK_LEN
569
                        memory capacity = BLOCKNR * BLOCK_LEN
570
                        BLOCKNR = (C_SIZE+1) * MULT
570
                        BLOCKNR = (C_SIZE+1) * MULT
571
                        MULT = 2^(C_SIZE_MULT+2)
571
                        MULT = 2^(C_SIZE_MULT+2)
572
                        BLOCK_LEN = 2^READ_BL_LEN
572
                        BLOCK_LEN = 2^READ_BL_LEN
573
               
573
               
574
                        C_SIZE      is 12 bits [73:62] in CSD register
574
                        C_SIZE      is 12 bits [73:62] in CSD register
575
                        C_SIZE_MULT is  3 bits [49:47] in CSD register
575
                        C_SIZE_MULT is  3 bits [49:47] in CSD register
576
                        READ_BL_LEN is  4 bits [83:80] in CSD register
576
                        READ_BL_LEN is  4 bits [83:80] in CSD register
577
                        */
577
                        */
578
       
578
       
579
                        read_bl_len = (SDCardInfo.CSD[5] & 0x0F);               //CSD[05] -> [87:80]
579
                        read_bl_len = (SDCardInfo.CSD[5] & 0x0F);               //CSD[05] -> [87:80]
580
                        c_size = ((u32)(SDCardInfo.CSD[6] & 0x03))<<10; //CSD[06] -> [79:72]
580
                        c_size = ((u32)(SDCardInfo.CSD[6] & 0x03))<<10; //CSD[06] -> [79:72]
581
                        c_size |= ((u32)SDCardInfo.CSD[7])<<2;                  //CSD[07] -> [71:64]
581
                        c_size |= ((u32)SDCardInfo.CSD[7])<<2;                  //CSD[07] -> [71:64]
582
                        c_size |= (u32)(SDCardInfo.CSD[8]>>6);                  //CSD[08] -> [63:56]
582
                        c_size |= (u32)(SDCardInfo.CSD[8]>>6);                  //CSD[08] -> [63:56]
583
                        c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1;    //CSD[09] -> [55:48]
583
                        c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1;    //CSD[09] -> [55:48]
584
                        c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7;   //CSD[10] -> [47:40]
584
                        c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7;   //CSD[10] -> [47:40]
585
                        SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
585
                        SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
586
                        break;
586
                        break;
587
       
587
       
588
                case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB) 
588
                case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB) 
589
       
589
       
590
                        /*
590
                        /*
591
                        memory capacity = (C_SIZE+1) * 512K byte
591
                        memory capacity = (C_SIZE+1) * 512K byte
592
                        C_SIZE is 22 bits [69:48] in CSR register
592
                        C_SIZE is 22 bits [69:48] in CSR register
593
                        */
593
                        */
594
       
594
       
595
                        c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16; //CSD[07] -> [71:64]
595
                        c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16; //CSD[07] -> [71:64]
596
                        c_size |= ((u32)SDCardInfo.CSD[8])<<8;                  //CSD[08] -> [63:56]
596
                        c_size |= ((u32)SDCardInfo.CSD[8])<<8;                  //CSD[08] -> [63:56]
597
                        c_size |= (u32)SDCardInfo.CSD[9];                               //CSD[09] -> [55:48];
597
                        c_size |= (u32)SDCardInfo.CSD[9];                               //CSD[09] -> [55:48];
598
                        SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
598
                        SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
599
                        break;
599
                        break;
600
       
600
       
601
                default: //unknown CSD Version
601
                default: //unknown CSD Version
602
                        SDCardInfo.Capacity = 0;
602
                        SDCardInfo.Capacity = 0;
603
                        break; 
603
                        break; 
604
                }
604
                }
605
       
605
       
606
                switch(SDCardInfo.Version)
606
                switch(SDCardInfo.Version)
607
                {
607
                {
608
                        case VER_1X:
608
                        case VER_1X:
609
                                SerialPutString("  SD-CARD V1.x");
609
                                SerialPutString("  SD-CARD V1.x");
610
                                break;
610
                                break;
611
                        case VER_20:
611
                        case VER_20:
612
                                SerialPutString("  SD-CARD V2.0 or later");
612
                                SerialPutString("  SD-CARD V2.0 or later");
613
                        default:
613
                        default:
614
                                break;
614
                                break;
615
                }
615
                }
616
                u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
616
                u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
617
                sprintf(text, "\r\n  Capacity = %i MB", mb_size);
617
                sprintf(text, "\r\n  Capacity = %i MB", mb_size);
618
                SerialPutString(text);
618
                SerialPutString(text);
619
       
619
       
620
                SDC_PrintCID((u8 *)&SDCardInfo.CID);
620
                SDC_PrintCID((u8 *)&SDCardInfo.CID);
621
                SDCardInfo.Valid = 1;
621
                SDCardInfo.Valid = 1;
622
                // jump point for error condition before
622
                // jump point for error condition before
623
                end:
623
                end:
624
                SSC_Disable();
624
                SSC_Disable();
625
        }
625
        }
626
        else
626
        else
627
        {
627
        {
628
                SSC_Deinit();
628
                SSC_Deinit();
629
                SDCardInfo.Valid = 0;
629
                SDCardInfo.Valid = 0;
630
                result = SD_ERROR_NOCARD;
630
                result = SD_ERROR_NOCARD;
631
                SerialPutString("No Card in Slot.");
631
                SerialPutString("No Card in Slot.");
632
        }
632
        }
633
        return(result);
633
        return(result);
634
}
634
}
635
 
635
 
636
 
636
 
637
//________________________________________________________________________________________________________________________________________
637
//________________________________________________________________________________________________________________________________________
638
// Funtion:     SDC_Deinit(void);
638
// Funtion:     SDC_Deinit(void);
639
// 
639
// 
640
// Description: This function deinitialises the SDCard interface. 
640
// Description: This function deinitialises the SDCard interface. 
641
//                              
641
//                              
642
//
642
//
643
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
643
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
644
//________________________________________________________________________________________________________________________________________
644
//________________________________________________________________________________________________________________________________________
645
 
645
 
646
SD_Result_t SDC_Deinit(void)
646
SD_Result_t SDC_Deinit(void)
647
{
647
{
648
        SerialPutString("\r\n SDC deinit...");
648
        SerialPutString("\r\n SDC deinit...");
649
        SSC_Deinit();
649
        SSC_Deinit();
650
 
650
 
651
        SDCardInfo.Valid = 0;
651
        SDCardInfo.Valid = 0;
652
        SDCardInfo.Capacity = 0;
652
        SDCardInfo.Capacity = 0;
653
        SDCardInfo.Version = VER_UNKNOWN;
653
        SDCardInfo.Version = VER_UNKNOWN;
654
 
654
 
655
        SerialPutString("ok");
655
        SerialPutString("ok");
656
        return(SD_SUCCESS);
656
        return(SD_SUCCESS);
657
}
657
}
658
 
658
 
659
 
659
 
660
//________________________________________________________________________________________________________________________________________
660
//________________________________________________________________________________________________________________________________________
661
// Funtion:     SDC_PutSector(void);
661
// Funtion:     SDC_PutSector(void);
662
// 
662
// 
663
// Description: This function writes one sector of data to the SSC 
663
// Description: This function writes one sector of data to the SSC 
664
//                              
664
//                              
665
//
665
//
666
// Returnvalue: SD_Result_t
666
// Returnvalue: SD_Result_t
667
//________________________________________________________________________________________________________________________________________
667
//________________________________________________________________________________________________________________________________________
668
 
668
 
669
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
669
SD_Result_t SDC_PutSector(u32 addr, const u8 *Buffer)
670
{
670
{
671
        u8 rsp;
671
        u8 rsp;
672
        u16 a, crc16;
672
        u16 a, crc16;
673
        u16 timeout = 0;
673
        u16 timeout = 0;
674
        SD_Result_t result = SD_ERROR_UNKNOWN;
674
        SD_Result_t result = SD_ERROR_UNKNOWN;
675
 
675
 
676
        addr = addr << 9; // convert sectoradress to byteadress
676
        addr = addr << 9; // convert sectoradress to byteadress
677
        rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
677
        rsp = SDC_SendCMDR1(CMD_WRITE_SINGLE_BLOCK, addr);
678
        if (rsp != R1_NO_ERR)
678
        if (rsp != R1_NO_ERR)
679
        {
679
        {
680
                result = SD_ERROR_BAD_RESPONSE;
680
                result = SD_ERROR_BAD_RESPONSE;
681
                goto end;
681
                goto end;
682
        }
682
        }
683
        SSC_ClearRxFifo();             
683
        SSC_ClearRxFifo();             
684
        for (a=0;a<20;a++)                                      // at least one byte
684
        for (a=0;a<20;a++)                                      // at least one byte
685
        {
685
        {
686
                SSC_GetChar();
686
                SSC_GetChar();
687
        }
687
        }
688
        crc16 = CRC16(Buffer, 512);         // calc checksum for data block
688
        crc16 = CRC16(Buffer, 512);         // calc checksum for data block
689
        SSC_PutChar(DATA_START_TOKEN);          // send data start of header to the SSC 
689
        SSC_PutChar(DATA_START_TOKEN);          // send data start of header to the SSC 
690
       
690
       
691
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
691
        for (a=0;a<512;a++)                                     // transmit one sector (normaly 512bytes) of data to the sdcard.
692
        {
692
        {
693
                SSC_PutChar(Buffer[a]);
693
                SSC_PutChar(Buffer[a]);
694
        }
694
        }
695
        // write two bytes of crc16 to the sdcard
695
        // write two bytes of crc16 to the sdcard
696
        SSC_PutChar((u8)(crc16>>8));            // write high byte first
696
        SSC_PutChar((u8)(crc16>>8));            // write high byte first
697
        SSC_PutChar((u8)(0x00FF&crc16));        // lowbyte last
697
        SSC_PutChar((u8)(0x00FF&crc16));        // lowbyte last
698
        SSC_ClearRxFifo();
698
        SSC_ClearRxFifo();
699
        do                                                                      // wait for data response token
699
        do                                                                      // wait for data response token
700
        {
700
        {
701
                rsp = SSC_GetChar();
701
                rsp = SSC_GetChar();
702
                if(timeout++ > 500)
702
                if(timeout++ > 500)
703
                {
703
                {
704
                        result = SD_ERROR_TIMEOUT;
704
                        result = SD_ERROR_TIMEOUT;
705
                        goto end;
705
                        goto end;
706
                }
706
                }
707
        }while((rsp & 0x11) != 0x01 );
707
        }while((rsp & 0x11) != 0x01 );
708
        // analyse data response token
708
        // analyse data response token
709
        switch(rsp & DATA_RESPONSE_MASK)
709
        switch(rsp & DATA_RESPONSE_MASK)
710
        {
710
        {
711
                case DATA_RESPONSE_OK:
711
                case DATA_RESPONSE_OK:
712
                        result = SD_SUCCESS;
712
                        result = SD_SUCCESS;
713
                        break;
713
                        break;
714
                case DATA_RESPONSE_CRC_ERR:
714
                case DATA_RESPONSE_CRC_ERR:
715
                        result = SD_ERROR_CRC_DATA;
715
                        result = SD_ERROR_CRC_DATA;
716
                        goto end;
716
                        goto end;
717
                        break;
717
                        break;
718
                case DATA_RESPONSE_WRITE_ERR:
718
                case DATA_RESPONSE_WRITE_ERR:
719
                        result = SD_ERROR_WRITE_DATA;
719
                        result = SD_ERROR_WRITE_DATA;
720
                        goto end;
720
                        goto end;
721
                        break;
721
                        break;
722
                default:
722
                default:
723
                        result = SD_ERROR_UNKNOWN;
723
                        result = SD_ERROR_UNKNOWN;
724
                        goto end;
724
                        goto end;
725
                        break;
725
                        break;
726
 
726
 
727
        }
727
        }
728
        // wait 2 seconds until the sdcard is busy.
728
        // wait 2 seconds until the sdcard is busy.
729
        rsp = SDC_WaitForBusy(2000);
729
        rsp = SDC_WaitForBusy(2000);
730
        if(rsp != 0xFF)
730
        if(rsp != 0xFF)
731
        {
731
        {
732
                result =  SD_ERROR_TIMEOUT;
732
                result =  SD_ERROR_TIMEOUT;
733
                goto end;
733
                goto end;
734
        }
734
        }
735
 
735
 
736
        // check card status
736
        // check card status
737
        rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
737
        rsp = SDC_SendCMDR1(CMD_SEND_STATUS, 0);
738
        // first byte of R2 response is like R1 response
738
        // first byte of R2 response is like R1 response
739
        if(rsp != R1_NO_ERR)
739
        if(rsp != R1_NO_ERR)
740
        {
740
        {
741
                result =  SD_ERROR_BAD_RESPONSE;
741
                result =  SD_ERROR_BAD_RESPONSE;
742
                SSC_GetChar(); // read out 2nd byte
742
                SSC_GetChar(); // read out 2nd byte
743
                goto end;
743
                goto end;
744
        }
744
        }
745
        // 2nd byte of r2 response
745
        // 2nd byte of r2 response
746
        rsp = SSC_GetChar();
746
        rsp = SSC_GetChar();
747
        if(rsp != R2_NO_ERR)
747
        if(rsp != R2_NO_ERR)
748
        {
748
        {
749
                result =  SD_ERROR_WRITE_DATA;
749
                result =  SD_ERROR_WRITE_DATA;
750
                SSC_GetChar();
750
                SSC_GetChar();
751
                goto end;
751
                goto end;
752
        }
752
        }
753
        end:
753
        end:
754
        if(result != SD_SUCCESS)
754
        if(result != SD_SUCCESS)
755
        {
755
        {
756
                sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
756
                sprintf(text,"Error %02X writing data to sd card (R=%02X).\r\n", result, rsp);
757
                SerialPutString(text);
757
                SerialPutString(text);
758
        }
758
        }
759
        return(result);
759
        return(result);
760
}
760
}
761
 
761
 
762
 
762
 
763
//________________________________________________________________________________________________________________________________________
763
//________________________________________________________________________________________________________________________________________
764
// Funtion:     SDC_GetSector(u32 addr,u8 *Buffer);
764
// Funtion:     SDC_GetSector(u32 addr,u8 *Buffer);
765
// 
765
// 
766
// Description: This function reads one sector of data from the SSC
766
// Description: This function reads one sector of data from the SSC
767
//                              
767
//                              
768
//
768
//
769
// Returnvalue: SD_Result_t
769
// Returnvalue: SD_Result_t
770
//________________________________________________________________________________________________________________________________________
770
//________________________________________________________________________________________________________________________________________
771
 
771
 
772
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
772
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
773
{
773
{
774
        addr = addr << 9; // convert sectoradress to byteadress
774
        addr = addr << 9; // convert sectoradress to byteadress
775
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
775
        return SDC_GetData(CMD_READ_SINGLE_BLOCK, addr, Buffer, 512);
776
}
776
}
777
 
777
 
778
 
778
 
779
 
779
 
780
 
780