Subversion Repositories NaviCtrl

Rev

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

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