stm32f4xx_hal_nand.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_nand.c
  4. * @author MCD Application Team
  5. * @version V1.3.0
  6. * @date 09-March-2015
  7. * @brief NAND HAL module driver.
  8. * This file provides a generic firmware to drive NAND memories mounted
  9. * as external device.
  10. *
  11. @verbatim
  12. ==============================================================================
  13. ##### How to use this driver #####
  14. ==============================================================================
  15. [..]
  16. This driver is a generic layered driver which contains a set of APIs used to
  17. control NAND flash memories. It uses the FMC/FSMC layer functions to interface
  18. with NAND devices. This driver is used as follows:
  19. (+) NAND flash memory configuration sequence using the function HAL_NAND_Init()
  20. with control and timing parameters for both common and attribute spaces.
  21. (+) Read NAND flash memory maker and device IDs using the function
  22. HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef
  23. structure declared by the function caller.
  24. (+) Access NAND flash memory by read/write operations using the functions
  25. HAL_NAND_Read_Page()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea()
  26. to read/write page(s)/spare area(s). These functions use specific device
  27. information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef
  28. structure. The read/write address information is contained by the Nand_Address_Typedef
  29. structure passed as parameter.
  30. (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
  31. (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
  32. The erase block address information is contained in the Nand_Address_Typedef
  33. structure passed as parameter.
  34. (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
  35. (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
  36. HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
  37. feature or the function HAL_NAND_GetECC() to get the ECC correction code.
  38. (+) You can monitor the NAND device HAL state by calling the function
  39. HAL_NAND_GetState()
  40. [..]
  41. (@) This driver is a set of generic APIs which handle standard NAND flash operations.
  42. If a NAND flash device contains different operations and/or implementations,
  43. it should be implemented separately.
  44. @endverbatim
  45. ******************************************************************************
  46. * @attention
  47. *
  48. * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  49. *
  50. * Redistribution and use in source and binary forms, with or without modification,
  51. * are permitted provided that the following conditions are met:
  52. * 1. Redistributions of source code must retain the above copyright notice,
  53. * this list of conditions and the following disclaimer.
  54. * 2. Redistributions in binary form must reproduce the above copyright notice,
  55. * this list of conditions and the following disclaimer in the documentation
  56. * and/or other materials provided with the distribution.
  57. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  58. * may be used to endorse or promote products derived from this software
  59. * without specific prior written permission.
  60. *
  61. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  62. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  63. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  64. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  65. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  66. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  67. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  68. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  69. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  70. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71. *
  72. ******************************************************************************
  73. */
  74. /* Includes ------------------------------------------------------------------*/
  75. #include "stm32f4xx_hal.h"
  76. /** @addtogroup STM32F4xx_HAL_Driver
  77. * @{
  78. */
  79. #ifdef HAL_NAND_MODULE_ENABLED
  80. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
  81. defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
  82. defined(STM32F446xx)
  83. /** @defgroup NAND NAND
  84. * @brief NAND HAL module driver
  85. * @{
  86. */
  87. /* Private typedef -----------------------------------------------------------*/
  88. /* Private define ------------------------------------------------------------*/
  89. /** @defgroup NAND_Private_Constants NAND Private Constants
  90. * @{
  91. */
  92. /**
  93. * @}
  94. */
  95. /* Private macro -------------------------------------------------------------*/
  96. /** @defgroup NAND_Private_Macros NAND Private Macros
  97. * @{
  98. */
  99. /**
  100. * @}
  101. */
  102. /* Private variables ---------------------------------------------------------*/
  103. /* Private function prototypes -----------------------------------------------*/
  104. /* Exported functions --------------------------------------------------------*/
  105. /** @defgroup NAND_Exported_Functions NAND Exported Functions
  106. * @{
  107. */
  108. /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
  109. * @brief Initialization and Configuration functions
  110. *
  111. @verbatim
  112. ==============================================================================
  113. ##### NAND Initialization and de-initialization functions #####
  114. ==============================================================================
  115. [..]
  116. This section provides functions allowing to initialize/de-initialize
  117. the NAND memory
  118. @endverbatim
  119. * @{
  120. */
  121. /**
  122. * @brief Perform NAND memory Initialization sequence
  123. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  124. * the configuration information for NAND module.
  125. * @param ComSpace_Timing: pointer to Common space timing structure
  126. * @param AttSpace_Timing: pointer to Attribute space timing structure
  127. * @retval HAL status
  128. */
  129. HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
  130. {
  131. /* Check the NAND handle state */
  132. if(hnand == NULL)
  133. {
  134. return HAL_ERROR;
  135. }
  136. if(hnand->State == HAL_NAND_STATE_RESET)
  137. {
  138. /* Allocate lock resource and initialize it */
  139. hnand->Lock = HAL_UNLOCKED;
  140. /* Initialize the low level hardware (MSP) */
  141. HAL_NAND_MspInit(hnand);
  142. }
  143. /* Initialize NAND control Interface */
  144. FMC_NAND_Init(hnand->Instance, &(hnand->Init));
  145. /* Initialize NAND common space timing Interface */
  146. FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
  147. /* Initialize NAND attribute space timing Interface */
  148. FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
  149. /* Enable the NAND device */
  150. __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank);
  151. /* Update the NAND controller state */
  152. hnand->State = HAL_NAND_STATE_READY;
  153. return HAL_OK;
  154. }
  155. /**
  156. * @brief Perform NAND memory De-Initialization sequence
  157. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  158. * the configuration information for NAND module.
  159. * @retval HAL status
  160. */
  161. HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
  162. {
  163. /* Initialize the low level hardware (MSP) */
  164. HAL_NAND_MspDeInit(hnand);
  165. /* Configure the NAND registers with their reset values */
  166. FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
  167. /* Reset the NAND controller state */
  168. hnand->State = HAL_NAND_STATE_RESET;
  169. /* Release Lock */
  170. __HAL_UNLOCK(hnand);
  171. return HAL_OK;
  172. }
  173. /**
  174. * @brief NAND MSP Init
  175. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  176. * the configuration information for NAND module.
  177. * @retval None
  178. */
  179. __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
  180. {
  181. /* NOTE : This function Should not be modified, when the callback is needed,
  182. the HAL_NAND_MspInit could be implemented in the user file
  183. */
  184. }
  185. /**
  186. * @brief NAND MSP DeInit
  187. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  188. * the configuration information for NAND module.
  189. * @retval None
  190. */
  191. __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
  192. {
  193. /* NOTE : This function Should not be modified, when the callback is needed,
  194. the HAL_NAND_MspDeInit could be implemented in the user file
  195. */
  196. }
  197. /**
  198. * @brief This function handles NAND device interrupt request.
  199. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  200. * the configuration information for NAND module.
  201. * @retval HAL status
  202. */
  203. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  204. {
  205. /* Check NAND interrupt Rising edge flag */
  206. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
  207. {
  208. /* NAND interrupt callback*/
  209. HAL_NAND_ITCallback(hnand);
  210. /* Clear NAND interrupt Rising edge pending bit */
  211. __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE);
  212. }
  213. /* Check NAND interrupt Level flag */
  214. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
  215. {
  216. /* NAND interrupt callback*/
  217. HAL_NAND_ITCallback(hnand);
  218. /* Clear NAND interrupt Level pending bit */
  219. __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL);
  220. }
  221. /* Check NAND interrupt Falling edge flag */
  222. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
  223. {
  224. /* NAND interrupt callback*/
  225. HAL_NAND_ITCallback(hnand);
  226. /* Clear NAND interrupt Falling edge pending bit */
  227. __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE);
  228. }
  229. /* Check NAND interrupt FIFO empty flag */
  230. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
  231. {
  232. /* NAND interrupt callback*/
  233. HAL_NAND_ITCallback(hnand);
  234. /* Clear NAND interrupt FIFO empty pending bit */
  235. __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT);
  236. }
  237. }
  238. /**
  239. * @brief NAND interrupt feature callback
  240. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  241. * the configuration information for NAND module.
  242. * @retval None
  243. */
  244. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  245. {
  246. /* NOTE : This function Should not be modified, when the callback is needed,
  247. the HAL_NAND_ITCallback could be implemented in the user file
  248. */
  249. }
  250. /**
  251. * @}
  252. */
  253. /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
  254. * @brief Input Output and memory control functions
  255. *
  256. @verbatim
  257. ==============================================================================
  258. ##### NAND Input and Output functions #####
  259. ==============================================================================
  260. [..]
  261. This section provides functions allowing to use and control the NAND
  262. memory
  263. @endverbatim
  264. * @{
  265. */
  266. /**
  267. * @brief Read the NAND memory electronic signature
  268. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  269. * the configuration information for NAND module.
  270. * @param pNAND_ID: NAND ID structure
  271. * @retval HAL status
  272. */
  273. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  274. {
  275. __IO uint32_t data = 0;
  276. uint32_t deviceaddress = 0;
  277. /* Process Locked */
  278. __HAL_LOCK(hnand);
  279. /* Check the NAND controller state */
  280. if(hnand->State == HAL_NAND_STATE_BUSY)
  281. {
  282. return HAL_BUSY;
  283. }
  284. /* Identify the device address */
  285. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  286. {
  287. deviceaddress = NAND_DEVICE1;
  288. }
  289. else
  290. {
  291. deviceaddress = NAND_DEVICE2;
  292. }
  293. /* Update the NAND controller state */
  294. hnand->State = HAL_NAND_STATE_BUSY;
  295. /* Send Read ID command sequence */
  296. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID;
  297. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  298. /* Read the electronic signature from NAND flash */
  299. data = *(__IO uint32_t *)deviceaddress;
  300. /* Return the data read */
  301. pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
  302. pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
  303. pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
  304. pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
  305. /* Update the NAND controller state */
  306. hnand->State = HAL_NAND_STATE_READY;
  307. /* Process unlocked */
  308. __HAL_UNLOCK(hnand);
  309. return HAL_OK;
  310. }
  311. /**
  312. * @brief NAND memory reset
  313. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  314. * the configuration information for NAND module.
  315. * @retval HAL status
  316. */
  317. HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
  318. {
  319. uint32_t deviceaddress = 0;
  320. /* Process Locked */
  321. __HAL_LOCK(hnand);
  322. /* Check the NAND controller state */
  323. if(hnand->State == HAL_NAND_STATE_BUSY)
  324. {
  325. return HAL_BUSY;
  326. }
  327. /* Identify the device address */
  328. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  329. {
  330. deviceaddress = NAND_DEVICE1;
  331. }
  332. else
  333. {
  334. deviceaddress = NAND_DEVICE2;
  335. }
  336. /* Update the NAND controller state */
  337. hnand->State = HAL_NAND_STATE_BUSY;
  338. /* Send NAND reset command */
  339. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF;
  340. /* Update the NAND controller state */
  341. hnand->State = HAL_NAND_STATE_READY;
  342. /* Process unlocked */
  343. __HAL_UNLOCK(hnand);
  344. return HAL_OK;
  345. }
  346. /**
  347. * @brief Read Page(s) from NAND memory block
  348. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  349. * the configuration information for NAND module.
  350. * @param pAddress : pointer to NAND address structure
  351. * @param pBuffer : pointer to destination read buffer
  352. * @param NumPageToRead : number of pages to read from block
  353. * @retval HAL status
  354. */
  355. HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  356. {
  357. __IO uint32_t index = 0;
  358. uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS;
  359. NAND_AddressTypeDef nandaddress;
  360. uint32_t addressoffset = 0;
  361. /* Process Locked */
  362. __HAL_LOCK(hnand);
  363. /* Check the NAND controller state */
  364. if(hnand->State == HAL_NAND_STATE_BUSY)
  365. {
  366. return HAL_BUSY;
  367. }
  368. /* Identify the device address */
  369. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  370. {
  371. deviceaddress = NAND_DEVICE1;
  372. }
  373. else
  374. {
  375. deviceaddress = NAND_DEVICE2;
  376. }
  377. /* Update the NAND controller state */
  378. hnand->State = HAL_NAND_STATE_BUSY;
  379. /* Save the content of pAddress as it will be modified */
  380. nandaddress.Block = pAddress->Block;
  381. nandaddress.Page = pAddress->Page;
  382. nandaddress.Zone = pAddress->Zone;
  383. /* Page(s) read loop */
  384. while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
  385. {
  386. /* update the buffer size */
  387. size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread);
  388. /* Get the address offset */
  389. addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  390. /* Send read page command sequence */
  391. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  392. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  393. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
  394. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
  395. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
  396. /* for 512 and 1 GB devices, 4th cycle is required */
  397. if(hnand->Info.BlockNbr >= 1024)
  398. {
  399. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
  400. }
  401. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  402. /* Get Data into Buffer */
  403. for(index = size; index != 0; index--)
  404. {
  405. *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  406. }
  407. /* Increment read pages number */
  408. numpagesread++;
  409. /* Decrement pages to read */
  410. NumPageToRead--;
  411. /* Increment the NAND address */
  412. addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
  413. }
  414. /* Update the NAND controller state */
  415. hnand->State = HAL_NAND_STATE_READY;
  416. /* Process unlocked */
  417. __HAL_UNLOCK(hnand);
  418. return HAL_OK;
  419. }
  420. /**
  421. * @brief Write Page(s) to NAND memory block
  422. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  423. * the configuration information for NAND module.
  424. * @param pAddress : pointer to NAND address structure
  425. * @param pBuffer : pointer to source buffer to write
  426. * @param NumPageToWrite : number of pages to write to block
  427. * @retval HAL status
  428. */
  429. HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  430. {
  431. __IO uint32_t index = 0;
  432. uint32_t tickstart = 0;
  433. uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS;
  434. NAND_AddressTypeDef nandaddress;
  435. uint32_t addressoffset = 0;
  436. /* Process Locked */
  437. __HAL_LOCK(hnand);
  438. /* Check the NAND controller state */
  439. if(hnand->State == HAL_NAND_STATE_BUSY)
  440. {
  441. return HAL_BUSY;
  442. }
  443. /* Identify the device address */
  444. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  445. {
  446. deviceaddress = NAND_DEVICE1;
  447. }
  448. else
  449. {
  450. deviceaddress = NAND_DEVICE2;
  451. }
  452. /* Update the NAND controller state */
  453. hnand->State = HAL_NAND_STATE_BUSY;
  454. /* Save the content of pAddress as it will be modified */
  455. nandaddress.Block = pAddress->Block;
  456. nandaddress.Page = pAddress->Page;
  457. nandaddress.Zone = pAddress->Zone;
  458. /* Page(s) write loop */
  459. while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  460. {
  461. /* update the buffer size */
  462. size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten);
  463. /* Get the address offset */
  464. addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  465. /* Send write page command sequence */
  466. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
  467. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  468. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  469. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
  470. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
  471. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
  472. /* for 512 and 1 GB devices, 4th cycle is required */
  473. if(hnand->Info.BlockNbr >= 1024)
  474. {
  475. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
  476. }
  477. /* Write data to memory */
  478. for(index = size; index != 0; index--)
  479. {
  480. *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  481. }
  482. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  483. /* Get tick */
  484. tickstart = HAL_GetTick();
  485. /* Read status until NAND is ready */
  486. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  487. {
  488. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  489. {
  490. return HAL_TIMEOUT;
  491. }
  492. }
  493. /* Increment written pages number */
  494. numpageswritten++;
  495. /* Decrement pages to write */
  496. NumPageToWrite--;
  497. /* Increment the NAND address */
  498. addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
  499. }
  500. /* Update the NAND controller state */
  501. hnand->State = HAL_NAND_STATE_READY;
  502. /* Process unlocked */
  503. __HAL_UNLOCK(hnand);
  504. return HAL_OK;
  505. }
  506. /**
  507. * @brief Read Spare area(s) from NAND memory
  508. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  509. * the configuration information for NAND module.
  510. * @param pAddress : pointer to NAND address structure
  511. * @param pBuffer: pointer to source buffer to write
  512. * @param NumSpareAreaToRead: Number of spare area to read
  513. * @retval HAL status
  514. */
  515. HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
  516. {
  517. __IO uint32_t index = 0;
  518. uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS;
  519. NAND_AddressTypeDef nandaddress;
  520. uint32_t addressoffset = 0;
  521. /* Process Locked */
  522. __HAL_LOCK(hnand);
  523. /* Check the NAND controller state */
  524. if(hnand->State == HAL_NAND_STATE_BUSY)
  525. {
  526. return HAL_BUSY;
  527. }
  528. /* Identify the device address */
  529. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  530. {
  531. deviceaddress = NAND_DEVICE1;
  532. }
  533. else
  534. {
  535. deviceaddress = NAND_DEVICE2;
  536. }
  537. /* Update the NAND controller state */
  538. hnand->State = HAL_NAND_STATE_BUSY;
  539. /* Save the content of pAddress as it will be modified */
  540. nandaddress.Block = pAddress->Block;
  541. nandaddress.Page = pAddress->Page;
  542. nandaddress.Zone = pAddress->Zone;
  543. /* Spare area(s) read loop */
  544. while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS))
  545. {
  546. /* update the buffer size */
  547. size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read);
  548. /* Get the address offset */
  549. addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  550. /* Send read spare area command sequence */
  551. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  552. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  553. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
  554. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
  555. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
  556. /* for 512 and 1 GB devices, 4th cycle is required */
  557. if(hnand->Info.BlockNbr >= 1024)
  558. {
  559. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
  560. }
  561. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  562. /* Get Data into Buffer */
  563. for (index = size ;index != 0; index--)
  564. {
  565. *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
  566. }
  567. /* Increment read spare areas number */
  568. num_spare_area_read++;
  569. /* Decrement spare areas to read */
  570. NumSpareAreaToRead--;
  571. /* Increment the NAND address */
  572. addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
  573. }
  574. /* Update the NAND controller state */
  575. hnand->State = HAL_NAND_STATE_READY;
  576. /* Process unlocked */
  577. __HAL_UNLOCK(hnand);
  578. return HAL_OK;
  579. }
  580. /**
  581. * @brief Write Spare area(s) to NAND memory
  582. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  583. * the configuration information for NAND module.
  584. * @param pAddress : pointer to NAND address structure
  585. * @param pBuffer : pointer to source buffer to write
  586. * @param NumSpareAreaTowrite : number of spare areas to write to block
  587. * @retval HAL status
  588. */
  589. HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
  590. {
  591. __IO uint32_t index = 0;
  592. uint32_t tickstart = 0;
  593. uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS;
  594. NAND_AddressTypeDef nandaddress;
  595. uint32_t addressoffset = 0;
  596. /* Process Locked */
  597. __HAL_LOCK(hnand);
  598. /* Check the NAND controller state */
  599. if(hnand->State == HAL_NAND_STATE_BUSY)
  600. {
  601. return HAL_BUSY;
  602. }
  603. /* Identify the device address */
  604. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  605. {
  606. deviceaddress = NAND_DEVICE1;
  607. }
  608. else
  609. {
  610. deviceaddress = NAND_DEVICE2;
  611. }
  612. /* Update the FMC_NAND controller state */
  613. hnand->State = HAL_NAND_STATE_BUSY;
  614. /* Save the content of pAddress as it will be modified */
  615. nandaddress.Block = pAddress->Block;
  616. nandaddress.Page = pAddress->Page;
  617. nandaddress.Zone = pAddress->Zone;
  618. /* Spare area(s) write loop */
  619. while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS))
  620. {
  621. /* update the buffer size */
  622. size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written);
  623. /* Get the address offset */
  624. addressoffset = ARRAY_ADDRESS(&nandaddress, hnand);
  625. /* Send write Spare area command sequence */
  626. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C;
  627. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
  628. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00;
  629. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset);
  630. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset);
  631. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset);
  632. /* for 512 and 1 GB devices, 4th cycle is required */
  633. if(hnand->Info.BlockNbr >= 1024)
  634. {
  635. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset);
  636. }
  637. /* Write data to memory */
  638. for(; index < size; index++)
  639. {
  640. *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++;
  641. }
  642. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  643. /* Get tick */
  644. tickstart = HAL_GetTick();
  645. /* Read status until NAND is ready */
  646. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  647. {
  648. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  649. {
  650. return HAL_TIMEOUT;
  651. }
  652. }
  653. /* Increment written spare areas number */
  654. num_spare_area_written++;
  655. /* Decrement spare areas to write */
  656. NumSpareAreaTowrite--;
  657. /* Increment the NAND address */
  658. addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress);
  659. }
  660. /* Update the NAND controller state */
  661. hnand->State = HAL_NAND_STATE_READY;
  662. /* Process unlocked */
  663. __HAL_UNLOCK(hnand);
  664. return HAL_OK;
  665. }
  666. /**
  667. * @brief NAND memory Block erase
  668. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  669. * the configuration information for NAND module.
  670. * @param pAddress : pointer to NAND address structure
  671. * @retval HAL status
  672. */
  673. HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  674. {
  675. uint32_t deviceaddress = 0;
  676. uint32_t tickstart = 0;
  677. /* Process Locked */
  678. __HAL_LOCK(hnand);
  679. /* Check the NAND controller state */
  680. if(hnand->State == HAL_NAND_STATE_BUSY)
  681. {
  682. return HAL_BUSY;
  683. }
  684. /* Identify the device address */
  685. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  686. {
  687. deviceaddress = NAND_DEVICE1;
  688. }
  689. else
  690. {
  691. deviceaddress = NAND_DEVICE2;
  692. }
  693. /* Update the NAND controller state */
  694. hnand->State = HAL_NAND_STATE_BUSY;
  695. /* Send Erase block command sequence */
  696. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0;
  697. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  698. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  699. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  700. /* for 512 and 1 GB devices, 4th cycle is required */
  701. if(hnand->Info.BlockNbr >= 1024)
  702. {
  703. *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  704. }
  705. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1;
  706. /* Update the NAND controller state */
  707. hnand->State = HAL_NAND_STATE_READY;
  708. /* Get tick */
  709. tickstart = HAL_GetTick();
  710. /* Read status until NAND is ready */
  711. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  712. {
  713. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  714. {
  715. /* Process unlocked */
  716. __HAL_UNLOCK(hnand);
  717. return HAL_TIMEOUT;
  718. }
  719. }
  720. /* Process unlocked */
  721. __HAL_UNLOCK(hnand);
  722. return HAL_OK;
  723. }
  724. /**
  725. * @brief NAND memory read status
  726. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  727. * the configuration information for NAND module.
  728. * @retval NAND status
  729. */
  730. uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
  731. {
  732. uint32_t data = 0;
  733. uint32_t deviceaddress = 0;
  734. /* Identify the device address */
  735. if(hnand->Init.NandBank == FMC_NAND_BANK2)
  736. {
  737. deviceaddress = NAND_DEVICE1;
  738. }
  739. else
  740. {
  741. deviceaddress = NAND_DEVICE2;
  742. }
  743. /* Send Read status operation command */
  744. *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS;
  745. /* Read status register data */
  746. data = *(__IO uint8_t *)deviceaddress;
  747. /* Return the status */
  748. if((data & NAND_ERROR) == NAND_ERROR)
  749. {
  750. return NAND_ERROR;
  751. }
  752. else if((data & NAND_READY) == NAND_READY)
  753. {
  754. return NAND_READY;
  755. }
  756. return NAND_BUSY;
  757. }
  758. /**
  759. * @brief Increment the NAND memory address
  760. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  761. * the configuration information for NAND module.
  762. * @param pAddress: pointer to NAND address structure
  763. * @retval The new status of the increment address operation. It can be:
  764. * - NAND_VALID_ADDRESS: When the new address is valid address
  765. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  766. */
  767. uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  768. {
  769. uint32_t status = NAND_VALID_ADDRESS;
  770. /* Increment page address */
  771. pAddress->Page++;
  772. /* Check NAND address is valid */
  773. if(pAddress->Page == hnand->Info.BlockSize)
  774. {
  775. pAddress->Page = 0;
  776. pAddress->Block++;
  777. if(pAddress->Block == hnand->Info.ZoneSize)
  778. {
  779. pAddress->Block = 0;
  780. pAddress->Zone++;
  781. if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
  782. {
  783. status = NAND_INVALID_ADDRESS;
  784. }
  785. }
  786. }
  787. return (status);
  788. }
  789. /**
  790. * @}
  791. */
  792. /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
  793. * @brief management functions
  794. *
  795. @verbatim
  796. ==============================================================================
  797. ##### NAND Control functions #####
  798. ==============================================================================
  799. [..]
  800. This subsection provides a set of functions allowing to control dynamically
  801. the NAND interface.
  802. @endverbatim
  803. * @{
  804. */
  805. /**
  806. * @brief Enables dynamically NAND ECC feature.
  807. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  808. * the configuration information for NAND module.
  809. * @retval HAL status
  810. */
  811. HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
  812. {
  813. /* Check the NAND controller state */
  814. if(hnand->State == HAL_NAND_STATE_BUSY)
  815. {
  816. return HAL_BUSY;
  817. }
  818. /* Update the NAND state */
  819. hnand->State = HAL_NAND_STATE_BUSY;
  820. /* Enable ECC feature */
  821. FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
  822. /* Update the NAND state */
  823. hnand->State = HAL_NAND_STATE_READY;
  824. return HAL_OK;
  825. }
  826. /**
  827. * @brief Disables dynamically FMC_NAND ECC feature.
  828. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  829. * the configuration information for NAND module.
  830. * @retval HAL status
  831. */
  832. HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
  833. {
  834. /* Check the NAND controller state */
  835. if(hnand->State == HAL_NAND_STATE_BUSY)
  836. {
  837. return HAL_BUSY;
  838. }
  839. /* Update the NAND state */
  840. hnand->State = HAL_NAND_STATE_BUSY;
  841. /* Disable ECC feature */
  842. FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
  843. /* Update the NAND state */
  844. hnand->State = HAL_NAND_STATE_READY;
  845. return HAL_OK;
  846. }
  847. /**
  848. * @brief Disables dynamically NAND ECC feature.
  849. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  850. * the configuration information for NAND module.
  851. * @param ECCval: pointer to ECC value
  852. * @param Timeout: maximum timeout to wait
  853. * @retval HAL status
  854. */
  855. HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
  856. {
  857. HAL_StatusTypeDef status = HAL_OK;
  858. /* Check the NAND controller state */
  859. if(hnand->State == HAL_NAND_STATE_BUSY)
  860. {
  861. return HAL_BUSY;
  862. }
  863. /* Update the NAND state */
  864. hnand->State = HAL_NAND_STATE_BUSY;
  865. /* Get NAND ECC value */
  866. status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
  867. /* Update the NAND state */
  868. hnand->State = HAL_NAND_STATE_READY;
  869. return status;
  870. }
  871. /**
  872. * @}
  873. */
  874. /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
  875. * @brief Peripheral State functions
  876. *
  877. @verbatim
  878. ==============================================================================
  879. ##### NAND State functions #####
  880. ==============================================================================
  881. [..]
  882. This subsection permits to get in run-time the status of the NAND controller
  883. and the data flow.
  884. @endverbatim
  885. * @{
  886. */
  887. /**
  888. * @brief return the NAND state
  889. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  890. * the configuration information for NAND module.
  891. * @retval HAL state
  892. */
  893. HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
  894. {
  895. return hnand->State;
  896. }
  897. /**
  898. * @}
  899. */
  900. /**
  901. * @}
  902. */
  903. /**
  904. * @}
  905. */
  906. #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\
  907. STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\
  908. STM32F446xx */
  909. #endif /* HAL_NAND_MODULE_ENABLED */
  910. /**
  911. * @}
  912. */
  913. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/