1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 */
9 #include <rtthread.h>
10 #include <dfs_fs.h>
11
12 #include "spi.h"
13 #include "sd.h"
14
15 /* 512 bytes for each sector */
16 #define SD_SECTOR_SIZE 512
17
18 /* token for write operation */
19 #define TOKEN_SINGLE_BLOCK 0xFE
20 #define TOKEN_MULTI_BLOCK 0xFC
21 #define TOKEN_STOP_TRAN 0xFD
22
23 /* Local variables */
24 static uint8_t CardType;
25 static SDCFG SDCfg;
26 static struct rt_device sdcard_device;
27 static struct dfs_partition part;
28
29 /* Local Function Prototypes */
30 static bool LPC17xx_SD_Init(void);
31 static uint8_t LPC17xx_SD_SendCmd(uint8_t cmd, uint32_t arg);
32 static bool LPC17xx_SD_ReadSector(uint32_t sector, uint8_t *buff, uint32_t count);
33 static bool LPC17xx_SD_ReadDataBlock(uint8_t *buff, uint32_t cnt);
34 static bool LPC17xx_SD_WriteSector(uint32_t sector, const uint8_t *buff, uint32_t count);
35 static bool LPC17xx_SD_WriteDataBlock(const uint8_t *buff, uint8_t token);
36 static bool LPC17xx_SD_ReadCfg(SDCFG *cfg);
37 static bool LPC17xx_SD_WaitForReady(void);
38
39 /* wait until the card is not busy */
LPC17xx_SD_WaitForReady(void)40 static bool LPC17xx_SD_WaitForReady(void)
41 {
42 uint8_t res;
43 /* timeout should be large enough to make sure the write operaion can be completed. */
44 uint32_t timeout = 400000;
45
46 LPC17xx_SPI_SendByte(0xFF);
47 do
48 {
49 res = LPC17xx_SPI_RecvByte();
50 }
51 while ((res != 0xFF) && timeout--);
52
53 return (res == 0xFF ? true : false);
54 }
55
56 /* Initialize SD/MMC card. */
LPC17xx_SD_Init(void)57 static bool LPC17xx_SD_Init(void)
58 {
59 uint32_t i, timeout;
60 uint8_t cmd, ct, ocr[4];
61 bool ret = false;
62
63 /* Initialize SPI interface and enable Flash Card SPI mode. */
64 LPC17xx_SPI_Init();
65
66 /* At least 74 clock cycles are required prior to starting bus communication */
67 for (i = 0; i < 80; i++) /* 80 dummy clocks */
68 {
69 LPC17xx_SPI_SendByte(0xFF);
70 }
71
72 ct = CT_NONE;
73 if (LPC17xx_SD_SendCmd(GO_IDLE_STATE, 0) == 0x1)
74 {
75 timeout = 50000;
76 if (LPC17xx_SD_SendCmd(CMD8, 0x1AA) == 1) /* SDHC */
77 {
78 /* Get trailing return value of R7 resp */
79 for (i = 0; i < 4; i++) ocr[i] = LPC17xx_SPI_RecvByte();
80 if (ocr[2] == 0x01 && ocr[3] == 0xAA) /* The card can work at vdd range of 2.7-3.6V */
81 {
82 /* Wait for leaving idle state (ACMD41 with HCS bit) */
83 while (timeout-- && LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 1UL << 30));
84 /* Check CCS bit in the OCR */
85 if (timeout && LPC17xx_SD_SendCmd(READ_OCR, 0) == 0)
86 {
87 for (i = 0; i < 4; i++) ocr[i] = LPC17xx_SPI_RecvByte();
88 ct = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
89 }
90 }
91 else /* SDSC or MMC */
92 {
93 if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1)
94 {
95 ct = CT_SD1;
96 cmd = SD_SEND_OP_COND; /* SDSC */
97 }
98 else
99 {
100 ct = CT_MMC;
101 cmd = SEND_OP_COND; /* MMC */
102 }
103 /* Wait for leaving idle state */
104 while (timeout-- && LPC17xx_SD_SendCmd(cmd, 0));
105 /* Set R/W block length to 512 */
106 if (!timeout || LPC17xx_SD_SendCmd(SET_BLOCKLEN, SD_SECTOR_SIZE) != 0)
107 ct = CT_NONE;
108 }
109 }
110 else /* SDSC or MMC */
111 {
112 if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1)
113 {
114 ct = CT_SD1;
115 cmd = SD_SEND_OP_COND; /* SDSC */
116 }
117 else
118 {
119 ct = CT_MMC;
120 cmd = SEND_OP_COND; /* MMC */
121 }
122 /* Wait for leaving idle state */
123 while (timeout-- && LPC17xx_SD_SendCmd(cmd, 0));
124 /* Set R/W block length to 512 */
125 if (!timeout || LPC17xx_SD_SendCmd(SET_BLOCKLEN, SD_SECTOR_SIZE) != 0)
126 ct = CT_NONE;
127 }
128 }
129 CardType = ct;
130 LPC17xx_SPI_Release();
131
132 if (ct) /* Initialization succeeded */
133 {
134 ret = true;
135 if (ct == CT_MMC)
136 {
137 LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
138 }
139 else
140 {
141 LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
142 }
143 }
144 else /* Initialization failed */
145 {
146 LPC17xx_SPI_Select();
147 LPC17xx_SD_WaitForReady();
148 LPC17xx_SPI_DeInit();
149 }
150
151 return ret;
152 }
153
154 /*****************************************************************************
155 Send a Command to Flash card and get a Response
156 cmd: cmd index
157 arg: argument for the cmd
158 return the received response of the command
159 *****************************************************************************/
LPC17xx_SD_SendCmd(uint8_t cmd,uint32_t arg)160 static uint8_t LPC17xx_SD_SendCmd(uint8_t cmd, uint32_t arg)
161 {
162 uint32_t r1, n;
163
164 if (cmd & 0x80) /* ACMD<n> is the command sequence of CMD55-CMD<n> */
165 {
166 cmd &= 0x7F;
167 r1 = LPC17xx_SD_SendCmd(APP_CMD, 0); /* CMD55 */
168 if (r1 > 1) return r1; /* cmd send failed */
169 }
170
171 /* Select the card and wait for ready */
172 LPC17xx_SPI_DeSelect();
173 LPC17xx_SPI_Select();
174 if (LPC17xx_SD_WaitForReady() == false) return 0xFF;
175
176 LPC17xx_SPI_SendByte(0xFF); /* prepare 8 clocks */
177 LPC17xx_SPI_SendByte(cmd);
178 LPC17xx_SPI_SendByte(arg >> 24);
179 LPC17xx_SPI_SendByte(arg >> 16);
180 LPC17xx_SPI_SendByte(arg >> 8);
181 LPC17xx_SPI_SendByte(arg);
182 /* Checksum, should only be valid for the first command.CMD0 */
183 n = 0x01; /* Dummy CRC + Stop */
184 if (cmd == GO_IDLE_STATE) n = 0x95; /* Valid CRC for CMD0(0) */
185 if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
186 LPC17xx_SPI_SendByte(n);
187
188 if (cmd == STOP_TRAN) LPC17xx_SPI_RecvByte(); /* Skip a stuff byte when stop reading */
189
190 n = 10; /* Wait for a valid response in timeout of 10 attempts */
191 do
192 {
193 r1 = LPC17xx_SPI_RecvByte();
194 }
195 while ((r1 & 0x80) && --n);
196
197 return (r1); /* Return with the response value */
198 }
199
200 /*****************************************************************************
201 Read "count" Sector(s) starting from sector index "sector",
202 buff <- [sector, sector+1, ... sector+count-1]
203 if success, return true, otherwise return false
204 *****************************************************************************/
LPC17xx_SD_ReadSector(uint32_t sector,uint8_t * buff,uint32_t count)205 static bool LPC17xx_SD_ReadSector(uint32_t sector, uint8_t *buff, uint32_t count)
206 {
207 /* Convert to byte address if needed */
208 if (!(CardType & CT_BLOCK)) sector *= SD_SECTOR_SIZE;
209
210 if (count == 1) /* Single block read */
211 {
212 if ((LPC17xx_SD_SendCmd(READ_BLOCK, sector) == 0)
213 && LPC17xx_SD_ReadDataBlock(buff, SD_SECTOR_SIZE))
214 count = 0;
215 }
216 else /* Multiple block read */
217 {
218 if (LPC17xx_SD_SendCmd(READ_MULT_BLOCK, sector) == 0)
219 {
220 do
221 {
222 if (!LPC17xx_SD_ReadDataBlock(buff, SD_SECTOR_SIZE)) break;
223 buff += SD_SECTOR_SIZE;
224 }
225 while (--count);
226 LPC17xx_SD_SendCmd(STOP_TRAN, 0); /* STOP_TRANSMISSION */
227 }
228 }
229 LPC17xx_SPI_Release();
230
231 return count ? false : true;
232 }
233
234 /*****************************************************************************
235 read specified number of data to specified buffer.
236 buff: Data buffer to store received data
237 cnt: Byte count (must be multiple of 4, normally 512)
238 *****************************************************************************/
LPC17xx_SD_ReadDataBlock(uint8_t * buff,uint32_t cnt)239 static bool LPC17xx_SD_ReadDataBlock(uint8_t *buff, uint32_t cnt)
240 {
241 uint8_t token;
242 uint32_t timeout;
243
244 timeout = 20000;
245 do /* Wait for data packet in timeout of 100ms */
246 {
247 token = LPC17xx_SPI_RecvByte();
248 }
249 while ((token == 0xFF) && timeout--);
250 if (token != 0xFE) return false; /* If not valid data token, return with error */
251
252 #if USE_FIFO
253 LPC17xx_SPI_RecvBlock_FIFO(buff, cnt);
254 #else
255 do /* Receive the data block into buffer */
256 {
257 *buff++ = LPC17xx_SPI_RecvByte();
258 *buff++ = LPC17xx_SPI_RecvByte();
259 *buff++ = LPC17xx_SPI_RecvByte();
260 *buff++ = LPC17xx_SPI_RecvByte();
261 }
262 while (cnt -= 4);
263 #endif /* USE_FIFO */
264 LPC17xx_SPI_RecvByte(); /* Discard CRC */
265 LPC17xx_SPI_RecvByte();
266
267 return true; /* Return with success */
268 }
269
270 /*****************************************************************************
271 Write "count" Sector(s) starting from sector index "sector",
272 buff -> [sector, sector+1, ... sector+count-1]
273 if success, return true, otherwise return false
274 *****************************************************************************/
LPC17xx_SD_WriteSector(uint32_t sector,const uint8_t * buff,uint32_t count)275 static bool LPC17xx_SD_WriteSector(uint32_t sector, const uint8_t *buff, uint32_t count)
276 {
277 if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
278
279 if (count == 1) /* Single block write */
280 {
281 if ((LPC17xx_SD_SendCmd(WRITE_BLOCK, sector) == 0)
282 && LPC17xx_SD_WriteDataBlock(buff, TOKEN_SINGLE_BLOCK))
283 count = 0;
284 }
285 else /* Multiple block write */
286 {
287 if (CardType & CT_SDC) LPC17xx_SD_SendCmd(SET_WR_BLK_ERASE_COUNT, count);
288 if (LPC17xx_SD_SendCmd(WRITE_MULT_BLOCK, sector) == 0)
289 {
290 do
291 {
292 if (!LPC17xx_SD_WriteDataBlock(buff, TOKEN_MULTI_BLOCK)) break;
293 buff += 512;
294 }
295 while (--count);
296 #if 1
297 if (!LPC17xx_SD_WriteDataBlock(0, TOKEN_STOP_TRAN)) /* STOP_TRAN token */
298 count = 1;
299 #else
300 LPC17xx_SPI_SendByte(TOKEN_STOP_TRAN);
301 #endif
302 }
303 }
304 LPC17xx_SPI_Release();
305 return count ? false : true;
306 }
307
308 /*****************************************************************************
309 Write 512 bytes
310 buffer: 512 byte data block to be transmitted
311 token: 0xFE -> single block
312 0xFC -> multi block
313 0xFD -> Stop
314 *****************************************************************************/
LPC17xx_SD_WriteDataBlock(const uint8_t * buff,uint8_t token)315 static bool LPC17xx_SD_WriteDataBlock(const uint8_t *buff, uint8_t token)
316 {
317 uint8_t resp, i;
318
319 i = i; // avoid warning
320
321 LPC17xx_SPI_SendByte(token); /* send data token first*/
322
323 if (token != TOKEN_STOP_TRAN)
324 {
325 #if USE_FIFO
326 LPC17xx_SPI_SendBlock_FIFO(buff);
327 #else
328 /* Send data. */
329 for (i = 512 / 4; i ; i--)
330 {
331 LPC17xx_SPI_SendByte(*buff++);
332 LPC17xx_SPI_SendByte(*buff++);
333 LPC17xx_SPI_SendByte(*buff++);
334 LPC17xx_SPI_SendByte(*buff++);
335 }
336 #endif /* USE_FIFO */
337 LPC17xx_SPI_SendByte(0xFF); /* 16-bit CRC (Dummy) */
338 LPC17xx_SPI_SendByte(0xFF);
339
340 resp = LPC17xx_SPI_RecvByte(); /* Receive data response */
341 if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
342 return false;
343
344 if (LPC17xx_SD_WaitForReady() == false) /* Wait while Flash Card is busy. */
345 return false;
346 }
347
348 return true;
349 }
350
351 /* Read MMC/SD Card device configuration. */
LPC17xx_SD_ReadCfg(SDCFG * cfg)352 static bool LPC17xx_SD_ReadCfg(SDCFG *cfg)
353 {
354 uint8_t i;
355 uint16_t csize;
356 uint8_t n, csd[16];
357 bool retv = false;
358
359 /* Read the OCR - Operations Condition Register. */
360 if (LPC17xx_SD_SendCmd(READ_OCR, 0) != 0x00) goto x;
361 for (i = 0; i < 4; i++) cfg->ocr[i] = LPC17xx_SPI_RecvByte();
362
363 /* Read the CID - Card Identification. */
364 if ((LPC17xx_SD_SendCmd(SEND_CID, 0) != 0x00) ||
365 (LPC17xx_SD_ReadDataBlock(cfg->cid, 16) == false))
366 goto x;
367
368 /* Read the CSD - Card Specific Data. */
369 if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) != 0x00) ||
370 (LPC17xx_SD_ReadDataBlock(cfg->csd, 16) == false))
371 goto x;
372
373 cfg -> sectorsize = SD_SECTOR_SIZE;
374
375 /* Get number of sectors on the disk (DWORD) */
376 if ((cfg->csd[0] >> 6) == 1) /* SDC ver 2.00 */
377 {
378 csize = cfg->csd[9] + ((uint16_t)cfg->csd[8] << 8) + 1;
379 cfg -> sectorcnt = (uint32_t)csize << 10;
380 }
381 else /* SDC ver 1.XX or MMC*/
382 {
383 n = (cfg->csd[5] & 15) + ((cfg->csd[10] & 128) >> 7) + ((cfg->csd[9] & 3) << 1) + 2; // 19
384 csize = (cfg->csd[8] >> 6) + ((uint16_t)cfg->csd[7] << 2) + ((uint16_t)(cfg->csd[6] & 3) << 10) + 1; // 3752
385 cfg -> sectorcnt = (uint32_t)csize << (n - 9); // 3842048
386 }
387
388 cfg->size = cfg -> sectorcnt * cfg -> sectorsize; // 512*3842048=1967128576Byte (1.83GB)
389
390 /* Get erase block size in unit of sector (DWORD) */
391 if (CardType & CT_SD2) /* SDC ver 2.00 */
392 {
393 if (LPC17xx_SD_SendCmd(SD_STATUS /*ACMD13*/, 0) == 0) /* Read SD status */
394 {
395 LPC17xx_SPI_RecvByte();
396 if (LPC17xx_SD_ReadDataBlock(csd, 16)) /* Read partial block */
397 {
398 for (n = 64 - 16; n; n--) LPC17xx_SPI_RecvByte(); /* Purge trailing data */
399 cfg->blocksize = 16UL << (csd[10] >> 4);
400 retv = true;
401 }
402 }
403 }
404 else /* SDC ver 1.XX or MMC */
405 {
406 if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) == 0) && LPC17xx_SD_ReadDataBlock(csd, 16)) /* Read CSD */
407 {
408 if (CardType & CT_SD1) /* SDC ver 1.XX */
409 {
410 cfg->blocksize = (((csd[10] & 63) << 1) + ((uint16_t)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
411 }
412 else /* MMC */
413 {
414 // cfg->blocksize = ((uint16_t)((buf[10] & 124) >> 2) + 1) * (((buf[11] & 3) << 3) + ((buf[11] & 224) >> 5) + 1);
415 cfg->blocksize = ((uint16_t)((cfg->csd[10] & 124) >> 2) + 1) * (((cfg->csd[10] & 3) << 3) + ((cfg->csd[11] & 224) >> 5) + 1);
416 }
417 retv = true;
418 }
419 }
420
421 x:
422 LPC17xx_SPI_Release();
423 return (retv);
424 }
425
rt_sdcard_init(rt_device_t dev)426 static rt_err_t rt_sdcard_init(rt_device_t dev)
427 {
428 return RT_EOK;
429 }
430
rt_sdcard_open(rt_device_t dev,rt_uint16_t oflag)431 static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
432 {
433 return RT_EOK;
434 }
435
rt_sdcard_close(rt_device_t dev)436 static rt_err_t rt_sdcard_close(rt_device_t dev)
437 {
438 return RT_EOK;
439 }
440
rt_sdcard_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)441 static rt_ssize_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
442 {
443 bool status;
444
445 status = LPC17xx_SD_ReadSector(part.offset + pos, buffer, size);
446
447 if (status == true) return size;
448
449 rt_kprintf("read failed: %d, pos 0x%08x, size %d\n", status, pos, size);
450 return 0;
451 }
452
rt_sdcard_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)453 static rt_ssize_t rt_sdcard_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
454 {
455 bool status;
456
457 status = LPC17xx_SD_WriteSector(part.offset + pos, buffer, size);
458
459 if (status == true) return size;
460
461 rt_kprintf("write failed: %d, pos 0x%08x, size %d\n", status, pos, size);
462 return 0;
463 }
464
rt_sdcard_control(rt_device_t dev,int cmd,void * args)465 static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
466 {
467 if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
468 {
469 struct rt_device_blk_geometry *geometry;
470
471 geometry = (struct rt_device_blk_geometry *)args;
472
473 if (geometry == RT_NULL) return -RT_ERROR;
474 if (dev->user_data == RT_NULL) return -RT_ERROR;
475
476 geometry->bytes_per_sector = ((SDCFG *)dev->user_data)->sectorsize;
477 geometry->block_size = ((SDCFG *)dev->user_data)->blocksize;
478 geometry->sector_count = ((SDCFG *)dev->user_data)->sectorcnt;
479 }
480
481 return RT_EOK;
482 }
483
rt_hw_sdcard_init()484 void rt_hw_sdcard_init()
485 {
486 if (LPC17xx_SD_Init() && LPC17xx_SD_ReadCfg(&SDCfg))
487 {
488 bool status;
489 rt_uint8_t *sector;
490
491 /* get the first sector to read partition table */
492 sector = (rt_uint8_t *) rt_malloc(512);
493 if (sector == RT_NULL)
494 {
495 rt_kprintf("allocate partition sector buffer failed\n");
496 return;
497 }
498
499 status = LPC17xx_SD_ReadSector(0, sector, 1);
500 if (status == true)
501 {
502 /* get the first partition */
503 if (dfs_filesystem_get_partition(&part, sector, 0) != 0)
504 {
505 /* there is no partition */
506 part.offset = 0;
507 part.size = 0;
508 }
509 }
510 else
511 {
512 /* there is no partition table */
513 part.offset = 0;
514 part.size = 0;
515 }
516
517 /* release sector buffer */
518 rt_free(sector);
519
520 /* register sdcard device */
521 sdcard_device.type = RT_Device_Class_Block;
522 sdcard_device.init = rt_sdcard_init;
523 sdcard_device.open = rt_sdcard_open;
524 sdcard_device.close = rt_sdcard_close;
525 sdcard_device.read = rt_sdcard_read;
526 sdcard_device.write = rt_sdcard_write;
527 sdcard_device.control = rt_sdcard_control;
528
529 /* no private */
530 sdcard_device.user_data = &SDCfg;
531
532 rt_device_register(&sdcard_device, "sd0",
533 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
534
535 return;
536 }
537
538 rt_kprintf("sdcard init failed\n");
539 }
540