hpm_common.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * Copyright (c) 2021-2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef _HPM_COMMON_H
  8. #define _HPM_COMMON_H
  9. #include <assert.h>
  10. #include <stdbool.h>
  11. #include <stdint.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. /**
  15. *
  16. * @brief COMMON driver APIs
  17. * @defgroup common_interface COMMON driver APIs
  18. * @{
  19. *
  20. */
  21. #define __R volatile const /* Define "read-only" permission */
  22. #define __RW volatile /* Define "read-write" permission */
  23. #define __W volatile /* Define "write-only" permission */
  24. #ifndef __I
  25. #define __I __R
  26. #endif
  27. #ifndef __IO
  28. #define __IO __RW
  29. #endif
  30. #ifndef __O
  31. #define __O __W
  32. #endif
  33. #ifndef ARRAY_SIZE
  34. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  35. #endif
  36. #ifndef MAX
  37. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  38. #endif
  39. #ifndef MIN
  40. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  41. #endif
  42. #ifndef HPM_ALIGN_DOWN
  43. #define HPM_ALIGN_DOWN(a, n) ((uint32_t)(a) & ~(n-1U))
  44. #endif
  45. #ifndef HPM_ALIGN_UP
  46. #define HPM_ALIGN_UP(a, n) (((uint32_t)(a) + (n-1U)) & ~(n-1U))
  47. #endif
  48. #define HPM_BITSMASK(val, offset) ((uint32_t)(val) << (offset))
  49. #define IS_HPM_BITMASK_SET(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) != 0U)
  50. #define IS_HPM_BIT_SET(val, offset) (((uint32_t)(val) & (1UL << (offset))) != 0U)
  51. #define IS_HPM_BITMASK_CLR(val, mask) (((uint32_t)(val) & (uint32_t)(mask)) == 0U)
  52. #define IS_HPM_BIT_CLR(val, offset) (((uint32_t)(val) & (1UL << (offset))) == 0U)
  53. #define HPM_BREAK_IF(cond) if (cond) { break; }
  54. #define HPM_CONTINUE_IF(cond) if (cond) { continue; }
  55. #define HPM_DIV_ROUND_CLOSEST(x, div) (((x) + (div) / 2) / (div))
  56. #define HPM_DIV_ROUND_UP(x, div) (((x) + (div) - 1) / (div))
  57. #define HPM_NUM_TO_EVEN_CEILING(x) ((x + 1) & 0xFFFFFFFEUL)
  58. #define HPM_NUM_TO_EVEN_FLOOR(x) ((x) & 0xFFFFFFFEUL)
  59. #define HPM_CHECK_RET(x) \
  60. do { \
  61. stat = (x); \
  62. if (status_success != stat) { \
  63. return stat; \
  64. } \
  65. } while (false)
  66. #define SIZE_1KB (1024UL)
  67. #define SIZE_1MB (1048576UL)
  68. #define BIT0_MASK (0x00000001UL)
  69. #define BIT1_MASK (0x00000002UL)
  70. #define BIT2_MASK (0x00000004UL)
  71. #define BIT3_MASK (0x00000008UL)
  72. #define BIT4_MASK (0x00000010UL)
  73. #define BIT5_MASK (0x00000020UL)
  74. #define BIT6_MASK (0x00000040UL)
  75. #define BIT7_MASK (0x00000080UL)
  76. #define BIT8_MASK (0x00000100UL)
  77. #define BIT9_MASK (0x00000200UL)
  78. #define BIT10_MASK (0x00000400UL)
  79. #define BIT11_MASK (0x00000800UL)
  80. #define BIT12_MASK (0x00001000UL)
  81. #define BIT13_MASK (0x00002000UL)
  82. #define BIT14_MASK (0x00004000UL)
  83. #define BIT15_MASK (0x00008000UL)
  84. #define BIT16_MASK (0x00010000UL)
  85. #define BIT17_MASK (0x00020000UL)
  86. #define BIT18_MASK (0x00040000UL)
  87. #define BIT19_MASK (0x00080000UL)
  88. #define BIT20_MASK (0x00100000UL)
  89. #define BIT21_MASK (0x00200000UL)
  90. #define BIT22_MASK (0x00400000UL)
  91. #define BIT23_MASK (0x00800000UL)
  92. #define BIT24_MASK (0x01000000UL)
  93. #define BIT25_MASK (0x02000000UL)
  94. #define BIT26_MASK (0x04000000UL)
  95. #define BIT27_MASK (0x08000000UL)
  96. #define BIT28_MASK (0x10000000UL)
  97. #define BIT29_MASK (0x20000000UL)
  98. #define BIT30_MASK (0x40000000UL)
  99. #define BIT31_MASK (0x80000000UL)
  100. typedef uint32_t hpm_stat_t;
  101. /* @brief Enum definition for the Status group
  102. * Rule:
  103. * [Group] 0-999 for the SoC driver and the corresponding components
  104. * 1000 or above for the application status group
  105. * [Code] Valid value: 0-999
  106. *
  107. */
  108. #define MAKE_STATUS(group, code) ((uint32_t)(group)*1000U + (uint32_t)(code))
  109. /* @brief System status group definitions */
  110. enum {
  111. status_group_common = 0,
  112. status_group_uart = 1,
  113. status_group_i2c = 2,
  114. status_group_spi = 3,
  115. status_group_usb = 4,
  116. status_group_i2s = 5,
  117. status_group_xpi = 6,
  118. status_group_l1c,
  119. status_group_dma,
  120. status_group_femc,
  121. status_group_sdp,
  122. status_group_xpi_nor,
  123. status_group_otp,
  124. status_group_lcdc,
  125. status_group_mbx,
  126. status_group_rng,
  127. status_group_pdma,
  128. status_group_wdg,
  129. status_group_pmic_sec,
  130. status_group_can,
  131. status_group_sdxc,
  132. status_group_pcfg,
  133. status_group_clk,
  134. status_group_pllctl,
  135. status_group_pllctlv2,
  136. status_group_ffa,
  137. status_group_mcan,
  138. status_group_ewdg,
  139. status_group_esc,
  140. status_group_middleware_start = 500,
  141. status_group_sdmmc = status_group_middleware_start,
  142. status_group_audio_codec,
  143. status_group_dma_manager,
  144. status_group_spi_nor_flash,
  145. status_group_touch,
  146. };
  147. /* @brief Common status code definitions */
  148. enum {
  149. status_success = MAKE_STATUS(status_group_common, 0),
  150. status_fail = MAKE_STATUS(status_group_common, 1),
  151. status_invalid_argument = MAKE_STATUS(status_group_common, 2),
  152. status_timeout = MAKE_STATUS(status_group_common, 3),
  153. };
  154. #if defined(__GNUC__)
  155. /* weak */
  156. #define ATTR_WEAK __attribute__((weak))
  157. #define HPM_ATTR_MACHINE_INTERRUPT __attribute__ ((section(".isr_vector"), interrupt("machine"), aligned(4)))
  158. #define HPM_ATTR_SUPERVISOR_INTERRUPT __attribute__ ((section(".isr_s_vector"), interrupt("supervisor"), aligned(4)))
  159. #elif defined(__ICCRISCV__)
  160. /* weak */
  161. #define ATTR_WEAK __weak
  162. #define HPM_ATTR_MACHINE_INTERRUPT __machine __interrupt
  163. #define HPM_ATTR_SUPERVISOR_INTERRUPT __supervisor __interrupt
  164. #ifndef __TIMEVAL_DEFINED
  165. #define __TIMEVAL_DEFINED 1
  166. struct timeval {
  167. long tv_sec; /* Seconds since the Epoch */
  168. long tv_usec; /* Microseconds */
  169. };
  170. #endif
  171. #else
  172. #error Unknown toolchain
  173. #endif
  174. #if defined(__GNUC__) || defined(__ICCRISCV__)
  175. /* alway_inline */
  176. #define ATTR_ALWAYS_INLINE __attribute__((always_inline))
  177. /* alignment */
  178. #define ATTR_ALIGN(alignment) __attribute__((aligned(alignment)))
  179. #define ATTR_PACKED __attribute__((packed, aligned(1)))
  180. /* place var_declare at section_name, e.x. PLACE_AT(".target_section", var); */
  181. #define ATTR_PLACE_AT(section_name) __attribute__((section(section_name)))
  182. #define ATTR_PLACE_AT_WITH_ALIGNMENT(section_name, alignment) \
  183. ATTR_PLACE_AT(section_name) ATTR_ALIGN(alignment)
  184. #define ATTR_PLACE_AT_NONCACHEABLE ATTR_PLACE_AT(".noncacheable")
  185. #define ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(alignment) \
  186. ATTR_PLACE_AT_NONCACHEABLE ATTR_ALIGN(alignment)
  187. #define ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_PLACE_AT(".noncacheable.bss")
  188. #define ATTR_PLACE_AT_NONCACHEABLE_BSS_WITH_ALIGNMENT(alignment) \
  189. ATTR_PLACE_AT_NONCACHEABLE_BSS ATTR_ALIGN(alignment)
  190. /* initialize variable x with y using PLACE_AT_NONCACHEABLE_INIT(x) = {y}; */
  191. #define ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_PLACE_AT(".noncacheable.init")
  192. #define ATTR_PLACE_AT_NONCACHEABLE_INIT_WITH_ALIGNMENT(alignment) \
  193. ATTR_PLACE_AT_NONCACHEABLE_INIT ATTR_ALIGN(alignment)
  194. /* .fast_ram section */
  195. #define ATTR_PLACE_AT_FAST_RAM ATTR_PLACE_AT(".fast_ram")
  196. #define ATTR_PLACE_AT_FAST_RAM_WITH_ALIGNMENT(alignment) \
  197. ATTR_PLACE_AT_FAST_RAM ATTR_ALIGN(alignment)
  198. #define ATTR_PLACE_AT_FAST_RAM_BSS ATTR_PLACE_AT(".fast_ram.bss")
  199. #define ATTR_PLACE_AT_FAST_RAM_BSS_WITH_ALIGNMENT(alignment) \
  200. ATTR_PLACE_AT_FAST_RAM_BSS ATTR_ALIGN(alignment)
  201. #define ATTR_PLACE_AT_FAST_RAM_INIT ATTR_PLACE_AT(".fast_ram.init")
  202. #define ATTR_PLACE_AT_FAST_RAM_INIT_WITH_ALIGNMENT(alignment) \
  203. ATTR_PLACE_AT_FAST_RAM_INIT ATTR_ALIGN(alignment)
  204. #define ATTR_RAMFUNC ATTR_PLACE_AT(".fast")
  205. #define ATTR_RAMFUNC_WITH_ALIGNMENT(alignment) \
  206. ATTR_RAMFUNC ATTR_ALIGN(alignment)
  207. #define ATTR_SHARE_MEM ATTR_PLACE_AT(".sh_mem")
  208. #define NOP() __asm volatile("nop")
  209. #define WFI() __asm volatile("wfi")
  210. #endif
  211. #ifdef __cplusplus
  212. extern "C" {
  213. #endif
  214. /**
  215. * @brief Count bits set to 1
  216. *
  217. * @param value Data to be counted
  218. *
  219. * @return number of bits set to 1
  220. */
  221. static inline uint32_t count_set_bits(uint32_t value)
  222. {
  223. if (value == 0) {
  224. return 0;
  225. }
  226. return 1 + count_set_bits(value & (value - 1));
  227. }
  228. /**
  229. * @brief Count bits set to 1 from least significant bit
  230. *
  231. * @param value Data to be counted
  232. *
  233. * @return number of bits set to 1
  234. * @return 0xFFFFFFFF if no bit was set to 1
  235. */
  236. static inline uint32_t get_first_set_bit_from_lsb(uint32_t value)
  237. {
  238. uint32_t i = 0;
  239. if (!value) {
  240. return 0xFFFFFFFFUL;
  241. }
  242. while (value && !(value & 0x1)) {
  243. value >>= 1;
  244. i++;
  245. }
  246. return i;
  247. }
  248. /**
  249. * @brief Count bits set to 1 from most significant bit
  250. *
  251. * @param value Data to be counted
  252. *
  253. * @return number of bits set to 1
  254. * @return 0xFFFFFFFF if no bit was set to 1
  255. */
  256. static inline uint32_t get_first_set_bit_from_msb(uint32_t value)
  257. {
  258. uint32_t i = 31;
  259. if (!value) {
  260. return 0xFFFFFFFFUL;
  261. }
  262. while (value && !(value & 0x80000000)) {
  263. value <<= 1;
  264. value &= ~1;
  265. i--;
  266. }
  267. return i;
  268. }
  269. /**
  270. * @brief Convert the elapsed ticks to microseconds according to the source clock frequency
  271. * @param [in] ticks elapsed ticks
  272. * @param [in] src_clk_freq The Frequency of the source
  273. *
  274. * @return elapsed microseconds
  275. */
  276. static inline uint32_t hpm_convert_ticks_to_us(uint32_t ticks, uint32_t src_clk_freq)
  277. {
  278. uint32_t ticks_per_us = (src_clk_freq + 1000000UL - 1UL) / 1000000UL;
  279. return (ticks + ticks_per_us - 1UL) / ticks_per_us;
  280. }
  281. /**
  282. * @brief Convert the elapsed ticks to milliseconds according to the source clock frequency
  283. * @param [in] ticks elapsed ticks
  284. * @param [in] src_clk_freq The Frequency of the source
  285. *
  286. * @return elapsed milliseconds
  287. */
  288. static inline uint32_t hpm_convert_ticks_to_ms(uint32_t ticks, uint32_t src_clk_freq)
  289. {
  290. uint32_t ticks_per_ms = (src_clk_freq + 1000UL - 1UL) / 1000UL;
  291. return (ticks + ticks_per_ms - 1UL) / ticks_per_ms;
  292. }
  293. #ifdef __cplusplus
  294. }
  295. #endif
  296. /**
  297. * @}
  298. */
  299. #endif /* _HPM_COMMON_H */