hpm_clc_drv.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /*
  2. * Copyright (c) 2024 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_CLC_DRV_H
  8. #define HPM_CLC_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_clc_regs.h"
  11. /**
  12. * @brief CLC driver APIs
  13. * @defgroup clc_interface CLC driver APIs
  14. * @ingroup motor_interfaces
  15. * @{
  16. */
  17. /**
  18. * @brief clc channel
  19. */
  20. typedef enum {
  21. clc_vd_chn = CLC_VDVQ_CHAN_VD,
  22. clc_vq_chn = CLC_VDVQ_CHAN_VQ,
  23. } clc_chn_t; /**< clc_chn_t */
  24. /**
  25. * @brief clc coefficient zone
  26. */
  27. typedef enum {
  28. clc_coeff_zone_0 = CLC_COEFF_0,
  29. clc_coeff_zone_1 = CLC_COEFF_1,
  30. clc_coeff_zone_2 = CLC_COEFF_2,
  31. } clc_coeff_zone_t; /**< clc_coeff_zone_t */
  32. /**
  33. * @brief clc irq mask bit
  34. */
  35. typedef enum {
  36. clc_irq_calc_done = BIT0_MASK,
  37. clc_irq_eadc_setting_err = BIT1_MASK,
  38. clc_irq_2p2z_clamp_setting_err = BIT2_MASK,
  39. clc_irq_2p2z_over_hi = BIT3_MASK,
  40. clc_irq_2p2z_over_lo = BIT4_MASK,
  41. clc_irq_2p2z_over_sf = BIT5_MASK,
  42. clc_irq_3p3z_clamp_setting_err = BIT6_MASK,
  43. clc_irq_3p3z_over_hi = BIT7_MASK,
  44. clc_irq_3p3z_over_lo = BIT8_MASK,
  45. clc_irq_forb_setting_err = BIT9_MASK,
  46. clc_irq_data_in_forbid = BIT10_MASK
  47. } clc_irq_mask_t;
  48. /**
  49. * @brief clc parameter configuration
  50. */
  51. typedef struct {
  52. int32_t eadc_lowth;
  53. int32_t eadc_mid_lowth;
  54. int32_t eadc_mid_highth;
  55. int32_t eadc_highth;
  56. int32_t _2p2z_clamp_lowth;
  57. int32_t _2p2z_clamp_highth;
  58. int32_t _3p3z_clamp_lowth;
  59. int32_t _3p3z_clamp_highth;
  60. int32_t output_forbid_lowth;
  61. int32_t output_forbid_mid;
  62. int32_t output_forbid_highth;
  63. } clc_param_config_t; /**< clc_param_config_t */
  64. /**
  65. * @brief clc coefficient configuration
  66. */
  67. typedef struct {
  68. float b0;
  69. float b1;
  70. float b2;
  71. float b3;
  72. float a0;
  73. float a1;
  74. float a2;
  75. } clc_coeff_config_t; /**< clc_coeff_config_t */
  76. #ifdef __cplusplus
  77. extern "C" {
  78. #endif
  79. /**
  80. * @brief CLC enable or disable
  81. *
  82. * @param[in] clc CLC base address
  83. * @param[in] chn CLC channel, @ref clc_chn_t
  84. * @param[in] enable true-enable, false-disable
  85. */
  86. static inline void clc_set_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
  87. {
  88. if (enable) {
  89. clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_ENABLE_CLC_MASK;
  90. } else {
  91. clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_ENABLE_CLC_MASK;
  92. }
  93. }
  94. /**
  95. * @brief CLC keep working even if bad irq status ocurred
  96. *
  97. * @param[in] clc CLC base address
  98. * @param[in] chn CLC channel, @ref clc_chn_t
  99. * @param[in] enable true-enable, false-disable
  100. */
  101. static inline void clc_set_mask_mode_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
  102. {
  103. if (enable) {
  104. clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_MASK_MODE_MASK;
  105. } else {
  106. clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_MASK_MODE_MASK;
  107. }
  108. }
  109. /**
  110. * @brief CLC set software inject dq work mode
  111. *
  112. * @param[in] clc CLC base address
  113. * @param[in] chn CLC channel, @ref clc_chn_t
  114. * @param[in] enable true-if the ADC value comes from software injection and the VD/VQ channel is required for joint use.
  115. */
  116. static inline void clc_set_sw_inject_dq_mode_enable(CLC_Type *clc, clc_chn_t chn, bool enable)
  117. {
  118. if (enable) {
  119. clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_DQ_MODE_MASK;
  120. } else {
  121. clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_DQ_MODE_MASK;
  122. }
  123. }
  124. /**
  125. * @brief CLC set irq enable or disable
  126. * @param[in] clc CLC base address
  127. * @param[in] chn CLC channel, @ref clc_chn_t
  128. * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
  129. * @param[in] enable enable or disable
  130. * @arg true enable
  131. * @arg false disable
  132. */
  133. static inline void clc_set_irq_enable(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask, bool enable)
  134. {
  135. if (enable) {
  136. clc->VDVQ_CHAN[chn].MODE |= CLC_VDVQ_CHAN_MODE_ENABLE_IRQ_SET(irq_mask);
  137. } else {
  138. clc->VDVQ_CHAN[chn].MODE &= ~CLC_VDVQ_CHAN_MODE_ENABLE_IRQ_SET(irq_mask);
  139. }
  140. }
  141. /**
  142. * @brief CLC get irq status
  143. * @param[in] clc CLC base address
  144. * @param[in] chn CLC channel, @ref clc_chn_t
  145. * @retval irq status.
  146. */
  147. static inline uint32_t clc_get_irq_status(CLC_Type *clc, clc_chn_t chn)
  148. {
  149. return CLC_VDVQ_CHAN_STATUS_STATUS_GET(clc->VDVQ_CHAN[chn].STATUS);
  150. }
  151. /**
  152. * @brief CLC clear irq status
  153. * @param[in] clc CLC base address
  154. * @param[in] chn CLC channel, @ref clc_chn_t
  155. * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
  156. */
  157. static inline void clc_clear_irq_status(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask)
  158. {
  159. clc->VDVQ_CHAN[chn].STATUS = CLC_VDVQ_CHAN_STATUS_STATUS_SET(irq_mask);
  160. }
  161. /**
  162. * @brief CLC check irq request flag
  163. * @param[in] clc CLC base address
  164. * @param[in] chn CLC channel, @ref clc_chn_t
  165. * @param[in] irq_mask irq mask, @ref clc_irq_mask_t
  166. * @retval true-has irq req, false-no irq req.
  167. */
  168. static inline bool clc_get_irq_flag(CLC_Type *clc, clc_chn_t chn, uint32_t irq_mask)
  169. {
  170. return ((clc->VDVQ_CHAN[chn].STATUS & irq_mask) == irq_mask) ? true : false;
  171. }
  172. /**
  173. * @brief CLC set adc channel
  174. * @param[in] clc CLC base address
  175. * @param[in] chn CLC channel, @ref clc_chn_t
  176. * @param[in] adc_chn adc channel for ADC0~3 or SDM_ADC0~7, adc from VSC must be set to 0.
  177. * @param[in] adc_offset adc offset for ADC0~3 or SDM_ADC0~7, adc from VSC must be set to 0.
  178. */
  179. static inline void clc_set_adc_chn_offset(CLC_Type *clc, clc_chn_t chn, uint32_t adc_chn, uint32_t adc_offset)
  180. {
  181. clc->VDVQ_CHAN[chn].ADC_CHAN = adc_chn;
  182. clc->VDVQ_CHAN[chn].ADC_OFFSET = adc_offset;
  183. }
  184. /**
  185. * @brief CLC set pwm period
  186. * @param[in] clc CLC base address
  187. * @param[in] chn CLC channel, @ref clc_chn_t
  188. * @param[in] pwm_period 0-clc dac output pwm duty ratio, else-clc dac output pwm period, number of clock cycles.
  189. */
  190. static inline void clc_set_pwm_period(CLC_Type *clc, clc_chn_t chn, uint32_t pwm_period)
  191. {
  192. clc->VDVQ_CHAN[chn].PWM_PERIOD = pwm_period;
  193. }
  194. /**
  195. * @brief CLC set pwm period
  196. * @param[in] clc CLC base address
  197. * @param[in] chn CLC channel, @ref clc_chn_t
  198. * @retval pwm period
  199. */
  200. static inline uint32_t clc_get_pwm_period(CLC_Type *clc, clc_chn_t chn)
  201. {
  202. return clc->VDVQ_CHAN[chn].PWM_PERIOD;
  203. }
  204. /**
  205. * @brief CLC get output caculated value
  206. * @param[in] clc CLC base address
  207. * @param[in] chn CLC channel, @ref clc_chn_t
  208. * @retval CLC output caculated value
  209. */
  210. static inline uint32_t clc_get_output_value(CLC_Type *clc, clc_chn_t chn)
  211. {
  212. return clc->VDVQ_CHAN[chn].OUTPUT_VALUE;
  213. }
  214. /**
  215. * @brief CLC get timestamp
  216. * @param[in] clc CLC base address
  217. * @param[in] chn CLC channel, @ref clc_chn_t
  218. * @retval CLC adc timestamp
  219. */
  220. static inline uint32_t clc_get_timestamp(CLC_Type *clc, clc_chn_t chn)
  221. {
  222. return clc->VDVQ_CHAN[chn].TIMESTAMP;
  223. }
  224. /**
  225. * @brief CLC get error adc latest value
  226. * @param[in] clc CLC base address
  227. * @param[in] chn CLC channel, @ref clc_chn_t
  228. * @retval CLC error adc latest value
  229. */
  230. static inline int32_t clc_get_eadc_current_value(CLC_Type *clc, clc_chn_t chn)
  231. {
  232. return (int32_t)clc->VDVQ_CHAN[chn].EADC_CURR;
  233. }
  234. /**
  235. * @brief CLC get error adc previous0 value
  236. * @param[in] clc CLC base address
  237. * @param[in] chn CLC channel, @ref clc_chn_t
  238. * @retval CLC error adc previous0 value
  239. */
  240. static inline int32_t clc_get_eadc_previous0_value(CLC_Type *clc, clc_chn_t chn)
  241. {
  242. return (int32_t)clc->VDVQ_CHAN[chn].EADC_PRE0;
  243. }
  244. /**
  245. * @brief CLC software inject error adc previous0 value
  246. * @param[in] clc CLC base address
  247. * @param[in] chn CLC channel, @ref clc_chn_t
  248. * @param[in] value CLC error adc previous0 value
  249. */
  250. static inline void clc_sw_inject_eadc_previous0_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
  251. {
  252. clc->VDVQ_CHAN[chn].EADC_PRE0 = (uint32_t)value;
  253. }
  254. /**
  255. * @brief CLC get error adc previous1 value
  256. * @param[in] clc CLC base address
  257. * @param[in] chn CLC channel, @ref clc_chn_t
  258. * @retval CLC error adc previous1 value
  259. */
  260. static inline int32_t clc_get_eadc_previous1_value(CLC_Type *clc, clc_chn_t chn)
  261. {
  262. return (int32_t)clc->VDVQ_CHAN[chn].EADC_PRE1;
  263. }
  264. /**
  265. * @brief CLC software inject error adc previous1 value
  266. * @param[in] clc CLC base address
  267. * @param[in] chn CLC channel, @ref clc_chn_t
  268. * @param[in] value CLC error adc previous1 value
  269. */
  270. static inline void clc_sw_inject_eadc_previous1_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
  271. {
  272. clc->VDVQ_CHAN[chn].EADC_PRE1 = (uint32_t)value;
  273. }
  274. /**
  275. * @brief CLC get 2p2z last value
  276. * @param[in] clc CLC base address
  277. * @param[in] chn CLC channel, @ref clc_chn_t
  278. * @retval CLC 2p2z last value
  279. */
  280. static inline int32_t clc_get_2p2z_current_value(CLC_Type *clc, clc_chn_t chn)
  281. {
  282. return (int32_t)clc->VDVQ_CHAN[chn].P2Z2_CURR;
  283. }
  284. /**
  285. * @brief CLC software inject 2p2z last value
  286. * @param[in] clc CLC base address
  287. * @param[in] chn CLC channel, @ref clc_chn_t
  288. * @param[in] value CLC 2p2z last value
  289. */
  290. static inline void clc_sw_inject_2p2z_current_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
  291. {
  292. clc->VDVQ_CHAN[chn].P2Z2_CURR = (uint32_t)value;
  293. }
  294. /**
  295. * @brief CLC get 2p2z previous0 value
  296. * @param[in] clc CLC base address
  297. * @param[in] chn CLC channel, @ref clc_chn_t
  298. * @retval CLC 2p2z previous0 value
  299. */
  300. static inline int32_t clc_get_2p2z_previous0_value(CLC_Type *clc, clc_chn_t chn)
  301. {
  302. return (int32_t)clc->VDVQ_CHAN[chn].P2Z2_PRE0;
  303. }
  304. /**
  305. * @brief CLC software inject 2p2z previous0 value
  306. * @param[in] clc CLC base address
  307. * @param[in] chn CLC channel, @ref clc_chn_t
  308. * @param[in] value CLC 2p2z previous0 value
  309. */
  310. static inline void clc_sw_inject_2p2z_previous0_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
  311. {
  312. clc->VDVQ_CHAN[chn].P2Z2_PRE0 = (uint32_t)value;
  313. }
  314. /**
  315. * @brief CLC get 3p3z last value
  316. * @param[in] clc CLC base address
  317. * @param[in] chn CLC channel, @ref clc_chn_t
  318. * @retval CLC 3p3z last value
  319. */
  320. static inline int32_t clc_get_3p3z_current_value(CLC_Type *clc, clc_chn_t chn)
  321. {
  322. return (int32_t)clc->VDVQ_CHAN[chn].P3Z3_CURR;
  323. }
  324. /**
  325. * @brief CLC software inject 3p3z last value
  326. * @param[in] clc CLC base address
  327. * @param[in] chn CLC channel, @ref clc_chn_t
  328. * @param[in] value CLC 3p3z last value
  329. */
  330. static inline void clc_sw_inject_3p3z_current_value(CLC_Type *clc, clc_chn_t chn, int32_t value)
  331. {
  332. clc->VDVQ_CHAN[chn].P3Z3_CURR = (uint32_t)value;
  333. }
  334. /**
  335. * @brief CLC set expected adc value
  336. * @param[in] clc CLC base address
  337. * @param[in] chn CLC channel, @ref clc_chn_t
  338. * @param[in] expect expected adc value
  339. */
  340. static inline void clc_set_expect_adc_value(CLC_Type *clc, clc_chn_t chn, int32_t expect)
  341. {
  342. clc->VDVQ_CHAN[chn].ADC_EXPECT = (uint32_t)expect;
  343. }
  344. /**
  345. * @brief CLC software inject adc value. If it's not dq mode, this will trig clc calculation.
  346. * @param[in] clc CLC base address
  347. * @param[in] chn CLC channel, @ref clc_chn_t
  348. * @param[in] value CLC adc value
  349. */
  350. static inline void clc_sw_inject_adc_value(CLC_Type *clc, clc_chn_t chn, uint32_t value)
  351. {
  352. clc->VDVQ_CHAN[chn].ADC_SW = value;
  353. }
  354. /**
  355. * @brief CLC set software inject dq adc value ready, this will trig clc calculation.
  356. * @param[in] clc CLC base address
  357. */
  358. static inline void clc_set_sw_inject_dq_adc_value_ready(CLC_Type *clc)
  359. {
  360. clc->DQ_ADC_SW_READY = CLC_DQ_ADC_SW_READY_DQ_ADC_SW_READY_MASK;
  361. }
  362. /**
  363. * @brief CLC parameter configuration
  364. * @param[in] clc CLC base address
  365. * @param[in] chn CLC channel, @ref clc_chn_t
  366. * @param[in] param @ref clc_param_config_t.
  367. */
  368. void clc_config_param(CLC_Type *clc, clc_chn_t chn, clc_param_config_t *param);
  369. /**
  370. * @brief CLC coefficient configuration
  371. * @param[in] clc CLC base address
  372. * @param[in] chn CLC channel, @ref clc_chn_t
  373. * @param[in] zone CLC coefficient zone, @ref clc_coeff_zone_t
  374. * @param[in] coeff @ref clc_param_config_t.
  375. *
  376. * @retval status_invalid_argument some parameters are invalid
  377. * @retval status_success operation is successful
  378. */
  379. hpm_stat_t clc_config_coeff(CLC_Type *clc, clc_chn_t chn, clc_coeff_zone_t zone, clc_coeff_config_t *coeff);
  380. /**
  381. * @brief CLC software inject dq adc value
  382. * @param[in] clc CLC base address
  383. * @param[in] d_value CLC d adc value
  384. * @param[in] q_value CLC q adc value
  385. */
  386. void clc_sw_inject_dq_adc_value(CLC_Type *clc, uint32_t d_value, uint32_t q_value);
  387. #ifdef __cplusplus
  388. }
  389. #endif
  390. /**
  391. * @}
  392. */
  393. #endif /* HPM_CLC_DRV_H */