码迷,mamicode.com
首页 > 其他好文 > 详细

STM32-移植FATFS的NANDFLASH驱动

时间:2014-07-27 10:26:32      阅读:476      评论:0      收藏:0      [点我收藏+]

标签:

一,建立工程FATFS源码
 1,在http://elm-chan.org/fsw/ff/00index_e.html上下载ff007c.zip,并把ff007c.zip里面的
 src文件夹复制到D:\works\EK-STM3210E-UCOSII下,并改名为Fatfs;
 2,在IDE工程中右击选择“Add Group”建立“FATFS”文件组,并在“FATFS”上右击选择“Add Files”添加
 D:\works\EK-STM3210E-UCOSII\Fatfs下的C文件;
 3,把D:\works\EK-STM3210E-UCOSII\Fatfs文件夹目录添加到项目头文件搜索路径中,如:
 $PROJ_DIR$\..\..\Fatfs
 
二,移植NANDFLASH驱动接口
 1,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.c复制到
 D:\works\EK-STM3210E-UCOSII\Drivers下,并加入到工程的DRV文件组;
 2,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.h复制到
 D:\works\EK-STM3210E-UCOSII\Include下;
 3,在fsmc_nand.c前添加上#include "stm32f10x_conf.h",并把系统中的 "stm32f10x_conf.h"
 文件的/* #include "stm32f10x_fsmc.h" */注释打开;

三,修改FATFS的配置文件
 1,把D:\works\EK-STM3210E-UCOSII\Fatfs下的ff.h中的宏定义:
 

[cpp] view plaincopy
 
  1.  #define _USE_MKFS 0  
  2.   #define _CODE_PAGE 932  
  3.   #define _FS_RPATH 0  
  4.   #define _MAX_SS  512  
  5.   修改为:  
  6.   #define _USE_MKFS 1  
  7.   #define _CODE_PAGE 936  
  8.   #define _MAX_SS  <span style="font-size:18px;color:#3333ff;">2048  
  9. </span>  #define _FS_RPATH 1  


 

 2,把D:\works\EK-STM3210E-UCOSII\Fatfs下的integer.h的宏定义:
 

[cpp] view plaincopy
 
  1. typedef enum { FALSE = 0, TRUE } BOOL;  
  2.  修改为:  
  3.  typedef bool BOOL;//typedef enum { FALSE = 0, TRUE } BOOL;  


 

四,修改FATFS的DISK/IO接口
 1,把diskio.c复制后改名为nandio.c替换掉工程中的diskio.c,并添加到EWARM的工程中的
  “FATFS”文件组;
 2,媒介初始化直接返回正常的0:
 

[cpp] view plaincopy
 
  1. DSTATUS disk_initialize (BYTE drv)  
  2.  {  return 0;}  


 

 3,媒介状态查询直接返回正常的0:
  

[cpp] view plaincopy
 
  1. DSTATUS disk_status (BYTE drv)  
  2.   {  return 0;}  


 

 4,取系统系统直接返回0(自己可以按格式修改为真实时间):

[cpp] view plaincopy
 
  1. DWORD get_fattime (void)  
  2. {  return 0;}  


 

 5,媒介控制接口:
  

[cpp] view plaincopy
 
  1. DRESULT disk_ioctl (BYTE drv,BYTE ctrl, void *buff)  
  2.   {  
  3.    DRESULT res = RES_OK;  
  4.    uint32_t result;  
  5.   
  6.       if (drv){ return RES_PARERR;}  
  7.      
  8.       switch(ctrl)  
  9.       {  
  10.        case CTRL_SYNC:  
  11.            break;  
  12.     case GET_BLOCK_SIZE:  
  13.            <span style="color:#000099;">*(DWORD*)buff = NAND_BLOCK_SIZE</span>;  
  14.            break;  
  15.     case GET_SECTOR_COUNT:  
  16.            <span style="color:#000099;">*(DWORD*)buff = (((NAND_MAX_ZONE/2) * NAND_ZONE_SIZE) * NAND_BLOCK_SIZE);  
  17. </span>           break;  
  18.     case GET_SECTOR_SIZE:  
  19.            <span style="color:#000099;">*(WORD*)buff = NAND_PAGE_SIZE;  
  20. </span>           break;  
  21.        default:  
  22.           <span style="color:#000099;"> res = RES_PARERR;  
  23. </span>           break;  
  24.    }  
  25.       return res;  
  26.   }  
  27.    


 

6,媒介多扇区读接口:
  

[cpp] view plaincopy
 
  1. DRESULT disk_read (BYTE drv,BYTE *buff,DWORD sector,BYTE count)  
  2.   {  
  3.    uint32_t result;  
  4.   
  5.       if (drv || !count){  return RES_PARERR;}  
  6.    result = FSMC_NAND_ReadSmallPage(buff, sector, count);                                                 
  7.       if(result & NAND_READY){  return RES_OK; }  
  8.       else { return RES_ERROR;  }  
  9.   }  


 

 7,媒介多扇区写接口:
 

[cpp] view plaincopy
 
  1. #if _READONLY == 0  
  2.  DRESULT disk_write (BYTE drv,const BYTE *buff,DWORD sector,BYTE count)  
  3.  {  
  4.   uint32_t result;  
  5.   uint32_t BackupBlockAddr;  
  6.   uint32_t WriteBlockAddr;  
  7.   uint16_t IndexTmp = 0;  
  8.   uint16_t OffsetPage;  
  9.    
  10.   /* NAND memory write page at block address*/  
  11.   WriteBlockAddr = (sector/NAND_BLOCK_SIZE);  
  12.   /* NAND memory backup block address*/  
  13.   BackupBlockAddr = (WriteBlockAddr + (NAND_MAX_ZONE/2)*NAND_ZONE_SIZE);  
  14.   OffsetPage = sector%NAND_BLOCK_SIZE;  
  15.    
  16.      if (drv || !count){  return RES_PARERR;}  
  17.     
  18.   /* Erase the NAND backup Block */  
  19.      result = FSMC_NAND_EraseBlock(BackupBlockAddr*NAND_BLOCK_SIZE);  
  20.    
  21.      /* Backup the NAND Write Block to High zone*/  
  22.    
  23.   for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ )  
  24.   {  
  25.    FSMC_NAND_MoveSmallPage (WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp);  
  26.   }  
  27.    
  28.   /* Erase the NAND Write Block */  
  29.   result = FSMC_NAND_EraseBlock(WriteBlockAddr*NAND_BLOCK_SIZE);  
  30.    
  31.      /*return write the block  with modify*/  
  32.   for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ )  
  33.   {  
  34.    if((IndexTmp>=OffsetPage)&&(IndexTmp < (OffsetPage+count)))  
  35.    {  
  36.     FSMC_NAND_WriteSmallPage((uint8_t *)buff, WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp, 1);  
  37.     buff = (uint8_t *)buff + NAND_PAGE_SIZE;  
  38.       }  
  39.    else  
  40.    {  
  41.          FSMC_NAND_MoveSmallPage (BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp);  
  42.       }  
  43.   }     
  44.     
  45.      if(result == NAND_READY){   return RES_OK;}  
  46.      else {   return RES_ERROR;}  
  47.  }  
  48.  #endif /* _READONLY */  


 

五,调用接口及测试代码
 1,调用接口,先初始化FSMC和NANDFLASH:
  

[cpp] view plaincopy
 
  1. //NANDFLASH HY27UF081G2A-TPCB  
  2.   #define NAND_HY_MakerID     0xAD  
  3.   #define NAND_HY_DeviceID    0xF1  
  4.     
  5.   /* Configure the NAND FLASH */  
  6.   void NAND_Configuration(void)  
  7.   {  
  8.    NAND_IDTypeDef NAND_ID;  
  9.      
  10.    /* Enable the FSMC Clock */  
  11.    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);  
  12.      
  13.       /* FSMC Initialization */  
  14.    FSMC_NAND_Init();  
  15.     
  16.    /* NAND read ID command */  
  17.    FSMC_NAND_ReadID(&NAND_ID);  
  18.       
  19.    /* Verify the NAND ID */  
  20.    if((NAND_ID.Maker_ID == NAND_ST_MakerID) && (NAND_ID.Device_ID == NAND_ST_DeviceID))  
  21.    {  
  22.           printf("ST NANDFLASH");  
  23.    }  
  24.       else  
  25.       if((NAND_ID.Maker_ID == NAND_HY_MakerID) && (NAND_ID.Device_ID == NAND_HY_DeviceID))  
  26.    {  
  27.           printf("HY27UF081G2A-TPCB");  
  28.    }  
  29.    printf(" ID = 0x%x%x%x%x \n\r",NAND_ID.Maker_ID,NAND_ID.Device_ID,NAND_ID.Third_ID,NAND_ID.Fourth_ID);  
  30.   }  
  31.    


 

 

2,然后对媒介格式化,创建读写文件:
  

[cpp] view plaincopy
 
  1. void test_fatfs(void)  
  2.   {  
  3.       FATFS fs;  
  4.    FIL fl;  
  5.    FATFS *pfs;  
  6.    DWORD clust;  
  7.    unsigned int r,w,i;  
  8.    FRESULT  res;  
  9.      
  10.   // NF_CHKDSK(0,1024);  
  11.    display_page(0,0);  
  12.      
  13.   // for mount   
  14.    res=f_mount(0,&fs);  
  15.    printf("f_mount=%x \n\r",res);  
  16.      
  17.   // for format  
  18.    //res=f_mkfs(0,1,2048);  //MUST Format for New NANDFLASH !!!  
  19.    //printf("f_mkfs=%x \n\r",res);  
  20.     
  21.   // for  
  22.    pfs=&fs;  
  23.    res = f_getfree("/", &clust, &pfs);  
  24.    printf("f_getfree=%x \n\r",res);  
  25.    printf("\n\r%lu MB total drive space."  
  26.        "\n\r%lu MB available.\n\r",  
  27.      (DWORD)(pfs->max_clust - 2) * pfs->csize /2/1024,  
  28.      clust * pfs->csize /2/1024);  
  29.      
  30.   // for read  
  31.       res=f_open(&fl,"/test2.dat",FA_OPEN_EXISTING | FA_READ);  
  32.       printf("f_open=%x \n\r",res);  
  33.    for(i=0;i<2;i++)  
  34.    {  
  35.     for(r = 0; r < NAND_PAGE_SIZE; r++)  
  36.     {  
  37.      RxBuffer[r]= 0xff;  
  38.     }  
  39.       
  40.     res=f_read(&fl,RxBuffer,NAND_PAGE_SIZE,&r);  
  41.     printf("f_read=%x \n\r",res);  
  42.     if(res || r == 0)break;  
  43.     for(r = 0; r < NAND_PAGE_SIZE; r++)  
  44.        {  
  45.            printf("D[%08x]=%02x ",(i*NAND_PAGE_SIZE+r),RxBuffer[r]);  
  46.            if((r%8)==7)  
  47.            {printf("\n\r");}  
  48.        }  
  49.         
  50.    }  
  51.    f_close(&fl);  
  52.   // for write  
  53.    res=f_open(&fl,"/test2.dat",FA_CREATE_ALWAYS | FA_WRITE);  
  54.    printf("f_open=%x \n\r",res);  
  55.    for(i=0;i<2;i++)  
  56.    {  
  57.     for(w = 0; w < NAND_PAGE_SIZE; w++)  
  58.     {  
  59.      TxBuffer[w]=((w<<0)&0xff);  
  60.     }  
  61.           res=f_write(&fl,TxBuffer,NAND_PAGE_SIZE,&w);  
  62.           printf("f_write=%x \n\r",res);  
  63.     if(res || w  
  64.       
  65.    }  
  66.    f_close(&fl);  
  67.      
  68.   // for umount  
  69.    f_mount(0,NULL);  
  70.   }  


 

六,编写NANDFLASH接口
 1,fsmc_nand.c文件:
 

[cpp] view plaincopy
 
  1. /* Includes ------------------------------------------------------------------*/  
  2.  #include "fsmc_nand.h"  
  3.  #include "stm32f10x_conf.h"  
  4.    
  5.  /** @addtogroup StdPeriph_Examples 
  6.    * @{ 
  7.    */  
  8.    
  9.  /** @addtogroup FSMC_NAND 
  10.    * @{ 
  11.    */  
  12.    
  13.  /* Private typedef -----------------------------------------------------------*/  
  14.  /* Private define ------------------------------------------------------------*/  
  15.    
  16.  #define FSMC_Bank_NAND     FSMC_Bank2_NAND  
  17.  #define Bank_NAND_ADDR     Bank2_NAND_ADDR  
  18.  #define Bank2_NAND_ADDR    ((uint32_t)0x70000000)  
  19.    
  20.  /* Private macro -------------------------------------------------------------*/  
  21.  /* Private variables ---------------------------------------------------------*/  
  22.  /* Private function prototypes -----------------------------------------------*/  
  23.  /* Private functions ---------------------------------------------------------*/  
  24.    
  25.  /** 
  26.    * @brief  Configures the FSMC and GPIOs to interface with the NAND memory. 
  27.    *   This function must be called before any write/read operation 
  28.    *   on the NAND. 
  29.    * @param  None 
  30.    * @retval : None 
  31.    */  
  32.  void FSMC_NAND_Init(void)  
  33.  {  
  34.    GPIO_InitTypeDef GPIO_InitStructure;  
  35.    FSMC_NANDInitTypeDef FSMC_NANDInitStructure;  
  36.    FSMC_NAND_PCCARDTimingInitTypeDef  p;  
  37.     
  38.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |  
  39.                           RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);  
  40.     
  41.  /*-- GPIO Configuration ------------------------------------------------------*/  
  42.  /* CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */  
  43.    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |   
  44.                                   GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |  
  45.                                   GPIO_Pin_7;                                   
  46.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  47.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  48.    
  49.    GPIO_Init(GPIOD, &GPIO_InitStructure);  
  50.    
  51.  /* D4->D7 NAND pin configuration  */   
  52.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;  
  53.    
  54.    GPIO_Init(GPIOE, &GPIO_InitStructure);  
  55.    
  56.    
  57.  /* NWAIT NAND pin configuration */  
  58.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;            
  59.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  60.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
  61.    
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);  
  63.    
  64.  /* INT2 NAND pin configuration */   
  65.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;            
  66.    GPIO_Init(GPIOG, &GPIO_InitStructure);  
  67.    
  68.    /*-- FSMC Configuration ------------------------------------------------------*/  
  69.    p.FSMC_SetupTime = 0x1;  
  70.    p.FSMC_WaitSetupTime = 0x3;  
  71.    p.FSMC_HoldSetupTime = 0x2;  
  72.    p.FSMC_HiZSetupTime = 0x1;  
  73.    
  74.    FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;  
  75.    FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;  
  76.    FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;  
  77.    FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;  
  78.    FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;  
  79.    FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;  
  80.    FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;  
  81.    FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;  
  82.    FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;  
  83.    
  84.    FSMC_NANDInit(&FSMC_NANDInitStructure);  
  85.    
  86.    /* FSMC NAND Bank Cmd Test */  
  87.    FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);  
  88.  }  
  89.     
  90.  /** 
  91.    * @brief  Reads NAND memory‘s ID. 
  92.    * @param  NAND_ID: pointer to a NAND_IDTypeDef structure which will hold 
  93.    *                  the Manufacturer and Device ID.  
  94.    * @retval : None 
  95.    */  
  96.  void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)  
  97.  {  
  98.    uint32_t data = 0;  
  99.    
  100.    /* Send Command to the command area */    
  101.    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA)  = NAND_CMD_READID;  
  102.    /* Send Address to the address area */  
  103.    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = NAND_CMD_IDADDR;  
  104.    
  105.     /* Sequence to read ID from NAND flash */   
  106.     data = *(__IO uint32_t *)(Bank_NAND_ADDR | DATA_AREA);  
  107.    
  108.     NAND_ID->Maker_ID   = DATA_1st_CYCLE (data);  
  109.     NAND_ID->Device_ID  = DATA_2nd_CYCLE (data);  
  110.     NAND_ID->Third_ID   = DATA_3rd_CYCLE (data);  
  111.     NAND_ID->Fourth_ID  = DATA_4th_CYCLE (data);   
  112.  }  
  113.  /** 
  114.    * @brief  This routine is for move one 2048 Bytes Page size to an other 2048 Bytes Page. 
  115.    *         the copy-back program is permitted just between odd address pages or even address pages. 
  116.    * @param  SourcePageAddress: Source page address 
  117.    * @param  TargetPageAddress: Target page address 
  118.    * @retval : New status of the NAND operation. This parameter can be: 
  119.    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
  120.    *                a Timeout error 
  121.    *              - NAND_READY: when memory is ready for the next operation 
  122.    *                And the new status of the increment address operation. It can be: 
  123.    *              - NAND_VALID_ADDRESS: When the new address is valid address 
  124.    *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
  125.    */  
  126.  uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress, uint32_t TargetPageAddress)  
  127.  {  
  128.    uint32_t status = NAND_READY ;  
  129.    uint32_t data = 0xff;  
  130.    
  131.      /* Page write command and address */  
  132.      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE0;  
  133.    
  134.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(SourcePageAddress);   
  135.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(SourcePageAddress);   
  136.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(SourcePageAddress);   
  137.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(SourcePageAddress);  
  138.    
  139.      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE1;  
  140.    
  141.      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );  
  142.    
  143.       *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE2;  
  144.    
  145.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(TargetPageAddress);   
  146.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(TargetPageAddress);   
  147.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(TargetPageAddress);   
  148.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(TargetPageAddress);  
  149.    
  150.      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE3;  
  151.    
  152.      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );    
  153.    
  154.      /* Check status for successful operation */  
  155.      status = FSMC_NAND_GetStatus();  
  156.       
  157.   data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);  
  158.   if(!(data&0x1)) status = NAND_READY;  
  159.       
  160.   return (status);  
  161.  }  
  162.  /** 
  163.    * @brief  This routine is for writing one or several 2048 Bytes Page size. 
  164.    * @param  pBuffer: pointer on the Buffer containing data to be written 
  165.    * @param  PageAddress: First page address 
  166.    * @param  NumPageToWrite: Number of page to write  
  167.    * @retval : New status of the NAND operation. This parameter can be: 
  168.    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
  169.    *                a Timeout error 
  170.    *              - NAND_READY: when memory is ready for the next operation 
  171.    *                And the new status of the increment address operation. It can be: 
  172.    *              - NAND_VALID_ADDRESS: When the new address is valid address 
  173.    *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
  174.    */  
  175.    
  176.  uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, uint32_t PageAddress, uint32_t NumPageToWrite)  
  177.  {  
  178.    uint32_t index = 0x00, numpagewritten = 0x00,addressstatus = NAND_VALID_ADDRESS;  
  179.    uint32_t status = NAND_READY, size = 0x00;  
  180.    uint32_t data = 0xff;  
  181.    
  182.    while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))  
  183.    {  
  184.      /* Page write command and address */  
  185.      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;  
  186.    
  187.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(PageAddress);   
  188.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(PageAddress);   
  189.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress);   
  190.      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);  
  191.       
  192.      /* Calculate the size */  
  193.      size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);  
  194.    
  195.      /* Write data */  
  196.      for(; index < size; index++)  
  197.      {  
  198.        *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];  
  199.      }  
  200.       
  201.      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE1;  
  202.    
  203.      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );  
  204.       
  205.      /* Check status for successful operation */  
  206.      status = FSMC_NAND_GetStatus();  
  207.       
  208.   data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);  
  209.   if(!(data&0x1)) status = NAND_READY;  
  210.       
  211.      if(status == NAND_READY)  
  212.      {  
  213.        numpagewritten++; NumPageToWrite--;  
  214.    
  215.        /* Calculate Next small page Address */  
  216.        if(PageAddress++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE))  
  217.        { addressstatus = NAND_INVALID_ADDRESS;}   
  218.      }     
  219.    }  
  220.     
  221.    return (status | addressstatus);  
  222.  }  
  223.     
  224.  /** 
  225.    * @brief  This routine is for sequential read from one or several 
  226.    *         2048 Bytes Page size.  
  227.    * @param  pBuffer: pointer on the Buffer to fill 
  228.    * @param  PageAddress: First page address 
  229.    * @param  NumPageToRead: Number of page to read  
  230.    * @retval : New status of the NAND operation. This parameter can be: 
  231.    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
  232.    *                a Timeout error 
  233.    *              - NAND_READY: when memory is ready for the next operation 
  234.    *                And the new status of the increment address operation. It can be: 
  235.    *              - NAND_VALID_ADDRESS: When the new address is valid address 
  236.    *              - NAND_INVALID_ADDRESS: When the new address is invalid address 
  237.    */  
  238.     
  239.     
  240.  uint32_t FSMC_NAND_ReadSmallPage(uint8_t *pBuffer, uint32_t PageAddress, uint32_t NumPageToRead)  
  241.  {  
  242.    uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;  
  243.    uint32_t status = NAND_READY, size = 0x00;  
  244.    
  245.   *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ1;  
  246.       
  247.   while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))  
  248.     {     
  249.       /* Page Read command and page address */  
  250.      
  251.    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(PageAddress);  
  252.       *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(PageAddress);  
  253.       *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress);  
  254.       *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);  
  255.           
  256.       *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ2;  
  257.    
  258.       while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );  
  259.        
  260.       /* Calculate the size */  
  261.       size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);  
  262.        
  263.       /* Get Data into Buffer */     
  264.       for(; index < size; index++)  
  265.       {  
  266.         pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);  
  267.       }  
  268.     
  269.       numpageread++; NumPageToRead--;  
  270.    
  271.       /* Calculate page address */                
  272.    if(PageAddress++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE))  
  273.    { addressstatus = NAND_INVALID_ADDRESS;}  
  274.   }  
  275.    
  276.     status = FSMC_NAND_GetStatus();  
  277.     
  278.     return (status | addressstatus);  
  279.  }  
  280.     
  281.  /** 
  282.    * @brief  This routine erase complete block from NAND FLASH 
  283.    * @param  PageAddress: Any address into block to be erased 
  284.    * @retval :New status of the NAND operation. This parameter can be: 
  285.    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
  286.    *                a Timeout error 
  287.    *              - NAND_READY: when memory is ready for the next operation 
  288.    */  
  289.     
  290.  uint32_t FSMC_NAND_EraseBlock(uint32_t PageAddress)  
  291.  {  
  292.   uint32_t data = 0xff, status = NAND_ERROR;  
  293.     
  294.    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;  
  295.    
  296.    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress);  
  297.    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);  
  298.      
  299.    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;  
  300.    
  301.    while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );  
  302.    
  303.    /* Read status operation ------------------------------------ */   
  304.    FSMC_NAND_GetStatus();  
  305.    
  306.    data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);  
  307.     
  308.    if(!(data&0x1)) status = NAND_READY;  
  309.       
  310.    return (status);  
  311.  }  
  312.    
  313.  /** 
  314.    * @brief  This routine reset the NAND FLASH 
  315.    * @param  None 
  316.    * @retval :NAND_READY 
  317.    */  
  318.    
  319.  uint32_t FSMC_NAND_Reset(void)  
  320.  {  
  321.    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;  
  322.    
  323.    return (NAND_READY);  
  324.  }  
  325.    
  326.  /** 
  327.    * @brief  Get the NAND operation status 
  328.    * @param  None 
  329.    * @retval :New status of the NAND operation. This parameter can be: 
  330.    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
  331.    *                a Timeout error 
  332.    *              - NAND_READY: when memory is ready for the next operation    
  333.    */  
  334.     
  335.     
  336.  uint32_t FSMC_NAND_GetStatus(void)  
  337.  {  
  338.    uint32_t timeout = 0x1000000, status = NAND_READY;  
  339.    
  340.    status = FSMC_NAND_ReadStatus();  
  341.    
  342.    /* Wait for a NAND operation to complete or a TIMEOUT to occur */  
  343.    while ((status != NAND_READY) &&( timeout != 0x00))  
  344.    {  
  345.       status = FSMC_NAND_ReadStatus();  
  346.       timeout --;       
  347.    }  
  348.    
  349.    if(timeout == 0x00)  
  350.    {           
  351.      status =  NAND_TIMEOUT_ERROR;       
  352.    }  
  353.    
  354.    /* Return the operation status */  
  355.    return (status);       
  356.  }  
  357.     
  358.  /** 
  359.    * @brief  Reads the NAND memory status using the Read status command 
  360.    * @param  None 
  361.    * @retval :The status of the NAND memory. This parameter can be: 
  362.    *              - NAND_BUSY: when memory is busy 
  363.    *              - NAND_READY: when memory is ready for the next operation    
  364.    *              - NAND_ERROR: when the previous operation gererates error     
  365.    */  
  366.     
  367.  uint32_t FSMC_NAND_ReadStatus(void)  
  368.  {  
  369.    uint32_t data = 0x00, status = NAND_BUSY;  
  370.    
  371.    /* Read status operation ------------------------------------ */  
  372.    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;  
  373.    data = *(__IO uint8_t *)(Bank_NAND_ADDR);  
  374.    
  375.    if((data & NAND_ERROR) == NAND_ERROR)  
  376.    {  
  377.      status = NAND_ERROR;  
  378.    }  
  379.    else if((data & NAND_READY) == NAND_READY)  
  380.    {  
  381.      status = NAND_READY;  
  382.    }  
  383.    else  
  384.    {  
  385.      status = NAND_BUSY;  
  386.    }  
  387.     
  388.    return (status);  
  389.  }  


 

2,fsmc_nand.h文件:
 

[cpp] view plaincopy
 
    1. /* Define to prevent recursive inclusion -------------------------------------*/  
    2.  #ifndef __FSMC_NAND_H  
    3.  #define __FSMC_NAND_H  
    4.    
    5.  /* Includes ------------------------------------------------------------------*/  
    6.  #include "stm32f10x.h"  
    7.    
    8.  /* Exported types ------------------------------------------------------------*/  
    9.  typedef struct  
    10.  {  
    11.    uint8_t Maker_ID;  
    12.    uint8_t Device_ID;  
    13.    uint8_t Third_ID;  
    14.    uint8_t Fourth_ID;  
    15.  }NAND_IDTypeDef;  
    16.    
    17.  typedef struct  
    18.  {  
    19.    uint16_t Zone;  
    20.    uint16_t Block;  
    21.    uint16_t Page;  
    22.  } NAND_ADDRESS;  
    23.    
    24.  /* Exported constants --------------------------------------------------------*/  
    25.  /* NAND Area definition  for STM3210E-EVAL Board RevD */  
    26.  #define CMD_AREA                   (uint32_t)(1<<16)  /* A16 = CLE high */  
    27.  #define ADDR_AREA                  (uint32_t)(1<<17)  /* A17 = ALE high */  
    28.  #define DATA_AREA                  ((uint32_t)0x00000000)  
    29.    
    30.  /* FSMC NAND memory command */  
    31.  #define NAND_CMD_READ1             ((uint8_t)0x00)  
    32.  #define NAND_CMD_READ2            ((uint8_t)0x30)  
    33.    
    34.  #define NAND_CMD_WRITE0            ((uint8_t)0x80)  
    35.  #define NAND_CMD_WRITE1            ((uint8_t)0x10)  
    36.    
    37.  #define NAND_CMD_MOVE0             ((uint8_t)0x00)  
    38.  #define NAND_CMD_MOVE1             ((uint8_t)0x35)  
    39.  #define NAND_CMD_MOVE2             ((uint8_t)0x85)  
    40.  #define NAND_CMD_MOVE3             ((uint8_t)0x10)  
    41.     
    42.  #define NAND_CMD_ERASE0            ((uint8_t)0x60)  
    43.  #define NAND_CMD_ERASE1            ((uint8_t)0xD0)   
    44.    
    45.  #define NAND_CMD_READID            ((uint8_t)0x90)  
    46.  #define NAND_CMD_IDADDR            ((uint8_t)0x00)  
    47.     
    48.  #define NAND_CMD_STATUS            ((uint8_t)0x70)  
    49.  #define NAND_CMD_RESET             ((uint8_t)0xFF)  
    50.    
    51.  /* NAND memory status */  
    52.  #define NAND_VALID_ADDRESS         ((uint32_t)0x00000100)  
    53.  #define NAND_INVALID_ADDRESS       ((uint32_t)0x00000200)  
    54.  #define NAND_TIMEOUT_ERROR         ((uint32_t)0x00000400)  
    55.  #define NAND_BUSY                  ((uint32_t)0x00000000)  
    56.  #define NAND_ERROR                 ((uint32_t)0x00000001)  
    57.  #define NAND_READY                 ((uint32_t)0x00000040)  
    58.    
    59.  /* FSMC NAND memory parameters */  
    60.  //#define NAND_PAGE_SIZE             ((uint16_t)0x0200) /* 512 bytes per page w/o Spare Area */  
    61.  //#define NAND_BLOCK_SIZE            ((uint16_t)0x0020) /* 32x512 bytes pages per block */  
    62.  //#define NAND_ZONE_SIZE             ((uint16_t)0x0400) /* 1024 Block per zone */  
    63.  //#define NAND_SPARE_AREA_SIZE       ((uint16_t)0x0010) /* last 16 bytes as spare area */  
    64.  //#define NAND_MAX_ZONE              ((uint16_t)0x0004) /* 4 zones of 1024 block */  
    65.    
    66.  /* FSMC NAND memory HY27UF081G2A-TPCB parameters */  
    67.  #define NAND_PAGE_SIZE             ((uint16_t)0x0800) /* 2048 bytes per page w/o Spare Area */  
    68.  #define NAND_BLOCK_SIZE            ((uint16_t)0x0040) /* 64x2048 bytes pages per block */  
    69.  #define NAND_ZONE_SIZE             ((uint16_t)0x0200) /* 512 Block per zone */  
    70.  #define NAND_SPARE_AREA_SIZE       ((uint16_t)0x0040) /* last 64 bytes as spare area */  
    71.  #define NAND_MAX_ZONE              ((uint16_t)0x0002) /* 2 zones of 1024 block */  
    72.    
    73.  /* FSMC NAND memory data computation */  
    74.  #define DATA_1st_CYCLE(DATA)       (uint8_t)((DATA)& 0xFF)               /* 1st data cycle */  
    75.  #define DATA_2nd_CYCLE(DATA)       (uint8_t)(((DATA)& 0xFF00) >> 8)      /* 2nd data cycle */  
    76.  #define DATA_3rd_CYCLE(DATA)       (uint8_t)(((DATA)& 0xFF0000) >> 16)   /* 3rd data cycle */  
    77.  #define DATA_4th_CYCLE(DATA)       (uint8_t)(((DATA)& 0xFF000000) >> 24) /* 4th data cycle */  
    78.    
    79.  /* FSMC NAND memory HY27UF081G2A-TPCB address computation */  
    80.  #define ADDR_1st_CYCLE(PADDR)       (uint8_t)(0x0)          /* 1st addressing cycle */  
    81.  #define ADDR_2nd_CYCLE(PADDR)       (uint8_t)(0x0)     /* 2nd addressing cycle */  
    82.  #define ADDR_3rd_CYCLE(PADDR)       (uint8_t)(PADDR & 0xFF)      /* 3rd addressing cycle */  
    83.  #define ADDR_4th_CYCLE(PADDR)       (uint8_t)((PADDR>>8) & 0xFF) /* 4th addressing cycle */  
    84.    
    85.  /* Exported macro ------------------------------------------------------------*/  
    86.  /* Exported functions ------------------------------------------------------- */  
    87.  void FSMC_NAND_Init(void);  
    88.  void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID);  
    89.  uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, uint32_t Address, uint32_t NumPageToWrite);  
    90.  uint32_t FSMC_NAND_ReadSmallPage (uint8_t *pBuffer, uint32_t Address, uint32_t NumPageToRead);  
    91.  uint32_t FSMC_NAND_MoveSmallPage (uint32_t SourcePageAddress, uint32_t TargetPageAddress);  
    92.  //uint32_t FSMC_NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite);  
    93.  //uint32_t FSMC_NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead);  
    94.  uint32_t FSMC_NAND_EraseBlock(uint32_t Address);  
    95.  uint32_t FSMC_NAND_Reset(void);  
    96.  uint32_t FSMC_NAND_GetStatus(void);  
    97.  uint32_t FSMC_NAND_ReadStatus(void);  
    98.  //uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);  
    99.    
    100.  #endif /* __FSMC_NAND_H */  

STM32-移植FATFS的NANDFLASH驱动

标签:

原文地址:http://www.cnblogs.com/wjgaas/p/3870701.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!