You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

442 lines
14 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_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. @verbatim
  18. ==============================================================================
  19. ##### How to use this driver #####
  20. ==============================================================================
  21. [..]
  22. (#)Take a semaphore In 2-Step mode Using function HAL_HSEM_Take. This function takes as parameters :
  23. (++) the semaphore ID from 0 to 31
  24. (++) the process ID from 0 to 255
  25. (#) Fast Take semaphore In 1-Step mode Using function HAL_HSEM_FastTake. This function takes as parameter :
  26. (++) the semaphore ID from 0_ID to 31. Note that the process ID value is implicitly assumed as zero
  27. (#) Check if a semaphore is Taken using function HAL_HSEM_IsSemTaken. This function takes as parameter :
  28. (++) the semaphore ID from 0_ID to 31
  29. (++) It returns 1 if the given semaphore is taken otherwise (Free) zero
  30. (#)Release a semaphore using function with HAL_HSEM_Release. This function takes as parameters :
  31. (++) the semaphore ID from 0 to 31
  32. (++) the process ID from 0 to 255:
  33. (++) Note: If ProcessID and MasterID match, semaphore is freed, and an interrupt
  34. may be generated when enabled (notification activated). If ProcessID or MasterID does not match,
  35. semaphore remains taken (locked)
  36. (#)Release all semaphores at once taken by a given Master using function HAL_HSEM_Release_All
  37. This function takes as parameters :
  38. (++) the Release Key (value from 0 to 0xFFFF) can be Set or Get respectively by
  39. HAL_HSEM_SetClearKey() or HAL_HSEM_GetClearKey functions
  40. (++) the Master ID:
  41. (++) Note: If the Key and MasterID match, all semaphores taken by the given CPU that corresponds
  42. to MasterID will be freed, and an interrupt may be generated when enabled (notification activated). If the
  43. Key or the MasterID doesn't match, semaphores remains taken (locked)
  44. (#)Semaphores Release all key functions:
  45. (++) HAL_HSEM_SetClearKey() to set semaphore release all Key
  46. (++) HAL_HSEM_GetClearKey() to get release all Key
  47. (#)Semaphores notification functions :
  48. (++) HAL_HSEM_ActivateNotification to activate a notification callback on
  49. a given semaphores Mask (bitfield). When one or more semaphores defined by the mask are released
  50. the callback HAL_HSEM_FreeCallback will be asserted giving as parameters a mask of the released
  51. semaphores (bitfield).
  52. (++) HAL_HSEM_DeactivateNotification to deactivate the notification of a given semaphores Mask (bitfield).
  53. (++) See the description of the macro __HAL_HSEM_SEMID_TO_MASK to check how to calculate a semaphore mask
  54. Used by the notification functions
  55. *** HSEM HAL driver macros list ***
  56. =============================================
  57. [..] Below the list of most used macros in HSEM HAL driver.
  58. (+) __HAL_HSEM_SEMID_TO_MASK: Helper macro to convert a Semaphore ID to a Mask.
  59. [..] Example of use :
  60. [..] mask = __HAL_HSEM_SEMID_TO_MASK(8) | __HAL_HSEM_SEMID_TO_MASK(21) | __HAL_HSEM_SEMID_TO_MASK(25).
  61. [..] All next macros take as parameter a semaphore Mask (bitfiled) that can be constructed using __HAL_HSEM_SEMID_TO_MASK as the above example.
  62. (+) __HAL_HSEM_ENABLE_IT: Enable the specified semaphores Mask interrupts.
  63. (+) __HAL_HSEM_DISABLE_IT: Disable the specified semaphores Mask interrupts.
  64. (+) __HAL_HSEM_GET_IT: Checks whether the specified semaphore interrupt has occurred or not.
  65. (+) __HAL_HSEM_GET_FLAG: Get the semaphores status release flags.
  66. (+) __HAL_HSEM_CLEAR_FLAG: Clear the semaphores status release flags.
  67. @endverbatim
  68. ******************************************************************************
  69. * @attention
  70. *
  71. * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  72. * All rights reserved.</center></h2>
  73. *
  74. * This software component is licensed by ST under BSD 3-Clause license,
  75. * the "License"; You may not use this file except in compliance with the
  76. * License. You may obtain a copy of the License at:
  77. * opensource.org/licenses/BSD-3-Clause
  78. *
  79. ******************************************************************************
  80. */
  81. /* Includes ------------------------------------------------------------------*/
  82. #include "stm32h7xx_hal.h"
  83. /** @addtogroup STM32H7xx_HAL_Driver
  84. * @{
  85. */
  86. /** @defgroup HSEM HSEM
  87. * @brief HSEM HAL module driver
  88. * @{
  89. */
  90. #ifdef HAL_HSEM_MODULE_ENABLED
  91. /* Private typedef -----------------------------------------------------------*/
  92. /* Private define ------------------------------------------------------------*/
  93. #if defined(DUAL_CORE)
  94. #ifndef HSEM_R_MASTERID
  95. #define HSEM_R_MASTERID HSEM_R_COREID
  96. #endif
  97. #ifndef HSEM_RLR_MASTERID
  98. #define HSEM_RLR_MASTERID HSEM_RLR_COREID
  99. #endif
  100. #ifndef HSEM_CR_MASTERID
  101. #define HSEM_CR_MASTERID HSEM_CR_COREID
  102. #endif
  103. #endif /* DUAL_CORE */
  104. /* Private macro -------------------------------------------------------------*/
  105. /* Private variables ---------------------------------------------------------*/
  106. /* Private function prototypes -----------------------------------------------*/
  107. /* Private functions ---------------------------------------------------------*/
  108. /* Exported functions --------------------------------------------------------*/
  109. /** @defgroup HSEM_Exported_Functions HSEM Exported Functions
  110. * @{
  111. */
  112. /** @defgroup HSEM_Exported_Functions_Group1 Take and Release functions
  113. * @brief HSEM Take and Release functions
  114. *
  115. @verbatim
  116. ==============================================================================
  117. ##### HSEM Take and Release functions #####
  118. ==============================================================================
  119. [..] This section provides functions allowing to:
  120. (+) Take a semaphore with 2 Step method
  121. (+) Fast Take a semaphore with 1 Step method
  122. (+) Check semaphore state Taken or not
  123. (+) Release a semaphore
  124. (+) Release all semaphore at once
  125. @endverbatim
  126. * @{
  127. */
  128. /**
  129. * @brief Take a semaphore in 2 Step mode.
  130. * @param SemID: semaphore ID from 0 to 31
  131. * @param ProcessID: Process ID from 0 to 255
  132. * @retval HAL status
  133. */
  134. HAL_StatusTypeDef HAL_HSEM_Take(uint32_t SemID, uint32_t ProcessID)
  135. {
  136. /* Check the parameters */
  137. assert_param(IS_HSEM_SEMID(SemID));
  138. assert_param(IS_HSEM_PROCESSID(ProcessID));
  139. #if USE_MULTI_CORE_SHARED_CODE != 0U
  140. /* First step write R register with MasterID, processID and take bit=1*/
  141. HSEM->R[SemID] = ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK);
  142. /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
  143. if (HSEM->R[SemID] == ((ProcessID & HSEM_R_PROCID) | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID) | HSEM_R_LOCK))
  144. {
  145. /*take success when MasterID and ProcessID match and take bit set*/
  146. return HAL_OK;
  147. }
  148. #else
  149. /* First step write R register with MasterID, processID and take bit=1*/
  150. HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK);
  151. /* second step : read the R register . Take achieved if MasterID and processID match and take bit set to 1 */
  152. if (HSEM->R[SemID] == (ProcessID | HSEM_CR_COREID_CURRENT | HSEM_R_LOCK))
  153. {
  154. /*take success when MasterID and ProcessID match and take bit set*/
  155. return HAL_OK;
  156. }
  157. #endif
  158. /* Semaphore take fails*/
  159. return HAL_ERROR;
  160. }
  161. /**
  162. * @brief Fast Take a semaphore with 1 Step mode.
  163. * @param SemID: semaphore ID from 0 to 31
  164. * @retval HAL status
  165. */
  166. HAL_StatusTypeDef HAL_HSEM_FastTake(uint32_t SemID)
  167. {
  168. /* Check the parameters */
  169. assert_param(IS_HSEM_SEMID(SemID));
  170. #if USE_MULTI_CORE_SHARED_CODE != 0U
  171. /* Read the RLR register to take the semaphore */
  172. if (HSEM->RLR[SemID] == (((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_RLR_MASTERID) | HSEM_RLR_LOCK))
  173. {
  174. /*take success when MasterID match and take bit set*/
  175. return HAL_OK;
  176. }
  177. #else
  178. /* Read the RLR register to take the semaphore */
  179. if (HSEM->RLR[SemID] == (HSEM_CR_COREID_CURRENT | HSEM_RLR_LOCK))
  180. {
  181. /*take success when MasterID match and take bit set*/
  182. return HAL_OK;
  183. }
  184. #endif
  185. /* Semaphore take fails */
  186. return HAL_ERROR;
  187. }
  188. /**
  189. * @brief Check semaphore state Taken or not.
  190. * @param SemID: semaphore ID
  191. * @retval HAL HSEM state
  192. */
  193. uint32_t HAL_HSEM_IsSemTaken(uint32_t SemID)
  194. {
  195. return (((HSEM->R[SemID] & HSEM_R_LOCK) != 0U) ? 1UL : 0UL);
  196. }
  197. /**
  198. * @brief Release a semaphore.
  199. * @param SemID: semaphore ID from 0 to 31
  200. * @param ProcessID: Process ID from 0 to 255
  201. * @retval None
  202. */
  203. void HAL_HSEM_Release(uint32_t SemID, uint32_t ProcessID)
  204. {
  205. /* Check the parameters */
  206. assert_param(IS_HSEM_SEMID(SemID));
  207. assert_param(IS_HSEM_PROCESSID(ProcessID));
  208. /* Clear the semaphore by writing to the R register : the MasterID , the processID and take bit = 0 */
  209. #if USE_MULTI_CORE_SHARED_CODE != 0U
  210. HSEM->R[SemID] = (ProcessID | ((HAL_GetCurrentCPUID() << POSITION_VAL(HSEM_R_MASTERID)) & HSEM_R_MASTERID));
  211. #else
  212. HSEM->R[SemID] = (ProcessID | HSEM_CR_COREID_CURRENT);
  213. #endif
  214. }
  215. /**
  216. * @brief Release All semaphore used by a given Master .
  217. * @param Key: Semaphore Key , value from 0 to 0xFFFF
  218. * @param CoreID: CoreID of the CPU that is using semaphores to be released
  219. * @retval None
  220. */
  221. void HAL_HSEM_ReleaseAll(uint32_t Key, uint32_t CoreID)
  222. {
  223. assert_param(IS_HSEM_KEY(Key));
  224. assert_param(IS_HSEM_COREID(CoreID));
  225. HSEM->CR = ((Key << HSEM_CR_KEY_Pos) | (CoreID << HSEM_CR_COREID_Pos));
  226. }
  227. /**
  228. * @}
  229. */
  230. /** @defgroup HSEM_Exported_Functions_Group2 HSEM Set and Get Key functions
  231. * @brief HSEM Set and Get Key functions.
  232. *
  233. @verbatim
  234. ==============================================================================
  235. ##### HSEM Set and Get Key functions #####
  236. ==============================================================================
  237. [..] This section provides functions allowing to:
  238. (+) Set semaphore Key
  239. (+) Get semaphore Key
  240. @endverbatim
  241. * @{
  242. */
  243. /**
  244. * @brief Set semaphore Key .
  245. * @param Key: Semaphore Key , value from 0 to 0xFFFF
  246. * @retval None
  247. */
  248. void HAL_HSEM_SetClearKey(uint32_t Key)
  249. {
  250. assert_param(IS_HSEM_KEY(Key));
  251. MODIFY_REG(HSEM->KEYR, HSEM_KEYR_KEY, (Key << HSEM_KEYR_KEY_Pos));
  252. }
  253. /**
  254. * @brief Get semaphore Key .
  255. * @retval Semaphore Key , value from 0 to 0xFFFF
  256. */
  257. uint32_t HAL_HSEM_GetClearKey(void)
  258. {
  259. return (HSEM->KEYR >> HSEM_KEYR_KEY_Pos);
  260. }
  261. /**
  262. * @}
  263. */
  264. /** @defgroup HSEM_Exported_Functions_Group3 HSEM IRQ handler management
  265. * @brief HSEM Notification functions.
  266. *
  267. @verbatim
  268. ==============================================================================
  269. ##### HSEM IRQ handler management and Notification functions #####
  270. ==============================================================================
  271. [..] This section provides HSEM IRQ handler and Notification function.
  272. @endverbatim
  273. * @{
  274. */
  275. /**
  276. * @brief Activate Semaphore release Notification for a given Semaphores Mask .
  277. * @param SemMask: Mask of Released semaphores
  278. * @retval Semaphore Key
  279. */
  280. void HAL_HSEM_ActivateNotification(uint32_t SemMask)
  281. {
  282. #if USE_MULTI_CORE_SHARED_CODE != 0U
  283. /*enable the semaphore mask interrupts */
  284. if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
  285. {
  286. /*Use interrupt line 0 for CPU1 Master */
  287. HSEM->C1IER |= SemMask;
  288. }
  289. else /* HSEM_CPU2_COREID */
  290. {
  291. /*Use interrupt line 1 for CPU2 Master*/
  292. HSEM->C2IER |= SemMask;
  293. }
  294. #else
  295. HSEM_COMMON->IER |= SemMask;
  296. #endif
  297. }
  298. /**
  299. * @brief Deactivate Semaphore release Notification for a given Semaphores Mask .
  300. * @param SemMask: Mask of Released semaphores
  301. * @retval Semaphore Key
  302. */
  303. void HAL_HSEM_DeactivateNotification(uint32_t SemMask)
  304. {
  305. #if USE_MULTI_CORE_SHARED_CODE != 0U
  306. /*enable the semaphore mask interrupts */
  307. if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
  308. {
  309. /*Use interrupt line 0 for CPU1 Master */
  310. HSEM->C1IER &= ~SemMask;
  311. }
  312. else /* HSEM_CPU2_COREID */
  313. {
  314. /*Use interrupt line 1 for CPU2 Master*/
  315. HSEM->C2IER &= ~SemMask;
  316. }
  317. #else
  318. HSEM_COMMON->IER &= ~SemMask;
  319. #endif
  320. }
  321. /**
  322. * @brief This function handles HSEM interrupt request
  323. * @retval None
  324. */
  325. void HAL_HSEM_IRQHandler(void)
  326. {
  327. uint32_t statusreg;
  328. #if USE_MULTI_CORE_SHARED_CODE != 0U
  329. if (HAL_GetCurrentCPUID() == HSEM_CPU1_COREID)
  330. {
  331. /* Get the list of masked freed semaphores*/
  332. statusreg = HSEM->C1MISR; /*Use interrupt line 0 for CPU1 Master*/
  333. /*Disable Interrupts*/
  334. HSEM->C1IER &= ~((uint32_t)statusreg);
  335. /*Clear Flags*/
  336. HSEM->C1ICR = ((uint32_t)statusreg);
  337. }
  338. else /* HSEM_CPU2_COREID */
  339. {
  340. /* Get the list of masked freed semaphores*/
  341. statusreg = HSEM->C2MISR;/*Use interrupt line 1 for CPU2 Master*/
  342. /*Disable Interrupts*/
  343. HSEM->C2IER &= ~((uint32_t)statusreg);
  344. /*Clear Flags*/
  345. HSEM->C2ICR = ((uint32_t)statusreg);
  346. }
  347. #else
  348. /* Get the list of masked freed semaphores*/
  349. statusreg = HSEM_COMMON->MISR;
  350. /*Disable Interrupts*/
  351. HSEM_COMMON->IER &= ~((uint32_t)statusreg);
  352. /*Clear Flags*/
  353. HSEM_COMMON->ICR = ((uint32_t)statusreg);
  354. #endif
  355. /* Call FreeCallback */
  356. HAL_HSEM_FreeCallback(statusreg);
  357. }
  358. /**
  359. * @brief Semaphore Released Callback.
  360. * @param SemMask: Mask of Released semaphores
  361. * @retval None
  362. */
  363. __weak void HAL_HSEM_FreeCallback(uint32_t SemMask)
  364. {
  365. /* Prevent unused argument(s) compilation warning */
  366. UNUSED(SemMask);
  367. /* NOTE : This function should not be modified, when the callback is needed,
  368. the HAL_HSEM_FreeCallback can be implemented in the user file
  369. */
  370. }
  371. /**
  372. * @}
  373. */
  374. /**
  375. * @}
  376. */
  377. #endif /* HAL_HSEM_MODULE_ENABLED */
  378. /**
  379. * @}
  380. */
  381. /**
  382. * @}
  383. */
  384. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/