1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file    hw.h
5   * @author  MCD Application Team
6   * @brief   This file contains the interface of STM32 HW drivers.
7   ******************************************************************************
8   * @attention
9   *
10   * Copyright (c) 2024 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   */
19 /* USER CODE END Header */
20 
21 #ifndef HW_H__
22 #define HW_H__
23 
24 #include "stm32wbaxx.h"
25 
26 /* ---------------------------------------------------------------------------
27  *                               General
28  * ---------------------------------------------------------------------------
29  */
30 
31 #ifndef CFG_HW_ERROR_OFFSET
32 #define CFG_HW_ERROR_OFFSET 0
33 #endif
34 
35 /* Return values definition */
36 enum
37 {
38   HW_OK     = 0,
39   HW_BUSY   = 1
40 };
41 
42 /*
43  * HW_Init
44  *
45  * This function must be called once after reset before calling any of the
46  * other HW functions.
47  */
48 extern void HW_Init( void );
49 
50 /*
51  * HW_Delay
52  *
53  * This function is used internally for minimum delays.
54  * The input is given in microseconds and must be strictly higher than 0 (> 0)
55  * and lower than 16000000 (= 16 s).
56  * Be careful that the actual delay can be higher than the one programmed
57  * if the function is interrupted.
58  * The function is declared "weak" and can be overloaded by the user.
59  */
60 extern void HW_Delay( uint32_t delay_us );
61 
62 /*
63  * HW_GetPackageType
64  *
65  * Returns the package type (cf Package Data Register in STM32WB UM)
66  */
67 extern uint32_t HW_GetPackageType( void );
68 
69 /*
70  * HW_Config_HSE
71  */
72 void HW_Config_HSE( uint8_t hsetune );
73 
74 /* ---------------------------------------------------------------------------
75  *                                 AES
76  * ---------------------------------------------------------------------------
77  */
78 
79 /* Mode definitions used for HW_AES_SetKey() function */
80 enum
81 {
82   HW_AES_DEC     = 0,
83   HW_AES_ENC     = 1,
84   HW_AES_REV     = 2,
85   HW_AES_SWAP    = 4
86 };
87 
88 /*
89  * HW_AES_Enable
90  *
91  * Enables the AES hardware block.
92  * If the AES was already in use, the function does nothing and returns 0;
93  * otherwise it returns 1.
94  * Be careful: no re-entrance is ensured for the HW_AES functions
95  */
96 extern int HW_AES_Enable( void );
97 
98 /*
99  * HW_AES_SetKey
100  *
101  * Sets the key used for encryption/decryption.
102  * The "mode" parameter must be set to HW_AES_ENC for encryption and to
103  * HW_AES_DEC for decryption. It can be or-ed with HW_AES_REV for a reveresd
104  * oreder of key bytes, and with HW_AES_SWAP to use data byte swapping mode.
105  */
106 extern void HW_AES_SetKey( uint32_t mode,
107                            const uint8_t* key );
108 
109 /*
110  * HW_AES_Crypt
111  *
112  * Encrypts/decrypts the 16-byte input data ("input"). Result is written in the
113  * 16-byte buffer ("output") allocated by the user.
114  */
115 extern void HW_AES_Crypt( const uint32_t* input,
116                           uint32_t* output );
117 
118 /*
119  * HW_AES_Disable
120  *
121  * Disables the AES hardware block.
122  */
123 extern void HW_AES_Disable( void );
124 
125 /*
126  * HW_AES_InitCcm
127  *
128  * Initilaizes AES for CCM encryption (decrypt = 0) or decryption (decrypt = 1)
129  * Note: B0 and B1 4-word blocks must be provided by user.
130  *
131  */
132 extern void HW_AES_InitCcm( uint8_t decrypt,
133                             const uint8_t* key,
134                             const uint32_t* b0,
135                             const uint32_t* b1 );
136 
137 /*
138  * HW_AES_EndCcm
139  *
140  * Completes CCM processing by computing the authentication tag
141  *
142  */
143 extern void HW_AES_EndCcm( uint8_t tag_length,
144                            uint8_t* tag );
145 
146 /*
147  * HW_AES_SetLast
148  *
149  * Function used in CCM processing to indicate the last block of data in
150  * case of decryption
151  *
152  */
153 extern void HW_AES_SetLast( uint8_t left_length );
154 
155 /* ---------------------------------------------------------------------------
156  *                                 PKA
157  * ---------------------------------------------------------------------------
158  */
159 
160 /*
161  * HW_PKA_Enable
162  *
163  * Enables the PKA hardware block.
164  * If the driver is already in used, the function returns 0 immediately.
165  * If the PKA semaphore is available, this function locks the PKA semaphore,
166  * otherwise it returns 0.
167  * Then, when PKA semaphore is locked, the function enables PKA security,
168  * PKA clock and the block itself.
169  * This function must not be directly called when using P-256 elliptic curve
170  * dedicated functions.
171  * Be careful: no re-entrance is ensured for the HW_PKA functions
172  */
173 extern int HW_PKA_Enable( void );
174 
175 /*
176  * HW_PKA_WriteSingleInput
177  *
178  * Writes one single word into the PKA memory.
179  * This function must not be directly called when using P-256 elliptic curve
180  * dedicated functions.
181  */
182 extern void HW_PKA_WriteSingleInput( uint32_t index,
183                                      uint32_t word );
184 
185 /*
186  * HW_PKA_WriteOperand
187  *
188  * Writes one operand of size 'n' 32-bit words into the PKA memory.
189  * This function must not be directly called when using P-256 elliptic curve
190  * dedicated functions.
191  */
192 extern void HW_PKA_WriteOperand( uint32_t index,
193                                  int size,
194                                  const uint32_t* in );
195 
196 /*
197  * HW_PKA_Start
198  *
199  * Starts the PKA operation with mode defined by the parameter "mode".
200  * This function must not be directly called when using P-256 elliptic curve
201  * dedicated functions.
202  *
203  * "mode" can be one of the LL_PKA_MODE...  definitions that can be found
204  * in "stm32wbxx_ll_pka.h" file.
205  */
206 extern void HW_PKA_Start( uint32_t mode );
207 
208 /*
209  * HW_PKA_EndOfOperation
210  *
211  * Returns 0 if the PKA processing is still active.
212  * Returns a value different from 0 when the PKA processing is complete.
213  */
214 extern int HW_PKA_EndOfOperation( void );
215 
216 /*
217  * HW_PKA_ReadSingleOutput
218  *
219  * Reads one 32-bit word result from the PKA memory.
220  * This function must not be directly called when using P-256 elliptic curve
221  * dedicated functions.
222  */
223 extern uint32_t HW_PKA_ReadSingleOutput( uint32_t index );
224 
225 /*
226  * HW_PKA_ReadResult
227  *
228  * Reads one multi-word result ("size" x 32-bit words) from the PKA memory.
229  * This function must not be directly called when using P-256 elliptic curve
230  * dedicated functions.
231  */
232 extern void HW_PKA_ReadResult( uint32_t index,
233                                int size,
234                                uint32_t* out );
235 
236 /*
237  * HW_PKA_Disable
238  *
239  * Disables the PKA hardware block.
240  * This function disables also the PKA clock and the PKA security.
241  * It then releases the PKA semaphore.
242  */
243 extern void HW_PKA_Disable( void );
244 
245 /*
246  * Notes:
247  *
248  * - this driver uses a semaphore to handle access to the PKA. The index of
249  * the semaphore must be configured with CFG_HW_PKA_SEMID.
250  */
251 
252 /* ---------------------------------------------------------------------------
253  *                               PKA_P256
254  * ---------------------------------------------------------------------------
255  */
256 
257 /*
258  * HW_PKA_P256_StartRangeCheck
259  *
260  * Starts the range check of a point coordinate for P-256 elliptic curve.
261  *
262  * This function sets the parameters in PKA memory and then starts the
263  * processing. The PKA has to be enabled before with HW_PKA_Enable( ).
264  * The user must poll on the result availability by calling the
265  * HW_PKA_EndOfOperation() function.
266  *
267  * The input parameter is one the point coordinate. It must be a vector of
268  * 8 x 32-bit words (32 bytes).
269  *
270  * The check result is retrieved by calling HW_PKA_P256_IsRangeCheckOk().
271  */
272 extern void HW_PKA_P256_StartRangeCheck( const uint32_t* coord );
273 
274 /*
275  * HW_PKA_P256_IsRangeCheckOk
276  *
277  * Reads the result of P-256 range check. This function must only be called
278  * when HW_PKA_EndOfOperation() returns a non-zero value.
279  *
280  * Returns 0 if the check fails ; 1 otherwise.
281  */
282 extern uint32_t HW_PKA_P256_IsRangeCheckOk( void );
283 
284 /*
285  * HW_PKA_P256_StartPointCheck
286  *
287  * Starts the check of a point for P-256 elliptic curve.
288  *
289  * This function sets the parameters in PKA memory and then starts the
290  * processing. The PKA has to be enabled before with HW_PKA_Enable( ).
291  * The user must poll on the result availability by calling the
292  * HW_PKA_EndOfOperation() function.
293  *
294  * The input parameters are the point coordinates. Each parameter must be a
295  * vector of 8 x 32-bit words (32 bytes).
296  *
297  * The check result is retrieved by calling HW_PKA_P256_IsPointCheckOk().
298  */
299 extern void HW_PKA_P256_StartPointCheck( const uint32_t* x,
300                                          const uint32_t* y );
301 
302 /*
303  * HW_PKA_P256_IsPointCheckOk
304  *
305  * Reads the result of P-256 point check. This function must only be called
306  * when HW_PKA_EndOfOperation() returns a non-zero value.
307  *
308  * Returns 0 if the check fails ; 1 otherwise.
309  */
310 extern uint32_t HW_PKA_P256_IsPointCheckOk( void );
311 
312 /*
313  * HW_PKA_P256_StartEccScalarMul
314  *
315  * Starts the PKA scalar multiplication using the P-256 elliptic curve.
316  *
317  * This function sets the parameters in PKA memory and then starts the
318  * processing. The PKA has to be enabled before with HW_PKA_Enable( ).
319  * The user must poll on the result availability by calling the
320  * HW_PKA_EndOfOperation() function.
321  *
322  * The input parameter is the starting point P defined by its 2 coordinates
323  * p_x and p_y, and the scalar k. Each parameter must be a vector of 8 x 32-bit
324  * words (32 bytes).
325  */
326 extern void HW_PKA_P256_StartEccScalarMul( const uint32_t* k,
327                                            const uint32_t* p_x,
328                                            const uint32_t* p_y );
329 
330 /*
331  * HW_PKA_P256_ReadEccScalarMul
332  *
333  * Reads the result of PKA scalar multiplication using the P-256 elliptic
334  * curve. This function must only be called when HW_PKA_EndOfOperation()
335  * returns a non-zero value.
336  *
337  * This function retrieves the result from PKA memory: coordinates of point P,
338  * p_x and p_y, 8 x 32-bit words each (2 times 32 bytes).
339  * Before returning, it disables the PKA block, releasing the PKA semaphore.
340  */
341 extern void HW_PKA_P256_ReadEccScalarMul( uint32_t* p_x,
342                                           uint32_t* p_y );
343 
344 /* ---------------------------------------------------------------------------
345  *                                 RNG
346  * ---------------------------------------------------------------------------
347  */
348 
349 /*
350  * The RNG driver is made to generate the random numbers in background instead
351  * of generating them each time they are needed by the application.
352  * Thus, the function HW_RNG_Process() must be called regularly in background
353  * loop to generate a pool of random numbers. The function HW_RNG_Get() reads
354  * the random numbers from the pool.
355  * The size of the pool must be configured with CFG_HW_RNG_POOL_SIZE.
356  */
357 
358 /* Error codes definition for HW_RNG return values */
359 enum
360 {
361   HW_RNG_CLOCK_ERROR = CFG_HW_ERROR_OFFSET + 0x101,
362   HW_RNG_NOISE_ERROR = CFG_HW_ERROR_OFFSET + 0x102,
363   HW_RNG_UFLOW_ERROR = CFG_HW_ERROR_OFFSET + 0x103,
364 };
365 
366 /* RNG_KERNEL_CLK_ON
367  *
368  * Enable RNG kernel clock.
369  */
370 void RNG_KERNEL_CLK_ON(void);
371 
372 /* RNG_KERNEL_CLK_OFF
373  *
374  * Called when RNG kernel clock may be disabled.
375  * Weak function to be implemented by user.
376  */
377 void RNG_KERNEL_CLK_OFF(void);
378 
379 /* HW_RNG_Disable
380  *
381  * Disables the RNG peripheral and switch off its clock in RCC.
382  */
383 extern void HW_RNG_Disable( void );
384 
385 /* HW_RNG_Start
386  *
387  * Starts the generation of random numbers using the RNG IP. This function has
388  * to be called only once at reset before calling HW_RNG_Get() to retrieve
389  * the generated random values.
390  */
391 extern void HW_RNG_Start( void );
392 
393 /*
394  * HW_RNG_Get
395  *
396  * Retrieves "n" random 32-bit words.
397  * "n" must be in the range [1, CFG_HW_RNG_POOL_SIZE].
398  * The random numbers are written in memory from "val" pointer.
399  * "val" must point to a sufficient memory buffer allocated by the caller.
400  */
401 extern void HW_RNG_Get( uint8_t n,
402                         uint32_t* val );
403 
404 /*
405  * HW_RNG_Process
406  *
407  * This function must be called in a separate task or in "background" loop.
408  * It implements a simple state machine that enables the RNG block,
409  * generates random numbers and then disables the RNG.
410  * It returns 0 (HW_OK) if the low power mode can be entered.
411  * It returns HW_BUSY as long as this function must be called.
412  * In error conditions, it returns one of the following error codes:
413  * - HW_RNG_CLOCK_ERROR for clock error,
414  * - HW_RNG_NOISE_ERROR for noise source error;
415  * the hardware must then be reset.
416  * - HW_RNG_UFLOW_ERROR in case of pool underflow error.
417  */
418 extern int HW_RNG_Process( void );
419 
420 /*
421  * HW_RNG_EnableClock
422  *
423  * This function enables the RNG clock for "other user" than RNG driver itself
424  */
425 extern void HW_RNG_EnableClock( uint8_t user_mask );
426 
427 /*
428  * HW_RNG_DisableClock
429  *
430  * This function disables the RNG clock for "other user" than RNG driver itself
431  */
432 extern void HW_RNG_DisableClock( uint8_t user_mask );
433 
434 extern void HWCB_RNG_Process( void );
435 
436 /* ---------------------------------------------------------------------------
437  *                               GPIO
438  * ---------------------------------------------------------------------------
439  */
440 
441 /* Index definitions used for all GPIO functions */
442 enum
443 {
444   HW_GPIO_DBG          =  0,
445   HW_GPIO_GREEN_LED    = 13,
446   HW_GPIO_RED_LED      = 14,
447   HW_GPIO_BLUE_LED     = 15,
448 };
449 
450 /*
451  * HW_GPIO_Init
452  *
453  * This function initilaizes the GPIO pins used for debug.
454  */
455 extern void HW_GPIO_Init( const uint32_t* dbg_pins );
456 
457 /*
458  * HW_GPIO_Read
459  *
460  * This function reads the output pin which index is given in parameter.
461  * It returns 0 if the pin is low, 1 if the pin is high.
462  */
463 extern uint8_t HW_GPIO_Read( uint8_t index );
464 
465 /*
466  * HW_GPIO_Set
467  *
468  * This function sets to high level the output pin which index is given
469  * in parameter.
470  */
471 extern void HW_GPIO_Set( uint8_t index );
472 
473 /*
474  * HW_GPIO_Reset
475  *
476  * This function resets to low level the output pin which index is given
477  * in parameter.
478  */
479 extern void HW_GPIO_Reset( uint8_t index );
480 
481 extern void GPIO_SetDebug( int gpio_pin,
482                            int pin_value );
483 
484 /* ---------------------------------------------------------------------------
485  *                             OTP
486  * ---------------------------------------------------------------------------
487  */
488 
489 typedef __PACKED_STRUCT
490 {
491   uint8_t additional_data[8]; /*!< 64 bits of data to fill OTP slot */
492   uint8_t bd_address[6];      /*!< Bluetooth Device Address*/
493   uint8_t hsetune;            /*!< Load capacitance to be applied on HSE pad */
494   uint8_t index;              /*!< Structure index */
495 } HW_OTP_data_t;
496 
497 /*
498  * HW_OTP_Read
499  *
500  * Read the OTP
501  *
502  */
503 int HW_OTP_Read( uint8_t index,
504                  HW_OTP_data_t** data );
505 
506 /*
507  * HW_OTP_Write
508  *
509  * ReadWrite the OTP
510  *
511  */
512 int HW_OTP_Write( uint8_t* additional_data,
513                   uint8_t* bd_address,
514                   uint8_t hsetune,
515                   uint8_t index );
516 
517 #endif /* HW_H__ */
518