| 1 |
|
= |
1 |
|
| 2 |
|
|
2 |
|
| 3 |
|
|
3 |
|
| 4 |
|
|
4 |
|
| 5 |
|
|
5 |
|
| 6 |
#include "sd_card_raw.h" |
|
6 |
#include "sd_card_raw.h" |
| 7 |
#include "sd_card_raw_cbk.h" |
|
7 |
#include "sd_card_raw_cbk.h" |
| 8 |
|
|
8 |
|
| 9 |
#define SD_CARD_MAX_RETRIES (5000) |
|
9 |
#define SD_CARD_MAX_RETRIES (5000) |
| 10 |
|
|
10 |
|
| 11 |
static uint8_t Is_SDHC = 0; |
|
11 |
static uint8_t Is_SDHC = 0; |
| 12 |
|
|
12 |
|
| 13 |
static uint8_t SD_Card_Send_Command(uint8_t frame1, uint32_t adrs, uint8_t frame2); |
|
13 |
static uint8_t SD_Card_Send_Command(uint8_t frame1, uint32_t adrs, uint8_t frame2); |
| 14 |
|
|
14 |
|
| 15 |
|
|
15 |
|
| 16 |
|
|
16 |
|
| 17 |
|
|
17 |
|
| 18 |
static uint8_t SD_Card_Send_Command(uint8_t frame1, uint32_t adrs, uint8_t frame2) |
|
18 |
static uint8_t SD_Card_Send_Command(uint8_t frame1, uint32_t adrs, uint8_t frame2) |
| 19 |
{ |
|
19 |
{ |
| 20 |
uint16_t i; |
|
20 |
uint16_t i; |
| 21 |
uint8_t res; |
|
21 |
uint8_t res; |
| 22 |
|
|
22 |
|
| |
|
-+ |
23 |
/* Wait some clock cycles */ |
| 23 |
SD_Card_Write_SPI(0xFF); |
= |
24 |
SD_Card_Write_SPI(0xFF); |
| |
|
<> |
25 |
|
| 24 |
SD_Card_Write_SPI(frame1 | 0x40); //first 2 bits are 01 |
|
26 |
SD_Card_Write_SPI(frame1 | 0x40); |
| 25 |
SD_Card_Write_SPI((adrs & 0xFF000000) >> 24); |
= |
27 |
SD_Card_Write_SPI((adrs & 0xFF000000) >> 24); |
| 26 |
SD_Card_Write_SPI((adrs & 0x00FF0000) >> 16); |
|
28 |
SD_Card_Write_SPI((adrs & 0x00FF0000) >> 16); |
| 27 |
SD_Card_Write_SPI((adrs & 0x0000FF00) >> 8); |
|
29 |
SD_Card_Write_SPI((adrs & 0x0000FF00) >> 8); |
| 28 |
SD_Card_Write_SPI(adrs & 0x000000FF); |
|
30 |
SD_Card_Write_SPI(adrs & 0x000000FF); |
| 29 |
SD_Card_Write_SPI(frame2 | 1); |
|
31 |
SD_Card_Write_SPI(frame2 | 1); |
| 30 |
|
|
32 |
|
| 31 |
for (i = 0; i < SD_CARD_MAX_RETRIES; i++) // wait for OK |
<> |
33 |
for (i = 0; i < 10; i++) // wait for OK |
| 32 |
{ |
= |
34 |
{ |
| 33 |
res = SD_Card_Write_SPI(0xFF); |
|
35 |
res = SD_Card_Write_SPI(0xFF); |
| 34 |
if (res != 0xFF) |
|
36 |
if (res != 0xFF) |
| 35 |
{ |
|
37 |
{ |
| 36 |
break; |
|
38 |
break; |
| 37 |
} |
|
39 |
} |
| 38 |
} |
|
40 |
} |
| 39 |
return res; |
|
41 |
return res; |
| 40 |
} |
|
42 |
} |
| 41 |
|
|
43 |
|
| 42 |
|
|
44 |
|
| 43 |
|
|
45 |
|
| 44 |
|
|
46 |
|
| 45 |
void SD_Card_Initialize(void) |
|
47 |
void SD_Card_Initialize(void) |
| 46 |
{ |
|
48 |
{ |
| 47 |
uint8_t i; |
|
49 |
uint8_t i; |
| 48 |
uint8_t r[4]; |
|
50 |
uint8_t r[4]; |
| 49 |
uint8_t res; |
|
51 |
uint8_t res; |
| 50 |
uint16_t retries; |
|
52 |
uint16_t retries; |
| 51 |
|
|
53 |
|
| 52 |
SD_Card_Set_Slow_Clock(); |
|
54 |
SD_Card_Set_Slow_Clock(); |
| 53 |
SD_Card_Chip_Select(1); |
|
55 |
SD_Card_Chip_Select(1); |
| 54 |
|
|
56 |
|
| 55 |
for (i = 0; i < 16; i++) |
<> |
57 |
for (i = 0; i < 10; i++) |
| 56 |
{ |
= |
58 |
{ |
| 57 |
SD_Card_Write_SPI(0xFF); // min 100 clocks |
<> |
59 |
SD_Card_Write_SPI(0xFF); // min 74 clocks |
| 58 |
} |
= |
60 |
} |
| 59 |
SD_Card_Chip_Select(0); |
|
61 |
SD_Card_Chip_Select(0); |
| 60 |
|
|
62 |
|
| 61 |
|
|
63 |
|
| 62 |
retries = SD_CARD_MAX_RETRIES; |
<> |
64 |
retries = 512; |
| 63 |
do |
= |
65 |
do |
| 64 |
{ |
|
66 |
{ |
| 65 |
res = SD_Card_Send_Command(0x00, 0, 0x95); |
|
67 |
res = SD_Card_Send_Command(0x00, 0, 0x95); |
| 66 |
}while((res != 1) && retries--); |
|
68 |
}while((res != 1) && retries--); |
| 67 |
if (res != 1) |
|
69 |
if (res != 1) |
| 68 |
{ |
|
70 |
{ |
| 69 |
SD_Card_Error(__LINE__); |
|
71 |
SD_Card_Error(__LINE__); |
| 70 |
} |
|
72 |
} |
| 71 |
|
<> |
73 |
|
| 72 |
/* Read the OCR register */ |
|
74 |
/* Start the card initialization process */ |
| 73 |
res = SD_Card_Send_Command(58, 0, 0xFF); |
|
|
|
| 74 |
if(res != 1) |
|
75 |
retries = 32768; |
| |
|
|
76 |
do |
| 75 |
{ |
= |
77 |
{ |
| 76 |
SD_Card_Error(__LINE__); |
<> |
|
|
| 77 |
} |
|
|
|
| 78 |
//read CCS in the OCR - SD or Is_SDHC |
|
|
|
| 79 |
r[0] = SD_Card_Write_SPI(0xFF); |
|
78 |
res = SD_Card_Send_Command(1, 0, 0xFF); |
| 80 |
r[1] = SD_Card_Write_SPI(0xFF); |
|
79 |
}while(((res & 0x01) != 0) && retries--); |
| 81 |
r[2] = SD_Card_Write_SPI(0xFF); |
|
|
|
| 82 |
r[3] = SD_Card_Write_SPI(0xFF); //rest of R3 |
|
|
|
| 83 |
Is_SDHC = r[0] & 0x40; |
|
|
|
| 84 |
if (Is_SDHC) |
|
80 |
if (res != 0) |
| 85 |
{ |
= |
81 |
{ |
| 86 |
SD_Card_Error(__LINE__); |
|
82 |
SD_Card_Error(__LINE__); |
| 87 |
} |
|
83 |
} |
| |
|
<> |
84 |
|
| 88 |
/* check that the SDCard supports 3.3V */ |
|
85 |
/* Set sector size to 512 */ |
| 89 |
if((r[1] & 0x03) != 0x03) |
|
86 |
res = SD_Card_Send_Command(16, SD_CARD_BLOCK_SIZE, 0xFF); |
| |
|
|
87 |
if(res) |
| 90 |
{ |
= |
88 |
{ |
| 91 |
SD_Card_Error(__LINE__); |
|
89 |
SD_Card_Error(__LINE__); |
| 92 |
} |
|
90 |
} |
| 93 |
|
<> |
91 |
|
| 94 |
/* Start the card initialization process */ |
|
|
|
| 95 |
retries = SD_CARD_MAX_RETRIES; |
|
|
|
| 96 |
do |
|
|
|
| 97 |
{ |
|
|
|
| 98 |
res = SD_Card_Send_Command(1, 0, 0xFF); |
|
|
|
| 99 |
}while(((res & 0x01) != 0) && retries--); |
|
|
|
| 100 |
|
|
|
|
| 101 |
/* The command 55 shall precede all application specific commands */ |
|
|
|
| 102 |
SD_Card_Send_Command(55, 0, 0xFF); |
|
|
|
| 103 |
|
|
|
|
| 104 |
/* Start the SD Card mode ACMD41 */ |
|
92 |
/* Disable the CRC */ |
| 105 |
retries = SD_CARD_MAX_RETRIES; |
|
|
|
| 106 |
do |
|
|
|
| 107 |
{ |
|
|
|
| 108 |
res = SD_Card_Send_Command(41, 0, 0xFF); |
|
93 |
res = SD_Card_Send_Command(59, 0, 0xFF); |
| 109 |
}while(((res & 0x01) != 0) && retries--); |
|
|
|
| 110 |
|
|
|
|
| 111 |
//Set sector size to 512 |
|
|
|
| 112 |
res = SD_Card_Send_Command(16, SD_CARD_BLOCK_SIZE, 0xFF); |
|
|
|
| 113 |
if(res) |
= |
94 |
if(res) |
| 114 |
{ |
|
95 |
{ |
| 115 |
SD_Card_Error(__LINE__); |
|
96 |
SD_Card_Error(__LINE__); |
| 116 |
} |
|
97 |
} |
| 117 |
|
<> |
98 |
|
| 118 |
SD_Card_Chip_Select(1); |
|
99 |
SD_Card_Chip_Select(1); |
| 119 |
SD_Card_Set_Fast_Clock(); |
= |
100 |
SD_Card_Set_Fast_Clock(); |
| 120 |
} |
|
101 |
} |
| 121 |
|
|
102 |
|
| 122 |
|
|
103 |
|
| 123 |
|
|
104 |
|
| 124 |
|
|
105 |
|
| 125 |
void SD_Card_Write(uint32_t loc, uint8_t* data) |
|
106 |
void SD_Card_Write(uint32_t loc, uint8_t* data) |
| 126 |
{ |
|
107 |
{ |
| 127 |
uint16_t r; |
|
108 |
uint16_t r; |
| 128 |
uint16_t i; |
|
109 |
uint16_t i; |
| 129 |
uint16_t retries = SD_CARD_MAX_RETRIES; |
+- |
|
|
| 130 |
|
= |
110 |
|
| 131 |
SD_Card_Chip_Select(0); |
|
111 |
SD_Card_Chip_Select(0); |
| 132 |
|
|
112 |
|
| 133 |
r = SD_Card_Send_Command(25, loc, 0xFF); //sector write |
<> |
113 |
r = SD_Card_Send_Command(24, loc, 0xFF); //sector write |
| 134 |
if (r != 0) |
= |
114 |
if (r != 0) |
| 135 |
{ |
|
115 |
{ |
| 136 |
SD_Card_Error(__LINE__); |
|
116 |
SD_Card_Error(__LINE__); |
| 137 |
} |
|
117 |
} |
| 138 |
SD_Card_Write_SPI(0xFF); |
<> |
118 |
|
| 139 |
SD_Card_Write_SPI(0xFF); |
|
119 |
/* send start byte */ |
| 140 |
SD_Card_Write_SPI(0xFF); |
|
120 |
SD_Card_Write_SPI(0xFE); |
| 141 |
|
= |
121 |
|
| 142 |
SD_Card_Write_SPI(0xFC); //multi sector token byte |
+- |
|
|
| 143 |
for (i = 0; i < SD_CARD_BLOCK_SIZE; i++) |
= |
122 |
for (i = 0; i < SD_CARD_BLOCK_SIZE; i++) |
| 144 |
{ |
|
123 |
{ |
| 145 |
SD_Card_Write_SPI(data[i]); |
|
124 |
SD_Card_Write_SPI(data[i]); |
| 146 |
} |
|
125 |
} |
| |
|
-+ |
126 |
|
| |
|
|
127 |
/* write dummy crc16 */ |
| 147 |
SD_Card_Write_SPI(0xFF); |
= |
128 |
SD_Card_Write_SPI(0xFF); |
| 148 |
SD_Card_Write_SPI(0xFF); |
|
129 |
SD_Card_Write_SPI(0xFF); |
| 149 |
|
|
130 |
|
| |
|
-+ |
131 |
/* wait while card is busy */ |
| 150 |
do |
= |
132 |
do |
| 151 |
{ |
|
133 |
{ |
| 152 |
r = SD_Card_Write_SPI(0xFF); |
|
134 |
r = SD_Card_Write_SPI(0xFF); |
| 153 |
}while(retries-- && (0xFF == r)); |
<> |
135 |
}while(0xFF != r); |
| 154 |
|
|
136 |
|
| 155 |
if ((r & 0x0F) == 0x05) |
|
|
|
| 156 |
{ |
|
|
|
| 157 |
//data accepted = 0101 |
|
|
|
| 158 |
for (i = 10000; i > 0; i--) |
|
|
|
| 159 |
{ |
|
|
|
| 160 |
r = SD_Card_Write_SPI(0xFF); |
|
|
|
| 161 |
if (r) |
|
|
|
| 162 |
{ |
|
|
|
| 163 |
break; |
|
|
|
| 164 |
} |
|
|
|
| 165 |
} |
|
|
|
| 166 |
} |
|
|
|
| 167 |
else |
|
|
|
| 168 |
{ |
|
|
|
| 169 |
SD_Card_Error(__LINE__); |
|
|
|
| 170 |
} |
|
|
|
| 171 |
|
|
|
|
| 172 |
while (SD_Card_Write_SPI(0xFF) != 0xFF); // while busy |
|
|
|
| 173 |
|
|
|
|
| 174 |
SD_Card_Write_SPI(0xFD); //stop transfer token byte |
|
|
|
| 175 |
|
|
|
|
| 176 |
SD_Card_Write_SPI(0xFF); |
= |
137 |
SD_Card_Write_SPI(0xFF); |
| 177 |
SD_Card_Write_SPI(0xFF); |
<> |
|
|
| 178 |
while (SD_Card_Write_SPI(0xFF) != 0xFF); // while busy |
|
|
|
| 179 |
|
|
138 |
|
| 180 |
SD_Card_Chip_Select(1); |
= |
139 |
SD_Card_Chip_Select(1); |
| 181 |
} |
|
140 |
} |
| 182 |
|
|
141 |
|
| 183 |
|
|
142 |
|
| 184 |
|
|
143 |
|
| 185 |
|
|
144 |
|
| 186 |
void SD_Card_Read(uint32_t loc, uint8_t* data) |
|
145 |
void SD_Card_Read(uint32_t loc, uint8_t* data) |
| 187 |
{ |
|
146 |
{ |
| 188 |
uint16_t i; |
|
147 |
uint16_t i; |
| 189 |
uint8_t r; |
|
148 |
uint8_t r; |
| |
|
-+ |
149 |
uint16_t retries; |
| 190 |
|
= |
150 |
|
| 191 |
SD_Card_Chip_Select(0); |
|
151 |
SD_Card_Chip_Select(0); |
| 192 |
|
|
152 |
|
| |
|
<> |
153 |
r = 0xFF; |
| |
|
|
154 |
retries = SD_CARD_MAX_RETRIES; |
| |
|
|
155 |
while(r && --retries) |
| |
|
|
156 |
{ |
| 193 |
r = SD_Card_Send_Command(17, loc, 0xFF); //read single-sector |
|
157 |
r = SD_Card_Send_Command(17, loc, 0xFF); //read single-sector |
| |
|
|
158 |
} |
| 194 |
if (r != 0) |
|
159 |
if(0 != r) |
| 195 |
{ |
= |
160 |
{ |
| 196 |
SD_Card_Error(__LINE__); |
|
161 |
SD_Card_Error(__LINE__); |
| 197 |
} |
|
162 |
} |
| 198 |
|
|
163 |
|
| 199 |
// wait for not busy |
<> |
164 |
/* wait for data block (start byte 0xfe) */ |
| 200 |
do |
= |
165 |
do |
| 201 |
{ |
|
166 |
{ |
| 202 |
r = SD_Card_Write_SPI(0xFF); |
|
167 |
r = SD_Card_Write_SPI(0xFF); |
| 203 |
}while(r == 0xFF); |
<> |
168 |
}while(r != 0xFE); |
| 204 |
|
= |
169 |
|
| 205 |
if(r != 0xFE) |
+- |
|
|
| 206 |
{ |
|
|
|
| 207 |
SD_Card_Error(__LINE__); |
|
|
|
| 208 |
} |
|
|
|
| 209 |
|
|
|
|
| 210 |
for (i = 0; i < SD_CARD_BLOCK_SIZE; i++) |
= |
170 |
for (i = 0; i < SD_CARD_BLOCK_SIZE; i++) |
| 211 |
{ |
|
171 |
{ |
| 212 |
data[i] = SD_Card_Write_SPI(0xFF); |
|
172 |
data[i] = SD_Card_Write_SPI(0xFF); |
| 213 |
} |
|
173 |
} |
| |
|
<> |
174 |
|
| |
|
|
175 |
/* read crc16 */ |
| 214 |
SD_Card_Write_SPI(0xFF); //discard of CRC |
|
176 |
SD_Card_Write_SPI(0xFF); |
| 215 |
SD_Card_Write_SPI(0xFF); |
= |
177 |
SD_Card_Write_SPI(0xFF); |
| 216 |
|
|
178 |
|
| 217 |
SD_Card_Chip_Select(1); |
|
179 |
SD_Card_Chip_Select(1); |
| 218 |
|
|
180 |
|
| 219 |
SD_Card_Write_SPI(0xFF); |
|
181 |
SD_Card_Write_SPI(0xFF); |
| 220 |
} |
|
182 |
} |