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