1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_hal_hsem.c
4   * @author  MCD Application Team
5   * @brief   HSEM HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the semaphore peripheral:
8   *           + Semaphore Take function (2-Step Procedure) , non blocking
9   *           + Semaphore FastTake function (1-Step Procedure) , non blocking
10   *           + Semaphore Status check
11   *           + Semaphore Clear Key Set and Get
12   *           + Release and release all functions
13   *           + Semaphore notification enabling and disabling and callnack functions
14   *           + IRQ handler management
15   *
16   *
17   ******************************************************************************
18   * @attention
19   *
20   * Copyright (c) 2022 STMicroelectronics.
21   * All rights reserved.
22   *
23   * This software is licensed under terms that can be found in the LICENSE file
24   * in the root directory of this software component.
25   * If no LICENSE file comes with this software, it is provided AS-IS.
26   *
27   ******************************************************************************
28   @verbatim
29   ==============================================================================
30                      ##### How to use this driver #####
31   ==============================================================================
32   [..]
33       (#)Take a semaphore In 2-Step mode Using function HAL_HSEM_Take. This function takes as parameters :
34            (++) the semaphore ID from 0 to 15
35            (++) the process ID from 0 to 255
36       (#) Fast Take semaphore In 1-Step mode Using function HAL_HSEM_FastTake. This function takes as parameter :
37            (++) the semaphore ID from 0_ID to 15. Note that the process ID value is implicitly assumed as zero
38       (#) Check if a semaphore is Taken using function HAL_HSEM_IsSemTaken. This function takes as parameter :
39           (++) the semaphore ID from 0_ID to 15
40           (++) It returns 1 if the given semaphore is taken otherwise (Free) zero
41       (#)Release a semaphore using function with HAL_HSEM_Release. This function takes as parameters :
42            (++) the semaphore ID from 0 to 15
43            (++) the process ID from 0 to 255:
44            (++) Note: If ProcessID and MasterID match, semaphore is freed, and an interrupt
45          may be generated when enabled (notification activated). If ProcessID or MasterID does not match,
46          semaphore remains taken (locked)
47 
48       (#)Release all semaphores at once taken by a given Master using function HAL_HSEM_Release_All
49           This function takes as parameters :
50            (++) the Release Key (value from 0 to 0xFFFF) can be Set or Get respectively by
51               HAL_HSEM_SetClearKey() or HAL_HSEM_GetClearKey functions
52            (++) the Master ID:
53            (++) Note: If the Key and MasterID match, all semaphores taken by the given CPU that corresponds
54            to MasterID  will be freed, and an interrupt may be generated when enabled (notification activated). If the
55            Key or the MasterID doesn't match, semaphores remains taken (locked)
56 
57       (#)Semaphores Release all key functions:
58          (++)  HAL_HSEM_SetClearKey() to set semaphore release all Key
59          (++)  HAL_HSEM_GetClearKey() to get release all Key
60       (#)Semaphores notification functions :
61          (++)  HAL_HSEM_ActivateNotification to activate a notification callback on
62                a given semaphores Mask (bitfield). When one or more semaphores defined by the mask are released
63                the callback HAL_HSEM_FreeCallback will be asserted giving as parameters a mask of the released
64                semaphores (bitfield).
65 
66          (++)  HAL_HSEM_DeactivateNotification to deactivate the notification of a given semaphores Mask (bitfield).
67          (++) See the description of the macro __HAL_HSEM_SEMID_TO_MASK to check how to calculate a semaphore mask
68                 Used by the notification functions
69      *** HSEM HAL driver macros list ***
70      =============================================
71      [..] Below the list of most used macros in HSEM HAL driver.
72 
73       (+) __HAL_HSEM_SEMID_TO_MASK: Helper macro to convert a Semaphore ID to a Mask.
74       [..] Example of use :
75       [..] mask = __HAL_HSEM_SEMID_TO_MASK(8)  |  __HAL_HSEM_SEMID_TO_MASK(21) | __HAL_HSEM_SEMID_TO_MASK(25).
76       [..] All next macros take as parameter a semaphore Mask (bitfiled) that can be constructed using  __HAL_HSEM_SEMID_TO_MASK as the above example.
77       (+) __HAL_HSEM_ENABLE_IT: Enable the specified semaphores Mask interrupts.
78       (+) __HAL_HSEM_DISABLE_IT: Disable the specified semaphores Mask interrupts.
79       (+) __HAL_HSEM_GET_IT: Checks whether the specified semaphore interrupt has occurred or not.
80       (+) __HAL_HSEM_GET_FLAG: Get the semaphores status release flags.
81       (+) __HAL_HSEM_CLEAR_FLAG: Clear the semaphores status release flags.
82 
83   @endverbatim
84   ******************************************************************************
85   */
86 
87 /* Includes ------------------------------------------------------------------*/
88 #include "stm32wbaxx_hal.h"
89 
90 /** @addtogroup STM32WBAxx_HAL_Driver
91   * @{
92   */
93 
94 /** @defgroup HSEM HSEM
95   * @brief HSEM HAL module driver
96   * @{
97   */
98 
99 #ifdef HAL_HSEM_MODULE_ENABLED
100 
101 /* Private typedef -----------------------------------------------------------*/
102 /* Private define ------------------------------------------------------------*/
103 /** @defgroup HSEM_Private_Constants  HSEM Private Constants
104   * @{
105   */
106 
107 #ifndef HSEM_R_MASTERID
108 #define HSEM_R_MASTERID HSEM_R_LOCKID
109 #endif
110 
111 /**
112   * @}
113   */
114 /* Private macro -------------------------------------------------------------*/
115 /* Private variables ---------------------------------------------------------*/
116 /* Private function prototypes -----------------------------------------------*/
117 /* Private functions ---------------------------------------------------------*/
118 /* Exported functions --------------------------------------------------------*/
119 
120 /** @defgroup HSEM_Exported_Functions  HSEM Exported Functions
121   * @{
122   */
123 
124 /** @defgroup HSEM_Exported_Functions_Group1 Take and Release functions
125   *  @brief    HSEM Take and Release functions
126   *
127 @verbatim
128  ==============================================================================
129               ##### HSEM Take and Release functions #####
130  ==============================================================================
131 [..] This section provides functions allowing to:
132       (+) Take a semaphore with 2 Step method
133       (+) Fast Take a semaphore with 1 Step method
134       (+) Check semaphore state Taken or not
135       (+) Release a semaphore
136       (+) Release all semaphore at once
137 
138 @endverbatim
139   * @{
140   */
141 
142 
143 /**
144   * @brief  Take a semaphore in 2 Step mode.
145   * @param  SemID: semaphore ID from 0 to 15
146   * @param  ProcessID: Process ID from 0 to 255
147   * @param  Attribute: semaphore privilege and security attributes
148   *          This parameter can be one of the following values:
149   *            @arg HSEM_NSEC_PRIV:  NSecure and Privileged attribute
150   *            @arg HSEM_NSEC_NPRIV: NSecure and NPrivileged attribute
151   *            @arg HSEM_SEC_PRIV:   Secure and Privileged attribute
152   *            @arg HSEM_SEC_NPRIV:  Secure and NPrivileged attribute
153   * @retval HAL status
154   */
HAL_HSEM_Take(uint32_t SemID,uint32_t ProcessID,uint32_t Attribute)155 HAL_StatusTypeDef  HAL_HSEM_Take(uint32_t SemID, uint32_t ProcessID, uint32_t Attribute)
156 {
157   /* Check the parameters */
158   assert_param(IS_HSEM_SEMID(SemID));
159   assert_param(IS_HSEM_PROCESSID(ProcessID));
160 
161   /* First step  write R register with MasterID, processID, privilege and security attributes and take bit=1*/
162   HSEM->R[SemID] = (ProcessID | HSEM_CR_LOCKID_CURRENT | HSEM_R_LOCK | Attribute);
163 
164   /* second step : read the R register . Take achieved if privilege and security attributes, MasterID and processID match and take bit set to 1 */
165   if (HSEM->R[SemID] == (ProcessID | HSEM_CR_LOCKID_CURRENT | HSEM_R_LOCK | Attribute))
166   {
167     /*take success when MasterID and ProcessID match and take bit set*/
168     return HAL_OK;
169   }
170 
171   /* Semaphore take fails*/
172   return HAL_ERROR;
173 }
174 
175 /**
176   * @brief  Fast Take a semaphore with 1 Step mode.
177   * @param  SemID: semaphore ID from 0 to 15
178   * @param  Attribute: semaphore privilege and security attributes
179   *          This parameter can be one of the following values:
180   *            @arg HSEM_NSEC_PRIV:  NSecure and Privileged attribute
181   *            @arg HSEM_NSEC_NPRIV: NSecure and NPrivileged attribute
182   *            @arg HSEM_SEC_PRIV:   Secure and Privileged attribute
183   *            @arg HSEM_SEC_NPRIV:  Secure and NPrivileged attribute
184   * @retval HAL status
185   */
HAL_HSEM_FastTake(uint32_t SemID,uint32_t Attribute)186 HAL_StatusTypeDef  HAL_HSEM_FastTake(uint32_t SemID, uint32_t Attribute)
187 {
188   /* Check the parameters */
189   assert_param(IS_HSEM_SEMID(SemID));
190 
191   /* Read the RLR register to take the semaphore */
192   if (HSEM->RLR[SemID] == (HSEM_CR_LOCKID_CURRENT | HSEM_R_LOCK | Attribute))
193   {
194     /*take success when MasterID match and take bit set*/
195     return HAL_OK;
196   }
197 
198   /* Semaphore take fails */
199   return HAL_ERROR;
200 }
201 /**
202   * @brief  Check semaphore state Taken or not.
203   * @param  SemID: semaphore ID
204   * @retval HAL HSEM state
205   */
HAL_HSEM_IsSemTaken(uint32_t SemID)206 uint32_t HAL_HSEM_IsSemTaken(uint32_t SemID)
207 {
208   return (((HSEM->R[SemID] & HSEM_R_LOCK) != 0U) ? 1UL : 0UL);
209 }
210 
211 
212 /**
213   * @brief  Release a semaphore.
214   * @param  SemID: semaphore ID from 0 to 15
215   * @param  ProcessID: Process ID from 0 to 255
216   * @param  Attribute: semaphore privilege and security attributes
217   *          This parameter can be one of the following values:
218   *            @arg HSEM_NSEC_PRIV:  NSecure and Privileged attribute
219   *            @arg HSEM_NSEC_NPRIV: NSecure and NPrivileged attribute
220   *            @arg HSEM_SEC_PRIV:   Secure and Privileged attribute
221   *            @arg HSEM_SEC_NPRIV:  Secure and NPrivileged attribute
222   * @retval None
223   */
HAL_HSEM_Release(uint32_t SemID,uint32_t ProcessID,uint32_t Attribute)224 void  HAL_HSEM_Release(uint32_t SemID, uint32_t ProcessID, uint32_t Attribute)
225 {
226   /* Check the parameters */
227   assert_param(IS_HSEM_SEMID(SemID));
228   assert_param(IS_HSEM_PROCESSID(ProcessID));
229 
230   /* Clear the semaphore by writing to the R register : the MasterID , the processID and take bit = 0  */
231   HSEM->R[SemID] = (ProcessID | HSEM_CR_LOCKID_CURRENT | Attribute);
232 
233 }
234 
235 /**
236   * @brief  Release All semaphore used by a given Master .
237   * @param  Key: Semaphore Key , value from 0 to 0xFFFF
238   * @param  CoreID: CoreID of the CPU that is using semaphores to be released
239   * @param  Attribute: semaphore privilege and security attributes
240   *          This parameter can be one of the following values:
241   *            @arg HSEM_NSEC_PRIV:  NSecure and Privileged attribute
242   *            @arg HSEM_NSEC_NPRIV: NSecure and NPrivileged attribute
243   *            @arg HSEM_SEC_PRIV:   Secure and Privileged attribute
244   *            @arg HSEM_SEC_NPRIV:  Secure and NPrivileged attribute
245   * @retval None
246   */
HAL_HSEM_ReleaseAll(uint32_t Key,uint32_t CoreID,uint32_t Attribute)247 void  HAL_HSEM_ReleaseAll(uint32_t Key, uint32_t CoreID, uint32_t Attribute)
248 {
249   assert_param(IS_HSEM_KEY(Key));
250   assert_param(IS_HSEM_LOCKID(CoreID));
251 
252   HSEM->CR = ((Key << HSEM_CR_KEY_Pos) | (CoreID << HSEM_CR_LOCKID_Pos) | Attribute);
253 }
254 
255 /**
256   * @}
257   */
258 
259 /** @defgroup HSEM_Exported_Functions_Group2 HSEM Set and Get Key functions
260   *  @brief    HSEM Set and Get Key functions.
261   *
262 @verbatim
263   ==============================================================================
264               ##### HSEM Set and Get Key functions #####
265   ==============================================================================
266     [..]  This section provides functions allowing to:
267       (+) Set semaphore Key
268       (+) Get semaphore Key
269 @endverbatim
270 
271   * @{
272   */
273 
274 /**
275   * @brief  Set semaphore Key .
276   * @param  Key: Semaphore Key , value from 0 to 0xFFFF
277   * @retval None
278   */
HAL_HSEM_SetClearKey(uint32_t Key)279 void  HAL_HSEM_SetClearKey(uint32_t Key)
280 {
281   assert_param(IS_HSEM_KEY(Key));
282 
283   MODIFY_REG(HSEM->KEYR, HSEM_KEYR_KEY, (Key << HSEM_KEYR_KEY_Pos));
284 
285 }
286 
287 /**
288   * @brief  Get semaphore Key .
289   * @retval Semaphore Key , value from 0 to 0xFFFF
290   */
HAL_HSEM_GetClearKey(void)291 uint32_t HAL_HSEM_GetClearKey(void)
292 {
293   return (HSEM->KEYR >> HSEM_KEYR_KEY_Pos);
294 }
295 
296 /**
297   * @}
298   */
299 
300 /** @defgroup HSEM_Exported_Functions_Group3 HSEM IRQ handler management
301   *  @brief    HSEM Notification functions.
302   *
303 @verbatim
304   ==============================================================================
305       ##### HSEM IRQ handler management and Notification functions #####
306   ==============================================================================
307 [..]  This section provides HSEM IRQ handler and Notification function.
308 
309 @endverbatim
310   * @{
311   */
312 
313 /**
314   * @brief  Activate Semaphore release Notification for a given Semaphores Mask .
315   * @param  SemMask: Mask of Released semaphores
316   * @retval Semaphore Key
317   */
HAL_HSEM_ActivateNotification(uint32_t SemMask)318 void HAL_HSEM_ActivateNotification(uint32_t SemMask)
319 {
320 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
321   HSEM_COMMON->SIER |= SemMask;
322 #else
323   HSEM_COMMON->IER |= SemMask;
324 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
325 }
326 
327 /**
328   * @brief  Deactivate Semaphore release Notification for a given Semaphores Mask .
329   * @param  SemMask: Mask of Released semaphores
330   * @retval Semaphore Key
331   */
HAL_HSEM_DeactivateNotification(uint32_t SemMask)332 void HAL_HSEM_DeactivateNotification(uint32_t SemMask)
333 {
334 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
335   HSEM_COMMON->SIER &= ~SemMask;
336 #else
337   HSEM_COMMON->IER &= ~SemMask;
338 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
339 }
340 
341 /**
342   * @brief  This function handles HSEM interrupt request
343   * @retval None
344   */
HAL_HSEM_IRQHandler(void)345 void HAL_HSEM_IRQHandler(void)
346 {
347   uint32_t statusreg;
348 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
349   /* Get the list of masked freed semaphores*/
350   statusreg = HSEM_COMMON->SMISR;
351 
352   /*Disable Interrupts*/
353   HSEM_COMMON->SIER &= ~((uint32_t)statusreg);
354 
355   /*Clear Flags*/
356   HSEM_COMMON->SICR = ((uint32_t)statusreg);
357 #else
358   /* Get the list of masked freed semaphores*/
359   statusreg = HSEM_COMMON->MISR;
360 
361   /*Disable Interrupts*/
362   HSEM_COMMON->IER &= ~((uint32_t)statusreg);
363 
364   /*Clear Flags*/
365   HSEM_COMMON->ICR = ((uint32_t)statusreg);
366 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
367   /* Call FreeCallback */
368   HAL_HSEM_FreeCallback(statusreg);
369 }
370 
371 /**
372   * @brief Semaphore Released Callback.
373   * @param SemMask: Mask of Released semaphores
374   * @retval None
375   */
HAL_HSEM_FreeCallback(uint32_t SemMask)376 __weak void HAL_HSEM_FreeCallback(uint32_t SemMask)
377 {
378   /* Prevent unused argument(s) compilation warning */
379   UNUSED(SemMask);
380 
381   /* NOTE : This function should not be modified, when the callback is needed,
382   the HAL_HSEM_FreeCallback can be implemented in the user file
383     */
384 }
385 
386 /** @defgroup HSEM_Exported_Functions_Group4 HSEM Security and privilege management
387   *  @brief    HSEM Attributes functions.
388   *
389 @verbatim
390   ==============================================================================
391       ##### Secure and privilege setting clearing reading functions #####
392   ==============================================================================
393 [..]  This section provides HSEM attributes setting and reading functions.
394 
395 @endverbatim
396   * @{
397   */
398 
399 #if defined(HSEM_SECCFGR_SEC0)
400 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
401 /**
402   * @brief  Set semaphore access limited to secure access only.
403   * @param  SemMask: Mask of secure semaphores
404   * @retval None
405   */
HAL_HSEM_SetSemaphoreSecure(uint32_t SemMask)406 void HAL_HSEM_SetSemaphoreSecure(uint32_t SemMask)
407 {
408   SET_BIT(HSEM->SECCFGR, SemMask);
409 }
410 
411 /**
412   * @brief  Allow secure and non-secure access to semaphore.
413   * @param  SemMask: Mask of non-secure semaphores
414   * @retval None
415   */
HAL_HSEM_SetSemaphoreNonSecure(uint32_t SemMask)416 void HAL_HSEM_SetSemaphoreNonSecure(uint32_t SemMask)
417 {
418   CLEAR_BIT(HSEM->SECCFGR, SemMask);
419 }
420 #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
421 
422 /**
423   * @brief  Get semaphores with access limited to secure access only.
424   * @retval Mask of secure semaphores
425   */
HAL_HSEM_GetSemaphoreSecure(void)426 uint32_t HAL_HSEM_GetSemaphoreSecure(void)
427 {
428   return HSEM->SECCFGR;
429 }
430 #endif /* (HSEM_SECCFGR_SEC0) */
431 
432 #if defined(HSEM_PRIVCFGR_PRIV0)
433 /**
434   * @brief  Set semaphore access limited to privilege access only.
435   * @param  SemMask: Mask of privilege semaphores
436   * @retval None
437   */
HAL_HSEM_SetSemaphorePrivilege(uint32_t SemMask)438 void HAL_HSEM_SetSemaphorePrivilege(uint32_t SemMask)
439 {
440   SET_BIT(HSEM->PRIVCFGR, SemMask);
441 }
442 
443 /**
444   * @brief  Allow privilege and non-privilege access to semaphore.
445   * @param  SemMask: Mask of non-privilege semaphores
446   * @retval None
447   */
HAL_HSEM_SetSemaphoreNonPrivilege(uint32_t SemMask)448 void HAL_HSEM_SetSemaphoreNonPrivilege(uint32_t SemMask)
449 {
450   CLEAR_BIT(HSEM->PRIVCFGR, SemMask);
451 }
452 
453 /**
454   * @brief  Get semaphores with access limited to privilege access only.
455   * @retval Mask of privilege semaphores
456   */
HAL_HSEM_GetSemaphorePrivilege(void)457 uint32_t HAL_HSEM_GetSemaphorePrivilege(void)
458 {
459   return HSEM->PRIVCFGR;
460 }
461 #endif /* (HSEM_PRIVCFGR_PRIV0) */
462 
463 /**
464   * @}
465   */
466 
467 /**
468   * @}
469   */
470 
471 /**
472   * @}
473   */
474 
475 #endif /* HAL_HSEM_MODULE_ENABLED */
476 /**
477   * @}
478   */
479 
480 /**
481   * @}
482   */
483