fsmc_nand.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. /******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
  2. * File Name : fsmc_nand.c
  3. * Author : MCD Application Team
  4. * Version : V2.0.3
  5. * Date : 09/22/2008
  6. * Description : This file provides a set of functions needed to drive the
  7. * NAND512W3A2 memory mounted on STM3210E-EVAL board.
  8. ********************************************************************************
  9. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  10. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
  11. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  12. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  13. * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  14. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  15. *******************************************************************************/
  16. /* Includes ------------------------------------------------------------------*/
  17. #include "fsmc_nand.h"
  18. /* Private typedef -----------------------------------------------------------*/
  19. /* Private define ------------------------------------------------------------*/
  20. #define FSMC_Bank_NAND FSMC_Bank2_NAND
  21. #define Bank_NAND_ADDR Bank2_NAND_ADDR
  22. #define Bank2_NAND_ADDR ((u32)0x70000000)
  23. /* Private macro -------------------------------------------------------------*/
  24. #define ROW_ADDRESS (Address.Page + (Address.Block + (Address.Zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE)
  25. /* Private variables ---------------------------------------------------------*/
  26. /* Private function prototypes -----------------------------------------------*/
  27. /* Private functions ---------------------------------------------------------*/
  28. /*******************************************************************************
  29. * Function Name : FSMC_NAND_Init
  30. * Description : Configures the FSMC and GPIOs to interface with the NAND memory.
  31. * This function must be called before any write/read operation
  32. * on the NAND.
  33. * Input : None
  34. * Output : None
  35. * Return : None
  36. *******************************************************************************/
  37. void FSMC_NAND_Init(void)
  38. {
  39. FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
  40. FSMC_NAND_PCCARDTimingInitTypeDef p;
  41. /*-- FSMC Configuration ------------------------------------------------------*/
  42. p.FSMC_SetupTime = 0x1;
  43. p.FSMC_WaitSetupTime = 0x3;
  44. p.FSMC_HoldSetupTime = 0x2;
  45. p.FSMC_HiZSetupTime = 0x1;
  46. FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
  47. FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
  48. FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
  49. FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
  50. FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
  51. // FSMC_NANDInitStructure.FSMC_AddressLowMapping = FSMC_AddressLowMapping_Direct;
  52. FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
  53. FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
  54. FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
  55. FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
  56. FSMC_NANDInit(&FSMC_NANDInitStructure);
  57. /* FSMC NAND Bank Cmd Test */
  58. FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
  59. }
  60. /******************************************************************************
  61. * Function Name : FSMC_NAND_ReadID
  62. * Description : Reads NAND memory's ID.
  63. * Input : - NAND_ID: pointer to a NAND_IDTypeDef structure which will hold
  64. * the Manufacturer and Device ID.
  65. * Output : None
  66. * Return : None
  67. *******************************************************************************/
  68. void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)
  69. {
  70. u32 data = 0;
  71. /* Send Command to the command area */
  72. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = 0x90;
  73. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
  74. /* Sequence to read ID from NAND flash */
  75. data = *(vu32 *)(Bank_NAND_ADDR | DATA_AREA);
  76. NAND_ID->Maker_ID = ADDR_1st_CYCLE (data);
  77. NAND_ID->Device_ID = ADDR_2nd_CYCLE (data);
  78. NAND_ID->Third_ID = ADDR_3rd_CYCLE (data);
  79. NAND_ID->Fourth_ID = ADDR_4th_CYCLE (data);
  80. }
  81. /******************************************************************************
  82. * Function Name : FSMC_NAND_WriteSmallPage
  83. * Description : This routine is for writing one or several 512 Bytes Page size.
  84. * Input : - pBuffer: pointer on the Buffer containing data to be written
  85. * - Address: First page address
  86. * - NumPageToWrite: Number of page to write
  87. * Output : None
  88. * Return : New status of the NAND operation. This parameter can be:
  89. * - NAND_TIMEOUT_ERROR: when the previous operation generate
  90. * a Timeout error
  91. * - NAND_READY: when memory is ready for the next operation
  92. * And the new status of the increment address operation. It can be:
  93. * - NAND_VALID_ADDRESS: When the new address is valid address
  94. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  95. *******************************************************************************/
  96. u32 FSMC_NAND_WriteSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToWrite)
  97. {
  98. u32 index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  99. u32 status = NAND_READY, size = 2048;
  100. while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
  101. {
  102. /* Page write command and address */
  103. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
  104. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
  105. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  106. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  107. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
  108. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);
  109. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS);
  110. /* Calculate the size */
  111. size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
  112. /* Write data */
  113. for(; index < size; index++)
  114. {
  115. *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
  116. }
  117. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
  118. /* Check status for successful operation */
  119. status = FSMC_NAND_GetStatus();
  120. if(status == NAND_READY)
  121. {
  122. numpagewritten++;
  123. NumPageToWrite--;
  124. /* Calculate Next small page Address */
  125. addressstatus = FSMC_NAND_AddressIncrement(&Address);
  126. }
  127. }
  128. return (status | addressstatus);
  129. }
  130. /******************************************************************************
  131. * Function Name : FSMC_NAND_ReadSmallPage
  132. * Description : This routine is for sequential read from one or several
  133. * 512 Bytes Page size.
  134. * Input : - pBuffer: pointer on the Buffer to fill
  135. * - Address: First page address
  136. * - NumPageToRead: Number of page to read
  137. * Output : None
  138. * Return : New status of the NAND operation. This parameter can be:
  139. * - NAND_TIMEOUT_ERROR: when the previous operation generate
  140. * a Timeout error
  141. * - NAND_READY: when memory is ready for the next operation
  142. * And the new status of the increment address operation. It can be:
  143. * - NAND_VALID_ADDRESS: When the new address is valid address
  144. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  145. *******************************************************************************/
  146. u32 FSMC_NAND_ReadSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead)
  147. {
  148. u32 index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
  149. u32 status = NAND_READY, size = 2048, i = 0;
  150. /* Calculate the size */
  151. size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
  152. while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  153. {
  154. /* Page Read command and page address */
  155. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
  156. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  157. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  158. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
  159. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);
  160. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS);
  161. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;
  162. for(i = 0; i <= 10000; i++);
  163. /* Get Data into Buffer */
  164. for(; index < size; index++)
  165. {
  166. pBuffer[index]= *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
  167. }
  168. numpageread++;
  169. NumPageToRead--;
  170. /* Calculate page address */
  171. addressstatus = FSMC_NAND_AddressIncrement(&Address);
  172. }
  173. status = FSMC_NAND_GetStatus();
  174. return (status | addressstatus);
  175. }
  176. /******************************************************************************
  177. * Function Name : FSMC_NAND_WriteSpareArea
  178. * Description : This routine write the spare area information for the specified
  179. * pages addresses.
  180. * Input : - pBuffer: pointer on the Buffer containing data to be written
  181. * - Address: First page address
  182. * - NumSpareAreaTowrite: Number of Spare Area to write
  183. * Output : None
  184. * Return : New status of the NAND operation. This parameter can be:
  185. * - NAND_TIMEOUT_ERROR: when the previous operation generate
  186. * a Timeout error
  187. * - NAND_READY: when memory is ready for the next operation
  188. * And the new status of the increment address operation. It can be:
  189. * - NAND_VALID_ADDRESS: When the new address is valid address
  190. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  191. *******************************************************************************/
  192. u32 FSMC_NAND_WriteSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaTowrite)
  193. {
  194. u32 index = 0x00, numsparesreawritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  195. u32 status = NAND_READY, size = 0x00;
  196. while((NumSpareAreaTowrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
  197. {
  198. /* Page write Spare area command and address */
  199. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
  200. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
  201. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  202. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  203. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
  204. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);
  205. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS);
  206. /* Calculate the size */
  207. size = NAND_SPARE_AREA_SIZE + (NAND_SPARE_AREA_SIZE * numsparesreawritten);
  208. /* Write the data */
  209. for(; index < size; index++)
  210. {
  211. *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
  212. }
  213. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
  214. /* Check status for successful operation */
  215. status = FSMC_NAND_GetStatus();
  216. if(status == NAND_READY)
  217. {
  218. numsparesreawritten++;
  219. NumSpareAreaTowrite--;
  220. /* Calculate Next page Address */
  221. addressstatus = FSMC_NAND_AddressIncrement(&Address);
  222. }
  223. }
  224. return (status | addressstatus);
  225. }
  226. /******************************************************************************
  227. * Function Name : FSMC_NAND_ReadSpareArea
  228. * Description : This routine read the spare area information from the specified
  229. * pages addresses.
  230. * Input : - pBuffer: pointer on the Buffer to fill
  231. * - Address: First page address
  232. * - NumSpareAreaToRead: Number of Spare Area to read
  233. * Output : None
  234. * Return : New status of the NAND operation. This parameter can be:
  235. * - NAND_TIMEOUT_ERROR: when the previous operation generate
  236. * a Timeout error
  237. * - NAND_READY: when memory is ready for the next operation
  238. * And the new status of the increment address operation. It can be:
  239. * - NAND_VALID_ADDRESS: When the new address is valid address
  240. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  241. *******************************************************************************/
  242. u32 FSMC_NAND_ReadSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaToRead)
  243. {
  244. u32 numsparearearead = 0x00, index = 0x00, addressstatus = NAND_VALID_ADDRESS;
  245. u32 status = NAND_READY, size = 0x00;
  246. while((NumSpareAreaToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  247. {
  248. /* Page Read command and page address */
  249. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
  250. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  251. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  252. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
  253. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);
  254. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS);
  255. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;
  256. /* Data Read */
  257. size = NAND_SPARE_AREA_SIZE + (NAND_SPARE_AREA_SIZE * numsparearearead);
  258. /* Get Data into Buffer */
  259. for ( ; index < size; index++)
  260. {
  261. pBuffer[index] = *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
  262. }
  263. numsparearearead++;
  264. NumSpareAreaToRead--;
  265. /* Calculate page address */
  266. addressstatus = FSMC_NAND_AddressIncrement(&Address);
  267. }
  268. status = FSMC_NAND_GetStatus();
  269. return (status | addressstatus);
  270. }
  271. /******************************************************************************
  272. * Function Name : FSMC_NAND_EraseBlock
  273. * Description : This routine erase complete block from NAND FLASH
  274. * Input : - Address: Any address into block to be erased
  275. * Output : None
  276. * Return : New status of the NAND operation. This parameter can be:
  277. * - NAND_TIMEOUT_ERROR: when the previous operation generate
  278. * a Timeout error
  279. * - NAND_READY: when memory is ready for the next operation
  280. *******************************************************************************/
  281. u32 FSMC_NAND_EraseBlock(NAND_ADDRESS Address)
  282. {
  283. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;
  284. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  285. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  286. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
  287. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);
  288. *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS);
  289. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;
  290. return (FSMC_NAND_GetStatus());
  291. }
  292. /******************************************************************************
  293. * Function Name : FSMC_NAND_Reset
  294. * Description : This routine reset the NAND FLASH
  295. * Input : None
  296. * Output : None
  297. * Return : NAND_READY
  298. *******************************************************************************/
  299. u32 FSMC_NAND_Reset(void)
  300. {
  301. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;
  302. return (NAND_READY);
  303. }
  304. /******************************************************************************
  305. * Function Name : FSMC_NAND_GetStatus
  306. * Description : Get the NAND operation status
  307. * Input : None
  308. * Output : None
  309. * Return : New status of the NAND operation. This parameter can be:
  310. * - NAND_TIMEOUT_ERROR: when the previous operation generate
  311. * a Timeout error
  312. * - NAND_READY: when memory is ready for the next operation
  313. *******************************************************************************/
  314. u32 FSMC_NAND_GetStatus(void)
  315. {
  316. u32 timeout = 0x1000000, status = NAND_READY;
  317. status = FSMC_NAND_ReadStatus();
  318. /* Wait for a NAND operation to complete or a TIMEOUT to occur */
  319. while ((status != NAND_READY) &&( timeout != 0x00))
  320. {
  321. status = FSMC_NAND_ReadStatus();
  322. timeout --;
  323. }
  324. if(timeout == 0x00)
  325. {
  326. status = NAND_TIMEOUT_ERROR;
  327. }
  328. /* Return the operation status */
  329. return (status);
  330. }
  331. /******************************************************************************
  332. * Function Name : FSMC_NAND_ReadStatus
  333. * Description : Reads the NAND memory status using the Read status command
  334. * Input : None
  335. * Output : None
  336. * Return : The status of the NAND memory. This parameter can be:
  337. * - NAND_BUSY: when memory is busy
  338. * - NAND_READY: when memory is ready for the next operation
  339. * - NAND_ERROR: when the previous operation gererates error
  340. *******************************************************************************/
  341. u32 FSMC_NAND_ReadStatus(void)
  342. {
  343. u32 data = 0x00, status = NAND_BUSY;
  344. /* Read status operation ------------------------------------ */
  345. *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
  346. data = *(vu8 *)(Bank_NAND_ADDR);
  347. if((data & NAND_ERROR) == NAND_ERROR)
  348. {
  349. status = NAND_ERROR;
  350. }
  351. else if((data & NAND_READY) == NAND_READY)
  352. {
  353. status = NAND_READY;
  354. }
  355. else
  356. {
  357. status = NAND_BUSY;
  358. }
  359. return (status);
  360. }
  361. /******************************************************************************
  362. * Function Name : NAND_AddressIncrement
  363. * Description : Increment the NAND memory address
  364. * Input : - Address: address to be incremented.
  365. * Output : None
  366. * Return : The new status of the increment address operation. It can be:
  367. * - NAND_VALID_ADDRESS: When the new address is valid address
  368. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  369. *******************************************************************************/
  370. u32 FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address)
  371. {
  372. u32 status = NAND_VALID_ADDRESS;
  373. Address->Page++;
  374. if(Address->Page == NAND_BLOCK_SIZE)
  375. {
  376. Address->Page = 0;
  377. Address->Block++;
  378. if(Address->Block == NAND_ZONE_SIZE)
  379. {
  380. Address->Block = 0;
  381. Address->Zone++;
  382. if(Address->Zone == NAND_MAX_ZONE)
  383. {
  384. status = NAND_INVALID_ADDRESS;
  385. }
  386. }
  387. }
  388. return (status);
  389. }
  390. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/