image/svg+xml
Brteve's API for EveApps
Version 0.0.1
The reference document for common folder of EveApps project.
 
Loading...
Searching...
No Matches
sdcard.h
Go to the documentation of this file.
1
32#ifndef _SDCARD_H_
33#define _SDCARD_H_
34#define VERBOSE 0
35
47
48// https://www.sdcard.org/downloads/pls/simplified_specs/Part_1_Physical_Layer_Simplified_Specification_Ver_3.01_Final_100518.pdf
49// page 22
50// http://mac6.ma.psu.edu/space2008/RockSat/microController/sdcard_appnote_foust.pdf
51// http://elm-chan.org/docs/mmc/mmc_e.html
52// http://www.pjrc.com/tech/8051/ide/fat32.html
53
54#define FAT16 0
55#define FAT32 1
56
57class sdcard {
58 public:
59 void sel() { digitalWrite(pin, LOW); }
60 void desel() {
61 digitalWrite(pin, HIGH);
62 SPI.transfer(0xff); // force DO release
63 }
64 void sd_delay(byte n) {
65 while (n--)
66 SPI.transfer(0xff);
67 }
68
69 void cmd(byte cmd, uint32_t lba = 0, uint8_t crc = 0x95) {
70#if VERBOSE
71 Serial.print("cmd ");
72 Serial.print(cmd, DEC);
73 Serial.print(" ");
74 Serial.print(lba, HEX);
75 Serial.println();
76#endif
77
78 sel();
79 SPI.transfer(0xff);
80 SPI.transfer(0x40 | cmd);
81 SPI.transfer(0xff & (lba >> 24));
82 SPI.transfer(0xff & (lba >> 16));
83 SPI.transfer(0xff & (lba >> 8));
84 SPI.transfer(0xff & (lba));
85 SPI.transfer(crc);
86 SPI.transfer(0xff);
87 }
88
89 byte R1()
90 { // read response R1
91 byte r;
92
93 while ((r = SPI.transfer(0xff)) & 0x80);
94 desel();
95 SPI.transfer(0xff);
96 return r;
97 }
98
99 byte sdR3(uint32_t &ocr) { // read response R3
100 uint32_t r;
101 while ((r = SPI.transfer(0xff)) & 0x80)
102 ;
103 for (byte i = 4; i; i--)
104 ocr = (ocr << 8) | SPI.transfer(0xff);
105 SPI.transfer(0xff); // trailing byte
106
107 desel();
108 return r;
109 }
110
111 byte sdR7() { // read response R3
112 uint32_t r;
113 while ((r = SPI.transfer(0xff)) & 0x80)
114 ;
115 for (byte i = 4; i; i--)
116 // Serial.println(SPI.transfer(0xff), HEX);
117 SPI.transfer(0xff);
118 desel();
119
120 return r;
121 }
122
123 void appcmd(byte cc, uint32_t lba = 0) {
124 cmd(55); R1();
125 cmd(cc, lba);
126 }
127
129 {
130 uint16_t cts=2000;
131 pin = p;
132
133 pinMode(pin, OUTPUT);
134 SPI.begin();
135 SPI.setClockDivider(SPI_CLOCK_DIV64);
136 desel();
137
138 delay(10); // wait for boot
139 sd_delay(10); // deselected, 80 pulses
140
141 // Tty.printf("Attempting card reset... ");
142 // attempt reset
143 byte r1,r;
144 do
145 { // reset, enter idle
146 cmd(0);
147 do
148 {
149 if(cts>0) cts--; else
150 {
151 desel();
152 return 0;
153 }
154 }while ((r = SPI.transfer(0xff)) & 0x80);
155 desel();
156 SPI.transfer(0xff); // trailing byte
157 r1 = r;
158 }while(r1!=1);
159 // Tty.printf("reset ok\n");
160
161 byte sdhc = 0;
162 cmd(8, 0x1aa, 0x87);
163 r1 = sdR7();
164 sdhc = (r1 == 1);
165
166 // Tty.printf("card %s SDHC\n", sdhc ? "is" : "is not");
167
168 // Tty.printf("Sending card init command... ");
169 while (1) {
170 appcmd(41, sdhc ? (1UL << 30) : 0); // card init
171 r1 = R1();
172 if ((r1 & 1) == 0)
173 break;
174 delay(100);
175 }
176 // Tty.printf("OK\n");
177
178 if (sdhc) {
179 cmd(58);
180 uint32_t OCR;
181 sdR3(OCR);
182 ccs = 1UL & (OCR >> 30);
183 // Tty.printf("OCR register is %#010lx\n", long(OCR));
184 } else {
185 ccs = 0;
186 }
187 // Tty.printf("ccs = %d\n", ccs);
188
189 byte type_code = rd(0x1be + 0x4);
190 switch (type_code) {
191 default:
192 type = FAT16;
193 break;
194 case 0x0b:
195 case 0x0c:
196 type = FAT32;
197 break;
198 }
199 // Tty.printf("Type code %#02x means FAT%d\n", type_code, (type == FAT16) ? 16 : 32);
200
201 o_partition = 512L * rd4(0x1be + 0x8);
205
206 // Tty.printf("Bytes per sector: %d\n", rd2(o_partition + 0xb));
207 // Tty.printf("Sectors per cluster: %d\n", sectors_per_cluster);
208
209 if (type == FAT16) {
213 o_root = o_fat + (2 * 512L * sectors_per_fat);
214 // data area starts with cluster 2, so offset it here
215 o_data = o_root + (max_root_dir_entries * 32L) - (2L * cluster_size);
216 } else {
219 uint32_t fat_begin_lba = (o_partition >> 9) + reserved_sectors;
220 uint32_t cluster_begin_lba = (o_partition >> 9) + reserved_sectors + (2 * sectors_per_fat);
221
222 o_fat = 512L * fat_begin_lba;
223 o_root = (512L * (cluster_begin_lba + (root_dir_first_cluster - 2) * sectors_per_cluster));
224 o_data = (512L * (cluster_begin_lba - 2 * sectors_per_cluster));
225 }
226 return 1;
227 }
228 void cmd17(uint32_t off) {
229 if (ccs)
230 cmd(17, off >> 9);
231 else
232 cmd(17, off & ~511L);
233 R1();
234 sel();
235 while (SPI.transfer(0xff) != 0xfe)
236 ;
237 }
238 void rdn(byte *d, uint32_t off, uint16_t n) {
239 cmd17(off);
240 uint16_t i;
241 uint16_t bo = (off & 511);
242 for (i = 0; i < bo; i++)
243 SPI.transfer(0xff);
244 for (i = 0; i < n; i++)
245 *d++ = SPI.transfer(0xff);
246 for (i = 0; i < (514 - bo - n); i++)
247 SPI.transfer(0xff);
248 desel();
249 }
250
252 uint32_t r;
253 rdn((byte*)&r, off, sizeof(r));
254 return r;
255 }
256
258 uint16_t r;
259 rdn((byte*)&r, off, sizeof(r));
260 return r;
261 }
262
263 byte rd(uint32_t off) {
264 byte r;
265 rdn((byte*)&r, off, sizeof(r));
266 return r;
267 }
268 byte pin;
269 byte ccs;
270
271 byte type;
278
279 // These are all linear addresses, hence the o_ prefix
284};
285
286static void dos83(byte dst[11], const char *ps)
287{
288 byte i = 0;
289 while (*ps) {
290 if (*ps != '.')
291 dst[i++] = toupper(*ps);
292 else {
293 while (i < 8)
294 dst[i++] = ' ';
295 }
296 ps++;
297 }
298 while (i < 11)
299 dst[i++] = ' ';
300}
301
302class Reader {
303public:
305 int openfile(const char *filename) {
306 int i = 0;
307 byte dosname[11];
308 dirent de;
309
310 dos83(dosname, filename);
311 do {
312 SD.rdn((byte*)&de, SD.o_root + i * 32, sizeof(de));
313 // Serial.println(de.name);
314 if (0 == memcmp(de.name, dosname, 11)) {
315 begin(de);
316 return 1;
317 }
318 i++;
319 } while (de.name[0]);
320 return 0;
321 }
322
323 void begin(dirent &de) {
324 size = de.size;
325 cluster = de.cluster;
326 if (SD.type == FAT32)
327 cluster |= ((long)de.cluster_hi << 16);
328 sector = 0;
329 offset = 0;
330 }
331 void nextcluster() {
332 if (SD.type == FAT16)
333 cluster = SD.rd2(SD.o_fat + 2 * cluster);
334 else
335 cluster = SD.rd4(SD.o_fat + 4 * cluster);
336#if VERBOSE
337 Serial.print("nextcluster=");
338 Serial.println(cluster, DEC);
339#endif
340 }
341 void skipcluster() {
342 nextcluster();
344 }
345 void skipsector() {
347 sector = 0;
348 nextcluster();
349 }
350 sector++;
351 offset += 512;
352 }
353 void seek(uint32_t o) {
354 while (offset < o) {
355 if ((sector == SD.sectors_per_cluster) && ((o - offset) > (long)SD.cluster_size))
356 skipcluster();
357 else
358 skipsector();
359 }
360 }
361 void readsector() {
363 sector = 0;
364 nextcluster();
365 }
366 uint32_t off = SD.o_data + ((long)SD.cluster_size * cluster) + (512L * sector);
367#if VERBOSE
368 Serial.print("off=0x");
369 Serial.println(off, HEX);
370#endif
371 SD.cmd17(off & ~511L);
372// Serial.println(2 * (micros() - t0), DEC);
373 sector++;
374 offset += 512;
375 }
376 void readsector(byte *dst) {
377 readsector();
378 for (int i = 0; i < 64; i++) {
379 *dst++ = SPI.transfer(0xff);
380 *dst++ = SPI.transfer(0xff);
381 *dst++ = SPI.transfer(0xff);
382 *dst++ = SPI.transfer(0xff);
383 *dst++ = SPI.transfer(0xff);
384 *dst++ = SPI.transfer(0xff);
385 *dst++ = SPI.transfer(0xff);
386 *dst++ = SPI.transfer(0xff);
387 }
388 SPI.transfer(0xff); // consume CRC
389 SPI.transfer(0xff);
390 SD.desel();
391 }
395 byte sector;
396};
397
398#endif
static uint32_t d
Definition Common.c:39
unsigned short uint16_t
unsigned int uint32_t
unsigned char uint8_t
static ft_void_t ft_uint32_t * cmd
Definition FT_Gpu_Hal.h:184
#define delay(x)
Definition Gpu_Hal.h:468
void begin(dirent &de)
Definition sdcard.h:323
void skipcluster()
Definition sdcard.h:341
void nextcluster()
Definition sdcard.h:331
int openfile(const char *filename)
Definition sdcard.h:305
void readsector()
Definition sdcard.h:361
uint32_t cluster
Definition sdcard.h:392
byte sector
Definition sdcard.h:395
void skipsector()
Definition sdcard.h:345
uint32_t offset
Definition sdcard.h:393
uint32_t size
Definition sdcard.h:394
sdcard SD
Definition sdcard.h:304
void readsector(byte *dst)
Definition sdcard.h:376
void seek(uint32_t o)
Definition sdcard.h:353
uint16_t sectors_per_fat
Definition sdcard.h:275
byte sdR7()
Definition sdcard.h:111
byte pin
Definition sdcard.h:268
uint32_t rd4(uint32_t off)
Definition sdcard.h:251
uint8_t begin(byte p)
Definition sdcard.h:128
void desel()
Definition sdcard.h:60
byte R1()
Definition sdcard.h:89
void sel()
Definition sdcard.h:59
void cmd17(uint32_t off)
Definition sdcard.h:228
byte type
Definition sdcard.h:271
uint16_t rd2(uint32_t off)
Definition sdcard.h:257
byte ccs
Definition sdcard.h:269
uint16_t cluster_size
Definition sdcard.h:276
uint16_t reserved_sectors
Definition sdcard.h:273
uint16_t max_root_dir_entries
Definition sdcard.h:274
uint32_t o_data
Definition sdcard.h:283
void cmd(byte cmd, uint32_t lba=0, uint8_t crc=0x95)
Definition sdcard.h:69
uint32_t o_root
Definition sdcard.h:282
uint32_t o_fat
Definition sdcard.h:281
void rdn(byte *d, uint32_t off, uint16_t n)
Definition sdcard.h:238
void sd_delay(byte n)
Definition sdcard.h:64
void appcmd(byte cc, uint32_t lba=0)
Definition sdcard.h:123
uint32_t o_partition
Definition sdcard.h:280
uint32_t root_dir_first_cluster
Definition sdcard.h:277
byte rd(uint32_t off)
Definition sdcard.h:263
uint16_t sectors_per_cluster
Definition sdcard.h:272
byte sdR3(uint32_t &ocr)
Definition sdcard.h:99
#define FAT32
Definition sdcard.h:55
#define FAT16
Definition sdcard.h:54
static void dos83(byte dst[11], const char *ps)
Definition sdcard.h:286
byte reserved[8]
Definition sdcard.h:40
uint16_t cluster
Definition sdcard.h:44
byte attribute
Definition sdcard.h:39
uint32_t size
Definition sdcard.h:45
char ext[3]
Definition sdcard.h:38
uint16_t cluster_hi
Definition sdcard.h:41
uint16_t time
Definition sdcard.h:42
uint16_t date
Definition sdcard.h:43
char name[8]
Definition sdcard.h:37