首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STM32-移植FATFS的NANDFLASH驱动(4)

STM32-移植FATFS的NANDFLASH驱动(4)

  • /**
  •    * @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);  
  • }  
  • /**
  •    * @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);  
  • }  
继承事业,薪火相传
返回列表