stm32f4xx_hal_nand.c 35 KB

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