stm32h7xx_hal_nand.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862
  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_nand.c
  4. * @author MCD Application Team
  5. * @version V1.0.0
  6. * @date 21-April-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/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_8b()/HAL_NAND_Read_SpareArea_8b(),
  26. HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(),
  27. HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(),
  28. HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b()
  29. to read/write page(s)/spare area(s). These functions use specific device
  30. information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef
  31. structure. The read/write address information is contained by the Nand_Address_Typedef
  32. structure passed as parameter.
  33. (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset().
  34. (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block().
  35. The erase block address information is contained in the Nand_Address_Typedef
  36. structure passed as parameter.
  37. (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status().
  38. (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/
  39. HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction
  40. feature or the function HAL_NAND_GetECC() to get the ECC correction code.
  41. (+) You can monitor the NAND device HAL state by calling the function
  42. HAL_NAND_GetState()
  43. [..]
  44. (@) This driver is a set of generic APIs which handle standard NAND flash operations.
  45. If a NAND flash device contains different operations and/or implementations,
  46. it should be implemented separately.
  47. @endverbatim
  48. ******************************************************************************
  49. * @attention
  50. *
  51. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  52. *
  53. * Redistribution and use in source and binary forms, with or without modification,
  54. * are permitted provided that the following conditions are met:
  55. * 1. Redistributions of source code must retain the above copyright notice,
  56. * this list of conditions and the following disclaimer.
  57. * 2. Redistributions in binary form must reproduce the above copyright notice,
  58. * this list of conditions and the following disclaimer in the documentation
  59. * and/or other materials provided with the distribution.
  60. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  61. * may be used to endorse or promote products derived from this software
  62. * without specific prior written permission.
  63. *
  64. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  65. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  66. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  68. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  69. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  70. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  71. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  72. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  73. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74. *
  75. ******************************************************************************
  76. */
  77. /* Includes ------------------------------------------------------------------*/
  78. #include "stm32h7xx_hal.h"
  79. /** @addtogroup STM32H7xx_HAL_Driver
  80. * @{
  81. */
  82. #ifdef HAL_NAND_MODULE_ENABLED
  83. /** @defgroup NAND NAND
  84. * @brief NAND HAL module driver
  85. * @{
  86. */
  87. /* Private typedef -----------------------------------------------------------*/
  88. /* Private Constants ------------------------------------------------------------*/
  89. /* Private macro -------------------------------------------------------------*/
  90. /* Private variables ---------------------------------------------------------*/
  91. /* Private function prototypes -----------------------------------------------*/
  92. /* Exported functions ---------------------------------------------------------*/
  93. /** @defgroup NAND_Exported_Functions NAND Exported Functions
  94. * @{
  95. */
  96. /** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions
  97. * @brief Initialization and Configuration functions
  98. *
  99. @verbatim
  100. ==============================================================================
  101. ##### NAND Initialization and de-initialization functions #####
  102. ==============================================================================
  103. [..]
  104. This section provides functions allowing to initialize/de-initialize
  105. the NAND memory
  106. @endverbatim
  107. * @{
  108. */
  109. /**
  110. * @brief Perform NAND memory Initialization sequence
  111. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  112. * the configuration information for NAND module.
  113. * @param ComSpace_Timing: pointer to Common space timing structure
  114. * @param AttSpace_Timing: pointer to Attribute space timing structure
  115. * @retval HAL status
  116. */
  117. HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
  118. {
  119. /* Check the NAND handle state */
  120. if(hnand == NULL)
  121. {
  122. return HAL_ERROR;
  123. }
  124. if(hnand->State == HAL_NAND_STATE_RESET)
  125. {
  126. /* Allocate lock resource and initialize it */
  127. hnand->Lock = HAL_UNLOCKED;
  128. /* Initialize the low level hardware (MSP) */
  129. HAL_NAND_MspInit(hnand);
  130. }
  131. /* Initialize NAND control Interface */
  132. FMC_NAND_Init(hnand->Instance, &(hnand->Init));
  133. /* Initialize NAND common space timing Interface */
  134. FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
  135. /* Initialize NAND attribute space timing Interface */
  136. FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
  137. /* Enable the NAND device */
  138. __FMC_NAND_ENABLE(hnand->Instance);
  139. /* Enable FMC IP */
  140. __FMC_ENABLE();
  141. /* Update the NAND controller state */
  142. hnand->State = HAL_NAND_STATE_READY;
  143. return HAL_OK;
  144. }
  145. /**
  146. * @brief Perform NAND memory De-Initialization sequence
  147. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  148. * the configuration information for NAND module.
  149. * @retval HAL status
  150. */
  151. HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)
  152. {
  153. /* Initialize the low level hardware (MSP) */
  154. HAL_NAND_MspDeInit(hnand);
  155. /* Configure the NAND registers with their reset values */
  156. FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);
  157. /* Reset the NAND controller state */
  158. hnand->State = HAL_NAND_STATE_RESET;
  159. /* Release Lock */
  160. __HAL_UNLOCK(hnand);
  161. return HAL_OK;
  162. }
  163. /**
  164. * @brief NAND MSP Init
  165. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  166. * the configuration information for NAND module.
  167. * @retval None
  168. */
  169. __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
  170. {
  171. /* Prevent unused argument(s) compilation warning */
  172. UNUSED(hnand);
  173. /* NOTE : This function Should not be modified, when the callback is needed,
  174. the HAL_NAND_MspInit could be implemented in the user file
  175. */
  176. }
  177. /**
  178. * @brief NAND MSP DeInit
  179. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  180. * the configuration information for NAND module.
  181. * @retval None
  182. */
  183. __weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand)
  184. {
  185. /* Prevent unused argument(s) compilation warning */
  186. UNUSED(hnand);
  187. /* NOTE : This function Should not be modified, when the callback is needed,
  188. the HAL_NAND_MspDeInit could be implemented in the user file
  189. */
  190. }
  191. /**
  192. * @brief This function handles NAND device interrupt request.
  193. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  194. * the configuration information for NAND module.
  195. * @retval HAL status
  196. */
  197. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  198. {
  199. /* Check NAND interrupt Rising edge flag */
  200. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
  201. {
  202. /* NAND interrupt callback*/
  203. HAL_NAND_ITCallback(hnand);
  204. /* Clear NAND interrupt Rising edge pending bit */
  205. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
  206. }
  207. /* Check NAND interrupt Level flag */
  208. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
  209. {
  210. /* NAND interrupt callback*/
  211. HAL_NAND_ITCallback(hnand);
  212. /* Clear NAND interrupt Level pending bit */
  213. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
  214. }
  215. /* Check NAND interrupt Falling edge flag */
  216. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
  217. {
  218. /* NAND interrupt callback*/
  219. HAL_NAND_ITCallback(hnand);
  220. /* Clear NAND interrupt Falling edge pending bit */
  221. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
  222. }
  223. /* Check NAND interrupt FIFO empty flag */
  224. if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
  225. {
  226. /* NAND interrupt callback*/
  227. HAL_NAND_ITCallback(hnand);
  228. /* Clear NAND interrupt FIFO empty pending bit */
  229. __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
  230. }
  231. }
  232. /**
  233. * @brief NAND interrupt feature callback
  234. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  235. * the configuration information for NAND module.
  236. * @retval None
  237. */
  238. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  239. {
  240. /* Prevent unused argument(s) compilation warning */
  241. UNUSED(hnand);
  242. /* NOTE : This function Should not be modified, when the callback is needed,
  243. the HAL_NAND_ITCallback could be implemented in the user file
  244. */
  245. }
  246. /**
  247. * @}
  248. */
  249. /** @defgroup NAND_Exported_Functions_Group2 Input and Output functions
  250. * @brief Input Output and memory control functions
  251. *
  252. @verbatim
  253. ==============================================================================
  254. ##### NAND Input and Output functions #####
  255. ==============================================================================
  256. [..]
  257. This section provides functions allowing to use and control the NAND
  258. memory
  259. @endverbatim
  260. * @{
  261. */
  262. /**
  263. * @brief Read the NAND memory electronic signature
  264. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  265. * the configuration information for NAND module.
  266. * @param pNAND_ID: NAND ID structure
  267. * @retval HAL status
  268. */
  269. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  270. {
  271. __IO uint32_t data = 0;
  272. __IO uint32_t data1 = 0;
  273. uint32_t deviceAddress = 0;
  274. /* Process Locked */
  275. __HAL_LOCK(hnand);
  276. /* Check the NAND controller state */
  277. if(hnand->State == HAL_NAND_STATE_BUSY)
  278. {
  279. return HAL_BUSY;
  280. }
  281. /* Identify the device address */
  282. deviceAddress = NAND_DEVICE;
  283. /* Update the NAND controller state */
  284. hnand->State = HAL_NAND_STATE_BUSY;
  285. /* Send Read ID command sequence */
  286. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_READID;
  287. __DSB();
  288. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  289. __DSB();
  290. /* Read the electronic signature from NAND flash */
  291. if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8)
  292. {
  293. data = *(__IO uint32_t *)deviceAddress;
  294. /* Return the data read */
  295. pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
  296. pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data);
  297. pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data);
  298. pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data);
  299. }
  300. else
  301. {
  302. data = *(__IO uint32_t *)deviceAddress;
  303. data1 = *((__IO uint32_t *)deviceAddress + 4);
  304. /* Return the data read */
  305. pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data);
  306. pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data);
  307. pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1);
  308. pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1);
  309. }
  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 Configure the device: Enter the physical parameters of the device
  346. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  347. * the configuration information for NAND module.
  348. * @param pDeviceConfig : pointer to NAND_DeviceConfigTypeDef structure
  349. * @retval HAL status
  350. */
  351. HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
  352. {
  353. hnand->Config.PageSize = pDeviceConfig->PageSize;
  354. hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize;
  355. hnand->Config.BlockSize = pDeviceConfig->BlockSize;
  356. hnand->Config.BlockNbr = pDeviceConfig->BlockNbr;
  357. hnand->Config.PlaneSize = pDeviceConfig->PlaneSize;
  358. hnand->Config.PlaneNbr = pDeviceConfig->BlockNbr;
  359. hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
  360. return HAL_OK;
  361. }
  362. /**
  363. * @brief Read Page(s) from NAND memory block (8-bits addressing)
  364. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  365. * the configuration information for NAND module.
  366. * @param pAddress : pointer to NAND address structure
  367. * @param pBuffer : pointer to destination read buffer
  368. * @param NumPageToRead : number of pages to read from block
  369. * @retval HAL status
  370. */
  371. HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  372. {
  373. __IO uint32_t index = 0;
  374. uint32_t tickstart = 0U;
  375. uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
  376. /* Process Locked */
  377. __HAL_LOCK(hnand);
  378. /* Check the NAND controller state */
  379. if(hnand->State == HAL_NAND_STATE_BUSY)
  380. {
  381. return HAL_BUSY;
  382. }
  383. /* Identify the device address */
  384. deviceAddress = NAND_DEVICE;
  385. /* Update the NAND controller state */
  386. hnand->State = HAL_NAND_STATE_BUSY;
  387. /* NAND raw address calculation */
  388. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  389. /* Page(s) read loop */
  390. while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  391. {
  392. /* update the buffer size */
  393. size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
  394. /* Send read page command sequence */
  395. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  396. __DSB();
  397. /* Cards with page size <= 512 bytes */
  398. if((hnand->Config.PageSize) <= 512)
  399. {
  400. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  401. {
  402. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  403. __DSB();
  404. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  405. __DSB();
  406. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  407. __DSB();
  408. }
  409. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  410. {
  411. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  412. __DSB();
  413. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  414. __DSB();
  415. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  416. __DSB();
  417. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  418. __DSB();
  419. }
  420. }
  421. else /* (hnand->Config.PageSize) > 512 */
  422. {
  423. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  424. {
  425. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  426. __DSB();
  427. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  428. __DSB();
  429. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  430. __DSB();
  431. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  432. __DSB();
  433. }
  434. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  435. {
  436. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  437. __DSB();
  438. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  439. __DSB();
  440. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  441. __DSB();
  442. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  443. __DSB();
  444. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  445. __DSB();
  446. }
  447. }
  448. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  449. __DSB();
  450. if(hnand->Config.ExtraCommandEnable == ENABLE)
  451. {
  452. /* Get tick */
  453. tickstart = HAL_GetTick();
  454. /* Read status until NAND is ready */
  455. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  456. {
  457. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  458. {
  459. return HAL_TIMEOUT;
  460. }
  461. }
  462. /* Go back to read mode */
  463. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
  464. __DSB();
  465. }
  466. /* Get Data into Buffer */
  467. for(; index < size; index++)
  468. {
  469. *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
  470. }
  471. /* Increment read pages number */
  472. numPagesRead++;
  473. /* Decrement pages to read */
  474. NumPageToRead--;
  475. /* Increment the NAND address */
  476. nandAddress = (uint32_t)(nandAddress + 1);
  477. }
  478. /* Update the NAND controller state */
  479. hnand->State = HAL_NAND_STATE_READY;
  480. /* Process unlocked */
  481. __HAL_UNLOCK(hnand);
  482. return HAL_OK;
  483. }
  484. /**
  485. * @brief Read Page(s) from NAND memory block (16-bits addressing)
  486. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  487. * the configuration information for NAND module.
  488. * @param pAddress : pointer to NAND address structure
  489. * @param pBuffer : pointer to destination read buffer. pBuffer should be 16bits aligned
  490. * @param NumPageToRead : number of pages to read from block
  491. * @retval HAL status
  492. */
  493. HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
  494. {
  495. __IO uint32_t index = 0;
  496. uint32_t tickstart = 0;
  497. uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
  498. /* Process Locked */
  499. __HAL_LOCK(hnand);
  500. /* Check the NAND controller state */
  501. if(hnand->State == HAL_NAND_STATE_BUSY)
  502. {
  503. return HAL_BUSY;
  504. }
  505. /* Identify the device address */
  506. deviceAddress = NAND_DEVICE;
  507. /* Update the NAND controller state */
  508. hnand->State = HAL_NAND_STATE_BUSY;
  509. /* NAND raw address calculation */
  510. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  511. /* Page(s) read loop */
  512. while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  513. {
  514. /* update the buffer size */
  515. size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
  516. /* Send read page command sequence */
  517. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  518. __DSB();
  519. /* Cards with page size <= 512 bytes */
  520. if((hnand->Config.PageSize) <= 512)
  521. {
  522. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  523. {
  524. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  525. __DSB();
  526. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  527. __DSB();
  528. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  529. __DSB();
  530. }
  531. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  532. {
  533. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  534. __DSB();
  535. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  536. __DSB();
  537. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  538. __DSB();
  539. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  540. __DSB();
  541. }
  542. }
  543. else /* (hnand->Config.PageSize) > 512 */
  544. {
  545. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  546. {
  547. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  548. __DSB();
  549. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  550. __DSB();
  551. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  552. __DSB();
  553. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  554. __DSB();
  555. }
  556. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  557. {
  558. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  559. __DSB();
  560. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  561. __DSB();
  562. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  563. __DSB();
  564. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  565. __DSB();
  566. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  567. __DSB();
  568. }
  569. }
  570. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  571. __DSB();
  572. if(hnand->Config.ExtraCommandEnable == ENABLE)
  573. {
  574. /* Get tick */
  575. tickstart = HAL_GetTick();
  576. /* Read status until NAND is ready */
  577. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  578. {
  579. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  580. {
  581. return HAL_TIMEOUT;
  582. }
  583. }
  584. /* Go back to read mode */
  585. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
  586. __DSB();
  587. }
  588. /* Get Data into Buffer */
  589. for(; index < size; index++)
  590. {
  591. *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
  592. }
  593. /* Increment read pages number */
  594. numPagesRead++;
  595. /* Decrement pages to read */
  596. NumPageToRead--;
  597. /* Increment the NAND address */
  598. nandAddress = (uint32_t)(nandAddress + 1);
  599. }
  600. /* Update the NAND controller state */
  601. hnand->State = HAL_NAND_STATE_READY;
  602. /* Process unlocked */
  603. __HAL_UNLOCK(hnand);
  604. return HAL_OK;
  605. }
  606. /**
  607. * @brief Write Page(s) to NAND memory block (8-bits addressing)
  608. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  609. * the configuration information for NAND module.
  610. * @param pAddress : pointer to NAND address structure
  611. * @param pBuffer : pointer to source buffer to write
  612. * @param NumPageToWrite : number of pages to write to block
  613. * @retval HAL status
  614. */
  615. HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  616. {
  617. __IO uint32_t index = 0;
  618. uint32_t tickstart = 0;
  619. uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
  620. /* Process Locked */
  621. __HAL_LOCK(hnand);
  622. /* Check the NAND controller state */
  623. if(hnand->State == HAL_NAND_STATE_BUSY)
  624. {
  625. return HAL_BUSY;
  626. }
  627. /* Identify the device address */
  628. deviceAddress = NAND_DEVICE;
  629. /* Update the NAND controller state */
  630. hnand->State = HAL_NAND_STATE_BUSY;
  631. /* NAND raw address calculation */
  632. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  633. /* Page(s) write loop */
  634. while((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  635. {
  636. /* update the buffer size */
  637. size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
  638. /* Send write page command sequence */
  639. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  640. __DSB();
  641. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  642. __DSB();
  643. /* Cards with page size <= 512 bytes */
  644. if((hnand->Config.PageSize) <= 512)
  645. {
  646. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  647. {
  648. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  649. __DSB();
  650. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  651. __DSB();
  652. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  653. __DSB();
  654. }
  655. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  656. {
  657. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  658. __DSB();
  659. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  660. __DSB();
  661. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  662. __DSB();
  663. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  664. __DSB();
  665. }
  666. }
  667. else /* (hnand->Config.PageSize) > 512 */
  668. {
  669. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  670. {
  671. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  672. __DSB();
  673. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  674. __DSB();
  675. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  676. __DSB();
  677. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  678. __DSB();
  679. }
  680. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  681. {
  682. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  683. __DSB();
  684. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  685. __DSB();
  686. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  687. __DSB();
  688. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  689. __DSB();
  690. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  691. __DSB();
  692. }
  693. }
  694. /* Write data to memory */
  695. for(; index < size; index++)
  696. {
  697. *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
  698. __DSB();
  699. }
  700. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  701. __DSB();
  702. /* Read status until NAND is ready */
  703. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  704. {
  705. /* Get tick */
  706. tickstart = HAL_GetTick();
  707. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  708. {
  709. return HAL_TIMEOUT;
  710. }
  711. }
  712. /* Increment written pages number */
  713. numPagesWritten++;
  714. /* Decrement pages to write */
  715. NumPageToWrite--;
  716. /* Increment the NAND address */
  717. nandAddress = (uint32_t)(nandAddress + 1);
  718. }
  719. /* Update the NAND controller state */
  720. hnand->State = HAL_NAND_STATE_READY;
  721. /* Process unlocked */
  722. __HAL_UNLOCK(hnand);
  723. return HAL_OK;
  724. }
  725. /**
  726. * @brief Write Page(s) to NAND memory block (16-bits addressing)
  727. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  728. * the configuration information for NAND module.
  729. * @param pAddress : pointer to NAND address structure
  730. * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned
  731. * @param NumPageToWrite : number of pages to write to block
  732. * @retval HAL status
  733. */
  734. HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
  735. {
  736. __IO uint32_t index = 0;
  737. uint32_t tickstart = 0;
  738. uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
  739. /* Process Locked */
  740. __HAL_LOCK(hnand);
  741. /* Check the NAND controller state */
  742. if(hnand->State == HAL_NAND_STATE_BUSY)
  743. {
  744. return HAL_BUSY;
  745. }
  746. /* Identify the device address */
  747. deviceAddress = NAND_DEVICE;
  748. /* Update the NAND controller state */
  749. hnand->State = HAL_NAND_STATE_BUSY;
  750. /* NAND raw address calculation */
  751. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  752. /* Page(s) write loop */
  753. while((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  754. {
  755. /* update the buffer size */
  756. size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);
  757. /* Send write page command sequence */
  758. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  759. __DSB();
  760. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  761. __DSB();
  762. /* Cards with page size <= 512 bytes */
  763. if((hnand->Config.PageSize) <= 512)
  764. {
  765. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  766. {
  767. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  768. __DSB();
  769. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  770. __DSB();
  771. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  772. __DSB();
  773. }
  774. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  775. {
  776. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  777. __DSB();
  778. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  779. __DSB();
  780. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  781. __DSB();
  782. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  783. __DSB();
  784. }
  785. }
  786. else /* (hnand->Config.PageSize) > 512 */
  787. {
  788. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  789. {
  790. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  791. __DSB();
  792. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  793. __DSB();
  794. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  795. __DSB();
  796. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  797. __DSB();
  798. }
  799. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  800. {
  801. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  802. __DSB();
  803. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  804. __DSB();
  805. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  806. __DSB();
  807. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  808. __DSB();
  809. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  810. __DSB();
  811. }
  812. }
  813. /* Write data to memory */
  814. for(; index < size; index++)
  815. {
  816. *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
  817. __DSB();
  818. }
  819. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  820. __DSB();
  821. /* Read status until NAND is ready */
  822. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  823. {
  824. /* Get tick */
  825. tickstart = HAL_GetTick();
  826. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  827. {
  828. return HAL_TIMEOUT;
  829. }
  830. }
  831. /* Increment written pages number */
  832. numPagesWritten++;
  833. /* Decrement pages to write */
  834. NumPageToWrite--;
  835. /* Increment the NAND address */
  836. nandAddress = (uint32_t)(nandAddress + 1);
  837. }
  838. /* Update the NAND controller state */
  839. hnand->State = HAL_NAND_STATE_READY;
  840. /* Process unlocked */
  841. __HAL_UNLOCK(hnand);
  842. return HAL_OK;
  843. }
  844. /**
  845. * @brief Read Spare area(s) from NAND memory (8-bits addressing)
  846. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  847. * the configuration information for NAND module.
  848. * @param pAddress : pointer to NAND address structure
  849. * @param pBuffer: pointer to source buffer to write
  850. * @param NumSpareAreaToRead: Number of spare area to read
  851. * @retval HAL status
  852. */
  853. HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead)
  854. {
  855. __IO uint32_t index = 0;
  856. uint32_t tickstart = 0U;
  857. uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
  858. /* Process Locked */
  859. __HAL_LOCK(hnand);
  860. /* Check the NAND controller state */
  861. if(hnand->State == HAL_NAND_STATE_BUSY)
  862. {
  863. return HAL_BUSY;
  864. }
  865. /* Identify the device address */
  866. deviceAddress = NAND_DEVICE;
  867. /* Update the NAND controller state */
  868. hnand->State = HAL_NAND_STATE_BUSY;
  869. /* NAND raw address calculation */
  870. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  871. /* Column in page address */
  872. columnAddress = COLUMN_ADDRESS(hnand);
  873. /* Spare area(s) read loop */
  874. while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  875. {
  876. /* update the buffer size */
  877. size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
  878. /* Cards with page size <= 512 bytes */
  879. if((hnand->Config.PageSize) <= 512)
  880. {
  881. /* Send read spare area command sequence */
  882. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
  883. __DSB();
  884. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  885. {
  886. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  887. __DSB();
  888. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  889. __DSB();
  890. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  891. __DSB();
  892. }
  893. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  894. {
  895. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  896. __DSB();
  897. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  898. __DSB();
  899. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  900. __DSB();
  901. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  902. __DSB();
  903. }
  904. }
  905. else /* (hnand->Config.PageSize) > 512 */
  906. {
  907. /* Send read spare area command sequence */
  908. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  909. __DSB();
  910. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  911. {
  912. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  913. __DSB();
  914. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  915. __DSB();
  916. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  917. __DSB();
  918. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  919. __DSB();
  920. }
  921. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  922. {
  923. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  924. __DSB();
  925. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  926. __DSB();
  927. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  928. __DSB();
  929. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  930. __DSB();
  931. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  932. __DSB();
  933. }
  934. }
  935. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  936. __DSB();
  937. if(hnand->Config.ExtraCommandEnable == ENABLE)
  938. {
  939. /* Get tick */
  940. tickstart = HAL_GetTick();
  941. /* Read status until NAND is ready */
  942. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  943. {
  944. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  945. {
  946. return HAL_TIMEOUT;
  947. }
  948. }
  949. /* Go back to read mode */
  950. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
  951. __DSB();
  952. }
  953. /* Get Data into Buffer */
  954. for(; index < size; index++)
  955. {
  956. *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
  957. }
  958. /* Increment read spare areas number */
  959. numSpareAreaRead++;
  960. /* Decrement spare areas to read */
  961. NumSpareAreaToRead--;
  962. /* Increment the NAND address */
  963. nandAddress = (uint32_t)(nandAddress + 1);
  964. }
  965. /* Update the NAND controller state */
  966. hnand->State = HAL_NAND_STATE_READY;
  967. /* Process unlocked */
  968. __HAL_UNLOCK(hnand);
  969. return HAL_OK;
  970. }
  971. /**
  972. * @brief Read Spare area(s) from NAND memory (16-bits addressing)
  973. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  974. * the configuration information for NAND module.
  975. * @param pAddress : pointer to NAND address structure
  976. * @param pBuffer: pointer to source buffer to write. pBuffer should be 16bits aligned.
  977. * @param NumSpareAreaToRead: Number of spare area to read
  978. * @retval HAL status
  979. */
  980. HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaToRead)
  981. {
  982. __IO uint32_t index = 0;
  983. uint32_t tickstart = 0U;
  984. uint32_t deviceAddress = 0, size = 0, numSpareAreaRead = 0, nandAddress = 0, columnAddress = 0;
  985. /* Process Locked */
  986. __HAL_LOCK(hnand);
  987. /* Check the NAND controller state */
  988. if(hnand->State == HAL_NAND_STATE_BUSY)
  989. {
  990. return HAL_BUSY;
  991. }
  992. /* Identify the device address */
  993. deviceAddress = NAND_DEVICE;
  994. /* Update the NAND controller state */
  995. hnand->State = HAL_NAND_STATE_BUSY;
  996. /* NAND raw address calculation */
  997. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  998. /* Column in page address */
  999. columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
  1000. /* Spare area(s) read loop */
  1001. while((NumSpareAreaToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1002. {
  1003. /* update the buffer size */
  1004. size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaRead);
  1005. /* Cards with page size <= 512 bytes */
  1006. if((hnand->Config.PageSize) <= 512)
  1007. {
  1008. /* Send read spare area command sequence */
  1009. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1010. __DSB();
  1011. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  1012. {
  1013. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  1014. __DSB();
  1015. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1016. __DSB();
  1017. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1018. __DSB();
  1019. }
  1020. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1021. {
  1022. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  1023. __DSB();
  1024. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1025. __DSB();
  1026. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1027. __DSB();
  1028. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  1029. __DSB();
  1030. }
  1031. }
  1032. else /* (hnand->Config.PageSize) > 512 */
  1033. {
  1034. /* Send read spare area command sequence */
  1035. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1036. __DSB();
  1037. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  1038. {
  1039. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  1040. __DSB();
  1041. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  1042. __DSB();
  1043. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1044. __DSB();
  1045. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1046. __DSB();
  1047. }
  1048. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1049. {
  1050. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  1051. __DSB();
  1052. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  1053. __DSB();
  1054. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1055. __DSB();
  1056. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1057. __DSB();
  1058. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  1059. __DSB();
  1060. }
  1061. }
  1062. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
  1063. __DSB();
  1064. if(hnand->Config.ExtraCommandEnable == ENABLE)
  1065. {
  1066. /* Get tick */
  1067. tickstart = HAL_GetTick();
  1068. /* Read status until NAND is ready */
  1069. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1070. {
  1071. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1072. {
  1073. return HAL_TIMEOUT;
  1074. }
  1075. }
  1076. /* Go back to read mode */
  1077. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
  1078. __DSB();
  1079. }
  1080. /* Get Data into Buffer */
  1081. for(; index < size; index++)
  1082. {
  1083. *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
  1084. }
  1085. /* Increment read spare areas number */
  1086. numSpareAreaRead++;
  1087. /* Decrement spare areas to read */
  1088. NumSpareAreaToRead--;
  1089. /* Increment the NAND address */
  1090. nandAddress = (uint32_t)(nandAddress + 1);
  1091. }
  1092. /* Update the NAND controller state */
  1093. hnand->State = HAL_NAND_STATE_READY;
  1094. /* Process unlocked */
  1095. __HAL_UNLOCK(hnand);
  1096. return HAL_OK;
  1097. }
  1098. /**
  1099. * @brief Write Spare area(s) to NAND memory (8-bits addressing)
  1100. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1101. * the configuration information for NAND module.
  1102. * @param pAddress : pointer to NAND address structure
  1103. * @param pBuffer : pointer to source buffer to write
  1104. * @param NumSpareAreaTowrite : number of spare areas to write to block
  1105. * @retval HAL status
  1106. */
  1107. HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite)
  1108. {
  1109. __IO uint32_t index = 0;
  1110. uint32_t tickstart = 0;
  1111. uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress =0;
  1112. /* Process Locked */
  1113. __HAL_LOCK(hnand);
  1114. /* Check the NAND controller state */
  1115. if(hnand->State == HAL_NAND_STATE_BUSY)
  1116. {
  1117. return HAL_BUSY;
  1118. }
  1119. /* Identify the device address */
  1120. deviceAddress = NAND_DEVICE;
  1121. /* Update the FMC_NAND controller state */
  1122. hnand->State = HAL_NAND_STATE_BUSY;
  1123. /* Page address calculation */
  1124. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  1125. /* Column in page address */
  1126. columnAddress = COLUMN_ADDRESS(hnand);
  1127. /* Spare area(s) write loop */
  1128. while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1129. {
  1130. /* update the buffer size */
  1131. size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
  1132. /* Cards with page size <= 512 bytes */
  1133. if((hnand->Config.PageSize) <= 512)
  1134. {
  1135. /* Send write Spare area command sequence */
  1136. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1137. __DSB();
  1138. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1139. __DSB();
  1140. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  1141. {
  1142. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  1143. __DSB();
  1144. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1145. __DSB();
  1146. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1147. __DSB();
  1148. }
  1149. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1150. {
  1151. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  1152. __DSB();
  1153. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1154. __DSB();
  1155. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1156. __DSB();
  1157. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  1158. __DSB();
  1159. }
  1160. }
  1161. else /* (hnand->Config.PageSize) > 512 */
  1162. {
  1163. /* Send write Spare area command sequence */
  1164. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1165. __DSB();
  1166. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1167. __DSB();
  1168. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  1169. {
  1170. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  1171. __DSB();
  1172. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  1173. __DSB();
  1174. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1175. __DSB();
  1176. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1177. __DSB();
  1178. }
  1179. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1180. {
  1181. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  1182. __DSB();
  1183. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  1184. __DSB();
  1185. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1186. __DSB();
  1187. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1188. __DSB();
  1189. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  1190. __DSB();
  1191. }
  1192. }
  1193. /* Write data to memory */
  1194. for(; index < size; index++)
  1195. {
  1196. *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
  1197. __DSB();
  1198. }
  1199. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  1200. __DSB();
  1201. /* Read status until NAND is ready */
  1202. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1203. {
  1204. /* Get tick */
  1205. tickstart = HAL_GetTick();
  1206. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1207. {
  1208. return HAL_TIMEOUT;
  1209. }
  1210. }
  1211. /* Increment written spare areas number */
  1212. numSpareAreaWritten++;
  1213. /* Decrement spare areas to write */
  1214. NumSpareAreaTowrite--;
  1215. /* Increment the NAND address */
  1216. nandAddress = (uint32_t)(nandAddress + 1);
  1217. }
  1218. /* Update the NAND controller state */
  1219. hnand->State = HAL_NAND_STATE_READY;
  1220. /* Process unlocked */
  1221. __HAL_UNLOCK(hnand);
  1222. return HAL_OK;
  1223. }
  1224. /**
  1225. * @brief Write Spare area(s) to NAND memory (16-bits addressing)
  1226. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1227. * the configuration information for NAND module.
  1228. * @param pAddress : pointer to NAND address structure
  1229. * @param pBuffer : pointer to source buffer to write. pBuffer should be 16bits aligned.
  1230. * @param NumSpareAreaTowrite : number of spare areas to write to block
  1231. * @retval HAL status
  1232. */
  1233. HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumSpareAreaTowrite)
  1234. {
  1235. __IO uint32_t index = 0;
  1236. uint32_t tickstart = 0;
  1237. uint32_t deviceAddress = 0, size = 0, numSpareAreaWritten = 0, nandAddress = 0, columnAddress = 0;
  1238. /* Process Locked */
  1239. __HAL_LOCK(hnand);
  1240. /* Check the NAND controller state */
  1241. if(hnand->State == HAL_NAND_STATE_BUSY)
  1242. {
  1243. return HAL_BUSY;
  1244. }
  1245. /* Identify the device address */
  1246. deviceAddress = NAND_DEVICE;
  1247. /* Update the FMC_NAND controller state */
  1248. hnand->State = HAL_NAND_STATE_BUSY;
  1249. /* NAND raw address calculation */
  1250. nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  1251. /* Column in page address */
  1252. columnAddress = (uint32_t)(COLUMN_ADDRESS(hnand) * 2);
  1253. /* Spare area(s) write loop */
  1254. while((NumSpareAreaTowrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  1255. {
  1256. /* update the buffer size */
  1257. size = (hnand->Config.SpareAreaSize) + ((hnand->Config.SpareAreaSize) * numSpareAreaWritten);
  1258. /* Cards with page size <= 512 bytes */
  1259. if((hnand->Config.PageSize) <= 512)
  1260. {
  1261. /* Send write Spare area command sequence */
  1262. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_C;
  1263. __DSB();
  1264. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1265. __DSB();
  1266. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  1267. {
  1268. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  1269. __DSB();
  1270. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1271. __DSB();
  1272. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1273. __DSB();
  1274. }
  1275. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1276. {
  1277. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  1278. __DSB();
  1279. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1280. __DSB();
  1281. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1282. __DSB();
  1283. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  1284. __DSB();
  1285. }
  1286. }
  1287. else /* (hnand->Config.PageSize) > 512 */
  1288. {
  1289. /* Send write Spare area command sequence */
  1290. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  1291. __DSB();
  1292. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  1293. __DSB();
  1294. if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  1295. {
  1296. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  1297. __DSB();
  1298. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  1299. __DSB();
  1300. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1301. __DSB();
  1302. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1303. __DSB();
  1304. }
  1305. else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  1306. {
  1307. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnAddress);
  1308. __DSB();
  1309. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnAddress);
  1310. __DSB();
  1311. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  1312. __DSB();
  1313. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  1314. __DSB();
  1315. *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  1316. __DSB();
  1317. }
  1318. }
  1319. /* Write data to memory */
  1320. for(; index < size; index++)
  1321. {
  1322. *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
  1323. __DSB();
  1324. }
  1325. *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  1326. __DSB();
  1327. /* Read status until NAND is ready */
  1328. while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  1329. {
  1330. /* Get tick */
  1331. tickstart = HAL_GetTick();
  1332. if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  1333. {
  1334. return HAL_TIMEOUT;
  1335. }
  1336. }
  1337. /* Increment written spare areas number */
  1338. numSpareAreaWritten++;
  1339. /* Decrement spare areas to write */
  1340. NumSpareAreaTowrite--;
  1341. /* Increment the NAND address */
  1342. nandAddress = (uint32_t)(nandAddress + 1);
  1343. }
  1344. /* Update the NAND controller state */
  1345. hnand->State = HAL_NAND_STATE_READY;
  1346. /* Process unlocked */
  1347. __HAL_UNLOCK(hnand);
  1348. return HAL_OK;
  1349. }
  1350. /**
  1351. * @brief NAND memory Block erase
  1352. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1353. * the configuration information for NAND module.
  1354. * @param pAddress : pointer to NAND address structure
  1355. * @retval HAL status
  1356. */
  1357. HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  1358. {
  1359. uint32_t DeviceAddress = 0;
  1360. /* Process Locked */
  1361. __HAL_LOCK(hnand);
  1362. /* Check the NAND controller state */
  1363. if(hnand->State == HAL_NAND_STATE_BUSY)
  1364. {
  1365. return HAL_BUSY;
  1366. }
  1367. /* Identify the device address */
  1368. DeviceAddress = NAND_DEVICE;
  1369. /* Update the NAND controller state */
  1370. hnand->State = HAL_NAND_STATE_BUSY;
  1371. /* Send Erase block command sequence */
  1372. *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE0;
  1373. __DSB();
  1374. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  1375. __DSB();
  1376. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  1377. __DSB();
  1378. *(__IO uint8_t *)((uint32_t)(DeviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand));
  1379. __DSB();
  1380. *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_ERASE1;
  1381. __DSB();
  1382. /* Update the NAND controller state */
  1383. hnand->State = HAL_NAND_STATE_READY;
  1384. /* Process unlocked */
  1385. __HAL_UNLOCK(hnand);
  1386. return HAL_OK;
  1387. }
  1388. /**
  1389. * @brief Increment the NAND memory address
  1390. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1391. * the configuration information for NAND module.
  1392. * @param pAddress: pointer to NAND address structure
  1393. * @retval The new status of the increment address operation. It can be:
  1394. * - NAND_VALID_ADDRESS: When the new address is valid address
  1395. * - NAND_INVALID_ADDRESS: When the new address is invalid address
  1396. */
  1397. uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress)
  1398. {
  1399. uint32_t status = NAND_VALID_ADDRESS;
  1400. /* Increment page address */
  1401. pAddress->Page++;
  1402. /* Check NAND address is valid */
  1403. if(pAddress->Page == hnand->Config.BlockSize)
  1404. {
  1405. pAddress->Page = 0;
  1406. pAddress->Block++;
  1407. if(pAddress->Block == hnand->Config.PlaneSize)
  1408. {
  1409. pAddress->Block = 0;
  1410. pAddress->Plane++;
  1411. if(pAddress->Plane == (hnand->Config.PlaneSize/ hnand->Config.BlockNbr))
  1412. {
  1413. status = NAND_INVALID_ADDRESS;
  1414. }
  1415. }
  1416. }
  1417. return (status);
  1418. }
  1419. /**
  1420. * @}
  1421. */
  1422. /** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions
  1423. * @brief management functions
  1424. *
  1425. @verbatim
  1426. ==============================================================================
  1427. ##### NAND Control functions #####
  1428. ==============================================================================
  1429. [..]
  1430. This subsection provides a set of functions allowing to control dynamically
  1431. the NAND interface.
  1432. @endverbatim
  1433. * @{
  1434. */
  1435. /**
  1436. * @brief Enables dynamically NAND ECC feature.
  1437. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1438. * the configuration information for NAND module.
  1439. * @retval HAL status
  1440. */
  1441. HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand)
  1442. {
  1443. /* Check the NAND controller state */
  1444. if(hnand->State == HAL_NAND_STATE_BUSY)
  1445. {
  1446. return HAL_BUSY;
  1447. }
  1448. /* Update the NAND state */
  1449. hnand->State = HAL_NAND_STATE_BUSY;
  1450. /* Enable ECC feature */
  1451. FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank);
  1452. /* Update the NAND state */
  1453. hnand->State = HAL_NAND_STATE_READY;
  1454. return HAL_OK;
  1455. }
  1456. /**
  1457. * @brief Disables dynamically FMC_NAND ECC feature.
  1458. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1459. * the configuration information for NAND module.
  1460. * @retval HAL status
  1461. */
  1462. HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand)
  1463. {
  1464. /* Check the NAND controller state */
  1465. if(hnand->State == HAL_NAND_STATE_BUSY)
  1466. {
  1467. return HAL_BUSY;
  1468. }
  1469. /* Update the NAND state */
  1470. hnand->State = HAL_NAND_STATE_BUSY;
  1471. /* Disable ECC feature */
  1472. FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank);
  1473. /* Update the NAND state */
  1474. hnand->State = HAL_NAND_STATE_READY;
  1475. return HAL_OK;
  1476. }
  1477. /**
  1478. * @brief Disables dynamically NAND ECC feature.
  1479. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1480. * the configuration information for NAND module.
  1481. * @param ECCval: pointer to ECC value
  1482. * @param Timeout: maximum timeout to wait
  1483. * @retval HAL status
  1484. */
  1485. HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout)
  1486. {
  1487. HAL_StatusTypeDef status = HAL_OK;
  1488. /* Check the NAND controller state */
  1489. if(hnand->State == HAL_NAND_STATE_BUSY)
  1490. {
  1491. return HAL_BUSY;
  1492. }
  1493. /* Update the NAND state */
  1494. hnand->State = HAL_NAND_STATE_BUSY;
  1495. /* Get NAND ECC value */
  1496. status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout);
  1497. /* Update the NAND state */
  1498. hnand->State = HAL_NAND_STATE_READY;
  1499. return status;
  1500. }
  1501. /**
  1502. * @}
  1503. */
  1504. /** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions
  1505. * @brief Peripheral State functions
  1506. *
  1507. @verbatim
  1508. ==============================================================================
  1509. ##### NAND State functions #####
  1510. ==============================================================================
  1511. [..]
  1512. This subsection permits to get in run-time the status of the NAND controller
  1513. and the data flow.
  1514. @endverbatim
  1515. * @{
  1516. */
  1517. /**
  1518. * @brief return the NAND state
  1519. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1520. * the configuration information for NAND module.
  1521. * @retval HAL state
  1522. */
  1523. HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand)
  1524. {
  1525. return hnand->State;
  1526. }
  1527. /**
  1528. * @brief NAND memory read status
  1529. * @param hnand: pointer to a NAND_HandleTypeDef structure that contains
  1530. * the configuration information for NAND module.
  1531. * @retval NAND status
  1532. */
  1533. uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)
  1534. {
  1535. uint32_t data = 0;
  1536. uint32_t DeviceAddress = 0;
  1537. /* Identify the device address */
  1538. DeviceAddress = NAND_DEVICE;
  1539. /* Send Read status operation command */
  1540. *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;
  1541. /* Read status register data */
  1542. data = *(__IO uint8_t *)DeviceAddress;
  1543. /* Return the status */
  1544. if((data & NAND_ERROR) == NAND_ERROR)
  1545. {
  1546. return NAND_ERROR;
  1547. }
  1548. else if((data & NAND_READY) == NAND_READY)
  1549. {
  1550. return NAND_READY;
  1551. }
  1552. return NAND_BUSY;
  1553. }
  1554. /**
  1555. * @}
  1556. */
  1557. /**
  1558. * @}
  1559. */
  1560. #endif /* HAL_NAND_MODULE_ENABLED */
  1561. /**
  1562. * @}
  1563. */
  1564. /**
  1565. * @}
  1566. */
  1567. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/