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