Subversion Repositories NaviCtrl

Rev

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

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