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