rt-thread/bsp/nuvoton/libraries/ma35/StdDriver/inc/nu_hwsem.h

175 lines
5.3 KiB
C

/**************************************************************************//**
* @file nu_hwsem.h
* @brief HWSEM driver header file
*
* SPDX-License-Identifier: Apache-2.0
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#ifndef __NU_HWSEM_H__
#define __NU_HWSEM_H__
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup Standard_Driver Standard Driver
@{
*/
/** @addtogroup HWSEM_Driver HWSEM Driver
@{
*/
/** @addtogroup HWSEM_EXPORTED_CONSTANTS HWSEM Exported Constants
@{
*/
#define HWSEM_CNT 8ul /*!<HWSEM count \hideinitializer */
#define HWSEM_LOCK_BY_A35 1ul /*!<Semaphore lock by A35 \hideinitializer */
#define HWSEM_LOCK_BY_M4 2ul /*!<Semaphore lock by M4 \hideinitializer */
/*@}*/ /* end of group HWSEM_EXPORTED_CONSTANTS */
/** @addtogroup HWSEM_EXPORTED_FUNCTIONS HWSEM Exported Functions
@{
*/
/**
* @brief Reset hardware semaphore
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
* \hideinitializer
*/
#define HWSEM_RESET(hwsem, u32Num) ((hwsem)->CTL |= (HWSEM_CTL_SEM0RST_Msk << (u32Num)))
/**
* @brief
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
*
* @retval 0 The specified semaphore is not locked.
* Otherwise The specified semaphore is locked.
* \hideinitializer
*/
#define HWSEM_IS_LOCKED(hwsem, u32Num) ((hwsem)->SEM[(u32Num)] & (HWSEM_SEM_ID_Msk))
/**
* @brief Enable specified HWSEM interrupt
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
*
*
* \hideinitializer
*/
#define HWSEM_ENABLE_INT(hwsem, u32Num) ((hwsem)->INTENM4 |= (HWSEM_INTENM4_SEM0IEN_Msk << (u32Num)))
/**
* @brief Disable specified HWSEM interrupt
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
*
*
* \hideinitializer
*/
#define HWSEM_DISABLE_INT(hwsem, u32Num) ((hwsem)->INTENM4 &= ~(HWSEM_INTENM4_SEM0IEN_Msk << (u32Num)))
/**
* @brief Get specified interrupt flag
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
*
* @retval 0 The specified interrupt is not happened.
* Otherwise The specified interrupt is happened.
* \hideinitializer
*/
#define HWSEM_GET_INT_FLAG(hwsem, u32Num) ((hwsem)->INTSTSM4 & (HWSEM_INTSTSM4_SEM0IF_Msk << (u32Num)))
/**
* @brief Clear specified interrupt flag
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
*
* \hideinitializer
*/
#define HWSEM_CLR_INT_FLAG(hwsem, u32Num) ((hwsem)->INTSTSM4 = (HWSEM_INTSTSM4_SEM0IF_Msk << (u32Num)))
/**
* @brief Unlock specified semaphore
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
* @param[in] u8Key HWSEM channel key
*
* \hideinitializer
*/
#define HWSEM_UNLOCK(hwsem, u32Num, u8Key) ((hwsem)->SEM[(u32Num)] = ((u8Key) << HWSEM_SEM_KEY_Pos) & HWSEM_SEM_KEY_Msk)
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE int32_t HWSEM_Try_Lock(HWSEM_T *hwsem, uint32_t u32Num, uint8_t u8Key);
__STATIC_INLINE void HWSEM_Spin_Lock(HWSEM_T *hwsem, uint32_t u32Num, uint8_t u8Key);
/**
* @brief Try to lock specified semaphore
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
* @param[in] u8Key HWSEM channel key
* @retval 0 Successfully acquire semaphore
* @retval -1 Failed to acquire semaphore
* \hideinitializer
*/
__STATIC_INLINE int32_t HWSEM_Try_Lock(HWSEM_T *hwsem, uint32_t u32Num, uint8_t u8Key)
{
hwsem->SEM[u32Num] = (u8Key << HWSEM_SEM_KEY_Pos);
if ((hwsem->SEM[u32Num] & HWSEM_SEM_ID_Msk) == HWSEM_LOCK_BY_M4 &&
(hwsem->SEM[u32Num] & HWSEM_SEM_KEY_Msk) == (u8Key << HWSEM_SEM_KEY_Pos))
return 0;
else
return -1;
}
/**
* @brief Spin until lock specified semaphore
*
* @param[in] hwsem The pointer of the specified HWSEM module.
* @param[in] u32Num HWSEM number, valid values are between 0~7
* @param[in] u8Key HWSEM channel key
*
* \hideinitializer
*/
__STATIC_INLINE void HWSEM_Spin_Lock(HWSEM_T *hwsem, uint32_t u32Num, uint8_t u8Key)
{
while (1)
{
hwsem->SEM[u32Num] = (u8Key << HWSEM_SEM_KEY_Pos);
if ((hwsem->SEM[u32Num] & HWSEM_SEM_ID_Msk) == HWSEM_LOCK_BY_M4 &&
(hwsem->SEM[u32Num] & HWSEM_SEM_KEY_Msk) == (u8Key << HWSEM_SEM_KEY_Pos))
break;
}
}
/*@}*/ /* end of group HWSEM_EXPORTED_FUNCTIONS */
/*@}*/ /* end of group HWSEM_Driver */
/*@}*/ /* end of group Standard_Driver */
#ifdef __cplusplus
}
#endif
#endif