1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_ll_fmc.c
4   * @author  MCD Application Team
5   * @brief   FMC Low Layer HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the Flexible Memory Controller (FMC) peripheral memories:
9   *           + Initialization/de-initialization functions
10   *           + Peripheral Control functions
11   *           + Peripheral State functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2019 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### FMC peripheral features #####
27   ==============================================================================
28   [..] The Flexible memory controller (FMC) includes following memory controllers:
29        (+) The NOR/PSRAM memory controller
30      (+) The NAND memory controller
31 
32   [..] The FMC functional block makes the interface with synchronous and asynchronous static
33        memories. Its main purposes are:
34        (+) to translate AHB transactions into the appropriate external device protocol
35        (+) to meet the access time requirements of the external memory devices
36 
37   [..] All external memories share the addresses, data and control signals with the controller.
38        Each external device is accessed by means of a unique Chip Select. The FMC performs
39        only one access at a time to an external device.
40        The main features of the FMC controller are the following:
41         (+) Interface with static-memory mapped devices including:
42            (++) Static random access memory (SRAM)
43            (++) Read-only memory (ROM)
44            (++) NOR Flash memory/OneNAND Flash memory
45            (++) PSRAM (4 memory banks)
46            (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of
47                 data
48         (+) Independent Chip Select control for each memory bank
49         (+) Independent configuration for each memory bank
50 
51   @endverbatim
52   ******************************************************************************
53   */
54 
55 /* Includes ------------------------------------------------------------------*/
56 #include "stm32l5xx_hal.h"
57 
58 /** @addtogroup STM32L5xx_HAL_Driver
59   * @{
60   */
61 #if defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) \
62  || defined(HAL_SRAM_MODULE_ENABLED)
63 
64 /** @defgroup FMC_LL  FMC Low Layer
65   * @brief FMC driver modules
66   * @{
67   */
68 
69 /* Private typedef -----------------------------------------------------------*/
70 /* Private define ------------------------------------------------------------*/
71 
72 /** @defgroup FMC_LL_Private_Constants FMC Low Layer Private Constants
73   * @{
74   */
75 
76 /* ----------------------- FMC registers bit mask --------------------------- */
77 
78 /* --- BCR Register ---*/
79 /* BCR register clear mask */
80 
81 /* --- BTR Register ---*/
82 /* BTR register clear mask */
83 #define BTR_CLEAR_MASK    ((uint32_t)(FMC_BTRx_ADDSET | FMC_BTRx_ADDHLD  |\
84                                       FMC_BTRx_DATAST | FMC_BTRx_BUSTURN |\
85                                       FMC_BTRx_CLKDIV | FMC_BTRx_DATLAT  |\
86                                       FMC_BTRx_ACCMOD | FMC_BTRx_DATAHLD))
87 
88 /* --- BWTR Register ---*/
89 /* BWTR register clear mask */
90 #define BWTR_CLEAR_MASK   ((uint32_t)(FMC_BWTRx_ADDSET | FMC_BWTRx_ADDHLD  |\
91                                       FMC_BWTRx_DATAST | FMC_BWTRx_BUSTURN |\
92                                       FMC_BWTRx_ACCMOD | FMC_BWTRx_DATAHLD))
93 
94 /* --- PCR Register ---*/
95 /* PCR register clear mask */
96 #define PCR_CLEAR_MASK    ((uint32_t)(FMC_PCR_PWAITEN | FMC_PCR_PBKEN  | \
97                                       FMC_PCR_PTYP    | FMC_PCR_PWID   | \
98                                       FMC_PCR_ECCEN   | FMC_PCR_TCLR   | \
99                                       FMC_PCR_TAR     | FMC_PCR_ECCPS))
100 /* --- PMEM Register ---*/
101 /* PMEM register clear mask */
102 #define PMEM_CLEAR_MASK   ((uint32_t)(FMC_PMEM_MEMSET  | FMC_PMEM_MEMWAIT |\
103                                       FMC_PMEM_MEMHOLD | FMC_PMEM_MEMHIZ))
104 
105 /* --- PATT Register ---*/
106 /* PATT register clear mask */
107 #define PATT_CLEAR_MASK   ((uint32_t)(FMC_PATT_ATTSET  | FMC_PATT_ATTWAIT |\
108                                       FMC_PATT_ATTHOLD | FMC_PATT_ATTHIZ))
109 
110 
111 /**
112   * @}
113   */
114 
115 /* Private macro -------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /* Private function prototypes -----------------------------------------------*/
118 /* Exported functions --------------------------------------------------------*/
119 
120 /** @defgroup FMC_LL_Exported_Functions FMC Low Layer Exported Functions
121   * @{
122   */
123 
124 
125 /** @defgroup FMC_LL_Exported_Functions_NORSRAM FMC Low Layer NOR SRAM Exported Functions
126   * @brief  NORSRAM Controller functions
127   *
128   @verbatim
129   ==============================================================================
130                    ##### How to use NORSRAM device driver #####
131   ==============================================================================
132 
133   [..]
134     This driver contains a set of APIs to interface with the FMC NORSRAM banks in order
135     to run the NORSRAM external devices.
136 
137     (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit()
138     (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init()
139     (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init()
140     (+) FMC NORSRAM bank extended timing configuration using the function
141         FMC_NORSRAM_Extended_Timing_Init()
142     (+) FMC NORSRAM bank enable/disable write operation using the functions
143         FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable()
144 
145 @endverbatim
146   * @{
147   */
148 
149 /** @defgroup FMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions
150   * @brief    Initialization and Configuration functions
151   *
152   @verbatim
153   ==============================================================================
154               ##### Initialization and de_initialization functions #####
155   ==============================================================================
156   [..]
157     This section provides functions allowing to:
158     (+) Initialize and configure the FMC NORSRAM interface
159     (+) De-initialize the FMC NORSRAM interface
160     (+) Configure the FMC clock and associated GPIOs
161 
162 @endverbatim
163   * @{
164   */
165 
166 /**
167   * @brief  Initialize the FMC_NORSRAM device according to the specified
168   *         control parameters in the FMC_NORSRAM_InitTypeDef
169   * @param  Device Pointer to NORSRAM device instance
170   * @param  Init Pointer to NORSRAM Initialization structure
171   * @retval HAL status
172   */
FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_InitTypeDef * Init)173 HAL_StatusTypeDef  FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device,
174                                     FMC_NORSRAM_InitTypeDef *Init)
175 {
176   uint32_t flashaccess;
177   uint32_t btcr_reg;
178   uint32_t mask;
179 
180   /* Check the parameters */
181   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
182   assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank));
183   assert_param(IS_FMC_MUX(Init->DataAddressMux));
184   assert_param(IS_FMC_MEMORY(Init->MemoryType));
185   assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
186   assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode));
187   assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity));
188   assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
189   assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation));
190   assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal));
191   assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode));
192   assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait));
193   assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst));
194   assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock));
195   assert_param(IS_FMC_WRITE_FIFO(Init->WriteFifo));
196   assert_param(IS_FMC_PAGESIZE(Init->PageSize));
197   assert_param(IS_FMC_NBL_SETUPTIME(Init->NBLSetupTime));
198   assert_param(IS_FUNCTIONAL_STATE(Init->MaxChipSelectPulse));
199 
200   /* Disable NORSRAM Device */
201   __FMC_NORSRAM_DISABLE(Device, Init->NSBank);
202 
203   /* Set NORSRAM device control parameters */
204   if (Init->MemoryType == FMC_MEMORY_TYPE_NOR)
205   {
206     flashaccess = FMC_NORSRAM_FLASH_ACCESS_ENABLE;
207   }
208   else
209   {
210     flashaccess = FMC_NORSRAM_FLASH_ACCESS_DISABLE;
211   }
212 
213   btcr_reg = (flashaccess                   | \
214               Init->DataAddressMux          | \
215               Init->MemoryType              | \
216               Init->MemoryDataWidth         | \
217               Init->BurstAccessMode         | \
218               Init->WaitSignalPolarity      | \
219               Init->WaitSignalActive        | \
220               Init->WriteOperation          | \
221               Init->WaitSignal              | \
222               Init->ExtendedMode            | \
223               Init->AsynchronousWait        | \
224               Init->WriteBurst);
225 
226   btcr_reg |= Init->ContinuousClock;
227   btcr_reg |= Init->WriteFifo;
228   btcr_reg |= Init->NBLSetupTime;
229   btcr_reg |= Init->PageSize;
230 
231   mask = (FMC_BCRx_MBKEN                |
232           FMC_BCRx_MUXEN                |
233           FMC_BCRx_MTYP                 |
234           FMC_BCRx_MWID                 |
235           FMC_BCRx_FACCEN               |
236           FMC_BCRx_BURSTEN              |
237           FMC_BCRx_WAITPOL              |
238           FMC_BCRx_WAITCFG              |
239           FMC_BCRx_WREN                 |
240           FMC_BCRx_WAITEN               |
241           FMC_BCRx_EXTMOD               |
242           FMC_BCRx_ASYNCWAIT            |
243           FMC_BCRx_CBURSTRW);
244 
245   mask |= FMC_BCR1_CCLKEN;
246   mask |= FMC_BCR1_WFDIS;
247   mask |= FMC_BCRx_NBLSET;
248   mask |= FMC_BCRx_CPSIZE;
249 
250   MODIFY_REG(Device->BTCR[Init->NSBank], mask, btcr_reg);
251 
252   /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
253   if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1))
254   {
255     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN, Init->ContinuousClock);
256   }
257 
258   if (Init->NSBank != FMC_NORSRAM_BANK1)
259   {
260     /* Configure Write FIFO mode when Write Fifo is enabled for bank2..4 */
261     SET_BIT(Device->BTCR[FMC_NORSRAM_BANK1], (uint32_t)(Init->WriteFifo));
262   }
263 
264   /* Check PSRAM chip select counter state */
265   if (Init->MaxChipSelectPulse == ENABLE)
266   {
267     /* Check the parameters */
268     assert_param(IS_FMC_MAX_CHIP_SELECT_PULSE_TIME(Init->MaxChipSelectPulseTime));
269 
270     /* Configure PSRAM chip select counter value */
271     MODIFY_REG(Device->PCSCNTR, FMC_PCSCNTR_CSCOUNT, (uint32_t)(Init->MaxChipSelectPulseTime));
272 
273     /* Enable PSRAM chip select counter for the bank */
274     switch (Init->NSBank)
275     {
276       case FMC_NORSRAM_BANK1 :
277         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN);
278         break;
279 
280       case FMC_NORSRAM_BANK2 :
281         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN);
282         break;
283 
284       case FMC_NORSRAM_BANK3 :
285         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN);
286         break;
287 
288       default :
289         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN);
290         break;
291     }
292   }
293 
294   return HAL_OK;
295 }
296 
297 /**
298   * @brief  DeInitialize the FMC_NORSRAM peripheral
299   * @param  Device Pointer to NORSRAM device instance
300   * @param  ExDevice Pointer to NORSRAM extended mode device instance
301   * @param  Bank NORSRAM bank number
302   * @retval HAL status
303   */
FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_EXTENDED_TypeDef * ExDevice,uint32_t Bank)304 HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device,
305                                      FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
306 {
307   /* Check the parameters */
308   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
309   assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
310   assert_param(IS_FMC_NORSRAM_BANK(Bank));
311 
312   /* Disable the FMC_NORSRAM device */
313   __FMC_NORSRAM_DISABLE(Device, Bank);
314 
315   /* De-initialize the FMC_NORSRAM device */
316   /* FMC_NORSRAM_BANK1 */
317   if (Bank == FMC_NORSRAM_BANK1)
318   {
319     Device->BTCR[Bank] = 0x000030DBU;
320   }
321   /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */
322   else
323   {
324     Device->BTCR[Bank] = 0x000030D2U;
325   }
326 
327   Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
328   ExDevice->BWTR[Bank]   = 0x0FFFFFFFU;
329 
330   /* De-initialize PSRAM chip select counter */
331   switch (Bank)
332   {
333     case FMC_NORSRAM_BANK1 :
334       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN);
335       break;
336 
337     case FMC_NORSRAM_BANK2 :
338       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN);
339       break;
340 
341     case FMC_NORSRAM_BANK3 :
342       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN);
343       break;
344 
345     default :
346       CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN);
347       break;
348   }
349 
350   return HAL_OK;
351 }
352 
353 /**
354   * @brief  Initialize the FMC_NORSRAM Timing according to the specified
355   *         parameters in the FMC_NORSRAM_TimingTypeDef
356   * @param  Device Pointer to NORSRAM device instance
357   * @param  Timing Pointer to NORSRAM Timing structure
358   * @param  Bank NORSRAM bank number
359   * @retval HAL status
360   */
FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank)361 HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device,
362                                           FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
363 {
364   uint32_t tmpr;
365 
366   /* Check the parameters */
367   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
368   assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
369   assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
370   assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime));
371   assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
372   assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
373   assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision));
374   assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency));
375   assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
376   assert_param(IS_FMC_NORSRAM_BANK(Bank));
377 
378   /* Set FMC_NORSRAM device timing parameters */
379   Device->BTCR[Bank + 1U] =
380     (Timing->AddressSetupTime << FMC_BTRx_ADDSET_Pos) |
381     (Timing->AddressHoldTime << FMC_BTRx_ADDHLD_Pos) |
382     (Timing->DataSetupTime << FMC_BTRx_DATAST_Pos) |
383     (Timing->DataHoldTime << FMC_BTRx_DATAHLD_Pos) |
384     (Timing->BusTurnAroundDuration << FMC_BTRx_BUSTURN_Pos) |
385     ((Timing->CLKDivision - 1U) << FMC_BTRx_CLKDIV_Pos) |
386     ((Timing->DataLatency - 2U) << FMC_BTRx_DATLAT_Pos) |
387     Timing->AccessMode;
388 
389   /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
390   if (HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN))
391   {
392     tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~((0x0FU) << FMC_BTRx_CLKDIV_Pos));
393     tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FMC_BTRx_CLKDIV_Pos);
394     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1 + 1U], FMC_BTRx_CLKDIV, tmpr);
395   }
396 
397   return HAL_OK;
398 }
399 
400 /**
401   * @brief  Initialize the FMC_NORSRAM Extended mode Timing according to the specified
402   *         parameters in the FMC_NORSRAM_TimingTypeDef
403   * @param  Device Pointer to NORSRAM device instance
404   * @param  Timing Pointer to NORSRAM Timing structure
405   * @param  Bank NORSRAM bank number
406   * @param  ExtendedMode FMC Extended Mode
407   *          This parameter can be one of the following values:
408   *            @arg FMC_EXTENDED_MODE_DISABLE
409   *            @arg FMC_EXTENDED_MODE_ENABLE
410   * @retval HAL status
411   */
FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank,uint32_t ExtendedMode)412 HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device,
413                                                    FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank,
414                                                    uint32_t ExtendedMode)
415 {
416   /* Check the parameters */
417   assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode));
418 
419   /* Set NORSRAM device timing register for write configuration, if extended mode is used */
420   if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE)
421   {
422     /* Check the parameters */
423     assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device));
424     assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
425     assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
426     assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
427     assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime));
428     assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
429     assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
430     assert_param(IS_FMC_NORSRAM_BANK(Bank));
431 
432     /* Set NORSRAM device timing register for write configuration, if extended mode is used */
433     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
434                                                      ((Timing->AddressHoldTime)        << FMC_BWTRx_ADDHLD_Pos)  |
435                                                      ((Timing->DataSetupTime)          << FMC_BWTRx_DATAST_Pos)  |
436                                                      ((Timing->DataHoldTime)           << FMC_BWTRx_DATAHLD_Pos) |
437                                                      Timing->AccessMode                                          |
438                                                      ((Timing->BusTurnAroundDuration)  << FMC_BWTRx_BUSTURN_Pos)));
439   }
440   else
441   {
442     Device->BWTR[Bank] = 0x0FFFFFFFU;
443   }
444 
445   return HAL_OK;
446 }
447 /**
448   * @}
449   */
450 
451 /** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2
452   *  @brief   management functions
453   *
454 @verbatim
455   ==============================================================================
456                       ##### FMC_NORSRAM Control functions #####
457   ==============================================================================
458   [..]
459     This subsection provides a set of functions allowing to control dynamically
460     the FMC NORSRAM interface.
461 
462 @endverbatim
463   * @{
464   */
465 
466 /**
467   * @brief  Enables dynamically FMC_NORSRAM write operation.
468   * @param  Device Pointer to NORSRAM device instance
469   * @param  Bank NORSRAM bank number
470   * @retval HAL status
471   */
FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)472 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
473 {
474   /* Check the parameters */
475   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
476   assert_param(IS_FMC_NORSRAM_BANK(Bank));
477 
478   /* Enable write operation */
479   SET_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
480 
481   return HAL_OK;
482 }
483 
484 /**
485   * @brief  Disables dynamically FMC_NORSRAM write operation.
486   * @param  Device Pointer to NORSRAM device instance
487   * @param  Bank NORSRAM bank number
488   * @retval HAL status
489   */
FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)490 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
491 {
492   /* Check the parameters */
493   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
494   assert_param(IS_FMC_NORSRAM_BANK(Bank));
495 
496   /* Disable write operation */
497   CLEAR_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
498 
499   return HAL_OK;
500 }
501 
502 /**
503   * @}
504   */
505 
506 /**
507   * @}
508   */
509 
510 
511 /** @defgroup FMC_LL_Exported_Functions_NAND FMC Low Layer NAND Exported Functions
512   * @brief    NAND Controller functions
513   *
514   @verbatim
515   ==============================================================================
516                     ##### How to use NAND device driver #####
517   ==============================================================================
518   [..]
519     This driver contains a set of APIs to interface with the FMC NAND banks in order
520     to run the NAND external devices.
521 
522     (+) FMC NAND bank reset using the function FMC_NAND_DeInit()
523     (+) FMC NAND bank control configuration using the function FMC_NAND_Init()
524     (+) FMC NAND bank common space timing configuration using the function
525         FMC_NAND_CommonSpace_Timing_Init()
526     (+) FMC NAND bank attribute space timing configuration using the function
527         FMC_NAND_AttributeSpace_Timing_Init()
528     (+) FMC NAND bank enable/disable ECC correction feature using the functions
529         FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable()
530     (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC()
531 
532 @endverbatim
533   * @{
534   */
535 
536 /** @defgroup FMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions
537   *  @brief    Initialization and Configuration functions
538   *
539 @verbatim
540   ==============================================================================
541               ##### Initialization and de_initialization functions #####
542   ==============================================================================
543   [..]
544     This section provides functions allowing to:
545     (+) Initialize and configure the FMC NAND interface
546     (+) De-initialize the FMC NAND interface
547     (+) Configure the FMC clock and associated GPIOs
548 
549 @endverbatim
550   * @{
551   */
552 
553 /**
554   * @brief  Initializes the FMC_NAND device according to the specified
555   *         control parameters in the FMC_NAND_HandleTypeDef
556   * @param  Device Pointer to NAND device instance
557   * @param  Init Pointer to NAND Initialization structure
558   * @retval HAL status
559   */
FMC_NAND_Init(FMC_NAND_TypeDef * Device,FMC_NAND_InitTypeDef * Init)560 HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init)
561 {
562   /* Check the parameters */
563   assert_param(IS_FMC_NAND_DEVICE(Device));
564   assert_param(IS_FMC_NAND_BANK(Init->NandBank));
565   assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature));
566   assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth));
567   assert_param(IS_FMC_ECC_STATE(Init->EccComputation));
568   assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize));
569   assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime));
570   assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime));
571 
572   /* NAND bank 3 registers configuration */
573   MODIFY_REG(Device->PCR, PCR_CLEAR_MASK, (Init->Waitfeature                            |
574                                            FMC_PCR_MEMORY_TYPE_NAND                     |
575                                            Init->MemoryDataWidth                        |
576                                            Init->EccComputation                         |
577                                            Init->ECCPageSize                            |
578                                            ((Init->TCLRSetupTime) << FMC_PCR_TCLR_Pos)  |
579                                            ((Init->TARSetupTime)  << FMC_PCR_TAR_Pos)));
580 
581   return HAL_OK;
582 }
583 
584 /**
585   * @brief  Initializes the FMC_NAND Common space Timing according to the specified
586   *         parameters in the FMC_NAND_PCC_TimingTypeDef
587   * @param  Device Pointer to NAND device instance
588   * @param  Timing Pointer to NAND timing structure
589   * @param  Bank NAND bank number
590   * @retval HAL status
591   */
FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)592 HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device,
593                                                    FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
594 {
595   /* Check the parameters */
596   assert_param(IS_FMC_NAND_DEVICE(Device));
597   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
598   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
599   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
600   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
601   assert_param(IS_FMC_NAND_BANK(Bank));
602 
603   /* Prevent unused argument(s) compilation warning if no assert_param check */
604   UNUSED(Bank);
605 
606   /* NAND bank 3 registers configuration */
607   Device->PMEM =(Timing->SetupTime  |
608     ((Timing->WaitSetupTime) << FMC_PMEM_MEMWAIT_Pos) |
609     ((Timing->HoldSetupTime )<< FMC_PMEM_MEMHOLD_Pos) |
610     ((Timing->HiZSetupTime) << FMC_PMEM_MEMHIZ_Pos));
611 
612   return HAL_OK;
613 }
614 
615 /**
616   * @brief  Initializes the FMC_NAND Attribute space Timing according to the specified
617   *         parameters in the FMC_NAND_PCC_TimingTypeDef
618   * @param  Device Pointer to NAND device instance
619   * @param  Timing Pointer to NAND timing structure
620   * @param  Bank NAND bank number
621   * @retval HAL status
622   */
FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef * Device,FMC_NAND_PCC_TimingTypeDef * Timing,uint32_t Bank)623 HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device,
624                                                       FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank)
625 {
626   /* Check the parameters */
627   assert_param(IS_FMC_NAND_DEVICE(Device));
628   assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime));
629   assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime));
630   assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime));
631   assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime));
632   assert_param(IS_FMC_NAND_BANK(Bank));
633 
634   /* Prevent unused argument(s) compilation warning if no assert_param check */
635   UNUSED(Bank);
636 
637   /* NAND bank 3 registers configuration */
638   Device->PATT =(Timing->SetupTime |
639       ((Timing->WaitSetupTime) << FMC_PATT_ATTWAIT_Pos) |
640       ((Timing->HoldSetupTime) << FMC_PATT_ATTHOLD_Pos) |
641       ((Timing->HiZSetupTime)  << FMC_PATT_ATTHIZ_Pos));
642 
643   return HAL_OK;
644 }
645 
646 /**
647   * @brief  DeInitializes the FMC_NAND device
648   * @param  Device Pointer to NAND device instance
649   * @param  Bank NAND bank number
650   * @retval HAL status
651   */
FMC_NAND_DeInit(FMC_NAND_TypeDef * Device,uint32_t Bank)652 HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank)
653 {
654   /* Check the parameters */
655   assert_param(IS_FMC_NAND_DEVICE(Device));
656   assert_param(IS_FMC_NAND_BANK(Bank));
657 
658   /* Disable the NAND Bank */
659   __FMC_NAND_DISABLE(Device, Bank);
660 
661   /* De-initialize the NAND Bank */
662   /* Prevent unused argument(s) compilation warning if no assert_param check */
663   UNUSED(Bank);
664 
665   /* Set the FMC_NAND_BANK3 registers to their reset values */
666   WRITE_REG(Device->PCR,  0x00000018U);
667   WRITE_REG(Device->SR,   0x00000040U);
668   WRITE_REG(Device->PMEM, 0xFCFCFCFCU);
669   WRITE_REG(Device->PATT, 0xFCFCFCFCU);
670 
671   return HAL_OK;
672 }
673 
674 /**
675   * @}
676   */
677 
678 /** @defgroup HAL_FMC_NAND_Group2 Peripheral Control functions
679   *  @brief   management functions
680   *
681 @verbatim
682   ==============================================================================
683                        ##### FMC_NAND Control functions #####
684   ==============================================================================
685   [..]
686     This subsection provides a set of functions allowing to control dynamically
687     the FMC NAND interface.
688 
689 @endverbatim
690   * @{
691   */
692 
693 
694 /**
695   * @brief  Enables dynamically FMC_NAND ECC feature.
696   * @param  Device Pointer to NAND device instance
697   * @param  Bank NAND bank number
698   * @retval HAL status
699   */
FMC_NAND_ECC_Enable(FMC_NAND_TypeDef * Device,uint32_t Bank)700 HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank)
701 {
702   /* Check the parameters */
703   assert_param(IS_FMC_NAND_DEVICE(Device));
704   assert_param(IS_FMC_NAND_BANK(Bank));
705 
706   /* Enable ECC feature */
707   /* Prevent unused argument(s) compilation warning if no assert_param check */
708   UNUSED(Bank);
709 
710   SET_BIT(Device->PCR, FMC_PCR_ECCEN);
711 
712   return HAL_OK;
713 }
714 
715 
716 /**
717   * @brief  Disables dynamically FMC_NAND ECC feature.
718   * @param  Device Pointer to NAND device instance
719   * @param  Bank NAND bank number
720   * @retval HAL status
721   */
FMC_NAND_ECC_Disable(FMC_NAND_TypeDef * Device,uint32_t Bank)722 HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank)
723 {
724   /* Check the parameters */
725   assert_param(IS_FMC_NAND_DEVICE(Device));
726   assert_param(IS_FMC_NAND_BANK(Bank));
727 
728   /* Disable ECC feature */
729   /* Prevent unused argument(s) compilation warning if no assert_param check */
730   UNUSED(Bank);
731 
732   CLEAR_BIT(Device->PCR, FMC_PCR_ECCEN);
733 
734   return HAL_OK;
735 }
736 
737 /**
738   * @brief  Disables dynamically FMC_NAND ECC feature.
739   * @param  Device Pointer to NAND device instance
740   * @param  ECCval Pointer to ECC value
741   * @param  Bank NAND bank number
742   * @param  Timeout Timeout wait value
743   * @retval HAL status
744   */
FMC_NAND_GetECC(FMC_NAND_TypeDef * Device,uint32_t * ECCval,uint32_t Bank,uint32_t Timeout)745 HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank,
746                                   uint32_t Timeout)
747 {
748   uint32_t tickstart;
749 
750   /* Check the parameters */
751   assert_param(IS_FMC_NAND_DEVICE(Device));
752   assert_param(IS_FMC_NAND_BANK(Bank));
753 
754   /* Get tick */
755   tickstart = HAL_GetTick();
756 
757   /* Wait until FIFO is empty */
758   while (__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET)
759   {
760     /* Check for the Timeout */
761     if (Timeout != HAL_MAX_DELAY)
762     {
763       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
764       {
765         return HAL_TIMEOUT;
766       }
767     }
768   }
769 
770   /* Prevent unused argument(s) compilation warning if no assert_param check */
771   UNUSED(Bank);
772 
773   /* Get the ECCR register value */
774   *ECCval = (uint32_t)Device->ECCR;
775 
776   return HAL_OK;
777 }
778 
779 /**
780   * @}
781   */
782 
783 
784 
785 /**
786   * @}
787   */
788 
789 /**
790   * @}
791   */
792 
793 #endif /* HAL_NOR_MODULE_ENABLED */
794 /**
795   * @}
796   */
797 /**
798   * @}
799   */
800