hpm_adc.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /*
  2. * Copyright (c) 2022 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_ADC_H
  8. #define HPM_ADC_H
  9. #include "hpm_common.h"
  10. #ifdef CONFIG_HAS_HPMSDK_ADC12
  11. #include "hpm_adc12_drv.h"
  12. #endif
  13. #ifdef CONFIG_HAS_HPMSDK_ADC16
  14. #include "hpm_adc16_drv.h"
  15. #endif
  16. #include "hpm_soc_feature.h"
  17. /**
  18. * @brief ADC HAL driver APIs
  19. * @defgroup hpm_adc_interface HPM ADC driver APIs
  20. * @ingroup hpm_adc_interfaces
  21. * @{
  22. */
  23. /**
  24. * @brief An ADC peripheral base address.
  25. *
  26. */
  27. typedef union
  28. {
  29. #ifdef CONFIG_HAS_HPMSDK_ADC12
  30. ADC12_Type *adc12;
  31. #endif
  32. #ifdef CONFIG_HAS_HPMSDK_ADC16
  33. ADC16_Type *adc16;
  34. #endif
  35. } adc_base;
  36. /**
  37. * @brief use adc12 or adc16.
  38. *
  39. */
  40. #define ADCX_MODULE_ADC12 1
  41. #define ADCX_MODULE_ADC16 2
  42. typedef enum {
  43. adc_module_adc12 = ADCX_MODULE_ADC12,
  44. adc_module_adc16 = ADCX_MODULE_ADC16
  45. } adc_module;
  46. /**
  47. * @brief ADC common configuration struct.
  48. *
  49. */
  50. typedef struct {
  51. adc_module module;
  52. adc_base adc_base;
  53. struct {
  54. #ifdef CONFIG_HAS_HPMSDK_ADC12
  55. adc12_config_t adc12;
  56. #endif
  57. #ifdef CONFIG_HAS_HPMSDK_ADC16
  58. adc16_config_t adc16;
  59. #endif
  60. } config;
  61. } adc_config_t;
  62. /**
  63. * @brief ADC channel configuration struct.
  64. *
  65. */
  66. typedef struct {
  67. adc_module module;
  68. adc_base adc_base;
  69. struct {
  70. #ifdef CONFIG_HAS_HPMSDK_ADC12
  71. adc12_channel_config_t adc12_ch;
  72. #endif
  73. #ifdef CONFIG_HAS_HPMSDK_ADC16
  74. adc16_channel_config_t adc16_ch;
  75. #endif
  76. } config;
  77. } adc_channel_config_t;
  78. /**
  79. * @brief ADC DMA configuration struct.
  80. *
  81. * */
  82. typedef struct {
  83. adc_module module;
  84. adc_base adc_base;
  85. struct {
  86. #ifdef CONFIG_HAS_HPMSDK_ADC12
  87. adc12_dma_config_t adc12;
  88. #endif
  89. #ifdef CONFIG_HAS_HPMSDK_ADC16
  90. adc16_dma_config_t adc16;
  91. #endif
  92. } config;
  93. } adc_dma_config_t;
  94. /**
  95. * @brief ADC configuration struct for period mode.
  96. *
  97. * */
  98. typedef struct {
  99. adc_module module;
  100. adc_base adc_base;
  101. struct {
  102. #ifdef CONFIG_HAS_HPMSDK_ADC12
  103. adc12_prd_config_t adc12;
  104. #endif
  105. #ifdef CONFIG_HAS_HPMSDK_ADC16
  106. adc16_prd_config_t adc16;
  107. #endif
  108. } config;
  109. } adc_prd_config_t;
  110. /**
  111. * @brief ADC configuration struct for sequence mode.
  112. *
  113. * */
  114. typedef struct {
  115. adc_module module;
  116. adc_base adc_base;
  117. struct {
  118. #ifdef CONFIG_HAS_HPMSDK_ADC12
  119. adc12_seq_config_t adc12;
  120. #endif
  121. #ifdef CONFIG_HAS_HPMSDK_ADC16
  122. adc16_seq_config_t adc16;
  123. #endif
  124. } config;
  125. } adc_seq_config_t;
  126. /**
  127. * @brief ADC trigger configuration struct for preempt mode.
  128. *
  129. * */
  130. typedef struct
  131. {
  132. adc_module module;
  133. adc_base adc_base;
  134. struct {
  135. #ifdef CONFIG_HAS_HPMSDK_ADC12
  136. adc12_pmt_config_t adc12;
  137. #endif
  138. #ifdef CONFIG_HAS_HPMSDK_ADC16
  139. adc16_pmt_config_t adc16;
  140. #endif
  141. } config;
  142. } adc_pmt_config_t;
  143. typedef struct
  144. {
  145. adc_module module;
  146. adc_base adc_base;
  147. } adc_type;
  148. #ifdef __cplusplus
  149. extern "C" {
  150. #endif
  151. /**
  152. * @brief Get a default configuration for an ADC instance.
  153. *
  154. * @param[out] config A pointer to the configuration struct of "adc_config_t".
  155. *
  156. */
  157. static inline void hpm_adc_init_default_config(adc_config_t *config)
  158. {
  159. if (config->module == adc_module_adc12) {
  160. #ifdef CONFIG_HAS_HPMSDK_ADC12
  161. adc12_get_default_config(&config->config.adc12);
  162. #endif
  163. } else if (config->module == adc_module_adc16) {
  164. #ifdef CONFIG_HAS_HPMSDK_ADC16
  165. adc16_get_default_config(&config->config.adc16);
  166. #endif
  167. }
  168. }
  169. /**
  170. * @brief Get a default configuration for an ADC channel instance.
  171. *
  172. * @param[out] config A pointer to the configuration struct of "adc_channel_config_t".
  173. *
  174. */
  175. static inline void hpm_adc_init_channel_default_config(adc_channel_config_t *config)
  176. {
  177. if (config->module == adc_module_adc12) {
  178. #ifdef CONFIG_HAS_HPMSDK_ADC12
  179. adc12_get_channel_default_config(&config->config.adc12_ch);
  180. #endif
  181. } else if (config->module == adc_module_adc16) {
  182. #ifdef CONFIG_HAS_HPMSDK_ADC16
  183. adc16_get_channel_default_config(&config->config.adc16_ch);
  184. #endif
  185. }
  186. }
  187. /**
  188. * @brief Initialize an ADC instance.
  189. *
  190. * @param[in] config A pointer to the configuration struct of "adc_config_t".
  191. * @retval status_success Initialize an ADC instance successfully.
  192. * @retval status_invalid_argument Initialize an ADC instance unsuccessfully because of passing one or more invalid arguments.
  193. */
  194. static inline hpm_stat_t hpm_adc_init(adc_config_t *config)
  195. {
  196. if (config->module == adc_module_adc12) {
  197. #ifdef CONFIG_HAS_HPMSDK_ADC12
  198. return adc12_init(config->adc_base.adc12, &config->config.adc12);
  199. #else
  200. return status_invalid_argument;
  201. #endif
  202. } else if (config->module == adc_module_adc16) {
  203. #ifdef CONFIG_HAS_HPMSDK_ADC16
  204. return adc16_init(config->adc_base.adc16, &config->config.adc16);
  205. #else
  206. return status_invalid_argument;
  207. #endif
  208. } else {
  209. return false;
  210. }
  211. }
  212. /**
  213. * @brief Initialize an ADC channel.
  214. *
  215. * @param[in] config A pointer to the configuration struct of "adc_config_t".
  216. * @retval status_success Initialize an ADC instance successfully.
  217. * @retval status_invalid_argument Initialize an ADC instance unsuccessfully because of passing one or more invalid arguments.
  218. */
  219. static inline hpm_stat_t hpm_adc_channel_init(adc_channel_config_t *config)
  220. {
  221. if (config->module == adc_module_adc12) {
  222. #ifdef CONFIG_HAS_HPMSDK_ADC12
  223. return adc12_init_channel(config->adc_base.adc12, &config->config.adc12_ch);
  224. #else
  225. return status_invalid_argument;
  226. #endif
  227. } else if (config->module == adc_module_adc16) {
  228. #ifdef CONFIG_HAS_HPMSDK_ADC16
  229. return adc16_init_channel(config->adc_base.adc16, &config->config.adc16_ch);
  230. #else
  231. return status_invalid_argument;
  232. #endif
  233. } else {
  234. return false;
  235. }
  236. }
  237. /**
  238. * @brief Configure the periodic mode for an ADC instance.
  239. *
  240. * @param[in] config A pointer to the configuration struct of "adc_prd_config_t".
  241. * @retval status_success Configure the periodic mode for an ADC instance successfully.
  242. * @retval status_invalid_argument Configure the periodic mode for an ADC instance unsuccessfully because of passing one or more invalid arguments.
  243. *
  244. */
  245. static inline hpm_stat_t hpm_adc_set_period_config(adc_prd_config_t *config)
  246. {
  247. if (config->module == adc_module_adc12) {
  248. #ifdef CONFIG_HAS_HPMSDK_ADC12
  249. return adc12_set_prd_config(config->adc_base.adc12, &config->config.adc12);
  250. #else
  251. return status_invalid_argument;
  252. #endif
  253. } else if (config->module == adc_module_adc16) {
  254. #ifdef CONFIG_HAS_HPMSDK_ADC16
  255. return adc16_set_prd_config(config->adc_base.adc16, &config->config.adc16);
  256. #else
  257. return status_invalid_argument;
  258. #endif
  259. } else {
  260. return false;
  261. }
  262. }
  263. /**
  264. * @brief Configure the sequence mode for an ADC instance.
  265. *
  266. * @param[in] config A pointer to configuration struct of "adc_seq_config_t".
  267. * @retval status_success Configure the sequence mode for an ADC instance successfully.
  268. * @retval status_invalid_argument Configure the sequence mode for an ADC instance unsuccessfully because of passing one or more invalid arguments.
  269. */
  270. static inline hpm_stat_t hpm_adc_set_sequence_config(adc_seq_config_t *config)
  271. {
  272. if (config->module == adc_module_adc12) {
  273. #ifdef CONFIG_HAS_HPMSDK_ADC12
  274. return adc12_set_seq_config(config->adc_base.adc12, &config->config.adc12);
  275. #else
  276. return status_invalid_argument;
  277. #endif
  278. } else if (config->module == adc_module_adc16) {
  279. #ifdef CONFIG_HAS_HPMSDK_ADC16
  280. return adc16_set_seq_config(config->adc_base.adc16, &config->config.adc16);
  281. #else
  282. return status_invalid_argument;
  283. #endif
  284. } else {
  285. return false;
  286. }
  287. }
  288. /**
  289. * @brief Configure the preemption mode for an ADC instance.
  290. *
  291. * @param[in] config a pointer to configuration struct of "adc_pmt_config_t".
  292. * @retval status_success Configure the preemption mode for an ADC instance successfully.
  293. * @retval status_invalid_argument Configure the preemption mode for an ADC instance unsuccessfully because of passing one or more invalid arguments.
  294. */
  295. static inline hpm_stat_t hpm_adc_set_preempt_config(adc_pmt_config_t *config)
  296. {
  297. if (config->module == adc_module_adc12) {
  298. #ifdef CONFIG_HAS_HPMSDK_ADC12
  299. return adc12_set_pmt_config(config->adc_base.adc12, &config->config.adc12);
  300. #else
  301. return status_invalid_argument;
  302. #endif
  303. } else if (config->module == adc_module_adc16) {
  304. #ifdef CONFIG_HAS_HPMSDK_ADC16
  305. return adc16_set_pmt_config(config->adc_base.adc16, &config->config.adc16);
  306. #else
  307. return status_invalid_argument;
  308. #endif
  309. } else {
  310. return false;
  311. }
  312. }
  313. /**
  314. * @brief Configure the stop position offset in the specified memory for DMA write operation for sequence mode.
  315. *
  316. * @param[in] ptr An ADC peripheral base address.
  317. * @param[in] stop_pos The stop position offset.
  318. */
  319. static inline void hpm_adc_set_seq_stop_pos(adc_type *ptr, uint16_t stop_pos)
  320. {
  321. if (ptr->module == adc_module_adc12) {
  322. #ifdef CONFIG_HAS_HPMSDK_ADC12
  323. adc12_set_seq_stop_pos(ptr->adc_base.adc12, stop_pos);
  324. #endif
  325. } else if (ptr->module == adc_module_adc16) {
  326. #ifdef CONFIG_HAS_HPMSDK_ADC16
  327. adc16_set_seq_stop_pos(ptr->adc_base.adc16, stop_pos);
  328. #endif
  329. }
  330. }
  331. /**
  332. * @brief Configure the start address of DMA write operation for preemption mode.
  333. *
  334. * @param[in] ptr An ADC peripheral base address.
  335. * @param[in] addr The start address of DMA write operation.
  336. */
  337. static inline void hpm_adc_init_pmt_dma(adc_type *ptr, uint32_t addr)
  338. {
  339. if (ptr->module == adc_module_adc12) {
  340. #ifdef CONFIG_HAS_HPMSDK_ADC12
  341. adc12_init_pmt_dma(ptr->adc_base.adc12, addr);
  342. #endif
  343. } else if (ptr->module == adc_module_adc16) {
  344. #ifdef CONFIG_HAS_HPMSDK_ADC16
  345. adc16_init_pmt_dma(ptr->adc_base.adc16, addr);
  346. #endif
  347. }
  348. }
  349. /**
  350. * @brief Configure the start address of DMA write operation for preemption mode.
  351. *
  352. * @param[in] config A pointer to configuration struct of "adc_dma_config_t".
  353. */
  354. static inline void hpm_adc_init_seq_dma(adc_dma_config_t *config)
  355. {
  356. if (config->module == adc_module_adc12) {
  357. #ifdef CONFIG_HAS_HPMSDK_ADC12
  358. adc12_init_seq_dma(config->adc_base.adc12, &config->config.adc12);
  359. #endif
  360. } else if (config->module == adc_module_adc16) {
  361. #ifdef CONFIG_HAS_HPMSDK_ADC16
  362. adc16_init_seq_dma(config->adc_base.adc16, &config->config.adc16);
  363. #endif
  364. }
  365. }
  366. /**
  367. * @brief Get ADC status flags.
  368. *
  369. * This function gets all ADC status flags.
  370. * @param[in] ptr An ADC peripheral base address.
  371. * @retval Status The ADC interrupt status flags.
  372. */
  373. static inline uint32_t hpm_adc_get_status_flags(adc_type *ptr)
  374. {
  375. if (ptr->module == adc_module_adc12) {
  376. #ifdef CONFIG_HAS_HPMSDK_ADC12
  377. return adc12_get_status_flags(ptr->adc_base.adc12);
  378. #else
  379. return 0;
  380. #endif
  381. } else if (ptr->module == adc_module_adc16) {
  382. #ifdef CONFIG_HAS_HPMSDK_ADC16
  383. return adc16_get_status_flags(ptr->adc_base.adc16);
  384. #else
  385. return 0;
  386. #endif
  387. } else {
  388. return false;
  389. }
  390. }
  391. /**
  392. * @brief Get the setting value of wait disable.
  393. *
  394. * This status flag is only used when wait_dis is set to disable.
  395. *
  396. * @param[in] ptr An ADC peripheral base address.
  397. * @retval Status It means whether the current setting of wait disable is disable.
  398. */
  399. static inline bool hpm_adc_get_wait_dis_status(adc_type *ptr)
  400. {
  401. if (ptr->module == adc_module_adc12) {
  402. #ifdef CONFIG_HAS_HPMSDK_ADC12
  403. return adc12_get_wait_dis_status(ptr->adc_base.adc12);
  404. #else
  405. return 1;
  406. #endif
  407. } else if (ptr->module == adc_module_adc16) {
  408. #ifdef CONFIG_HAS_HPMSDK_ADC16
  409. return adc16_get_wait_dis_status(ptr->adc_base.adc16);
  410. #else
  411. return 1;
  412. #endif
  413. } else {
  414. return false;
  415. }
  416. }
  417. /**
  418. * @brief Get status flag of a conversion.
  419. *
  420. * This status flag is only used when wait_dis is set to disable.
  421. *
  422. * @param[in] ptr An ADC peripheral base address.
  423. * @param[in] ch An ADC peripheral channel.
  424. * @retval Status It means the current conversion is valid.
  425. */
  426. static inline bool hpm_adc_get_conv_valid_status(adc_type *ptr, uint8_t ch)
  427. {
  428. if (ptr->module == adc_module_adc12) {
  429. #ifdef CONFIG_HAS_HPMSDK_ADC12
  430. return adc12_get_conv_valid_status(ptr->adc_base.adc12, ch);
  431. #else
  432. return 0;
  433. #endif
  434. } else if (ptr->module == adc_module_adc16) {
  435. #ifdef CONFIG_HAS_HPMSDK_ADC16
  436. return adc16_get_conv_valid_status(ptr->adc_base.adc16, ch);
  437. #else
  438. return 0;
  439. #endif
  440. } else {
  441. return false;
  442. }
  443. }
  444. /**
  445. * @brief Clear status flags.
  446. *
  447. * Only the specified flags can be cleared by writing INT_STS register.
  448. *
  449. * @param[in] ptr An ADC peripheral base address.
  450. * @param[in] mask Mask value for flags to be cleared. Refer to "adc12_irq_event_t". Refer to "adc16_irq_event_t".
  451. */
  452. static inline void hpm_adc_clear_status_flags(adc_type *ptr, uint32_t mask)
  453. {
  454. if (ptr->module == adc_module_adc12) {
  455. #ifdef CONFIG_HAS_HPMSDK_ADC12
  456. adc12_clear_status_flags(ptr->adc_base.adc12, mask);
  457. #endif
  458. } else if (ptr->module == adc_module_adc16) {
  459. #ifdef CONFIG_HAS_HPMSDK_ADC16
  460. adc16_clear_status_flags(ptr->adc_base.adc16, mask);
  461. #endif
  462. }
  463. }
  464. /**
  465. * @brief Enable interrupts.
  466. *
  467. * @param[in] ptr An ADC peripheral base address.
  468. * @param[in] mask Mask value for interrupt events. Refer to "adc12_irq_event_t".Refer to "adc16_irq_event_t".
  469. */
  470. static inline void hpm_adc_enable_interrupts(adc_type *ptr, uint32_t mask)
  471. {
  472. if (ptr->module == adc_module_adc12) {
  473. #ifdef CONFIG_HAS_HPMSDK_ADC12
  474. adc12_enable_interrupts(ptr->adc_base.adc12, mask);
  475. #endif
  476. } else if (ptr->module == adc_module_adc16) {
  477. #ifdef CONFIG_HAS_HPMSDK_ADC16
  478. adc16_enable_interrupts(ptr->adc_base.adc16, mask);
  479. #endif
  480. }
  481. }
  482. /**
  483. * @brief Disable interrupts.
  484. *
  485. * @param[in] ptr An ADC peripheral base address.
  486. * @param[in] mask Mask value for interrupt events. Refer to "adc12_irq_event_t".Refer to "adc16_irq_event_t".
  487. */
  488. static inline void hpm_adc_disable_interrupts(adc_type *ptr, uint32_t mask)
  489. {
  490. if (ptr->module == adc_module_adc12) {
  491. #ifdef CONFIG_HAS_HPMSDK_ADC12
  492. adc12_disable_interrupts(ptr->adc_base.adc12, mask);
  493. #endif
  494. } else if (ptr->module == adc_module_adc16) {
  495. #ifdef CONFIG_HAS_HPMSDK_ADC16
  496. adc16_disable_interrupts(ptr->adc_base.adc16, mask);
  497. #endif
  498. }
  499. }
  500. /**
  501. * @brief Get the result in oneshot mode.
  502. *
  503. * @param[in] ptr An ADC peripheral base address.
  504. * @param[in] ch An ADC peripheral channel.
  505. * @param[out] result The result of an ADC12 conversion.
  506. *
  507. * @retval status_success Get the result of an ADC12 conversion in oneshot mode successfully.
  508. * @retval status_invalid_argument Get the result of an ADC12 conversion in oneshot mode unsuccessfully because of passing invalid arguments.
  509. */
  510. static inline hpm_stat_t hpm_adc_get_oneshot_result(adc_type *ptr, uint8_t ch, uint16_t *result)
  511. {
  512. if (ptr->module == adc_module_adc12) {
  513. #ifdef CONFIG_HAS_HPMSDK_ADC12
  514. return adc12_get_oneshot_result(ptr->adc_base.adc12, ch, result);
  515. #else
  516. return status_invalid_argument;
  517. #endif
  518. } else if (ptr->module == adc_module_adc16) {
  519. #ifdef CONFIG_HAS_HPMSDK_ADC16
  520. return adc16_get_oneshot_result(ptr->adc_base.adc16, ch, result);
  521. #else
  522. return status_invalid_argument;
  523. #endif
  524. } else {
  525. return false;
  526. }
  527. }
  528. /**
  529. * @brief Get the result in periodic mode.
  530. *
  531. * @param[in] ptr An ADC12 peripheral base address.
  532. * @param[in] ch An ADC12 peripheral channel.
  533. * @param[out] result The result of an ADC12 conversion.
  534. *
  535. * @retval status_success Get the result of an ADC12 conversion in periodic mode successfully.
  536. * @retval status_invalid_argument Get the result of an ADC12 conversion in periodic mode unsuccessfully because of passing invalid arguments.
  537. */
  538. hpm_stat_t hpm_adc_get_prd_result(adc_type *ptr, uint8_t ch, uint16_t *result)
  539. {
  540. if (ptr->module == adc_module_adc12) {
  541. #ifdef CONFIG_HAS_HPMSDK_ADC12
  542. return adc12_get_prd_result(ptr->adc_base.adc12, ch, result);
  543. #else
  544. return status_invalid_argument;
  545. #endif
  546. } else if (ptr->module == adc_module_adc16) {
  547. #ifdef CONFIG_HAS_HPMSDK_ADC16
  548. return adc16_get_prd_result(ptr->adc_base.adc16, ch, result);
  549. #else
  550. return status_invalid_argument;
  551. #endif
  552. } else {
  553. return false;
  554. }
  555. }
  556. /**
  557. * @brief Do a software trigger for sequence mode.
  558. *
  559. * @param[in] ptr An adc peripheral base address.
  560. *
  561. */
  562. void hpm_adc_trigger_seq_by_sw(adc_type *ptr)
  563. {
  564. if (ptr->module == adc_module_adc12) {
  565. #ifdef CONFIG_HAS_HPMSDK_ADC12
  566. return adc12_trigger_seq_by_sw(ptr->adc_base.adc12);
  567. #endif
  568. } else if (ptr->module == adc_module_adc16) {
  569. #ifdef CONFIG_HAS_HPMSDK_ADC16
  570. return adc16_trigger_seq_by_sw(ptr->adc_base.adc16);
  571. #endif
  572. }
  573. }
  574. #ifdef __cplusplus
  575. }
  576. #endif
  577. /** @} */
  578. #endif