| /** |
| ****************************************************************************** |
| * @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 */ |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |