337 lines
7.6 KiB
C
337 lines
7.6 KiB
C
|
|
#include "sys_config.h"
|
||
|
|
#include "typesdef.h"
|
||
|
|
#include "devid.h"
|
||
|
|
#include "list.h"
|
||
|
|
#include "dev.h"
|
||
|
|
|
||
|
|
#include "hal/gpio.h"
|
||
|
|
#include "osal/irq.h"
|
||
|
|
#include "osal/string.h"
|
||
|
|
#include "osal/semaphore.h"
|
||
|
|
#include "osal/mutex.h"
|
||
|
|
#include "osal/mutex.h"
|
||
|
|
#include "osal/irq.h"
|
||
|
|
#include "osal/task.h"
|
||
|
|
#include "osal/sleep.h"
|
||
|
|
#include "osal/timer.h"
|
||
|
|
#include "osal/work.h"
|
||
|
|
|
||
|
|
#include "lib/sdhost/sdhost.h"
|
||
|
|
#include "lib/sdhost/mmc.h"
|
||
|
|
#include "lib/sdhost/mmc_ops.h"
|
||
|
|
|
||
|
|
#include "fatfs/integer.h"
|
||
|
|
#include "fatfs/diskio.h"
|
||
|
|
#include "fatfs/ff.h"
|
||
|
|
|
||
|
|
#if 0
|
||
|
|
#define MMCFS_PRIN(fmt, arg...) printf(fmt, ##arg)
|
||
|
|
#else
|
||
|
|
#define MMCFS_PRIN(fmt, arg...)
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
static DSTATUS fatfs_status(void *status);
|
||
|
|
static DSTATUS fatfs_init(void *init_dev);
|
||
|
|
static DRESULT fatfs_read(void *dev, BYTE* buf, DWORD sector, UINT count);
|
||
|
|
static DRESULT fatfs_write(void *dev, BYTE* buf, DWORD sector, UINT count);
|
||
|
|
static DRESULT fatfs_ioctl(void *init_dev, BYTE cmd, void* buf);
|
||
|
|
void mmc_fatfs_unregister(uint32_t dev_id);
|
||
|
|
int mmc_fatfs_register(uint32_t dev_id);
|
||
|
|
uint32_t get_sdhost_status(struct sdh_device *host);
|
||
|
|
uint32_t sd_tran_stop(struct sdh_device * host);
|
||
|
|
|
||
|
|
extern void sdhost_io_func_init(uint32 req);
|
||
|
|
extern uint32 sd_power_up(struct sdh_device *host,uint8 bus_w);
|
||
|
|
extern void sd_set_clk(struct sdh_device * host,uint32 clk);
|
||
|
|
|
||
|
|
|
||
|
|
static struct os_work host_wk = {
|
||
|
|
.running=0
|
||
|
|
};
|
||
|
|
|
||
|
|
static int32 sdh_loop(struct os_work *work)
|
||
|
|
{
|
||
|
|
struct sdh_device *host = NULL;
|
||
|
|
host = (struct sdh_device *)dev_get(HG_SDIOHOST_DEVID);
|
||
|
|
static uint8_t opt = SD_IDLE;
|
||
|
|
static uint32_t lba = 0;
|
||
|
|
static uint8_t flag = 0;
|
||
|
|
static uint8_t count = 0;
|
||
|
|
uint32_t sleep_time = 500;
|
||
|
|
uint32 ret;
|
||
|
|
|
||
|
|
if(SD_OFF == host->sd_opt)
|
||
|
|
{
|
||
|
|
os_printf("sdh no online2\r\n");
|
||
|
|
if(flag == 1)
|
||
|
|
{
|
||
|
|
flag = 0;
|
||
|
|
os_mutex_del(&host->lock);
|
||
|
|
mmc_fatfs_unregister(HG_SDIOHOST_DEVID);
|
||
|
|
}
|
||
|
|
|
||
|
|
//判断状态,是否重新挂在文件系统
|
||
|
|
mmc_fatfs_register(HG_SDIOHOST_DEVID);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ret = os_mutex_lock(&host->lock,0);
|
||
|
|
if(ret)
|
||
|
|
{
|
||
|
|
sleep_time = 1;
|
||
|
|
//获取锁失败
|
||
|
|
goto sdh_loop_end;
|
||
|
|
}
|
||
|
|
if(SD_IDLE != host->sd_opt)
|
||
|
|
{
|
||
|
|
if((opt != host->sd_opt)||(lba != host->new_lba))
|
||
|
|
{
|
||
|
|
opt = host->sd_opt;
|
||
|
|
lba = host->new_lba;
|
||
|
|
count = 0;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
count++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
ret = send_card_status(host);
|
||
|
|
if(ret != 0)
|
||
|
|
{
|
||
|
|
host->sd_opt = SD_OFF;
|
||
|
|
count = 0;
|
||
|
|
flag = 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(count >= 2){
|
||
|
|
count = 0;
|
||
|
|
sd_tran_stop(host);
|
||
|
|
}
|
||
|
|
os_mutex_unlock(&host->lock);
|
||
|
|
}
|
||
|
|
sdh_loop_end:
|
||
|
|
os_run_work_delay(work, sleep_time);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int mmc_init(struct sdh_device * host, uint32_t clk)
|
||
|
|
{
|
||
|
|
uint32_t ret;
|
||
|
|
uint32_t ocr;
|
||
|
|
uint8_t bw = 1;
|
||
|
|
uint8_t *ext_csd = NULL;
|
||
|
|
|
||
|
|
|
||
|
|
if(((const struct sdhc_hal_ops *)host->dev.ops)->open)
|
||
|
|
((const struct sdhc_hal_ops *)host->dev.ops)->open(host, 1, SD_MODE_TYPE);
|
||
|
|
os_mutex_init(&host->lock);
|
||
|
|
|
||
|
|
sdhost_io_func_init(host->flags);
|
||
|
|
|
||
|
|
if(bw == 4)
|
||
|
|
sd_power_up(host, MMCSD_BUSWIDTH_4);
|
||
|
|
else
|
||
|
|
sd_power_up(host,0);
|
||
|
|
|
||
|
|
sd_set_clk(host, 400*1000);
|
||
|
|
|
||
|
|
send_idle(host);
|
||
|
|
|
||
|
|
send_op_cond(host, 0x40FF8080, &ocr);
|
||
|
|
while(!(ocr & 0x80000000))
|
||
|
|
{
|
||
|
|
os_sleep_ms(5);
|
||
|
|
send_op_cond(host, 0x40FF8080, &ocr);
|
||
|
|
}
|
||
|
|
|
||
|
|
send_all_get_cid(host, host->resp_cid);
|
||
|
|
|
||
|
|
host->rca = 1;
|
||
|
|
mmc_set_card_addr(host, host->rca);
|
||
|
|
|
||
|
|
//解析csd (to do)
|
||
|
|
send_get_csd(host, host->resp_csd);
|
||
|
|
host->card_blksize = 1 << GET_BITS(host->resp_csd, 80, 4);
|
||
|
|
|
||
|
|
//select card
|
||
|
|
send_select_card(host);
|
||
|
|
|
||
|
|
//解析ext_csd (to do)
|
||
|
|
ext_csd = os_malloc(512);
|
||
|
|
if(!ext_csd) {
|
||
|
|
printf("ext_csd malloc fail\r\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
ret = mmc_get_ext_csd(host, ext_csd);
|
||
|
|
|
||
|
|
//de select
|
||
|
|
host->rca = 0;
|
||
|
|
send_select_card(host);
|
||
|
|
((const struct sdhc_hal_ops *)host->dev.ops)->close(host);
|
||
|
|
os_free(ext_csd);
|
||
|
|
|
||
|
|
|
||
|
|
if(ret == 1) {
|
||
|
|
//sd 卡
|
||
|
|
host->card_type = CARD_TYPE_SD;
|
||
|
|
sd_init(host, clk, 0);
|
||
|
|
} else {
|
||
|
|
host->card_type = CARD_TYPE_MMC;
|
||
|
|
emmc_init(host, clk);
|
||
|
|
}
|
||
|
|
|
||
|
|
if(host_wk.running == 0)
|
||
|
|
{
|
||
|
|
OS_WORK_INIT(&host_wk, sdh_loop, 0);
|
||
|
|
os_run_work_delay(&host_wk, 500);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
static struct fatfs_diskio sdcdisk_driver = {
|
||
|
|
.status = fatfs_status,
|
||
|
|
.init = fatfs_init,
|
||
|
|
.read = fatfs_read,
|
||
|
|
.write = fatfs_write,
|
||
|
|
.ioctl = fatfs_ioctl
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
static DSTATUS fatfs_status(void *status){
|
||
|
|
//TEST_INFO_SHOW ("fatfs_status_test\r\n");
|
||
|
|
DSTATUS err = get_sdhost_status(status);
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
static DSTATUS fatfs_init(void *init_dev){
|
||
|
|
//TEST_INFO_SHOW ("fatfs_init_test\r\n");
|
||
|
|
DSTATUS err;
|
||
|
|
err = mmc_init((struct sdh_device*)init_dev, 24*1000*1000);
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
static DRESULT fatfs_read(void *dev, BYTE* buf, DWORD sector, UINT count){
|
||
|
|
DRESULT err;
|
||
|
|
|
||
|
|
err = sd_multiple_read((struct sdh_device*)dev, sector, count*512, buf);
|
||
|
|
MMCFS_PRIN ("fatfs_read_test:%d %x %d %d\r\n",sector,buf,count, err);
|
||
|
|
//printf("E");
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
static DRESULT fatfs_write(void *dev, BYTE* buf, DWORD sector, UINT count){
|
||
|
|
DRESULT err;
|
||
|
|
|
||
|
|
err = sd_multiple_write((struct sdh_device*)dev,sector,count*512,buf);
|
||
|
|
MMCFS_PRIN ("fatfs_write_test:%d %x %d %d\r\n",sector,buf,count, err);
|
||
|
|
//printf("E");
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
extern uint32 fatfs_sd_tran_stop(struct sdh_device * host);
|
||
|
|
static DRESULT fatfs_ioctl(void *init_dev, BYTE cmd, void* buf){
|
||
|
|
uint8 ret = RES_OK;
|
||
|
|
switch(cmd)
|
||
|
|
{
|
||
|
|
case CTRL_SYNC:
|
||
|
|
fatfs_sd_tran_stop(init_dev);
|
||
|
|
break;
|
||
|
|
case GET_SECTOR_COUNT:
|
||
|
|
*(DWORD *)buf = ((struct sdh_device *)init_dev)->card_capacity * 2;
|
||
|
|
ret = RES_OK;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case GET_SECTOR_SIZE:
|
||
|
|
*(WORD *)buf = 512;
|
||
|
|
ret = RES_OK;
|
||
|
|
|
||
|
|
break;
|
||
|
|
case GET_BLOCK_SIZE:
|
||
|
|
*(DWORD *)buf = 4;
|
||
|
|
// printf("*0B:%d\n",*B);
|
||
|
|
ret = RES_OK;
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
ret = RES_ERROR; //not finish
|
||
|
|
printf("rtos_sd_ioctl err\n");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
FATFS fatfs[2];
|
||
|
|
int mmc_fatfs_register(uint32_t dev_id){
|
||
|
|
|
||
|
|
int ret = 1;
|
||
|
|
int ldnum;
|
||
|
|
char vpath[8];
|
||
|
|
struct sdh_device *fatfs_sdh;
|
||
|
|
|
||
|
|
printf("enter %s test\r\n", __func__);
|
||
|
|
fatfs_sdh = (struct sdh_device *)dev_get(dev_id);
|
||
|
|
|
||
|
|
if(dev_id == HG_SDIOHOST_DEVID) {
|
||
|
|
ldnum = 1;
|
||
|
|
} else if(dev_id == HG_SDIOHOST1_DEVID) {
|
||
|
|
ldnum = 2;
|
||
|
|
} else {
|
||
|
|
os_printf("%s err parameter\r\n", __FUNCTION__);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
sprintf(vpath, "%d:", ldnum);
|
||
|
|
|
||
|
|
if(fatfs_sdh)
|
||
|
|
{
|
||
|
|
fatfs_register_drive(ldnum, &sdcdisk_driver, fatfs_sdh);
|
||
|
|
ret = f_mount (&fatfs[ldnum-1], vpath, 1);
|
||
|
|
if (ret) {
|
||
|
|
printf("%s ret:%d\n",__FUNCTION__,ret);
|
||
|
|
f_mount (NULL, vpath, 0);
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("mmc fatfs mounted\r\n");
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
void mmc_fatfs_unregister(uint32_t dev_id)
|
||
|
|
{
|
||
|
|
int ret = 1;
|
||
|
|
int ldnum;
|
||
|
|
char vpath[8];
|
||
|
|
struct sdh_device *fatfs_sdh;
|
||
|
|
fatfs_sdh = (struct sdh_device *)dev_get(HG_SDIOHOST_DEVID);
|
||
|
|
if(dev_id == HG_SDIOHOST_DEVID) {
|
||
|
|
ldnum = 1;
|
||
|
|
} else if(dev_id == HG_SDIOHOST1_DEVID) {
|
||
|
|
ldnum = 2;
|
||
|
|
} else {
|
||
|
|
os_printf("%s err parameter\r\n", __FUNCTION__);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
sprintf(vpath, "%d:", ldnum);
|
||
|
|
|
||
|
|
if(fatfs_sdh)
|
||
|
|
{
|
||
|
|
ret = f_mount (NULL, vpath, 1);
|
||
|
|
fatfs_register_drive(ldnum, NULL, NULL);
|
||
|
|
if (ret) {
|
||
|
|
printf("%s ret:%d\n",__FUNCTION__,ret);
|
||
|
|
return ;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|