summaryrefslogtreecommitdiff
path: root/bsp/nuvoton/libraries/ma35/StdDriver/inc/nu_hwsem.h
blob: a46de00ae0025faf1ebcbdcc384d960b85dc8f51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/**************************************************************************//**
 * @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

#ifdef __has_include
    #if __has_include("rtconfig.h")
        #include "rtconfig.h"
    #endif
#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_NOLOCK            0ul     /*!<Semaphore is non-lock \hideinitializer */
#define HWSEM_LOCK_BY_A35       1ul     /*!<Semaphore lock by A35 \hideinitializer */
#define HWSEM_LOCK_BY_M4        2ul     /*!<Semaphore lock by M4 \hideinitializer */

#if defined(USE_MA35D1_SUBM)
#define HWSEM_LOCK_BY_OWNER     HWSEM_LOCK_BY_M4
#define INTSTS_CORE                         INTSTSM4
#define INTEN_CORE                          INTENM4
#else
#define HWSEM_LOCK_BY_OWNER     HWSEM_LOCK_BY_A35
#define INTSTS_CORE                         INTSTSA35
#define INTEN_CORE                          INTENA35
#endif
#define HWSEM_INTSTS_SEM0IF_Pos     0
#define HWSEM_INTSTS_SEM0IF_Msk     (1<<HWSEM_INTSTS_SEM0IF_Pos)
#define HWSEM_INTEN_SEM0IEN_Pos     0
#define HWSEM_INTEN_SEM0IEN_Msk     (1<<HWSEM_INTEN_SEM0IEN_Pos)

/*@}*/ /* 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
  *
  * @param[in]  hwsem         The pointer of the specified HWSEM module.
  * @param[in]  u32Num        HWSEM number, valid values are between 0~7
  *
  * @retval       0 The key of specified semaphore.
  * \hideinitializer
  */
#define HWSEM_GET_KEY(hwsem, u32Num)         (((hwsem)->SEM[(u32Num)]&HWSEM_SEM_KEY_Msk) >> HWSEM_SEM_KEY_Pos)

/**
  * @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)->INTEN_CORE |= (HWSEM_INTEN_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)->INTEN_CORE &= ~(HWSEM_INTEN_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)->INTSTS_CORE & (HWSEM_INTSTS_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)->INTSTS_CORE = (HWSEM_INTSTS_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)
#define HWSEM_LOCK   HWSEM_UNLOCK

/* 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_OWNER &&
            (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_OWNER &&
                (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