stm32f7xx_hal_nand.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_hal_nand.c
  4. * @author MCD Application Team
  5. * @version V1.0.1
  6. * @date 25-June-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 "stm32f7xx_hal.h"
  76. /** @addtogroup STM32F7xx_HAL_Driver
  77. * @{
  78. */
  79. #ifdef HAL_NAND_MODULE_ENABLED
  80. /** @defgroup NAND NAND
  81. * @brief NAND HAL module driver
  82. * @{
  83. */
  84. /* Private typedef -----------------------------------------------------------*/
  85. /* Private Constants ------------------------------------------------------------*/
  86. /* Private macro -------------------------------------------------------------*/
  87. /* Private variables ---------------------------------------------------------*/
  88. /* Private function prototypes -----------------------------------------------*/
  89. /* Exported functions ---------------------------------------------------------*/
  90. /** @defgroup NAND_Exported_Functions NAND Exported Functions
  91. * @{
  92. */
  93. /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
  94. * @brief Initialization and Configuration functions
  95. *
  96. @verbatim
  97. ==============================================================================
  98. ##### NAND Initialization and de-initialization functions #####
  99. ==============================================================================
  100. [..]
  101. This section provides functions allowing to initialize/de-initialize
  102. the NAND memory
  103. @endverbatim
  104. * @{
  105. */
  106. /**
  107. * @brief Perform NAND memory Initialization sequence
  108. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  109. * the configuration information for NAND module.
  110. * @param ComSpace_Timing: pointer to Common space timing structure
  111. * @param AttSpace_Timing: pointer to Attribute space timing structure
  112. * @retval HAL status
  113. */
  114. HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
  115. {
  116. /* Check the NAND handle state */
  117. if(hnand == NULL)
  118. {
  119. return HAL_ERROR;
  120. }
  121. if(hnand->State == HAL_NAND_STATE_RESET)
  122. {
  123. /* Allocate lock resource and initialize it */
  124. hnand->Lock = HAL_UNLOCKED;
  125. /* Initialize the low level hardware (MSP) */
  126. HAL_NAND_MspInit(hnand);
  127. }
  128. /* Initialize NAND control Interface */
  129. FMC_NAND_Init(hnand->Instance, &(hnand->Init));
  130. /* Initialize NAND common space timing Interface */
  131. FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
  132. /* Initialize NAND attribute space timing Interface */
  133. FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
  134. /* Enable the NAND device */
  135. __FMC_NAND_ENABLE(hnand->Instance);
  136. /* Update the NAND controller state */
  137. hnand->State = HAL_NAND_STATE_READY;
  138. return HAL_OK;
  139. }
  140. /**
  141. * @brief Perform NAND memory De-Initialization sequence
  142. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  143. * the configuration information for NAND module.
  144. * @retval HAL status
  145. */
  146. HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
  147. {
  148. /* Initialize the low level hardware (MSP) */
  149. HAL_NAND_MspDeInit(hnand);
  150. /* Configure the NAND registers with their reset values */
  151. FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
  152. /* Reset the NAND controller state */
  153. hnand->State = HAL_NAND_STATE_RESET;
  154. /* Release Lock */
  155. __HAL_UNLOCK(hnand);
  156. return HAL_OK;
  157. }
  158. /**
  159. * @brief NAND MSP Init
  160. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  161. * the configuration information for NAND module.
  162. * @retval None
  163. */
  164. __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
  165. {
  166. /* NOTE : This function Should not be modified, when the callback is needed,
  167. the HAL_NAND_MspInit could be implemented in the user file
  168. */
  169. }
  170. /**
  171. * @brief NAND MSP DeInit
  172. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  173. * the configuration information for NAND module.
  174. * @retval None
  175. */
  176. __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
  177. {
  178. /* NOTE : This function Should not be modified, when the callback is needed,
  179. the HAL_NAND_MspDeInit could be implemented in the user file
  180. */
  181. }
  182. /**
  183. * @brief This function handles NAND device interrupt request.
  184. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  185. * the configuration information for NAND module.
  186. * @retval HAL status
  187. */
  188. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  189. {
  190. /* Check NAND interrupt Rising edge flag */
  191. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
  192. {
  193. /* NAND interrupt callback*/
  194. HAL_NAND_ITCallback(hnand);
  195. /* Clear NAND interrupt Rising edge pending bit */
  196. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
  197. }
  198. /* Check NAND interrupt Level flag */
  199. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
  200. {
  201. /* NAND interrupt callback*/
  202. HAL_NAND_ITCallback(hnand);
  203. /* Clear NAND interrupt Level pending bit */
  204. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
  205. }
  206. /* Check NAND interrupt Falling edge flag */
  207. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
  208. {
  209. /* NAND interrupt callback*/
  210. HAL_NAND_ITCallback(hnand);
  211. /* Clear NAND interrupt Falling edge pending bit */
  212. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
  213. }
  214. /* Check NAND interrupt FIFO empty flag */
  215. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
  216. {
  217. /* NAND interrupt callback*/
  218. HAL_NAND_ITCallback(hnand);
  219. /* Clear NAND interrupt FIFO empty pending bit */
  220. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
  221. }
  222. }
  223. /**
  224. * @brief NAND interrupt feature callback
  225. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  226. * the configuration information for NAND module.
  227. * @retval None
  228. */
  229. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  230. {
  231. /* NOTE : This function Should not be modified, when the callback is needed,
  232. the HAL_NAND_ITCallback could be implemented in the user file
  233. */
  234. }
  235. /**
  236. * @}
  237. */
  238. /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
  239. * @brief Input Output and memory control functions
  240. *
  241. @verbatim
  242. ==============================================================================
  243. ##### NAND Input and Output functions #####
  244. ==============================================================================
  245. [..]
  246. This section provides functions allowing to use and control the NAND
  247. memory
  248. @endverbatim
  249. * @{
  250. */
  251. /**
  252. * @brief Read the NAND memory electronic signature
  253. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  254. * the configuration information for NAND module.
  255. * @param pNAND_ID: NAND ID structure
  256. * @retval HAL status
  257. */
  258. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  259. {
  260. __IO uint32_t data = 0;
  261. uint32_t deviceAddress = 0;
  262. /* Process Locked */
  263. __HAL_LOCK(hnand);
  264. /* Check the NAND controller state */
  265. if(hnand->State == HAL_NAND_STATE_BUSY)
  266. {
  267. return HAL_BUSY;
  268. }
  269. /* Identify the device address */
  270. deviceAddress = NAND_DEVICE;
  271. /* Update the NAND controller state */
  272. hnand->State = HAL_NAND_STATE_BUSY;
  273. /* Send Read ID command sequence */
  274. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
  275. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  276. /* Read the electronic signature from NAND flash */
  277. data = *(__IO uint32_t *)deviceAddress;
  278. /* Return the data read */
  279. pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
  280. pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
  281. pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
  282. pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
  283. /* Update the NAND controller state */
  284. hnand->State = HAL_NAND_STATE_READY;
  285. /* Process unlocked */
  286. __HAL_UNLOCK(hnand);
  287. return HAL_OK;
  288. }
  289. /**
  290. * @brief NAND memory reset
  291. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  292. * the configuration information for NAND module.
  293. * @retval HAL status
  294. */
  295. HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
  296. {
  297. uint32_t deviceAddress = 0;
  298. /* Process Locked */
  299. __HAL_LOCK(hnand);
  300. /* Check the NAND controller state */
  301. if(hnand->State == HAL_NAND_STATE_BUSY)
  302. {
  303. return HAL_BUSY;
  304. }
  305. /* Identify the device address */
  306. deviceAddress = NAND_DEVICE;
  307. /* Update the NAND controller state */
  308. hnand->State = HAL_NAND_STATE_BUSY;
  309. /* Send NAND reset command */
  310. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;
  311. /* Update the NAND controller state */
  312. hnand->State = HAL_NAND_STATE_READY;
  313. /* Process unlocked */
  314. __HAL_UNLOCK(hnand);
  315. return HAL_OK;
  316. }
  317. /**
  318. * @brief Read Page(s) from NAND memory block
  319. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  320. * the configuration information for NAND module.
  321. * @param pAddress : pointer to NAND address structure
  322. * @param pBuffer : pointer to destination read buffer
  323. * @param NumPageToRead : number of pages to read from block
  324. * @retval HAL status
  325. */
  326. HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  327. {
  328. __IO uint32_t index = 0;
  329. uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
  330. /* Process Locked */
  331. __HAL_LOCK(hnand);
  332. /* Check the NAND controller state */
  333. if(hnand->State == HAL_NAND_STATE_BUSY)
  334. {
  335. return HAL_BUSY;
  336. }
  337. /* Identify the device address */
  338. deviceAddress = NAND_DEVICE;
  339. /* Update the NAND controller state */
  340. hnand->State = HAL_NAND_STATE_BUSY;
  341. /* NAND raw address calculation */
  342. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  343. /* Page(s) read loop */
  344. while((NumPageToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
  345. {
  346. /* update the buffer size */
  347. size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesRead);
  348. /* Send read page command sequence */
  349. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  350. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  351. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  352. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  353. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  354. /* for 512 and 1 GB devices, 4th cycle is required */
  355. if(hnand->Info.BlockNbr >= 1024)
  356. {
  357. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
  358. }
  359. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  360. /* Get Data into Buffer */
  361. for(index = 0; index < size; index++)
  362. {
  363. *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
  364. }
  365. /* Increment read pages number */
  366. numPagesRead++;
  367. /* Decrement pages to read */
  368. NumPageToRead--;
  369. /* Increment the NAND address */
  370. nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
  371. }
  372. /* Update the NAND controller state */
  373. hnand->State = HAL_NAND_STATE_READY;
  374. /* Process unlocked */
  375. __HAL_UNLOCK(hnand);
  376. return HAL_OK;
  377. }
  378. /**
  379. * @brief Write Page(s) to NAND memory block
  380. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  381. * the configuration information for NAND module.
  382. * @param pAddress : pointer to NAND address structure
  383. * @param pBuffer : pointer to source buffer to write
  384. * @param NumPageToWrite : number of pages to write to block
  385. * @retval HAL status
  386. */
  387. HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  388. {
  389. __IO uint32_t index = 0;
  390. uint32_t tickstart = 0;
  391. uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
  392. /* Process Locked */
  393. __HAL_LOCK(hnand);
  394. /* Check the NAND controller state */
  395. if(hnand->State == HAL_NAND_STATE_BUSY)
  396. {
  397. return HAL_BUSY;
  398. }
  399. /* Identify the device address */
  400. deviceAddress = NAND_DEVICE;
  401. /* Update the NAND controller state */
  402. hnand->State = HAL_NAND_STATE_BUSY;
  403. /* NAND raw address calculation */
  404. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  405. /* Page(s) write loop */
  406. while((NumPageToWrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.PageSize) * (hnand->Info.ZoneSize))))
  407. {
  408. /* update the buffer size */
  409. size = (hnand->Info.PageSize) + ((hnand->Info.PageSize) * numPagesWritten);
  410. /* Send write page command sequence */
  411. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  412. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  413. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  414. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  415. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  416. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  417. __DSB();
  418. /* for 512 and 1 GB devices, 4th cycle is required */
  419. if(hnand->Info.BlockNbr >= 1024)
  420. {
  421. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
  422. __DSB();
  423. }
  424. /* Write data to memory */
  425. for(index = 0; index < size; index++)
  426. {
  427. *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
  428. __DSB();
  429. }
  430. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  431. /* Read status until NAND is ready */
  432. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  433. {
  434. /* Get tick */
  435. tickstart = HAL_GetTick();
  436. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  437. {
  438. return HAL_TIMEOUT;
  439. }
  440. }
  441. /* Increment written pages number */
  442. numPagesWritten++;
  443. /* Decrement pages to write */
  444. NumPageToWrite--;
  445. /* Increment the NAND address */
  446. nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize * 8));
  447. }
  448. /* Update the NAND controller state */
  449. hnand->State = HAL_NAND_STATE_READY;
  450. /* Process unlocked */
  451. __HAL_UNLOCK(hnand);
  452. return HAL_OK;
  453. }
  454. /**
  455. * @brief Read Spare area(s) from NAND memory
  456. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  457. * the configuration information for NAND module.
  458. * @param pAddress : pointer to NAND address structure
  459. * @param pBuffer: pointer to source buffer to write
  460. * @param NumSpareAreaToRead: Number of spare area to read
  461. * @retval HAL status
  462. */
  463. HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
  464. {
  465. __IO uint32_t index = 0;
  466. uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0;
  467. /* Process Locked */
  468. __HAL_LOCK(hnand);
  469. /* Check the NAND controller state */
  470. if(hnand->State == HAL_NAND_STATE_BUSY)
  471. {
  472. return HAL_BUSY;
  473. }
  474. /* Identify the device address */
  475. deviceAddress = NAND_DEVICE;
  476. /* Update the NAND controller state */
  477. hnand->State = HAL_NAND_STATE_BUSY;
  478. /* NAND raw address calculation */
  479. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  480. /* Spare area(s) read loop */
  481. while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
  482. {
  483. /* update the buffer size */
  484. size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaRead);
  485. /* Send read spare area command sequence */
  486. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
  487. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  488. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  489. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  490. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  491. /* for 512 and 1 GB devices, 4th cycle is required */
  492. if(hnand->Info.BlockNbr >= 1024)
  493. {
  494. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
  495. }
  496. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  497. /* Get Data into Buffer */
  498. for(index = 0; index < size; index++)
  499. {
  500. *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
  501. }
  502. /* Increment read spare areas number */
  503. numSpareAreaRead++;
  504. /* Decrement spare areas to read */
  505. NumSpareAreaToRead--;
  506. /* Increment the NAND address */
  507. nandAddress = (uint32_t)(nandAddress + (hnand->Info.SpareAreaSize));
  508. }
  509. /* Update the NAND controller state */
  510. hnand->State = HAL_NAND_STATE_READY;
  511. /* Process unlocked */
  512. __HAL_UNLOCK(hnand);
  513. return HAL_OK;
  514. }
  515. /**
  516. * @brief Write Spare area(s) to NAND memory
  517. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  518. * the configuration information for NAND module.
  519. * @param pAddress : pointer to NAND address structure
  520. * @param pBuffer : pointer to source buffer to write
  521. * @param NumSpareAreaTowrite : number of spare areas to write to block
  522. * @retval HAL status
  523. */
  524. HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
  525. {
  526. __IO uint32_t index = 0;
  527. uint32_t tickstart = 0;
  528. uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0;
  529. /* Process Locked */
  530. __HAL_LOCK(hnand);
  531. /* Check the NAND controller state */
  532. if(hnand->State == HAL_NAND_STATE_BUSY)
  533. {
  534. return HAL_BUSY;
  535. }
  536. /* Identify the device address */
  537. deviceAddress = NAND_DEVICE;
  538. /* Update the FMC_NAND controller state */
  539. hnand->State = HAL_NAND_STATE_BUSY;
  540. /* NAND raw address calculation */
  541. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  542. /* Spare area(s) write loop */
  543. while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Info.BlockSize) * (hnand->Info.SpareAreaSize) * (hnand->Info.ZoneSize))))
  544. {
  545. /* update the buffer size */
  546. size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * numSpareAreaWritten);
  547. /* Send write Spare area command sequence */
  548. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
  549. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  550. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  551. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  552. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  553. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  554. __DSB();
  555. /* for 512 and 1 GB devices, 4th cycle is required */
  556. if(hnand->Info.BlockNbr >= 1024)
  557. {
  558. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(nandAddress);
  559. __DSB();
  560. }
  561. /* Write data to memory */
  562. for(index = 0; index < size; index++)
  563. {
  564. *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
  565. __DSB();
  566. }
  567. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  568. __DSB();
  569. /* Read status until NAND is ready */
  570. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  571. {
  572. /* Get tick */
  573. tickstart = HAL_GetTick();
  574. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  575. {
  576. return HAL_TIMEOUT;
  577. }
  578. }
  579. /* Increment written spare areas number */
  580. numSpareAreaWritten++;
  581. /* Decrement spare areas to write */
  582. NumSpareAreaTowrite--;
  583. /* Increment the NAND address */
  584. nandAddress = (uint32_t)(nandAddress + (hnand->Info.PageSize));
  585. }
  586. /* Update the NAND controller state */
  587. hnand->State = HAL_NAND_STATE_READY;
  588. /* Process unlocked */
  589. __HAL_UNLOCK(hnand);
  590. return HAL_OK;
  591. }
  592. /**
  593. * @brief NAND memory Block erase
  594. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  595. * the configuration information for NAND module.
  596. * @param pAddress : pointer to NAND address structure
  597. * @retval HAL status
  598. */
  599. HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  600. {
  601. uint32_t DeviceAddress = 0;
  602. /* Process Locked */
  603. __HAL_LOCK(hnand);
  604. /* Check the NAND controller state */
  605. if(hnand->State == HAL_NAND_STATE_BUSY)
  606. {
  607. return HAL_BUSY;
  608. }
  609. /* Identify the device address */
  610. DeviceAddress = NAND_DEVICE;
  611. /* Update the NAND controller state */
  612. hnand->State = HAL_NAND_STATE_BUSY;
  613. /* Send Erase block command sequence */
  614. *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
  615. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  616. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  617. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  618. __DSB();
  619. /* for 512 and 1 GB devices, 4th cycle is required */
  620. if(hnand->Info.BlockNbr >= 1024)
  621. {
  622. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  623. __DSB();
  624. }
  625. *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
  626. __DSB();
  627. /* Update the NAND controller state */
  628. hnand->State = HAL_NAND_STATE_READY;
  629. /* Process unlocked */
  630. __HAL_UNLOCK(hnand);
  631. return HAL_OK;
  632. }
  633. /**
  634. * @brief NAND memory read status
  635. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  636. * the configuration information for NAND module.
  637. * @retval NAND status
  638. */
  639. uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
  640. {
  641. uint32_t data = 0;
  642. uint32_t DeviceAddress = 0;
  643. /* Identify the device address */
  644. DeviceAddress = NAND_DEVICE;
  645. /* Send Read status operation command */
  646. *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
  647. /* Read status register data */
  648. data = *(__IO uint8_t *)DeviceAddress;
  649. /* Return the status */
  650. if((data & NAND_ERROR) == NAND_ERROR)
  651. {
  652. return NAND_ERROR;
  653. }
  654. else if((data & NAND_READY) == NAND_READY)
  655. {
  656. return NAND_READY;
  657. }
  658. return NAND_BUSY;
  659. }
  660. /**
  661. * @brief Increment the NAND memory address
  662. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  663. * the configuration information for NAND module.
  664. * @param pAddress: pointer to NAND address structure
  665. * @retval The new status of the increment address operation. It can be:
  666. * - NAND_VALID_ADDRESS: When the new address is valid address
  667. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  668. */
  669. uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  670. {
  671. uint32_t status = NAND_VALID_ADDRESS;
  672. /* Increment page address */
  673. pAddress->Page++;
  674. /* Check NAND address is valid */
  675. if(pAddress->Page == hnand->Info.BlockSize)
  676. {
  677. pAddress->Page = 0;
  678. pAddress->Block++;
  679. if(pAddress->Block == hnand->Info.ZoneSize)
  680. {
  681. pAddress->Block = 0;
  682. pAddress->Zone++;
  683. if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr))
  684. {
  685. status = NAND_INVALID_ADDRESS;
  686. }
  687. }
  688. }
  689. return (status);
  690. }
  691. /**
  692. * @}
  693. */
  694. /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
  695. * @brief management functions
  696. *
  697. @verbatim
  698. ==============================================================================
  699. ##### NAND Control functions #####
  700. ==============================================================================
  701. [..]
  702. This subsection provides a set of functions allowing to control dynamically
  703. the NAND interface.
  704. @endverbatim
  705. * @{
  706. */
  707. /**
  708. * @brief Enables dynamically NAND ECC feature.
  709. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  710. * the configuration information for NAND module.
  711. * @retval HAL status
  712. */
  713. HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
  714. {
  715. /* Check the NAND controller state */
  716. if(hnand->State == HAL_NAND_STATE_BUSY)
  717. {
  718. return HAL_BUSY;
  719. }
  720. /* Update the NAND state */
  721. hnand->State = HAL_NAND_STATE_BUSY;
  722. /* Enable ECC feature */
  723. FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
  724. /* Update the NAND state */
  725. hnand->State = HAL_NAND_STATE_READY;
  726. return HAL_OK;
  727. }
  728. /**
  729. * @brief Disables dynamically FMC_NAND ECC feature.
  730. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  731. * the configuration information for NAND module.
  732. * @retval HAL status
  733. */
  734. HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
  735. {
  736. /* Check the NAND controller state */
  737. if(hnand->State == HAL_NAND_STATE_BUSY)
  738. {
  739. return HAL_BUSY;
  740. }
  741. /* Update the NAND state */
  742. hnand->State = HAL_NAND_STATE_BUSY;
  743. /* Disable ECC feature */
  744. FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
  745. /* Update the NAND state */
  746. hnand->State = HAL_NAND_STATE_READY;
  747. return HAL_OK;
  748. }
  749. /**
  750. * @brief Disables dynamically NAND ECC feature.
  751. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  752. * the configuration information for NAND module.
  753. * @param ECCval: pointer to ECC value
  754. * @param Timeout: maximum timeout to wait
  755. * @retval HAL status
  756. */
  757. HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
  758. {
  759. HAL_StatusTypeDef status = HAL_OK;
  760. /* Check the NAND controller state */
  761. if(hnand->State == HAL_NAND_STATE_BUSY)
  762. {
  763. return HAL_BUSY;
  764. }
  765. /* Update the NAND state */
  766. hnand->State = HAL_NAND_STATE_BUSY;
  767. /* Get NAND ECC value */
  768. status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
  769. /* Update the NAND state */
  770. hnand->State = HAL_NAND_STATE_READY;
  771. return status;
  772. }
  773. /**
  774. * @}
  775. */
  776. /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
  777. * @brief Peripheral State functions
  778. *
  779. @verbatim
  780. ==============================================================================
  781. ##### NAND State functions #####
  782. ==============================================================================
  783. [..]
  784. This subsection permits to get in run-time the status of the NAND controller
  785. and the data flow.
  786. @endverbatim
  787. * @{
  788. */
  789. /**
  790. * @brief return the NAND state
  791. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  792. * the configuration information for NAND module.
  793. * @retval HAL state
  794. */
  795. HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
  796. {
  797. return hnand->State;
  798. }
  799. /**
  800. * @}
  801. */
  802. /**
  803. * @}
  804. */
  805. #endif /* HAL_NAND_MODULE_ENABLED */
  806. /**
  807. * @}
  808. */
  809. /**
  810. * @}
  811. */
  812. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/