1 /**
2 ******************************************************************************
3 * @file stm32mp1xx_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) 2019 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 31
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 31. 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 31
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 31
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 "stm32mp1xx_hal.h"
89
90 /** @addtogroup STM32MP1xx_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 #if defined(DUAL_CORE)
104 #ifndef HSEM_R_MASTERID
105 #define HSEM_R_MASTERID HSEM_R_COREID
106 #endif
107
108 #ifndef HSEM_RLR_MASTERID
109 #define HSEM_RLR_MASTERID HSEM_RLR_COREID
110 #endif
111
112 #ifndef HSEM_CR_MASTERID
113 #define HSEM_CR_MASTERID HSEM_CR_COREID
114 #endif
115 #endif /* DUAL_CORE */
116 /* Private macro -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 /* Private functions ---------------------------------------------------------*/
120 /* Exported functions --------------------------------------------------------*/
121
122 /** @defgroup HSEM_Exported_Functions HSEM Exported Functions
123 * @{
124 */
125
126 /** @defgroup HSEM_Exported_Functions_Group1 Take and Release functions
127 * @brief HSEM Take and Release functions
128 *
129 @verbatim
130 ==============================================================================
131 ##### HSEM Take and Release functions #####
132 ==============================================================================
133 [..] This section provides functions allowing to:
134 (+) Take a semaphore with 2 Step method
135 (+) Fast Take a semaphore with 1 Step method
136 (+) Check semaphore state Taken or not
137 (+) Release a semaphore
138 (+) Release all semaphore at once
139
140 @endverbatim
141 * @{
142 */
143
144
145 /**
146 * @brief Take a semaphore in 2 Step mode.
147 * @param SemID: semaphore ID from 0 to 31
148 * @param ProcessID: Process ID from 0 to 255
149 * @retval HAL status
150 */
HAL_HSEM_Take(uint32_t SemID,uint32_t ProcessID)151 HAL_StatusTypeDef HAL_HSEM_Take(uint32_t SemID, uint32_t ProcessID)
152 {
153 /* Check the parameters */
154 assert_param(IS_HSEM_SEMID(SemID));
155 assert_param(IS_HSEM_PROCESSID(ProcessID));
156
157 #if USE_MULTI_CORE_SHARED_CODE != 0U
158 /* First step write R register with MasterID, processID and take bit=1*/
159 HSEM->R[SemID] = ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK);
160
161 /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
162 if (HSEM->R[SemID] == ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK))
163 {
164 /*take success when MasterID and ProcessID match and take bit set*/
165 return HAL_OK;
166 }
167 #else
168 /* First step write R register with MasterID, processID and take bit=1*/
169 HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK);
170
171 /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
172 if (HSEM->R[SemID] == (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK))
173 {
174 /*take success when MasterID and ProcessID match and take bit set*/
175 return HAL_OK;
176 }
177 #endif
178
179 /* Semaphore take fails*/
180 return HAL_ERROR;
181 }
182
183 /**
184 * @brief Fast Take a semaphore with 1 Step mode.
185 * @param SemID: semaphore ID from 0 to 31
186 * @retval HAL status
187 */
HAL_HSEM_FastTake(uint32_t SemID)188 HAL_StatusTypeDef HAL_HSEM_FastTake(uint32_t SemID)
189 {
190 /* Check the parameters */
191 assert_param(IS_HSEM_SEMID(SemID));
192
193 #if USE_MULTI_CORE_SHARED_CODE != 0U
194 /* Read the RLR register to take the semaphore */
195 if (HSEM->RLR[SemID] == (((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_RLR_MASTERID) | HSEM_RLR_LOCK))
196 {
197 /*take success when MasterID match and take bit set*/
198 return HAL_OK;
199 }
200 #else
201 /* Read the RLR register to take the semaphore */
202 if (HSEM->RLR[SemID] == (HSEM_CR_COREID_CURRENT | HSEM_RLR_LOCK))
203 {
204 /*take success when MasterID match and take bit set*/
205 return HAL_OK;
206 }
207 #endif
208
209 /* Semaphore take fails */
210 return HAL_ERROR;
211 }
212 /**
213 * @brief Check semaphore state Taken or not.
214 * @param SemID: semaphore ID
215 * @retval HAL HSEM state
216 */
HAL_HSEM_IsSemTaken(uint32_t SemID)217 uint32_t HAL_HSEM_IsSemTaken(uint32_t SemID)
218 {
219 return (((HSEM->R[SemID] & HSEM_R_LOCK) != 0U) ? 1UL : 0UL);
220 }
221
222
223 /**
224 * @brief Release a semaphore.
225 * @param SemID: semaphore ID from 0 to 31
226 * @param ProcessID: Process ID from 0 to 255
227 * @retval None
228 */
HAL_HSEM_Release(uint32_t SemID,uint32_t ProcessID)229 void HAL_HSEM_Release(uint32_t SemID, uint32_t ProcessID)
230 {
231 /* Check the parameters */
232 assert_param(IS_HSEM_SEMID(SemID));
233 assert_param(IS_HSEM_PROCESSID(ProcessID));
234
235 /* Clear the semaphore by writing to the R register : the MasterID , the processID and take bit = 0 */
236 HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT);
237
238 }
239
240 /**
241 * @brief Release All semaphore used by a given Master .
242 * @param Key: Semaphore Key , value from 0 to 0xFFFF
243 * @param CoreID: CoreID of the CPU that is using semaphores to be released
244 * @retval None
245 */
HAL_HSEM_ReleaseAll(uint32_t Key,uint32_t CoreID)246 void HAL_HSEM_ReleaseAll(uint32_t Key, uint32_t CoreID)
247 {
248 assert_param(IS_HSEM_KEY(Key));
249 assert_param(IS_HSEM_COREID(CoreID));
250
251 HSEM->CR = ((Key << HSEM_CR_KEY_Pos) | (CoreID << HSEM_CR_COREID_Pos));
252 }
253
254 /**
255 * @}
256 */
257
258 /** @defgroup HSEM_Exported_Functions_Group2 HSEM Set and Get Key functions
259 * @brief HSEM Set and Get Key functions.
260 *
261 @verbatim
262 ==============================================================================
263 ##### HSEM Set and Get Key functions #####
264 ==============================================================================
265 [..] This section provides functions allowing to:
266 (+) Set semaphore Key
267 (+) Get semaphore Key
268 @endverbatim
269
270 * @{
271 */
272
273 /**
274 * @brief Set semaphore Key .
275 * @param Key: Semaphore Key , value from 0 to 0xFFFF
276 * @retval None
277 */
HAL_HSEM_SetClearKey(uint32_t Key)278 void HAL_HSEM_SetClearKey(uint32_t Key)
279 {
280 assert_param(IS_HSEM_KEY(Key));
281
282 MODIFY_REG(HSEM->KEYR, HSEM_KEYR_KEY, (Key << HSEM_KEYR_KEY_Pos));
283
284 }
285
286 /**
287 * @brief Get semaphore Key .
288 * @retval Semaphore Key , value from 0 to 0xFFFF
289 */
HAL_HSEM_GetClearKey(void)290 uint32_t HAL_HSEM_GetClearKey(void)
291 {
292 return (HSEM->KEYR >> HSEM_KEYR_KEY_Pos);
293 }
294
295 /**
296 * @}
297 */
298
299 /** @defgroup HSEM_Exported_Functions_Group3 HSEM IRQ handler management
300 * @brief HSEM Notification functions.
301 *
302 @verbatim
303 ==============================================================================
304 ##### HSEM IRQ handler management and Notification functions #####
305 ==============================================================================
306 [..] This section provides HSEM IRQ handler and Notification function.
307
308 @endverbatim
309 * @{
310 */
311
312 /**
313 * @brief Activate Semaphore release Notification for a given Semaphores Mask .
314 * @param SemMask: Mask of Released semaphores
315 * @retval Semaphore Key
316 */
HAL_HSEM_ActivateNotification(uint32_t SemMask)317 void HAL_HSEM_ActivateNotification(uint32_t SemMask)
318 {
319 #if USE_MULTI_CORE_SHARED_CODE != 0U
320 /*enable the semaphore mask interrupts */
321 if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
322 {
323 /*Use interrupt line 0 for CPU1 Master */
324 HSEM->C1IER |= SemMask;
325 }
326 else /* HSEM_CPU2_COREID */
327 {
328 /*Use interrupt line 1 for CPU2 Master*/
329 HSEM->C2IER |= SemMask;
330 }
331 #else
332 HSEM_COMMON->IER |= SemMask;
333 #endif
334 }
335
336 /**
337 * @brief Deactivate Semaphore release Notification for a given Semaphores Mask .
338 * @param SemMask: Mask of Released semaphores
339 * @retval Semaphore Key
340 */
HAL_HSEM_DeactivateNotification(uint32_t SemMask)341 void HAL_HSEM_DeactivateNotification(uint32_t SemMask)
342 {
343 #if USE_MULTI_CORE_SHARED_CODE != 0U
344 /*enable the semaphore mask interrupts */
345 if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
346 {
347 /*Use interrupt line 0 for CPU1 Master */
348 HSEM->C1IER &= ~SemMask;
349 }
350 else /* HSEM_CPU2_COREID */
351 {
352 /*Use interrupt line 1 for CPU2 Master*/
353 HSEM->C2IER &= ~SemMask;
354 }
355 #else
356 HSEM_COMMON->IER &= ~SemMask;
357 #endif
358 }
359
360 /**
361 * @brief This function handles HSEM interrupt request
362 * @retval None
363 */
HAL_HSEM_IRQHandler(void)364 void HAL_HSEM_IRQHandler(void)
365 {
366 uint32_t statusreg;
367 #if USE_MULTI_CORE_SHARED_CODE != 0U
368 if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
369 {
370 /* Get the list of masked freed semaphores*/
371 statusreg = HSEM->C1MISR; /*Use interrupt line 0 for CPU1 Master*/
372
373 /*Disable Interrupts*/
374 HSEM->C1IER &= ~((uint32_t)statusreg);
375
376 /*Clear Flags*/
377 HSEM->C1ICR = ((uint32_t)statusreg);
378 }
379 else /* HSEM_CPU2_COREID */
380 {
381 /* Get the list of masked freed semaphores*/
382 statusreg = HSEM->C2MISR;/*Use interrupt line 1 for CPU2 Master*/
383
384 /*Disable Interrupts*/
385 HSEM->C2IER &= ~((uint32_t)statusreg);
386
387 /*Clear Flags*/
388 HSEM->C2ICR = ((uint32_t)statusreg);
389 }
390 #else
391 /* Get the list of masked freed semaphores*/
392 statusreg = HSEM_COMMON->MISR;
393
394 /*Disable Interrupts*/
395 HSEM_COMMON->IER &= ~((uint32_t)statusreg);
396
397 /*Clear Flags*/
398 HSEM_COMMON->ICR = ((uint32_t)statusreg);
399
400 #endif
401 /* Call FreeCallback */
402 HAL_HSEM_FreeCallback(statusreg);
403 }
404
405 /**
406 * @brief Semaphore Released Callback.
407 * @param SemMask: Mask of Released semaphores
408 * @retval None
409 */
HAL_HSEM_FreeCallback(uint32_t SemMask)410 __weak void HAL_HSEM_FreeCallback(uint32_t SemMask)
411 {
412 /* Prevent unused argument(s) compilation warning */
413 UNUSED(SemMask);
414
415 /* NOTE : This function should not be modified, when the callback is needed,
416 the HAL_HSEM_FreeCallback can be implemented in the user file
417 */
418 }
419
420 /**
421 * @}
422 */
423
424 /**
425 * @}
426 */
427
428 #endif /* HAL_HSEM_MODULE_ENABLED */
429 /**
430 * @}
431 */
432
433 /**
434 * @}
435 */
436