hpm_opamp_drv.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*
  2. * Copyright (c) 2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_OPAMP_DRV_H
  8. #define HPM_OPAMP_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_opamp_regs.h"
  11. #include "hpm_soc_feature.h"
  12. /**
  13. * @brief OPMAP driver APIs
  14. * @defgroup opamp_interface OPAMP driver APIs
  15. * @ingroup io_interfaces
  16. * @{
  17. *
  18. */
  19. #define OPAMP_MODE_FOLLOW_KEY (0x06)
  20. #define OPAMP_MODE_INVERT_INDEX0_KEY (0x08)
  21. #define OPAMP_MODE_INVERT_INDEX1_KEY (0x18)
  22. #define OPAMP_MODE_NON_INVERT_INDEX0_KEY (0x01)
  23. #define OPAMP_MODE_NON_INVERT_INDEX1_KEY (0x09)
  24. #define OPAMP_MODE_NON_INVERT_INDEX2_KEY (0x11)
  25. #define OPAMP_MODE_NON_INVERT_INDEX3_KEY (0x19)
  26. #define OPAMP_MODE_NON_INVERT_INDEX4_KEY (0x09)
  27. #define OPAMP_MODE_USER_DEFINE_KEY (0x04)
  28. /**
  29. * @brief Reverse Input Pin Selection
  30. *
  31. */
  32. typedef enum {
  33. inm_pad_vim0 = 0, /**< Connect pad vim0 */
  34. inm_pad_vim1 = 1, /**< Connect pad vim1 */
  35. inm_pad_vim2 = 2, /**< Connect pad vim2 */
  36. inm_pad_dac = 3, /**< Connect pad vim dac */
  37. inm_pad_floating = 4 /**< Connect inm floating */
  38. } opamp_inm_pad_t;
  39. /**
  40. * @brief Gain multiplier selection
  41. *
  42. */
  43. typedef enum {
  44. gain_x_2 = 0, /**< gain x2 */
  45. gain_x_4 = 1,
  46. gain_x_8 = 2,
  47. gain_x_16 = 3,
  48. gain_x_32 = 4,
  49. gain_x_64 = 5,
  50. gain_x_128 = 6, /**< gain x128 */
  51. } opamp_gain_t;
  52. /**
  53. * @brief Miller Capacitor Selection
  54. *
  55. */
  56. typedef enum {
  57. miller_cap_x_7 = 0, /**< 7 unit cap */
  58. miller_cap_x_8 = 1,
  59. miller_cap_x_10 = 2,
  60. miller_cap_x_13 = 3,
  61. miller_cap_x_15 = 4, /**< 15 unit cap */
  62. miller_cap_x_18 = 5,
  63. miller_cap_x_5 = 6,
  64. miller_cap_x_6 = 7, /**< 6 unit cap */
  65. } opamp_miller_cap_t;
  66. /**
  67. * @brief Positive Input Pin Selection
  68. *
  69. */
  70. typedef enum {
  71. inp_pad_vip0 = 0, /**< Connect pad vip0 */
  72. inp_pad_vip1 = 1, /**< Connect pad vip1 */
  73. inp_pad_vip2 = 2, /**< Connect pad vip2 */
  74. inp_pad_dac = 3, /**< Connect pad vip dac */
  75. inp_pad_vsupply_x_0_25 = 4, /**< Connect reference = 0.25 * vsupply */
  76. inp_pad_vsupply_x_0_5 = 5, /**< Connect reference = 0.5 * vsupply */
  77. inp_pad_vsupply_x_0_75 = 6, /**< Connect reference = 0.75 * vsupply */
  78. inp_pad_floating = 7 /**< Connect inp floating */
  79. } opamp_inp_pad_t;
  80. /**
  81. * @brief opamp preset channel
  82. *
  83. */
  84. typedef enum {
  85. cfg_preset_0 = OPAMP_CFG_PRESET0,
  86. cfg_preset_1 = OPAMP_CFG_PRESET1,
  87. cfg_preset_2 = OPAMP_CFG_PRESET2,
  88. cfg_preset_3 = OPAMP_CFG_PRESET3,
  89. cfg_preset_4 = OPAMP_CFG_PRESET4,
  90. cfg_preset_5 = OPAMP_CFG_PRESET5,
  91. cfg_preset_6 = OPAMP_CFG_PRESET6,
  92. cfg_preset_7 = OPAMP_CFG_PRESET7,
  93. } opamp_cfg_preset_chn_t;
  94. /**
  95. * @brief operational amplifier
  96. *
  97. */
  98. typedef enum {
  99. mode_follow = 0, /**< opamp follow mode */
  100. mode_invert_intern_vol = 1, /**< inverting opamp */
  101. mode_invert_extern_vol = 2, /**< inverted amplification mode, external reference voltage */
  102. mode_invert_dac_vol = 3, /**< inverted amplification mode, DAC output reference voltage */
  103. mode_non_invert_gnd_vol = 4, /**< forward amplification mode, GND is the reference voltage */
  104. mode_non_invert_extern_vol = 5, /**< forward amplification mode, external reference voltage */
  105. mode_non_invert_dac_vol = 6, /**< forward amplification mode, DAC output reference voltage */
  106. mode_user = 7, /**< custom Mode */
  107. } opamp_mode_t;
  108. /**
  109. * @brief opamp configuration preset0
  110. *
  111. */
  112. typedef union opamp_cfg_preset0 {
  113. struct {
  114. uint32_t vip_select: 3;
  115. uint32_t vim_select: 3;
  116. uint32_t vswitch_select: 3;
  117. uint32_t cap_select: 4;
  118. uint32_t reserve: 19;
  119. };
  120. uint32_t val;
  121. } opamp_ctrl_cfg_preset0_t;
  122. /**
  123. * @brief opamp configuration preset1
  124. *
  125. */
  126. typedef union opamp_cfg_preset1 {
  127. struct {
  128. uint32_t res_select: 3;
  129. uint32_t function_mode: 5;
  130. uint32_t iref_select: 2;
  131. uint32_t opaout_select: 2;
  132. uint32_t is_vssa_disconnect: 1;
  133. uint32_t en_lv: 1;
  134. uint32_t hw_trig_en: 1;
  135. uint32_t reserve: 17;
  136. };
  137. uint32_t val;
  138. } opamp_ctrl_cfg_preset1_t;
  139. typedef struct opamp_cfg {
  140. opamp_mode_t mode;
  141. opamp_inm_pad_t negative_input_pin;
  142. opamp_inp_pad_t positive_input_pin;
  143. opamp_gain_t gain;
  144. opamp_miller_cap_t miller_cap;
  145. bool enable_extern_filter_cap;
  146. bool enable_phase_margin_cap;
  147. } opamp_cfg_t;
  148. #ifdef __cplusplus
  149. extern "C" {
  150. #endif
  151. /**
  152. * @brief opamp initialisation functions
  153. * Use this function to initialise the op-amp to different modes
  154. * @param opamp @ref OPAMP_Type
  155. * @param cfg @ref opamp_cfg_t
  156. * @return @ref hpm_stat_t
  157. */
  158. hpm_stat_t opamp_init(OPAMP_Type *opamp, opamp_cfg_t *cfg);
  159. /**
  160. * @brief enable opamp function
  161. *
  162. * @param opamp @ref OPAMP_Type
  163. */
  164. static inline void opamp_enable(OPAMP_Type *opamp)
  165. {
  166. opamp->CTRL0 |= OPAMP_CTRL0_EN_LV_MASK;
  167. }
  168. /**
  169. * @brief preset enable opamp function
  170. *
  171. * @param opamp @ref OPAMP_Type
  172. * @param preset_chn preset channel
  173. */
  174. static inline void opamp_preset_opamp_enable(OPAMP_Type *opamp, uint8_t preset_chn)
  175. {
  176. opamp->CFG[preset_chn].CFG1 |= OPAMP_CFG_CFG1_EN_LV_MASK;
  177. }
  178. /**
  179. * @brief disable opamp function
  180. *
  181. * @param opamp @ref OPAMP_Type
  182. */
  183. static inline void opamp_disable(OPAMP_Type *opamp)
  184. {
  185. opamp->CTRL0 &= ~OPAMP_CTRL0_EN_LV_MASK;
  186. }
  187. /**
  188. * @brief preset disable opamp function
  189. *
  190. * @param opamp @ref OPAMP_Type
  191. * @param preset_chn preset channel
  192. */
  193. static inline void opamp_preset_opamp_disable(OPAMP_Type *opamp, uint8_t preset_chn)
  194. {
  195. opamp->CFG[preset_chn].CFG1 &= ~OPAMP_CFG_CFG1_EN_LV_MASK;
  196. }
  197. /**
  198. * @brief opamp miller cap selection
  199. *
  200. * @param opamp @ref OPAMP_Type
  201. * @param select @ref opamp_miller_cap_t
  202. */
  203. static inline void opamp_miller_cap_select(OPAMP_Type *opamp, opamp_miller_cap_t select)
  204. {
  205. opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_MILLER_SEL_MASK)) | OPAMP_CTRL0_MILLER_SEL_SET(select);
  206. }
  207. /**
  208. * @brief opamp miller cap selection preset
  209. *
  210. * @param opamp @ref OPAMP_Type
  211. * @param preset_chn preset channel
  212. * @param select @ref opamp_miller_cap_t
  213. */
  214. static inline void opamp_preset_miller_cap_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_miller_cap_t select)
  215. {
  216. opamp->CFG[preset_chn].CFG0 = (opamp->CFG[preset_chn].CFG0 & (~OPAMP_CFG_CFG0_MILLER_SEL_MASK)) | OPAMP_CFG_CFG0_MILLER_SEL_SET(select);
  217. }
  218. /**
  219. * @brief enable phase margin compensation cap
  220. *
  221. * @param opamp @ref OPAMP_Type
  222. */
  223. static inline void opamp_phase_margin_cap_enable(OPAMP_Type *opamp)
  224. {
  225. opamp->CTRL0 &= ~OPAMP_CTRL0_DISABLE_PM_CAP_MASK;
  226. }
  227. /**
  228. * @brief enable phase margin compensation cap preset
  229. *
  230. * @param opamp @ref OPAMP_Type
  231. * @param preset_chn preset channel
  232. */
  233. static inline void opamp_preset_phase_margin_cap_enable(OPAMP_Type *opamp, uint8_t preset_chn)
  234. {
  235. opamp->CFG[preset_chn].CFG0 &= ~OPAMP_CFG_CFG0_DISABLE_PM_CAP_MASK;
  236. }
  237. /**
  238. * @brief disable phase margin compensation cap
  239. *
  240. * @param opamp @ref OPAMP_Type
  241. */
  242. static inline void opamp_phase_margin_cap_disable(OPAMP_Type *opamp)
  243. {
  244. opamp->CTRL0 |= OPAMP_CTRL0_DISABLE_PM_CAP_MASK;
  245. }
  246. /**
  247. * @brief disable phase margin compensation cap preset
  248. *
  249. * @param opamp @ref OPAMP_Type
  250. * @param preset_chn preset channel
  251. */
  252. static inline void opamp_preset_phase_margin_cap_disable(OPAMP_Type *opamp, uint8_t preset_chn)
  253. {
  254. opamp->CFG[preset_chn].CFG0 |= OPAMP_CFG_CFG0_DISABLE_PM_CAP_MASK;
  255. }
  256. /**
  257. * @brief opamp core inm connect pad
  258. *
  259. * @param opamp @ref OPAMP_Type
  260. * @param select @ref opamp_inm_pad_t
  261. */
  262. static inline void opamp_inn_pad_select(OPAMP_Type *opamp, opamp_inm_pad_t select)
  263. {
  264. opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_VIM_SEL_MASK)) | OPAMP_CTRL0_VIM_SEL_SET(select);
  265. }
  266. /**
  267. * @brief opamp core inm connect pad preset
  268. *
  269. * @param opamp @ref OPAMP_Type
  270. * @param preset_chn preset channel
  271. * @param select @ref opamp_inm_pad_t
  272. */
  273. static inline void opamp_preset_inn_pad_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_inm_pad_t select)
  274. {
  275. opamp->CFG[preset_chn].CFG0 = (opamp->CFG[preset_chn].CFG0 & (~OPAMP_CFG_CFG0_VIM_SEL_MASK)) | OPAMP_CFG_CFG0_VIM_SEL_SET(select);
  276. }
  277. /**
  278. * @brief main string resistor selection
  279. *
  280. * @param opamp @ref OPAMP_Type
  281. * @param select @ref opamp_gain_t
  282. *
  283. */
  284. static inline void opamp_gain_select(OPAMP_Type *opamp, opamp_gain_t select)
  285. {
  286. opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_GAIN_SEL_MASK)) | OPAMP_CTRL0_GAIN_SEL_SET(select);
  287. }
  288. /**
  289. * @brief main string resistor selection preset
  290. *
  291. * @param opamp @ref OPAMP_Type
  292. * @param preset_chn preset channel
  293. * @param select @ref opamp_gain_t
  294. *
  295. */
  296. static inline void opamp_preset_gain_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_gain_t select)
  297. {
  298. opamp->CFG[preset_chn].CFG1 = (opamp->CFG[preset_chn].CFG1 & (~OPAMP_CFG_CFG1_GAIN_SEL_MASK)) | OPAMP_CFG_CFG1_GAIN_SEL_SET(select);
  299. }
  300. /**
  301. * @brief disconnect the main series resistor and VSSA
  302. *
  303. * @param opamp @ref OPAMP_Type
  304. */
  305. static inline void opamp_disconnect_vssa(OPAMP_Type *opamp)
  306. {
  307. opamp->CTRL0 |= OPAMP_CTRL0_VBYPASS_MASK;
  308. }
  309. /**
  310. * @brief disconnect the main series resistor and VSSA preset
  311. *
  312. * @param opamp @ref OPAMP_Type
  313. * @param preset_chn preset channel
  314. */
  315. static inline void opamp_preset_disconnect_vssa(OPAMP_Type *opamp, uint8_t preset_chn)
  316. {
  317. opamp->CFG[preset_chn].CFG1 |= OPAMP_CFG_CFG1_VBYPASS_LV_MASK;
  318. }
  319. /**
  320. * @brief connect the main series resistor and VSSA
  321. *
  322. * @param opamp @ref OPAMP_Type
  323. */
  324. static inline void opamp_connect_vssa(OPAMP_Type *opamp)
  325. {
  326. opamp->CTRL0 &= ~OPAMP_CTRL0_VBYPASS_MASK;
  327. }
  328. /**
  329. * @brief connect the main series resistor and VSSA preset
  330. *
  331. * @param opamp @ref OPAMP_Type
  332. * @param preset_chn preset channel
  333. */
  334. static inline void opamp_preset_connect_vssa(OPAMP_Type *opamp, uint8_t preset_chn)
  335. {
  336. opamp->CFG[preset_chn].CFG1 &= ~OPAMP_CFG_CFG1_VBYPASS_LV_MASK;
  337. }
  338. /**
  339. * @brief opamp inp select
  340. *
  341. * @param opamp @ref OPAMP_Type
  342. * @param select @ref opamp_inp_pad_t
  343. */
  344. static inline void opamp_inp_pad_select(OPAMP_Type *opamp, opamp_inp_pad_t select)
  345. {
  346. opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_VIP_SEL_MASK)) | OPAMP_CTRL0_VIP_SEL_SET(select);
  347. }
  348. /**
  349. * @brief opamp inp select preset
  350. *
  351. * @param opamp @ref OPAMP_Type
  352. * @param preset_chn preset channel
  353. * @param select @ref opamp_inp_pad_t
  354. */
  355. static inline void opamp_preset_inp_pad_select(OPAMP_Type *opamp, uint8_t preset_chn, opamp_inp_pad_t select)
  356. {
  357. opamp->CFG[preset_chn].CFG0 = (opamp->CFG[preset_chn].CFG0 & (~OPAMP_CFG_CFG0_VIP_SEL_MASK)) | OPAMP_CFG_CFG0_VIP_SEL_SET(select);
  358. }
  359. /**
  360. * @brief opamp get current preset
  361. *
  362. * @param opamp @ref OPAMP_Type
  363. * @return value
  364. */
  365. static inline uint8_t opamp_get_cur_preset(OPAMP_Type *opamp)
  366. {
  367. return OPAMP_STATUS_CUR_PRESET_GET(opamp->STATUS);
  368. }
  369. /**
  370. * @brief get the current preset value
  371. *
  372. * @param opamp @ref OPAMP_Type
  373. * @return true one of cur_preset is selected for opamp
  374. * @return false opamp use cfg0 parameters
  375. */
  376. static inline bool opamp_get_is_preset(OPAMP_Type *opamp)
  377. {
  378. return OPAMP_STATUS_PRESET_ACT_GET(opamp->STATUS);
  379. }
  380. /**
  381. * @brief Get the trigger conflict status
  382. *
  383. * @param opamp @ref OPAMP_Type
  384. * @return if more than one hardware trigger is set, will put all trigger input there.
  385. */
  386. static inline uint8_t opamp_get_trig_conflict_status(OPAMP_Type *opamp)
  387. {
  388. return OPAMP_STATUS_TRIG_CONFLICT_GET(opamp->STATUS);
  389. }
  390. /**
  391. * @brief Clear the trigger conflict status
  392. *
  393. * @param opamp @ref OPAMP_Type
  394. */
  395. static inline void opamp_clear_conflict_status(OPAMP_Type *opamp)
  396. {
  397. opamp->STATUS = OPAMP_STATUS_TRIG_CONFLICT_MASK;
  398. }
  399. /**
  400. * @brief Set opamp preset value
  401. *
  402. * @param opamp @ref OPAMP_Type
  403. * @param val @ref opamp_cfg_preset_chn_t
  404. */
  405. static inline void opamp_set_sw_preset_val(OPAMP_Type *opamp, opamp_cfg_preset_chn_t val)
  406. {
  407. opamp->CTRL1 = (opamp->CTRL1 & (~OPAMP_CTRL1_SW_SEL_MASK)) | OPAMP_CTRL1_SW_SEL_SET(val);
  408. }
  409. /**
  410. * @brief Enable software preset
  411. *
  412. * @param opamp @ref OPAMP_Type
  413. */
  414. static inline void opamp_enable_sw_preset(OPAMP_Type *opamp)
  415. {
  416. opamp->CTRL1 |= OPAMP_CTRL1_SW_PRESET_MASK;
  417. }
  418. /**
  419. * @brief Disable software preset
  420. *
  421. * @param opamp @ref OPAMP_Type
  422. */
  423. static inline void opamp_disable_sw_preset(OPAMP_Type *opamp)
  424. {
  425. opamp->CTRL1 &= ~OPAMP_CTRL1_SW_PRESET_MASK;
  426. }
  427. /**
  428. * @brief Set preset x channel value
  429. *
  430. * @param opamp @ref OPAMP_Type
  431. * @param preset_chn preset channel
  432. * @param chn channel
  433. */
  434. static inline void opamp_set_preset_x_chn(OPAMP_Type *opamp, uint8_t preset_chn, uint8_t chn)
  435. {
  436. opamp->CFG[preset_chn].CFG2 = OPAMP_CFG_CFG2_CHANNEL_SET(chn);
  437. }
  438. /**
  439. * @brief Set preset cfg
  440. *
  441. * @param opamp @ref OPAMP_Type
  442. * @param preset_chn preset channel
  443. * @param cfg @ref opamp_cfg_t
  444. * @return hpm_stat_t
  445. */
  446. hpm_stat_t opamp_set_preset_cfg(OPAMP_Type *opamp, uint8_t preset_chn, opamp_cfg_t *cfg);
  447. /**
  448. * @brief opamp enable preset hardware trig
  449. *
  450. * @param opamp @ref OPAMP_Type
  451. * @param preset_chn preset channel
  452. */
  453. static inline void opamp_preset_enable_hw_trig(OPAMP_Type *opamp, uint8_t preset_chn)
  454. {
  455. opamp->CFG[preset_chn].CFG1 |= OPAMP_CFG_CFG1_HW_TRIG_EN_MASK;
  456. }
  457. /**
  458. * @brief opamp disable preset hardware trig
  459. *
  460. * @param opamp @ref OPAMP_Type
  461. * @param preset_chn preset channel
  462. */
  463. static inline void opamp_preset_disable_hw_trig(OPAMP_Type *opamp, uint8_t preset_chn)
  464. {
  465. opamp->CFG[preset_chn].CFG1 &= ~OPAMP_CFG_CFG1_HW_TRIG_EN_MASK;
  466. }
  467. /**
  468. * @brief opamp set mode
  469. *
  470. * @param opamp @ref OPAMP_Type
  471. * @param mode OPAMP_MODE_XX
  472. */
  473. static inline void opamp_mode_set(OPAMP_Type *opamp, uint8_t mode)
  474. {
  475. opamp->CTRL0 = (opamp->CTRL0 & (~OPAMP_CTRL0_MODE_MASK)) | OPAMP_CTRL0_MODE_SET(mode);
  476. }
  477. /**
  478. * @brief opamp preset set mode
  479. *
  480. * @param opamp @ref OPAMP_Type
  481. * @param preset_chn preset channel
  482. * @param mode OPAMP_MODE_XX
  483. */
  484. static inline void opamp_preset_mode_set(OPAMP_Type *opamp, uint8_t preset_chn, uint8_t mode)
  485. {
  486. opamp->CFG[preset_chn].CFG1 = (opamp->CFG[preset_chn].CFG1 & (~OPAMP_CFG_CFG1_MODE_MASK)) | OPAMP_CFG_CFG1_MODE_SET(mode);
  487. }
  488. /**
  489. * @}
  490. *
  491. */
  492. #ifdef __cplusplus
  493. }
  494. #endif
  495. #endif /* HPM_ACMP_DRV_H */