移植FatFs到ALIENTEK MiniSTM32

来源:互联网 发布:网络 cos 编辑:程序博客网 时间:2024/06/01 08:14

移植FatFs(版本R0.08b)到ALIENTEK MiniSTM32:

1、修改integer.h

/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/


#ifndef _INTEGER
#define _INTEGER


#ifdef _WIN32 /* FatFs development platform */


#include <windows.h>
#include <tchar.h>


#else /* Embedded platform */


/* These types must be 16-bit, 32-bit or larger integer */
typedef int INT;
typedef unsigned int UINT;


/* These types must be 8-bit integer */
typedef char CHAR;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;


/* These types must be 16-bit integer */
typedef short SHORT;
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;


/* These types must be 32-bit integer */
typedef long LONG;
typedef unsigned long ULONG;
typedef unsigned long DWORD;

#endif


#endif

2、配置ffconf.h

2_1、配置按字节or按字访问

/*---------------------------------------------------------------------------/
/ System Configurations
/----------------------------------------------------------------------------*/


#define _WORD_ACCESS 0/* 0 or 1 */


/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
/  option defines which access method is used to the word data on the FAT volume.
/
/   0: Byte-by-byte access.
/   1: Word access. Do not choose this unless following condition is met.
/
/  When the byte order on the memory is big-endian or address miss-aligned word
/  access results incorrect behavior, the _WORD_ACCESS must be set to 0.
/  If it is not the case, the value can also be set to 1 to improve the
/  performance and code size. */

2_2、配置小or大的RAM&FLASH

#define _FS_TINY0 /* 0:Normal or 1:Tiny */


/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
/  object instead of the sector buffer in the individual file object for file
/  data transfer. This reduces memory consumption 512 bytes each file object. */

3、配置diskio.c

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2007        */
/*-----------------------------------------------------------------------*/
/* This is a stub disk I/O module that acts as front end of the existing */
/* disk I/O modules and attach it to FatFs module with common interface. */
/*-----------------------------------------------------------------------*/


#include "common.h"
//#include "rtc.h"


/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */


DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
  /**
    u8 state;
drv=0x00;
    if(drv)
    {
        return STA_NOINIT;  //仅支持磁盘0的操作
    }


    state = SD_Init();
    if(state == STA_NODISK)
    {
        return STA_NODISK;
    }
    else if(state != 0)
    {
        return STA_NOINIT;  //其他错误:初始化失败
    }
    else
    {
        return 0;           //初始化成功
    }
**/
 
u8 state;
state=SD_Init();
if(!state){
return STA_NODISK;
}   
return 0;  
}






/*-----------------------------------------------------------------------*/
/* Return Disk Status                                                    */


DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{ /**
    if(drv)
    {
        return STA_NOINIT;  //仅支持磁盘0操作
    }


    //检查SD卡是否插入
    if(!SD_DET())
    {
        return STA_NODISK;
    }
    return 0;
**/
return 0;
}






/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */


DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
u8 res=0;
/*
    if (drv || !count)
    {    
        return RES_PARERR;  //仅支持单磁盘操作,count不能等于0,否则返回参数错误
    }
    if(!SD_DET())
    {
        return RES_NOTRDY;  //没有检测到SD卡,报NOT READY错误
    }


    */

    if(count==1)            //1个sector的读操作      
    {                                                
        res = SD_ReadSingleBlock(sector, buff);      
    }                                                
    else                    //多个sector的读操作     
    {                                                
        res = SD_ReadMultiBlock(sector, buff, count);
    }                                                
/*
    do                           
    {                                          
        if(SD_ReadSingleBlock(sector, buff)!=0)
        {                                      
            res = 1;                           
            break;                             
        }                                      
        buff+=512;                             
    }while(--count);                                         
    */
    //处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
    if(res == 0x00)
    {
        return RES_OK;
    }
    else
    {
        return RES_ERROR;
    }
}






/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */


#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff,/* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
u8 res;
/*
    if (drv || !count)
    {    
        return RES_PARERR;  //仅支持单磁盘操作,count不能等于0,否则返回参数错误
    }
    if(!SD_DET())
    {
        return RES_NOTRDY;  //没有检测到SD卡,报NOT READY错误
    }
*/
    // 读写操作
    if(count == 1)
    {
        res = SD_WriteSingleBlock(sector, buff);
    }
    else
    {
        res = SD_WriteMultiBlock(sector, buff, count);
    }
    // 返回值转换
    if(res == 0)
    {
        return RES_OK;
    }
    else
    {
        return RES_ERROR;
    }
}
#endif /* _READONLY */






/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */


DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
    DRESULT res;




    if (drv)
    {    
        return RES_PARERR;  //仅支持单磁盘操作,否则返回参数错误
    }
    
    //FATFS目前版本仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个命令
    switch(ctrl)
    {
    case CTRL_SYNC:
/*
         SD_CS_ENABLE();
 
        if(SD_WaitReady()==0)
        {
            res = RES_OK;
        }
        else
        {
            res = RES_ERROR;
        }
        SD_CS_DISABLE();
*/
res=RES_OK;
        break;
        
    case GET_BLOCK_SIZE:
        *(WORD*)buff = 512;
        res = RES_OK;
        break;


    case GET_SECTOR_COUNT:
        *(DWORD*)buff = SD_GetCapacity();
        res = RES_OK;
        break;
    default:
        res = RES_PARERR;
        break;
    }


    return res;
}




/*-----------------------------------------------------------------------*/
/* User defined function to give a current time to fatfs module          */
/* 31-26: Year(0-127 org.1970), 25-22: Month(1-12), 21-17: Day(1-31) */                                                                                                                                                                                                                                          
/* 16-12: Hour(0-23), 11-6: Minute(0-59), 5-0: Second(0-60) */                                                                                                                                                                                                                                                
DWORD get_fattime (void)
{


    DWORD date=0;
//    timer.w_year -= 1970; //年份为1970年起       
//  
//    date = (timer.w_year << 26)|(timer.w_month<<22)|(timer.w_date<<17)|\
//            (timer.hour<<12)|(timer.min<<6)|(timer.sec);


    return date;

}

4、配置MMC_SD.c

4_1

//读SD卡的一个block
//输入:u32 sector 取地址(sector值,非物理地址) 
//     u8 *buffer 数据存储地址(大小至少512byte)   
//返回值:0: 成功
//       other:失败  
u8 SD_ReadSingleBlock(u32 sector, u8 *buffer)
{
u8 r1;    
    //设置为高速模式
    SPIx_SetSpeed(SPI_SPEED_4);     
    //如果不是SDHC,给定的是sector地址,将其转换成byte地址
    if(SD_Type!=SD_TYPE_V2HC)
    {
        sector = sector<<9;
    } 
r1 = SD_SendCommand(CMD17, sector, 0);//读命令   
if(r1 != 0x00)return r1;    
r1 = SD_ReceiveData(buffer, 512, RELEASE); 
if(r1 != 0)return r1;   //读数据出错!
    else return 0; 
}


4_2

//写入SD卡的一个block(未实际测试过)   
//输入:u32 sector 扇区地址(sector值,非物理地址) 
//     u8 *buffer 数据存储地址(大小至少512byte)   
//返回值:0: 成功
//       other:失败  
u8 SD_WriteSingleBlock(u32 sector, const u8 *data)
{
    u8 r1;
    u16 i;
    u16 retry;


    //设置为高速模式
    //SPIx_SetSpeed(SPI_SPEED_HIGH);   
    //如果不是SDHC,给定的是sector地址,将其转换成byte地址
    if(SD_Type!=SD_TYPE_V2HC)
    {
        sector = sector<<9;
    }   
    r1 = SD_SendCommand(CMD24, sector, 0x00);
    if(r1 != 0x00)
    {
        return r1;  //应答不正确,直接返回
    }
    
    //开始准备数据传输
    SD_CS=0;
    //先放3个空数据,等待SD卡准备好
    SPIx_ReadWriteByte(0xff);
    SPIx_ReadWriteByte(0xff);
    SPIx_ReadWriteByte(0xff);
    //放起始令牌0xFE
    SPIx_ReadWriteByte(0xFE);


    //放一个sector的数据
    for(i=0;i<512;i++)
    {
        SPIx_ReadWriteByte(*data++);
    }
    //发2个Byte的dummy CRC
    SPIx_ReadWriteByte(0xff);
    SPIx_ReadWriteByte(0xff);
    
    //等待SD卡应答
    r1 = SPIx_ReadWriteByte(0xff);
    if((r1&0x1F)!=0x05)
    {
        SD_CS=1;
        return r1;
    }
    
    //等待操作完成
    retry = 0;
    while(!SPIx_ReadWriteByte(0xff))
    {
        retry++;
        if(retry>0xfffe)        //如果长时间写入没有完成,报错退出
        {
            SD_CS=1;
            return 1;           //写入超时返回1
        }
    }    
    //写入完成,片选置1
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);


    return 0;
}


4_3

//读SD卡的多个block(实际测试过)    
//输入:u32 sector 扇区地址(sector值,非物理地址) 
//     u8 *buffer 数据存储地址(大小至少512byte)
//     u8 count 连续读count个block   
//返回值:0: 成功
//       other:失败  
u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count)
{
    u8 r1;  
    //SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式  
  //如果不是SDHC,将sector地址转成byte地址
    if(SD_Type!=SD_TYPE_V2HC)sector = sector<<9;  
    //SD_WaitDataReady();
    //发读多块命令
r1 = SD_SendCommand(CMD18, sector, 0);//读命令
if(r1 != 0x00)return r1; 
    do//开始接收数据
    {
        if(SD_ReceiveData(buffer, 512, NO_RELEASE) != 0x00)break; 
        buffer += 512;
    } while(--count);  
    //全部传输完毕,发送停止命令
    SD_SendCommand(CMD12, 0, 0);
    //释放总线
    SD_CS=1;
    SPIx_ReadWriteByte(0xFF);    
    if(count != 0)return count;   //如果没有传完,返回剩余个数  
    else return 0;  
}


4_4

//写入SD卡的N个block(未实际测试过)    
//输入:u32 sector 扇区地址(sector值,非物理地址) 
//     u8 *buffer 数据存储地址(大小至少512byte)
//     u8 count 写入的block数目   
//返回值:0: 成功
//       other:失败   
u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count)
{
    u8 r1;
    u16 i;  
    //SPIx_SetSpeed(SPI_SPEED_HIGH);//设置为高速模式  
    if(SD_Type != SD_TYPE_V2HC)sector = sector<<9;//如果不是SDHC,给定的是sector地址,将其转换成byte地址  
    if(SD_Type != SD_TYPE_MMC) r1 = SD_SendCommand(ACMD23, count, 0x00);//如果目标卡不是MMC卡,启用ACMD23指令使能预擦除   
    r1 = SD_SendCommand(CMD25, sector, 0x00);//发多块写入指令
    if(r1 != 0x00)return r1;  //应答不正确,直接返回  
    SD_CS=0;//开始准备数据传输   
    SPIx_ReadWriteByte(0xff);//先放3个空数据,等待SD卡准备好
    SPIx_ReadWriteByte(0xff);   
    //--------下面是N个sector写入的循环部分
    do
    {
        //放起始令牌0xFC 表明是多块写入
        SPIx_ReadWriteByte(0xFC);  
        //放一个sector的数据
        for(i=0;i<512;i++)
        {
            SPIx_ReadWriteByte(*data++);
        }
        //发2个Byte的dummy CRC
        SPIx_ReadWriteByte(0xff);
        SPIx_ReadWriteByte(0xff);
        
        //等待SD卡应答
        r1 = SPIx_ReadWriteByte(0xff);
        if((r1&0x1F)!=0x05)
        {
            SD_CS=1;    //如果应答为报错,则带错误代码直接退出
            return r1;
        }   
        //等待SD卡写入完成
        if(SD_WaitDataReady()==1)
        {
            SD_CS=1;    //等待SD卡写入完成超时,直接退出报错
            return 1;
        }   
    }while(--count);//本sector数据传输完成  
    //发结束传输令牌0xFD
    r1 = SPIx_ReadWriteByte(0xFD);
    if(r1==0x00)
    {
        count =  0xfe;
    }   
    if(SD_WaitDataReady()) //等待准备好
{
SD_CS=1;
return 1;  
}
    //写入完成,片选置1
    SD_CS=1;
    SPIx_ReadWriteByte(0xff);  
    return count;   //返回count值,如果写完则count=0,否则count=1
}

原创粉丝点击