一,建立工程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中的宏定义:

  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的宏定义:

  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:

  1. DSTATUS disk_initialize (BYTE drv)
  2. {  return 0;}

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

  1. DSTATUS disk_status (BYTE drv)
  2. {  return 0;}

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

  1. DWORD get_fattime (void)
  2. {  return 0;}

5,媒介控制接口:

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

6,媒介多扇区读接口:

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

7,媒介多扇区写接口:

  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. /* NAND memory write page at block address*/
  10. WriteBlockAddr = (sector/NAND_BLOCK_SIZE);
  11. /* NAND memory backup block address*/
  12. BackupBlockAddr = (WriteBlockAddr + (NAND_MAX_ZONE/2)*NAND_ZONE_SIZE);
  13. OffsetPage = sector%NAND_BLOCK_SIZE;
  14. if (drv || !count){  return RES_PARERR;}
  15. /* Erase the NAND backup Block */
  16. result = FSMC_NAND_EraseBlock(BackupBlockAddr*NAND_BLOCK_SIZE);
  17. /* Backup the NAND Write Block to High zone*/
  18. for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ )
  19. {
  20. FSMC_NAND_MoveSmallPage (WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp);
  21. }
  22. /* Erase the NAND Write Block */
  23. result = FSMC_NAND_EraseBlock(WriteBlockAddr*NAND_BLOCK_SIZE);
  24. /*return write the block  with modify*/
  25. for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ )
  26. {
  27. if((IndexTmp>=OffsetPage)&&(IndexTmp < (OffsetPage+count)))
  28. {
  29. FSMC_NAND_WriteSmallPage((uint8_t *)buff, WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp, 1);
  30. buff = (uint8_t *)buff + NAND_PAGE_SIZE;
  31. }
  32. else
  33. {
  34. FSMC_NAND_MoveSmallPage (BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp);
  35. }
  36. }
  37. if(result == NAND_READY){   return RES_OK;}
  38. else {   return RES_ERROR;}
  39. }
  40. #endif /* _READONLY */

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

  1. //NANDFLASH HY27UF081G2A-TPCB
  2. #define NAND_HY_MakerID     0xAD
  3. #define NAND_HY_DeviceID    0xF1
  4. /* Configure the NAND FLASH */
  5. void NAND_Configuration(void)
  6. {
  7. NAND_IDTypeDef NAND_ID;
  8. /* Enable the FSMC Clock */
  9. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
  10. /* FSMC Initialization */
  11. FSMC_NAND_Init();
  12. /* NAND read ID command */
  13. FSMC_NAND_ReadID(&NAND_ID);
  14. /* Verify the NAND ID */
  15. if((NAND_ID.Maker_ID == NAND_ST_MakerID) && (NAND_ID.Device_ID == NAND_ST_DeviceID))
  16. {
  17. printf("ST NANDFLASH");
  18. }
  19. else
  20. if((NAND_ID.Maker_ID == NAND_HY_MakerID) && (NAND_ID.Device_ID == NAND_HY_DeviceID))
  21. {
  22. printf("HY27UF081G2A-TPCB");
  23. }
  24. 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);
  25. }

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

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

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

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

2,fsmc_nand.h文件:

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

STM32-移植FATFS的NANDFLASH驱动的更多相关文章

  1. STM32下FatFs的移植,实现了坏块管理,硬件ECC,ECC纠错,并进行擦写均衡分析

    最近因项目需要,做一个数据采集的单片机平台.需要移植 FatFs .现在把最后成果贴上来. 1.摘要 在 STM32 单片机上,成功移植 FatFs 0.12b,使用的 Nand Flash 芯片为 ...

  2. Nandflash 驱动移植

    前段时间,研究了一下4G的Nandflash驱动.手头上只有飞凌6410BSP自带的Nandflash驱动,该驱动不支持K9GAG08U0D(2G)和K9LBG08U0D(4G)的Nandflash. ...

  3. STM32移植USB驱动总结

    https://blog.csdn.net/stm32_newlearner/article/details/88095944 stm32   移植usb驱动开发 单片机 STM32单片机和51单片机 ...

  4. 【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(七)-准备移植FatFs

    [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(一)-初步认识SD卡 [STM32]使用SDIO进行SD卡读写,包含文件管理FatFs(二)-了解SD总线,命令的相关介绍 [STM3 ...

  5. 【转】hurry_liu 大神STM32移植contiki入门之一:系统介绍和开发环境搭建

    前言: 由于项目的原因,需要在LPC1788(STM32 cortex-M3)上面跑contiki. 之前没有涉及到contiki,不知其为何物.不过这个不是难事,做IT的,每每遇到新事物,都不会处理 ...

  6. 移植Fatfs文件系统到工程中

    下载Fatfs文件管理系统:http://elm-chan.org/fsw/ff/archives.html 下载最新版本 在工程中新建Fatfs文件夹,把fatfs文件中的全部复制过来 由于Fatf ...

  7. STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085和串口只发送数据不能接收数据问题

    STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...

  8. MTD NANDFLASH驱动相关知识介绍

    转:http://blog.csdn.net/zhouzhuan2008/article/details/11053877 目录 MTD总概述 MTD数据结构 MTD相关层实现 MTD,Memory ...

  9. Hello China操作系统STM32移植指南(一)

    Hello China操作系统移植指南 首先说明一下,为了适应更多的文化背景,对Hello China操作系统的名字做了修改,修改为"Hello X",或者连接在一起,写为&quo ...

随机推荐

  1. Restorator软件使exe文件都不能打开,exe不支持此接口

    遇到的问题: 下载了一个软件Restorator(资源修改器),填写完注册码之后,所有的exe文件都不能打开了,任务管理器不支持此接口打不开. 问题原因: 软件Restorator关联exe文件,运行 ...

  2. Hadoop常用操作汇总

    Hadoop Streaming示例程序(wordcount) run_hadoop_word_counter.sh $HADOOP_BIN streaming \ -input "${IN ...

  3. 客户端配置代理服务实现yum上外网

    vi  /etc/profile http_proxy=http://172.20.188.193:3128/https_proxy=https://172.20.188.193:3128/expor ...

  4. 以太坊Geth通过私钥导入新地址到钱包步骤(3种方法)

    一: 通过Geth客户端导入私钥: Open TextEdit Paste key into TextEdit without any extra characters or quotations S ...

  5. 如何单独编译Linux内核的某个模块?

    1. 配置该模块为[M] 2. 编译 make modules SUBDIRS=./drivers/rtc (5.3的内核为make modules M=./drivers/rtc) 3. 安装 ma ...

  6. MySQL中tinytext、text、mediumtext和longtext等各个类型详解

    转: MySQL中tinytext.text.mediumtext和longtext等各个类型详解 2018年06月13日 08:55:24 youcijibi 阅读数 26900更多 个人分类: 每 ...

  7. Windows Qt 项目中文乱码

    在头文件中加入 #if _MSC_VER >= 1600 #pragma execution_character_set("utf-8") #endif

  8. Mask_RCNN

  9. 如何不让Excel图表随源数据改变而改变

    如何不让Excel图表随源数据改变而改变 一般我们在用Excel时,经常会碰到一些问题,比如,如何才能不让Excel图表随源数据改变而改变呢,下面就谈一下,一般在默认情况下,Excel的图表在一个区域 ...

  10. 二分类Logistic回归模型

    Logistic回归属于概率型的非线性回归,分为二分类和多分类的回归模型.这里只讲二分类. 对于二分类的Logistic回归,因变量y只有“是.否”两个取值,记为1和0.这种值为0/1的二值品质型变量 ...