1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_bsec.c
4   * @author  MCD Application Team
5   * @brief   BSEC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of Boot and SECurity (BSEC):
8   *           + Initialization and de-initialization functions
9   *
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2023 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                         ##### How to use this driver #####
25   ==============================================================================
26   [..]
27 
28      *** General Configuration ***
29     ============================================================
30     [..]
31 
32       (+) Call the function HAL_BSEC_GetStatus() to get the status of BSEC
33     peripheral.
34 
35       (+) Call the function HAL_BSEC_GlobalLock() to lock the write to BSEC
36     registers.
37 
38       (+) Call the function HAL_BSEC_GetGlobalLockStatus() to get the global
39     write registers lock status.
40 
41       (+) Call the function HAL_BSEC_GetErrorCode() to get the error code
42     raised when API return HAL_ERROR.
43 
44      *** OTP Management ***
45     ============================================================
46     [..]
47 
48       (+) Call the function HAL_BSEC_OTP_Read() to read the value of
49     an OTP fuse.
50 
51       (+) Call the function HAL_BSEC_OTP_Program() to program an OTP
52     fuse with or without permanent lock.
53 
54       (+) Call the function HAL_BSEC_OTP_Reload() to reload an OTP
55     fuse value.
56 
57       (+) Call the function HAL_BSEC_OTP_Lock() to sticky lock
58     an OTP fuse programming, writing shadowed register or reload.
59 
60       (+) Call the function HAL_BSEC_OTP_GetState() to get the sticky lock
61     status (programming, writing shadowed register or reload), the permanent
62     lock status, the shadow configuration, the ECC or hidden status of an
63     OTP fuse.
64 
65 
66      *** Shadow fuse register management ***
67     [..]
68 
69       (+) Call the function HAL_BSEC_OTP_ReadShadow() to read the value of
70     a shadow fuse register.
71 
72       (+) Call the function HAL_BSEC_OTP_WriteShadow() to write in a shadow
73     fuse register.
74 
75       (+) Call the function HAL_BSEC_OTP_GetShadowState() to
76     get the validity status of a shadow fuse register.
77 
78      *** Device lifecycle management ***
79     ============================================================
80     [..]
81 
82       (+) Call the function HAL_BSEC_GetDeviceLifeCycleState() to get the
83     BSEC device lifecycle state.
84 
85       (+) Call the function HAL_BSEC_ReadEpochCounter() to read the value
86     of epoch counter.
87 
88       (+) Call the function HAL_BSEC_SelectEpochCounter() to select the
89     epoch counter used by SAES.
90 
91       (+) Call the function HAL_BSEC_GetEpochCounterSelection() to get
92     the epoch counter selection for SAES.
93 
94      *** HDPL management ***
95     ============================================================
96         [..]
97 
98       (+) Call the function HAL_BSEC_GetHDPLValue() to get the current HDPL.
99 
100       (+) Call the function HAL_BSEC_IncrementHDPLValue() to increment the HDPL.
101 
102       (+) Call the function HAL_BSEC_ConfigSAESHDPLIncrementValue() to configure
103     the increment of HDPL sent to SAES.
104 
105       (+) Call the function HAL_BSEC_GetSAESHDPLIncrementValue() to get the SAES
106     increment to HDPL.
107 
108          *** Scratch register management ***
109     ============================================================
110     [..]
111 
112       (+) Call the function HAL_BSEC_WriteScratchValue() to write a value in
113     write once scratch or scratch register.
114 
115       (+) Call the function HAL_BSEC_ReadScratchValue() to read a value from
116     write once scratch or scratch register.
117 
118 
119          *** Debug management ***
120     ============================================================
121     [..]
122 
123       (+) Call the function HAL_BSEC_GetDebugRequest() to get the debug
124     request of host debugger.
125 
126       (+) Call the function HAL_BSEC_SendJTAGData() to send data via JTAG.
127 
128       (+) Call the function HAL_BSEC_ReceiveJTAGData() to receive data
129     via JTAG.
130 
131       (+) Call the function HAL_BSEC_ConfigDebug() to configure the HDPL,
132     secure and non-secure authorization for debugger.
133 
134       (+) Call the function HAL_BSEC_GetDebugConfig() to get the HDPL,
135     secure and non-secure authorization of debug.
136 
137       (+) Call the function HAL_BSEC_LockDebug() to lock the debug.
138 
139       (+) Call the function HAL_BSEC_UnlockDebug() to unlock the debug.
140 
141       (+) Call the function HAL_BSEC_GetDebugLockState() to get the debug
142     lock status.
143 
144          *** DHUK management ***
145     ============================================================
146         [..]
147 
148       (+) Call the function HAL_BSEC_GetDHUKValidity() to get the validity
149     of DHUK.
150 
151       (+) Call the function HAL_BSEC_LockDHUKUse() to lock the DHUK use.
152 
153       (+) Call the function HAL_BSEC_GetDHUKLockStatus() to get the DHUK
154     lock status.
155 
156          *** Reset counter ***
157     ============================================================
158         [..]
159 
160       (+) Call the function HAL_BSEC_GetNumberOfResets() to get the number
161     of hot or warm resets.
162   @endverbatim
163 
164   */
165 
166 /* Includes ------------------------------------------------------------------*/
167 #include "stm32n6xx_hal.h"
168 
169 /** @addtogroup STM32N6xx_HAL_Driver
170   * @{
171   */
172 
173 #if defined(HAL_BSEC_MODULE_ENABLED)
174 
175 /** @defgroup BSEC BSEC
176   * @brief BSEC HAL module driver.
177   * @{
178   */
179 
180 /* Private typedef -----------------------------------------------------------*/
181 /* Private define ------------------------------------------------------------*/
182 /** @defgroup BSEC_Private_Constants BSEC Private Constants
183   * @{
184   */
185 #define BSEC_HDPL_INCREMENT_CODE     0x60B166E7U
186 #define BSEC_NB_FUSES                376U
187 #define BSEC_LIMIT_UPPER_FUSES       256U
188 #define BSEC_NB_SHADOW_REG           BSEC_NB_FUSES
189 #define BSEC_NB_EPOCH_COUNTER        2U
190 #define BSEC_NB_SCRATCH_REG          4U
191 #define BSEC_NB_WOSCR_REG            8U
192 #define BSEC_OTPSR_RELOAD_ERRORS     (BSEC_OTPSR_DISTURBF | BSEC_OTPSR_DEDF | BSEC_OTPSR_AMEF)
193 #define BSEC_SHADOW_REG_WRITE_LIMIT  9U
194 #define BSEC_TIMEOUT                 1000U
195 /**
196   * @}
197   */
198 /* Private macro -------------------------------------------------------------*/
199 
200 
201 /* Private variables ---------------------------------------------------------*/
202 /* Private function prototypes -----------------------------------------------*/
203 /** @defgroup BSEC_Private_Functions BSEC Private Functions
204   * @{
205   */
206 
207 /**
208   * @}
209   */
210 
211 /* Exported functions --------------------------------------------------------*/
212 
213 /** @defgroup BSEC_Exported_Functions BSEC Exported Functions
214   * @{
215   */
216 
217 /** @defgroup BSEC_Exported_Functions_Group1 General configuration functions
218  *  @brief   General configuration functions
219  *
220 @verbatim
221  ===============================================================================
222                 ##### General configuration functions #####
223  ===============================================================================
224     [..]
225   This subsection provides a set of functions allowing to perform global
226   configuration of BSEC.
227 
228 @endverbatim
229   * @{
230   */
231 
232 /**
233   * @brief  Get the status of BSEC peripheral.
234   *
235   * @param  hbsec   BSEC handle
236   * @param  pStatus  Returned value of BSEC status. The returned value is @ref BSEC_Status
237   *
238   * @retval HAL_StatusTypeDef HAL Status
239   */
HAL_BSEC_GetStatus(BSEC_HandleTypeDef * hbsec,uint32_t * pStatus)240 HAL_StatusTypeDef HAL_BSEC_GetStatus(BSEC_HandleTypeDef * hbsec, uint32_t *pStatus)
241 {
242   /* Check the handle pointer */
243   if (hbsec == NULL)
244   {
245     return HAL_ERROR;
246   }
247 
248   /* Check the address of returned value and instance */
249  if ((pStatus == NULL) || (hbsec->Instance != BSEC))
250   {
251     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
252     return HAL_ERROR;
253   }
254 
255   *pStatus = (hbsec->Instance->OTPSR & (BSEC_OTPSR_INIT_DONE | BSEC_OTPSR_HIDEUP | BSEC_OTPSR_OTPNVIR));
256 
257   return HAL_OK;
258 }
259 
260 /**
261   * @brief  Lock the write to BSEC registers.
262   *
263   * @param  hbsec  BSEC handle
264   *
265   * @retval HAL_StatusTypeDef HAL Status
266   */
HAL_BSEC_GlobalLock(BSEC_HandleTypeDef * hbsec)267 HAL_StatusTypeDef HAL_BSEC_GlobalLock(BSEC_HandleTypeDef *hbsec)
268 {
269   /* Check the handle pointer */
270   if (hbsec == NULL)
271   {
272     return HAL_ERROR;
273   }
274 
275   /* Check the instance */
276   if (hbsec->Instance != BSEC)
277   {
278     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
279     return HAL_ERROR;
280   }
281 
282   /* Set the value of global lock */
283   SET_BIT(hbsec->Instance->LOCKR, BSEC_LOCKR_GWLOCK);
284 
285   return HAL_OK;
286 }
287 
288 /**
289   * @brief  Get the global write registers lock status.
290   *
291   * @param  hbsec  BSEC handle
292   * @param  pStatus  Returned value of global lock status. The returned value is @ref BSEC_Global_Lock
293   *
294   * @retval HAL_StatusTypeDef HAL Status
295   */
HAL_BSEC_GetGlobalLockStatus(BSEC_HandleTypeDef * hbsec,uint32_t * pStatus)296 HAL_StatusTypeDef HAL_BSEC_GetGlobalLockStatus(BSEC_HandleTypeDef * hbsec, uint32_t *pStatus)
297 {
298   /* Check the handle pointer */
299   if (hbsec == NULL)
300   {
301     return HAL_ERROR;
302   }
303 
304   /* Check the address of returned value and instance */
305   if ((pStatus == NULL) || (hbsec->Instance != BSEC))
306   {
307     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
308     return HAL_ERROR;
309   }
310 
311   /* Get the global lock status */
312   *pStatus = (hbsec->Instance->LOCKR & BSEC_LOCKR_GWLOCK);
313 
314   return HAL_OK;
315 }
316 
317 /**
318   * @brief  Get the error code of BSEC driver.
319   *
320   * @param  hbsec  BSEC handle
321   * @param  pError  Returned value of error code. The returned value is @ref BSEC_Error_Code
322   *
323   * @retval HAL_StatusTypeDef HAL Status
324   */
HAL_BSEC_GetErrorCode(BSEC_HandleTypeDef * hbsec,uint32_t * pError)325 HAL_StatusTypeDef HAL_BSEC_GetErrorCode(BSEC_HandleTypeDef * hbsec, uint32_t *pError)
326 {
327   /* Check the handle pointer */
328   if (hbsec == NULL)
329   {
330     return HAL_ERROR;
331   }
332 
333   /* Check the address of returned value */
334  if (pError == NULL)
335   {
336     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
337     return HAL_ERROR;
338   }
339 
340   *pError = hbsec->ErrorCode;
341 
342   return HAL_OK;
343 }
344 
345 /**
346   * @}
347   */
348 
349 /** @defgroup BSEC_Exported_Functions_Group2 OTP fuse management functions
350  *  @brief   OTP fuse management functions
351  *
352 @verbatim
353  ===============================================================================
354                   ##### OTP fuse management functions #####
355  ===============================================================================
356     [..]
357   This subsection provides a set of functions allowing to manage the OTP fuses.
358 
359 @endverbatim
360   * @{
361   */
362 
363 /**
364   * @brief  Read OTP fuse value.
365   *
366   * @param  hbsec     BSEC handle
367   * @param  FuseId     Fuse to be read, this parameter value is between 0 and BSEC_NB_FUSES-1
368   * @param  pFuseData  Returned value of fuse. The returned value is between 0 and 0xFFFFFFFFU
369   *
370   * @retval HAL_StatusTypeDef HAL Status
371   */
HAL_BSEC_OTP_Read(BSEC_HandleTypeDef * hbsec,uint32_t FuseId,uint32_t * pFuseData)372 HAL_StatusTypeDef HAL_BSEC_OTP_Read(BSEC_HandleTypeDef * hbsec, uint32_t FuseId, uint32_t *pFuseData)
373 {
374   /* Check the handle pointer */
375   if (hbsec == NULL)
376   {
377     return HAL_ERROR;
378   }
379 
380   /* Check the address of returned value and instance */
381  if ((pFuseData == NULL) || (hbsec->Instance != BSEC))
382   {
383     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
384     return HAL_ERROR;
385   }
386 
387   if (FuseId < BSEC_NB_FUSES)
388   {
389     /* Reload the data :
390        - Unshadowed fuse are not automatically reload and data no more available after register read
391        - Shadowed fuse contains by default the shadow value in the register */
392     if (HAL_BSEC_OTP_Reload(hbsec, FuseId) == HAL_OK)
393     {
394       /* Read data from shadow register */
395       *pFuseData = hbsec->Instance->FVRw[FuseId];
396     }
397     else
398     {
399       return HAL_ERROR;
400     }
401   }
402   else
403   {
404     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
405     return HAL_ERROR;
406   }
407 
408   return HAL_OK;
409 }
410 
411 /**
412   * @brief  Program an OTP fuse with or without permanent lock.
413   *
414   * @param  hbsec    BSEC handle
415   * @param  FuseId    Fuse to be written, this parameter value is between 0 and BSEC_NB_FUSES-1
416   * @param  FuseData  Data to be written in fuse, this parameter value is between 0 and 0xFFFFFFFFU
417   * @param  Lock      Permanent lock value, this parameter is @ref BSEC_Permanent_Lock
418   *
419   * @retval HAL_StatusTypeDef HAL Status
420   */
HAL_BSEC_OTP_Program(BSEC_HandleTypeDef * hbsec,uint32_t FuseId,uint32_t FuseData,uint32_t Lock)421 HAL_StatusTypeDef HAL_BSEC_OTP_Program(BSEC_HandleTypeDef *hbsec, uint32_t FuseId, uint32_t FuseData, uint32_t Lock)
422 {
423   uint32_t status_reg;
424   uint32_t status_bit;
425   uint32_t read_data;
426   uint32_t tick_start = HAL_GetTick();
427 
428   /* Check the handle pointer */
429   if (hbsec == NULL)
430   {
431     return HAL_ERROR;
432   }
433 
434   /* Check the instance */
435  if (hbsec->Instance != BSEC)
436   {
437     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
438     return HAL_ERROR;
439   }
440 
441   /* Check the permanent lock */
442   assert_param(IS_BSEC_PERMANENT_LOCK(Lock));
443 
444   /* Get the correct register value */
445   if (FuseId < BSEC_NB_FUSES)
446   {
447     status_reg = FuseId / 32U;
448     status_bit = (uint32_t)(1UL << (FuseId % 32U));
449 
450     if ((hbsec->Instance->SPLOCKx[status_reg] & status_bit) == 0U)
451     {
452       /* Write data in register */
453       hbsec->Instance->WDR = FuseData;
454 
455       /* Perform a program of the fuse register */
456       MODIFY_REG(hbsec->Instance->OTPCR, (BSEC_OTPCR_PPLOCK | BSEC_OTPCR_PROG | BSEC_OTPCR_ADDR),
457                                          (FuseId | BSEC_OTPCR_PROG | Lock));
458 
459       /* Wait the operation is finished */
460       while ((hbsec->Instance->OTPSR & BSEC_OTPSR_BUSY) != 0U)
461       {
462         if ((HAL_GetTick() - tick_start) > BSEC_TIMEOUT)
463         {
464           hbsec->ErrorCode = HAL_BSEC_ERROR_TIMEOUT;
465           return HAL_ERROR;
466         }
467       }
468 
469       /* Check programming errors */
470       if ((hbsec->Instance->OTPSR & BSEC_OTPSR_PROGFAIL) != 0U)
471       {
472         hbsec->ErrorCode = HAL_BSEC_ERROR_PROGFAIL;
473         return HAL_ERROR;
474       }
475 
476       /* Read back programmed data */
477       if (HAL_BSEC_OTP_Read(hbsec, FuseId, &read_data) == HAL_OK)
478       {
479         /* Verify programmed data */
480         if (read_data != FuseData)
481         {
482           hbsec->ErrorCode = HAL_BSEC_ERROR_PROGFAIL;
483           return HAL_ERROR;
484         }
485       }
486       else
487       {
488         return HAL_ERROR;
489       }
490     }
491     else
492     {
493       /* Fuse is sticky programming locked */
494       hbsec->ErrorCode = HAL_BSEC_ERROR_LOCK;
495       return HAL_ERROR;
496     }
497   }
498   else
499   {
500     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
501     return HAL_ERROR;
502   }
503 
504   return HAL_OK;
505 }
506 
507 /**
508   * @brief  Reload a OTP fuse value.
509   *
510   * @param  hbsec  BSEC handle
511   * @param  FuseId  Fuse to be reload, this parameter value is between 0 and BSEC_NB_FUSES-1
512   *
513   * @retval HAL_StatusTypeDef HAL Status
514   */
HAL_BSEC_OTP_Reload(BSEC_HandleTypeDef * hbsec,uint32_t FuseId)515 HAL_StatusTypeDef HAL_BSEC_OTP_Reload(BSEC_HandleTypeDef *hbsec, uint32_t FuseId)
516 {
517   uint32_t status_reg;
518   uint32_t status_bit;
519   uint32_t tick_start = HAL_GetTick();
520 
521   /* Check the handle pointer */
522   if (hbsec == NULL)
523   {
524     return HAL_ERROR;
525   }
526 
527   /* Check the instance */
528  if (hbsec->Instance != BSEC)
529   {
530     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
531     return HAL_ERROR;
532   }
533 
534   if (FuseId < BSEC_NB_FUSES)
535   {
536     status_reg = FuseId / 32U;
537     status_bit = (uint32_t)(1UL << (FuseId % 32U));
538 
539     if ((hbsec->Instance->SRLOCKx[status_reg] & status_bit) == 0U)
540     {
541       /* Perform a reload of the fuse register */
542       MODIFY_REG(hbsec->Instance->OTPCR, (BSEC_OTPCR_PPLOCK | BSEC_OTPCR_PROG | BSEC_OTPCR_ADDR), FuseId);
543 
544       /* Wait the operation is finished */
545       while ((hbsec->Instance->OTPSR & BSEC_OTPSR_BUSY) != 0U)
546       {
547         if ((HAL_GetTick() - tick_start) > BSEC_TIMEOUT)
548         {
549           hbsec->ErrorCode = HAL_BSEC_ERROR_TIMEOUT;
550           return HAL_ERROR;
551         }
552       }
553 
554       if ((hbsec->Instance->OTPSR & BSEC_OTPSR_RELOAD_ERRORS) != 0U)
555       {
556         /* An error occurred during reloading, value can't be relied on */
557         hbsec->ErrorCode = (hbsec->Instance->OTPSR & BSEC_OTPSR_RELOAD_ERRORS);
558         return HAL_ERROR;
559       }
560     }
561     else
562     {
563       /* Shadow register is sticky reload locked */
564       hbsec->ErrorCode = HAL_BSEC_ERROR_LOCK;
565       return HAL_ERROR;
566     }
567   }
568   else
569   {
570     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
571     return HAL_ERROR;
572   }
573 
574   return HAL_OK;
575 }
576 
577 /**
578   * @brief  Sticky lock an OTP fuse programming, writing shadowed register or reload.
579   *
580   * @param  hbsec  BSEC handle
581   * @param  FuseId  Fuse to lock, this parameter value is between 0 and BSEC_NB_FUSES-1
582   * @param  Lock    Lock status of the fuse, this parameter is a combination of
583   *                   @ref HAL_BSEC_FUSE_PROG_LOCKED,
584   *                   @ref HAL_BSEC_FUSE_WRITE_LOCKED,
585   *                   @ref HAL_BSEC_FUSE_RELOAD_LOCKED
586   *
587   * @retval HAL_StatusTypeDef HAL Status
588   */
HAL_BSEC_OTP_Lock(BSEC_HandleTypeDef * hbsec,uint32_t FuseId,uint32_t Lock)589 HAL_StatusTypeDef HAL_BSEC_OTP_Lock(BSEC_HandleTypeDef *hbsec, uint32_t FuseId, uint32_t Lock)
590 {
591   uint32_t status_reg;
592   uint32_t status_bit;
593 
594   /* Check the handle pointer */
595   if (hbsec == NULL)
596   {
597     return HAL_ERROR;
598   }
599 
600   /* Check the instance */
601  if (hbsec->Instance != BSEC)
602   {
603     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
604     return HAL_ERROR;
605   }
606 
607   /* Check the lock configuration */
608   assert_param(IS_BSEC_LOCK_CFG(Lock));
609 
610   if (FuseId < BSEC_NB_FUSES)
611   {
612     status_reg = FuseId / 32U;
613     status_bit = (uint32_t)(1UL << (FuseId % 32U));
614 
615     if ((Lock & HAL_BSEC_FUSE_PROG_LOCKED) != 0U)
616     {
617       /* Programming lock */
618       SET_BIT(hbsec->Instance->SPLOCKx[status_reg], status_bit);
619     }
620 
621     if ((Lock & HAL_BSEC_FUSE_WRITE_LOCKED) != 0U)
622     {
623       /* Write lock */
624       SET_BIT(hbsec->Instance->SWLOCKx[status_reg], status_bit);
625     }
626 
627     if ((Lock & HAL_BSEC_FUSE_RELOAD_LOCKED) != 0U)
628     {
629       /* Reload lock */
630       SET_BIT(hbsec->Instance->SRLOCKx[status_reg], status_bit);
631     }
632   }
633   else
634   {
635     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
636     return HAL_ERROR;
637   }
638 
639   return HAL_OK;
640 }
641 
642 /**
643   * @brief  Get the sticky lock status (programming, writing shadowed register
644   *         or reload), the permanent lock status, the shadow configuration,
645   *         the ECC or hidden status of an OTP fuse.
646   *
647   * @param  hbsec  BSEC handle
648   * @param  FuseId  Fuse to get the state, this parameter value is between 0 and BSEC_NB_FUSES-1
649   * @param  pState  Returned value of state. The returned value is a combination of @ref BSEC_State
650   *
651   * @retval HAL_StatusTypeDef HAL Status
652   */
HAL_BSEC_OTP_GetState(BSEC_HandleTypeDef * hbsec,uint32_t FuseId,uint32_t * pState)653 HAL_StatusTypeDef HAL_BSEC_OTP_GetState(BSEC_HandleTypeDef * hbsec, uint32_t FuseId, uint32_t *pState)
654 {
655   uint32_t status_reg;
656   uint32_t status_bit;
657   uint32_t otpsr_reg;
658   uint32_t state;
659 
660   /* Check the handle pointer */
661   if (hbsec == NULL)
662   {
663     return HAL_ERROR;
664   }
665 
666   /* Check the address of returned value and instance */
667  if ((pState == NULL) || (hbsec->Instance != BSEC))
668   {
669     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
670     return HAL_ERROR;
671   }
672 
673   if (FuseId < BSEC_NB_FUSES)
674   {
675     status_reg = FuseId / 32U;
676     status_bit = (uint32_t)(1UL << (FuseId % 32U));
677 
678     /* Initialize return value */
679     state = 0U;
680 
681     /* Check sticky programming lock */
682     if ((hbsec->Instance->SPLOCKx[status_reg] & status_bit) != 0U)
683     {
684       state |= HAL_BSEC_FUSE_PROG_LOCKED;
685     }
686 
687     /* Check sticky write lock */
688     if ((hbsec->Instance->SWLOCKx[status_reg] & status_bit) != 0U)
689     {
690       state |= HAL_BSEC_FUSE_WRITE_LOCKED;
691     }
692 
693     /* Check sticky reload lock */
694     if ((hbsec->Instance->SRLOCKx[status_reg] & status_bit) != 0U)
695     {
696       state |= HAL_BSEC_FUSE_RELOAD_LOCKED;
697     }
698     else
699     {
700       /* Check permanent lock : only in case of reload allowed as OTPSR reflect
701          status of most recently read word */
702       if (HAL_BSEC_OTP_Reload(hbsec, FuseId) == HAL_OK)
703       {
704         otpsr_reg = hbsec->Instance->OTPSR;
705 
706         if ((otpsr_reg & BSEC_OTPSR_PPLF) != 0u)
707         {
708           /* Permanent programming lock detected */
709           state |= HAL_BSEC_FUSE_LOCKED;
710         }
711         else if ((otpsr_reg & BSEC_OTPSR_PPLMF) != 0U)
712         {
713           /* Permanent programming lock on the two lower fuse values in the array are not identical */
714           hbsec->ErrorCode = HAL_BSEC_ERROR_PPLM;
715           return HAL_ERROR;
716         }
717         else
718         {
719           /* No permanent programming lock detected */
720         }
721       }
722     }
723 
724     /* Check shadow configuration */
725     if ((hbsec->Instance->SFSRx[status_reg] & status_bit) != 0U)
726     {
727       state |= HAL_BSEC_FUSE_SHADOWED;
728     }
729 
730     /* Check hidden status */
731     if (((hbsec->Instance->OTPSR & BSEC_OTPSR_HIDEUP) != 0U) &&
732         (FuseId >= BSEC_LIMIT_UPPER_FUSES))
733     {
734       state |= HAL_BSEC_FUSE_HIDDEN;
735     }
736 
737     /* Check ECC errors on all OTP fuses */
738     state |= (hbsec->Instance->OTPSR & (BSEC_OTPSR_OTPERR | BSEC_OTPSR_OTPSEC));
739 
740   }
741   else
742   {
743     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
744     return HAL_ERROR;
745   }
746   *pState = state;
747   return HAL_OK;
748 }
749 
750 /**
751   * @}
752   */
753 
754 /** @defgroup BSEC_Exported_Functions_Group3 Shadow fuse register management functions
755  *  @brief   Shadow fuse register management functions
756  *
757 @verbatim
758  ===============================================================================
759              ##### Shadow fuse register management functions #####
760  ===============================================================================
761     [..]
762   This subsection provides a set of functions allowing to manage the
763   shadow fuse registers.
764 
765 @endverbatim
766   * @{
767   */
768 
769 /**
770   * @brief  Read the value of a shadow fuse register.
771   *
772   * @param  hbsec    BSEC handle
773   * @param  RegId     Shadow register to be read, this parameter value is between 0 and BSEC_NB_FUSES-1
774   * @param  pRegData  Returned value of register data. The returned value is between 0 and 0xFFFFFFFFU
775   *
776   * @retval HAL_StatusTypeDef HAL Status
777   */
HAL_BSEC_OTP_ReadShadow(BSEC_HandleTypeDef * hbsec,uint32_t RegId,uint32_t * pRegData)778 HAL_StatusTypeDef HAL_BSEC_OTP_ReadShadow(BSEC_HandleTypeDef * hbsec, uint32_t RegId, uint32_t *pRegData)
779 {
780   uint32_t status_reg;
781   uint32_t status_bit;
782 
783   /* Check the handle pointer */
784   if (hbsec == NULL)
785   {
786     return HAL_ERROR;
787   }
788 
789   /* Check the address of returned value and instance */
790   if ((pRegData == NULL) || (hbsec->Instance != BSEC))
791   {
792     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
793     return HAL_ERROR;
794   }
795 
796   if (RegId < BSEC_NB_SHADOW_REG)
797   {
798     status_reg = RegId / 32U;
799     status_bit = (uint32_t)(1UL << (RegId % 32U));
800 
801     if ((hbsec->Instance->SFSRx[status_reg] & status_bit) != 0U)
802     {
803       /* Read data from shadow register */
804       *pRegData = hbsec->Instance->FVRw[RegId];
805     }
806     else
807     {
808       /* Fuse is not shadowed */
809       hbsec->ErrorCode = HAL_BSEC_ERROR_UNALLOWED;
810       return HAL_ERROR;
811     }
812   }
813   else
814   {
815     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
816     return HAL_ERROR;
817   }
818 
819   return HAL_OK;
820 }
821 
822 /**
823   * @brief  Write in a shadow fuse register.
824   *
825   * @param  hbsec    BSEC handle
826   * @param  RegId     Shadow register to be written, this parameter value is between 0 and BSEC_NB_FUSES-1
827   * @param  RegData   Data to be written in shadow register, this parameter value is between 0 and 0xFFFFFFFFU
828   *
829   * @retval HAL_StatusTypeDef HAL Status
830   */
HAL_BSEC_OTP_WriteShadow(BSEC_HandleTypeDef * hbsec,uint32_t RegId,uint32_t RegData)831 HAL_StatusTypeDef HAL_BSEC_OTP_WriteShadow(BSEC_HandleTypeDef *hbsec, uint32_t RegId, uint32_t RegData)
832 {
833   uint32_t status_reg;
834   uint32_t status_bit;
835 
836   /* Check the handle pointer */
837   if (hbsec == NULL)
838   {
839     return HAL_ERROR;
840   }
841 
842   /* Check the instance */
843  if (hbsec->Instance != BSEC)
844   {
845     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
846     return HAL_ERROR;
847   }
848 
849   /* Get the correct register value */
850   if ((RegId > BSEC_SHADOW_REG_WRITE_LIMIT) && (RegId < BSEC_NB_SHADOW_REG))
851   {
852     status_reg = RegId / 32U;
853     status_bit = (uint32_t)(1UL << (RegId % 32U));
854 
855     if ((hbsec->Instance->SFSRx[status_reg] & status_bit) != 0U)
856     {
857       if ((hbsec->Instance->SWLOCKx[status_reg] & status_bit) == 0U)
858       {
859         /* Value is written in register */
860         hbsec->Instance->FVRw[RegId] = RegData;
861       }
862       else
863       {
864         /* Shadow register is sticky write locked */
865         hbsec->ErrorCode = HAL_BSEC_ERROR_LOCK;
866         return HAL_ERROR;
867       }
868     }
869     else
870     {
871       /* Fuse is not shadowed */
872       hbsec->ErrorCode = HAL_BSEC_ERROR_UNALLOWED;
873       return HAL_ERROR;
874     }
875   }
876   else
877   {
878     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
879     return HAL_ERROR;
880   }
881 
882   return HAL_OK;
883 }
884 
885 /**
886   * @brief  Get the validity status of a shadow register.
887   *
888   * @param  hbsec     BSEC handle
889   * @param  RegId      Shadow register to be checked, this parameter value is between 0 and BSEC_NB_FUSES-1
890   * @param  pValidity  Returned value of validity status. The returned value is @ref BSEC_Reload_Validity
891   *
892   * @retval HAL_StatusTypeDef HAL Status
893   */
HAL_BSEC_OTP_GetShadowState(BSEC_HandleTypeDef * hbsec,uint32_t RegId,uint32_t * pValidity)894 HAL_StatusTypeDef HAL_BSEC_OTP_GetShadowState(BSEC_HandleTypeDef * hbsec, uint32_t RegId, uint32_t *pValidity)
895 {
896   uint32_t status_reg;
897   uint32_t status_bit;
898 
899   /* Check the handle pointer */
900   if (hbsec == NULL)
901   {
902     return HAL_ERROR;
903   }
904 
905   /* Check the address of returned value and instance */
906  if ((pValidity == NULL) || (hbsec->Instance != BSEC))
907   {
908     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
909     return HAL_ERROR;
910   }
911 
912   if (RegId < BSEC_NB_SHADOW_REG)
913   {
914     status_reg = RegId / 32U;
915     status_bit = (uint32_t)(1UL << (RegId % 32U));
916 
917     if ((hbsec->Instance->SFSRx[status_reg] & status_bit) != 0U)
918     {
919       if ((hbsec->Instance->OTPVLDRx[status_reg] & status_bit) != 0U)
920       {
921         *pValidity = HAL_BSEC_RELOAD_DONE;
922       }
923       else
924       {
925         *pValidity = HAL_BSEC_RELOAD_ERROR;
926       }
927     }
928     else
929     {
930       /* Fuse is not shadowed */
931       hbsec->ErrorCode = HAL_BSEC_ERROR_UNALLOWED;
932       return HAL_ERROR;
933     }
934   }
935   else
936   {
937     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
938     return HAL_ERROR;
939   }
940 
941   return HAL_OK;
942 }
943 
944 /**
945   * @}
946   */
947 
948 /** @defgroup BSEC_Exported_Functions_Group4 Device lifecycle management functions
949  *  @brief   Device lifecycle management functions
950  *
951 @verbatim
952  ===============================================================================
953                ##### Device lifecycle management functions #####
954  ===============================================================================
955     [..]
956   This subsection provides a set of functions allowing to manage the
957   device lifecycle.
958 
959 @endverbatim
960   * @{
961   */
962 
963 /**
964   * @brief  Get the BSEC device lifecycle state.
965   *
966   * @param  hbsec  BSEC handle
967   * @param  pState  Returned value of device lifecycle state. The returned value is @ref BSEC_Lifecycle_State
968   *
969   * @retval HAL_StatusTypeDef HAL Status
970   */
HAL_BSEC_GetDeviceLifeCycleState(BSEC_HandleTypeDef * hbsec,uint32_t * pState)971 HAL_StatusTypeDef HAL_BSEC_GetDeviceLifeCycleState(BSEC_HandleTypeDef * hbsec, uint32_t *pState)
972 {
973 
974   uint32_t state;
975   /* Check the handle pointer */
976   if (hbsec == NULL)
977   {
978     return HAL_ERROR;
979   }
980 
981   /* Check the address of returned value and instance */
982  if ((pState == NULL) || (hbsec->Instance != BSEC))
983   {
984     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
985     return HAL_ERROR;
986   }
987 
988   /* Return the state */
989   state = (hbsec->Instance->SR & BSEC_SR_NVSTATE);
990 
991   if (IS_BSEC_STATE(state))
992   {
993     *pState = state;
994     return HAL_OK;
995   }
996   else
997   {
998     hbsec->ErrorCode = HAL_BSEC_ERROR_UNDEFINED_VALUE;
999     return HAL_ERROR;
1000   }
1001 }
1002 
1003 /**
1004   * @brief  Read the value of epoch counter.
1005   *
1006   * @param  hbsec        BSEC handle
1007   * @param  CounterId     Identifier of the epoch counter to be read, this parameter can be @ref BSEC_Epoch_Select
1008   * @param  pCounterData  Returned value of epoch counter data. The returned value is between 0 and 0xFFFFFFFFU
1009   *
1010   * @retval HAL_StatusTypeDef HAL Status
1011   */
HAL_BSEC_ReadEpochCounter(BSEC_HandleTypeDef * hbsec,uint32_t CounterId,uint32_t * pCounterData)1012 HAL_StatusTypeDef HAL_BSEC_ReadEpochCounter(BSEC_HandleTypeDef * hbsec, uint32_t CounterId, uint32_t *pCounterData)
1013 {
1014   /* Check the handle pointer */
1015   if (hbsec == NULL)
1016   {
1017     return HAL_ERROR;
1018   }
1019 
1020   /* Check the address of returned value and instance */
1021  if ((pCounterData == NULL) || (hbsec->Instance != BSEC))
1022   {
1023     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1024     return HAL_ERROR;
1025   }
1026 
1027   /* Get the correct register value */
1028   if (CounterId < BSEC_NB_EPOCH_COUNTER)
1029   {
1030     *pCounterData = hbsec->Instance->EPOCHRx[CounterId];
1031   }
1032   else
1033   {
1034     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1035     return HAL_ERROR;
1036   }
1037 
1038   return HAL_OK;
1039 }
1040 
1041 /**
1042   * @brief  Select the epoch counter used by SAES.
1043   *
1044   * @param  hbsec            BSEC handle
1045   * @param  SelectedCounter   Epoch selected counter, this parameter can be @ref BSEC_Epoch_Select
1046   *
1047   * @retval HAL_StatusTypeDef HAL Status
1048   */
HAL_BSEC_SelectEpochCounter(BSEC_HandleTypeDef * hbsec,uint32_t SelectedCounter)1049 HAL_StatusTypeDef HAL_BSEC_SelectEpochCounter(BSEC_HandleTypeDef *hbsec, uint32_t SelectedCounter)
1050 {
1051   /* Check the handle pointer */
1052   if (hbsec == NULL)
1053   {
1054     return HAL_ERROR;
1055   }
1056 
1057   /* Check the instance */
1058  if (hbsec->Instance != BSEC)
1059   {
1060     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1061     return HAL_ERROR;
1062   }
1063 
1064   /* Check the epoch counter selection */
1065   assert_param(IS_BSEC_EPOCHSEL(SelectedCounter));
1066 
1067   /* Update the selected epoch counter value */
1068   MODIFY_REG(hbsec->Instance->EPOCHSELR, BSEC_EPOCHSELR_EPSEL, SelectedCounter);
1069 
1070   return HAL_OK;
1071 }
1072 
1073 /**
1074   * @brief  Get the epoch counter selection for SAES.
1075   *
1076   * @param  hbsec            BSEC handle
1077   * @param  pSelectedCounter  Returned value of epoch selected counter. The returned value is @ref BSEC_Epoch_Select
1078   *
1079   * @retval HAL_StatusTypeDef HAL Status
1080   */
HAL_BSEC_GetEpochCounterSelection(BSEC_HandleTypeDef * hbsec,uint32_t * pSelectedCounter)1081 HAL_StatusTypeDef HAL_BSEC_GetEpochCounterSelection(BSEC_HandleTypeDef * hbsec, uint32_t *pSelectedCounter)
1082 {
1083   /* Check the handle pointer */
1084   if (hbsec == NULL)
1085   {
1086     return HAL_ERROR;
1087   }
1088 
1089   /* Check the address of returned value and instance */
1090   if ((pSelectedCounter == NULL) || (hbsec->Instance != BSEC))
1091   {
1092     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1093     return HAL_ERROR;
1094   }
1095 
1096   /* Return the debug request */
1097   *pSelectedCounter = (hbsec->Instance->EPOCHSELR & BSEC_EPOCHSELR_EPSEL);
1098 
1099   return HAL_OK;
1100 }
1101 
1102 /**
1103   * @}
1104   */
1105 
1106 /** @defgroup BSEC_Exported_Functions_Group5 HDPL management functions
1107  *  @brief   HDPL management functions
1108  *
1109 @verbatim
1110  ===============================================================================
1111                      ##### HDPL management functions #####
1112  ===============================================================================
1113     [..]
1114   This subsection provides a set of functions allowing to manage the
1115   HDPL (Hide Protection Level).
1116 
1117 @endverbatim
1118   * @{
1119   */
1120 
1121 /**
1122   * @brief  Get the current HDPL.
1123   *
1124   * @param  hbsec  BSEC handle
1125   * @param  pHDPL   Returned value of current HDPL. The returned value is @ref BSEC_HDPL
1126   *
1127   * @retval HAL_StatusTypeDef HAL Status
1128   */
HAL_BSEC_GetHDPLValue(BSEC_HandleTypeDef * hbsec,uint32_t * pHDPL)1129 HAL_StatusTypeDef HAL_BSEC_GetHDPLValue(BSEC_HandleTypeDef * hbsec, uint32_t *pHDPL)
1130 {
1131 
1132   uint32_t hdpl;
1133   /* Check the handle pointer */
1134   if (hbsec == NULL)
1135   {
1136     return HAL_ERROR;
1137   }
1138 
1139   /* Check the address of returned value and instance */
1140   if ((pHDPL == NULL) || (hbsec->Instance != BSEC))
1141   {
1142     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1143     return HAL_ERROR;
1144   }
1145 
1146   /* Return the HDPL */
1147   hdpl = (hbsec->Instance->HDPLSR & BSEC_HDPLSR_HDPL);
1148 
1149   if (IS_BSEC_HDPL(hdpl))
1150   {
1151     *pHDPL = hdpl;
1152     return HAL_OK;
1153   }
1154   else
1155   {
1156     hbsec->ErrorCode = HAL_BSEC_ERROR_UNDEFINED_VALUE;
1157     return HAL_ERROR;
1158   }
1159 }
1160 
1161 /**
1162   * @brief  Increment the HDPL.
1163   *
1164   * @param  hbsec  BSEC handle
1165   *
1166   * @retval HAL_StatusTypeDef HAL Status
1167   */
HAL_BSEC_IncrementHDPLValue(BSEC_HandleTypeDef * hbsec)1168 HAL_StatusTypeDef HAL_BSEC_IncrementHDPLValue(BSEC_HandleTypeDef *hbsec)
1169 {
1170   /* Check the handle pointer */
1171   if (hbsec == NULL)
1172   {
1173     return HAL_ERROR;
1174   }
1175 
1176   /* Check the instance */
1177  if (hbsec->Instance != BSEC)
1178   {
1179     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1180     return HAL_ERROR;
1181   }
1182 
1183   /* Increment HDPL value */
1184   hbsec->Instance->HDPLCR = BSEC_HDPL_INCREMENT_CODE;
1185 
1186   return HAL_OK;
1187 }
1188 
1189 /**
1190   * @brief  Configure the increment of HDPL sent to SAES.
1191   *
1192   * @param  hbsec      BSEC handle
1193   * @param  Increment   Value of HDPL increment, this parameter can be a value of @ref BSEC_INCR_HDPL
1194   *
1195   * @retval HAL_StatusTypeDef HAL Status
1196   */
HAL_BSEC_ConfigSAESHDPLIncrementValue(BSEC_HandleTypeDef * hbsec,uint32_t Increment)1197 HAL_StatusTypeDef HAL_BSEC_ConfigSAESHDPLIncrementValue(BSEC_HandleTypeDef *hbsec, uint32_t Increment)
1198 {
1199   /* Check the handle pointer */
1200   if (hbsec == NULL)
1201   {
1202     return HAL_ERROR;
1203   }
1204 
1205   /* Check the instance */
1206  if (hbsec->Instance != BSEC)
1207   {
1208     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1209     return HAL_ERROR;
1210   }
1211 
1212   /* Check the debug configuration */
1213   assert_param(IS_BSEC_NEXTHDPL(Increment));
1214 
1215   /* Write HDPL increment value */
1216   MODIFY_REG(hbsec->Instance->NEXTLR, BSEC_NEXTLR_INCR, Increment);
1217 
1218   return HAL_OK;
1219 }
1220 
1221 /**
1222   * @brief  Get the SAES increment to HDPL.
1223   *
1224   * @param  hbsec      BSEC handle
1225   * @param  pIncrement  Returned value of HDPL increment. The returned value is a value of @ref BSEC_INCR_HDPL
1226   *
1227   * @retval HAL_StatusTypeDef HAL Status
1228   */
HAL_BSEC_GetSAESHDPLIncrementValue(BSEC_HandleTypeDef * hbsec,uint32_t * pIncrement)1229 HAL_StatusTypeDef HAL_BSEC_GetSAESHDPLIncrementValue(BSEC_HandleTypeDef * hbsec, uint32_t *pIncrement)
1230 {
1231   /* Check the handle pointer */
1232   if (hbsec == NULL)
1233   {
1234     return HAL_ERROR;
1235   }
1236 
1237   /* Check the address of returned value and instance */
1238   if ((pIncrement == NULL) || (hbsec->Instance != BSEC))
1239   {
1240     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1241     return HAL_ERROR;
1242   }
1243 
1244   /* Return the debug request */
1245   *pIncrement = (hbsec->Instance->NEXTLR & BSEC_NEXTLR_INCR);
1246 
1247   return HAL_OK;
1248 }
1249 
1250 /**
1251   * @}
1252   */
1253 
1254 /** @defgroup BSEC_Exported_Functions_Group6 Scratch registers management functions
1255  *  @brief   Scratch registers management functions
1256  *
1257 @verbatim
1258  ===============================================================================
1259                ##### Scratch registers management functions #####
1260  ===============================================================================
1261     [..]
1262   This subsection provides a set of functions allowing to manage the
1263   write once scratch and scratch registers.
1264 
1265 @endverbatim
1266   * @{
1267   */
1268 
1269 /**
1270   * @brief  Write a value in write once scratch or scratch register.
1271   *
1272   * @param  hbsec     BSEC handle
1273   * @param  pRegAddr  Register to be written
1274   * @param  Value     Value to be written, this parameter can be a value between 0 and 0xFFFFFFFFU
1275   *
1276   * @retval HAL_StatusTypeDef HAL Status
1277   */
HAL_BSEC_WriteScratchValue(BSEC_HandleTypeDef * hbsec,const BSEC_ScratchRegTypeDef * pRegAddr,uint32_t Value)1278 HAL_StatusTypeDef HAL_BSEC_WriteScratchValue(BSEC_HandleTypeDef *hbsec, const BSEC_ScratchRegTypeDef *pRegAddr, uint32_t Value)
1279 {
1280   /* Check the handle pointer */
1281   if (hbsec == NULL)
1282   {
1283     return HAL_ERROR;
1284   }
1285 
1286   /* Check the register configuration and instance */
1287  if ((pRegAddr == NULL) || (hbsec->Instance != BSEC))
1288   {
1289     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1290     return HAL_ERROR;
1291   }
1292 
1293   /* Check the debug configuration */
1294   assert_param(IS_BSEC_REGTYPE(pRegAddr->RegType));
1295 
1296   /* Write data in correct register */
1297   if (pRegAddr->RegType == HAL_BSEC_SCRATCH_REG)
1298   {
1299     if (pRegAddr->RegNumber < BSEC_NB_SCRATCH_REG)
1300     {
1301       hbsec->Instance->SCRATCHRx[pRegAddr->RegNumber] = Value;
1302     }
1303     else
1304     {
1305       hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1306       return HAL_ERROR;
1307     }
1308   }
1309   else
1310   {
1311     if (pRegAddr->RegNumber < BSEC_NB_WOSCR_REG)
1312     {
1313       hbsec->Instance->WOSCRx[pRegAddr->RegNumber] = Value;
1314     }
1315     else
1316     {
1317       hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1318       return HAL_ERROR;
1319     }
1320   }
1321 
1322   return HAL_OK;
1323 }
1324 
1325 /**
1326   * @brief  Read a value from write once scratch or scratch register.
1327   *
1328   * @param  hbsec    BSEC handle
1329   * @param  pRegAddr  Register to be read
1330   * @param  pValue  Returned value of register data. The returned value is between 0 and 0xFFFFFFFFU
1331   *
1332   * @retval HAL_StatusTypeDef HAL Status
1333   */
HAL_BSEC_ReadScratchValue(BSEC_HandleTypeDef * hbsec,const BSEC_ScratchRegTypeDef * pRegAddr,uint32_t * pValue)1334 HAL_StatusTypeDef HAL_BSEC_ReadScratchValue(BSEC_HandleTypeDef * hbsec, const BSEC_ScratchRegTypeDef *pRegAddr, uint32_t *pValue)
1335 {
1336   /* Check the handle pointer */
1337   if (hbsec == NULL)
1338   {
1339     return HAL_ERROR;
1340   }
1341 
1342   /* Check the register configuration, address of returned value and instance */
1343  if ((pRegAddr == NULL) || (pValue == NULL) || (hbsec->Instance != BSEC))
1344   {
1345     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1346     return HAL_ERROR;
1347   }
1348 
1349   /* Check the debug configuration */
1350   assert_param(IS_BSEC_REGTYPE(pRegAddr->RegType));
1351 
1352   /* Get the correct register value */
1353   if (pRegAddr->RegType == HAL_BSEC_SCRATCH_REG)
1354   {
1355     if (pRegAddr->RegNumber < BSEC_NB_SCRATCH_REG)
1356     {
1357       *pValue = hbsec->Instance->SCRATCHRx[pRegAddr->RegNumber];
1358     }
1359     else
1360     {
1361       hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1362       return HAL_ERROR;
1363     }
1364   }
1365   else
1366   {
1367     if (pRegAddr->RegNumber < BSEC_NB_WOSCR_REG)
1368     {
1369       *pValue = hbsec->Instance->WOSCRx[pRegAddr->RegNumber];
1370     }
1371     else
1372     {
1373       hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1374       return HAL_ERROR;
1375     }
1376   }
1377 
1378   return HAL_OK;
1379 }
1380 
1381 /**
1382   * @}
1383   */
1384 
1385 /** @defgroup BSEC_Exported_Functions_Group7 Debug management functions
1386  *  @brief   Debug management functions
1387  *
1388 @verbatim
1389  ===============================================================================
1390                    ##### Debug management functions #####
1391  ===============================================================================
1392     [..]
1393   This subsection provides a set of functions allowing to manage the
1394   debug functionalities.
1395 
1396 @endverbatim
1397   * @{
1398   */
1399 
1400 /**
1401   * @brief  Get the debug request of host debugger.
1402   *
1403   * @param  hbsec   BSEC handle
1404   * @param  pDbgReq  Returned value of debug request. The returned value is @ref BSEC_Debug_Req
1405   *
1406   * @retval HAL_StatusTypeDef HAL Status
1407   */
HAL_BSEC_GetDebugRequest(BSEC_HandleTypeDef * hbsec,uint32_t * pDbgReq)1408 HAL_StatusTypeDef HAL_BSEC_GetDebugRequest(BSEC_HandleTypeDef * hbsec, uint32_t *pDbgReq)
1409 {
1410   /* Check the handle pointer */
1411   if (hbsec == NULL)
1412   {
1413     return HAL_ERROR;
1414   }
1415 
1416   /* Check the address of returned value and instance */
1417   if ((pDbgReq == NULL) || (hbsec->Instance != BSEC))
1418   {
1419     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1420     return HAL_ERROR;
1421   }
1422 
1423   /* Return the debug request */
1424   *pDbgReq = (hbsec->Instance->SR & BSEC_SR_DBGREQ);
1425 
1426   return HAL_OK;
1427 }
1428 
1429 /**
1430   * @brief  Send data via JTAG.
1431   *
1432   * @param  hbsec  BSEC handle
1433   * @param  Data    Data to be sent via JTAG, this parameter can be a value between 0 and 0xFFFFFFFFU
1434   *
1435   * @retval HAL_StatusTypeDef HAL Status
1436   */
HAL_BSEC_SendJTAGData(BSEC_HandleTypeDef * hbsec,uint32_t Data)1437 HAL_StatusTypeDef HAL_BSEC_SendJTAGData(BSEC_HandleTypeDef *hbsec, uint32_t Data)
1438 {
1439   /* Check the handle pointer */
1440   if (hbsec == NULL)
1441   {
1442     return HAL_ERROR;
1443   }
1444 
1445   /* Check the instance */
1446   if (hbsec->Instance != BSEC)
1447   {
1448     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1449     return HAL_ERROR;
1450   }
1451 
1452   /* Send the data */
1453   hbsec->Instance->JTAGOUTR = Data;
1454 
1455   return HAL_OK;
1456 }
1457 
1458 /**
1459   * @brief  Receive data via JTAG.
1460   *
1461   * @param  hbsec  BSEC handle
1462   * @param  pData   Returned value of received data. The returned value is between 0 and 0xFFFFFFFFU
1463   *
1464   * @retval HAL_StatusTypeDef HAL Status
1465   */
HAL_BSEC_ReceiveJTAGData(BSEC_HandleTypeDef * hbsec,uint32_t * pData)1466 HAL_StatusTypeDef HAL_BSEC_ReceiveJTAGData(BSEC_HandleTypeDef * hbsec, uint32_t *pData)
1467 {
1468   /* Check the handle pointer */
1469   if (hbsec == NULL)
1470   {
1471     return HAL_ERROR;
1472   }
1473 
1474   /* Check the address of returned value and instance */
1475   if ((pData == NULL) || (hbsec->Instance != BSEC))
1476   {
1477     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1478     return HAL_ERROR;
1479   }
1480 
1481   /* Return the received data */
1482   *pData = hbsec->Instance->JTAGINR;
1483 
1484   return HAL_OK;
1485 }
1486 
1487 /**
1488   * @brief  Configure the HDPL, secure and non-secure authorization
1489   *         for debugger.
1490   *
1491   * @param  hbsec  BSEC handle
1492   * @param  pCfg    Configuration of debug
1493   *
1494   * @retval HAL_StatusTypeDef HAL Status
1495   */
HAL_BSEC_ConfigDebug(BSEC_HandleTypeDef * hbsec,const BSEC_DebugCfgTypeDef * pCfg)1496 HAL_StatusTypeDef HAL_BSEC_ConfigDebug(BSEC_HandleTypeDef *hbsec, const BSEC_DebugCfgTypeDef *pCfg)
1497 {
1498   uint32_t cfg_reg;
1499 
1500   /* Check the handle pointer */
1501   if (hbsec == NULL)
1502   {
1503     return HAL_ERROR;
1504   }
1505 
1506   /* Check the configuration pointer and instance */
1507   if ((pCfg == NULL) || (hbsec->Instance != BSEC))
1508   {
1509     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1510     return HAL_ERROR;
1511   }
1512 
1513   /* Check the debug configuration */
1514   assert_param(IS_BSEC_OPENDBG(pCfg->HDPL_Open_Dbg));
1515   assert_param(IS_BSEC_SECDBGAUTH(pCfg->Sec_Dbg_Auth));
1516   assert_param(IS_BSEC_NSDBGAUTH(pCfg->NonSec_Dbg_Auth));
1517 
1518   cfg_reg = ((pCfg->HDPL_Open_Dbg   & BSEC_DBGCR_AUTH_HDPL) \
1519            | (pCfg->Sec_Dbg_Auth    & BSEC_DBGCR_AUTH_SEC)  \
1520            | (pCfg->NonSec_Dbg_Auth & BSEC_DBGCR_UNLOCK));
1521 
1522   hbsec->Instance->DBGCR = cfg_reg;
1523 
1524   return HAL_OK;
1525 }
1526 
1527 /**
1528   * @brief  Get the HDPL, secure and non-secure authorization of debug.
1529   *
1530   * @param  hbsec   BSEC handle
1531   * @param  pDbgCfg  Returned value of debug configuration
1532   *
1533   * @retval HAL_StatusTypeDef HAL Status
1534   */
HAL_BSEC_GetDebugConfig(BSEC_HandleTypeDef * hbsec,BSEC_DebugCfgTypeDef * pDbgCfg)1535 HAL_StatusTypeDef HAL_BSEC_GetDebugConfig(BSEC_HandleTypeDef * hbsec, BSEC_DebugCfgTypeDef *pDbgCfg)
1536 {
1537   uint32_t cfg_reg;
1538 
1539   /* Check the handle pointer */
1540   if (hbsec == NULL)
1541   {
1542     return HAL_ERROR;
1543   }
1544 
1545   /* Check the address of returned value and instance */
1546   if ((pDbgCfg == NULL) || (hbsec->Instance != BSEC))
1547   {
1548     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1549     return HAL_ERROR;
1550   }
1551 
1552   /* Get the debug configuration */
1553   cfg_reg = hbsec->Instance->DBGCR;
1554   pDbgCfg->HDPL_Open_Dbg = (cfg_reg & BSEC_DBGCR_AUTH_HDPL);
1555   pDbgCfg->Sec_Dbg_Auth = (cfg_reg & BSEC_DBGCR_AUTH_SEC);
1556   pDbgCfg->NonSec_Dbg_Auth = (cfg_reg & BSEC_DBGCR_UNLOCK);
1557 
1558   return HAL_OK;
1559 }
1560 
1561 /**
1562   * @brief  Lock the debug.
1563   *
1564   * @param  hbsec  BSEC handle
1565   *
1566   * @retval HAL_StatusTypeDef HAL Status
1567   */
HAL_BSEC_LockDebug(BSEC_HandleTypeDef * hbsec)1568 HAL_StatusTypeDef HAL_BSEC_LockDebug(BSEC_HandleTypeDef *hbsec)
1569 {
1570   /* Check the handle pointer */
1571   if (hbsec == NULL)
1572   {
1573     return HAL_ERROR;
1574   }
1575 
1576   /* Check the instance */
1577   if (hbsec->Instance != BSEC)
1578   {
1579     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1580     return HAL_ERROR;
1581   }
1582 
1583   /* Set the value of the debug lock */
1584   MODIFY_REG(hbsec->Instance->AP_UNLOCK, BSEC_AP_UNLOCK_UNLOCK, HAL_BSEC_DEBUG_LOCKED);
1585 
1586   return HAL_OK;
1587 }
1588 
1589 /**
1590   * @brief  Unlock the debug.
1591   *
1592   * @param  hbsec  BSEC handle
1593   *
1594   * @retval HAL_StatusTypeDef HAL Status
1595   */
HAL_BSEC_UnlockDebug(BSEC_HandleTypeDef * hbsec)1596 HAL_StatusTypeDef HAL_BSEC_UnlockDebug(BSEC_HandleTypeDef *hbsec)
1597 {
1598   /* Check the handle pointer */
1599   if (hbsec == NULL)
1600   {
1601     return HAL_ERROR;
1602   }
1603 
1604   /* Check the instance */
1605   if (hbsec->Instance != BSEC)
1606   {
1607     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1608     return HAL_ERROR;
1609   }
1610 
1611   /* Set the value of the debug lock */
1612   MODIFY_REG(hbsec->Instance->AP_UNLOCK, BSEC_AP_UNLOCK_UNLOCK, HAL_BSEC_DEBUG_UNLOCKED);
1613 
1614   return HAL_OK;
1615 }
1616 
1617 /**
1618   * @brief  Get the debug lock status.
1619   *
1620   * @param  hbsec   BSEC handle
1621   * @param  pStatus  Returned value of debug lock status. The returned value is @ref BSEC_Debug_Lock
1622   *
1623   * @retval HAL_StatusTypeDef HAL Status
1624   */
HAL_BSEC_GetDebugLockState(BSEC_HandleTypeDef * hbsec,uint32_t * pStatus)1625 HAL_StatusTypeDef HAL_BSEC_GetDebugLockState(BSEC_HandleTypeDef * hbsec, uint32_t *pStatus)
1626 {
1627   /* Check the handle pointer */
1628   if (hbsec == NULL)
1629   {
1630     return HAL_ERROR;
1631   }
1632 
1633   /* Check the address of returned value and instance */
1634   if ((pStatus == NULL) || (hbsec->Instance != BSEC))
1635   {
1636     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1637     return HAL_ERROR;
1638   }
1639 
1640   /* Get the debug lock status */
1641   *pStatus = (hbsec->Instance->AP_UNLOCK & BSEC_AP_UNLOCK_UNLOCK);
1642 
1643   return HAL_OK;
1644 }
1645 
1646 /**
1647   * @}
1648   */
1649 
1650 /** @defgroup BSEC_Exported_Functions_Group8 DHUK management functions
1651  *  @brief   DHUK management functions
1652  *
1653 @verbatim
1654  ===============================================================================
1655                     ##### DHUK management functions #####
1656  ===============================================================================
1657     [..]
1658   This subsection provides a set of functions allowing to manage the
1659   DHUK (Derived Hardware Unique Key).
1660 
1661 @endverbatim
1662   * @{
1663   */
1664 
1665 /**
1666   * @brief  Get the validity of DHUK.
1667   *
1668   * @param  hbsec     BSEC handle
1669   * @param  pValidity  Returned value of DHUK validity. The returned value is @ref BSEC_DHUK_Validity
1670   *
1671   * @retval HAL_StatusTypeDef HAL Status
1672   */
HAL_BSEC_GetDHUKValidity(BSEC_HandleTypeDef * hbsec,uint32_t * pValidity)1673 HAL_StatusTypeDef HAL_BSEC_GetDHUKValidity(BSEC_HandleTypeDef * hbsec, uint32_t *pValidity)
1674 {
1675   /* Check the handle pointer */
1676   if (hbsec == NULL)
1677   {
1678     return HAL_ERROR;
1679   }
1680 
1681   /* Check the address of returned value and instance */
1682   if ((pValidity == NULL) || (hbsec->Instance != BSEC))
1683   {
1684     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1685     return HAL_ERROR;
1686   }
1687 
1688   /* Get the DHUK validity */
1689   *pValidity = (hbsec->Instance->SR & BSEC_SR_HVALID);
1690 
1691   return HAL_OK;
1692 }
1693 
1694 /**
1695   * @brief  Lock the DHUK use.
1696   *
1697   * @param  hbsec  BSEC handle
1698   *
1699   * @retval HAL_StatusTypeDef HAL Status
1700   */
HAL_BSEC_LockDHUKUse(BSEC_HandleTypeDef * hbsec)1701 HAL_StatusTypeDef HAL_BSEC_LockDHUKUse(BSEC_HandleTypeDef *hbsec)
1702 {
1703   /* Check the handle pointer */
1704   if (hbsec == NULL)
1705   {
1706     return HAL_ERROR;
1707   }
1708 
1709   /* Check the instance */
1710   if (hbsec->Instance != BSEC)
1711   {
1712     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1713     return HAL_ERROR;
1714   }
1715 
1716   /* Set the value of the DHUK lock */
1717   SET_BIT(hbsec->Instance->LOCKR, BSEC_LOCKR_HKLOCK);
1718 
1719   return HAL_OK;
1720 }
1721 
1722 /**
1723   * @brief  Get the DHUK lock status.
1724   *
1725   * @param  hbsec   BSEC handle
1726   * @param  pStatus  Returned value of DHUK lock status. The returned value is @ref BSEC_DHUK_Lock
1727   *
1728   * @retval HAL_StatusTypeDef HAL Status
1729   */
HAL_BSEC_GetDHUKLockStatus(BSEC_HandleTypeDef * hbsec,uint32_t * pStatus)1730 HAL_StatusTypeDef HAL_BSEC_GetDHUKLockStatus(BSEC_HandleTypeDef * hbsec, uint32_t *pStatus)
1731 {
1732   /* Check the handle pointer */
1733   if (hbsec == NULL)
1734   {
1735     return HAL_ERROR;
1736   }
1737 
1738   /* Check the address of returned value and instance */
1739   if ((pStatus == NULL) || (hbsec->Instance != BSEC))
1740   {
1741     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1742     return HAL_ERROR;
1743   }
1744 
1745   /* Get the DHUK lock status */
1746   *pStatus = (hbsec->Instance->LOCKR & BSEC_LOCKR_HKLOCK);
1747 
1748   return HAL_OK;
1749 }
1750 
1751 /**
1752   * @}
1753   */
1754 
1755 /** @defgroup BSEC_Exported_Functions_Group9 Reset management functions
1756  *  @brief   Reset management functions
1757  *
1758 @verbatim
1759  ===============================================================================
1760                     ##### Reset management functions #####
1761  ===============================================================================
1762     [..]
1763   This subsection provides a set of functions allowing to manage the reset.
1764 
1765 @endverbatim
1766   * @{
1767   */
1768 
1769 /**
1770   * @brief  Get the number of hot or warm resets.
1771   *
1772   * @param  hbsec        BSEC handle
1773   * @param  ResetType     Type of the reset, this parameter can be a value of @ref BSEC_Reset_Type
1774   * @param  pResetNumber  Returned value of number of reset. The returned value is between 0 and 0xFFFFFFFFU
1775   *
1776   * @retval HAL_StatusTypeDef HAL Status
1777   */
HAL_BSEC_GetNumberOfResets(BSEC_HandleTypeDef * hbsec,uint32_t ResetType,uint32_t * pResetNumber)1778 HAL_StatusTypeDef HAL_BSEC_GetNumberOfResets(BSEC_HandleTypeDef * hbsec, uint32_t ResetType, uint32_t *pResetNumber)
1779 {
1780   /* Check the handle pointer */
1781   if (hbsec == NULL)
1782   {
1783     return HAL_ERROR;
1784   }
1785 
1786   /* Check the address of returned value and instance */
1787   if ((pResetNumber == NULL) || (hbsec->Instance != BSEC))
1788   {
1789     hbsec->ErrorCode = HAL_BSEC_ERROR_INVALID_PARAM;
1790     return HAL_ERROR;
1791   }
1792 
1793   /* Check the reset type */
1794   assert_param(IS_BSEC_RESETTYPE(ResetType));
1795 
1796   /* Get the correct register value */
1797   if (ResetType == HAL_BSEC_HOT_RESET)
1798   {
1799     *pResetNumber = hbsec->Instance->HRCR;
1800   }
1801   else
1802   {
1803     *pResetNumber = hbsec->Instance->WRCR;
1804   }
1805 
1806   return HAL_OK;
1807 }
1808 
1809 /**
1810   * @}
1811   */
1812 
1813 /**
1814   * @}
1815   */
1816 
1817 /**
1818   * @}
1819   */
1820 #endif /* HAL_BSEC_MODULE_ENABLED */
1821 
1822 /**
1823   * @}
1824   */
1825 
1826