STM32H735xx HAL User Manual
stm32h7xx_hal_hsem.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_hsem.c
00004   * @author  MCD Application Team
00005   * @brief   HSEM HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the semaphore peripheral:
00008   *           + Semaphore Take function (2-Step Procedure) , non blocking
00009   *           + Semaphore FastTake function (1-Step Procedure) , non blocking
00010   *           + Semaphore Status check
00011   *           + Semaphore Clear Key Set and Get
00012   *           + Release and release all functions
00013   *           + Semaphore notification enabling and disabling and callnack functions
00014   *           + IRQ handler management
00015   *
00016   *
00017   ******************************************************************************
00018   * @attention
00019   *
00020   * Copyright (c) 2017 STMicroelectronics.
00021   * All rights reserved.
00022   *
00023   * This software is licensed under terms that can be found in the LICENSE file
00024   * in the root directory of this software component.
00025   * If no LICENSE file comes with this software, it is provided AS-IS.
00026   *
00027   ******************************************************************************
00028   @verbatim
00029   ==============================================================================
00030                      ##### How to use this driver #####
00031   ==============================================================================
00032   [..]
00033       (#)Take a semaphore In 2-Step mode Using function HAL_HSEM_Take. This function takes as parameters :
00034            (++) the semaphore ID from 0 to 31
00035            (++) the process ID from 0 to 255
00036       (#) Fast Take semaphore In 1-Step mode Using function HAL_HSEM_FastTake. This function takes as parameter :
00037            (++) the semaphore ID from 0_ID to 31. Note that the process ID value is implicitly assumed as zero
00038       (#) Check if a semaphore is Taken using function HAL_HSEM_IsSemTaken. This function takes as parameter :
00039           (++) the semaphore ID from 0_ID to 31
00040           (++) It returns 1 if the given semaphore is taken otherwise (Free) zero
00041       (#)Release a semaphore using function with HAL_HSEM_Release. This function takes as parameters :
00042            (++) the semaphore ID from 0 to 31
00043            (++) the process ID from 0 to 255:
00044            (++) Note: If ProcessID and MasterID match, semaphore is freed, and an interrupt
00045          may be generated when enabled (notification activated). If ProcessID or MasterID does not match,
00046          semaphore remains taken (locked)
00047 
00048       (#)Release all semaphores at once taken by a given Master using function HAL_HSEM_Release_All
00049           This function takes as parameters :
00050            (++) the Release Key (value from 0 to 0xFFFF) can be Set or Get respectively by
00051               HAL_HSEM_SetClearKey() or HAL_HSEM_GetClearKey functions
00052            (++) the Master ID:
00053            (++) Note: If the Key and MasterID match, all semaphores taken by the given CPU that corresponds
00054            to MasterID  will be freed, and an interrupt may be generated when enabled (notification activated). If the
00055            Key or the MasterID doesn't match, semaphores remains taken (locked)
00056 
00057       (#)Semaphores Release all key functions:
00058          (++)  HAL_HSEM_SetClearKey() to set semaphore release all Key
00059          (++)  HAL_HSEM_GetClearKey() to get release all Key
00060       (#)Semaphores notification functions :
00061          (++)  HAL_HSEM_ActivateNotification to activate a notification callback on
00062                a given semaphores Mask (bitfield). When one or more semaphores defined by the mask are released
00063                the callback HAL_HSEM_FreeCallback will be asserted giving as parameters a mask of the released
00064                semaphores (bitfield).
00065 
00066          (++)  HAL_HSEM_DeactivateNotification to deactivate the notification of a given semaphores Mask (bitfield).
00067          (++) See the description of the macro __HAL_HSEM_SEMID_TO_MASK to check how to calculate a semaphore mask
00068                 Used by the notification functions
00069      *** HSEM HAL driver macros list ***
00070      =============================================
00071      [..] Below the list of most used macros in HSEM HAL driver.
00072 
00073       (+) __HAL_HSEM_SEMID_TO_MASK: Helper macro to convert a Semaphore ID to a Mask.
00074       [..] Example of use :
00075       [..] mask = __HAL_HSEM_SEMID_TO_MASK(8)  |  __HAL_HSEM_SEMID_TO_MASK(21) | __HAL_HSEM_SEMID_TO_MASK(25).
00076       [..] All next macros take as parameter a semaphore Mask (bitfiled) that can be constructed using  __HAL_HSEM_SEMID_TO_MASK as the above example.
00077       (+) __HAL_HSEM_ENABLE_IT: Enable the specified semaphores Mask interrupts.
00078       (+) __HAL_HSEM_DISABLE_IT: Disable the specified semaphores Mask interrupts.
00079       (+) __HAL_HSEM_GET_IT: Checks whether the specified semaphore interrupt has occurred or not.
00080       (+) __HAL_HSEM_GET_FLAG: Get the semaphores status release flags.
00081       (+) __HAL_HSEM_CLEAR_FLAG: Clear the semaphores status release flags.
00082 
00083   @endverbatim
00084   ******************************************************************************
00085   */
00086 
00087 /* Includes ------------------------------------------------------------------*/
00088 #include "stm32h7xx_hal.h"
00089 
00090 /** @addtogroup STM32H7xx_HAL_Driver
00091   * @{
00092   */
00093 
00094 /** @defgroup HSEM HSEM
00095   * @brief HSEM HAL module driver
00096   * @{
00097   */
00098 
00099 #ifdef HAL_HSEM_MODULE_ENABLED
00100 
00101 /* Private typedef -----------------------------------------------------------*/
00102 /* Private define ------------------------------------------------------------*/
00103 #if defined(DUAL_CORE)
00104 /** @defgroup HSEM_Private_Constants  HSEM Private Constants
00105   * @{
00106   */
00107 
00108 #ifndef HSEM_R_MASTERID
00109 #define HSEM_R_MASTERID HSEM_R_COREID
00110 #endif
00111 
00112 #ifndef HSEM_RLR_MASTERID
00113 #define HSEM_RLR_MASTERID HSEM_RLR_COREID
00114 #endif
00115 
00116 #ifndef HSEM_CR_MASTERID
00117 #define HSEM_CR_MASTERID HSEM_CR_COREID
00118 #endif
00119 
00120 /**
00121   * @}
00122   */  
00123 #endif /* DUAL_CORE */
00124 /* Private macro -------------------------------------------------------------*/
00125 /* Private variables ---------------------------------------------------------*/
00126 /* Private function prototypes -----------------------------------------------*/
00127 /* Private functions ---------------------------------------------------------*/
00128 /* Exported functions --------------------------------------------------------*/
00129 
00130 /** @defgroup HSEM_Exported_Functions  HSEM Exported Functions
00131   * @{
00132   */
00133 
00134 /** @defgroup HSEM_Exported_Functions_Group1 Take and Release functions
00135   *  @brief    HSEM Take and Release functions
00136   *
00137 @verbatim
00138  ==============================================================================
00139               ##### HSEM Take and Release functions #####
00140  ==============================================================================
00141 [..] This section provides functions allowing to:
00142       (+) Take a semaphore with 2 Step method
00143       (+) Fast Take a semaphore with 1 Step method
00144       (+) Check semaphore state Taken or not
00145       (+) Release a semaphore
00146       (+) Release all semaphore at once
00147 
00148 @endverbatim
00149   * @{
00150   */
00151 
00152 
00153 /**
00154   * @brief  Take a semaphore in 2 Step mode.
00155   * @param  SemID: semaphore ID from 0 to 31
00156   * @param  ProcessID: Process ID from 0 to 255
00157   * @retval HAL status
00158   */
00159 HAL_StatusTypeDef  HAL_HSEM_Take(uint32_t SemID, uint32_t ProcessID)
00160 {
00161   /* Check the parameters */
00162   assert_param(IS_HSEM_SEMID(SemID));
00163   assert_param(IS_HSEM_PROCESSID(ProcessID));
00164 
00165 #if  USE_MULTI_CORE_SHARED_CODE != 0U
00166   /* First step  write R register with MasterID, processID and take bit=1*/
00167   HSEM->R[SemID] = ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK);
00168 
00169   /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
00170   if (HSEM->R[SemID] == ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK))
00171   {
00172     /*take success when MasterID and ProcessID match and take bit set*/
00173     return HAL_OK;
00174   }
00175 #else
00176   /* First step  write R register with MasterID, processID and take bit=1*/
00177   HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK);
00178 
00179   /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
00180   if (HSEM->R[SemID] == (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK))
00181   {
00182     /*take success when MasterID and ProcessID match and take bit set*/
00183     return HAL_OK;
00184   }
00185 #endif
00186 
00187   /* Semaphore take fails*/
00188   return HAL_ERROR;
00189 }
00190 
00191 /**
00192   * @brief  Fast Take a semaphore with 1 Step mode.
00193   * @param  SemID: semaphore ID from 0 to 31
00194   * @retval HAL status
00195   */
00196 HAL_StatusTypeDef HAL_HSEM_FastTake(uint32_t SemID)
00197 {
00198   /* Check the parameters */
00199   assert_param(IS_HSEM_SEMID(SemID));
00200 
00201 #if  USE_MULTI_CORE_SHARED_CODE != 0U
00202   /* Read the RLR register to take the semaphore */
00203   if (HSEM->RLR[SemID] == (((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_RLR_MASTERID) | HSEM_RLR_LOCK))
00204   {
00205     /*take success when MasterID match and take bit set*/
00206     return HAL_OK;
00207   }
00208 #else  
00209   /* Read the RLR register to take the semaphore */
00210   if (HSEM->RLR[SemID] == (HSEM_CR_COREID_CURRENT | HSEM_RLR_LOCK))
00211   {
00212     /*take success when MasterID match and take bit set*/
00213     return HAL_OK;
00214   }
00215 #endif
00216 
00217   /* Semaphore take fails */
00218   return HAL_ERROR;
00219 }
00220 /**
00221   * @brief  Check semaphore state Taken or not.
00222   * @param  SemID: semaphore ID
00223   * @retval HAL HSEM state
00224   */
00225 uint32_t HAL_HSEM_IsSemTaken(uint32_t SemID)
00226 {
00227   return (((HSEM->R[SemID] & HSEM_R_LOCK) != 0U) ? 1UL : 0UL);
00228 }
00229 
00230 
00231 /**
00232   * @brief  Release a semaphore.
00233   * @param  SemID: semaphore ID from 0 to 31
00234   * @param  ProcessID: Process ID from 0 to 255
00235   * @retval None
00236   */
00237 void  HAL_HSEM_Release(uint32_t SemID, uint32_t ProcessID)
00238 {
00239   /* Check the parameters */
00240   assert_param(IS_HSEM_SEMID(SemID));
00241   assert_param(IS_HSEM_PROCESSID(ProcessID));
00242 
00243   /* Clear the semaphore by writing to the R register : the MasterID , the processID and take bit = 0  */
00244 #if  USE_MULTI_CORE_SHARED_CODE != 0U
00245   HSEM->R[SemID] = (ProcessID | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID));
00246 #else
00247   HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT);
00248 #endif
00249 
00250 }
00251 
00252 /**
00253   * @brief  Release All semaphore used by a given Master .
00254   * @param  Key: Semaphore Key , value from 0 to 0xFFFF
00255   * @param  CoreID: CoreID of the CPU that is using semaphores to be released
00256   * @retval None
00257   */
00258 void HAL_HSEM_ReleaseAll(uint32_t Key, uint32_t CoreID)
00259 {
00260   assert_param(IS_HSEM_KEY(Key));
00261   assert_param(IS_HSEM_COREID(CoreID));
00262 
00263   HSEM->CR = ((Key << HSEM_CR_KEY_Pos) | (CoreID << HSEM_CR_COREID_Pos));
00264 }
00265 
00266 /**
00267   * @}
00268   */
00269 
00270 /** @defgroup HSEM_Exported_Functions_Group2 HSEM Set and Get Key functions
00271   *  @brief    HSEM Set and Get Key functions.
00272   *
00273 @verbatim
00274   ==============================================================================
00275               ##### HSEM Set and Get Key functions #####
00276   ==============================================================================
00277     [..]  This section provides functions allowing to:
00278       (+) Set semaphore Key
00279       (+) Get semaphore Key
00280 @endverbatim
00281 
00282   * @{
00283   */
00284 
00285 /**
00286   * @brief  Set semaphore Key .
00287   * @param  Key: Semaphore Key , value from 0 to 0xFFFF
00288   * @retval None
00289   */
00290 void  HAL_HSEM_SetClearKey(uint32_t Key)
00291 {
00292   assert_param(IS_HSEM_KEY(Key));
00293 
00294   MODIFY_REG(HSEM->KEYR, HSEM_KEYR_KEY, (Key << HSEM_KEYR_KEY_Pos));
00295 
00296 }
00297 
00298 /**
00299   * @brief  Get semaphore Key .
00300   * @retval Semaphore Key , value from 0 to 0xFFFF
00301   */
00302 uint32_t HAL_HSEM_GetClearKey(void)
00303 {
00304   return (HSEM->KEYR >> HSEM_KEYR_KEY_Pos);
00305 }
00306 
00307 /**
00308   * @}
00309   */
00310 
00311 /** @defgroup HSEM_Exported_Functions_Group3 HSEM IRQ handler management
00312   *  @brief    HSEM Notification functions.
00313   *
00314 @verbatim
00315   ==============================================================================
00316       ##### HSEM IRQ handler management and Notification functions #####
00317   ==============================================================================
00318 [..]  This section provides HSEM IRQ handler and Notification function.
00319 
00320 @endverbatim
00321   * @{
00322   */
00323 
00324 /**
00325   * @brief  Activate Semaphore release Notification for a given Semaphores Mask .
00326   * @param  SemMask: Mask of Released semaphores
00327   * @retval Semaphore Key
00328   */
00329 void HAL_HSEM_ActivateNotification(uint32_t SemMask)
00330 {
00331 #if  USE_MULTI_CORE_SHARED_CODE != 0U
00332   /*enable the semaphore mask interrupts */
00333   if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
00334   {
00335     /*Use interrupt line 0 for CPU1 Master */
00336     HSEM->C1IER |= SemMask;
00337   }
00338   else /* HSEM_CPU2_COREID */
00339   {
00340     /*Use interrupt line 1 for CPU2 Master*/
00341     HSEM->C2IER |= SemMask;
00342   }
00343 #else
00344   HSEM_COMMON->IER |= SemMask;
00345 #endif
00346 }
00347 
00348 /**
00349   * @brief  Deactivate Semaphore release Notification for a given Semaphores Mask .
00350   * @param  SemMask: Mask of Released semaphores
00351   * @retval Semaphore Key
00352   */
00353 void HAL_HSEM_DeactivateNotification(uint32_t SemMask)
00354 {
00355 #if  USE_MULTI_CORE_SHARED_CODE != 0U
00356   /*enable the semaphore mask interrupts */
00357   if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
00358   {
00359     /*Use interrupt line 0 for CPU1 Master */
00360     HSEM->C1IER &= ~SemMask;
00361   }
00362   else /* HSEM_CPU2_COREID */
00363   {
00364     /*Use interrupt line 1 for CPU2 Master*/
00365     HSEM->C2IER &= ~SemMask;
00366   }
00367 #else
00368   HSEM_COMMON->IER &= ~SemMask;
00369 #endif
00370 }
00371 
00372 /**
00373   * @brief  This function handles HSEM interrupt request
00374   * @retval None
00375   */
00376 void HAL_HSEM_IRQHandler(void)
00377 {
00378   uint32_t statusreg;
00379 #if  USE_MULTI_CORE_SHARED_CODE != 0U
00380   if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
00381   {
00382     /* Get the list of masked freed semaphores*/
00383     statusreg = HSEM->C1MISR; /*Use interrupt line 0 for CPU1 Master*/
00384 
00385     /*Disable Interrupts*/
00386     HSEM->C1IER &= ~((uint32_t)statusreg);
00387 
00388     /*Clear Flags*/
00389     HSEM->C1ICR = ((uint32_t)statusreg);
00390   }
00391   else /* HSEM_CPU2_COREID */
00392   {
00393     /* Get the list of masked freed semaphores*/
00394     statusreg = HSEM->C2MISR;/*Use interrupt line 1 for CPU2 Master*/
00395 
00396     /*Disable Interrupts*/
00397     HSEM->C2IER &= ~((uint32_t)statusreg);
00398 
00399     /*Clear Flags*/
00400     HSEM->C2ICR = ((uint32_t)statusreg);
00401   }
00402 #else
00403   /* Get the list of masked freed semaphores*/
00404   statusreg = HSEM_COMMON->MISR;
00405 
00406   /*Disable Interrupts*/
00407   HSEM_COMMON->IER &= ~((uint32_t)statusreg);
00408 
00409   /*Clear Flags*/
00410   HSEM_COMMON->ICR = ((uint32_t)statusreg);
00411 
00412 #endif
00413   /* Call FreeCallback */
00414   HAL_HSEM_FreeCallback(statusreg);
00415 }
00416 
00417 /**
00418   * @brief Semaphore Released Callback.
00419   * @param SemMask: Mask of Released semaphores
00420   * @retval None
00421   */
00422 __weak void HAL_HSEM_FreeCallback(uint32_t SemMask)
00423 {
00424   /* Prevent unused argument(s) compilation warning */
00425   UNUSED(SemMask);
00426 
00427   /* NOTE : This function should not be modified, when the callback is needed,
00428   the HAL_HSEM_FreeCallback can be implemented in the user file
00429     */
00430 }
00431 
00432 /**
00433   * @}
00434   */
00435 
00436 /**
00437   * @}
00438   */
00439 
00440 #endif /* HAL_HSEM_MODULE_ENABLED */
00441 /**
00442   * @}
00443   */
00444 
00445 /**
00446   * @}
00447   */