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