stm32l4xx_hal_nand.c 35 KB

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