• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef _HPM_COMMON_H
9 #define _HPM_COMMON_H
10 
11 #include <assert.h>
12 #include <stdbool.h>
13 #include <stdint.h>
14 #include <string.h>
15 #include <stdlib.h>
16 
17 /**
18  *
19  * @brief COMMON driver APIs
20  * @defgroup common_interface COMMON driver APIs
21  * @{
22  *
23  */
24 
25 #define __R volatile const /* Define "read-only" permission */
26 #define __RW volatile      /* Define "read-write" permission */
27 #define __W volatile       /* Define "write-only" permission */
28 
29 #ifndef __I
30 #define __I __R
31 #endif
32 
33 #ifndef __IO
34 #define __IO __RW
35 #endif
36 
37 #ifndef __O
38 #define __O __W
39 #endif
40 
41 #ifndef ARRAY_SIZE
42 #define ARRAY_SIZE(a)   (sizeof(a) / sizeof((a)[0]))
43 #endif
44 
45 #ifndef MAX
46 #define MAX(a, b) ((a) > (b) ? (a) : (b))
47 #endif
48 #ifndef MIN
49 #define MIN(a, b) ((a) < (b) ? (a) : (b))
50 #endif
51 
52 #define HPM_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
53 #define IS_HPM_BITMASK_SET(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) != 0U)
54 #define IS_HPM_BIT_SET(val, offset) (((uint32_t)(val) & (1UL << (offset))) != 0U)
55 #define IS_HPM_BITMASK_CLR(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) == 0U)
56 #define IS_HPM_BIT_CLR(val, offset) (((uint32_t)(val) & (1UL << (offset))) == 0U)
57 
58 #define HPM_BREAK_IF(cond)   if (cond) { break; }
59 #define HPM_CONTINUE_IF(cond) if (cond) { continue; }
60 
61 #define HPM_CHECK_RET(x)               \
62     do {                               \
63         stat = (x);                    \
64         if (status_success != stat) { \
65             return stat;               \
66         }                              \
67     } while (false)
68 
69 #define SIZE_1KB (1024UL)
70 #define SIZE_1MB (1048576UL)
71 
72 typedef uint32_t hpm_stat_t;
73 
74 /* @brief Enum definition for the Status group
75  * Rule:
76  *  [Group] 0-999 for the SoC driver and the corresponding components
77  *       1000 or above for the application status group
78  *  [Code]  Valid value: 0-999
79  *
80  */
81 #define MAKE_STATUS(group, code) ((uint32_t)(group)*1000U + (uint32_t)(code))
82 /* @brief System status group definitions */
83 enum {
84     status_group_common = 0,
85     status_group_uart = 1,
86     status_group_i2c = 2,
87     status_group_spi = 3,
88     status_group_usb = 4,
89     status_group_i2s = 5,
90     status_group_xpi = 6,
91     status_group_l1c,
92     status_group_dma,
93     status_group_dram,
94     status_group_sdp,
95     status_group_xpi_nor,
96     status_group_otp,
97     status_group_lcdc,
98     status_group_mbx,
99     status_group_rng,
100     status_group_pdma,
101     status_group_wdg,
102     status_group_pmic_sec,
103     status_group_can,
104     status_group_sdxc,
105     status_group_pcfg,
106     status_group_clk,
107     status_group_pllctl,
108     status_group_pllctlv2,
109     status_group_ffa,
110 
111     status_group_middleware_start = 500,
112     status_group_sdmmc = status_group_middleware_start,
113     status_group_audio_codec,
114     status_group_dma_manager,
115 };
116 
117 /* @brief Common status code definitions */
118 enum {
119     status_success = MAKE_STATUS(status_group_common, 0),
120     status_fail = MAKE_STATUS(status_group_common, 1),
121     status_invalid_argument = MAKE_STATUS(status_group_common, 2),
122     status_timeout = MAKE_STATUS(status_group_common, 3),
123 };
124 
125 #if defined(__GNUC__)
126 
127 /* alway_inline */
128 #define ATTR_ALWAYS_INLINE __attribute__((always_inline))
129 
130 /* weak */
131 #define ATTR_WEAK __attribute__((weak))
132 
133 /* alignment */
134 #define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
135 
136 /* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
137 #define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
138 
139 #define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
140 ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
141 
142 #define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable")
143 #define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
144     ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
145 
146 #define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
147 #define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
148     ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
149 
150 /* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
151 #define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
152 #define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
153     ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
154 
155 #define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
156 #define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
157     ATTR_RAMFUNC ATTR_ALIGN(alignment)
158 
159 #define ATTR_RPMSG ATTR_PLACE_AT(".noinit.rpmsg_sh_mem")
160 
161 #else
162 #error Unknown toolchain
163 #endif
164 
165 #ifdef __cplusplus
166 extern "C" {
167 #endif
168 
169 
170 /**
171  * @brief   Count bits set to 1
172  *
173  * @param value Data to be counted
174  *
175  * @return number of bits set to 1
176  */
count_set_bits(uint32_t value)177 static inline uint32_t count_set_bits(uint32_t value)
178 {
179     if (value == 0) {
180         return 0;
181     }
182     return 1 + count_set_bits(value & (value - 1));
183 }
184 
185 /**
186  * @brief   Count bits set to 1 from least significant bit
187  *
188  * @param value Data to be counted
189  *
190  * @return number of bits set to 1
191  * @return 0xFFFFFFFF if no bit was set to 1
192  */
get_first_set_bit_from_lsb(uint32_t value)193 static inline uint32_t get_first_set_bit_from_lsb(uint32_t value)
194 {
195     uint32_t i = 0;
196     if (!value) {
197         return 0xFFFFFFFFUL;
198     }
199     while (value && !(value & 0x1)) {
200         value >>= 1;
201         i++;
202     }
203     return i;
204 }
205 
206 /**
207  * @brief   Count bits set to 1 from most significant bit
208  *
209  * @param value Data to be counted
210  *
211  * @return number of bits set to 1
212  * @return 0xFFFFFFFF if no bit was set to 1
213  */
get_first_set_bit_from_msb(uint32_t value)214 static inline uint32_t get_first_set_bit_from_msb(uint32_t value)
215 {
216     uint32_t i = 31;
217     if (!value) {
218         return 0xFFFFFFFFUL;
219     }
220     while (value && !(value & 0x80000000)) {
221         value <<= 1;
222         value &= ~1;
223         i--;
224     }
225     return i;
226 }
227 
228 #ifdef __cplusplus
229 }
230 #endif
231 
232 /**
233  * @}
234  */
235 #endif /* _HPM_COMMON_H */
236