Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_hsem.c
0004   * @author  MCD Application Team
0005   * @brief   HSEM HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the semaphore peripheral:
0008   *           + Semaphore Take function (2-Step Procedure) , non blocking
0009   *           + Semaphore FastTake function (1-Step Procedure) , non blocking
0010   *           + Semaphore Status check
0011   *           + Semaphore Clear Key Set and Get
0012   *           + Release and release all functions
0013   *           + Semaphore notification enabling and disabling and callnack functions
0014   *           + IRQ handler management
0015   *
0016   *
0017   ******************************************************************************
0018   * @attention
0019   *
0020   * Copyright (c) 2017 STMicroelectronics.
0021   * All rights reserved.
0022   *
0023   * This software is licensed under terms that can be found in the LICENSE file
0024   * in the root directory of this software component.
0025   * If no LICENSE file comes with this software, it is provided AS-IS.
0026   *
0027   ******************************************************************************
0028   @verbatim
0029   ==============================================================================
0030                      ##### How to use this driver #####
0031   ==============================================================================
0032   [..]
0033       (#)Take a semaphore In 2-Step mode Using function HAL_HSEM_Take. This function takes as parameters :
0034            (++) the semaphore ID from 0 to 31
0035            (++) the process ID from 0 to 255
0036       (#) Fast Take semaphore In 1-Step mode Using function HAL_HSEM_FastTake. This function takes as parameter :
0037            (++) the semaphore ID from 0_ID to 31. Note that the process ID value is implicitly assumed as zero
0038       (#) Check if a semaphore is Taken using function HAL_HSEM_IsSemTaken. This function takes as parameter :
0039           (++) the semaphore ID from 0_ID to 31
0040           (++) It returns 1 if the given semaphore is taken otherwise (Free) zero
0041       (#)Release a semaphore using function with HAL_HSEM_Release. This function takes as parameters :
0042            (++) the semaphore ID from 0 to 31
0043            (++) the process ID from 0 to 255:
0044            (++) Note: If ProcessID and MasterID match, semaphore is freed, and an interrupt
0045          may be generated when enabled (notification activated). If ProcessID or MasterID does not match,
0046          semaphore remains taken (locked)
0047 
0048       (#)Release all semaphores at once taken by a given Master using function HAL_HSEM_Release_All
0049           This function takes as parameters :
0050            (++) the Release Key (value from 0 to 0xFFFF) can be Set or Get respectively by
0051               HAL_HSEM_SetClearKey() or HAL_HSEM_GetClearKey functions
0052            (++) the Master ID:
0053            (++) Note: If the Key and MasterID match, all semaphores taken by the given CPU that corresponds
0054            to MasterID  will be freed, and an interrupt may be generated when enabled (notification activated). If the
0055            Key or the MasterID doesn't match, semaphores remains taken (locked)
0056 
0057       (#)Semaphores Release all key functions:
0058          (++)  HAL_HSEM_SetClearKey() to set semaphore release all Key
0059          (++)  HAL_HSEM_GetClearKey() to get release all Key
0060       (#)Semaphores notification functions :
0061          (++)  HAL_HSEM_ActivateNotification to activate a notification callback on
0062                a given semaphores Mask (bitfield). When one or more semaphores defined by the mask are released
0063                the callback HAL_HSEM_FreeCallback will be asserted giving as parameters a mask of the released
0064                semaphores (bitfield).
0065 
0066          (++)  HAL_HSEM_DeactivateNotification to deactivate the notification of a given semaphores Mask (bitfield).
0067          (++) See the description of the macro __HAL_HSEM_SEMID_TO_MASK to check how to calculate a semaphore mask
0068                 Used by the notification functions
0069      *** HSEM HAL driver macros list ***
0070      =============================================
0071      [..] Below the list of most used macros in HSEM HAL driver.
0072 
0073       (+) __HAL_HSEM_SEMID_TO_MASK: Helper macro to convert a Semaphore ID to a Mask.
0074       [..] Example of use :
0075       [..] mask = __HAL_HSEM_SEMID_TO_MASK(8)  |  __HAL_HSEM_SEMID_TO_MASK(21) | __HAL_HSEM_SEMID_TO_MASK(25).
0076       [..] All next macros take as parameter a semaphore Mask (bitfiled) that can be constructed using  __HAL_HSEM_SEMID_TO_MASK as the above example.
0077       (+) __HAL_HSEM_ENABLE_IT: Enable the specified semaphores Mask interrupts.
0078       (+) __HAL_HSEM_DISABLE_IT: Disable the specified semaphores Mask interrupts.
0079       (+) __HAL_HSEM_GET_IT: Checks whether the specified semaphore interrupt has occurred or not.
0080       (+) __HAL_HSEM_GET_FLAG: Get the semaphores status release flags.
0081       (+) __HAL_HSEM_CLEAR_FLAG: Clear the semaphores status release flags.
0082 
0083   @endverbatim
0084   ******************************************************************************
0085   */
0086 
0087 /* Includes ------------------------------------------------------------------*/
0088 #include "stm32h7xx_hal.h"
0089 
0090 /** @addtogroup STM32H7xx_HAL_Driver
0091   * @{
0092   */
0093 
0094 /** @defgroup HSEM HSEM
0095   * @ingroup RTEMSBSPsARMSTM32H7
0096   * @brief HSEM HAL module driver
0097   * @{
0098   */
0099 
0100 #ifdef HAL_HSEM_MODULE_ENABLED
0101 
0102 /* Private typedef -----------------------------------------------------------*/
0103 /* Private define ------------------------------------------------------------*/
0104 #if defined(DUAL_CORE)
0105 /** @defgroup HSEM_Private_Constants  HSEM Private Constants
0106   * @ingroup RTEMSBSPsARMSTM32H7
0107   * @{
0108   */
0109 
0110 #ifndef HSEM_R_MASTERID
0111 #define HSEM_R_MASTERID HSEM_R_COREID
0112 #endif
0113 
0114 #ifndef HSEM_RLR_MASTERID
0115 #define HSEM_RLR_MASTERID HSEM_RLR_COREID
0116 #endif
0117 
0118 #ifndef HSEM_CR_MASTERID
0119 #define HSEM_CR_MASTERID HSEM_CR_COREID
0120 #endif
0121 
0122 /**
0123   * @}
0124   */  
0125 #endif /* DUAL_CORE */
0126 /* Private macro -------------------------------------------------------------*/
0127 /* Private variables ---------------------------------------------------------*/
0128 /* Private function prototypes -----------------------------------------------*/
0129 /* Private functions ---------------------------------------------------------*/
0130 /* Exported functions --------------------------------------------------------*/
0131 
0132 /** @defgroup HSEM_Exported_Functions  HSEM Exported Functions
0133   * @ingroup RTEMSBSPsARMSTM32H7
0134   * @{
0135   */
0136 
0137 /** @defgroup HSEM_Exported_Functions_Group1 Take and Release functions
0138   * @ingroup RTEMSBSPsARMSTM32H7
0139   *  @brief    HSEM Take and Release functions
0140   *
0141 @verbatim
0142  ==============================================================================
0143               ##### HSEM Take and Release functions #####
0144  ==============================================================================
0145 [..] This section provides functions allowing to:
0146       (+) Take a semaphore with 2 Step method
0147       (+) Fast Take a semaphore with 1 Step method
0148       (+) Check semaphore state Taken or not
0149       (+) Release a semaphore
0150       (+) Release all semaphore at once
0151 
0152 @endverbatim
0153   * @{
0154   */
0155 
0156 
0157 /**
0158   * @brief  Take a semaphore in 2 Step mode.
0159   * @param  SemID: semaphore ID from 0 to 31
0160   * @param  ProcessID: Process ID from 0 to 255
0161   * @retval HAL status
0162   */
0163 HAL_StatusTypeDef  HAL_HSEM_Take(uint32_t SemID, uint32_t ProcessID)
0164 {
0165   /* Check the parameters */
0166   assert_param(IS_HSEM_SEMID(SemID));
0167   assert_param(IS_HSEM_PROCESSID(ProcessID));
0168 
0169 #if  USE_MULTI_CORE_SHARED_CODE != 0U
0170   /* First step  write R register with MasterID, processID and take bit=1*/
0171   HSEM->R[SemID] = ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK);
0172 
0173   /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
0174   if (HSEM->R[SemID] == ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK))
0175   {
0176     /*take success when MasterID and ProcessID match and take bit set*/
0177     return HAL_OK;
0178   }
0179 #else
0180   /* First step  write R register with MasterID, processID and take bit=1*/
0181   HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK);
0182 
0183   /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
0184   if (HSEM->R[SemID] == (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK))
0185   {
0186     /*take success when MasterID and ProcessID match and take bit set*/
0187     return HAL_OK;
0188   }
0189 #endif
0190 
0191   /* Semaphore take fails*/
0192   return HAL_ERROR;
0193 }
0194 
0195 /**
0196   * @brief  Fast Take a semaphore with 1 Step mode.
0197   * @param  SemID: semaphore ID from 0 to 31
0198   * @retval HAL status
0199   */
0200 HAL_StatusTypeDef HAL_HSEM_FastTake(uint32_t SemID)
0201 {
0202   /* Check the parameters */
0203   assert_param(IS_HSEM_SEMID(SemID));
0204 
0205 #if  USE_MULTI_CORE_SHARED_CODE != 0U
0206   /* Read the RLR register to take the semaphore */
0207   if (HSEM->RLR[SemID] == (((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_RLR_MASTERID) | HSEM_RLR_LOCK))
0208   {
0209     /*take success when MasterID match and take bit set*/
0210     return HAL_OK;
0211   }
0212 #else  
0213   /* Read the RLR register to take the semaphore */
0214   if (HSEM->RLR[SemID] == (HSEM_CR_COREID_CURRENT | HSEM_RLR_LOCK))
0215   {
0216     /*take success when MasterID match and take bit set*/
0217     return HAL_OK;
0218   }
0219 #endif
0220 
0221   /* Semaphore take fails */
0222   return HAL_ERROR;
0223 }
0224 /**
0225   * @brief  Check semaphore state Taken or not.
0226   * @param  SemID: semaphore ID
0227   * @retval HAL HSEM state
0228   */
0229 uint32_t HAL_HSEM_IsSemTaken(uint32_t SemID)
0230 {
0231   return (((HSEM->R[SemID] & HSEM_R_LOCK) != 0U) ? 1UL : 0UL);
0232 }
0233 
0234 
0235 /**
0236   * @brief  Release a semaphore.
0237   * @param  SemID: semaphore ID from 0 to 31
0238   * @param  ProcessID: Process ID from 0 to 255
0239   * @retval None
0240   */
0241 void  HAL_HSEM_Release(uint32_t SemID, uint32_t ProcessID)
0242 {
0243   /* Check the parameters */
0244   assert_param(IS_HSEM_SEMID(SemID));
0245   assert_param(IS_HSEM_PROCESSID(ProcessID));
0246 
0247   /* Clear the semaphore by writing to the R register : the MasterID , the processID and take bit = 0  */
0248 #if  USE_MULTI_CORE_SHARED_CODE != 0U
0249   HSEM->R[SemID] = (ProcessID | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID));
0250 #else
0251   HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT);
0252 #endif
0253 
0254 }
0255 
0256 /**
0257   * @brief  Release All semaphore used by a given Master .
0258   * @param  Key: Semaphore Key , value from 0 to 0xFFFF
0259   * @param  CoreID: CoreID of the CPU that is using semaphores to be released
0260   * @retval None
0261   */
0262 void HAL_HSEM_ReleaseAll(uint32_t Key, uint32_t CoreID)
0263 {
0264   assert_param(IS_HSEM_KEY(Key));
0265   assert_param(IS_HSEM_COREID(CoreID));
0266 
0267   HSEM->CR = ((Key << HSEM_CR_KEY_Pos) | (CoreID << HSEM_CR_COREID_Pos));
0268 }
0269 
0270 /**
0271   * @}
0272   */
0273 
0274 /** @defgroup HSEM_Exported_Functions_Group2 HSEM Set and Get Key functions
0275   * @ingroup RTEMSBSPsARMSTM32H7
0276   *  @brief    HSEM Set and Get Key functions.
0277   *
0278 @verbatim
0279   ==============================================================================
0280               ##### HSEM Set and Get Key functions #####
0281   ==============================================================================
0282     [..]  This section provides functions allowing to:
0283       (+) Set semaphore Key
0284       (+) Get semaphore Key
0285 @endverbatim
0286 
0287   * @{
0288   */
0289 
0290 /**
0291   * @brief  Set semaphore Key .
0292   * @param  Key: Semaphore Key , value from 0 to 0xFFFF
0293   * @retval None
0294   */
0295 void  HAL_HSEM_SetClearKey(uint32_t Key)
0296 {
0297   assert_param(IS_HSEM_KEY(Key));
0298 
0299   MODIFY_REG(HSEM->KEYR, HSEM_KEYR_KEY, (Key << HSEM_KEYR_KEY_Pos));
0300 
0301 }
0302 
0303 /**
0304   * @brief  Get semaphore Key .
0305   * @retval Semaphore Key , value from 0 to 0xFFFF
0306   */
0307 uint32_t HAL_HSEM_GetClearKey(void)
0308 {
0309   return (HSEM->KEYR >> HSEM_KEYR_KEY_Pos);
0310 }
0311 
0312 /**
0313   * @}
0314   */
0315 
0316 /** @defgroup HSEM_Exported_Functions_Group3 HSEM IRQ handler management
0317   * @ingroup RTEMSBSPsARMSTM32H7
0318   *  @brief    HSEM Notification functions.
0319   *
0320 @verbatim
0321   ==============================================================================
0322       ##### HSEM IRQ handler management and Notification functions #####
0323   ==============================================================================
0324 [..]  This section provides HSEM IRQ handler and Notification function.
0325 
0326 @endverbatim
0327   * @{
0328   */
0329 
0330 /**
0331   * @brief  Activate Semaphore release Notification for a given Semaphores Mask .
0332   * @param  SemMask: Mask of Released semaphores
0333   * @retval Semaphore Key
0334   */
0335 void HAL_HSEM_ActivateNotification(uint32_t SemMask)
0336 {
0337 #if  USE_MULTI_CORE_SHARED_CODE != 0U
0338   /*enable the semaphore mask interrupts */
0339   if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
0340   {
0341     /*Use interrupt line 0 for CPU1 Master */
0342     HSEM->C1IER |= SemMask;
0343   }
0344   else /* HSEM_CPU2_COREID */
0345   {
0346     /*Use interrupt line 1 for CPU2 Master*/
0347     HSEM->C2IER |= SemMask;
0348   }
0349 #else
0350   HSEM_COMMON->IER |= SemMask;
0351 #endif
0352 }
0353 
0354 /**
0355   * @brief  Deactivate Semaphore release Notification for a given Semaphores Mask .
0356   * @param  SemMask: Mask of Released semaphores
0357   * @retval Semaphore Key
0358   */
0359 void HAL_HSEM_DeactivateNotification(uint32_t SemMask)
0360 {
0361 #if  USE_MULTI_CORE_SHARED_CODE != 0U
0362   /*enable the semaphore mask interrupts */
0363   if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
0364   {
0365     /*Use interrupt line 0 for CPU1 Master */
0366     HSEM->C1IER &= ~SemMask;
0367   }
0368   else /* HSEM_CPU2_COREID */
0369   {
0370     /*Use interrupt line 1 for CPU2 Master*/
0371     HSEM->C2IER &= ~SemMask;
0372   }
0373 #else
0374   HSEM_COMMON->IER &= ~SemMask;
0375 #endif
0376 }
0377 
0378 /**
0379   * @brief  This function handles HSEM interrupt request
0380   * @retval None
0381   */
0382 void HAL_HSEM_IRQHandler(void)
0383 {
0384   uint32_t statusreg;
0385 #if  USE_MULTI_CORE_SHARED_CODE != 0U
0386   if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
0387   {
0388     /* Get the list of masked freed semaphores*/
0389     statusreg = HSEM->C1MISR; /*Use interrupt line 0 for CPU1 Master*/
0390 
0391     /*Disable Interrupts*/
0392     HSEM->C1IER &= ~((uint32_t)statusreg);
0393 
0394     /*Clear Flags*/
0395     HSEM->C1ICR = ((uint32_t)statusreg);
0396   }
0397   else /* HSEM_CPU2_COREID */
0398   {
0399     /* Get the list of masked freed semaphores*/
0400     statusreg = HSEM->C2MISR;/*Use interrupt line 1 for CPU2 Master*/
0401 
0402     /*Disable Interrupts*/
0403     HSEM->C2IER &= ~((uint32_t)statusreg);
0404 
0405     /*Clear Flags*/
0406     HSEM->C2ICR = ((uint32_t)statusreg);
0407   }
0408 #else
0409   /* Get the list of masked freed semaphores*/
0410   statusreg = HSEM_COMMON->MISR;
0411 
0412   /*Disable Interrupts*/
0413   HSEM_COMMON->IER &= ~((uint32_t)statusreg);
0414 
0415   /*Clear Flags*/
0416   HSEM_COMMON->ICR = ((uint32_t)statusreg);
0417 
0418 #endif
0419   /* Call FreeCallback */
0420   HAL_HSEM_FreeCallback(statusreg);
0421 }
0422 
0423 /**
0424   * @brief Semaphore Released Callback.
0425   * @param SemMask: Mask of Released semaphores
0426   * @retval None
0427   */
0428 __weak void HAL_HSEM_FreeCallback(uint32_t SemMask)
0429 {
0430   /* Prevent unused argument(s) compilation warning */
0431   UNUSED(SemMask);
0432 
0433   /* NOTE : This function should not be modified, when the callback is needed,
0434   the HAL_HSEM_FreeCallback can be implemented in the user file
0435     */
0436 }
0437 
0438 /**
0439   * @}
0440   */
0441 
0442 /**
0443   * @}
0444   */
0445 
0446 #endif /* HAL_HSEM_MODULE_ENABLED */
0447 /**
0448   * @}
0449   */
0450 
0451 /**
0452   * @}
0453   */