stm32f1xx_hal_nand.c 36 KB

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