hpm_qeo_drv.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /*
  2. * Copyright (c) 2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_QEO_DRV_H
  8. #define HPM_QEO_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_qeo_regs.h"
  11. /**
  12. * @brief QEO driver APIs
  13. * @defgroup qeo_interface QEO driver APIs
  14. * @ingroup qeo_interfaces
  15. * @{
  16. */
  17. typedef enum {
  18. qeo_wave_cosine = 0,
  19. qeo_wave_saddle = 1,
  20. qeo_wave_abs_cosine = 2,
  21. qeo_wave_saw = 3,
  22. } qeo_wave_type_t;
  23. typedef enum {
  24. qeo_wave_above_max_limit_max_val = 0,
  25. qeo_wave_above_max_limit_zero = 1,
  26. qeo_wave_above_max_limit_max_level0_val = 2,
  27. qeo_wave_high_area_limit_max_val = 0,
  28. qeo_wave_high_area_limit_max_level0_val = 1,
  29. qeo_wave_low_area_limit_zero = 0,
  30. qeo_wave_low_area_limit_min_level1_val = 1,
  31. qeo_wave_below_min_limit_zero = 0,
  32. qeo_wave_below_min_limit_max_val = 1,
  33. qeo_wave_below_min_limit_min_level1_val = 2,
  34. } qeo_wave_limit_t;
  35. typedef struct {
  36. uint8_t above_max_limit;
  37. uint8_t high_area0_limit;
  38. uint8_t high_area1_limit;
  39. uint8_t low_area0_limit;
  40. uint8_t low_area1_limit;
  41. uint8_t below_min_limit;
  42. } qeo_wave_limit_config_t;
  43. typedef struct {
  44. qeo_wave_limit_config_t wave0;
  45. qeo_wave_limit_config_t wave1;
  46. qeo_wave_limit_config_t wave2;
  47. uint8_t wave_type;
  48. uint8_t saddle_type;
  49. } qeo_wave_mode_t;
  50. typedef enum {
  51. qeo_abz_output_abz = 0, /*< A and B are orthogonal signals, Z is zero pulse */
  52. qeo_abz_output_pulse_revise = 1, /*< A is speed pulse, B is directional pulse, Z not used */
  53. qeo_abz_output_up_down = 2, /*< A is forward pulse, B is reverse pusle, Z not used */
  54. qeo_abz_output_three_phase = 3, /*< A/B/Z are 3-phase orthogonal pulse */
  55. } qeo_abz_type_t;
  56. /* take effect when output type is qeo_abz_output_abz */
  57. typedef enum {
  58. qeo_z_pulse_25_percent = 0,
  59. qeo_z_pulse_75_percent = 1,
  60. qeo_z_pulse_100_percent = 2,
  61. } qeo_z_pulse_period_t;
  62. typedef struct {
  63. bool z_inv_pol;
  64. bool b_inv_pol;
  65. bool a_inv_pol;
  66. uint8_t output_type; /*!< @ref qeo_abz_type_t */
  67. uint8_t z_pulse_period; /*!< @ref qeo_z_pulse_period_t */
  68. } qeo_abz_mode_t;
  69. typedef enum {
  70. qeo_pwm_output_force_0 = 2,
  71. qeo_pwm_output_force_1 = 3,
  72. qeo_pwm_output_not_force = 0,
  73. } qeo_pwm_force_output_t;
  74. typedef enum {
  75. qeo_pwm_safety_output_0 = 0,
  76. qeo_pwm_safety_output_1 = 1,
  77. qeo_pwm_safety_output_highz = 2,
  78. } qeo_pwm_safety_output_t;
  79. typedef struct {
  80. uint8_t pwm0_output; /*!< @ref qeo_pwm_force_output_t */
  81. uint8_t pwm1_output;
  82. uint8_t pwm2_output;
  83. uint8_t pwm3_output;
  84. uint8_t pwm4_output;
  85. uint8_t pwm5_output;
  86. uint8_t pwm6_output;
  87. uint8_t pwm7_output;
  88. } qeo_pwm_phase_output_table_t;
  89. typedef struct {
  90. uint8_t pwm0_output; /*!< @ref qeo_pwm_safety_output_t */
  91. uint8_t pwm1_output;
  92. uint8_t pwm2_output;
  93. uint8_t pwm3_output;
  94. uint8_t pwm4_output;
  95. uint8_t pwm5_output;
  96. uint8_t pwm6_output;
  97. uint8_t pwm7_output;
  98. } qeo_pwm_safety_output_table_t;
  99. typedef struct {
  100. uint8_t phase_num;
  101. bool shield_hardware_trig_safety;
  102. bool revise_pairs_output;
  103. } qeo_pwm_mode_t;
  104. #ifdef __cplusplus
  105. extern "C" {
  106. #endif
  107. /* WAVE API */
  108. /**
  109. * @brief QEO set resolution lines for wave mode
  110. * @param [in] base QEO base address
  111. * @param [in] lines resolution lines
  112. */
  113. static inline void qeo_wave_set_resolution_lines(QEO_Type *base, uint32_t lines)
  114. {
  115. base->WAVE.RESOLUTION = QEO_WAVE_RESOLUTION_LINES_SET(lines);
  116. }
  117. /**
  118. * @brief QEO set output type for wave mode
  119. * @param [in] base QEO base address
  120. * @param [in] type qeo_wave_type_t
  121. */
  122. static inline void qeo_wave_set_output_type(QEO_Type *base, qeo_wave_type_t type)
  123. {
  124. base->WAVE.MODE = (base->WAVE.MODE & ~QEO_WAVE_MODE_WAVES_OUTPUT_TYPE_MASK) | QEO_WAVE_MODE_WAVES_OUTPUT_TYPE_SET(type);
  125. }
  126. /**
  127. * @brief QEO set saddle type for wave mode
  128. * @param [in] base QEO base address
  129. * @param [in] standard true for standard saddle, false for triangular wave stacking
  130. */
  131. static inline void qeo_wave_set_saddle_type(QEO_Type *base, bool standard)
  132. {
  133. if (standard) {
  134. base->WAVE.MODE &= ~QEO_WAVE_MODE_SADDLE_TYPE_MASK;
  135. } else {
  136. base->WAVE.MODE |= QEO_WAVE_MODE_SADDLE_TYPE_MASK;
  137. }
  138. }
  139. /**
  140. * @brief QEO set phase shift for wave mode
  141. * @param [in] base QEO base address
  142. * @param [in] index wave index(0/1/2)
  143. * @param [in] angle left shift angle
  144. */
  145. static inline void qeo_wave_set_phase_shift(QEO_Type *base, uint8_t index, double angle)
  146. {
  147. assert((angle >= 0) && (angle <= 360));
  148. uint32_t val = (uint32_t)(angle * 0x10000U / 360);
  149. base->WAVE.PHASE_SHIFT[index] = QEO_WAVE_PHASE_SHIFT_VAL_SET(val);
  150. }
  151. /**
  152. * @brief QEO enable vd vq inject for wave mode
  153. * @param [in] base QEO base address
  154. * @param [in] index wave index(0/1/2)
  155. * @param [in] vd_val vd value
  156. * @param [in] vq_val vq value
  157. */
  158. static inline void qeo_wave_enable_vd_vq_inject(QEO_Type *base, uint8_t index, int32_t vd_val, int32_t vq_val)
  159. {
  160. (void) vd_val;
  161. assert(index < 3);
  162. base->WAVE.MODE |= (1U << (QEO_WAVE_MODE_EN_WAVE0_VD_VQ_INJECT_SHIFT + index));
  163. base->WAVE.VD_VQ_INJECT[index] = QEO_WAVE_VD_VQ_INJECT_VQ_VAL_SET(vq_val) | QEO_WAVE_VD_VQ_INJECT_VD_VAL_SET(vq_val);
  164. }
  165. /**
  166. * @brief QEO disable vd vq inject for wave mode
  167. * @param [in] base QEO base address
  168. * @param [in] index wave index(0/1/2)
  169. */
  170. static inline void qeo_wave_disable_vd_vq_inject(QEO_Type *base, uint8_t index)
  171. {
  172. assert(index < 3);
  173. base->WAVE.MODE &= ~(1U << (QEO_WAVE_MODE_EN_WAVE0_VD_VQ_INJECT_SHIFT + index));
  174. }
  175. /**
  176. * @brief QEO load vd vq inject value for wave mode
  177. * @param [in] base QEO base address
  178. */
  179. static inline void qeo_wave_load_vd_vq(QEO_Type *base)
  180. {
  181. base->WAVE.VD_VQ_LOAD = QEO_WAVE_VD_VQ_LOAD_LOAD_MASK;
  182. }
  183. /**
  184. * @brief QEO enable amplitude for wave mode
  185. * @param [in] base QEO base address
  186. * @param [in] index wave index(0/1/2)
  187. * @param [in] amp amplitude value
  188. */
  189. static inline void qeo_wave_enable_amplitude(QEO_Type *base, uint8_t index, double amp)
  190. {
  191. assert(amp > 0);
  192. uint32_t val = (uint32_t)(amp * (1U << 12U));
  193. base->WAVE.AMPLITUDE[index] = QEO_WAVE_AMPLITUDE_EN_SCAL_MASK | QEO_WAVE_AMPLITUDE_AMP_VAL_SET(val);
  194. }
  195. /**
  196. * @brief QEO disable amplitude for wave mode
  197. * @param [in] base QEO base address
  198. * @param [in] index wave index(0/1/2)
  199. */
  200. static inline void qeo_wave_disable_amplitude(QEO_Type *base, uint8_t index)
  201. {
  202. base->WAVE.AMPLITUDE[index] &= ~QEO_WAVE_AMPLITUDE_EN_SCAL_MASK;
  203. }
  204. /**
  205. * @brief QEO set mid point shift for wave mode
  206. * @param [in] base QEO base address
  207. * @param [in] index wave index(0/1/2)
  208. * @param [in] shift mid point shift value
  209. */
  210. static inline void qeo_wave_set_mid_point_shift(QEO_Type *base, uint8_t index, double shift)
  211. {
  212. int32_t val = (int32_t)(shift * (1U << 27U));
  213. base->WAVE.MID_POINT[index] = QEO_WAVE_MID_POINT_VAL_SET(val);
  214. }
  215. /**
  216. * @brief QEO set max limmit for wave mode
  217. * @param [in] base QEO base address
  218. * @param [in] index wave index(0/1/2)
  219. * @param [in] limit0 limit0 value
  220. * @param [in] limit1 limit1 value
  221. */
  222. static inline void qeo_wave_set_max_limit(QEO_Type *base, uint8_t index, uint32_t limit0, uint32_t limit1)
  223. {
  224. base->WAVE.LIMIT[index].MAX = QEO_WAVE_LIMIT_MAX_LIMIT0_SET(limit0) | QEO_WAVE_LIMIT_MAX_LIMIT1_SET(limit1);
  225. }
  226. /**
  227. * @brief QEO set min limmit for wave mode
  228. * @param [in] base QEO base address
  229. * @param [in] index wave index(0/1/2)
  230. * @param [in] limit0 limit0 value
  231. * @param [in] limit1 limit1 value
  232. */
  233. static inline void qeo_wave_set_min_limit(QEO_Type *base, uint8_t index, uint32_t limit0, uint32_t limit1)
  234. {
  235. base->WAVE.LIMIT[index].MIN = QEO_WAVE_LIMIT_MIN_LIMIT0_SET(limit0) | QEO_WAVE_LIMIT_MIN_LIMIT1_SET(limit1);
  236. }
  237. /**
  238. * @brief QEO set deadzone shift for wave mode
  239. * @param [in] base QEO base address
  240. * @param [in] index wave index(0/1/2)
  241. * @param [in] shift deadzone shift value
  242. */
  243. static inline void qeo_wave_set_deadzone_shift(QEO_Type *base, uint8_t index, int16_t shift)
  244. {
  245. base->WAVE.DEADZONE_SHIFT[index] = QEO_WAVE_DEADZONE_SHIFT_VAL_SET(shift);
  246. }
  247. /**
  248. * @brief QEO get wave output value
  249. * @param [in] base QEO base address
  250. * @param [in] index wave index(0/1/2)
  251. * @retval wave output value
  252. */
  253. static inline uint16_t qeo_get_wave_output_val(QEO_Type *base, uint8_t index)
  254. {
  255. if (index == 0) {
  256. return QEO_DEBUG0_WAVE0_GET(base->DEBUG0);
  257. } else if (index == 1) {
  258. return QEO_DEBUG0_WAVE1_GET(base->DEBUG0);
  259. } else if (index == 2) {
  260. return QEO_DEBUG1_WAVE2_GET(base->DEBUG1);
  261. }
  262. return 0;
  263. }
  264. /**
  265. * @brief QEO wave get defalut mode config
  266. * @param [in] base QEO base address
  267. * @param [in] config qeo_wave_mode_t
  268. */
  269. void qeo_wave_get_default_mode_config(QEO_Type *base, qeo_wave_mode_t *config);
  270. /**
  271. * @brief QEO wave config mode
  272. * @param [in] base QEO base address
  273. * @param [in] config qeo_wave_mode_t
  274. */
  275. void qeo_wave_config_mode(QEO_Type *base, qeo_wave_mode_t *config);
  276. /* ABZ API */
  277. /**
  278. * @brief QEO set resolution lines for ABZ mode
  279. * @param [in] base QEO base address
  280. * @param [in] lines resolution lines
  281. */
  282. static inline void qeo_abz_set_resolution_lines(QEO_Type *base, uint32_t lines)
  283. {
  284. base->ABZ.RESOLUTION = QEO_ABZ_RESOLUTION_LINES_SET(lines);
  285. }
  286. /**
  287. * @brief QEO set phase shift for ABZ mode
  288. * @param [in] base QEO base address
  289. * @param [in] index ABZ index(0/1/2)
  290. * @param [in] angle left shift angle
  291. */
  292. static inline void qeo_abz_set_phase_shift(QEO_Type *base, uint8_t index, double angle)
  293. {
  294. assert((angle >= 0) && (angle <= 360));
  295. uint32_t val = (uint32_t)(angle * 0x10000U / 360);
  296. base->ABZ.PHASE_SHIFT[index] = QEO_ABZ_PHASE_SHIFT_VAL_SET(val);
  297. }
  298. /**
  299. * @brief QEO set max frequency for ABZ mode
  300. * @param [in] base QEO base address
  301. * @param [in] src_freq QEO(MOTO system) frequency
  302. * @param [in] freq abz signal frequency (A pulse frequency)
  303. * @retval status_success or status_invalid_argument
  304. */
  305. hpm_stat_t qeo_abz_set_max_frequency(QEO_Type *base, uint32_t src_freq, uint32_t freq);
  306. /**
  307. * @brief QEO set wdog frequency for ABZ mode
  308. * @param [in] base QEO base address
  309. * @param [in] src_freq QEO(MOTO system) frequency
  310. * @param [in] freq wdog frequency
  311. * @retval status_success or status_invalid_argument
  312. */
  313. hpm_stat_t qeo_abz_set_wdog_frequency(QEO_Type *base, uint32_t src_freq, uint32_t freq);
  314. /**
  315. * @brief QEO disable wdog for ABZ mode
  316. * @param [in] base QEO base address
  317. */
  318. static inline void qeo_abz_disable_wdog(QEO_Type *base)
  319. {
  320. base->ABZ.MODE &= ~QEO_ABZ_MODE_EN_WDOG_MASK;
  321. }
  322. /**
  323. * @brief QEO config reverse edge for ABZ mode
  324. * @param [in] base QEO base address
  325. * @param [in] speed_pulse_negedge true for reverse edge point speed pulse's negedge
  326. * false for reverse edge point between speed pulse's posedge and negedge, min period dedicated by the num line_width
  327. *
  328. * @note take effect when ABZ work on qeo_abz_output_pulse_revise mode
  329. */
  330. static inline void qeo_abz_config_reverse_edge(QEO_Type *base, bool speed_pulse_negedge)
  331. {
  332. if (speed_pulse_negedge) {
  333. base->ABZ.MODE |= QEO_ABZ_MODE_REVERSE_EDGE_TYPE_MASK;
  334. } else {
  335. base->ABZ.MODE &= ~QEO_ABZ_MODE_REVERSE_EDGE_TYPE_MASK;
  336. }
  337. }
  338. /**
  339. * @brief QEO sync position for ABZ mode
  340. * @param [in] base QEO base address
  341. * @param [in] lines ABZ line counter
  342. * @param [in] sync_pos the position value to be synchronized
  343. */
  344. void qeo_abz_position_sync(QEO_Type *base, uint32_t lines, uint32_t sync_pos);
  345. /**
  346. * @brief QEO ABZ get default mode config
  347. * @param [in] base QEO base address
  348. * @param [in] config qeo_abz_mode_t
  349. */
  350. void qeo_abz_get_default_mode_config(QEO_Type *base, qeo_abz_mode_t *config);
  351. /**
  352. * @brief QEO ABZ config mode
  353. * @param [in] base QEO base address
  354. * @param [in] config qeo_abz_mode_t
  355. */
  356. void qeo_abz_config_mode(QEO_Type *base, qeo_abz_mode_t *config);
  357. /* PWM API */
  358. /**
  359. * @brief QEO set resolution lines for PWM mode
  360. * @param [in] base QEO base address
  361. * @param [in] lines resolution lines
  362. */
  363. static inline void qeo_pwm_set_resolution_lines(QEO_Type *base, uint32_t lines)
  364. {
  365. base->PWM.RESOLUTION = QEO_PWM_RESOLUTION_LINES_SET(lines);
  366. }
  367. /**
  368. * @brief QEO set phase shift for PWM mode
  369. * @param [in] base QEO base address
  370. * @param [in] index PWM index(0/1/2/3)
  371. * @param [in] angle left shift angle
  372. */
  373. static inline void qeo_pwm_set_phase_shift(QEO_Type *base, uint8_t index, double angle)
  374. {
  375. assert((angle >= 0) && (angle <= 360));
  376. uint32_t val = (uint32_t)(angle * 0x10000U / 360);
  377. base->PWM.PHASE_SHIFT[index] = QEO_PWM_PHASE_SHIFT_VAL_SET(val);
  378. }
  379. /**
  380. * @brief QEO PWM check if it is triggered by hardware to enter safety mode
  381. *
  382. * @note This bit is only valid if the hardware trigger source has not been cleared
  383. *
  384. * @param [in] base QEO base address
  385. * @retval true or false
  386. */
  387. static inline bool qeo_pwm_check_hardware_trig_safety(QEO_Type *base)
  388. {
  389. return ((base->STATUS & QEO_STATUS_PWM_SAFETY_MASK) != 0) ? true : false;
  390. }
  391. /**
  392. * @brief QEO PWM select phase table
  393. * @param [in] base QEO base address
  394. * @param [in] positive true for using positive phase table, false for using negative phase table
  395. */
  396. static inline void qeo_pwm_select_phase_table(QEO_Type *base, bool positive)
  397. {
  398. if (positive) {
  399. base->PWM.MODE &= ~QEO_PWM_MODE_REVISE_UP_DN_MASK;
  400. } else {
  401. base->PWM.MODE |= QEO_PWM_MODE_REVISE_UP_DN_MASK;
  402. }
  403. }
  404. /**
  405. * @brief QEO PWM enter safety mode by software
  406. *
  407. * @note call qeo_pwm_software_exit_safety to exit safety mode
  408. *
  409. * @param [in] base QEO base address
  410. */
  411. static inline void qeo_pwm_software_enter_safety(QEO_Type *base)
  412. {
  413. base->PWM.MODE |= QEO_PWM_MODE_PWM_ENTER_SAFETY_MODE_MASK;
  414. }
  415. /**
  416. * @brief QEO PWM exit safety mode by software
  417. * @param [in] base QEO base address
  418. */
  419. static inline void qeo_pwm_software_exit_safety(QEO_Type *base)
  420. {
  421. base->PWM.MODE &= ~QEO_PWM_MODE_PWM_ENTER_SAFETY_MODE_MASK;
  422. }
  423. /**
  424. * @brief QEO PWM get default mode config
  425. * @param [in] base QEO base address
  426. * @param [in] config qeo_pwm_mode_t
  427. */
  428. void qeo_pwm_get_default_mode_config(QEO_Type *base, qeo_pwm_mode_t *config);
  429. /**
  430. * @brief QEO PWM config mode
  431. * @param [in] base QEO base address
  432. * @param [in] config qeo_pwm_mode_t
  433. */
  434. void qeo_pwm_config_mode(QEO_Type *base, qeo_pwm_mode_t *config);
  435. /**
  436. * @brief QEO PWM get default safety table
  437. * @param [in] base QEO base address
  438. * @param [in] table qeo_pwm_safety_output_table_t
  439. */
  440. void qeo_pwm_get_default_safety_table_config(QEO_Type *base, qeo_pwm_safety_output_table_t *table);
  441. /**
  442. * @brief QEO PWM get default phase table
  443. * @param [in] base QEO base address
  444. * @param [in] table qeo_pwm_phase_output_table_t
  445. */
  446. void qeo_pwm_get_default_phase_table_config(QEO_Type *base, qeo_pwm_phase_output_table_t *table);
  447. /**
  448. * @brief QEO PWM config safety table
  449. * @param [in] base QEO base address
  450. * @param [in] table qeo_pwm_safety_output_table_t
  451. */
  452. void qeo_pwm_config_safety_table(QEO_Type *base, qeo_pwm_safety_output_table_t *table);
  453. /**
  454. * @brief QEO PWM onfig phase table
  455. * @param [in] base QEO base address
  456. * @param [in] index phase table index
  457. * @param [in] table qeo_pwm_phase_output_table_t
  458. */
  459. void qeo_pwm_config_phase_table(QEO_Type *base, uint8_t index, qeo_pwm_phase_output_table_t *table);
  460. /**
  461. * @brief QEO enable software position inject
  462. * @param [in] base QEO base address
  463. */
  464. static inline void qeo_enable_software_position_inject(QEO_Type *base)
  465. {
  466. base->POSTION_SEL |= QEO_POSTION_SEL_POSTION_SEL_MASK;
  467. }
  468. /**
  469. * @brief QEO software inject position
  470. * @param [in] base QEO base address
  471. * @param [in] position position value
  472. */
  473. static inline void qeo_software_position_inject(QEO_Type *base, uint32_t position)
  474. {
  475. base->POSTION_SOFTWARE = QEO_POSTION_SOFTWARE_POSTION_SOFTWAVE_SET(position);
  476. }
  477. /**
  478. * @brief QEO disable software position inject, QEO will using position from hardware
  479. * @param [in] base QEO base address
  480. */
  481. static inline void qeo_disable_software_position_inject(QEO_Type *base)
  482. {
  483. base->POSTION_SEL &= ~QEO_POSTION_SEL_POSTION_SEL_MASK;
  484. }
  485. /**
  486. * @brief QEO check calculate finish status
  487. * @param [in] base QEO base address
  488. * @retval true or false
  489. */
  490. static inline bool qeo_check_calculate_finish(QEO_Type *base)
  491. {
  492. return (QEO_DEBUG1_QEO_FINISH_GET(base->DEBUG1) != 0) ? true : false;
  493. }
  494. #ifdef __cplusplus
  495. }
  496. #endif
  497. /**
  498. * @}
  499. */
  500. #endif /* HPM_QEO_DRV_H */