1 /**
2   ******************************************************************************
3   * @file    stm32mp1xx_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   @verbatim
14   ==============================================================================
15                         ##### FMC peripheral features #####
16   ==============================================================================
17   [..] The Flexible memory controller (FMC) includes following memory controllers:
18        (+) The NOR/PSRAM memory controller
19 
20   [..] The FMC functional block makes the interface with synchronous and asynchronous static
21        memories. Its main purposes are:
22        (+) to translate AHB transactions into the appropriate external device protocol
23        (+) to meet the access time requirements of the external memory devices
24 
25   [..] All external memories share the addresses, data and control signals with the controller.
26        Each external device is accessed by means of a unique Chip Select. The FMC performs
27        only one access at a time to an external device.
28        The main features of the FMC controller are the following:
29         (+) Interface with static-memory mapped devices including:
30            (++) Static random access memory (SRAM)
31            (++) Read-only memory (ROM)
32            (++) NOR Flash memory/OneNAND Flash memory
33            (++) PSRAM (4 memory banks)
34         (+) Independent Chip Select control for each memory bank
35         (+) Independent configuration for each memory bank
36 
37   @endverbatim
38   ******************************************************************************
39   * @attention
40   *
41   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
42   * All rights reserved.</center></h2>
43   *
44   * This software component is licensed by ST under BSD 3-Clause license,
45   * the "License"; You may not use this file except in compliance with the
46   * License. You may obtain a copy of the License at:
47   *                       opensource.org/licenses/BSD-3-Clause
48   *
49   ******************************************************************************
50   */
51 
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32mp1xx_hal.h"
54 
55 /** @addtogroup STM32MP1xx_HAL_Driver
56   * @{
57   */
58 #if defined HAL_NOR_MODULE_ENABLED || defined HAL_SRAM_MODULE_ENABLED
59 
60 /** @defgroup FMC_LL  FMC Low Layer
61   * @brief FMC driver modules
62   * @{
63   */
64 
65 /* Private typedef -----------------------------------------------------------*/
66 /* Private define ------------------------------------------------------------*/
67 
68 /** @defgroup FMC_LL_Private_Constants FMC Low Layer Private Constants
69   * @{
70   */
71 
72 /* ----------------------- FMC registers bit mask --------------------------- */
73 
74 /* --- BCR Register ---*/
75 /* BCR register clear mask */
76 
77 /* --- BTR Register ---*/
78 /* BTR register clear mask */
79 #define BTR_CLEAR_MASK    ((uint32_t)(FMC_BTR1_ADDSET | FMC_BTR1_ADDHLD  |\
80                                       FMC_BTR1_DATAST | FMC_BTR1_BUSTURN |\
81                                       FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT  |\
82                                       FMC_BTR1_ACCMOD | FMC_BTR1_DATAHLD))
83 
84 /* --- BWTR Register ---*/
85 /* BWTR register clear mask */
86 #if defined(FMC_BWTR1_BUSTURN)
87 #define BWTR_CLEAR_MASK   ((uint32_t)(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD  |\
88                                       FMC_BWTR1_DATAST | FMC_BWTR1_BUSTURN |\
89                                       FMC_BWTR1_ACCMOD | FMC_BWTR1_DATAHLD))
90 #else
91 #define BWTR_CLEAR_MASK   ((uint32_t)(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD  |\
92                                       FMC_BWTR1_DATAST | FMC_BWTR1_ACCMOD  |\
93                                       FMC_BWTR1_DATAHLD))
94 #endif /* FMC_BWTR1_BUSTURN */
95 
96 /**
97   * @}
98   */
99 
100 /* Private macro -------------------------------------------------------------*/
101 /* Private variables ---------------------------------------------------------*/
102 /* Private function prototypes -----------------------------------------------*/
103 /* Exported functions --------------------------------------------------------*/
104 
105 /** @defgroup FMC_LL_Exported_Functions FMC Low Layer Exported Functions
106   * @{
107   */
108 
109 
110 /** @defgroup FMC_LL_Exported_Functions_NORSRAM FMC Low Layer NOR SRAM Exported Functions
111   * @brief  NORSRAM Controller functions
112   *
113   @verbatim
114   ==============================================================================
115                    ##### How to use NORSRAM device driver #####
116   ==============================================================================
117 
118   [..]
119     This driver contains a set of APIs to interface with the FMC NORSRAM banks in order
120     to run the NORSRAM external devices.
121 
122     (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit()
123     (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init()
124     (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init()
125     (+) FMC NORSRAM bank extended timing configuration using the function
126         FMC_NORSRAM_Extended_Timing_Init()
127     (+) FMC NORSRAM bank enable/disable write operation using the functions
128         FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable()
129 
130 @endverbatim
131   * @{
132   */
133 
134 /** @defgroup FMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions
135   * @brief    Initialization and Configuration functions
136   *
137   @verbatim
138   ==============================================================================
139               ##### Initialization and de_initialization functions #####
140   ==============================================================================
141   [..]
142     This section provides functions allowing to:
143     (+) Initialize and configure the FMC NORSRAM interface
144     (+) De-initialize the FMC NORSRAM interface
145     (+) Configure the FMC clock and associated GPIOs
146 
147 @endverbatim
148   * @{
149   */
150 
151 /**
152   * @brief  Initialize the FMC_NORSRAM device according to the specified
153   *         control parameters in the FMC_NORSRAM_InitTypeDef
154   * @param  Device Pointer to NORSRAM device instance
155   * @param  Init Pointer to NORSRAM Initialization structure
156   * @retval HAL status
157   */
FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_InitTypeDef * Init)158 HAL_StatusTypeDef  FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef *Init)
159 {
160   uint32_t flashaccess;
161 
162   /* Check the parameters */
163   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
164   assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank));
165   assert_param(IS_FMC_MUX(Init->DataAddressMux));
166   assert_param(IS_FMC_MEMORY(Init->MemoryType));
167   assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth));
168   assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode));
169   assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity));
170   assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive));
171   assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation));
172   assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal));
173   assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode));
174   assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait));
175   assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst));
176   assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock));
177   assert_param(IS_FMC_PAGESIZE(Init->PageSize));
178   assert_param(IS_FMC_NBL_SETUPTIME(Init->NBLSetupTime));
179   assert_param(IS_FUNCTIONAL_STATE(Init->MaxChipSelectPulse));
180 
181   /* Disable NORSRAM Device */
182   __FMC_NORSRAM_DISABLE(Device, Init->NSBank);
183 
184   /* Set NORSRAM device control parameters */
185   if (Init->MemoryType == FMC_MEMORY_TYPE_NOR)
186   {
187     flashaccess = FMC_NORSRAM_FLASH_ACCESS_ENABLE;
188   }
189   else
190   {
191     flashaccess = FMC_NORSRAM_FLASH_ACCESS_DISABLE;
192   }
193 
194   MODIFY_REG(Device->BTCR[Init->NSBank],
195              (FMC_BCR1_MBKEN                |
196               FMC_BCR1_MUXEN                |
197               FMC_BCR1_MTYP                 |
198               FMC_BCR1_MWID                 |
199               FMC_BCR1_FACCEN               |
200               FMC_BCR1_BURSTEN              |
201               FMC_BCR1_WAITPOL              |
202               FMC_BCR1_WAITCFG              |
203               FMC_BCR1_WREN                 |
204               FMC_BCR1_WAITEN               |
205               FMC_BCR1_EXTMOD               |
206               FMC_BCR1_ASYNCWAIT            |
207               FMC_BCR1_CBURSTRW             |
208               FMC_BCR1_CCLKEN               |
209               FMC_BCR1_NBLSET               |
210               FMC_BCR1_CPSIZE),
211              (flashaccess                   |
212               Init->DataAddressMux          |
213               Init->MemoryType              |
214               Init->MemoryDataWidth         |
215               Init->BurstAccessMode         |
216               Init->WaitSignalPolarity      |
217               Init->WaitSignalActive        |
218               Init->WriteOperation          |
219               Init->WaitSignal              |
220               Init->ExtendedMode            |
221               Init->AsynchronousWait        |
222               Init->WriteBurst              |
223               Init->ContinuousClock         |
224               Init->NBLSetupTime            |
225               Init->PageSize));
226 
227   /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
228   if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1))
229   {
230     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN, Init->ContinuousClock);
231   }
232 
233   /* Check PSRAM chip select counter state */
234   if(Init->MaxChipSelectPulse == ENABLE)
235   {
236     /* Check the parameters */
237     assert_param(IS_FMC_MAX_CHIP_SELECT_PULSE_TIME(Init->MaxChipSelectPulseTime));
238 
239     /* Configure PSRAM chip select counter value */
240     MODIFY_REG(Device->PCSCNTR, FMC_PCSCNTR_CSCOUNT, (uint32_t)(Init->MaxChipSelectPulseTime));
241 
242     /* Enable PSRAM chip select counter for the bank */
243     switch (Init->NSBank)
244     {
245       case FMC_NORSRAM_BANK1 :
246         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN);
247         break;
248 
249       case FMC_NORSRAM_BANK2 :
250         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN);
251         break;
252 
253       case FMC_NORSRAM_BANK3 :
254         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN);
255         break;
256 
257       case FMC_NORSRAM_BANK4 :
258         SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN);
259         break;
260 
261       default :
262         break;
263     }
264   }
265 
266   return HAL_OK;
267 }
268 
269 /**
270   * @brief  DeInitialize the FMC_NORSRAM peripheral
271   * @param  Device Pointer to NORSRAM device instance
272   * @param  ExDevice Pointer to NORSRAM extended mode device instance
273   * @param  Bank NORSRAM bank number
274   * @retval HAL status
275   */
FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_EXTENDED_TypeDef * ExDevice,uint32_t Bank)276 HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank)
277 {
278   /* Check the parameters */
279   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
280   assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice));
281   assert_param(IS_FMC_NORSRAM_BANK(Bank));
282 
283   /* Disable the FMC_NORSRAM device */
284   __FMC_NORSRAM_DISABLE(Device, Bank);
285 
286   /* De-initialize the FMC_NORSRAM device */
287   /* FMC_NORSRAM_BANK1 */
288   if (Bank == FMC_NORSRAM_BANK1)
289   {
290     Device->BTCR[Bank] = 0x000030DBU;
291   }
292   /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */
293   else
294   {
295     Device->BTCR[Bank] = 0x000030D2U;
296   }
297 
298   Device->BTCR[Bank + 1U] = 0x0FFFFFFFU;
299   ExDevice->BWTR[Bank]   = 0x000FFFFFU;
300 
301   /* De-initialize PSRAM chip select counter */
302     switch (Bank)
303     {
304       case FMC_NORSRAM_BANK1 :
305         CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN);
306         break;
307 
308       case FMC_NORSRAM_BANK2 :
309         CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN);
310         break;
311 
312       case FMC_NORSRAM_BANK3 :
313         CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN);
314         break;
315 
316       case FMC_NORSRAM_BANK4 :
317         CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN);
318         break;
319 
320       default :
321         break;
322     }
323 
324   return HAL_OK;
325 }
326 
327 /**
328   * @brief  Initialize the FMC_NORSRAM Timing according to the specified
329   *         parameters in the FMC_NORSRAM_TimingTypeDef
330   * @param  Device Pointer to NORSRAM device instance
331   * @param  Timing Pointer to NORSRAM Timing structure
332   * @param  Bank NORSRAM bank number
333   * @retval HAL status
334   */
FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank)335 HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank)
336 {
337   uint32_t tmpr;
338 
339   /* Check the parameters */
340   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
341   assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
342   assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
343   assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime));
344   assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
345   assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
346   assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision));
347   assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency));
348   assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
349   assert_param(IS_FMC_NORSRAM_BANK(Bank));
350 
351   /* Set FMC_NORSRAM device timing parameters */
352   MODIFY_REG(Device->BTCR[Bank + 1U], BTR_CLEAR_MASK, (Timing->AddressSetupTime                                  |
353                                                       ((Timing->AddressHoldTime)        << FMC_BTR1_ADDHLD_Pos)  |
354                                                       ((Timing->DataSetupTime)          << FMC_BTR1_DATAST_Pos)  |
355                                                       ((Timing->DataHoldTime)           << FMC_BTR1_DATAHLD_Pos) |
356                                                       ((Timing->BusTurnAroundDuration)  << FMC_BTR1_BUSTURN_Pos) |
357                                                       (((Timing->CLKDivision) - 1U)     << FMC_BTR1_CLKDIV_Pos)  |
358                                                       (((Timing->DataLatency) - 2U)     << FMC_BTR1_DATLAT_Pos)  |
359                                                       (Timing->AccessMode)));
360 
361   /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
362   if (HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN))
363   {
364     tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~(((uint32_t)0x0F) << FMC_BTR1_CLKDIV_Pos));
365     tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FMC_BTR1_CLKDIV_Pos);
366     MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1 + 1U], FMC_BTR1_CLKDIV, tmpr);
367   }
368 
369   return HAL_OK;
370 }
371 
372 /**
373   * @brief  Initialize the FMC_NORSRAM Extended mode Timing according to the specified
374   *         parameters in the FMC_NORSRAM_TimingTypeDef
375   * @param  Device Pointer to NORSRAM device instance
376   * @param  Timing Pointer to NORSRAM Timing structure
377   * @param  Bank NORSRAM bank number
378   * @param  ExtendedMode FMC Extended Mode
379   *          This parameter can be one of the following values:
380   *            @arg FMC_EXTENDED_MODE_DISABLE
381   *            @arg FMC_EXTENDED_MODE_ENABLE
382   * @retval HAL status
383   */
FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef * Device,FMC_NORSRAM_TimingTypeDef * Timing,uint32_t Bank,uint32_t ExtendedMode)384 HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode)
385 {
386   /* Check the parameters */
387   assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode));
388 
389   /* Set NORSRAM device timing register for write configuration, if extended mode is used */
390   if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE)
391   {
392     /* Check the parameters */
393     assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device));
394     assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime));
395     assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime));
396     assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime));
397     assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime));
398 #if defined(FMC_BWTR1_BUSTURN)
399     assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration));
400 #endif /* FMC_BWTR1_BUSTURN */
401     assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode));
402     assert_param(IS_FMC_NORSRAM_BANK(Bank));
403 
404     /* Set NORSRAM device timing register for write configuration, if extended mode is used */
405     MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime                                    |
406                                                      ((Timing->AddressHoldTime)        << FMC_BWTR1_ADDHLD_Pos)  |
407                                                      ((Timing->DataSetupTime)          << FMC_BWTR1_DATAST_Pos)  |
408                                                      ((Timing->DataHoldTime)           << FMC_BWTR1_DATAHLD_Pos) |
409 #if defined(FMC_BWTR1_BUSTURN)
410                                                      Timing->AccessMode                                          |
411                                                      ((Timing->BusTurnAroundDuration)  << FMC_BWTR1_BUSTURN_Pos)));
412 #else
413                                                      Timing->AccessMode));
414 #endif /* FMC_BWTR1_BUSTURN */
415   }
416   else
417   {
418     Device->BWTR[Bank] = 0x000FFFFFU;
419   }
420 
421   return HAL_OK;
422 }
423 /**
424   * @}
425   */
426 
427 /** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2
428  *  @brief   management functions
429  *
430 @verbatim
431   ==============================================================================
432                       ##### FMC_NORSRAM Control functions #####
433   ==============================================================================
434   [..]
435     This subsection provides a set of functions allowing to control dynamically
436     the FMC NORSRAM interface.
437 
438 @endverbatim
439   * @{
440   */
441 
442 /**
443   * @brief  Enables dynamically FMC_NORSRAM write operation.
444   * @param  Device Pointer to NORSRAM device instance
445   * @param  Bank NORSRAM bank number
446   * @retval HAL status
447   */
FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)448 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
449 {
450   /* Check the parameters */
451   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
452   assert_param(IS_FMC_NORSRAM_BANK(Bank));
453 
454   /* Enable write operation */
455   SET_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
456 
457   return HAL_OK;
458 }
459 
460 /**
461   * @brief  Disables dynamically FMC_NORSRAM write operation.
462   * @param  Device Pointer to NORSRAM device instance
463   * @param  Bank NORSRAM bank number
464   * @retval HAL status
465   */
FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef * Device,uint32_t Bank)466 HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank)
467 {
468   /* Check the parameters */
469   assert_param(IS_FMC_NORSRAM_DEVICE(Device));
470   assert_param(IS_FMC_NORSRAM_BANK(Bank));
471 
472   /* Disable write operation */
473   CLEAR_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE);
474 
475   return HAL_OK;
476 }
477 
478 /**
479   * @}
480   */
481 
482 /**
483   * @}
484   */
485 
486 
487 
488 
489 /**
490   * @}
491   */
492 
493 /**
494   * @}
495   */
496 
497 #endif /* HAL_NOR_MODULE_ENABLED */
498 /**
499   * @}
500   */
501 
502 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
503