1
0
Эх сурвалжийг харах

add csd support for mini2440 sdio driver.

kuangdazzidd 7 жил өмнө
parent
commit
c3e2f6a568
1 өөрчлөгдсөн 110 нэмэгдсэн , 10 устгасан
  1. 110 10
      bsp/mini2440/drivers/sdcard.c

+ 110 - 10
bsp/mini2440/drivers/sdcard.c

@@ -8,19 +8,26 @@
  * http://www.rt-thread.org/license/LICENSE
  *
  * Change Logs:
- * Date           Author      Notes
- * 2007-12-02     Yi.Qiu      the first version
- * 2010-01-01     Bernard     Modify for mini2440
- * 2012-12-15     amr168      support SDHC
+ * Date           Author        Notes
+ * 2007-12-02     Yi.Qiu        the first version
+ * 2010-01-01     Bernard       Modify for mini2440
+ * 2012-12-15     amr168        support SDHC
+ * 2017-11-20     kuangdazzidd  add csd cmd support
  */
 
 #include "sdcard.h"
+#include "rtdef.h"
 
-extern rt_uint32_t PCLK;
-volatile rt_uint32_t rd_cnt;
-volatile rt_uint32_t wt_cnt;
-volatile rt_int32_t RCA;
-volatile rt_int32_t sd_type;
+extern   rt_uint32_t   PCLK;
+volatile rt_uint32_t   rd_cnt;
+volatile rt_uint32_t   wt_cnt;
+volatile rt_int32_t    RCA;
+volatile rt_int32_t    sd_type;
+
+struct sd_csd {
+    rt_uint16_t    bsize;
+    rt_uint32_t    nblks;
+}g_sd_csd;
 
 static void sd_delay(rt_uint32_t ms)
 {
@@ -118,9 +125,25 @@ static int sd_cmd55(void)
 
     SDICSTA = 0xa00;
 
+
     return RT_EOK;
 }
 
+static int sd_cmd9(void *p_rsp)
+{
+SDICARG = RCA << 16;
+SDICCON = (1 << 10) | (1 << 9) | (0x1<<8) | (0x40 | 0x09);
+
+sd_cmd_end(9, 1);
+
+    ((rt_uint32_t *)p_rsp)[0] = SDIRSP3;
+    ((rt_uint32_t *)p_rsp)[1] = SDIRSP2;
+    ((rt_uint32_t *)p_rsp)[2] = SDIRSP1;
+    ((rt_uint32_t *)p_rsp)[3] = SDIRSP0;
+
+return RT_EOK;
+}
+
 static void sd_sel_desel(char sel_desel)
 {
     if (sel_desel)
@@ -161,6 +184,75 @@ static void sd_setbus(void)
     SDICSTA=0xa00;      /* Clear cmd_end(with rsp) */
 }
 
+
+static rt_uint32_t bits_str (rt_uint32_t *str, rt_uint32_t start, rt_uint8_t len)
+{
+    rt_uint32_t  mask;
+    rt_uint32_t  index;
+    rt_uint8_t   shift;
+    rt_uint32_t  value;
+
+    mask  = (int)((len < 32) ? (1 << len) : 0) - 1;
+    index = start / 32;
+    shift = start & 31;
+    value = str[index] >> shift;
+
+    if ((len + shift) > 32) {
+        value |= str[index + 1] << (32 - shift);
+    }
+    value &= mask;
+    return value;
+}
+
+
+static int sd_decode_csd (rt_uint32_t  *p_csd)
+{
+    rt_uint32_t e, m, r;
+    rt_uint8_t  structure;
+
+    structure = bits_str(p_csd, 126, 2);
+
+    switch (structure) {
+        case 0:
+            m = bits_str(p_csd, 99, 4);
+            e = bits_str(p_csd, 96, 3);
+            g_sd_csd.bsize  = 512;
+            m = bits_str(p_csd, 62, 12);
+            e = bits_str(p_csd, 47, 3);
+            r = bits_str(p_csd, 80, 4);
+            g_sd_csd.nblks = ((1 + m) << (e + r - 7));
+            break;
+
+        case 1:
+            m = bits_str(p_csd, 99, 4);
+            e = bits_str(p_csd, 96, 3);
+            g_sd_csd.bsize  = 512;
+            m = bits_str(p_csd, 48, 22);
+            g_sd_csd.nblks = (1 + m) << 10;
+            break;
+
+        default:
+            return RT_ERROR;
+    }
+    return RT_EOK;
+}
+
+
+static int sd_send_csd(rt_uint32_t  *p_csd)
+{
+    int         ret;
+    rt_uint32_t rsp[4];
+
+    ret = sd_cmd9((void*)&rsp);
+
+    if (ret != 0) {
+        return ret;
+    }
+
+    rt_memcpy((void*)p_csd, (void*)rsp, 16);
+    return RT_EOK;
+}
+
 static int sd_ocr(void)
 {
     int i, ver=0;
@@ -213,7 +305,8 @@ rt_err_t sd_cmd8(void)
 static rt_uint8_t sd_init(void)
 {
     //-- SD controller & card initialize
-    int i;
+    int         i;
+    rt_uint32_t csd[4];
     /* Important notice for MMC test condition */
     /* Cmd & Data lines must be enabled by pull up resister */
     SDIPRE    = PCLK / (INICLK) - 1;
@@ -256,6 +349,9 @@ RECMD3:
         goto RECMD3;
     SDICSTA=0xa00;  /* Clear cmd_end(with rsp) */
 
+    sd_send_csd(csd);
+    sd_decode_csd(csd);
+
     RCA = (SDIRSP0 & 0xffff0000) >> 16;
     SDIPRE = PCLK / (SDCLK) - 1; /* Normal clock=25MHz */
     if (SDIRSP0 & 0x1e00 != 0x600)
@@ -385,6 +481,10 @@ static rt_err_t rt_sdcard_close(rt_device_t dev)
 
 static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
 {
+struct rt_device_blk_geometry *p_geometry = (struct rt_device_blk_geometry *)args;
+p_geometry->block_size = g_sd_csd.bsize;
+p_geometry->sector_count = g_sd_csd.nblks;
+p_geometry->bytes_per_sector = 512;
     return RT_EOK;
 }