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