1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2011-05-13 onelife Initial creation for using EFM32 USART module
9 * 2011-07-07 onelife Modify initialization function to return error code
10 * 2011-12-08 onelife Add giant gecko development kit support
11 * 2011-12-15 onelife Move MicroSD enabling routine to driver
12 * initialization function (board.c)
13 * 2011-12-21 onelife Modify code due to SPI write format changed
14 */
15
16 /***************************************************************************//**
17 * @addtogroup efm32_dk
18 * @{
19 ******************************************************************************/
20
21 /* Includes ------------------------------------------------------------------*/
22 #include "board.h"
23 #include "drv_usart.h"
24 #include "drv_sdcard.h"
25
26 #if defined(EFM32_USING_SPISD)
27 #include <dfs_fs.h>
28
29 /* Private typedef -----------------------------------------------------------*/
30 /* Private define ------------------------------------------------------------*/
31 /* Private macro -------------------------------------------------------------*/
32 #ifdef EFM32_SDCARD_DEBUG
33 #define sdcard_debug(format,args...) rt_kprintf(format, ##args)
34 #else
35 #define sdcard_debug(format,args...)
36 #endif
37
38 /* Private constants ---------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 static struct rt_device sd_device;
41 static struct dfs_partition sdPart;
42 static rt_device_t spi = RT_NULL;
43 static rt_uint16_t sdType;
44 static rt_bool_t sdAutoCs = true;
45 static rt_timer_t sdTimer = RT_NULL;
46 static volatile rt_bool_t sdInTime = true;
47
48 /* Private function prototypes -----------------------------------------------*/
49 /* Private functions ---------------------------------------------------------*/
50 /***************************************************************************//**
51 * @brief
52 * Memory device timeout interrupt handler
53 *
54 * @details
55 *
56 * @note
57 *
58 * @param[in] parameter
59 * Parameter
60 ******************************************************************************/
efm_spiSd_timer(void * parameter)61 static void efm_spiSd_timer(void* parameter)
62 {
63 sdInTime = false;
64 }
65
66 /***************************************************************************//**
67 * @brief
68 * Set/Clear chip select
69 *
70 * @details
71 *
72 * @note
73 *
74 * @param[in] enable
75 * Chip select pin setting
76 ******************************************************************************/
efm_spiSd_cs(rt_uint8_t enable)77 static void efm_spiSd_cs(rt_uint8_t enable)
78 {
79 if (!sdAutoCs)
80 {
81 if (enable)
82 {
83 GPIO_PinOutClear(SD_CS_PORT, SD_CS_PIN);
84 }
85 else
86 {
87 GPIO_PinOutSet(SD_CS_PORT, SD_CS_PIN);
88 }
89 }
90 }
91
92 /***************************************************************************//**
93 * @brief
94 * Set operation speed level
95 *
96 * @details
97 *
98 * @note
99 *
100 * @param[in] level
101 * Set SD speed level
102 ******************************************************************************/
efm_spiSd_speed(rt_uint8_t level)103 static void efm_spiSd_speed(rt_uint8_t level)
104 {
105 RT_ASSERT(spi != RT_NULL);
106
107 struct efm32_usart_device_t *usart;
108 rt_uint32_t baudrate;
109
110 usart = (struct efm32_usart_device_t *)(spi->user_data);
111 if (level == SD_SPEED_HIGH)
112 {
113 baudrate = EFM32_SDCLK_HIGH;
114 }
115 else
116 {
117 baudrate = EFM32_SDCLK_LOW;
118 }
119 USART_BaudrateSyncSet(usart->usart_device, 0, baudrate);
120 }
121
122 /***************************************************************************//**
123 * @brief
124 * Read raw data from memory device
125 *
126 * @details
127 *
128 * @note
129 *
130 * @param[in] buffer
131 * Poniter to the buffer
132 *
133 * @param[in] size
134 * Buffer size in byte
135 *
136 * @return
137 * Number of read bytes
138 ******************************************************************************/
efm_spiSd_read(void * buffer,rt_size_t size)139 static rt_ssize_t efm_spiSd_read(void *buffer, rt_size_t size)
140 {
141 RT_ASSERT(spi != RT_NULL);
142
143 rt_uint8_t buf_read[5], ret;
144
145 /* Build instruction buffer */
146 buf_read[0] = 0x00;
147 *(rt_uint8_t **)(&buf_read[1]) = buffer;
148 /* Read data */
149 efm_spiSd_cs(1);
150 if ((ret = spi->read(spi, EFM32_NO_DATA, buf_read, size)) == 0)
151 {
152 sdcard_debug("SPISD: Read failed!\n");
153 }
154 efm_spiSd_cs(0);
155
156 return ret;
157 }
158
159 /***************************************************************************//**
160 * @brief
161 * Send command to memory device
162 *
163 * @details
164 *
165 * @note
166 *
167 * @param[in] cmd
168 * Command index
169 *
170 * @param[in] arg
171 * Argument
172 *
173 * @param[in] trail
174 * Pointer to the buffer to store trailing data
175 *
176 * @return
177 * Command response
178 ******************************************************************************/
efm_spiSd_cmd(rt_uint8_t cmd,rt_uint32_t arg,rt_uint8_t * trail)179 static rt_uint16_t efm_spiSd_cmd(
180 rt_uint8_t cmd,
181 rt_uint32_t arg,
182 rt_uint8_t *trail)
183 {
184 RT_ASSERT(spi != RT_NULL);
185
186 rt_uint8_t buf_ins[11];
187 rt_uint8_t buf_res[32]; /* Expect (x+1+4) bytes for CRC, (x+1+19) for CSD/CID */
188 rt_uint8_t len_trl, i, j;
189 rt_uint16_t ret;
190 rt_bool_t skip;
191
192 ret = 0xffff;
193 rt_memset(buf_res, 0xff, sizeof(buf_res));
194
195 sdcard_debug("SPISD: Send command %d(%x)\n", cmd, arg);
196 do
197 {
198 /* Build instruction buffer */
199 buf_ins[0] = 6; /* Instruction length */
200 buf_ins[1] = 0x40 | cmd; /* Command index */
201 buf_ins[2] = (arg >> 24) & 0x000000ff; /* Argument: MSB first */
202 buf_ins[3] = (arg >> 16) & 0x000000ff;
203 buf_ins[4] = (arg >> 8) & 0x000000ff;
204 buf_ins[5] = arg & 0x000000ff;
205 if (cmd == CMD0)
206 {
207 buf_ins[6] = 0x95; /* Valid CRC for CMD0(0) */
208 }
209 else if (cmd == CMD8)
210 {
211 buf_ins[6] = 0x87; /* Valid CRC for CMD8(0x1AA) */
212 }
213 else if (cmd == CMD58)
214 {
215 buf_ins[6] = 0x01; /* Dummy CRC + Stop */
216 }
217 else
218 {
219 buf_ins[6] = 0x01; /* Dummy CRC + Stop */
220 }
221 *(rt_uint8_t **)(&buf_ins[7]) = buf_res; /* Pointer to RX buffer */
222
223 /* Set trail length */
224 if (cmd == CMD8)
225 {
226 len_trl = 4; /* R7 response */
227 }
228 else if (cmd == CMD9)
229 {
230 len_trl = SD_BLOCK_SIZE_CSD;
231 }
232 else if (cmd == CMD10)
233 {
234 len_trl = SD_BLOCK_SIZE_CID;
235 }
236 else if (cmd == CMD58)
237 {
238 len_trl = SD_BLOCK_SIZE_OCR; /* R3 response */
239 }
240 else
241 {
242 len_trl = 0;
243 }
244
245 /* Send command and get response */
246 efm_spiSd_cs(1);
247 if (spi->read(spi, EFM32_NO_DATA, buf_ins, sizeof(buf_res)) == 0)
248 {
249 sdcard_debug("SPISD: Send command failed!\n");
250 break;
251 }
252 efm_spiSd_cs(0);
253
254 /* Skip a stuff byte when stop reading */
255 if (cmd == CMD12)
256 {
257 skip = true;
258 }
259 else
260 {
261 skip = false;
262 }
263 /* Find valid response: The response is sent back within command response time
264 (NCR), 0 to 8 bytes for SDC, 1 to 8 bytes for MMC */
265 for (i = 0; i < sizeof(buf_res); i++)
266 {
267 if (buf_res[i] != 0xff)
268 {
269 if (skip)
270 {
271 skip = false;
272 sdcard_debug("SPISD: Skip %x (at %d)\n", buf_res[i], i);
273 continue;
274 }
275
276 if (cmd == ACMD13 & 0x7f)
277 {
278 ret = (rt_uint16_t)buf_res[i]; /* R2 response */
279 }
280 else
281 {
282 ret = (rt_uint8_t)buf_res[i];
283 }
284 break;
285 }
286 }
287 sdcard_debug("SPISD: Response %x (at %d)\n", ret, i);
288 i++;
289 /* Copy the trailing data */
290 if ((ret != 0xffff) && len_trl && trail)
291 {
292 if (cmd == CMD9 || cmd == CMD10)
293 {
294 /* Wait for data block */
295 for (; i < sizeof(buf_res); i++)
296 {
297 if (buf_res[i] == 0xfe)
298 {
299 break;
300 }
301 }
302 /* Check if valid */
303 if (i >= sizeof(buf_res))
304 {
305 sdcard_debug("SPISD: Token is not found!\n");
306 ret = 0xffff;
307 break;
308 }
309 i++;
310 }
311 /* Copy the data */
312 for (j = 0; j < len_trl; j++)
313 {
314 trail[j] = buf_res[i + j];
315 }
316 }
317 } while(0);
318
319 return ret;
320 }
321
322 /***************************************************************************//**
323 * @brief
324 * Read a block of data from memory device. This function is used to handle
325 * the responses of specified commands (e.g. ACMD13, CMD17 and CMD18)
326 *
327 * @details
328 *
329 * @note
330 *
331 * @param[in] buffer
332 * Poniter to the buffer
333 *
334 * @param[in] size
335 * Buffer size in byte
336 *
337 * @return
338 * Error code
339 ******************************************************************************/
efm_spiSd_readBlock(void * buffer,rt_size_t size)340 static rt_err_t efm_spiSd_readBlock(void *buffer, rt_size_t size)
341 {
342 RT_ASSERT(spi != RT_NULL);
343
344 rt_uint8_t buf_ins[5];
345 rt_uint8_t buf_res[8]; /* Expect 2 bytes for CRC */
346 rt_uint8_t i, len_copy;
347 rt_bool_t start;
348
349 start = false;
350 do
351 {
352 /* Build instruction buffer */
353 buf_ins[0] = 0; /* Instruction length */
354 *(rt_uint8_t **)(&buf_ins[1]) = buf_res; /* Pointer to RX buffer */
355
356 while(1)
357 {
358 /* Send read command */
359 efm_spiSd_cs(1);
360 if (spi->read(spi, EFM32_NO_DATA, buf_ins, \
361 sizeof(buf_res)) == 0)
362 {
363 sdcard_debug("SPISD: Get read command response failed!\n");
364 break;
365 }
366 efm_spiSd_cs(0);
367 /* Wait for data */
368 for (i = 0; i < sizeof(buf_res); i++)
369 {
370 if (buf_res[i] != 0xff)
371 {
372 start = true;
373 break;
374 }
375 }
376 if (start)
377 {
378 break;
379 }
380 };
381
382 /* Ckeck if valid */
383 if (!start || (buf_res[i] != 0xfe))
384 {
385 sdcard_debug("SPISD: Token is invalid! (%x)\n", buf_res[i]);
386 break;
387 }
388 /* Copy data to buffer and read the rest */
389 len_copy = sizeof(buf_res) - i - 1;
390 rt_memcpy(buffer, &buf_res[i + 1], len_copy);
391 sdcard_debug("SPISD: Read block start at %d, copy %d bytes\n", i, \
392 len_copy);
393
394 /* Build instruction buffer */
395 buf_ins[0] = 0; /* Instruction length */
396 *(rt_uint8_t **)(&buf_ins[1]) = (rt_uint8_t *)buffer + len_copy; /* Pointer to RX buffer */
397
398 /* Send read command */
399 efm_spiSd_cs(1);
400 if (spi->read(spi, EFM32_NO_DATA, buf_ins, size - len_copy) == 0)
401 {
402 sdcard_debug("SPISD: Read data block failed!\n");
403 break;
404 }
405 *(rt_uint8_t **)(&buf_ins[1]) = buf_res; /* Pointer to RX buffer */
406 if (spi->read(spi, EFM32_NO_DATA, buf_ins, sizeof(buf_res)) == 0)
407 {
408 sdcard_debug("SPISD: Read CRC failed!\n");
409 break;
410 }
411 sdcard_debug("SPISD: Read CRC %x %x\n", buf_res[0], buf_res[1]);
412 efm_spiSd_cs(0);
413
414 return RT_EOK;
415 } while(0);
416
417 sdcard_debug("SPISD: Read block failed!\n");
418 return -RT_ERROR;
419 }
420
421 /***************************************************************************//**
422 * @brief
423 * Write a block of data to memory device. This function is used to send data
424 * and control tokens for block write commands (e.g. CMD24 and CMD25)
425 *
426 * @details
427 *
428 * @note
429 *
430 * @param[in] buffer
431 * Poniter to the buffer
432 *
433 * @param[in] token
434 * Control token
435 *
436 * @return
437 * Error code
438 ******************************************************************************/
efm_spiSd_writeBlock(void * buffer,rt_uint8_t token)439 static rt_err_t efm_spiSd_writeBlock(void *buffer, rt_uint8_t token)
440 {
441 RT_ASSERT(spi != RT_NULL);
442
443 rt_err_t ret;
444 rt_uint8_t buf_ins[11];
445 rt_uint8_t buf_res[8]; /* Expect a byte for data response */
446 rt_uint8_t i;
447
448 ret = -RT_ERROR;
449 sdcard_debug("SPISD: Write block\n");
450 do
451 {
452 /* Initialize timer */
453 sdInTime = true;
454 rt_timer_start(sdTimer);
455 /* Wait for card ready */
456 do
457 {
458 efm_spiSd_read(buf_res, sizeof(buf_res));
459 } while (sdInTime && (buf_res[sizeof(buf_res) - 1] != 0xff));
460 if (buf_res[sizeof(buf_res) - 1] != 0xff)
461 {
462 sdcard_debug("SPISD: Card is busy before writing! (%x)\n", \
463 buf_res[sizeof(buf_res) - 1]);
464 ret = -RT_EBUSY;
465 break;
466 }
467 rt_timer_stop(sdTimer);
468
469 /* Send data */
470 sdcard_debug("SPISD: Send data, token %x\n", token);
471 if (token != 0xfd)
472 {
473 /* Send token and data */
474 buf_ins[0] = 1; /* Instruction length */
475 buf_ins[1] = token;
476 *(rt_uint8_t **)(&buf_ins[2]) = (rt_uint8_t *)buffer; /* Pointer to TX buffer */
477 efm_spiSd_cs(1);
478 if (spi->write(spi, EFM32_NO_DATA, buf_ins, SD_SECTOR_SIZE) == 0)
479 {
480 sdcard_debug("SPISD: Write data failed!\n");
481 break;
482 }
483
484 /* Build instruction buffer */
485 buf_ins[0] = 2; /* Instruction length */
486 buf_ins[1] = 0xff; /* CRC (Dummy) */
487 buf_ins[2] = 0xff;
488 *(rt_uint8_t **)(&buf_ins[3]) = buf_res; /* Pointer to RX buffer */
489 /* Send CRC and read a byte */
490 if (spi->read(spi, EFM32_NO_DATA, buf_ins, sizeof(buf_res)) == 0)
491 {
492 sdcard_debug("SPISD: Write CRC failed!\n");
493 break;
494 }
495 efm_spiSd_cs(0);
496
497 /* Check if accepted */
498 for (i = 0; i < sizeof(buf_res); i++)
499 {
500 if (buf_res[i] != 0xff)
501 {
502 buf_res[i] &= 0x1f;
503 break;
504 }
505 }
506 if (buf_res[i] != 0x05)
507 {
508 sdcard_debug("SPISD: Writing is not accepted! (%x at %d)\n", \
509 buf_res[i], i);
510 break;
511 }
512 }
513 else
514 {
515 /* Send token */
516 buf_ins[0] = 1; /* Instruction length */
517 buf_ins[1] = token;
518 *(rt_uint8_t **)(&buf_ins[2]) = RT_NULL; /* Pointer to TX buffer */
519 efm_spiSd_cs(1);
520 if (spi->write(spi, EFM32_NO_DATA, buf_ins, 0) != 0)
521 {
522 sdcard_debug("SPISD: Write token failed!\n");
523 break;
524 }
525
526 /* Initialize timer */
527 sdInTime = true;
528 rt_timer_start(sdTimer);
529 /* Wait for card ready */
530 do
531 {
532 efm_spiSd_read(buf_res, sizeof(buf_res));
533 } while (sdInTime && (buf_res[sizeof(buf_res) - 1] != 0xff));
534 if (buf_res[sizeof(buf_res) - 1] != 0xff)
535 {
536 sdcard_debug("SPISD: Card is busy after writing! (%x)\n", \
537 buf_res[sizeof(buf_res) - 1] );
538 ret = -RT_EBUSY;
539 break;
540 }
541 rt_timer_stop(sdTimer);
542 }
543
544 return RT_EOK;
545 } while(0);
546
547 sdcard_debug("SPISD: Write block failed!\n");
548 return ret;
549 }
550
551 /***************************************************************************//**
552 * @brief
553 * Wrapper function of send command to memory device
554 *
555 * @details
556 *
557 * @note
558 *
559 * @param[in] cmd
560 * Command index
561 *
562 * @param[in] arg
563 * Argument
564 *
565 * @param[in] trail
566 * Pointer to the buffer to store trailing data
567 *
568 * @return
569 * Command response
570 ******************************************************************************/
efm_spiSd_sendCmd(rt_uint8_t cmd,rt_uint32_t arg,rt_uint8_t * trail)571 rt_uint16_t efm_spiSd_sendCmd(
572 rt_uint8_t cmd,
573 rt_uint32_t arg,
574 rt_uint8_t *trail)
575 {
576 rt_uint16_t ret;
577
578 /* ACMD<n> is the command sequense of CMD55-CMD<n> */
579 if (cmd & 0x80)
580 {
581 cmd &= 0x7f;
582 ret = efm_spiSd_cmd(CMD55, 0x00000000, EFM32_NO_POINTER);
583 if (ret > 0x01)
584 {
585 return ret;
586 }
587 }
588
589 return efm_spiSd_cmd(cmd, arg, trail);
590 }
591
592 /***************************************************************************//**
593 * @brief
594 * Initialize memory card device
595 *
596 * @details
597 *
598 * @note
599 *
600 * @param[in] dev
601 * Pointer to device descriptor
602 *
603 * @return
604 * Error code
605 ******************************************************************************/
rt_spiSd_init(rt_device_t dev)606 static rt_err_t rt_spiSd_init(rt_device_t dev)
607 {
608 RT_ASSERT(spi != RT_NULL);
609
610 rt_uint8_t type, cmd, tril[4];
611 rt_uint8_t *buf_res;
612
613 type = 0;
614 buf_res = RT_NULL;
615
616 do
617 {
618 /* Create and setup timer */
619 if ((sdTimer = rt_timer_create(
620 "sd_tmr",
621 efm_spiSd_timer,
622 RT_NULL,
623 SD_WAIT_PERIOD,
624 RT_TIMER_FLAG_ONE_SHOT)) == RT_NULL)
625 {
626 sdcard_debug("SPISD: Create timer failed!\n");
627 break;
628 }
629
630 /* Open SPI device */
631 if (spi->open(spi, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
632 {
633 break;
634 }
635
636 /* Switch to low speed */
637 efm_spiSd_speed(SD_SPEED_LOW);
638
639 /* 80 dummy clocks */
640 efm_spiSd_read(RT_NULL, 80);
641 /* Enter Idle state */
642 if (efm_spiSd_sendCmd(CMD0, 0x00000000, EFM32_NO_POINTER) != 0x01)
643 {
644 break;
645 }
646 /* Check if SDv2 */
647 if (efm_spiSd_sendCmd(CMD8, 0x000001AA, tril) == 0x01)
648 {
649 /* SDv2, Vdd: 2.7-3.6V */
650 if (tril[2] == 0x01 && tril[3] == 0xAA)
651 {
652 /* Initialize timer */
653 sdInTime = true;
654 rt_timer_start(sdTimer);
655 /* Wait for leaving idle state (ACMD41 with HCS bit) */
656 while (efm_spiSd_sendCmd(ACMD41, 0x40000000, EFM32_NO_POINTER) \
657 && sdInTime);
658 /* Check CCS bit (bit 30) in the OCR */
659 if (sdInTime && efm_spiSd_sendCmd(CMD58, 0x00000000, tril) \
660 == 0x00)
661 {
662 type = (tril[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
663 }
664 }
665 }
666 else
667 {
668 if (efm_spiSd_sendCmd(ACMD41, 0x00000000, EFM32_NO_POINTER) <= 0x01)
669 {
670 /* SDv1 */
671 type = CT_SD1;
672 cmd = ACMD41;
673 }
674 else
675 {
676 /* MMCv3 */
677 type = CT_MMC;
678 cmd = CMD1;
679 }
680 /* Initialize timer */
681 sdInTime = true;
682 rt_timer_start(sdTimer);
683 /* Wait for leaving idle state */
684 while (efm_spiSd_sendCmd(cmd, 0x00000000, EFM32_NO_POINTER) && \
685 sdInTime);
686 /* Set read/write block length to SD_BLOCK_SIZE */
687 if (!sdInTime || \
688 (efm_spiSd_sendCmd(CMD16, SD_SECTOR_SIZE, EFM32_NO_POINTER) \
689 != 0x00))
690 {
691 type = 0;
692 break;
693 }
694 }
695 rt_timer_stop(sdTimer);
696
697 /* Check type */
698 sdType = type;
699 if (sdType)
700 {
701 /* Initialization succeded */
702 efm_spiSd_speed(SD_SPEED_HIGH);
703 }
704 else
705 {
706 break;
707 }
708
709 /* Allocate buffer */
710 if ((buf_res = rt_malloc(SD_SECTOR_SIZE)) == RT_NULL)
711 {
712 sdcard_debug("SPISD: No memory for sector buffer\n");
713 break;
714 }
715 /* Read the first sector for partition table */
716 if (dev->read(dev, 0, buf_res, 1) != 1)
717 {
718 sdcard_debug("SPISD: Read first sector failed!\n");
719 break;
720 }
721 /* Fetch the partition table */
722 if (dfs_filesystem_get_partition(&sdPart, buf_res, 0) != RT_EOK)
723 {
724 sdPart.offset = 0;
725 sdPart.size = 0;
726 sdcard_debug("SPISD: No partition table\n");
727 }
728 /* Release buffer */
729 rt_free(buf_res);
730 sdcard_debug("SPISD: Init OK, card type %x\n", sdType);
731 return RT_EOK;
732 } while (0);
733
734 /* Release buffer */
735 if (buf_res)
736 {
737 rt_free(buf_res);
738 }
739 efm_spiSd_deinit();
740 rt_kprintf("SPISD: Init failed!\n");
741 return -RT_ERROR;
742 }
743
744 /***************************************************************************//**
745 * @brief
746 * Open memory card device
747 *
748 * @details
749 *
750 * @note
751 *
752 * @param[in] dev
753 * Pointer to device descriptor
754 *
755 * @param[in] oflag
756 * Device open flag
757 *
758 * @return
759 * Error code
760 ******************************************************************************/
rt_spiSd_open(rt_device_t dev,rt_uint16_t oflag)761 static rt_err_t rt_spiSd_open(rt_device_t dev, rt_uint16_t oflag)
762 {
763 sdcard_debug("SPISD: Open, flag %x\n", sd_device.flag);
764 return RT_EOK;
765 }
766
767 /***************************************************************************//**
768 * @brief
769 * Close memory card device
770 *
771 * @details
772 *
773 * @note
774 *
775 * @param[in] dev
776 * Pointer to device descriptor
777 *
778 * @return
779 * Error code
780 ******************************************************************************/
rt_spiSd_close(rt_device_t dev)781 static rt_err_t rt_spiSd_close(rt_device_t dev)
782 {
783 sdcard_debug("SPISD: Close, flag %x\n", sd_device.flag);
784 return RT_EOK;
785 }
786
787 /***************************************************************************//**
788 * @brief
789 * Read from memory card device
790 *
791 * @details
792 *
793 * @note
794 *
795 * @param[in] dev
796 * Pointer to device descriptor
797 *
798 * @param[in] sector
799 * Start sector number (LBA)
800 *
801 * @param[in] buffer
802 * Pointer to the buffer
803 *
804 * @param[in] count
805 * Sector count (1..255)
806 *
807 * @return
808 * Number of read sectors
809 ******************************************************************************/
rt_spiSd_read(rt_device_t dev,rt_off_t sector,void * buffer,rt_size_t count)810 static rt_ssize_t rt_spiSd_read(
811 rt_device_t dev,
812 rt_off_t sector,
813 void *buffer,
814 rt_size_t count)
815 {
816 rt_uint8_t buf_ins[11], buf_res[12];
817 rt_uint8_t *ptr;
818 rt_uint8_t cmd, i;
819 rt_size_t cnt;
820
821 ptr = (rt_uint8_t *)buffer;
822 cnt = count;
823
824 sdcard_debug("SPISD: ****** Read Data ******\n");
825 if (!(sdType & CT_BLOCK))
826 {
827 /* Convert to byte address if needed */
828 sector *= SD_SECTOR_SIZE;
829 }
830
831 do
832 {
833 if (cnt == 1)
834 {
835 /* Single block read */
836 cmd = CMD17;
837 sdcard_debug("SPISD: Read single block\n");
838 }
839 else
840 {
841 /* Multiple block read */
842 cmd = CMD18;
843 sdcard_debug("SPISD: Read multiple blocks\n");
844 }
845
846 if (efm_spiSd_sendCmd(cmd, sector, EFM32_NO_POINTER))
847 {
848 sdcard_debug("SPISD: Read command error!\n");
849 break;
850 }
851
852 /* Read data */
853 do
854 {
855 if (efm_spiSd_readBlock(ptr, SD_SECTOR_SIZE))
856 {
857 break;
858 }
859 ptr += SD_SECTOR_SIZE;
860 } while(--cnt);
861
862 /* Stop transmission */
863 if (cmd == CMD18)
864 {
865 if (efm_spiSd_sendCmd(CMD12, 0x00000000, EFM32_NO_POINTER))
866 {
867 break;
868 }
869 }
870
871 return (count);
872 } while(0);
873
874 return (0);
875 }
876
877 /***************************************************************************//**
878 * @brief
879 * Write to memory card device
880 *
881 * @details
882 *
883 * @note
884 *
885 * @param[in] dev
886 * Pointer to device descriptor
887 *
888 * @param[in] sector
889 * Start sector number (LBA)
890 *
891 * @param[in] buffer
892 * Pointer to the buffer
893 *
894 * @param[in] count
895 * Sector count (1..255)
896 *
897 * @return
898 * Number of written sectors
899 ******************************************************************************/
rt_spiSd_write(rt_device_t dev,rt_off_t sector,const void * buffer,rt_size_t count)900 static rt_ssize_t rt_spiSd_write (
901 rt_device_t dev,
902 rt_off_t sector,
903 const void *buffer,
904 rt_size_t count)
905 {
906 rt_uint8_t buf_ins[11], buf_res[12];
907 rt_uint8_t *ptr;
908 rt_uint8_t cmd, token, i;
909 rt_size_t cnt;
910
911 ptr = (rt_uint8_t *)buffer;
912 cnt = count;
913
914 sdcard_debug("SPISD: ****** Write Data ******\n");
915 if (!(sdType & CT_BLOCK))
916 {
917 /* Convert to byte address if needed */
918 sector *= SD_SECTOR_SIZE;
919 }
920
921 do
922 {
923 if (cnt == 1)
924 {
925 /* Single block write */
926 cmd = CMD24;
927 token = 0xfe;
928 sdcard_debug("SPISD: Write single block\n");
929 }
930 else
931 {
932 /* Multiple block write */
933 cmd = CMD25;
934 token = 0xfc;
935 sdcard_debug("SPISD: Write multiple blocks\n");
936 if (sdType & CT_SDC)
937 {
938 if (efm_spiSd_sendCmd(ACMD23, count, EFM32_NO_POINTER))
939 {
940 break;
941 }
942 }
943 }
944
945 if (efm_spiSd_sendCmd(cmd, sector, EFM32_NO_POINTER))
946 {
947 sdcard_debug("SPISD: Write command error!\n");
948 break;
949 }
950
951 /* Write data */
952 do
953 {
954 if (efm_spiSd_writeBlock(ptr, token))
955 {
956 break;
957 }
958 ptr += SD_SECTOR_SIZE;
959 } while(--cnt);
960
961 /* Stop transmission token */
962 if (efm_spiSd_writeBlock(EFM32_NO_POINTER, 0xfd))
963 {
964 break;
965 }
966
967 return (count);
968 } while(0);
969
970 return (0);
971 }
972
973 /***************************************************************************//**
974 * @brief
975 * Configure memory card device
976 *
977 * @details
978 *
979 * @note
980 *
981 * @param[in] dev
982 * Pointer to device descriptor
983 *
984 * @param[in] ctrl
985 * Memory card control command
986 *
987 * @param[in] buffer
988 * Pointer to the buffer of in/out data
989 *
990 * @return
991 * Error code
992 ******************************************************************************/
rt_spiSd_control(rt_device_t dev,rt_uint8_t ctrl,void * buffer)993 static rt_err_t rt_spiSd_control (
994 rt_device_t dev,
995 rt_uint8_t ctrl,
996 void *buffer)
997 {
998 rt_err_t ret;
999 rt_uint32_t c_size;
1000 rt_uint8_t n;
1001 rt_uint8_t *buf_res;
1002
1003 ret = -RT_ERROR;
1004 buf_res = RT_NULL;
1005 switch (ctrl)
1006 {
1007 case RT_DEVICE_CTRL_SD_SYNC:
1008 /* Flush dirty buffer if present */
1009 efm_spiSd_cs(1);
1010 efm_spiSd_cs(0);
1011 ret = RT_EOK;
1012 break;
1013
1014 case RT_DEVICE_CTRL_SD_GET_SCOUNT:
1015 {
1016 /* Allocate buffer */
1017 if ((buf_res = rt_malloc(SD_BLOCK_SIZE_CSD)) == RT_NULL)
1018 {
1019 sdcard_debug("SPISD: No memory for RX buffer\n");
1020 break;
1021 }
1022 /* Get number of sectors on the disk (32 bits) */
1023 if (efm_spiSd_sendCmd(CMD9, 0x00000000, buf_res))
1024 {
1025 sdcard_debug("SPISD: Get CSD failed!\n");
1026 break;
1027 }
1028
1029 if ((buf_res[0] >> 6) == 0x01)
1030 {
1031 /* SDv2 */
1032 /* C_SIZE: Bit 48~69 */
1033 c_size = ((rt_uint32_t)(buf_res[7] & 0x3f) << 16) + \
1034 ((rt_uint32_t)buf_res[8] << 8) + buf_res[9] + 1;
1035 /* Result = Capacity / Sector Size */
1036 *(rt_uint32_t *)buffer = (rt_uint32_t)c_size << \
1037 (19 - SD_SECTOR_SIZE_SHIFT);
1038 }
1039 else
1040 {
1041 /* SDv1 or MMC */
1042 /* C_SIZE: Bit 62~73 */
1043 c_size = ((rt_uint32_t)(buf_res[6] & 0x03) << 10) + \
1044 ((rt_uint16_t)buf_res[7] << 2) + (buf_res[8] >> 6) + 1;
1045 /* READ_BL_LEN: Bit 80~83, C_SIZE_MULT: Bit 47~49 */
1046 n = ((buf_res[9] & 0x03) << 1) + ((buf_res[10] & 0x80) >> 7) + \
1047 2 + (buf_res[5] & 0x0f);
1048 /* Result = Capacity / Sector Size */
1049 *(rt_uint32_t *)buffer = (rt_uint32_t)c_size << \
1050 (n - SD_SECTOR_SIZE_SHIFT);
1051 }
1052 ret = RT_EOK;
1053 break;
1054 }
1055
1056 case RT_DEVICE_CTRL_SD_GET_SSIZE:
1057 /* Get sectors on the disk (16 bits) */
1058 *(rt_uint16_t *)buffer = SD_SECTOR_SIZE;
1059 ret = RT_EOK;
1060 break;
1061
1062 case RT_DEVICE_CTRL_SD_GET_BSIZE:
1063 /* Get erase block size in unit of sectors (32 bits) */
1064 if (sdType & CT_SD2)
1065 {
1066 /* Allocate buffer */
1067 if ((buf_res = rt_malloc(SD_BLOCK_SIZE_SDSTAT)) == RT_NULL)
1068 {
1069 sdcard_debug("SPISD: No memory for RX buffer\n");
1070 break;
1071 }
1072 /* SDv2 */
1073 if (efm_spiSd_sendCmd(ACMD13, 0x00000000, EFM32_NO_POINTER))
1074 {
1075 sdcard_debug("SPISD: Get SD status failed!\n");
1076 break;
1077 }
1078 if (efm_spiSd_readBlock(buf_res, SD_BLOCK_SIZE_SDSTAT))
1079 {
1080 sdcard_debug("SPISD: Read SD status failed!\n");
1081 break;
1082 }
1083 /* AU_SIZE: Bit 428~431 */
1084 *(rt_uint32_t *)buffer = 16UL << ((buf_res[10] >> 4) + 9 - \
1085 SD_SECTOR_SIZE_SHIFT);
1086 }
1087 else
1088 {
1089 /* Allocate buffer */
1090 if ((buf_res = rt_malloc(SD_BLOCK_SIZE_CSD)) == RT_NULL)
1091 {
1092 sdcard_debug("SPISD: No memory for RX buffer\n");
1093 break;
1094 }
1095 /* SDv1 or MMC */
1096 if (efm_spiSd_sendCmd(CMD9, 0x00000000, buf_res))
1097 {
1098 sdcard_debug("SPISD: Get CSD failed!\n");
1099 break;
1100 }
1101
1102 if (sdType & CT_SD1)
1103 {
1104 /* SECTOR_SIZE: Bit 39~45, WRITE_BL_LEN: Bit 22~25 (9, 10 or 11) */
1105 *(rt_uint32_t *)buffer = (((buf_res[10] & 0x3f) << 1) + \
1106 ((rt_uint32_t)(buf_res[11] & 0x80) >> 7) + 1) << \
1107 (8 + (buf_res[13] >> 6) - SD_SECTOR_SIZE_SHIFT);
1108 }
1109 else
1110 {
1111 /* ERASE_GRP_SIZE: Bit 42~46, ERASE_GRP_MULT: Bit 37~41 */
1112 *(rt_uint32_t *)buffer = \
1113 ((rt_uint16_t)((buf_res[10] & 0x7c) >> 2) + 1) * \
1114 (((buf_res[10] & 0x03) << 3) + \
1115 ((buf_res[11] & 0xe0) >> 5) + 1);
1116 }
1117 }
1118 ret = RT_EOK;
1119 break;
1120
1121 case RT_DEVICE_CTRL_SD_GET_TYPE:
1122 /* Get card type flags (1 byte) */
1123 *(rt_uint8_t *)buffer = sdType;
1124 ret = RT_EOK;
1125 break;
1126
1127 case RT_DEVICE_CTRL_SD_GET_CSD:
1128 /* Receive CSD as a data block (16 bytes) */
1129 if (efm_spiSd_sendCmd(CMD9, 0x00000000, buffer))
1130 {
1131 sdcard_debug("SPISD: Get CSD failed!\n");
1132 break;
1133 }
1134 ret = RT_EOK;
1135 break;
1136
1137 case RT_DEVICE_CTRL_SD_GET_CID:
1138 /* Receive CID as a data block (16 bytes) */
1139 if (efm_spiSd_sendCmd(CMD10, 0x00000000, buffer))
1140 {
1141 sdcard_debug("SPISD: Get CID failed!\n");
1142 break;
1143 }
1144 ret = RT_EOK;
1145 break;
1146
1147 case RT_DEVICE_CTRL_SD_GET_OCR:
1148 /* Receive OCR as an R3 resp (4 bytes) */
1149 if (efm_spiSd_sendCmd(CMD58, 0x00000000, buffer))
1150 {
1151 sdcard_debug("SPISD: Get OCR failed!\n");
1152 break;
1153 }
1154 ret = RT_EOK;
1155 break;
1156
1157 case RT_DEVICE_CTRL_SD_GET_SDSTAT:
1158 /* Receive SD statsu as a data block (64 bytes) */
1159 if (efm_spiSd_sendCmd(ACMD13, 0x00000000, buffer))
1160 {
1161 sdcard_debug("SPISD: Get SD status failed!\n");
1162 break;
1163 }
1164 if (efm_spiSd_readBlock(buffer, SD_BLOCK_SIZE_SDSTAT))
1165 {
1166 sdcard_debug("SPISD: Read SD status failed!\n");
1167 break;
1168 }
1169 ret = RT_EOK;
1170 break;
1171
1172 default:
1173 break;
1174 }
1175
1176 if (buf_res)
1177 {
1178 rt_free(buf_res);
1179 }
1180 return ret;
1181 }
1182
1183 /***************************************************************************//**
1184 * @brief
1185 * Initialize all memory card related hardware and register the device to
1186 * kernel
1187 *
1188 * @details
1189 *
1190 * @note
1191 *
1192 * @return
1193 * Error code
1194 ******************************************************************************/
efm_spiSd_init(void)1195 rt_err_t efm_spiSd_init(void)
1196 {
1197 struct efm32_usart_device_t *usart;
1198
1199 do
1200 {
1201 /* Find SPI device */
1202 spi = rt_device_find(SPISD_USING_DEVICE_NAME);
1203 if (spi == RT_NULL)
1204 {
1205 sdcard_debug("SPISD: Can't find device %s!\n",
1206 SPISD_USING_DEVICE_NAME);
1207 break;
1208 }
1209 sdcard_debug("SPISD: Find device %s\n", SPISD_USING_DEVICE_NAME);
1210
1211 /* Config chip slect pin */
1212 usart = (struct efm32_usart_device_t *)(spi->user_data);
1213 if (!(usart->state & USART_STATE_AUTOCS))
1214 {
1215 GPIO_PinModeSet(SD_CS_PORT, SD_CS_PIN, gpioModePushPull, 1);
1216 sdAutoCs = false;
1217 }
1218
1219 /* Register SPI SD device */
1220 sd_device.type = RT_Device_Class_MTD;
1221 sd_device.init = rt_spiSd_init;
1222 sd_device.open = rt_spiSd_open;
1223 sd_device.close = rt_spiSd_close;
1224 sd_device.read = rt_spiSd_read;
1225 sd_device.write = rt_spiSd_write;
1226 sd_device.control = rt_spiSd_control;
1227 sd_device.user_data = RT_NULL;
1228 rt_device_register(
1229 &sd_device,
1230 SPISD_DEVICE_NAME,
1231 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
1232
1233 sdcard_debug("SPISD: HW init OK, card type %x\n", sdType);
1234 return RT_EOK;
1235 } while (0);
1236
1237 /* Release buffer */
1238 rt_kprintf("SPISD: HW init failed!\n");
1239 return -RT_ERROR;
1240 }
1241
1242 /***************************************************************************//**
1243 * @brief
1244 * De-initialize memory card device
1245 *
1246 * @details
1247 *
1248 * @note
1249 ******************************************************************************/
efm_spiSd_deinit(void)1250 void efm_spiSd_deinit(void)
1251 {
1252 /* Close SPI device */
1253 if (spi != RT_NULL)
1254 {
1255 spi->close(spi);
1256 spi = RT_NULL;
1257 sdcard_debug("SPISD: Close device %s\n", SPISD_USING_DEVICE_NAME);
1258 }
1259 /* Delete timer */
1260 if (sdTimer != RT_NULL)
1261 {
1262 rt_timer_delete(sdTimer);
1263 sdTimer = RT_NULL;
1264 sdcard_debug("SPISD: Delete timer\n");
1265 }
1266
1267 sdcard_debug("SPISD: Deinit OK\n");
1268 }
1269
1270 /*******************************************************************************
1271 * Export to FINSH
1272 ******************************************************************************/
1273 #ifdef RT_USING_FINSH
1274 #include <finsh.h>
1275
list_sd(void)1276 void list_sd(void)
1277 {
1278 rt_uint8_t buf_res[16];
1279 rt_uint32_t capacity, temp32;
1280 rt_uint16_t temp16;
1281
1282 rt_kprintf(" SD Card on %s\n", SPISD_USING_DEVICE_NAME);
1283 rt_kprintf(" ------------------------------\n");
1284 sd_device.control(&sd_device, RT_DEVICE_CTRL_SD_GET_CID, buf_res);
1285 rt_kprintf(" Manufacturer ID:\t%x\n", buf_res[0]);
1286 rt_kprintf(" OEM/Application ID:\t%x%x\n", buf_res[1], buf_res[2]);
1287 rt_kprintf(" Product revision:\t%x\n", buf_res[8]);
1288 buf_res[8] = 0;
1289 rt_kprintf(" Product name:\t\t%s\n", &buf_res[3]);
1290 rt_kprintf(" Serial number:\t\t%x%x%x%x\n", \
1291 buf_res[9], buf_res[10], buf_res[11], buf_res[12]);
1292 rt_kprintf(" Manufacturing date:\t%d.%d\n", \
1293 2000 + ((buf_res[13] & 0x0F) << 4) + ((buf_res[14] & 0xF0) >> 4), \
1294 buf_res[14] & 0x0F);
1295 rt_kprintf(" Card type:\t\t");
1296 sd_device.control(&sd_device, RT_DEVICE_CTRL_SD_GET_TYPE, buf_res);
1297 if (buf_res[0] == CT_MMC)
1298 {
1299 rt_kprintf("%s\n", "MMC");
1300 }
1301 else if (buf_res[0] == CT_SDC)
1302 {
1303 rt_kprintf("%s\n", "SDXC");
1304 }
1305 else if (buf_res[0] == CT_SD1)
1306 {
1307 rt_kprintf("%s\n", "SDSC");
1308 }
1309 else if (buf_res[0] == CT_SD2)
1310 {
1311 rt_kprintf("%s\n", "SDHC");
1312 }
1313 sd_device.control(&sd_device, RT_DEVICE_CTRL_SD_GET_SSIZE, &temp16);
1314 sd_device.control(&sd_device, RT_DEVICE_CTRL_SD_GET_SCOUNT, &temp32);
1315 capacity = ((temp32 & 0x0000FFFF) * temp16) >> 16;
1316 capacity += ((temp32 >> 16) * temp16);
1317 capacity >>= 4;
1318 rt_kprintf(" Card capacity:\t\t%dMB\n", capacity);
1319 }
1320 FINSH_FUNCTION_EXPORT(list_sd, list the SD card.)
1321 #endif
1322
1323 #endif /* defined(EFM32_USING_SPISD) */
1324 /***************************************************************************//**
1325 * @}
1326 ******************************************************************************/
1327