9G-STM32 EWARM开发过程简介之五

发布者:caijt最新更新时间:2015-07-30 来源: eefocus关键字:9G-STM32  EWARM  开发过程 手机看文章 扫描二维码
随时随地手机看文章
9G-STM32 EWARM开发过程简介之五--移植FATFS的NANDFLASH驱动

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

三,修改FATFS的配置文件
 1,把D:worksEK-STM3210E-UCOSIIFatfs下的ff.h中的宏定义:
  #define _USE_MKFS 0
  #define _CODE_PAGE 932
  #define _FS_RPATH 0
  #define _MAX_SS  512
  修改为:
  #define _USE_MKFS 1
  #define _CODE_PAGE 936
  #define _MAX_SS  2048
  #define _FS_RPATH 1
 2,把D:worksEK-STM3210E-UCOSIIFatfs下的integer.h的宏定义:
  typedef enum { FALSE = 0, TRUE } BOOL;
  修改为:
  typedef bool BOOL;//typedef enum { FALSE = 0, TRUE } BOOL;
四,修改FATFS的DISK/IO接口
 1,把diskio.c复制后改名为nandio.c替换掉工程中的diskio.c,并添加到EWARM的工程中的
  “FATFS”文件组;
 2,媒介初始化直接返回正常的0:
  DSTATUS disk_initialize (BYTE drv)
  {  return 0;}
 3,媒介状态查询直接返回正常的0:
  DSTATUS disk_status (BYTE drv)
  {  return 0;}
 4,取系统系统直接返回0(自己可以按格式修改为真实时间):
  DWORD get_fattime (void)
  {  return 0;}
 5,媒介控制接口:
  DRESULT disk_ioctl (BYTE drv,BYTE ctrl, void *buff)
  {
   DRESULT res = RES_OK;
   uint32_t result;

      if (drv){ return RES_PARERR;}
    
      switch(ctrl)
      {
       case CTRL_SYNC:
           break;
    case GET_BLOCK_SIZE:
           *(DWORD*)buff = NAND_BLOCK_SIZE;
           break;
    case GET_SECTOR_COUNT:
           *(DWORD*)buff = (((NAND_MAX_ZONE/2) * NAND_ZONE_SIZE) * NAND_BLOCK_SIZE);
           break;
    case GET_SECTOR_SIZE:
           *(WORD*)buff = NAND_PAGE_SIZE;
           break;
       default:
           res = RES_PARERR;
           break;
   }
      return res;
  }
 6,媒介多扇区读接口:
  DRESULT disk_read (BYTE drv,BYTE *buff,DWORD sector,BYTE count)
  {
   uint32_t result;

      if (drv || !count){  return RES_PARERR;}
   result = FSMC_NAND_ReadSmallPage(buff, sector, count);                                                
      if(result & NAND_READY){  return RES_OK; }
      else { return RES_ERROR;  }
  }
 7,媒介多扇区写接口:
  #if _READONLY == 0
  DRESULT disk_write (BYTE drv,const BYTE *buff,DWORD sector,BYTE count)
  {
   uint32_t result;
   uint32_t BackupBlockAddr;
   uint32_t WriteBlockAddr;
   uint16_t IndexTmp = 0;
   uint16_t OffsetPage;
  
   /* NAND memory write page at block address*/
   WriteBlockAddr = (sector/NAND_BLOCK_SIZE);
   /* NAND memory backup block address*/
   BackupBlockAddr = (WriteBlockAddr + (NAND_MAX_ZONE/2)*NAND_ZONE_SIZE);
   OffsetPage = sector%NAND_BLOCK_SIZE;
  
      if (drv || !count){  return RES_PARERR;}
    
   /* Erase the NAND backup Block */
      result = FSMC_NAND_EraseBlock(BackupBlockAddr*NAND_BLOCK_SIZE);
  
      /* Backup the NAND Write Block to High zone*/
  
   for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ )
   {
    FSMC_NAND_MoveSmallPage (WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp);
   }
  
   /* Erase the NAND Write Block */
   result = FSMC_NAND_EraseBlock(WriteBlockAddr*NAND_BLOCK_SIZE);
  
      /*return write the block  with modify*/
   for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ )
   {
    if((IndexTmp>=OffsetPage)&&(IndexTmp < (OffsetPage+count)))
    {
     FSMC_NAND_WriteSmallPage((uint8_t *)buff, WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp, 1);
     buff = (uint8_t *)buff + NAND_PAGE_SIZE;
       }
    else
    {
          FSMC_NAND_MoveSmallPage (BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp);
       }
   }    
   
      if(result == NAND_READY){   return RES_OK;}
      else {   return RES_ERROR;}
  }
  #endif /* _READONLY */
五,调用接口及测试代码
 1,调用接口,先初始化FSMC和NANDFLASH:
  //NANDFLASH HY27UF081G2A-TPCB
  #define NAND_HY_MakerID     0xAD
  #define NAND_HY_DeviceID    0xF1
  
  /* Configure the NAND FLASH */
  void NAND_Configuration(void)
  {
   NAND_IDTypeDef NAND_ID;
   
   /* Enable the FSMC Clock */
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
    
      /* FSMC Initialization */
   FSMC_NAND_Init();
  
   /* NAND read ID command */
   FSMC_NAND_ReadID(&NAND_ID);
     
   /* Verify the NAND ID */
   if((NAND_ID.Maker_ID == NAND_ST_MakerID) && (NAND_ID.Device_ID == NAND_ST_DeviceID))
   {
          printf("ST NANDFLASH");
   }
      else
      if((NAND_ID.Maker_ID == NAND_HY_MakerID) && (NAND_ID.Device_ID == NAND_HY_DeviceID))
   {
          printf("HY27UF081G2A-TPCB");
   }
   printf(" ID = 0x%x%x%x%x ",NAND_ID.Maker_ID,NAND_ID.Device_ID,NAND_ID.Third_ID,NAND_ID.Fourth_ID);
  }
 2,然后对媒介格式化,创建读写文件:
  void test_fatfs(void)
  {
      FATFS fs;
   FIL fl;
   FATFS *pfs;
   DWORD clust;
   unsigned int r,w,i;
   FRESULT  res;
   
  // NF_CHKDSK(0,1024);
   display_page(0,0);
   
  // for mount 
   res=f_mount(0,&fs);
   printf("f_mount=%x ",res);
   
  // for format
   //res=f_mkfs(0,1,2048);  //MUST Format for New NANDFLASH !!!
   //printf("f_mkfs=%x ",res);
  
  // for 
   pfs=&fs;
   res = f_getfree("/", &clust, &pfs);
   printf("f_getfree=%x ",res);
   printf(" %lu MB total drive space."
       " %lu MB available. ",
     (DWORD)(pfs->max_clust - 2) * pfs->csize /2/1024,
     clust * pfs->csize /2/1024);
   
  // for read
      res=f_open(&fl,"/test2.dat",FA_OPEN_EXISTING | FA_READ);
      printf("f_open=%x ",res);
   for(i=0;i<2;i++)
   {
    for(r = 0; r < NAND_PAGE_SIZE; r++)
    {
     RxBuffer[r]= 0xff;
    }
    
    res=f_read(&fl,RxBuffer,NAND_PAGE_SIZE,&r);
    printf("f_read=%x ",res);
    if(res || r == 0)break;
    for(r = 0; r < NAND_PAGE_SIZE; r++)
       {
           printf("D[%08x]=%02x ",(i*NAND_PAGE_SIZE+r),RxBuffer[r]);
           if((r%8)==7)
           {printf(" ");}
       }
       
   }
   f_close(&fl);
  // for write
   res=f_open(&fl,"/test2.dat",FA_CREATE_ALWAYS | FA_WRITE);
   printf("f_open=%x ",res);
   for(i=0;i<2;i++)
   {
    for(w = 0; w < NAND_PAGE_SIZE; w++)
    {
     TxBuffer[w]=((w<<0)&0xff);
    }
          res=f_write(&fl,TxBuffer,NAND_PAGE_SIZE,&w);
          printf("f_write=%x ",res);
    if(res || w     
   }
   f_close(&fl);
   
  // for umount
   f_mount(0,NULL);
  }

六,编写NANDFLASH接口
 1,fsmc_nand.c文件:
  /* Includes ------------------------------------------------------------------*/
  #include "fsmc_nand.h"
  #include "stm32f10x_conf.h"
  
  /** @addtogroup StdPeriph_Examples
    * @{
    */
  
  /** @addtogroup FSMC_NAND
    * @{
    */ 
  
  /* Private typedef -----------------------------------------------------------*/
  /* Private define ------------------------------------------------------------*/
  
  #define FSMC_Bank_NAND     FSMC_Bank2_NAND
  #define Bank_NAND_ADDR     Bank2_NAND_ADDR 
  #define Bank2_NAND_ADDR    ((uint32_t)0x70000000)
  
  /* Private macro -------------------------------------------------------------*/
  /* Private variables ---------------------------------------------------------*/
  /* Private function prototypes -----------------------------------------------*/
  /* Private functions ---------------------------------------------------------*/
  
  /**
    * @brief  Configures the FSMC and GPIOs to interface with the NAND memory.
    *   This function must be called before any write/read operation
    *   on the NAND.
    * @param  None
    * @retval : None
    */
  void FSMC_NAND_Init(void)
  {
    GPIO_InitTypeDef GPIO_InitStructure; 
    FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
    FSMC_NAND_PCCARDTimingInitTypeDef  p;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | 
                           RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
    
  /*-- GPIO Configuration ------------------------------------------------------*/
  /* CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |  
                                   GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | 
                                   GPIO_Pin_7;                                  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  
    GPIO_Init(GPIOD, &GPIO_InitStructure); 
  
  /* D4->D7 NAND pin configuration  */  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
  
    GPIO_Init(GPIOE, &GPIO_InitStructure);
  
  
  /* NWAIT NAND pin configuration */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  
    GPIO_Init(GPIOD, &GPIO_InitStructure); 
  
  /* INT2 NAND pin configuration */  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           
    GPIO_Init(GPIOG, &GPIO_InitStructure);
  
    /*-- FSMC Configuration ------------------------------------------------------*/
    p.FSMC_SetupTime = 0x1;
    p.FSMC_WaitSetupTime = 0x3;
    p.FSMC_HoldSetupTime = 0x2;
    p.FSMC_HiZSetupTime = 0x1;
  
    FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
    FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
    FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
    FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
    FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
    FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
    FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
    FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
    FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
  
    FSMC_NANDInit(&FSMC_NANDInitStructure);
  
    /* FSMC NAND Bank Cmd Test */
    FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
  }
    
  /**
    * @brief  Reads NAND memory's ID.
    * @param  NAND_ID: pointer to a NAND_IDTypeDef structure which will hold
    *                  the Manufacturer and Device ID.  
    * @retval : None
    */
  void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)
  {
    uint32_t data = 0;
  
    /* Send Command to the command area */  
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA)  = NAND_CMD_READID;
    /* Send Address to the address area */ 
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = NAND_CMD_IDADDR;
  
     /* Sequence to read ID from NAND flash */ 
     data = *(__IO uint32_t *)(Bank_NAND_ADDR | DATA_AREA);
  
     NAND_ID->Maker_ID   = DATA_1st_CYCLE (data);
     NAND_ID->Device_ID  = DATA_2nd_CYCLE (data);
     NAND_ID->Third_ID   = DATA_3rd_CYCLE (data);
     NAND_ID->Fourth_ID  = DATA_4th_CYCLE (data);  
  }
  /**
    * @brief  This routine is for move one 2048 Bytes Page size to an other 2048 Bytes Page.
    *         the copy-back program is permitted just between odd address pages or even address pages.
    * @param  SourcePageAddress: Source page address
    * @param  TargetPageAddress: Target page address
    * @retval : New status of the NAND operation. This parameter can be:
    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
    *                a Timeout error
    *              - NAND_READY: when memory is ready for the next operation 
    *                And the new status of the increment address operation. It can be:
    *              - NAND_VALID_ADDRESS: When the new address is valid address
    *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
    */
  uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress, uint32_t TargetPageAddress)
  {
    uint32_t status = NAND_READY ;
    uint32_t data = 0xff;
  
      /* Page write command and address */
      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE0;
  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(SourcePageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(SourcePageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(SourcePageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(SourcePageAddress); 
  
      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE1;
  
      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
   
       *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE2;
  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(TargetPageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(TargetPageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(TargetPageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(TargetPageAddress); 
  
      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE3;
  
      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );   
  
      /* Check status for successful operation */
      status = FSMC_NAND_GetStatus();
      
   data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
   if(!(data&0x1)) status = NAND_READY;
      
   return (status);
  }[page]
  /**
    * @brief  This routine is for writing one or several 2048 Bytes Page size.
    * @param  pBuffer: pointer on the Buffer containing data to be written 
    * @param  PageAddress: First page address
    * @param  NumPageToWrite: Number of page to write  
    * @retval : New status of the NAND operation. This parameter can be:
    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
    *                a Timeout error
    *              - NAND_READY: when memory is ready for the next operation 
    *                And the new status of the increment address operation. It can be:
    *              - NAND_VALID_ADDRESS: When the new address is valid address
    *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
    */
  
  uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, uint32_t PageAddress, uint32_t NumPageToWrite)
  {
    uint32_t index = 0x00, numpagewritten = 0x00,addressstatus = NAND_VALID_ADDRESS;
    uint32_t status = NAND_READY, size = 0x00;
    uint32_t data = 0xff;
  
    while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
    {
      /* Page write command and address */
      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(PageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(PageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress);  
      *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress); 
      
      /* Calculate the size */
      size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
  
      /* Write data */
      for(; index < size; index++)
      {
        *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
      }
      
      *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE1;
  
      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
      
      /* Check status for successful operation */
      status = FSMC_NAND_GetStatus();
      
   data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
   if(!(data&0x1)) status = NAND_READY;
      
      if(status == NAND_READY)
      {
        numpagewritten++; NumPageToWrite--;
  
        /* Calculate Next small page Address */
        if(PageAddress++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE))
        { addressstatus = NAND_INVALID_ADDRESS;}  
      }    
    }
    
    return (status | addressstatus);
  }
    
  /**
    * @brief  This routine is for sequential read from one or several
    *         2048 Bytes Page size.  
    * @param  pBuffer: pointer on the Buffer to fill
    * @param  PageAddress: First page address
    * @param  NumPageToRead: Number of page to read  
    * @retval : New status of the NAND operation. This parameter can be:
    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
    *                a Timeout error
    *              - NAND_READY: when memory is ready for the next operation 
    *                And the new status of the increment address operation. It can be:
    *              - NAND_VALID_ADDRESS: When the new address is valid address
    *              - NAND_INVALID_ADDRESS: When the new address is invalid address
    */
    
    
  uint32_t FSMC_NAND_ReadSmallPage(uint8_t *pBuffer, uint32_t PageAddress, uint32_t NumPageToRead)
  {
    uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
    uint32_t status = NAND_READY, size = 0x00;
  
   *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ1; 
      
   while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
     {    
       /* Page Read command and page address */
     
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(PageAddress); 
       *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(PageAddress); 
       *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress); 
       *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress); 
          
       *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ2; 
  
       while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
       
       /* Calculate the size */
       size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
       
       /* Get Data into Buffer */    
       for(; index < size; index++)
       {
         pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
       }
   
       numpageread++; NumPageToRead--;
  
       /* Calculate page address */               
    if(PageAddress++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE))
    { addressstatus = NAND_INVALID_ADDRESS;} 
   }
  
     status = FSMC_NAND_GetStatus();
    
     return (status | addressstatus);
  }
    
  /**
    * @brief  This routine erase complete block from NAND FLASH
    * @param  PageAddress: Any address into block to be erased
    * @retval :New status of the NAND operation. This parameter can be:
    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
    *                a Timeout error
    *              - NAND_READY: when memory is ready for the next operation 
    */
    
  uint32_t FSMC_NAND_EraseBlock(uint32_t PageAddress)
  {
   uint32_t data = 0xff, status = NAND_ERROR;
   
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;
  
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);
    
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1; 
  
    while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );
  
    /* Read status operation ------------------------------------ */  
    FSMC_NAND_GetStatus();
  
    data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
    
    if(!(data&0x1)) status = NAND_READY;
     
    return (status);
  }
  
  /**
    * @brief  This routine reset the NAND FLASH
    * @param  None
    * @retval :NAND_READY
    */
  
  uint32_t FSMC_NAND_Reset(void)
  {
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;
  
    return (NAND_READY);
  }
  
  /**
    * @brief  Get the NAND operation status
    * @param  None
    * @retval :New status of the NAND operation. This parameter can be:
    *              - NAND_TIMEOUT_ERROR: when the previous operation generate 
    *                a Timeout error
    *              - NAND_READY: when memory is ready for the next operation    
    */
    
    
  uint32_t FSMC_NAND_GetStatus(void)
  {
    uint32_t timeout = 0x1000000, status = NAND_READY;
  
    status = FSMC_NAND_ReadStatus(); 
  
    /* Wait for a NAND operation to complete or a TIMEOUT to occur */
    while ((status != NAND_READY) &&( timeout != 0x00))
    {
       status = FSMC_NAND_ReadStatus();
       timeout --;      
    }
  
    if(timeout == 0x00)
    {          
      status =  NAND_TIMEOUT_ERROR;      
    } 
  
    /* Return the operation status */
    return (status);      
  }
    
  /**
    * @brief  Reads the NAND memory status using the Read status command 
    * @param  None
    * @retval :The status of the NAND memory. This parameter can be:
    *              - NAND_BUSY: when memory is busy
    *              - NAND_READY: when memory is ready for the next operation    
    *              - NAND_ERROR: when the previous operation gererates error     
    */
    
  uint32_t FSMC_NAND_ReadStatus(void)
  {
    uint32_t data = 0x00, status = NAND_BUSY;
  
    /* Read status operation ------------------------------------ */
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
    data = *(__IO uint8_t *)(Bank_NAND_ADDR);
  
    if((data & NAND_ERROR) == NAND_ERROR)
    {
      status = NAND_ERROR;
    } 
    else if((data & NAND_READY) == NAND_READY)
    {
      status = NAND_READY;
    }
    else
    {
      status = NAND_BUSY; 
    }
    
    return (status);
  }
 2,fsmc_nand.h文件:
  /* Define to prevent recursive inclusion -------------------------------------*/
  #ifndef __FSMC_NAND_H
  #define __FSMC_NAND_H
  
  /* Includes ------------------------------------------------------------------*/
  #include "stm32f10x.h"
  
  /* Exported types ------------------------------------------------------------*/
  typedef struct
  {
    uint8_t Maker_ID;
    uint8_t Device_ID;
    uint8_t Third_ID;
    uint8_t Fourth_ID;
  }NAND_IDTypeDef;
  
  typedef struct 
  {
    uint16_t Zone;
    uint16_t Block;
    uint16_t Page;
  } NAND_ADDRESS;
  
  /* Exported constants --------------------------------------------------------*/
  /* NAND Area definition  for STM3210E-EVAL Board RevD */
  #define CMD_AREA                   (uint32_t)(1<<16)  /* A16 = CLE high */
  #define ADDR_AREA                  (uint32_t)(1<<17)  /* A17 = ALE high */
  #define DATA_AREA                  ((uint32_t)0x00000000) 
  
  /* FSMC NAND memory command */
  #define NAND_CMD_READ1             ((uint8_t)0x00)
  #define NAND_CMD_READ2            ((uint8_t)0x30)
  
  #define NAND_CMD_WRITE0            ((uint8_t)0x80)
  #define NAND_CMD_WRITE1            ((uint8_t)0x10)
  
  #define NAND_CMD_MOVE0             ((uint8_t)0x00)
  #define NAND_CMD_MOVE1             ((uint8_t)0x35)
  #define NAND_CMD_MOVE2             ((uint8_t)0x85)
  #define NAND_CMD_MOVE3             ((uint8_t)0x10)
   
  #define NAND_CMD_ERASE0            ((uint8_t)0x60)
  #define NAND_CMD_ERASE1            ((uint8_t)0xD0)  
  
  #define NAND_CMD_READID            ((uint8_t)0x90)
  #define NAND_CMD_IDADDR            ((uint8_t)0x00)
   
  #define NAND_CMD_STATUS            ((uint8_t)0x70)
  #define NAND_CMD_RESET             ((uint8_t)0xFF)
  
  /* NAND memory status */
  #define NAND_VALID_ADDRESS         ((uint32_t)0x00000100)
  #define NAND_INVALID_ADDRESS       ((uint32_t)0x00000200)
  #define NAND_TIMEOUT_ERROR         ((uint32_t)0x00000400)
  #define NAND_BUSY                  ((uint32_t)0x00000000)
  #define NAND_ERROR                 ((uint32_t)0x00000001)
  #define NAND_READY                 ((uint32_t)0x00000040)
  
  /* FSMC NAND memory parameters */
  //#define NAND_PAGE_SIZE             ((uint16_t)0x0200) /* 512 bytes per page w/o Spare Area */
  //#define NAND_BLOCK_SIZE            ((uint16_t)0x0020) /* 32x512 bytes pages per block */
  //#define NAND_ZONE_SIZE             ((uint16_t)0x0400) /* 1024 Block per zone */
  //#define NAND_SPARE_AREA_SIZE       ((uint16_t)0x0010) /* last 16 bytes as spare area */
  //#define NAND_MAX_ZONE              ((uint16_t)0x0004) /* 4 zones of 1024 block */
  
  /* FSMC NAND memory HY27UF081G2A-TPCB parameters */
  #define NAND_PAGE_SIZE             ((uint16_t)0x0800) /* 2048 bytes per page w/o Spare Area */
  #define NAND_BLOCK_SIZE            ((uint16_t)0x0040) /* 64x2048 bytes pages per block */
  #define NAND_ZONE_SIZE             ((uint16_t)0x0200) /* 512 Block per zone */
  #define NAND_SPARE_AREA_SIZE       ((uint16_t)0x0040) /* last 64 bytes as spare area */
  #define NAND_MAX_ZONE              ((uint16_t)0x0002) /* 2 zones of 1024 block */
  
  /* FSMC NAND memory data computation */
  #define DATA_1st_CYCLE(DATA)       (uint8_t)((DATA)& 0xFF)               /* 1st data cycle */
  #define DATA_2nd_CYCLE(DATA)       (uint8_t)(((DATA)& 0xFF00) >> 8)      /* 2nd data cycle */
  #define DATA_3rd_CYCLE(DATA)       (uint8_t)(((DATA)& 0xFF0000) >> 16)   /* 3rd data cycle */
  #define DATA_4th_CYCLE(DATA)       (uint8_t)(((DATA)& 0xFF000000) >> 24) /* 4th data cycle */
  
  /* FSMC NAND memory HY27UF081G2A-TPCB address computation */
  #define ADDR_1st_CYCLE(PADDR)       (uint8_t)(0x0)          /* 1st addressing cycle */
  #define ADDR_2nd_CYCLE(PADDR)       (uint8_t)(0x0)     /* 2nd addressing cycle */
  #define ADDR_3rd_CYCLE(PADDR)       (uint8_t)(PADDR & 0xFF)      /* 3rd addressing cycle */
  #define ADDR_4th_CYCLE(PADDR)       (uint8_t)((PADDR>>8) & 0xFF) /* 4th addressing cycle */
  
  /* Exported macro ------------------------------------------------------------*/
  /* Exported functions ------------------------------------------------------- */
  void FSMC_NAND_Init(void);
  void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID);
  uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, uint32_t Address, uint32_t NumPageToWrite);
  uint32_t FSMC_NAND_ReadSmallPage (uint8_t *pBuffer, uint32_t Address, uint32_t NumPageToRead);
  uint32_t FSMC_NAND_MoveSmallPage (uint32_t SourcePageAddress, uint32_t TargetPageAddress);
  //uint32_t FSMC_NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite);
  //uint32_t FSMC_NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead);
  uint32_t FSMC_NAND_EraseBlock(uint32_t Address);
  uint32_t FSMC_NAND_Reset(void);
  uint32_t FSMC_NAND_GetStatus(void);
  uint32_t FSMC_NAND_ReadStatus(void);
  //uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);
  
  #endif /* __FSMC_NAND_H */
七,NFTL代码层
 有关NFTL代码,自行处理。

关键字:9G-STM32  EWARM  开发过程 引用地址:9G-STM32 EWARM开发过程简介之五

上一篇:9G-STM32 EWARM开发过程简介之四
下一篇:9G-STM8 CXSTM8使用过程简介

推荐阅读最新更新时间:2024-03-16 14:26

FPGA嵌入式系统开发过程中的XBD文件设计
  随着可编程逻辑器件的不断进步和发展,FPGA在嵌入式系统中发挥着越来越重要的作用,已经开始被广泛应用于通信、航天、医疗、工控等领域。Xilinx公司作为全球最大的可编程逻辑器件生产厂商,为嵌入式系统设计人员提供了比较全面的解决方案。Xilinx的嵌入式系统开发环境EDK,提供了一种通用的完全集成的硬件和软件开发环境,使设计人员可以利用单个开发环境快速配置针对PowerPC硬处理器或Microblaze软处理器内核的平台。在EDK开发环境下,利用用户向导可以准确快速地创建一个新的嵌入式系统,而在这一过程中,XBD文件决定了系统的硬件平台描述文件MHS以及约束文件UCF的正确与否,在构建系统过程中起着至关重要的作用。   1
[嵌入式]
FPGA嵌入式系统<font color='red'>开发</font><font color='red'>过程</font>中的XBD文件设计
【32位MCU】9G-CM0 新唐CM0+MDK-ARM入门开发过程简介
9G-CM0 新唐CM0+MDK-ARM入门开发过程简介 一,准备MDK-ARM + 新唐CM0软件包 1,在http://www.mcu123.com/news/Soft/embsof/arm/201006/529.html 下载RealView MDK-ARM 4.12 (MDK-ARM V4.12,MDK4.12) mdk412_mcu123.rar 在http://www.mcu123.com/news/Soft/ShowSoftDown.asp?UrlID=3&SoftID=529上 右击 下载地址: 后的 下载 选择 目标另存为 下载文件到本地硬盘。 (自己查找破解文件 keygen.exe ) http
[单片机]
【32位MCU】9G-STM32 简易BOOT及XMODEM串口IAP移植过程简介
9G-STM32 简易BOOT及XMODEM串口IAP移植过程简介 一,准备EWARM + AN2557软件包 1,在http://www.mcu123.com/news/Soft/embsof/arm/201001/514.html 上 下载 IAR Embedded Workbench for ARM version 5.41 (2010.1.5更新) 软件 CD-EWARM-5411-1760_mcu123.zip http://esoft.mcu123.com/MCU123_temp_20100103@/ARM/CD-EWARM-5411-1760_mcu123.zip 相关文件 IAR_EWARM5.4和谐文
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved