hpm_sdm_drv.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*
  2. * Copyright (c) 2022 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_SDM_DRV_H
  8. #define HPM_SDM_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_sdm_regs.h"
  11. /**
  12. * @brief SDM APIs
  13. * @defgroup sdm_interface SDM driver APIs
  14. * @ingroup sdm_interfaces
  15. * @{
  16. */
  17. /* defined channel mask macro */
  18. #define SAMPLING_MODE_MASK (0x7U)
  19. #define CHN_SAMPLING_MODE_SHIFT(ch) ((ch) * 3U + SDM_CTRL_CHMD_SHIFT)
  20. #define CHN_SAMPLING_MODE_MASK(ch) (SAMPLING_MODE_MASK << CHN_SAMPLING_MODE_SHIFT(ch))
  21. #define CH0_EN_MASK (0x1U << SDM_CTRL_CH_EN_SHIFT)
  22. #define CHN_EN_MASK(ch) (CH0_EN_MASK << (ch))
  23. #define CHN_ERR_MASK(ch) (SDM_INT_EN_CH0ERR_MASK << (ch))
  24. #define CHN_DRY_MASK(ch) (SDM_INT_EN_CH0DRY_MASK << (ch))
  25. typedef enum {
  26. sdm_sampling_rising_clk_edge = 0,
  27. sdm_sampling_every_clk_edge = 1,
  28. sdm_sampling_manchester_mode = 2,
  29. sdm_sampling_falling_clk_edge = 3,
  30. sdm_sampling_rising_two_clk_edge = 4,
  31. sdm_sampling_falling_two_clk_edge = 5
  32. } sdm_sampling_mode_t;
  33. typedef enum {
  34. sdm_filter_sinc1 = 0,
  35. sdm_filter_sinc2 = 1,
  36. sdm_filter_sinc3 = 2,
  37. sdm_filter_fast_sinc2 = 3
  38. } sdm_filter_type_t;
  39. typedef struct {
  40. uint8_t clk_signal_sync; /* clk sync for channel */
  41. uint8_t data_signal_sync; /* data sync for channel */
  42. bool interrupt_en;
  43. } sdm_control_t;
  44. typedef struct {
  45. uint8_t sampling_mode;
  46. bool enable_err_interrupt;
  47. bool enable_data_ready_interrupt;
  48. } sdm_channel_common_config_t;
  49. typedef struct {
  50. uint16_t high_threshold;
  51. uint16_t zero_cross_threshold;
  52. uint16_t low_threshold;
  53. bool en_zero_cross_threshold_int;
  54. bool en_clock_invalid_int;
  55. bool en_high_threshold_int;
  56. bool en_low_threshold_int;
  57. uint8_t filter_type; /**< sdm_filter_type_t */
  58. uint8_t oversampling_rate; /**< 1 - 32 */
  59. uint8_t ignore_invalid_samples;
  60. bool enable;
  61. } sdm_comparator_config_t;
  62. typedef struct {
  63. uint8_t fifo_threshold;
  64. bool en_fifo_threshold_int;
  65. uint8_t manchester_threshold :8;
  66. uint8_t wdg_threshold :8;
  67. uint8_t en_af_int :1;
  68. uint8_t en_data_overflow_int :1;
  69. uint8_t en_cic_data_saturation_int :1;
  70. uint8_t en_data_ready_int :1;
  71. uint8_t sync_source :6;
  72. uint8_t fifo_clean_on_sync :1; /**< fifo clean by hardware when fifo interrupt occurred */
  73. uint8_t wtsynaclr :1;
  74. uint8_t wtsynmclr :1;
  75. uint8_t wtsyncen :1;
  76. uint8_t output_32bit :1;
  77. uint8_t data_ready_flag_by_fifo :1;
  78. uint8_t enable :1;
  79. uint8_t filter_type; /**< sdm_filter_type_t */
  80. bool pwm_signal_sync;
  81. uint8_t output_offset; /**< 16bit mode need configure this */
  82. uint16_t oversampling_rate; /**< 1-256 */
  83. uint8_t ignore_invalid_samples;
  84. } sdm_filter_config_t;
  85. typedef struct {
  86. uint32_t count;
  87. uint8_t *buff;
  88. uint8_t data_len_in_bytes; /* 16bit-2 32bit-4 */
  89. bool using_fifo;
  90. } sdm_output_config_t;
  91. typedef enum {
  92. sdm_comparator_no_event = 0,
  93. sdm_comparator_event_out_high_threshold = SDM_CH_SCST_CMPH_MASK,
  94. sdm_comparator_event_out_low_threshold = SDM_CH_SCST_CMPL_MASK,
  95. sdm_comparator_event_hz = SDM_CH_SCST_HZ_MASK,
  96. sdm_comparator_event_invalid_clk = SDM_CH_SCST_MF_MASK
  97. } sdm_comparator_event_t;
  98. typedef enum {
  99. sdm_chn0_error_mask = SDM_INT_EN_CH0ERR_MASK,
  100. sdm_chn1_error_mask = SDM_INT_EN_CH1ERR_MASK,
  101. sdm_chn2_error_mask = SDM_INT_EN_CH2ERR_MASK,
  102. sdm_chn3_error_mask = SDM_INT_EN_CH3ERR_MASK,
  103. sdm_chn0_data_ready_mask = SDM_INT_EN_CH0DRY_MASK,
  104. sdm_chn1_data_ready_mask = SDM_INT_EN_CH1DRY_MASK,
  105. sdm_chn2_data_ready_mask = SDM_INT_EN_CH2DRY_MASK,
  106. sdm_chn3_data_ready_mask = SDM_INT_EN_CH3DRY_MASK
  107. } sdm_channel_int_status_mask_t;
  108. typedef enum {
  109. sdm_chn0_enable_mask = 1U << SDM_CTRL_CH_EN_SHIFT,
  110. sdm_chn1_enable_mask = 1U << (SDM_CTRL_CH_EN_SHIFT + 1U),
  111. sdm_chn2_enable_mask = 1U << (SDM_CTRL_CH_EN_SHIFT + 2U),
  112. sdm_chn3_enable_mask = 1U << (SDM_CTRL_CH_EN_SHIFT + 3U)
  113. } sdm_channel_enable_mask_t;
  114. #ifdef __cplusplus
  115. extern "C" {
  116. #endif
  117. /**
  118. * @brief sdm enable module interrupt
  119. *
  120. * @param ptr SDM base address
  121. * @param enable true for enable, false for disable
  122. */
  123. static inline void sdm_enable_module_interrupt(SDM_Type *ptr, bool enable)
  124. {
  125. if (enable) {
  126. ptr->CTRL |= SDM_CTRL_IE_MASK;
  127. } else {
  128. ptr->CTRL &= ~SDM_CTRL_IE_MASK;
  129. }
  130. }
  131. /**
  132. * @brief sdm enable channel
  133. *
  134. * @param ptr SDM base address
  135. * @param ch_index channel index
  136. * @param enable true for enable, false for disable
  137. */
  138. static inline void sdm_enable_channel(SDM_Type *ptr, uint8_t ch_index, bool enable)
  139. {
  140. if (enable) {
  141. ptr->CTRL |= CHN_EN_MASK(ch_index);
  142. } else {
  143. ptr->CTRL &= ~CHN_EN_MASK(ch_index);
  144. }
  145. }
  146. /**
  147. * @brief sdm enable channel by mask
  148. *
  149. * @note ch_mask supports bitwise or operation, this API could enable multiple channels at the same time
  150. *
  151. * @param ptr SDM base address
  152. * @param ch_mask sdm_channel_enable_mask_t
  153. */
  154. static inline void sdm_enable_channel_by_mask(SDM_Type *ptr, uint32_t ch_mask)
  155. {
  156. ptr->CTRL = (ptr->CTRL & (~SDM_CTRL_CH_EN_MASK)) | ch_mask;
  157. }
  158. /**
  159. * @brief sdm set channel sampling mode
  160. *
  161. * @param ptr SDM base address
  162. * @param ch_index channel index
  163. * @param mode sdm_sampling_mode_t
  164. */
  165. static inline void sdm_set_channel_sampling_mode(SDM_Type *ptr, uint8_t ch_index, sdm_sampling_mode_t mode)
  166. {
  167. ptr->CTRL &= ~CHN_SAMPLING_MODE_MASK(ch_index);
  168. ptr->CTRL |= mode << (SDM_CTRL_CHMD_SHIFT + ch_index);
  169. }
  170. /**
  171. * @brief sdm enable channel interrupt
  172. *
  173. * @param ptr SDM base address
  174. * @param mask sdm_channel_int_status_mask_t, support bitwise or operation
  175. */
  176. static inline void sdm_enable_channel_interrupt(SDM_Type *ptr, uint32_t mask)
  177. {
  178. ptr->INT_EN |= mask;
  179. }
  180. /**
  181. * @brief sdm get status register value
  182. *
  183. * @param ptr SDM base address
  184. * @return uint32_t sdm status register value
  185. */
  186. static inline uint32_t sdm_get_status(SDM_Type *ptr)
  187. {
  188. return ptr->STATUS;
  189. }
  190. /**
  191. * @brief get channel data ready status
  192. *
  193. * @param ptr SDM base address
  194. * @param ch channel
  195. * @return true data ready
  196. * @return false not ready
  197. */
  198. static inline bool sdm_get_channel_data_ready_status(SDM_Type *ptr, uint8_t ch)
  199. {
  200. return (((ptr->STATUS) & CHN_DRY_MASK(ch)) == CHN_DRY_MASK(ch));
  201. }
  202. /**
  203. * @brief get channel error status
  204. *
  205. * @param ptr SDM base address
  206. * @param ch channel
  207. * @return true error occur
  208. * @return false no error
  209. */
  210. static inline bool sdm_get_channel_data_error_status(SDM_Type *ptr, uint8_t ch)
  211. {
  212. return (((ptr->STATUS) & CHN_ERR_MASK(ch)) == CHN_ERR_MASK(ch));
  213. }
  214. /**
  215. * @brief sdm set channel's fifo threshold
  216. *
  217. * @param ptr SDM base address
  218. * @param ch channel index
  219. * @param threshold threshold value
  220. */
  221. static inline void sdm_set_ch_fifo_threshold(SDM_Type *ptr, uint8_t ch, uint8_t threshold)
  222. {
  223. ptr->CH[ch].SDFIFOCTRL = SDM_CH_SDFIFOCTRL_THRSH_SET(threshold);
  224. }
  225. /**
  226. * @brief sdm get channel fifo threshold
  227. *
  228. * @param ptr SDM base address
  229. * @param ch channel index
  230. * @return uint8_t fifo threshold value
  231. */
  232. static inline uint8_t sdm_get_ch_fifo_threshold(SDM_Type *ptr, uint8_t ch)
  233. {
  234. return (uint8_t)(SDM_CH_SDFIFOCTRL_THRSH_GET(ptr->CH[ch].SDFIFOCTRL));
  235. }
  236. /**
  237. * @brief sdm get channel filter status
  238. *
  239. * @param ptr SDM base address
  240. * @param ch channel index
  241. * @return uint32_t channel filter status register value
  242. */
  243. static inline uint32_t sdm_get_channel_filter_status(SDM_Type *ptr, uint8_t ch)
  244. {
  245. return ptr->CH[ch].SDST;
  246. }
  247. /**
  248. * @brief sdm get channel data count in fifo
  249. *
  250. * @param ptr SDM base address
  251. * @param ch channel index
  252. * @return uint8_t data count
  253. */
  254. static inline uint8_t sdm_get_channel_fifo_data_count(SDM_Type *ptr, uint8_t ch)
  255. {
  256. return (uint8_t)(SDM_CH_SDST_FILL_GET(ptr->CH[ch].SDST));
  257. }
  258. /**
  259. * @brief sdm get channel filter output data in fifo
  260. *
  261. * @param ptr SDM base address
  262. * @param ch channel index
  263. * @return int32_t data
  264. */
  265. static inline int32_t sdm_get_channel_fifo_data(SDM_Type *ptr, uint8_t ch)
  266. {
  267. return ptr->CH[ch].SDFIFO;
  268. }
  269. /**
  270. * @brief sdm get channel input clock cycle count
  271. *
  272. * @param ptr SDM base address
  273. * @param ch channel index
  274. * @return uint8_t clock cycle count
  275. */
  276. static inline uint8_t sdm_get_channel_clock_cycle_count(SDM_Type *ptr, uint8_t ch)
  277. {
  278. return (uint8_t)(SDM_CH_SDST_PERIOD_MCLK_GET(ptr->CH[ch].SDST));
  279. }
  280. /**
  281. * @brief sdm get channel comparator data
  282. *
  283. * @param ptr SDM base address
  284. * @param ch channel index
  285. * @return uint16_t comparator data
  286. */
  287. static inline uint16_t sdm_get_channel_comparator_data(SDM_Type *ptr, uint8_t ch)
  288. {
  289. return (uint16_t)(ptr->CH[ch].SCAMP);
  290. }
  291. /**
  292. * @brief sdm set channel comparator high threshold
  293. *
  294. * @param ptr SDM base address
  295. * @param ch channel index
  296. * @param value high threshold value
  297. */
  298. static inline void sdm_set_channel_comparator_high_threshold(SDM_Type *ptr, uint8_t ch, uint16_t value)
  299. {
  300. ptr->CH[ch].SCHTL = value;
  301. }
  302. /**
  303. * @brief sdm set channel comparator zero crossing threshold
  304. *
  305. * @param ptr SDM base address
  306. * @param ch channel index
  307. * @param value zero crossing threshold value
  308. */
  309. static inline void sdm_set_channel_comparator_zero_crossing_threshold(SDM_Type *ptr, uint8_t ch, uint16_t value)
  310. {
  311. ptr->CH[ch].SCHTLZ = value;
  312. }
  313. /**
  314. * @brief sdm set channel comparator low threshold
  315. *
  316. * @param ptr SDM base address
  317. * @param ch channel index
  318. * @param value low threshold value
  319. */
  320. static inline void sdm_set_channel_comparator_low_threshold(SDM_Type *ptr, uint8_t ch, uint16_t value)
  321. {
  322. ptr->CH[ch].SCLLT = value;
  323. }
  324. /**
  325. * @brief sdm get channel comparator status register value
  326. *
  327. * @param ptr SDM base address
  328. * @param ch channel index
  329. * @return uint32_t channel comparator status register value
  330. */
  331. static inline uint32_t sdm_get_channel_comparator_status(SDM_Type *ptr, uint8_t ch)
  332. {
  333. return ptr->CH[ch].SCST;
  334. }
  335. /**
  336. * @brief sdm get default module control
  337. *
  338. * @param ptr SDM base address
  339. * @param control sdm_control_t
  340. */
  341. void sdm_get_default_module_control(SDM_Type *ptr, sdm_control_t *control);
  342. /**
  343. * @brief sdm init module
  344. *
  345. * @param ptr SDM base address
  346. * @param control sdm_control_t
  347. */
  348. void sdm_init_module(SDM_Type *ptr, sdm_control_t *control);
  349. /**
  350. * @brief sdm get channel common setting
  351. *
  352. * @param ptr SDM base address
  353. * @param config sdm_channel_common_config_t
  354. */
  355. void sdm_get_channel_common_setting(SDM_Type *ptr, sdm_channel_common_config_t *config);
  356. /**
  357. * @brief sdm config channel's common setting
  358. *
  359. * @param ptr SDM base address
  360. * @param ch_index channel index
  361. * @param config sdm_channel_common_config_t
  362. */
  363. void sdm_config_channel_common_setting(SDM_Type *ptr, uint8_t ch_index, sdm_channel_common_config_t *config);
  364. /**
  365. * @brief sdm get channel default filter config
  366. *
  367. * @param ptr SDM base address
  368. * @param filter_config sdm_filter_config_t
  369. */
  370. void sdm_get_channel_default_filter_config(SDM_Type *ptr, sdm_filter_config_t *filter_config);
  371. /**
  372. * @brief sdm config channel filter
  373. *
  374. * @param ptr SDM base address
  375. * @param ch_index channel index
  376. * @param filter_config sdm_filter_config_t
  377. */
  378. void sdm_config_channel_filter(SDM_Type *ptr, uint8_t ch_index, sdm_filter_config_t *filter_config);
  379. /**
  380. * @brief sdm get channel default comparator config
  381. *
  382. * @param ptr SDM base address
  383. * @param cmp_config sdm_comparator_config_t
  384. */
  385. void sdm_get_channel_default_comparator_config(SDM_Type *ptr, sdm_comparator_config_t *cmp_config);
  386. /**
  387. * @brief sdm config channel comparator
  388. *
  389. * @param ptr SDM base address
  390. * @param ch_index channel index
  391. * @param cmp_config sdm_comparator_config_t
  392. */
  393. void sdm_config_channel_comparator(SDM_Type *ptr, uint8_t ch_index, sdm_comparator_config_t *cmp_config);
  394. /**
  395. * @brief sdm receive one filter data
  396. *
  397. * @param ptr SDM base address
  398. * @param ch_index channel index
  399. * @param using_fifo true for getting data from fifo, false for getting data from register
  400. * @param data data buff
  401. * @param data_len_in_bytes output data len in bytes
  402. * @retval hpm_stat_t status_success only if it succeeds
  403. */
  404. hpm_stat_t sdm_receive_one_filter_data(SDM_Type *ptr, uint8_t ch_index, bool using_fifo, int8_t *data, uint8_t data_len_in_bytes);
  405. /**
  406. * @brief sdm receive filter data
  407. *
  408. * @param ptr SDM base address
  409. * @param ch_index channel index
  410. * @param using_fifo true for getting data from fifo, false for getting data from register
  411. * @param data data buff
  412. * @param count data count
  413. * @param data_len_in_bytes output data len in bytes
  414. * @retval hpm_stat_t status_success only if it succeeds
  415. */
  416. hpm_stat_t sdm_receive_filter_data(SDM_Type *ptr, uint8_t ch_index, bool using_fifo, int8_t *data, uint32_t count, uint8_t data_len_in_bytes);
  417. /**
  418. * @}
  419. */
  420. #ifdef __cplusplus
  421. }
  422. #endif
  423. #endif /* HPM_SDM_DRV_H */