打印

移植FATFS到S3C2440的SD卡上遇到的困难,请高手指点

[复制链接]
楼主: dsoyy
手机看帖
扫描二维码
随时随地手机跟帖
21
xfcjava2| | 2010-4-8 20:28 | 只看该作者 回帖奖励 |倒序浏览
关键的函数还有:
/*********************************************************************************************************
** 函数名称: MMC_disk_ioctl
** 功能描述:
** 输   入: ctrl:Control code
**           buff:Buffer to send/receive control data **           
** 输   出: TRUE,正常返回
**           FALSE,出错返回
********************************************************************************************************/

int MMC_disk_ioctl (BYTE ctrl,void *buff)       
{
DRESULT res;
   BYTE n,*p,*ptr = buff;
   
   BYTE csd[16];
   
   WORD csize;
       
   if (Stat_MMC & STA_NOINIT) return RES_NOTRDY;
   
   res = RES_ERROR;            

         switch (ctrl)
                {
                        case CTRL_SYNC :        /* Make sure that all data has been written on the media */
                                if (CMD13())         /* Wait for card enters tarn state */
                                        res = RES_OK;
                                break;

                        case GET_SECTOR_COUNT :        /* Get number of sectors on the disk (DWORD) */
                               
                                p = &CardInfo[0];
                                if ((p[0] >> 6) == 1) {        /* SDC ver 2.00 */
                                        csize = p[9] + ((WORD)p[8] << 8) + 1;
                                        *(DWORD*)buff = (DWORD)csize << 10;
                                } else {                                        /* MMC or SDC ver 1.XX */
                                        n = (p[5] & 15) + ((p[10] & 128) >> 7) + ((p[9] & 3) << 1) + 2;
                                        csize = (p[8] >> 6) + ((WORD)p[7] << 2) + ((WORD)(p[6] & 3) << 10) + 1;
                                        *(DWORD*)buff = (DWORD)csize << (n - 9);
                                }                                        
                                res = RES_OK;                        
                               
                                //Uart_Printf(" GET_SECTOR_COUNT end!!!\n");
                               
                                return RES_OK;                               

                        case GET_SECTOR_SIZE :        /* Get R/W sector size (WORD) */
                                *(WORD*)buff = 512;
                                res = RES_OK;
                                break;

                        case GET_BLOCK_SIZE :        /* Get erase block size in unit of sector (DWORD) */
                                                                /* SDC ver 1.XX or MMC */                                                                        
                                //Uart_Printf(" GET_BLOCK_SIZE start!!!\n");                                                                       
                               
                                if (MMC & 2)
                                {                        /* SDC ver 1.XX */
                                        *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
                                }
                                else /* MMC */
                                {                                       
                                        *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
                                }
                               
                                res = RES_OK;                                 
                               
                                //Uart_Printf(" GET_BLOCK_SIZE end!!!\n");
                               
                                return RES_OK;                                        

                        case MMC_GET_TYPE :                /* Get card type flags (1 byte) */
                                *ptr =MMC;
                                res = RES_OK;
                                break;

                        case MMC_GET_CSD :                /* Receive CSD as a data block (16 bytes) */
                                if((CMD9() == 1)&& rcvr_datablock(ptr, 16))        /* READ_CSD */                               
                                res = RES_OK;
                                break;

                        case MMC_GET_CID :                /* Receive CID as a data block (16 bytes) */
                               
                                break;

                        case MMC_GET_OCR :                /* Receive OCR as an R3 resp (4 bytes) */
                               
                                break;

                        case MMC_GET_SDSTAT :        /* Receive SD statsu as a data block (64 bytes) */
                               
                                break;

                        default:
                                res = RES_PARERR;
                            break;
                }       
       
        return res;
}

此函数没有处理对的话,会出现SD卡初始化失败的错误!!!

使用特权

评论回复
22
xfcjava2| | 2010-4-8 20:38 | 只看该作者
如再有问题,我会及时替你解决的,请放心。
移植FATFS到S3C2440上,现在我已经调试完毕所有的移植,并用在工程中。
包括:硬盘(ATA),SD卡(MMC),U盘(USB)

使用特权

评论回复
23
dsoyy|  楼主 | 2010-4-8 23:13 | 只看该作者
顶楼上,明天调试继续请教你!

使用特权

评论回复
24
dsoyy|  楼主 | 2010-4-9 09:53 | 只看该作者
本帖最后由 dsoyy 于 2010-4-9 10:10 编辑

有如下几个问题请教xfcjava2:
1、您能提供下MMC_disk_write(buff, sector, count);这个函数吗?
2、您提供的int MMC_disk_ioctl (BYTE ctrl,void *buff)   里面的变量:CardInfo[0]和宏Stat_MMC不知道如何定义。
3、您说“int MMC_disk_ioctl (BYTE ctrl,void *buff)此函数没有处理对的话,会出现SD卡初始化失败的错误!!!”我认为这个是SD卡初始化,我每次初始化没有特殊要求是不会格式化的,所以我认为这个函数如果不需要格式化的时候是没有用的
4、我目前这样的进行操作:
void test_fatfs(void)
{
         FATFS fs;
        DSTATUS stat = 88;
        FRESULT res;                //文件系统返回信息
         FIL file;
          stat = disk_initialize(1);
        Uart_Printf("%d\n",stat);
         
        Write_SD("data.txt","12345",2);
        
        while(1);
}

void Write_SD(const char *write_file,const void *buffer,UINT count)
{
  FATFS fs;
  FIL fil;
  U32 bw;
  FRESULT res;                //文件系统返回信息

   f_mount(0,&fs);//注册一个文件系统
   res=f_open(&fil,write_file,FA_OPEN_ALWAYS|FA_WRITE);//建立文件的文件名最长8个字节
   Uart_Printf("%d\n",res);
    if(res!=FR_OK)
   {
        Uart_Printf("文件不能写!!!\r\n");
        return;
    }
     
        res=f_lseek(&fil,fil.fsize);
        res=f_write(&fil,buffer,count,&bw);

    f_close(&fil);
        f_mount(0, NULL);
}

然而没有在SD中建立一个对应文件或者在SD卡里没有对应文件的情况下写进任何内容。

res=f_open(&fil,write_file,FA_OPEN_ALWAYS|FA_WRITE);//建立文件的文件名最长8个字节
   Uart_Printf("%d\n",res);

这里显示为1和
文件不能写!!!

使用特权

评论回复
25
xfcjava2| | 2010-4-9 19:00 | 只看该作者
其中:CardInfo定义如下:
         U8 CardInfo[16+16+4];        /* CSD(16), CID(16), OCR(4) */

static volatile DSTATUS Stat_MMC = STA_NOINIT;        /* Disk status */       

DSTATUS,STA_NOINIT:请看diskio.h

int MMC_disk_ioctl (BYTE ctrl,void *buff):
此函数使得FATFS文件系统得到SD卡的基本参数:容量,扇区数,扇区大小等,所以很重要!!

使用特权

评论回复
26
xfcjava2| | 2010-4-9 19:04 | 只看该作者
/*********************************************************************************************************
** 函数名称: MMC_disk_write
** 功能描述:
** 输   入: buff  :Data to be written
**           sector:Sector address (LBA)
**           count:Number of sectors to write (1..255)
** 输   出: TRUE,正常返回
**              FALSE,出错返回
********************************************************************************************************/

int  MMC_disk_write (const BYTE *buff,DWORD sector,BYTE count)         
{
   sector *= 512;        /* Convert to byte address if needed */
   
    if (count == 1) /* Single block read */
     {       
                   if(xmit_datablock (buff, sector,1))/* WRITE_SINGLE_BLOCK */                       
                           count = 0;
                 }

                else /* Multiple block read */
                 {                               
                    if(xmit_datablock(buff, sector,count*512))/* WRITE_SINGLE_BLOCK */                       
                                count = 0;
                 }
   
    return count ? RES_ERROR : RES_OK;
}


/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC                                             */
/*-----------------------------------------------------------------------*/
/* 512 byte data block to be transmitted */
/* Data/Stop token */
static BOOL xmit_datablock (const BYTE *buff,DWORD sector,UINT token)
{         
   //Polling write Mode
   
   int status;
   
   unsigned int wrt_num=0;
   
   UINT blk_num;            
     
   
   blk_num=token;
   
         rSDIFSTA=rSDIFSTA|(1<<16);        // FIFO reset
   
         rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(blk_num<<0);        //YH 040220

                    //Word Tx, Tx after rsp, blk, 1bit bus, Tx start, blk num
   rSDICARG=sector;        // CMD24/25(addr)

REWTCMD:  

   if(blk_num<2) // SINGLE_WRITE
    {   
          
            rSDICCON=(0x1<<9)|(0x1<<8)|0x58;        //sht_resp, wait_resp, dat, start, CMD24
                  if(!Chk_CMDend(24, 1))        //-- Check end of CMD24
                    goto REWTCMD;  
    }
   
   else        // MULTI_WRITE
                {
                        rSDICCON=(0x1<<9)|(0x1<<8)|0x59;        //sht_resp, wait_resp, dat, start, CMD25
                        if(!Chk_CMDend(25, 1))        //-- Check end of CMD25
                        goto REWTCMD;               
                }

    rSDICSTA=0xa00;        // Clear cmd_end(with rsp)            

    while(wrt_num<128*blk_num)        // 512=128*4 bytes
     {
                                status=rSDIFSTA;
                               
                                if((status&0x2000)==0x2000)
                                {
                                   rSDIDAT=br_LD_DWORD(buff);                                  
                                   buff+=4;
                                         wrt_num++;
                                }
     }
   
    if(!Chk_DATend())
            return FALSE;
            
          rSDIDCON=rSDIDCON&~(7<<12);                //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
    rSDIDSTA=0x10;        // Clear data Tx/Rx end
   
    if(blk_num>1)
     {
                                        //--Stop cmd(CMD12)
                                REWCMD12:                                 
                                        rSDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<14)|(1<<12)|(blk_num<<0);         //YH  040220                        
                                       
                                        rSDICARG=0x0;            //CMD12(stuff bit)
                                        rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;    //sht_resp, wait_resp, start, CMD12
                       
                                        //-- Check end of CMD12
                                        if(!Chk_CMDend(12, 1))
                                            goto REWCMD12;
                                        rSDICSTA=0xa00;        // Clear cmd_end(with rsp)
                       
                                        //-- Check end of DATA(with busy state)
                                        if(!Chk_BUSYend())
                                            Uart_Printf("error\n");
                                        rSDIDSTA=0x08;        //! Should be cleared by writing '1'.
     }
   
    return TRUE;   // Return with success


}

使用特权

评论回复
27
xfcjava2| | 2010-4-9 19:09 | 只看该作者
等待dsoyy回复!!!

使用特权

评论回复
28
dsoyy|  楼主 | 2010-4-9 22:13 | 只看该作者
抱歉,让您久等。
我初始化SD卡后进行
  f_mount(0,&fs);//注册一个文件系统
res=f_open(&fil,write_file,FA_OPEN_ALWAYS|FA_WRITE);//建立文件的文件名最长8个字节
res = 1。  只有等于0才代表成功。这个错误什么导致的我不得而知。

此外据说在ADS下几个宏要改成函数写法,不知道楼上是否这样处理?

使用特权

评论回复
29
xfcjava2| | 2010-4-9 22:19 | 只看该作者
你用的FATFS的版本号是多少??

使用特权

评论回复
30
xfcjava2| | 2010-4-9 22:20 | 只看该作者
void br_ST_DWORD(const BYTE *ptr,DWORD val)
{

  *(BYTE*)(ptr+3)=(BYTE)(val);
  *(BYTE*)((ptr)+2)=(BYTE)((WORD)(val)>>8);
  *(BYTE*)((ptr)+1)=(BYTE)((DWORD)(val)>>16);
  *(BYTE*)(ptr)=(BYTE)((DWORD)(val)>>24);
}       


DWORD br_LD_DWORD(const BYTE *ptr)
{
    return (DWORD)( ((DWORD)*(BYTE*)(ptr)<<24)|((DWORD)*(BYTE*)((ptr)+1)<<16)|
                                ((WORD)*(BYTE*)((ptr)+2)<<8)|*(BYTE*)((ptr)+3)
                                                                        );   
         
}

使用特权

评论回复
31
dsoyy|  楼主 | 2010-4-9 22:25 | 只看该作者
我记得有4个宏,我没有改成函数,难怪我没有调试成功。

这么晚您还在等我,非常感激啊!
我明天去公司加班继续调试,还想加UCGUI.

使用特权

评论回复
32
dsoyy|  楼主 | 2010-4-9 22:27 | 只看该作者
FatFs - FAT file system module  R0.07c     

#define        LD_WORD(ptr)                (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define        LD_DWORD(ptr)                (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define        ST_WORD(ptr,val)        *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define        ST_DWORD(ptr,val)        *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)

使用特权

评论回复
33
xfcjava2| | 2010-4-9 22:29 | 只看该作者
f_mount(0,&fs):

  此函数的第1个参数指定操作的驱动器,默认情况下0(ATA); 1(MMC);2(USB),不知你注意到了没有?

如果你使用的是SD卡,请将此函数的第1个参数指定为MMC!!!

使用特权

评论回复
34
dsoyy|  楼主 | 2010-4-9 22:35 | 只看该作者
楼上说的是!
我知道错误所在了。
f_mount(0,&fs)参数错了。
此外,您介意把另外两个宏的函数源码也发上来吗?据说ADS打补丁可以弥补这个错误的,不定叫ADS  848好像

使用特权

评论回复
35
xfcjava2| | 2010-4-9 22:42 | 只看该作者
我使用的是FatFs   R0.07e
官方网址:http://elm-chan.org/fsw/ff/00index_e.html
你可以去下载最新版本,另外可以参考官方网址的样例!!

WORD  LD_WORD(BYTE *ptr)
{   
   return (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr));
   
}

DWORD LD_DWORD(BYTE *ptr)
{
   
    return (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr));      
}


void ST_WORD(BYTE *ptr,DWORD val)
{
   *(BYTE*)(ptr)=(BYTE)(val);
   *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8);
}

void ST_DWORD(BYTE *ptr,DWORD val)
{

  *(BYTE*)(ptr)=(BYTE)(val);
  *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8);
  *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16);
  *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24);
}

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
dsoyy + 1
36
xfcjava2| | 2010-4-9 22:49 | 只看该作者
本人在ADS下也成功移植过,只不过现在早已转到keil下,以前使用过的版本还有:FatFs R0.06,
FatFs R0.07c等

使用特权

评论回复
37
dsoyy|  楼主 | 2010-4-9 22:51 | 只看该作者
感谢您的热心回答。
希望和你进一步交流  交流  176855725 向您学习

使用特权

评论回复
38
xfcjava2| | 2010-4-9 22:52 | 只看该作者
最后给你的4个函数是在ADS1.2下FatFs R0.06中使用的函数。

使用特权

评论回复
39
dsoyy|  楼主 | 2010-4-9 22:55 | 只看该作者
看看0.7的这个函数可以不,不可以再考虑如何改写。
我也想用keil,考虑飞凌等的例程都是ADS下的,就没有去做这样的工作

使用特权

评论回复
40
xfcjava2| | 2010-4-9 22:56 | 只看该作者
都可以使用!我都试过了!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则