HPM SDK
HPMicro Software Development Kit
hpm_common.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-2025 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 
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 #ifndef HPM_ALIGN_DOWN
53 #define HPM_ALIGN_DOWN(a, n) ((uint32_t)(a) & ~(n-1U))
54 #endif
55 
56 #ifndef HPM_ALIGN_UP
57 #define HPM_ALIGN_UP(a, n) (((uint32_t)(a) + (n-1U)) & ~(n-1U))
58 #endif
59 
60 #define HPM_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
61 #define IS_HPM_BITMASK_SET(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) != 0U)
62 #define IS_HPM_BIT_SET(val, offset) (((uint32_t)(val) & (1UL << (offset))) != 0U)
63 #define IS_HPM_BITMASK_CLR(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) == 0U)
64 #define IS_HPM_BIT_CLR(val, offset) (((uint32_t)(val) & (1UL << (offset))) == 0U)
65 
66 #define HPM_BREAK_IF(cond) if (cond) { break; }
67 #define HPM_CONTINUE_IF(cond) if (cond) { continue; }
68 
69 #define HPM_DIV_ROUND_CLOSEST(x, div) (((x) + (div) / 2) / (div))
70 #define HPM_DIV_ROUND_UP(x, div) (((x) + (div) - 1) / (div))
71 
72 #define HPM_NUM_TO_EVEN_CEILING(x) ((x + 1) & 0xFFFFFFFEUL)
73 #define HPM_NUM_TO_EVEN_FLOOR(x) ((x) & 0xFFFFFFFEUL)
74 
75 #define HPM_CHECK_RET(x) \
76  do { \
77  stat = (x); \
78  if (status_success != stat) { \
79  return stat; \
80  } \
81  } while (false)
82 
83 #define _HPM_STRINGIFY(x) #x
84 #define HPM_STRINGIFY(x) _HPM_STRINGIFY(x)
85 
86 #define SIZE_1KB (1024UL)
87 #define SIZE_1MB (1048576UL)
88 
89 #define BIT0_MASK (0x00000001UL)
90 #define BIT1_MASK (0x00000002UL)
91 #define BIT2_MASK (0x00000004UL)
92 #define BIT3_MASK (0x00000008UL)
93 #define BIT4_MASK (0x00000010UL)
94 #define BIT5_MASK (0x00000020UL)
95 #define BIT6_MASK (0x00000040UL)
96 #define BIT7_MASK (0x00000080UL)
97 #define BIT8_MASK (0x00000100UL)
98 #define BIT9_MASK (0x00000200UL)
99 #define BIT10_MASK (0x00000400UL)
100 #define BIT11_MASK (0x00000800UL)
101 #define BIT12_MASK (0x00001000UL)
102 #define BIT13_MASK (0x00002000UL)
103 #define BIT14_MASK (0x00004000UL)
104 #define BIT15_MASK (0x00008000UL)
105 #define BIT16_MASK (0x00010000UL)
106 #define BIT17_MASK (0x00020000UL)
107 #define BIT18_MASK (0x00040000UL)
108 #define BIT19_MASK (0x00080000UL)
109 #define BIT20_MASK (0x00100000UL)
110 #define BIT21_MASK (0x00200000UL)
111 #define BIT22_MASK (0x00400000UL)
112 #define BIT23_MASK (0x00800000UL)
113 #define BIT24_MASK (0x01000000UL)
114 #define BIT25_MASK (0x02000000UL)
115 #define BIT26_MASK (0x04000000UL)
116 #define BIT27_MASK (0x08000000UL)
117 #define BIT28_MASK (0x10000000UL)
118 #define BIT29_MASK (0x20000000UL)
119 #define BIT30_MASK (0x40000000UL)
120 #define BIT31_MASK (0x80000000UL)
121 
122 #define HPM_PI (3.14159265358979323846)
123 #define HPM_2_PI (6.28318530717958647692)
124 #define HPM_HALF_PI (1.57079632679489661923)
125 
126 typedef uint32_t hpm_stat_t;
127 
128 /* @brief Enum definition for the Status group
129  * Rule:
130  * [Group] 0-999 for the SoC driver and the corresponding components
131  * 1000 or above for the application status group
132  * [Code] Valid value: 0-999
133  *
134  */
135 #define MAKE_STATUS(group, code) ((uint32_t)(group)*1000U + (uint32_t)(code))
136 /* @brief System status group definitions */
137 enum {
167 
176 };
177 
178 /* @brief Common status code definitions */
179 enum {
184 };
185 
186 #if defined(__GNUC__)
187 /* weak */
188 #define ATTR_WEAK __attribute__((weak))
189 
190 #define HPM_ATTR_MACHINE_INTERRUPT __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)))
191 #define HPM_ATTR_SUPERVISOR_INTERRUPT __attribute__ ((section(".isr_s_vector"), interrupt("supervisor"), aligned(4)))
192 
193 #elif defined(__ICCRISCV__)
194 /* weak */
195 #define ATTR_WEAK __weak
196 
197 #define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt
198 #define HPM_ATTR_SUPERVISOR_INTERRUPT __supervisor __interrupt
199 
200 #ifndef __TIMEVAL_DEFINED
201 #define __TIMEVAL_DEFINED 1
202 struct timeval {
203  long tv_sec; /* Seconds since the Epoch */
204  long tv_usec; /* Microseconds */
205 };
206 #endif
207 
208 #else
209 #error Unknown toolchain
210 #endif
211 
212 #if defined(__GNUC__) || defined(__ICCRISCV__)
213 
214 /* alway_inline */
215 #define ATTR_ALWAYS_INLINE __attribute__((always_inline))
216 
217 /* alignment */
218 #define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
219 #define ATTR_PACKED __attribute__((packed, aligned(1)))
220 
221 /* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
222 #define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
223 
224 #define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
225 ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
226 
227 /* ATTR_PLACE_AT_NONCACHEABLE is legacy attribute, ATTR_PLACE_AT_NONCACHEABLE_NON_INIT instead of this */
228 #define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable")
229 #define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
230  ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
231 
232 #define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
233 #define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
234  ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
235 
236 /* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
237 #define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
238 #define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
239  ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
240 
241 #define ATTR_PLACE_AT_NONCACHEABLE_NON_INIT ATTR_PLACE_AT(".noncacheable.non_init")
242 #define ATTR_PLACE_AT_NONCACHEABLE_NON_INIT_WITH_ALIGNMENT(alignment) \
243  ATTR_PLACE_AT_NONCACHEABLE_NON_INIT ATTR_ALIGN(alignment)
244 
245 /* .fast_ram section */
246 /* ATTR_PLACE_AT_FAST_RAM is legacy attribute, ATTR_PLACE_AT_FAST_RAM_NON_INIT instead of this */
247 #define ATTR_PLACE_AT_FAST_RAM ATTR_PLACE_AT(".fast_ram")
248 #define ATTR_PLACE_AT_FAST_RAM_WITH_ALIGNMENT(alignment) \
249  ATTR_PLACE_AT_FAST_RAM ATTR_ALIGN(alignment)
250 
251 #define ATTR_PLACE_AT_FAST_RAM_BSS ATTR_PLACE_AT(".fast_ram.bss")
252 #define ATTR_PLACE_AT_FAST_RAM_BSS_WITH_ALIGNMENT(alignment) \
253  ATTR_PLACE_AT_FAST_RAM_BSS ATTR_ALIGN(alignment)
254 
255 #define ATTR_PLACE_AT_FAST_RAM_INIT ATTR_PLACE_AT(".fast_ram.init")
256 #define ATTR_PLACE_AT_FAST_RAM_INIT_WITH_ALIGNMENT(alignment) \
257  ATTR_PLACE_AT_FAST_RAM_INIT ATTR_ALIGN(alignment)
258 
259 #define ATTR_PLACE_AT_FAST_RAM_NON_INIT ATTR_PLACE_AT(".fast_ram.non_init")
260 #define ATTR_PLACE_AT_FAST_RAM_NON_INIT_WITH_ALIGNMENT(alignment) \
261  ATTR_PLACE_AT_FAST_RAM_NON_INIT ATTR_ALIGN(alignment)
262 
263 #define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
264 #define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
265  ATTR_RAMFUNC ATTR_ALIGN(alignment)
266 
267 #define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
268 
269 #define NOP() __asm volatile("nop")
270 #define WFI() __asm volatile("wfi")
271 
272 #endif
273 
274 #ifdef __cplusplus
275 extern "C" {
276 #endif
277 
278 
286 static inline uint32_t count_set_bits(uint32_t value)
287 {
288  if (value == 0) {
289  return 0;
290  }
291  return 1 + count_set_bits(value & (value - 1));
292 }
293 
302 static inline uint32_t get_first_set_bit_from_lsb(uint32_t value)
303 {
304  uint32_t i = 0;
305  if (!value) {
306  return 0xFFFFFFFFUL;
307  }
308  while (value && !(value & 0x1)) {
309  value >>= 1;
310  i++;
311  }
312  return i;
313 }
314 
323 static inline uint32_t get_first_set_bit_from_msb(uint32_t value)
324 {
325  uint32_t i = 31;
326  if (!value) {
327  return 0xFFFFFFFFUL;
328  }
329  while (value && !(value & 0x80000000)) {
330  value <<= 1;
331  value &= ~1;
332  i--;
333  }
334  return i;
335 }
336 
344 static inline uint32_t hpm_convert_ticks_to_us(uint32_t ticks, uint32_t src_clk_freq)
345 {
346  uint32_t ticks_per_us = (src_clk_freq + 1000000UL - 1UL) / 1000000UL;
347  return (ticks + ticks_per_us - 1UL) / ticks_per_us;
348 }
349 
357 static inline uint32_t hpm_convert_ticks_to_ms(uint32_t ticks, uint32_t src_clk_freq)
358 {
359  uint32_t ticks_per_ms = (src_clk_freq + 1000UL - 1UL) / 1000UL;
360  return (ticks + ticks_per_ms - 1UL) / ticks_per_ms;
361 }
362 
363 #ifdef __cplusplus
364 }
365 #endif
366 
370 #endif /* _HPM_COMMON_H */
static uint32_t get_first_set_bit_from_lsb(uint32_t value)
Count bits set to 1 from least significant bit.
Definition: hpm_common.h:302
uint32_t hpm_stat_t
Definition: hpm_common.h:126
static uint32_t hpm_convert_ticks_to_ms(uint32_t ticks, uint32_t src_clk_freq)
Convert the elapsed ticks to milliseconds according to the source clock frequency.
Definition: hpm_common.h:357
static uint32_t get_first_set_bit_from_msb(uint32_t value)
Count bits set to 1 from most significant bit.
Definition: hpm_common.h:323
static uint32_t count_set_bits(uint32_t value)
Count bits set to 1.
Definition: hpm_common.h:286
static uint32_t hpm_convert_ticks_to_us(uint32_t ticks, uint32_t src_clk_freq)
Convert the elapsed ticks to microseconds according to the source clock frequency.
Definition: hpm_common.h:344
#define MAKE_STATUS(group, code)
Definition: hpm_common.h:135
@ status_timeout
Definition: hpm_common.h:183
@ status_invalid_argument
Definition: hpm_common.h:182
@ status_success
Definition: hpm_common.h:180
@ status_fail
Definition: hpm_common.h:181
@ status_group_common
Definition: hpm_common.h:138
@ status_group_usb
Definition: hpm_common.h:142
@ status_group_ewdg
Definition: hpm_common.h:165
@ status_group_i2c
Definition: hpm_common.h:140
@ status_group_audio_codec
Definition: hpm_common.h:170
@ status_group_spi
Definition: hpm_common.h:141
@ status_group_middleware_start
Definition: hpm_common.h:168
@ status_group_mbx
Definition: hpm_common.h:152
@ status_group_can
Definition: hpm_common.h:157
@ status_group_pllctl
Definition: hpm_common.h:161
@ status_group_femc
Definition: hpm_common.h:147
@ status_group_sdmmc
Definition: hpm_common.h:169
@ status_group_ffa
Definition: hpm_common.h:163
@ status_group_uart
Definition: hpm_common.h:139
@ status_group_dma_manager
Definition: hpm_common.h:171
@ status_group_xpi
Definition: hpm_common.h:144
@ status_group_i2s
Definition: hpm_common.h:143
@ status_group_otp
Definition: hpm_common.h:150
@ status_group_mcan
Definition: hpm_common.h:164
@ status_group_pllctlv2
Definition: hpm_common.h:162
@ status_group_sdxc
Definition: hpm_common.h:158
@ status_group_plb_qei_encoder
Definition: hpm_common.h:174
@ status_group_pdma
Definition: hpm_common.h:154
@ status_group_esc
Definition: hpm_common.h:166
@ status_group_spi_nor_flash
Definition: hpm_common.h:172
@ status_group_pmic_sec
Definition: hpm_common.h:156
@ status_group_pmbus
Definition: hpm_common.h:175
@ status_group_clk
Definition: hpm_common.h:160
@ status_group_wdg
Definition: hpm_common.h:155
@ status_group_dma
Definition: hpm_common.h:146
@ status_group_lcdc
Definition: hpm_common.h:151
@ status_group_pcfg
Definition: hpm_common.h:159
@ status_group_touch
Definition: hpm_common.h:173
@ status_group_sdp
Definition: hpm_common.h:148
@ status_group_l1c
Definition: hpm_common.h:145
@ status_group_xpi_nor
Definition: hpm_common.h:149
@ status_group_rng
Definition: hpm_common.h:153