hpm_adc16_drv.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. * Copyright (c) 2021 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_ADC16_DRV_H
  8. #define HPM_ADC16_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_adc16_regs.h"
  11. #include "hpm_soc_feature.h"
  12. /**
  13. * @brief ADC16 driver APIs
  14. * @defgroup adc16_interface ADC16 driver APIs
  15. * @ingroup adc_interfaces
  16. * @{
  17. */
  18. /** @brief Define ADC16 validity check for the channel number */
  19. #if defined (ADC16_SOC_TEMP_CH_EN) && ADC16_SOC_TEMP_CH_EN
  20. #define ADC16_IS_CHANNEL_INVALID(CH) (CH > ADC16_SOC_MAX_CH_NUM && CH != ADC16_SOC_TEMP_CH_NUM)
  21. #else
  22. #define ADC16_IS_CHANNEL_INVALID(CH) (CH > ADC16_SOC_MAX_CH_NUM)
  23. #endif
  24. /** @brief Define ADC16 validity check for the trigger number */
  25. #define ADC16_IS_TRIG_CH_INVLAID(CH) (CH > ADC_SOC_MAX_TRIG_CH_NUM)
  26. /** @brief Define ADC16 validity check for the trigger length */
  27. #define ADC16_IS_TRIG_LEN_INVLAID(TRIG_LEN) (TRIG_LEN > ADC_SOC_MAX_TRIG_CH_LEN)
  28. /** @brief Define ADC16 validity check for the sequence length */
  29. #define ADC16_IS_SEQ_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_LEN))
  30. /** @brief Define ADC16 validity check for the DMA buffer length in the sequence mode */
  31. #define ADC16_IS_SEQ_DMA_BUFF_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_DMA_BUFF_LEN_IN_4BYTES))
  32. /** @brief Define ADC16 validity check for the DMA buffer length in the preemption mode */
  33. #define ADC16_IS_PMT_DMA_BUFF_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_PMT_MAX_DMA_BUFF_LEN_IN_4BYTES))
  34. /** @brief Define ADC16 resolutions. */
  35. typedef enum {
  36. adc16_res_8_bits = 9,
  37. adc16_res_10_bits = 11,
  38. adc16_res_12_bits = 14,
  39. adc16_res_16_bits = 21
  40. } adc16_resolution_t;
  41. /** @brief Define ADC16 conversion modes. */
  42. typedef enum {
  43. adc16_conv_mode_oneshot = 0,
  44. adc16_conv_mode_period,
  45. adc16_conv_mode_sequence,
  46. adc16_conv_mode_preemption
  47. } adc16_conversion_mode_t;
  48. /** @brief Define adc16 Clock Divider */
  49. typedef enum {
  50. adc16_clock_divider_1 = 1,
  51. adc16_clock_divider_2,
  52. adc16_clock_divider_3,
  53. adc16_clock_divider_4,
  54. adc16_clock_divider_5,
  55. adc16_clock_divider_6,
  56. adc16_clock_divider_7,
  57. adc16_clock_divider_8,
  58. adc16_clock_divider_9,
  59. adc16_clock_divider_10,
  60. adc16_clock_divider_11,
  61. adc16_clock_divider_12,
  62. adc16_clock_divider_13,
  63. adc16_clock_divider_14,
  64. adc16_clock_divider_15,
  65. adc16_clock_divider_16,
  66. } adc16_clock_divider_t;
  67. /** @brief Define ADC16 irq events. */
  68. typedef enum {
  69. /** This mask indicates that a trigger conversion is complete. */
  70. adc16_event_trig_complete = ADC16_INT_STS_TRIG_CMPT_MASK,
  71. /** This mask indicates that a conflict caused by software-triggered conversions. */
  72. adc16_event_trig_sw_conflict = ADC16_INT_STS_TRIG_SW_CFLCT_MASK,
  73. /** This mask indicates that a conflict caused by hardware-triggered conversions. */
  74. adc16_event_trig_hw_conflict = ADC16_INT_STS_TRIG_HW_CFLCT_MASK,
  75. /** This mask indicates that a conflict caused when bus reading from different channels. */
  76. adc16_event_read_conflict = ADC16_INT_STS_READ_CFLCT_MASK,
  77. /** This mask indicates that a conflict caused by sequence-triggered conversions. */
  78. adc16_event_seq_sw_conflict = ADC16_INT_STS_SEQ_SW_CFLCT_MASK,
  79. /** This mask indicates that a conflict caused by hardware-triggered conversions. */
  80. adc16_event_seq_hw_conflict = ADC16_INT_STS_SEQ_HW_CFLCT_MASK,
  81. /** This mask indicates that DMA is stopped currently. */
  82. adc16_event_seq_dma_abort = ADC16_INT_STS_SEQ_DMAABT_MASK,
  83. /** This mask indicates that all of the configured conversion(s) in a queue is(are) complete. */
  84. adc16_event_seq_full_complete = ADC16_INT_STS_SEQ_CMPT_MASK,
  85. /** This mask indicates that one of the configured conversion(s) in a queue is complete. */
  86. adc16_event_seq_single_complete = ADC16_INT_STS_SEQ_CVC_MASK,
  87. /** This mask indicates that DMA FIFO is full currently. */
  88. adc16_event_dma_fifo_full = ADC16_INT_STS_DMA_FIFO_FULL_MASK
  89. } adc16_irq_event_t;
  90. /** @brief ADC16 common configuration struct. */
  91. typedef struct {
  92. uint8_t res;
  93. uint8_t conv_mode;
  94. uint32_t adc_clk_div;
  95. uint16_t conv_duration;
  96. bool port3_rela_time;
  97. bool wait_dis;
  98. bool sel_sync_ahb;
  99. bool adc_ahb_en;
  100. } adc16_config_t;
  101. /** @brief ADC16 channel configuration struct. */
  102. typedef struct {
  103. uint8_t ch;
  104. uint16_t thshdh;
  105. uint16_t thshdl;
  106. uint8_t sample_cycle_shift;
  107. uint32_t sample_cycle;
  108. } adc16_channel_config_t;
  109. /** @brief ADC16 DMA configuration struct. */
  110. typedef struct {
  111. uint32_t *start_addr;
  112. uint32_t buff_len_in_4bytes;
  113. uint32_t stop_pos;
  114. bool stop_en;
  115. } adc16_dma_config_t;
  116. /** @brief ADC16 DMA configuration struct for the sequence mode. */
  117. typedef struct {
  118. uint32_t result :16;
  119. uint32_t seq_num :4;
  120. uint32_t :4;
  121. uint32_t adc_ch :5;
  122. uint32_t :2;
  123. uint32_t cycle_bit :1;
  124. } adc16_seq_dma_data_t;
  125. /** @brief ADC16 DMA configuration struct for the preemption mode. */
  126. typedef struct {
  127. uint32_t result :16;
  128. uint32_t seq_num :2;
  129. uint32_t :2;
  130. uint32_t trig_ch :4;
  131. uint32_t adc_ch :5;
  132. uint32_t :2;
  133. uint32_t cycle_bit :1;
  134. } adc16_pmt_dma_data_t;
  135. /** @brief ADC16 configuration struct for the the period mode. */
  136. typedef struct {
  137. uint8_t ch;
  138. uint8_t prescale;
  139. uint8_t period_count;
  140. } adc16_prd_config_t;
  141. /** @brief ADC16 queue configuration struct for the sequence mode. */
  142. typedef struct {
  143. bool seq_int_en;
  144. uint8_t ch;
  145. } adc16_seq_queue_config_t;
  146. /** @brief ADC16 configuration struct for the sequence mode. */
  147. typedef struct {
  148. adc16_seq_queue_config_t queue[ADC_SOC_SEQ_MAX_LEN];
  149. bool restart_en;
  150. bool cont_en;
  151. bool sw_trig_en;
  152. bool hw_trig_en;
  153. uint8_t seq_len;
  154. } adc16_seq_config_t;
  155. /** @brief ADC16 trigger configuration struct for the preemption mode. */
  156. typedef struct {
  157. bool inten[ADC_SOC_MAX_TRIG_CH_LEN];
  158. uint8_t adc_ch[ADC_SOC_MAX_TRIG_CH_LEN];
  159. uint8_t trig_ch;
  160. uint8_t trig_len;
  161. } adc16_pmt_config_t;
  162. #ifdef __cplusplus
  163. extern "C" {
  164. #endif
  165. /**
  166. * @name Initialization and Deinitialization
  167. * @{
  168. */
  169. /**
  170. * @brief Get a default configuration for an ADC16 instance.
  171. *
  172. * @param[out] config A pointer to the configuration struct of @ref adc16_config_t.
  173. *
  174. */
  175. void adc16_get_default_config(adc16_config_t *config);
  176. /**
  177. * @brief Get a default configuration for an ADC16 Channel.
  178. *
  179. * @param[out] config A pointer to the configuration struct of @ref adc16_channel_config_t.
  180. */
  181. void adc16_get_channel_default_config(adc16_channel_config_t *config);
  182. /**
  183. * @brief Initialize an ADC16 instance.
  184. *
  185. * @param[in] ptr An ADC16 peripheral base address.
  186. * @param[in] config A pointer to the configuration struct of @ref adc16_config_t.
  187. * @return A result of initializing an ADC16 instance.
  188. * @retval status_success Initialize an ADC16 instance successfully. Please refer to @ref hpm_stat_t.
  189. * @retval status_invalid_argument Initialize an ADC16 instance unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
  190. */
  191. hpm_stat_t adc16_init(ADC16_Type *ptr, adc16_config_t *config);
  192. /**
  193. * @brief Initialize an ADC16 channel
  194. *
  195. * @param[in] ptr An ADC16 peripheral base address.
  196. * @param[in] config A pointer to the configuration struct of @ref adc16_channel_config_t.
  197. * @return A result of initializing an ADC16 channel.
  198. * @retval status_success Initialize an ADC16 channel successfully. Please refer to @ref hpm_stat_t.
  199. * @retval status_invalid_argument Initialize an ADC16 channel unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
  200. */
  201. hpm_stat_t adc16_init_channel(ADC16_Type *ptr, adc16_channel_config_t *config);
  202. /**
  203. * @brief Configure the the period mode for an ADC16 instance.
  204. *
  205. * @param[in] ptr An ADC16 peripheral base address.
  206. * @param[in] config A pointer to the configuration struct of @ref adc16_prd_config_t.
  207. * @return A result of configuring the the period mode for an ADC16 instance.
  208. * @retval status_success Configure the the period mode successfully. Please refer to @ref hpm_stat_t.
  209. * @retval status_invalid_argument Configure the the period mode unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
  210. */
  211. hpm_stat_t adc16_set_prd_config(ADC16_Type *ptr, adc16_prd_config_t *config);
  212. /**
  213. * @brief Configure the sequence mode for an ADC16 instance.
  214. *
  215. * @param[in] ptr An ADC16 peripheral base address.
  216. * @param[in] config A pointer to configuration struct of @ref adc16_seq_config_t.
  217. * @return A result of configuring the sequence mode for an ADC16 instance.
  218. * @retval status_success Configure the sequence mode successfully. Please refer to @ref hpm_stat_t.
  219. * @retval status_invalid_argument Configure the sequence mode unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
  220. */
  221. hpm_stat_t adc16_set_seq_config(ADC16_Type *ptr, adc16_seq_config_t *config);
  222. /**
  223. * @brief Configure the preemption mode for an ADC16 instance.
  224. *
  225. * @param[in] ptr An ADC16 peripheral base address.
  226. * @param[in] config A pointer to configuration struct of @ref adc16_pmt_config_t.
  227. * @return A result of configuring the preemption mode for an ADC16 instance.
  228. * @retval status_success Configure the preemption mode successfully. Please refer to @ref hpm_stat_t.
  229. * @retval status_invalid_argument Configure the preemption mode unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
  230. */
  231. hpm_stat_t adc16_set_pmt_config(ADC16_Type *ptr, adc16_pmt_config_t *config);
  232. /**
  233. * @brief Set the queue enable control.
  234. *
  235. * @param[in] ptr An ADC16 peripheral base address.
  236. * @param[in] trig_ch An ADC16 peripheral trigger channel.
  237. * @param[in] enable A enable control
  238. * @retval status_success Get the result of an ADC16 conversion in oneshot mode successfully.
  239. * @retval status_invalid_argument Get the result of an ADC16 conversion in oneshot mode unsuccessfully due to passing invalid arguments.
  240. */
  241. hpm_stat_t adc16_set_pmt_queue_enable(ADC16_Type *ptr, uint8_t trig_ch, bool enable);
  242. /** @} */
  243. /**
  244. * @name DMA Control
  245. * @{
  246. */
  247. /**
  248. * @brief Configure the stop position offset in the specified memory of DMA write operation for the sequence mode.
  249. *
  250. * @param[in] ptr An ADC16 peripheral base address.
  251. * @param[in] stop_pos A stop position offset.
  252. */
  253. static inline void adc16_set_seq_stop_pos(ADC16_Type *ptr, uint16_t stop_pos)
  254. {
  255. ptr->SEQ_DMA_CFG = (ptr->SEQ_DMA_CFG & ~ADC16_SEQ_DMA_CFG_STOP_POS_MASK)
  256. | ADC16_SEQ_DMA_CFG_STOP_POS_SET(stop_pos);
  257. }
  258. /**
  259. * @brief Configure the start address of DMA write operation for the preemption mode.
  260. *
  261. * @param[in] ptr An ADC16 peripheral base address.
  262. * @param[in] addr A start address of DMA write operation.
  263. */
  264. static inline void adc16_init_pmt_dma(ADC16_Type *ptr, uint32_t addr)
  265. {
  266. ptr->TRG_DMA_ADDR = addr & ADC16_TRG_DMA_ADDR_TRG_DMA_ADDR_MASK;
  267. }
  268. /**
  269. * @brief Configure the start address of DMA write operation for the preemption mode.
  270. *
  271. * @param[in] ptr An ADC16 peripheral base address.
  272. * @param[in] config A pointer to configuration struct of @ref adc16_dma_config_t.
  273. * @return An implementation result of DMA initializing for the sequence mode
  274. * @retval status_success ADC16 initialize in sequence mode successfully. Please refert to @ref hpm_stat_t.
  275. * @retval status_invalid_argument ADC16 initialize in sequence mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
  276. */
  277. hpm_stat_t adc16_init_seq_dma(ADC16_Type *ptr, adc16_dma_config_t *config);
  278. /** @} */
  279. /**
  280. * @name Status
  281. * @{
  282. */
  283. /**
  284. * @brief Get all ADC16 status flags.
  285. *
  286. * @param[in] ptr An ADC16 peripheral base address.
  287. * @return A mask indicating all corresponding interrupt statuses.
  288. * @retval A mask. Please refer to @ref adc16_irq_event_t.
  289. */
  290. static inline uint32_t adc16_get_status_flags(ADC16_Type *ptr)
  291. {
  292. return ptr->INT_STS;
  293. }
  294. /**
  295. * @brief Set value of the WAIT_DIS bit. The ADC does not block access to the associated peripheral bus
  296. * until the ADC has completed its conversion.
  297. *
  298. * @param[in] ptr An ADC16 peripheral base address.
  299. */
  300. static inline void adc16_disable_busywait(ADC16_Type *ptr)
  301. {
  302. ptr->BUF_CFG0 |= ADC16_BUF_CFG0_WAIT_DIS_SET(1);
  303. }
  304. /**
  305. * @brief Set value of the WAIT_DIS bit. ADC blocks access to the associated peripheral bus
  306. * until the ADC completes the conversion.
  307. *
  308. * @param[in] ptr An ADC16 peripheral base address.
  309. */
  310. static inline void adc16_enable_busywait(ADC16_Type *ptr)
  311. {
  312. ptr->BUF_CFG0 &= ~ADC16_BUF_CFG0_WAIT_DIS_MASK;
  313. }
  314. /**
  315. * @brief Get the status of a conversion validity.
  316. *
  317. * @param[in] ptr An ADC16 peripheral base address.
  318. * @param[in] ch An ADC16 peripheral channel.
  319. * @retval Status indicating the validity of the current conversion result.
  320. *
  321. * @note This function is only used when the WAIT_DIS bit in the BUF_RESULT register is 1.
  322. */
  323. static inline bool adc16_get_conv_valid_status(ADC16_Type *ptr, uint8_t ch)
  324. {
  325. return ADC16_BUS_RESULT_VALID_GET(ptr->BUS_RESULT[ch]);
  326. }
  327. /**
  328. * @brief Clear the status flags.
  329. *
  330. *
  331. * @param[in] ptr An ADC16 peripheral base address.
  332. * @param[in] mask A mask that means the specified flags to be cleared. Please refer to @ref adc16_irq_event_t.
  333. *
  334. * @note Only the specified flags can be cleared by writing the INT_STS register.
  335. */
  336. static inline void adc16_clear_status_flags(ADC16_Type *ptr, uint32_t mask)
  337. {
  338. ptr->INT_STS |= mask;
  339. }
  340. /** @} */
  341. /**
  342. * @name Interrupts
  343. * @{
  344. */
  345. /**
  346. * @brief Enable interrupts.
  347. *
  348. * @param[in] ptr An ADC16 peripheral base address.
  349. * @param[in] mask A mask indicating the specified ADC interrupt events. Please refer to @ref adc16_irq_event_t.
  350. */
  351. static inline void adc16_enable_interrupts(ADC16_Type *ptr, uint32_t mask)
  352. {
  353. ptr->INT_EN |= mask;
  354. }
  355. /**
  356. * @brief Disable interrupts.
  357. *
  358. * @param[in] ptr An ADC16 peripheral base address.
  359. * @param[in] mask A mask indicating the specified interrupt events. Please refer to @ref adc16_irq_event_t.
  360. */
  361. static inline void adc16_disable_interrupts(ADC16_Type *ptr, uint32_t mask)
  362. {
  363. ptr->INT_EN &= ~mask;
  364. }
  365. /** @} */
  366. /**
  367. * @name Trigger and Conversion
  368. * @{
  369. */
  370. /**
  371. * @brief Trigger ADC conversions by software in sequence mode
  372. *
  373. * @param[in] ptr An ADC16 peripheral base address.
  374. * @return An implementation result of getting an ADC16 software trigger.
  375. * @retval status_success ADC16 software triggers successfully. Please refer to @ref hpm_stat_t.
  376. * @retval status_fail ADC16 software triggers unsuccessfully. Please refer to @ref hpm_stat_t.
  377. */
  378. hpm_stat_t adc16_trigger_seq_by_sw(ADC16_Type *ptr);
  379. /**
  380. * @brief Trigger ADC conversions by software in preemption mode
  381. *
  382. * @param[in] ptr An ADC16 peripheral base address.
  383. * @param[in] trig_ch A trigger channel number(e.g. TRIG0A,TRIG0B,TRIG0C...).
  384. * @return An implementation result of getting an ADC16 software trigger.
  385. * @retval status_success ADC16 software triggers successfully. Please refer to @ref hpm_stat_t.
  386. * @retval status_fail ADC16 software triggers unsuccessfully. Please refer to @ref hpm_stat_t.
  387. */
  388. hpm_stat_t adc16_trigger_pmt_by_sw(ADC16_Type *ptr, uint8_t trig_ch);
  389. /**
  390. * @brief Get the result in oneshot mode.
  391. *
  392. * @param[in] ptr An ADC16 peripheral base address.
  393. * @param[in] ch An ADC16 peripheral channel.
  394. * @param[out] result A pointer to an ADC16 conversion result.
  395. * @return An implementation result of getting an ADC16 conversion result in oneshot mode.
  396. * @retval status_success Get the result of an ADC16 conversion in oneshot mode successfully. Please refer to @ref hpm_stat_t.
  397. * @retval status_invalid_argument Get the result of an ADC16 conversion in oneshot mode unsuccessfully due to passing invalid arguments. Please refer to @ref hpm_stat_t.
  398. */
  399. hpm_stat_t adc16_get_oneshot_result(ADC16_Type *ptr, uint8_t ch, uint16_t *result);
  400. /**
  401. * @brief Get the result in the period mode.
  402. *
  403. * @param[in] ptr An ADC16 peripheral base address.
  404. * @param[in] ch An ADC16 peripheral channel.
  405. * @param[out] result A pointer to a specified ADC16 conversion result
  406. * @return An implementation of getting an ADC16 conversion result in the period mode.
  407. * @retval status_success Get the result of an ADC16 conversion in the period mode successfully. Please refer to @ref hpm_stat_t.
  408. * @retval status_invalid_argument Get the result of an ADC16 conversion in the period mode unsuccessfully due to passing invalid arguments. Please refer to @ref hpm_stat_t.
  409. */
  410. hpm_stat_t adc16_get_prd_result(ADC16_Type *ptr, uint8_t ch, uint16_t *result);
  411. #if defined(ADC16_SOC_TEMP_CH_EN) && ADC16_SOC_TEMP_CH_EN
  412. /**
  413. * @brief Enable the temperature sensor
  414. *
  415. * @param[in] ptr An ADC16 peripheral base address.
  416. */
  417. void adc16_enable_temp_sensor(ADC16_Type *ptr);
  418. /**
  419. * @brief Disable the temperature sensor
  420. *
  421. * @param[in] ptr An ADC16 peripheral base address.
  422. */
  423. void adc16_disable_temp_sensor(ADC16_Type *ptr);
  424. #endif
  425. /** @} */
  426. #ifdef __cplusplus
  427. }
  428. #endif
  429. /** @} */
  430. #endif /* HPM_ADC16_DRV_H */