support SDHC in mini2440
contributed by amr168 git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2498 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
bcc4893d23
commit
7672426550
@ -11,6 +11,7 @@
|
||||
* Date Author Notes
|
||||
* 2007-12-02 Yi.Qiu the first version
|
||||
* 2010-01-01 Bernard Modify for mini2440
|
||||
* 2012-12-15 amr168 support SDHC
|
||||
*/
|
||||
|
||||
#include "sdcard.h"
|
||||
@ -19,6 +20,7 @@ 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;
|
||||
|
||||
static void sd_delay(rt_uint32_t ms)
|
||||
{
|
||||
@ -53,7 +55,7 @@ static int sd_cmd_end(int cmd, int be_resp)
|
||||
if ((finish0 & 0xf00) != 0xa00)
|
||||
{
|
||||
SDICSTA = finish0;
|
||||
if(((finish0&0x400)==0x400))
|
||||
if ((finish0&0x400) == 0x400)
|
||||
return RT_ERROR;
|
||||
}
|
||||
SDICSTA = finish0;
|
||||
@ -62,12 +64,9 @@ static int sd_cmd_end(int cmd, int be_resp)
|
||||
{
|
||||
if ((finish0 & 0x1f00) != 0xa00)
|
||||
{
|
||||
/*
|
||||
rt_kprintf("CMD%d:SDICSTA=0x%x, SDIRSP0=0x%x\n",
|
||||
cmd, SDICSTA, SDIRSP0);
|
||||
*/
|
||||
/* rt_kprintf("CMD%d:SDICSTA=0x%x, SDIRSP0=0x%x\n", cmd, SDICSTA, SDIRSP0); */
|
||||
SDICSTA = finish0;
|
||||
if(((finish0&0x400)==0x400))
|
||||
if ((finish0 & 0x400) == 0x400)
|
||||
return RT_ERROR;
|
||||
}
|
||||
SDICSTA = finish0;
|
||||
@ -90,8 +89,10 @@ static int sd_data_end(void)
|
||||
if ((finish & 0xfc) != 0x10)
|
||||
{
|
||||
SDIDSTA = 0xec;
|
||||
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
@ -116,6 +117,7 @@ static int sd_cmd55(void)
|
||||
}
|
||||
|
||||
SDICSTA = 0xa00;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
@ -161,28 +163,50 @@ static void sd_setbus(void)
|
||||
|
||||
static int sd_ocr(void)
|
||||
{
|
||||
int i;
|
||||
int i, ver=0;
|
||||
|
||||
/* Negotiate operating condition for SD, it makes card ready state */
|
||||
for (i = 0; i < 50; i ++)
|
||||
{
|
||||
sd_cmd55();
|
||||
|
||||
SDICARG=0xff8000;
|
||||
SDICARG = 0x40ff8000; /* HCS=1, compatible v1.x and v2.0 */
|
||||
SDICCON = (0x1<<9) | (0x1<<8) | 0x69;
|
||||
|
||||
/* if using real board, should replace code here. need to modify qemu in near future*/
|
||||
/* Check end of ACMD41 */
|
||||
if( (sd_cmd_end(41, 1)==RT_EOK) & SDIRSP0==0x80ff8000 )
|
||||
if (sd_cmd_end(41, 1) == RT_EOK)
|
||||
{
|
||||
SDICSTA=0xa00;
|
||||
return RT_EOK;
|
||||
if (SDIRSP0 == 0x80ff8000)
|
||||
{
|
||||
ver = 1; /* SD V1.x, CCS=0 */
|
||||
break;
|
||||
}
|
||||
else if (SDIRSP0 == 0xc0ff8000)
|
||||
{
|
||||
ver = 2; /* SD V2.0, CCS=1 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sd_delay(200);
|
||||
}
|
||||
SDICSTA = 0xa00;
|
||||
|
||||
return ver;
|
||||
}
|
||||
|
||||
rt_err_t sd_cmd8(void)
|
||||
{
|
||||
SDICARG = 0x000001AA;
|
||||
SDICCON = (0x1<<9) | (0x1<<8) | 0x48; //sht_resp, wait_resp, start
|
||||
if (sd_cmd_end(8, 1) == RT_ERROR)
|
||||
return RT_ERROR;
|
||||
SDICSTA = 0xa00;
|
||||
|
||||
if ((SDIRSP0&0x1aa) == 0x1aa)
|
||||
return RT_EOK;
|
||||
else
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
@ -202,15 +226,18 @@ static rt_uint8_t sd_init(void)
|
||||
for (i = 0; i < 0x1000; i ++);
|
||||
|
||||
sd_cmd0();
|
||||
sd_cmd8(); /* Must be use it, Host shall supports high capacity */
|
||||
|
||||
/* Check SD card OCR */
|
||||
if(sd_ocr() == RT_EOK)
|
||||
sd_type = sd_ocr();
|
||||
if (sd_type > 0)
|
||||
{
|
||||
rt_kprintf("In SD ready\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Initialize fail\nNo Card assertion\n");
|
||||
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
@ -280,6 +307,7 @@ RERDCMD:
|
||||
if (sd_data_end() == RT_ERROR)
|
||||
{
|
||||
rt_kprintf("Dat error\n");
|
||||
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
@ -296,6 +324,7 @@ static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf)
|
||||
|
||||
wt_cnt = 0;
|
||||
SDIFSTA = SDIFSTA | (1 << 16);
|
||||
|
||||
SDIDCON = (2 << 22) | (1 << 20) | (1 << 17) | (1 << 16) | (1 << 14) | (3 << 12) | (1 << 0);
|
||||
SDICARG = address;
|
||||
|
||||
@ -307,7 +336,7 @@ REWTCMD:
|
||||
|
||||
SDICSTA = 0xa00;
|
||||
|
||||
while(wt_cnt < 128*1)
|
||||
while (wt_cnt < 128)
|
||||
{
|
||||
status = SDIFSTA;
|
||||
if ((status & 0x2000) == 0x2000)
|
||||
@ -321,6 +350,7 @@ REWTCMD:
|
||||
if (sd_data_end() == RT_ERROR)
|
||||
{
|
||||
rt_kprintf("Data Error\n");
|
||||
|
||||
return RT_ERROR;
|
||||
}
|
||||
SDIDCON = SDIDCON &~ (7<<12);
|
||||
@ -358,14 +388,18 @@ static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||
static rt_size_t rt_sdcard_read(rt_device_t dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
int i;
|
||||
int i, addr;
|
||||
struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
|
||||
|
||||
if (dev == RT_NULL)
|
||||
{
|
||||
rt_set_errno(-DFS_STATUS_EINVAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -373,8 +407,11 @@ static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_
|
||||
for (i = 0; i < size; i ++)
|
||||
{
|
||||
rt_sem_take(part->lock, RT_WAITING_FOREVER);
|
||||
sd_readblock((part->offset + i + pos)*SECTOR_SIZE,
|
||||
(rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
|
||||
if (sd_type == 1)
|
||||
addr = (part->offset + i + pos)*SECTOR_SIZE;
|
||||
else
|
||||
addr = (part->offset + i + pos);
|
||||
sd_readblock(addr, (rt_uint8_t *)((rt_uint8_t *)buffer + i * SECTOR_SIZE));
|
||||
rt_sem_release(part->lock);
|
||||
}
|
||||
|
||||
@ -382,14 +419,18 @@ static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_
|
||||
return size;
|
||||
}
|
||||
|
||||
static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||
static rt_size_t rt_sdcard_write(rt_device_t dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
int i;
|
||||
int i, addr;
|
||||
struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
|
||||
|
||||
if (dev == RT_NULL)
|
||||
{
|
||||
rt_set_errno(-DFS_STATUS_EINVAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -397,8 +438,11 @@ static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buf
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
rt_sem_take(part->lock, RT_WAITING_FOREVER);
|
||||
sd_writeblock((part->offset + i + pos)*SECTOR_SIZE,
|
||||
(rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
|
||||
if (sd_type == 1)
|
||||
addr = (part->offset + i + pos)*SECTOR_SIZE;
|
||||
else
|
||||
addr = (part->offset + i + pos);
|
||||
sd_writeblock(addr, (rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
|
||||
rt_sem_release(part->lock);
|
||||
}
|
||||
|
||||
@ -429,6 +473,7 @@ void rt_hw_sdcard_init(void)
|
||||
if (sector == RT_NULL)
|
||||
{
|
||||
rt_kprintf("allocate partition sector buffer failed\n");
|
||||
|
||||
return;
|
||||
}
|
||||
status = sd_readblock(0, sector);
|
||||
|
Loading…
x
Reference in New Issue
Block a user