1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_ramcfg.c
4   * @author  MCD Application Team
5   * @brief   RAMCFG HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the RAMs configuration controller peripheral:
8   *           + RAMCFG Initialization and De-initialization Functions.
9   *           + RAMCFG ECC Operation Functions.
10   *           + RAMCFG Configure Wait State Functions.
11   *           + RAMCFG Write Protection Functions.
12   *           + RAMCFG Erase Operation Functions.
13   *           + RAMCFG Handle Interrupt and Callbacks Functions.
14   *           + RAMCFG State and Error Functions.
15   ******************************************************************************
16   * @attention
17   *
18   * Copyright (c) 2021 STMicroelectronics.
19   * All rights reserved.
20   *
21   * This software is licensed under terms that can be found in the LICENSE file
22   * in the root directory of this software component.
23   * If no LICENSE file comes with this software, it is provided AS-IS.
24   *
25   ******************************************************************************
26   @verbatim
27   ==============================================================================
28                     ##### RAMCFG Peripheral features #####
29   ==============================================================================
30   [..]
31     (+) Each SRAM is managed by a RAMCFG instance.
32 
33     (+) Each SRAM can be erased independently through its RAMCFG instance.
34 
35     (+) The wait state value for each SRAM can be configured independently
36         through its RAMCFG instance.
37 
38     (+) SRAM2 is divided to 64 pages with 1 kB granularity. Each page can be
39         write protected independently through its RAMCFG instance.
40 
41     (+) SRAM2, SRAM3 and BKPRAM support ECC correction feature. This mechanism
42         adopts the Single Error Correction Double Error Detection (SECDED)
43         algorithm. This feature provides the following information:
44              (++) Single error address.
45              (++) Double error address.
46   ==============================================================================
47                         ##### How to use this driver #####
48   ==============================================================================
49   [..]
50     (#) Call HAL_RAMCFG_Init() to initialize the RAMCFG peripheral before using
51        any feature. Call HAL_RAMCFG_DeInit() to de-initialize the RAMCFG when
52        using this peripheral is no more needed or a hardware issue has occurred.
53           (+) HAL_RAMCFG_Init() and HAL_RAMCFG_DeInit() APIs do not change the
54               activation status of ECC feature. It is managed by
55               HAL_RAMCFG_StartECC(), HAL_RAMCFG_StopECC() or option bytes (When
56               available on the device).
57 
58      *** ECC feature ***
59      ===================
60     [..]
61           (+) Call HAL_RAMCFG_StartECC() and HAL_RAMCFG_StopECC() to enable and
62               disable ECC hardware mechanism.
63                     (++) When ECC feature is previously enabled (case of option
64                          byte activation), calling HAL_RAMCFG_StartECC() is
65                          recommended to enable the ECC address latching feature.
66 
67           (+) Call HAL_RAMCFG_EnableNotification() and HAL_RAMCFG_DisableNotification()
68               to enable and disable ECC interrupts. Interrupts can be:
69                     (++) Single error interrupt.
70                     (++) Double error interrupt.
71                     (++) Double error interrupt redirected to Non maskable
72                           interrupt (NMI).
73 
74           (+) Call HAL_RAMCFG_GetSingleErrorAddress() to get the address of the
75               last fail RAM word detected (only for single error) and
76               call HAL_RAMCFG_GetDoubleErrorAddress() to get the address of the
77               last fail RAM word detected (only for double error).
78 
79           (+) Call HAL_RAMCFG_IsECCErrorDetected() to check if an ECC single/double
80               error was detected. This API is used in silent mode (No ECC interrupt
81               is enabled).
82 
83      *** Wait State feature ***
84      ==========================
85     [..]
86           (+) Call HAL_RAMCFG_ConfigWaitState() to configure the wait state value
87               for a given SRAM according to the HCLK frequency and voltage range
88               scaling.
89 
90           (+) Call HAL_RAMCFG_GetWaitState() to get the current configured wait
91               state value.
92 
93      *** Write protection feature ***
94      ================================
95     [..]
96           (+) Call HAL_RAMCFG_EnableWriteProtection() to enable the write
97               protection for the given SRAM2 page(s).
98 
99           (+) There is no API to disable write protection as this feature can
100               be disabled only by a global peripheral reset or system reset.
101 
102           (+) Any write access to a write protected area of SRAM2 causes a
103               HardFault interrupt.
104 
105      *** Erase feature ***
106      =====================
107     [..]
108           (+) Call HAL_RAMCFG_Erase() to launch a hardware erase for the given
109               SRAM.
110 
111           (+) The erase value is equal to 0 when launching erase hardware through
112               RAMCFG.
113 
114           (+) SRAM2 write protected pages are erased when performing an erase
115               through RAMCFG.
116 
117      *** RAMCFG HAL driver macros list ***
118      =====================================
119      [..]
120        Below the list of used macros in RAMCFG HAL driver.
121 
122       (+) __HAL_RAMCFG_ENABLE_IT     : Enable the specified RAMCFG interrupts.
123       (+) __HAL_RAMCFG_DISABLE_IT    : Disable the specified RAMCFG interrupts.
124       (+) __HAL_RAMCFG_GET_FLAG      : Get the RAMCFG pending flags.
125       (+) __HAL_RAMCFG_CLEAR_FLAG    : Clear the RAMCFG pending flags.
126       (+) __HAL_RAMCFG_GET_IT_SOURCE : Check whether the specified RAMCFG
127                                        interrupt source is enabled or not.
128   @endverbatim
129   */
130 
131 /* Includes ------------------------------------------------------------------*/
132 #include "stm32u5xx_hal.h"
133 
134 /** @addtogroup STM32U5xx_HAL_Driver
135   * @{
136   */
137 
138 /** @defgroup RAMCFG RAMCFG
139   * @brief RAMCFG HAL module driver
140   * @{
141   */
142 
143 #ifdef HAL_RAMCFG_MODULE_ENABLED
144 
145 /* Private types -------------------------------------------------------------*/
146 /* Private variables ---------------------------------------------------------*/
147 /* Private constants ---------------------------------------------------------*/
148 
149 /** @addtogroup RAMCFG_Private_Constants
150   * @{
151   */
152 #define RAMCFG_TIMEOUT_VALUE 50000U
153 /**
154   * @}
155   */
156 
157 /* Private macros ------------------------------------------------------------*/
158 /* Private functions ---------------------------------------------------------*/
159 /* Exported functions --------------------------------------------------------*/
160 
161 /** @addtogroup RAMCFG_Exported_Functions
162   * @{
163   */
164 
165 /** @addtogroup RAMCFG_Exported_Functions_Group1
166   *
167 @verbatim
168  ===============================================================================
169              ##### Initialization and de-initialization Functions  #####
170  ===============================================================================
171     [..]
172       This section provides functions allowing to initialize and de-initialize the
173       RAMCFG instance.
174     [..]
175       The HAL_RAMCFG_Init() function follows the RAMCFG instance configuration
176       procedures as described in the reference manual.
177       The HAL_RAMCFG_DeInit() function allows to deinitialize the RAMCFG instance.
178       HAL_RAMCFG_Init() and HAL_RAMCFG_DeInit() APIs do not change the activation
179       status of ECC feature. It is managed by HAL_RAMCFG_StartECC(),
180       HAL_RAMCFG_StopECC() or option bytes (When available on the device).
181 
182 @endverbatim
183   * @{
184   */
185 
186 /**
187   * @brief  Initialize the RAMCFG by clearing flags and disabling interrupts.
188   * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
189   *                   the configuration information for the specified RAMCFG
190   *                   instance.
191   * @retval HAL status.
192   */
HAL_RAMCFG_Init(RAMCFG_HandleTypeDef * hramcfg)193 HAL_StatusTypeDef HAL_RAMCFG_Init(RAMCFG_HandleTypeDef *hramcfg)
194 {
195   /* Check the RAMCFG peripheral handle */
196   if (hramcfg == NULL)
197   {
198     return HAL_ERROR;
199   }
200 
201   /* Check the parameters */
202   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
203 
204   /* Update RAMCFG peripheral state */
205   hramcfg->State = HAL_RAMCFG_STATE_BUSY;
206 
207 #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
208   /* Check if a valid MSP API was registered */
209   if (hramcfg->MspInitCallback == NULL)
210   {
211     /* Init the low level hardware */
212     hramcfg->MspInitCallback = HAL_RAMCFG_MspInit;
213   }
214 
215   /* Init the low level hardware */
216   hramcfg->MspInitCallback(hramcfg);
217 #else
218   HAL_RAMCFG_MspInit(hramcfg);
219 #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
220 
221   /* Disable the ECC Address latch */
222   hramcfg->Instance->CR &= ~(RAMCFG_CR_ALE);
223 
224   /* Disable all RAMCFG interrupts */
225   __HAL_RAMCFG_DISABLE_IT(hramcfg, RAMCFG_IT_ALL);
226 
227   /* Clear RAMCFG monitor flags */
228   __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAGS_ALL);
229 
230   /* Initialise the RAMCFG error code */
231   hramcfg->ErrorCode = HAL_RAMCFG_ERROR_NONE;
232 
233   /* Initialize the RAMCFG state */
234   hramcfg->State = HAL_RAMCFG_STATE_READY;
235 
236   return HAL_OK;
237 }
238 
239 /**
240   * @brief  DeInitialize the RAMCFG peripheral.
241   * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
242   *                   the configuration information for the specified RAMCFG
243   *                   instance.
244   * @retval HAL status.
245   */
HAL_RAMCFG_DeInit(RAMCFG_HandleTypeDef * hramcfg)246 HAL_StatusTypeDef HAL_RAMCFG_DeInit(RAMCFG_HandleTypeDef *hramcfg)
247 {
248   /* Check the RAMCFG peripheral handle */
249   if (hramcfg == NULL)
250   {
251     return HAL_ERROR;
252   }
253 
254   /* Check the parameters */
255   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
256 
257   /* Disable the ECC Address latch */
258   hramcfg->Instance->CR &= ~(RAMCFG_CR_ALE);
259 
260   /* Disable all RAMCFG interrupts */
261   __HAL_RAMCFG_DISABLE_IT(hramcfg, RAMCFG_IT_ALL);
262 
263   /* Clear RAMCFG monitor flags */
264   __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAGS_ALL);
265 
266 #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
267   /* Check if a valid MSP API was registered */
268   if (hramcfg->MspDeInitCallback != NULL)
269   {
270     /* Init the low level hardware */
271     hramcfg->MspDeInitCallback(hramcfg);
272   }
273 
274   /* Clean callbacks */
275   hramcfg->DetectSingleErrorCallback = NULL;
276   hramcfg->DetectDoubleErrorCallback = NULL;
277 #else
278   HAL_RAMCFG_MspDeInit(hramcfg);
279 #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
280 
281   /* Reset the RAMCFG error code */
282   hramcfg->ErrorCode = HAL_RAMCFG_ERROR_NONE;
283 
284   /* Reset the RAMCFG state */
285   hramcfg->State = HAL_RAMCFG_STATE_RESET;
286 
287   return HAL_OK;
288 }
289 
290 /**
291   * @brief Initialize the RAMCFG MSP.
292   * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
293   *                  the configuration information for the specified RAMCFG.
294   * @retval None.
295   */
HAL_RAMCFG_MspInit(RAMCFG_HandleTypeDef * hramcfg)296 __weak void HAL_RAMCFG_MspInit(RAMCFG_HandleTypeDef *hramcfg)
297 {
298   /* Prevent unused argument(s) compilation warning */
299   UNUSED(hramcfg);
300 
301   /* NOTE : This function should not be modified, when the callback is needed,
302             the HAL_RAMCFG_MspInit can be implemented in the user file      */
303 }
304 
305 /**
306   * @brief DeInitialize the RAMCFG MSP.
307   * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
308   *                  the configuration information for the specified RAMCFG.
309   * @retval None.
310   */
HAL_RAMCFG_MspDeInit(RAMCFG_HandleTypeDef * hramcfg)311 __weak void HAL_RAMCFG_MspDeInit(RAMCFG_HandleTypeDef *hramcfg)
312 {
313   /* Prevent unused argument(s) compilation warning */
314   UNUSED(hramcfg);
315 
316   /* NOTE : This function should not be modified, when the callback is needed,
317             the HAL_RAMCFG_MspDeInit can be implemented in the user file    */
318 }
319 /**
320   * @}
321   */
322 
323 /** @addtogroup RAMCFG_Exported_Functions_Group2
324   *
325 @verbatim
326  ===============================================================================
327                       ##### ECC Operations Functions  #####
328  ===============================================================================
329     [..]
330       This section provides functions allowing to manage ECC feature provided by
331       the RAMCFG peripheral.
332     [..]
333       The HAL_RAMCFG_StartECC() function allows starting the ECC mechanism and
334       enabling ECC address latching for the selected RAMCFG instance.
335       The HAL_RAMCFG_StopECC() function allows stopping the ECC mechanism and
336       disabling ECC address latching for the selected RAMCFG instance.
337       The HAL_RAMCFG_EnableNotification() function allows enabling interrupts
338       for single ECC error, double ECC error and NMI error.
339       The HAL_RAMCFG_DisableNotification() function allows disabling interrupts
340       for single ECC error, double ECC error. When NMI interrupt is enabled it
341       can only be disabled by a global peripheral reset or by a system reset.
342       The HAL_RAMCFG_IsECCErrorDetected() function allows to check if an ECC error
343       has occurred.
344       The HAL_RAMCFG_GetSingleErrorAddress() function allows to get the address of
345       the last single ECC error detected.
346       The HAL_RAMCFG_GetDoubleErrorAddress() function allows to get the address of
347       the last double ECC error detected.
348 
349 @endverbatim
350   * @{
351   */
352 
353 /**
354   * @brief  Start ECC mechanism for the given SRAM.
355   * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
356   *                   the configuration information for the specified RAMCFG
357   *                   instance.
358   * @retval HAL status.
359   */
HAL_RAMCFG_StartECC(RAMCFG_HandleTypeDef * hramcfg)360 HAL_StatusTypeDef HAL_RAMCFG_StartECC(RAMCFG_HandleTypeDef *hramcfg)
361 {
362   HAL_StatusTypeDef status = HAL_OK;
363   /* Check the parameters */
364   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
365 
366   /* Check RAMCFG state */
367   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
368   {
369     /* Update RAMCFG peripheral state */
370     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
371 
372     /* Check if ECC mechanism is non active */
373     if ((hramcfg->Instance->CR & RAMCFG_CR_ECCE) != RAMCFG_CR_ECCE)
374     {
375       /* Start the SRAM ECC mechanism and latching the error address */
376       hramcfg->Instance->CR |= (RAMCFG_CR_ECCE | RAMCFG_CR_ALE);
377     }
378     else
379     {
380       /* Start latching the error address */
381       hramcfg->Instance->CR |= RAMCFG_CR_ALE;
382     }
383 
384     /* Update the RAMCFG state */
385     hramcfg->State = HAL_RAMCFG_STATE_READY;
386   }
387   else
388   {
389     /* Update the RAMCFG error code and return error  */
390     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
391     status = HAL_ERROR;
392   }
393 
394   return status;
395 }
396 
397 /**
398   * @brief  Stop ECC mechanism for the given SRAM.
399   * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
400   *                   the configuration information for the specified RAMCFG
401   *                   instance.
402   * @retval HAL status.
403   */
HAL_RAMCFG_StopECC(RAMCFG_HandleTypeDef * hramcfg)404 HAL_StatusTypeDef HAL_RAMCFG_StopECC(RAMCFG_HandleTypeDef *hramcfg)
405 {
406   HAL_StatusTypeDef status = HAL_OK;
407   /* Check the parameters */
408   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
409 
410   /* Check RAMCFG state */
411   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
412   {
413     /* Update RAMCFG peripheral state */
414     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
415 
416     /* Check if ECC mechanism is active */
417     if ((hramcfg->Instance->CR & RAMCFG_CR_ECCE) == RAMCFG_CR_ECCE)
418     {
419       /* Unlock the SRAM ECC bit */
420       WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY1);
421       WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY2);
422 
423       /* Stop the SRAM ECC mechanism and latching the error address */
424       hramcfg->Instance->CR &= ~(RAMCFG_CR_ECCE | RAMCFG_CR_ALE);
425     }
426     /* Update the RAMCFG state */
427     hramcfg->State = HAL_RAMCFG_STATE_READY;
428   }
429   else
430   {
431     /* Update the RAMCFG error code and return error  */
432     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
433     status = HAL_ERROR;
434   }
435 
436   return status;
437 }
438 
439 /**
440   * @brief  Enable the RAMCFG error interrupts.
441   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
442   *                         contains the configuration information for the
443   *                         specified RAMCFG instance.
444   * @param  Notifications : Select the notification to be enabled.
445   *                         This parameter can be any value of @ref
446   *                         RAMCFG_Interrupt group.
447   * @retval HAL status.
448   */
HAL_RAMCFG_EnableNotification(RAMCFG_HandleTypeDef * hramcfg,uint32_t Notifications)449 HAL_StatusTypeDef HAL_RAMCFG_EnableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications)
450 {
451   HAL_StatusTypeDef status = HAL_OK;
452   /* Check the parameters */
453   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
454   assert_param(IS_RAMCFG_INTERRUPT(Notifications));
455 
456   /* Check RAMCFG state */
457   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
458   {
459     /* Update RAMCFG peripheral state */
460     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
461 
462     /* Enable RAMCFG interrupts */
463     __HAL_RAMCFG_ENABLE_IT(hramcfg, Notifications);
464 
465     /* Update the RAMCFG state */
466     hramcfg->State = HAL_RAMCFG_STATE_READY;
467 
468   }
469   else
470   {
471     /* Update the RAMCFG error code and return error */
472     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
473     status = HAL_ERROR;
474   }
475 
476   return status;
477 }
478 
479 /**
480   * @brief  Disable the RAMCFG error interrupts.
481   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
482   *                         contains the configuration information for the
483   *                         specified RAMCFG instance.
484   * @param  Notifications : Select the notification to be disabled.
485   *                         This parameter can be :
486   *                         RAMCFG_IT_SINGLEERR : Single Error Interrupt.
487   *                         RAMCFG_IT_DOUBLEERR : Double Error Interrupt.
488   * @retval HAL status.
489   */
HAL_RAMCFG_DisableNotification(RAMCFG_HandleTypeDef * hramcfg,uint32_t Notifications)490 HAL_StatusTypeDef HAL_RAMCFG_DisableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications)
491 {
492   HAL_StatusTypeDef status = HAL_OK;
493   /* Check the parameters */
494   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
495   assert_param(IS_RAMCFG_INTERRUPT(Notifications));
496 
497   /* Check RAMCFG state */
498   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
499   {
500     /* Update RAMCFG peripheral state */
501     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
502 
503     /* Disable RAMCFG interrupts */
504     __HAL_RAMCFG_DISABLE_IT(hramcfg, Notifications);
505 
506     /* Update the RAMCFG state */
507     hramcfg->State = HAL_RAMCFG_STATE_READY;
508   }
509   else
510   {
511     /* Update the RAMCFG error code and return error */
512     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
513     status = HAL_ERROR;
514   }
515 
516   return status;
517 }
518 
519 /**
520   * @brief  Check if an ECC single error has occurred.
521   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
522   *                         contains the configuration information for the
523   *                         specified RAMCFG instance.
524   * @retval State of bit (1 or 0).
525   */
HAL_RAMCFG_IsECCSingleErrorDetected(const RAMCFG_HandleTypeDef * hramcfg)526 uint32_t HAL_RAMCFG_IsECCSingleErrorDetected(const RAMCFG_HandleTypeDef *hramcfg)
527 {
528   /* Check the parameters */
529   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
530 
531   /* Return the state of SEDC flag */
532   return ((READ_BIT(hramcfg->Instance->ISR, RAMCFG_FLAG_SINGLEERR) == (RAMCFG_FLAG_SINGLEERR)) ? 1UL : 0UL);
533 }
534 
535 /**
536   * @brief  Check if an ECC double error was occurred.
537   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
538   *                         contains the configuration information for the
539   *                         specified RAMCFG instance.
540   * @retval State of bit (1 or 0).
541   */
HAL_RAMCFG_IsECCDoubleErrorDetected(const RAMCFG_HandleTypeDef * hramcfg)542 uint32_t HAL_RAMCFG_IsECCDoubleErrorDetected(const RAMCFG_HandleTypeDef *hramcfg)
543 {
544   /* Check the parameters */
545   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
546 
547   /* Return the state of DED flag */
548   return ((READ_BIT(hramcfg->Instance->ISR, RAMCFG_FLAG_DOUBLEERR) == (RAMCFG_FLAG_DOUBLEERR)) ? 1UL : 0UL);
549 }
550 
551 /**
552   * @brief  Get the RAMCFG single error address.
553   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
554   *                         contains the configuration information for the
555   *                         specified RAMCFG instance.
556   * @retval Single error address offset.
557   */
HAL_RAMCFG_GetSingleErrorAddress(const RAMCFG_HandleTypeDef * hramcfg)558 uint32_t HAL_RAMCFG_GetSingleErrorAddress(const RAMCFG_HandleTypeDef *hramcfg)
559 {
560   /* Check the parameters */
561   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
562 
563   return hramcfg->Instance->SEAR;
564 }
565 
566 /**
567   * @brief  Get the RAMCFG double error address.
568   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
569   *                         contains the configuration information for the
570   *                         specified RAMCFG instance.
571   * @retval Double error address offset.
572   */
HAL_RAMCFG_GetDoubleErrorAddress(const RAMCFG_HandleTypeDef * hramcfg)573 uint32_t HAL_RAMCFG_GetDoubleErrorAddress(const RAMCFG_HandleTypeDef *hramcfg)
574 {
575   /* Check the parameters */
576   assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance));
577 
578   return hramcfg->Instance->DEAR;
579 }
580 
581 /**
582   * @}
583   */
584 
585 /** @addtogroup RAMCFG_Exported_Functions_Group3
586   *
587 @verbatim
588  ===============================================================================
589                         ##### Wait State Functions  #####
590  ===============================================================================
591     [..]
592       This section provides functions allowing to get and configure the wait state
593       value.
594     [..]
595       The HAL_RAMCFG_ConfigWaitState() function allows configuring the wait state
596       value.
597       The HAL_RAMCFG_GetWaitState() function allows getting the current wait state
598       value.
599 
600 @endverbatim
601   * @{
602   */
603 
604 /**
605   * @brief  Configure the wait state value for the given SRAM.
606   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
607   *                         contains the configuration information for the
608   *                         specified RAMCFG instance.
609   * @param  WaitState     : Select the value of wait state to be configured.
610   * @retval HAL status.
611   */
HAL_RAMCFG_ConfigWaitState(RAMCFG_HandleTypeDef * hramcfg,uint32_t WaitState)612 HAL_StatusTypeDef HAL_RAMCFG_ConfigWaitState(RAMCFG_HandleTypeDef *hramcfg, uint32_t WaitState)
613 {
614   HAL_StatusTypeDef status = HAL_OK;
615   /* Check the parameters */
616   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
617   assert_param(IS_RAMCFG_WAITSTATE(WaitState));
618 
619   /* Check RAMCFG state */
620   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
621   {
622     /* Update RAMCFG peripheral state */
623     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
624 
625     /* Set the SRAM wait state */
626     hramcfg->Instance->CR = WaitState;
627 
628     /* Update RAMCFG peripheral state */
629     hramcfg->State = HAL_RAMCFG_STATE_READY;
630   }
631   else
632   {
633     /* Update the RAMCFG error code and return error */
634     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
635     status = HAL_ERROR;
636   }
637 
638   return status;
639 }
640 
641 /**
642   * @brief  Get the current wait state value for the given SRAM.
643   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
644   *                         contains the configuration information for the
645   *                         specified RAMCFG instance.
646   * @retval Wait state value.
647   */
HAL_RAMCFG_GetWaitState(const RAMCFG_HandleTypeDef * hramcfg)648 uint32_t HAL_RAMCFG_GetWaitState(const RAMCFG_HandleTypeDef *hramcfg)
649 {
650   /* Check the parameters */
651   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
652 
653   /* Return the configured wait state number */
654   return (hramcfg->Instance->CR & RAMCFG_CR_WSC);
655 }
656 
657 /**
658   * @}
659   */
660 
661 /** @addtogroup RAMCFG_Exported_Functions_Group4
662   *
663 @verbatim
664  ===============================================================================
665                       ##### Write Protection Functions  #####
666  ===============================================================================
667     [..]
668       This section provides functions to enable write protection feature for
669       the page(s) of SRAM2.
670     [..]
671       The HAL_RAMCFG_EnableWriteProtection() function allows the user to enable the write
672       protection for the page(s) of SRAM2.
673       Disabling SRAM2 page(s) protection is performed only by a global
674       peripheral reset or a by a system reset.
675 
676 @endverbatim
677   * @{
678   */
679 
680 /**
681   * @brief  Enable write protection for the given page(s).
682   *         Write protection feature can be disabled only by system reset.
683   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
684   *                         contains the configuration information for the
685   *                         specified RAMCFG instance.
686   * @param  StartPage     : Select the start page number.
687   * @param  NbPage        : Number of page to be protected.
688   * @retval HAL status.
689   */
HAL_RAMCFG_EnableWriteProtection(RAMCFG_HandleTypeDef * hramcfg,uint32_t StartPage,uint32_t NbPage)690 HAL_StatusTypeDef HAL_RAMCFG_EnableWriteProtection(RAMCFG_HandleTypeDef *hramcfg, uint32_t StartPage, uint32_t NbPage)
691 {
692   HAL_StatusTypeDef status = HAL_OK;
693   uint32_t page_mask_0 = 0U;
694   uint32_t page_mask_1 = 0U;
695 
696   /* Check the parameters */
697   assert_param(IS_RAMCFG_WP_INSTANCE(hramcfg->Instance));
698   assert_param(IS_RAMCFG_WRITEPROTECTION_PAGE(StartPage + NbPage));
699 
700   /* Check RAMCFG state */
701   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
702   {
703     /* Update RAMCFG peripheral state */
704     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
705 
706     /* Repeat for page number to be protected */
707     for (uint32_t count = 0U; count < NbPage; count++)
708     {
709       if ((StartPage + count) < 32U)
710       {
711         page_mask_0 |= (1UL << (StartPage + count));
712       }
713       else
714       {
715         page_mask_1 |= (1UL << ((StartPage + count) - 32U));
716       }
717     }
718 
719     /* Apply mask to protect pages */
720     SET_BIT(hramcfg->Instance->WPR1, page_mask_0);
721     SET_BIT(hramcfg->Instance->WPR2, page_mask_1);
722 
723     /* Update the RAMCFG state */
724     hramcfg->State = HAL_RAMCFG_STATE_READY;
725   }
726   else
727   {
728     /* Update the RAMCFG error code and return error  */
729     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
730     status = HAL_ERROR;
731   }
732 
733   return status;
734 }
735 
736 /**
737   * @}
738   */
739 
740 /** @addtogroup RAMCFG_Exported_Functions_Group5
741   *
742 @verbatim
743  ===============================================================================
744                       ##### Erase Operation Functions  #####
745  ===============================================================================
746     [..]
747       This section provides functions allowing a hardware erase for the given SRAM.
748     [..]
749       The HAL_RAMCFG_Erase() function allows a hardware mass erase for the given
750       SRAM. The erase value for all SRAMs is 0.
751 
752 @endverbatim
753   * @{
754   */
755 
756 /**
757   * @brief  Launch a Mass Erase for the given SRAM.
758   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
759   *                         contains the configuration information for the
760   *                         specified RAMCFG instance.
761 
762   * @retval HAL status.
763   */
HAL_RAMCFG_Erase(RAMCFG_HandleTypeDef * hramcfg)764 HAL_StatusTypeDef HAL_RAMCFG_Erase(RAMCFG_HandleTypeDef *hramcfg)
765 {
766   uint32_t tickstart = HAL_GetTick();
767 
768   /* Check the parameters */
769   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
770 
771   /* Check RAMCFG state */
772   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
773   {
774     /* Update RAMCFG peripheral state */
775     hramcfg->State = HAL_RAMCFG_STATE_BUSY;
776 
777     /* Unlock the RAMCFG erase bit */
778     WRITE_REG(hramcfg->Instance->ERKEYR, RAMCFG_ERASE_KEY1);
779     WRITE_REG(hramcfg->Instance->ERKEYR, RAMCFG_ERASE_KEY2);
780 
781     /* Start the SRAM erase operation */
782     hramcfg->Instance->CR |= RAMCFG_CR_SRAMER;
783 
784     /*
785        Wait for the SRAM hardware erase operation to complete by polling on
786        SRAMBUSY flag to be reset.
787     */
788     while (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_SRAMBUSY) != 0U)
789     {
790       if ((HAL_GetTick() - tickstart) > RAMCFG_TIMEOUT_VALUE)
791       {
792         /* Update the RAMCFG error code */
793         hramcfg->ErrorCode = HAL_RAMCFG_ERROR_TIMEOUT;
794 
795         /* Update the RAMCFG state and return error status */
796         hramcfg->State = HAL_RAMCFG_STATE_ERROR;
797         return HAL_ERROR;
798       }
799     }
800   }
801   else
802   {
803     /* Update the error code and return error status */
804     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY;
805     return HAL_ERROR;
806   }
807 
808   /* Update the RAMCFG state */
809   hramcfg->State = HAL_RAMCFG_STATE_READY;
810 
811   return HAL_OK;
812 }
813 
814 /**
815   * @}
816   */
817 
818 /** @addtogroup RAMCFG_Exported_Functions_Group6
819   *
820 @verbatim
821  ===============================================================================
822                ##### Handle Interrupt and Callbacks Functions  #####
823  ===============================================================================
824     [..]
825       This section provides functions to handle RAMCFG interrupts and
826       Register / UnRegister the different callbacks.
827     [..]
828       The HAL_RAMCFG_IRQHandler() function allows the user to handle the active RAMCFG
829       interrupt request.
830       The HAL_RAMCFG_RegisterCallback() function allows the user to register the selected
831       RAMCFG callbacks.
832       The HAL_RAMCFG_UnRegisterCallback() function allows the user to unregister the
833       selected RAMCFG callbacks.
834 @endverbatim
835   * @{
836   */
837 
838 /**
839   * @brief  Handles RAMCFG interrupt request.
840   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
841   *                         contains the configuration information for the
842   *                         specified RAMCFG instance.
843   * @retval None.
844   */
HAL_RAMCFG_IRQHandler(RAMCFG_HandleTypeDef * hramcfg)845 void HAL_RAMCFG_IRQHandler(RAMCFG_HandleTypeDef *hramcfg)
846 {
847   /* Single Error Interrupt Management ****************************************/
848   if (__HAL_RAMCFG_GET_IT_SOURCE(hramcfg, RAMCFG_IT_SINGLEERR) != 0U)
849   {
850     if (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_SINGLEERR) != 0U)
851     {
852       /* Clear active flags */
853       __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAG_SINGLEERR);
854 
855 #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
856       /* Check if a valid single error callback is registered */
857       if (hramcfg->DetectSingleErrorCallback != NULL)
858       {
859         /* Single error detection callback */
860         hramcfg->DetectSingleErrorCallback(hramcfg);
861       }
862 #else
863       HAL_RAMCFG_DetectSingleErrorCallback(hramcfg);
864 #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
865     }
866   }
867 
868   /* Double Error Interrupt Management ****************************************/
869   if (__HAL_RAMCFG_GET_IT_SOURCE(hramcfg, RAMCFG_IT_DOUBLEERR) != 0U)
870   {
871     if (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_DOUBLEERR) != 0U)
872     {
873       /* Clear active flags */
874       __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAG_DOUBLEERR);
875 
876 #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
877       /* Check if a valid double error callback is registered */
878       if (hramcfg->DetectDoubleErrorCallback != NULL)
879       {
880         /* Double error detection callback */
881         hramcfg->DetectDoubleErrorCallback(hramcfg);
882       }
883 #else
884       HAL_RAMCFG_DetectDoubleErrorCallback(hramcfg);
885 #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
886     }
887   }
888 }
889 
890 /**
891   * @brief  RAMCFG single error detection callback.
892   * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
893   *                   the configuration information for the specified RAMCFG.
894   * @retval None.
895   */
HAL_RAMCFG_DetectSingleErrorCallback(RAMCFG_HandleTypeDef * hramcfg)896 __weak void HAL_RAMCFG_DetectSingleErrorCallback(RAMCFG_HandleTypeDef *hramcfg)
897 {
898   /* Prevent unused argument(s) compilation warning */
899   UNUSED(hramcfg);
900 
901   /* NOTE : This function should not be modified, when the callback is needed,
902             the HAL_RAMCFG_DetectSingleErrorCallback can be implemented in
903             the user file.                                                    */
904 }
905 
906 /**
907   * @brief  RAMCFG double error detection callback.
908   * @param  hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains
909   *                   the configuration information for the specified RAMCFG.
910   * @retval None.
911   */
HAL_RAMCFG_DetectDoubleErrorCallback(RAMCFG_HandleTypeDef * hramcfg)912 __weak void HAL_RAMCFG_DetectDoubleErrorCallback(RAMCFG_HandleTypeDef *hramcfg)
913 {
914   /* Prevent unused argument(s) compilation warning */
915   UNUSED(hramcfg);
916 
917   /* NOTE : This function should not be modified, when the callback is needed,
918             the HAL_RAMCFG_DetectDoubleErrorCallback can be implemented in
919             the user file.                                                    */
920 }
921 
922 #if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1)
923 /**
924   * @brief  Register RAMCFG callbacks.
925   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
926   *                         contains the configuration information for the
927   *                         specified RAMCFG instance.
928   * @param  CallbackID    : User Callback identifier a HAL_RAMCFG_CallbackIDTypeDef
929   *                         ENUM as parameter.
930   * @param  pCallback     : Pointer to private callback function.
931   * @retval HAL status.
932   */
HAL_RAMCFG_RegisterCallback(RAMCFG_HandleTypeDef * hramcfg,HAL_RAMCFG_CallbackIDTypeDef CallbackID,void (* pCallback)(RAMCFG_HandleTypeDef * _hramcfg))933 HAL_StatusTypeDef HAL_RAMCFG_RegisterCallback(RAMCFG_HandleTypeDef *hramcfg,
934                                               HAL_RAMCFG_CallbackIDTypeDef CallbackID,
935                                               void (* pCallback)(RAMCFG_HandleTypeDef *_hramcfg))
936 {
937   HAL_StatusTypeDef status = HAL_OK;
938 
939   /* Check the parameters */
940   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
941 
942   if (pCallback == NULL)
943   {
944     /* Update the error code and return error */
945     hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
946     return HAL_ERROR;
947   }
948 
949   /* Check RAMCFG state */
950   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
951   {
952     switch (CallbackID)
953     {
954       case  HAL_RAMCFG_SE_DETECT_CB_ID:
955         /* Register single error callback */
956         hramcfg->DetectSingleErrorCallback = pCallback;
957         break;
958 
959       case  HAL_RAMCFG_DE_DETECT_CB_ID:
960         /* Register double error callback */
961         hramcfg->DetectDoubleErrorCallback = pCallback;
962         break;
963 
964       case HAL_RAMCFG_MSPINIT_CB_ID :
965         /* Register msp init callback */
966         hramcfg->MspInitCallback = pCallback;
967         break;
968 
969       case HAL_RAMCFG_MSPDEINIT_CB_ID :
970         /* Register msp de-init callback */
971         hramcfg->MspDeInitCallback = pCallback;
972         break;
973 
974       default:
975         /* Update the error code and return error */
976         hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
977         status = HAL_ERROR;
978         break;
979     }
980   }
981   else if (hramcfg->State == HAL_RAMCFG_STATE_RESET)
982   {
983     switch (CallbackID)
984     {
985       case HAL_RAMCFG_MSPINIT_CB_ID :
986         /* Register msp init callback */
987         hramcfg->MspInitCallback = pCallback;
988         break;
989 
990       case HAL_RAMCFG_MSPDEINIT_CB_ID :
991         /* Register msp de-init callback */
992         hramcfg->MspDeInitCallback = pCallback;
993         break;
994 
995       default :
996         /* Update the error code and return error */
997         hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
998         status =  HAL_ERROR;
999         break;
1000     }
1001   }
1002   else
1003   {
1004     /* Update the error code and return error  */
1005     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_INVALID_CALLBACK;
1006     status = HAL_ERROR;
1007   }
1008 
1009   return status;
1010 }
1011 
1012 /**
1013   * @brief  UnRegister RAMCFG callbacks.
1014   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
1015   *                         contains the configuration information for the
1016   *                         specified RAMCFG instance.
1017   * @param  CallbackID    : User Callback identifier a HAL_RAMCFG_CallbackIDTypeDef
1018   *                         ENUM as parameter.
1019   * @retval HAL status.
1020   */
HAL_RAMCFG_UnRegisterCallback(RAMCFG_HandleTypeDef * hramcfg,HAL_RAMCFG_CallbackIDTypeDef CallbackID)1021 HAL_StatusTypeDef HAL_RAMCFG_UnRegisterCallback(RAMCFG_HandleTypeDef *hramcfg, HAL_RAMCFG_CallbackIDTypeDef CallbackID)
1022 {
1023   HAL_StatusTypeDef status = HAL_OK;
1024 
1025   /* Check the parameters */
1026   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
1027 
1028   /* Check RAMCFG state */
1029   if (hramcfg->State == HAL_RAMCFG_STATE_READY)
1030   {
1031     switch (CallbackID)
1032     {
1033       case  HAL_RAMCFG_SE_DETECT_CB_ID:
1034         /* UnRegister single error callback */
1035         hramcfg->DetectSingleErrorCallback = NULL;
1036         break;
1037 
1038       case  HAL_RAMCFG_DE_DETECT_CB_ID:
1039         /* UnRegister double error callback */
1040         hramcfg->DetectDoubleErrorCallback = NULL;
1041         break;
1042 
1043       case HAL_RAMCFG_MSPINIT_CB_ID :
1044         /* UnRegister msp init callback */
1045         hramcfg->MspInitCallback = NULL;
1046         break;
1047 
1048       case HAL_RAMCFG_MSPDEINIT_CB_ID :
1049         /* UnRegister msp de-init callback */
1050         hramcfg->MspDeInitCallback = NULL;
1051         break;
1052 
1053       case  HAL_RAMCFG_ALL_CB_ID:
1054         /* UnRegister all available callbacks */
1055         hramcfg->DetectSingleErrorCallback = NULL;
1056         hramcfg->DetectDoubleErrorCallback = NULL;
1057         hramcfg->MspDeInitCallback         = NULL;
1058         hramcfg->MspInitCallback           = NULL;
1059         break;
1060 
1061       default:
1062         /* Return error status */
1063         status = HAL_ERROR;
1064         break;
1065     }
1066   }
1067   else if (hramcfg->State == HAL_RAMCFG_STATE_RESET)
1068   {
1069     switch (CallbackID)
1070     {
1071       case HAL_RAMCFG_MSPINIT_CB_ID :
1072         /* UnRegister msp init callback */
1073         hramcfg->MspInitCallback = NULL;
1074         break;
1075 
1076       case HAL_RAMCFG_MSPDEINIT_CB_ID :
1077         /* UnRegister msp de-init callback */
1078         hramcfg->MspDeInitCallback = NULL;
1079         break;
1080 
1081       case  HAL_RAMCFG_ALL_CB_ID:
1082         /* UnRegister all available callbacks */
1083         hramcfg->MspDeInitCallback = NULL;
1084         hramcfg->MspInitCallback   = NULL;
1085         break;
1086 
1087       default :
1088         /* Update the error code */
1089         hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK;
1090 
1091         /* Update return status */
1092         status =  HAL_ERROR;
1093         break;
1094     }
1095   }
1096   else
1097   {
1098     /* Update the error code and return error */
1099     hramcfg->ErrorCode = HAL_RAMCFG_ERROR_INVALID_CALLBACK;
1100     status = HAL_ERROR;
1101   }
1102 
1103   return status;
1104 }
1105 
1106 /**
1107   * @}
1108   */
1109 #endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */
1110 
1111 /** @addtogroup RAMCFG_Exported_Functions_Group7
1112   *
1113 @verbatim
1114  ===============================================================================
1115                     ##### State and Error Functions  #####
1116  ===============================================================================
1117     [..]
1118       This section provides functions to check and get the RAMCFG state
1119       and the error code.
1120     [..]
1121       The HAL_RAMCFG_GetState() function allows the user to get the RAMCFG peripheral
1122       state.
1123       The HAL_RAMCFG_GetError() function allows the user to get the RAMCFG peripheral error
1124       code.
1125 
1126 @endverbatim
1127   * @{
1128   */
1129 
1130 /**
1131   * @brief  Get the RAMCFG peripheral state.
1132   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
1133   *                         contains the configuration information for the
1134   *                         specified RAMCFG instance.
1135   * @retval RAMCFG state.
1136   */
HAL_RAMCFG_GetState(const RAMCFG_HandleTypeDef * hramcfg)1137 HAL_RAMCFG_StateTypeDef HAL_RAMCFG_GetState(const RAMCFG_HandleTypeDef *hramcfg)
1138 {
1139   /* Check the parameters */
1140   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
1141 
1142   /* Return the RAMCFG state */
1143   return hramcfg->State;
1144 }
1145 
1146 /**
1147   * @brief  Get the RAMCFG peripheral error code.
1148   * @param  hramcfg       : Pointer to a RAMCFG_HandleTypeDef structure that
1149   *                         contains the configuration information for the
1150   *                         specified RAMCFG instance.
1151   * @retval RAMCFG error code.
1152   */
HAL_RAMCFG_GetError(const RAMCFG_HandleTypeDef * hramcfg)1153 uint32_t HAL_RAMCFG_GetError(const RAMCFG_HandleTypeDef *hramcfg)
1154 {
1155   /* Check the parameters */
1156   assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance));
1157 
1158   /* Return the RAMCFG error code */
1159   return hramcfg->ErrorCode;
1160 }
1161 
1162 /**
1163   * @}
1164   */
1165 
1166 
1167 #endif /* HAL_RAMCFG_MODULE_ENABLED */
1168 /**
1169   * @}
1170   */
1171 
1172 /**
1173   * @}
1174   */
1175 
1176 /**
1177   * @}
1178   */
1179 
1180