hpm_qei_drv.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /*
  2. * Copyright (c) 2021 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_QEI_DRV_H
  8. #define HPM_QEI_DRV_H
  9. #include "hpm_common.h"
  10. #include "hpm_qei_regs.h"
  11. /**
  12. * @brief QEI driver APIs
  13. * @defgroup qei_interface QEI driver APIs
  14. * @ingroup io_interfaces
  15. * @{
  16. *
  17. */
  18. #define QEI_EVENT_WDOG_FLAG_MASK (1U << 31) /**< watchdog flag */
  19. #define QEI_EVENT_HOME_FLAG_MASK (1U << 30) /**< home flag */
  20. #define QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK (1U << 29) /**< postion compare match flag */
  21. #define QEI_EVENT_Z_PHASE_FLAG_MASK (1U << 28) /**< z input flag */
  22. /**
  23. * @brief counting mode of Z-phase counter
  24. *
  25. */
  26. typedef enum qei_z_count_inc_mode {
  27. qei_z_count_inc_on_z_input_assert = 0, /**< zcnt will increment or decrement when Z input assert */
  28. qei_z_count_inc_on_phase_count_max = 1, /**< zcnt will increment when phcnt upcount to phmax, decrement when phcnt downcount to 0 */
  29. } qei_z_count_inc_mode_t;
  30. /**
  31. * @brief motor rotation direction
  32. *
  33. */
  34. typedef enum qei_rotation_dir_cmp {
  35. qei_rotation_dir_cmp_positive = 0, /**< position compare need positive rotation */
  36. qei_rotation_dir_cmp_negative = 1, /**< position compare need negative rotation */
  37. qei_rotation_dir_cmp_ignore = 2, /**< ignore */
  38. } qei_rotation_dir_cmp_t;
  39. /**
  40. * @brief counter type
  41. *
  42. */
  43. typedef enum qei_counter_type {
  44. qei_counter_type_z = 0, /**< Z counter */
  45. qei_counter_type_phase = 1, /**< Phase counter */
  46. qei_counter_type_speed = 2, /**< Speed counter */
  47. qei_counter_type_timer = 3, /**< Timer counter */
  48. } qei_counter_type_t;
  49. /**
  50. * @brief qei work mode
  51. *
  52. */
  53. typedef enum qei_work_mode {
  54. qei_work_mode_abz = 0, /**< Orthogonal decoder mode */
  55. qei_work_mode_pd = 1, /**< Directional (PD) mode */
  56. qei_work_mode_ud = 2, /**< Up and Down (UD) mode */
  57. } qei_work_mode_t;
  58. #ifdef __cplusplus
  59. extern "C" {
  60. #endif
  61. /**
  62. * @brief enable qei watchdog
  63. *
  64. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  65. */
  66. static inline void qei_wdog_enable(QEI_Type *qei_x)
  67. {
  68. qei_x->WDGCFG |= QEI_WDGCFG_WDGEN_MASK;
  69. }
  70. /**
  71. * @brief disable qei watchdog
  72. *
  73. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  74. */
  75. static inline void qei_wdog_disable(QEI_Type *qei_x)
  76. {
  77. qei_x->WDGCFG &= ~QEI_WDGCFG_WDGEN_MASK;
  78. }
  79. /**
  80. * @brief config watchdog
  81. *
  82. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  83. * @param[in] timeout watchdog timeout time
  84. * @param[in] enable
  85. * @arg 1 - enable watchdog, You can use the @ref qei_wdog_disable open watchdog
  86. * @arg 0 - disable watchdog, You can use the @ref qei_wdog_enable open watchdog
  87. */
  88. static inline void qei_wdog_config(QEI_Type *qei_x, uint32_t timeout, bool enable)
  89. {
  90. qei_x->WDGCFG = QEI_WDGCFG_WDGTO_SET(timeout) | QEI_WDGCFG_WDGEN_SET(enable);
  91. }
  92. /**
  93. * @brief
  94. *
  95. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  96. * @param[in] phase_count maximum phcnt number, phcnt will rollover to 0 when it upcount to phmax
  97. * @param[in] mode
  98. * @arg 1 zcnt will increment when phcnt upcount to phmax, decrement when phcnt downcount to 0
  99. * @arg 0 zcnt will increment or decrement when Z input assert
  100. * @param[in] z_calibrate 1- phcnt will set to phidx when Z input assert
  101. */
  102. static inline void qei_phase_config(QEI_Type *qei_x, uint32_t phase_count,
  103. qei_z_count_inc_mode_t mode, bool z_calibrate)
  104. {
  105. qei_x->PHCFG = QEI_PHCFG_ZCNTCFG_SET(mode) | QEI_PHCFG_PHCALIZ_SET(z_calibrate)
  106. | QEI_PHCFG_PHMAX_SET(phase_count - 1);
  107. }
  108. /**
  109. * @brief set phase index
  110. *
  111. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  112. * @param[in] phase_index phcnt reset value, phcnt will reset to phidx when phcaliz set to 1
  113. */
  114. static inline void qei_phase_set_index(QEI_Type *qei_x, uint32_t phase_index)
  115. {
  116. qei_x->PHIDX = QEI_PHIDX_PHIDX_SET(phase_index);
  117. }
  118. /**
  119. * @brief enable trigger event
  120. *
  121. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  122. * @param[in] event_mask
  123. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  124. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  125. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  126. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  127. */
  128. static inline void qei_output_trigger_event_enable(QEI_Type *qei_x, uint32_t event_mask)
  129. {
  130. qei_x->TRGOEN |= event_mask;
  131. }
  132. /**
  133. * @brief disable trigger event
  134. *
  135. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  136. * @param[in] event_mask
  137. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  138. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  139. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  140. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  141. */
  142. static inline void qei_output_trigger_event_disable(QEI_Type *qei_x, uint32_t event_mask)
  143. {
  144. qei_x->TRGOEN &= ~event_mask;
  145. }
  146. /**
  147. * @brief enable load read trigger event
  148. *
  149. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  150. * @param[in] event_mask
  151. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  152. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  153. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  154. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  155. */
  156. static inline void qei_load_read_trigger_event_enable(QEI_Type *qei_x, uint32_t event_mask)
  157. {
  158. qei_x->READEN |= event_mask;
  159. }
  160. /**
  161. * @brief disable load read trigger event
  162. *
  163. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  164. * @param[in] event_mask
  165. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  166. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  167. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  168. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  169. */
  170. static inline void qei_load_read_trigger_event_disable(QEI_Type *qei_x, uint32_t event_mask)
  171. {
  172. qei_x->READEN &= ~event_mask;
  173. }
  174. /**
  175. * @brief set zcnt postion compare value
  176. *
  177. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  178. * @param[in] cmp zcnt postion compare value
  179. */
  180. static inline void qei_z_cmp_set(QEI_Type *qei_x, uint32_t cmp)
  181. {
  182. qei_x->ZCMP = QEI_ZCMP_ZCMP_SET(cmp);
  183. }
  184. /**
  185. * @brief set spdcnt position compare value
  186. *
  187. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  188. * @param[in] cmp spdcnt position compare value
  189. */
  190. static inline void qei_speed_cmp_set(QEI_Type *qei_x, uint32_t cmp)
  191. {
  192. qei_x->SPDCMP = QEI_SPDCMP_SPDCMP_SET(cmp);
  193. }
  194. /**
  195. * @brief set Phase comparator value
  196. *
  197. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  198. * @param[in] cmp phcnt position compare value
  199. * @param[in] cmp_z 1- postion compare not include zcnt
  200. * @param[in] rotation_dir @ref qei_rotation_dir_cmp_t
  201. */
  202. static inline void qei_phase_cmp_set(QEI_Type *qei_x, uint32_t cmp,
  203. bool cmp_z, qei_rotation_dir_cmp_t rotation_dir)
  204. {
  205. qei_x->PHCMP = QEI_PHCMP_PHCMP_SET(cmp)
  206. | QEI_PHCMP_ZCMPDIS_SET(!cmp_z)
  207. | ((rotation_dir == qei_rotation_dir_cmp_ignore)
  208. ? QEI_PHCMP_DIRCMPDIS_MASK : (QEI_PHCMP_DIRCMP_SET(rotation_dir)));
  209. }
  210. /**
  211. * @brief clear qei status register
  212. *
  213. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  214. * @param[in] mask
  215. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  216. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  217. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  218. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  219. */
  220. static inline void qei_clear_status(QEI_Type *qei_x, uint32_t mask)
  221. {
  222. qei_x->SR = mask;
  223. }
  224. /**
  225. * @brief get qei status
  226. *
  227. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  228. * @retval qei status:
  229. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  230. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  231. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  232. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  233. */
  234. static inline uint32_t qei_get_status(QEI_Type *qei_x)
  235. {
  236. return qei_x->SR;
  237. }
  238. /**
  239. * @brief get qei bit status
  240. *
  241. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  242. * @param[in] mask
  243. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  244. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  245. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  246. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  247. * @retval true or false
  248. */
  249. static inline bool qei_get_bit_status(QEI_Type *qei_x, uint32_t mask)
  250. {
  251. if ((qei_x->SR & mask) == mask) {
  252. return true;
  253. }
  254. else{
  255. return false;
  256. }
  257. }
  258. /**
  259. * @brief enable qei irq
  260. *
  261. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  262. * @param[in] mask
  263. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  264. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  265. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  266. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  267. */
  268. static inline void qei_irq_enable(QEI_Type *qei_x, uint32_t mask)
  269. {
  270. qei_x->IRQEN |= mask;
  271. }
  272. /**
  273. * @brief disable qei irq
  274. *
  275. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  276. * @param[in] mask
  277. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  278. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  279. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  280. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  281. */
  282. static inline void qei_irq_disable(QEI_Type *qei_x, uint32_t mask)
  283. {
  284. qei_x->IRQEN &= ~mask;
  285. }
  286. /**
  287. * @brief enable dma request
  288. *
  289. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  290. * @param[in] mask
  291. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  292. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  293. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  294. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  295. */
  296. static inline void qei_dma_request_enable(QEI_Type *qei_x, uint32_t mask)
  297. {
  298. qei_x->DMAEN |= mask;
  299. }
  300. /**
  301. * @brief disable qei dma
  302. *
  303. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  304. * @param[in] mask
  305. * @arg @ref QEI_EVENT_WDOG_FLAG_MASK
  306. * @arg @ref QEI_EVENT_HOME_FLAG_MASK
  307. * @arg @ref QEI_EVENT_POSITIVE_COMPARE_FLAG_MASK
  308. * @arg @ref QEI_EVENT_Z_PHASE_FLAG_MASK
  309. */
  310. static inline void qei_dma_request_disable(QEI_Type *qei_x, uint32_t mask)
  311. {
  312. qei_x->DMAEN &= ~mask;
  313. }
  314. /**
  315. * @brief get current counter value
  316. *
  317. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  318. * @param[in] type @ref qei_counter_type_t
  319. * @retval counter value
  320. */
  321. static inline uint32_t qei_get_current_count(QEI_Type *qei_x,
  322. qei_counter_type_t type)
  323. {
  324. return *(&qei_x->COUNT[QEI_COUNT_CURRENT].Z + type);
  325. }
  326. /**
  327. * @brief get read event count value
  328. *
  329. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  330. * @param[in] type @ref qei_counter_type_t
  331. * @retval counter value
  332. */
  333. static inline uint32_t qei_get_count_on_read_event(QEI_Type *qei_x,
  334. qei_counter_type_t type)
  335. {
  336. return *(&(qei_x->COUNT[QEI_COUNT_READ].Z) + type);
  337. }
  338. /**
  339. * @brief read the value of each phase snapshot 0 counter
  340. *
  341. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  342. * @param[in] type @ref qei_counter_type_t
  343. * @retval counter value
  344. */
  345. static inline uint32_t qei_get_count_on_snap0_event(QEI_Type *qei_x,
  346. qei_counter_type_t type)
  347. {
  348. return *(&qei_x->COUNT[QEI_COUNT_SNAP0].Z + type);
  349. }
  350. /**
  351. * @brief read the value of each phase snapshot 1 counter
  352. *
  353. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  354. * @param[in] type @ref qei_counter_type_t
  355. * @retval counter value
  356. */
  357. static inline uint32_t qei_get_count_on_snap1_event(QEI_Type *qei_x,
  358. qei_counter_type_t type)
  359. {
  360. return *(&qei_x->COUNT[QEI_COUNT_SNAP1].Z + type);
  361. }
  362. /**
  363. * @brief get speed history
  364. *
  365. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  366. * @param[in] hist_index @ref QEI_SPDHIS_SPDHIS1 ,QEI_SPDHIS_SPDHISx(x=0...n)
  367. * @retval speed history value
  368. * @arg 0 - hist_index out of range
  369. * @arg counter value
  370. */
  371. static inline uint32_t qei_get_speed_history(QEI_Type *qei_x, uint8_t hist_index)
  372. {
  373. if (hist_index > QEI_SPDHIS_SPDHIS3) {
  374. return 0;
  375. }
  376. return QEI_SPDHIS_SPDHIS0_GET(qei_x->SPDHIS[hist_index]);
  377. }
  378. /**
  379. * @brief load phcnt, zcnt, spdcnt and tmrcnt into their read registers
  380. *
  381. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  382. */
  383. static inline void qei_load_counter_to_read_registers(QEI_Type *qei_x)
  384. {
  385. qei_x->CR |= QEI_CR_READ_MASK;
  386. }
  387. /**
  388. * @brief reset spdcnt/phcnt/zcnt
  389. *
  390. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  391. * @param[in] counter_mask
  392. * @arg 1 reset zcnt when H assert
  393. * @arg (1<<1) reset phcnt when H assert
  394. * @arg (1<<2) reset spdcnt when H assert
  395. */
  396. static inline void qei_reset_counter_on_h_assert(QEI_Type *qei_x,
  397. uint32_t counter_mask)
  398. {
  399. qei_x->CR |= counter_mask << 16;
  400. }
  401. /**
  402. * @brief pause spdcnt when PAUSE assert
  403. *
  404. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  405. * @param[in] counter_mask
  406. * @arg 1 pause spdcnt when PAUSE assert
  407. * @arg (1<<1) pause spdcnt when PAUSE assert
  408. * @arg (1<<2) pause spdcnt when PAUSE assert
  409. */
  410. static inline void qei_pause_counter_on_pause(QEI_Type *qei_x,
  411. uint32_t counter_mask)
  412. {
  413. qei_x->CR |= counter_mask << 12;
  414. }
  415. /**
  416. * @brief load phcnt, zcnt, spdcnt and tmrcnt into their snap registers
  417. *
  418. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  419. */
  420. static inline void qei_snap_enable(QEI_Type *qei_x)
  421. {
  422. qei_x->CR |= QEI_CR_SNAPEN_MASK;
  423. }
  424. /**
  425. * @brief disable snap
  426. *
  427. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  428. */
  429. static inline void qei_snap_disable(QEI_Type *qei_x)
  430. {
  431. qei_x->CR &= ~QEI_CR_SNAPEN_MASK;
  432. }
  433. /**
  434. * @brief reset zcnt, spdcnt and tmrcnt to 0
  435. *
  436. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  437. */
  438. static inline void qei_counter_reset_assert(QEI_Type *qei_x)
  439. {
  440. qei_x->CR |= QEI_CR_RSTCNT_MASK;
  441. }
  442. /**
  443. * @brief qei counter reset release
  444. *
  445. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  446. */
  447. static inline void qei_counter_reset_release(QEI_Type *qei_x)
  448. {
  449. qei_x->CR &= ~QEI_CR_RSTCNT_MASK;
  450. }
  451. /**
  452. * @brief set work mode
  453. *
  454. * @param[in] qei_x QEI base address, HPM_QEIx(x=0...n)
  455. * @param[in] mode @ref qei_work_mode_t
  456. */
  457. static inline void qei_set_work_mode(QEI_Type *qei_x, qei_work_mode_t mode)
  458. {
  459. qei_x->CR = (qei_x->CR & ~QEI_CR_ENCTYP_MASK) | QEI_CR_ENCTYP_SET(mode);
  460. }
  461. #ifdef __cplusplus
  462. }
  463. #endif
  464. /**
  465. * @}
  466. */
  467. #endif /* HPM_QEI_DRV_H */