Subversion Repositories NaviCtrl

Rev

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

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