summaryrefslogtreecommitdiff
path: root/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_hsem.c
blob: b0f6e1910abdcaf7003d59ee644b99840c8ee95e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
/**
  ******************************************************************************
  * @file    stm32h7xx_hal_hsem.c
  * @author  MCD Application Team
  * @brief   HSEM HAL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the semaphore peripheral:
  *           + Semaphore Take function (2-Step Procedure) , non blocking
  *           + Semaphore FastTake function (1-Step Procedure) , non blocking
  *           + Semaphore Status check
  *           + Semaphore Clear Key Set and Get
  *           + Release and release all functions
  *           + Semaphore notification enabling and disabling and callnack functions
  *           + IRQ handler management
  *
  *
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  @verbatim
  ==============================================================================
                     ##### How to use this driver #####
  ==============================================================================
  [..]
      (#)Take a semaphore In 2-Step mode Using function HAL_HSEM_Take. This function takes as parameters :
           (++) the semaphore ID from 0 to 31
           (++) the process ID from 0 to 255
      (#) Fast Take semaphore In 1-Step mode Using function HAL_HSEM_FastTake. This function takes as parameter :
           (++) the semaphore ID from 0_ID to 31. Note that the process ID value is implicitly assumed as zero
      (#) Check if a semaphore is Taken using function HAL_HSEM_IsSemTaken. This function takes as parameter :
          (++) the semaphore ID from 0_ID to 31
          (++) It returns 1 if the given semaphore is taken otherwise (Free) zero
      (#)Release a semaphore using function with HAL_HSEM_Release. This function takes as parameters :
           (++) the semaphore ID from 0 to 31
           (++) the process ID from 0 to 255:
           (++) Note: If ProcessID and MasterID match, semaphore is freed, and an interrupt
         may be generated when enabled (notification activated). If ProcessID or MasterID does not match,
         semaphore remains taken (locked)

      (#)Release all semaphores at once taken by a given Master using function HAL_HSEM_Release_All
          This function takes as parameters :
           (++) the Release Key (value from 0 to 0xFFFF) can be Set or Get respectively by
              HAL_HSEM_SetClearKey() or HAL_HSEM_GetClearKey functions
           (++) the Master ID:
           (++) Note: If the Key and MasterID match, all semaphores taken by the given CPU that corresponds
           to MasterID  will be freed, and an interrupt may be generated when enabled (notification activated). If the
           Key or the MasterID doesn't match, semaphores remains taken (locked)

      (#)Semaphores Release all key functions:
         (++)  HAL_HSEM_SetClearKey() to set semaphore release all Key
         (++)  HAL_HSEM_GetClearKey() to get release all Key
      (#)Semaphores notification functions :
         (++)  HAL_HSEM_ActivateNotification to activate a notification callback on
               a given semaphores Mask (bitfield). When one or more semaphores defined by the mask are released
               the callback HAL_HSEM_FreeCallback will be asserted giving as parameters a mask of the released
               semaphores (bitfield).

         (++)  HAL_HSEM_DeactivateNotification to deactivate the notification of a given semaphores Mask (bitfield).
         (++) See the description of the macro __HAL_HSEM_SEMID_TO_MASK to check how to calculate a semaphore mask
                Used by the notification functions
     *** HSEM HAL driver macros list ***
     =============================================
     [..] Below the list of most used macros in HSEM HAL driver.

      (+) __HAL_HSEM_SEMID_TO_MASK: Helper macro to convert a Semaphore ID to a Mask.
      [..] Example of use :
      [..] mask = __HAL_HSEM_SEMID_TO_MASK(8)  |  __HAL_HSEM_SEMID_TO_MASK(21) | __HAL_HSEM_SEMID_TO_MASK(25).
      [..] All next macros take as parameter a semaphore Mask (bitfiled) that can be constructed using  __HAL_HSEM_SEMID_TO_MASK as the above example.
      (+) __HAL_HSEM_ENABLE_IT: Enable the specified semaphores Mask interrupts.
      (+) __HAL_HSEM_DISABLE_IT: Disable the specified semaphores Mask interrupts.
      (+) __HAL_HSEM_GET_IT: Checks whether the specified semaphore interrupt has occurred or not.
      (+) __HAL_HSEM_GET_FLAG: Get the semaphores status release flags.
      (+) __HAL_HSEM_CLEAR_FLAG: Clear the semaphores status release flags.

  @endverbatim
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32h7xx_hal.h"

/** @addtogroup STM32H7xx_HAL_Driver
  * @{
  */

/** @defgroup HSEM HSEM
  * @brief HSEM HAL module driver
  * @{
  */

#ifdef HAL_HSEM_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#if defined(DUAL_CORE)
/** @defgroup HSEM_Private_Constants  HSEM Private Constants
  * @{
  */

#ifndef HSEM_R_MASTERID
#define HSEM_R_MASTERID HSEM_R_COREID
#endif

#ifndef HSEM_RLR_MASTERID
#define HSEM_RLR_MASTERID HSEM_RLR_COREID
#endif

#ifndef HSEM_CR_MASTERID
#define HSEM_CR_MASTERID HSEM_CR_COREID
#endif

/**
  * @}
  */  
#endif /* DUAL_CORE */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/** @defgroup HSEM_Exported_Functions  HSEM Exported Functions
  * @{
  */

/** @defgroup HSEM_Exported_Functions_Group1 Take and Release functions
  *  @brief    HSEM Take and Release functions
  *
@verbatim
 ==============================================================================
              ##### HSEM Take and Release functions #####
 ==============================================================================
[..] This section provides functions allowing to:
      (+) Take a semaphore with 2 Step method
      (+) Fast Take a semaphore with 1 Step method
      (+) Check semaphore state Taken or not
      (+) Release a semaphore
      (+) Release all semaphore at once

@endverbatim
  * @{
  */


/**
  * @brief  Take a semaphore in 2 Step mode.
  * @param  SemID: semaphore ID from 0 to 31
  * @param  ProcessID: Process ID from 0 to 255
  * @retval HAL status
  */
HAL_StatusTypeDef  HAL_HSEM_Take(uint32_t SemID, uint32_t ProcessID)
{
  /* Check the parameters */
  assert_param(IS_HSEM_SEMID(SemID));
  assert_param(IS_HSEM_PROCESSID(ProcessID));

#if  USE_MULTI_CORE_SHARED_CODE != 0U
  /* First step  write R register with MasterID, processID and take bit=1*/
  HSEM->R[SemID] = ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK);

  /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
  if (HSEM->R[SemID] == ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK))
  {
    /*take success when MasterID and ProcessID match and take bit set*/
    return HAL_OK;
  }
#else
  /* First step  write R register with MasterID, processID and take bit=1*/
  HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK);

  /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
  if (HSEM->R[SemID] == (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK))
  {
    /*take success when MasterID and ProcessID match and take bit set*/
    return HAL_OK;
  }
#endif

  /* Semaphore take fails*/
  return HAL_ERROR;
}

/**
  * @brief  Fast Take a semaphore with 1 Step mode.
  * @param  SemID: semaphore ID from 0 to 31
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_HSEM_FastTake(uint32_t SemID)
{
  /* Check the parameters */
  assert_param(IS_HSEM_SEMID(SemID));

#if  USE_MULTI_CORE_SHARED_CODE != 0U
  /* Read the RLR register to take the semaphore */
  if (HSEM->RLR[SemID] == (((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_RLR_MASTERID) | HSEM_RLR_LOCK))
  {
    /*take success when MasterID match and take bit set*/
    return HAL_OK;
  }
#else  
  /* Read the RLR register to take the semaphore */
  if (HSEM->RLR[SemID] == (HSEM_CR_COREID_CURRENT | HSEM_RLR_LOCK))
  {
    /*take success when MasterID match and take bit set*/
    return HAL_OK;
  }
#endif

  /* Semaphore take fails */
  return HAL_ERROR;
}
/**
  * @brief  Check semaphore state Taken or not.
  * @param  SemID: semaphore ID
  * @retval HAL HSEM state
  */
uint32_t HAL_HSEM_IsSemTaken(uint32_t SemID)
{
  return (((HSEM->R[SemID] & HSEM_R_LOCK) != 0U) ? 1UL : 0UL);
}


/**
  * @brief  Release a semaphore.
  * @param  SemID: semaphore ID from 0 to 31
  * @param  ProcessID: Process ID from 0 to 255
  * @retval None
  */
void  HAL_HSEM_Release(uint32_t SemID, uint32_t ProcessID)
{
  /* Check the parameters */
  assert_param(IS_HSEM_SEMID(SemID));
  assert_param(IS_HSEM_PROCESSID(ProcessID));

  /* Clear the semaphore by writing to the R register : the MasterID , the processID and take bit = 0  */
#if  USE_MULTI_CORE_SHARED_CODE != 0U
  HSEM->R[SemID] = (ProcessID | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID));
#else
  HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT);
#endif

}

/**
  * @brief  Release All semaphore used by a given Master .
  * @param  Key: Semaphore Key , value from 0 to 0xFFFF
  * @param  CoreID: CoreID of the CPU that is using semaphores to be released
  * @retval None
  */
void HAL_HSEM_ReleaseAll(uint32_t Key, uint32_t CoreID)
{
  assert_param(IS_HSEM_KEY(Key));
  assert_param(IS_HSEM_COREID(CoreID));

  HSEM->CR = ((Key << HSEM_CR_KEY_Pos) | (CoreID << HSEM_CR_COREID_Pos));
}

/**
  * @}
  */

/** @defgroup HSEM_Exported_Functions_Group2 HSEM Set and Get Key functions
  *  @brief    HSEM Set and Get Key functions.
  *
@verbatim
  ==============================================================================
              ##### HSEM Set and Get Key functions #####
  ==============================================================================
    [..]  This section provides functions allowing to:
      (+) Set semaphore Key
      (+) Get semaphore Key
@endverbatim

  * @{
  */

/**
  * @brief  Set semaphore Key .
  * @param  Key: Semaphore Key , value from 0 to 0xFFFF
  * @retval None
  */
void  HAL_HSEM_SetClearKey(uint32_t Key)
{
  assert_param(IS_HSEM_KEY(Key));

  MODIFY_REG(HSEM->KEYR, HSEM_KEYR_KEY, (Key << HSEM_KEYR_KEY_Pos));

}

/**
  * @brief  Get semaphore Key .
  * @retval Semaphore Key , value from 0 to 0xFFFF
  */
uint32_t HAL_HSEM_GetClearKey(void)
{
  return (HSEM->KEYR >> HSEM_KEYR_KEY_Pos);
}

/**
  * @}
  */

/** @defgroup HSEM_Exported_Functions_Group3 HSEM IRQ handler management
  *  @brief    HSEM Notification functions.
  *
@verbatim
  ==============================================================================
      ##### HSEM IRQ handler management and Notification functions #####
  ==============================================================================
[..]  This section provides HSEM IRQ handler and Notification function.

@endverbatim
  * @{
  */

/**
  * @brief  Activate Semaphore release Notification for a given Semaphores Mask .
  * @param  SemMask: Mask of Released semaphores
  * @retval Semaphore Key
  */
void HAL_HSEM_ActivateNotification(uint32_t SemMask)
{
#if  USE_MULTI_CORE_SHARED_CODE != 0U
  /*enable the semaphore mask interrupts */
  if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
  {
    /*Use interrupt line 0 for CPU1 Master */
    HSEM->C1IER |= SemMask;
  }
  else /* HSEM_CPU2_COREID */
  {
    /*Use interrupt line 1 for CPU2 Master*/
    HSEM->C2IER |= SemMask;
  }
#else
  HSEM_COMMON->IER |= SemMask;
#endif
}

/**
  * @brief  Deactivate Semaphore release Notification for a given Semaphores Mask .
  * @param  SemMask: Mask of Released semaphores
  * @retval Semaphore Key
  */
void HAL_HSEM_DeactivateNotification(uint32_t SemMask)
{
#if  USE_MULTI_CORE_SHARED_CODE != 0U
  /*enable the semaphore mask interrupts */
  if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
  {
    /*Use interrupt line 0 for CPU1 Master */
    HSEM->C1IER &= ~SemMask;
  }
  else /* HSEM_CPU2_COREID */
  {
    /*Use interrupt line 1 for CPU2 Master*/
    HSEM->C2IER &= ~SemMask;
  }
#else
  HSEM_COMMON->IER &= ~SemMask;
#endif
}

/**
  * @brief  This function handles HSEM interrupt request
  * @retval None
  */
void HAL_HSEM_IRQHandler(void)
{
  uint32_t statusreg;
#if  USE_MULTI_CORE_SHARED_CODE != 0U
  if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
  {
    /* Get the list of masked freed semaphores*/
    statusreg = HSEM->C1MISR; /*Use interrupt line 0 for CPU1 Master*/

    /*Disable Interrupts*/
    HSEM->C1IER &= ~((uint32_t)statusreg);

    /*Clear Flags*/
    HSEM->C1ICR = ((uint32_t)statusreg);
  }
  else /* HSEM_CPU2_COREID */
  {
    /* Get the list of masked freed semaphores*/
    statusreg = HSEM->C2MISR;/*Use interrupt line 1 for CPU2 Master*/

    /*Disable Interrupts*/
    HSEM->C2IER &= ~((uint32_t)statusreg);

    /*Clear Flags*/
    HSEM->C2ICR = ((uint32_t)statusreg);
  }
#else
  /* Get the list of masked freed semaphores*/
  statusreg = HSEM_COMMON->MISR;

  /*Disable Interrupts*/
  HSEM_COMMON->IER &= ~((uint32_t)statusreg);

  /*Clear Flags*/
  HSEM_COMMON->ICR = ((uint32_t)statusreg);

#endif
  /* Call FreeCallback */
  HAL_HSEM_FreeCallback(statusreg);
}

/**
  * @brief Semaphore Released Callback.
  * @param SemMask: Mask of Released semaphores
  * @retval None
  */
__weak void HAL_HSEM_FreeCallback(uint32_t SemMask)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(SemMask);

  /* NOTE : This function should not be modified, when the callback is needed,
  the HAL_HSEM_FreeCallback can be implemented in the user file
    */
}

/**
  * @}
  */

/**
  * @}
  */

#endif /* HAL_HSEM_MODULE_ENABLED */
/**
  * @}
  */

/**
  * @}
  */