1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_HALL_DRV_H
9 #define HPM_HALL_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_hall_regs.h"
13
14 /**
15 * @brief HALL driver APIs
16 * @defgroup hall_interface HALL driver APIs
17 * @ingroup io_interfaces
18 * @{
19 *
20 */
21
22 #define HALL_EVENT_WDOG_FLAG_MASK (1U << 31) /**< wdg flag */
23 #define HALL_EVENT_PHUPT_FLAG_MASK (1U << 30) /**< phupt flag */
24 #define HALL_EVENT_PHPRE_FLAG_MASK (1U << 29) /**< phpre flag */
25 #define HALL_EVENT_PHDLYEN_FLAG_MASK (1U << 28) /**< phdly flag */
26 #define HALL_EVENT_U_FLAG_MASK (1U << 23) /**< u flag */
27 #define HALL_EVENT_V_FLAG_MASK (1U << 22) /**< v flag */
28 #define HALL_EVENT_W_FLAG_MASK (1U << 21) /**< w flag */
29 #define HALL_UVW_STAT_MASK (HALL_COUNT_U_USTAT_MASK | HALL_COUNT_U_VSTAT_MASK | HALL_COUNT_U_WSTAT_MASK)
30 #define HALL_U_STAT_MASK HALL_COUNT_U_USTAT_MASK
31 #define HALL_V_STAT_MASK HALL_COUNT_U_VSTAT_MASK
32 #define HALL_W_STAT_MASK HALL_COUNT_U_WSTAT_MASK
33
34 /**
35 * @brief select delay start time
36 *
37 */
38 typedef enum hall_count_delay_start {
39 hall_count_delay_start_after_uvw_toggle = 0, /**< start counting delay after u,v,w toggle */
40 hall_count_delay_start_after_pre_trigger = 1, /**< start counting delay after pre-trigger */
41 } hall_count_delay_start_t;
42
43 /**
44 * @brief return value of motor movement direction
45 *
46 */
47 typedef enum hall_rotate_direction {
48 hall_rotate_direction_forward = 0, /**< direction forward */
49 hall_rotate_direction_reversed = 1 /**< direction reversed */
50 } hall_rotate_direction_t;
51
52 /**
53 * @brief counter type config
54 *
55 */
56 typedef enum hall_counter_type {
57 hall_counter_type_w = 0, /**< type w */
58 hall_counter_type_v = 1, /**< type v */
59 hall_counter_type_u = 2, /**< type u */
60 hall_counter_type_timer = 3, /**< type timer */
61 } hall_counter_type_t;
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 /**
68 * @brief enable the watchdog
69 *
70 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
71 * @param[in] timeout watch dog timeout value , unit is HALL system clock
72 */
hall_wdog_enable(HALL_Type * hall_x,uint32_t timeout)73 static inline void hall_wdog_enable(HALL_Type *hall_x, uint32_t timeout)
74 {
75 hall_x->WDGCFG = HALL_WDGCFG_WDGTO_SET(timeout)
76 | HALL_WDGCFG_WDGEN_SET(true);
77 }
78
79 /**
80 * @brief disable the watchdog
81 *
82 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
83 */
hall_wdog_disable(HALL_Type * hall_x)84 static inline void hall_wdog_disable(HALL_Type *hall_x)
85 {
86 hall_x->WDGCFG = HALL_WDGCFG_WDGEN_SET(false);
87 }
88
89 /**
90 * @brief delay a certain number of clock cycles after receiving a trigger event
91 *
92 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
93 * @param[in] delay_count delay clock cycles number
94 * @param[in] delay_start select the trigger moment
95 */
hall_phase_config(HALL_Type * hall_x,uint32_t delay_count,hall_count_delay_start_t delay_start)96 static inline void hall_phase_config(HALL_Type *hall_x, uint32_t delay_count,
97 hall_count_delay_start_t delay_start)
98 {
99 hall_x->PHCFG = HALL_PHCFG_DLYSEL_SET(delay_start)
100 | HALL_PHCFG_DLYCNT_SET(delay_count);
101 }
102
103 /**
104 * @brief early trigger configuration
105 *
106 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
107 * @param[in] counter the clock cycle number
108 */
hall_pre_uvw_transition_config(HALL_Type * hall_x,uint32_t counter)109 static inline void hall_pre_uvw_transition_config(HALL_Type *hall_x, uint32_t counter)
110 {
111 hall_x->UVWCFG = HALL_UVWCFG_PRECNT_SET(counter);
112 }
113
114 /**
115 * @brief enable trigger event mask
116 *
117 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
118 * @param[in] event_mask event mask to be checked
119 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
120 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
121 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
122 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
123 * @arg @ref HALL_EVENT_U_FLAG_MASK
124 * @arg @ref HALL_EVENT_V_FLAG_MASK
125 * @arg @ref HALL_EVENT_W_FLAG_MASK
126 */
hall_trigger_output_event_enable(HALL_Type * hall_x,uint32_t event_mask)127 static inline void hall_trigger_output_event_enable(HALL_Type *hall_x,
128 uint32_t event_mask)
129 {
130 hall_x->TRGOEN = (hall_x->TRGOEN & ~event_mask) | event_mask;
131 }
132
133 /**
134 * @brief disable trigger event mask
135 *
136 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
137 * @param[in] event_mask event mask to bo checked
138 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
139 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
140 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
141 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
142 * @arg @ref HALL_EVENT_U_FLAG_MASK
143 * @arg @ref HALL_EVENT_V_FLAG_MASK
144 * @arg @ref HALL_EVENT_W_FLAG_MASK
145 */
hall_trigger_output_event_disable(HALL_Type * hall_x,uint32_t event_mask)146 static inline void hall_trigger_output_event_disable(HALL_Type *hall_x,
147 uint32_t event_mask)
148 {
149 hall_x->TRGOEN &= ~event_mask;
150 }
151
152 /**
153 * @brief enable hardware read event
154 *
155 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
156 * @param[in] event_mask read registers flag
157 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
158 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
159 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
160 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
161 * @arg @ref HALL_EVENT_U_FLAG_MASK
162 * @arg @ref HALL_EVENT_V_FLAG_MASK
163 * @arg @ref HALL_EVENT_W_FLAG_MASK
164 */
hall_load_read_trigger_event_enable(HALL_Type * hall_x,uint32_t event_mask)165 static inline void hall_load_read_trigger_event_enable(HALL_Type *hall_x,
166 uint32_t event_mask)
167 {
168 hall_x->READEN = (hall_x->READEN & ~event_mask) | event_mask;
169 }
170
171 /**
172 * @brief disable hardware read event
173 *
174 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
175 * @param[in] event_mask read registers flag
176 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
177 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
178 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
179 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
180 * @arg @ref HALL_EVENT_U_FLAG_MASK
181 * @arg @ref HALL_EVENT_V_FLAG_MASK
182 * @arg @ref HALL_EVENT_W_FLAG_MASK
183 */
hall_load_read_trigger_event_disable(HALL_Type * hall_x,uint32_t event_mask)184 static inline void hall_load_read_trigger_event_disable(HALL_Type *hall_x,
185 uint32_t event_mask)
186 {
187 hall_x->READEN &= ~event_mask;
188 }
189
190 /**
191 * @brief clear status register
192 *
193 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
194 * @param[in] mask hall event flag
195 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
196 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
197 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
198 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
199 * @arg @ref HALL_EVENT_U_FLAG_MASK
200 * @arg @ref HALL_EVENT_V_FLAG_MASK
201 * @arg @ref HALL_EVENT_W_FLAG_MASK
202 */
hall_clear_status(HALL_Type * hall_x,uint32_t mask)203 static inline void hall_clear_status(HALL_Type *hall_x, uint32_t mask)
204 {
205 hall_x->SR = mask;
206 }
207
208 /**
209 * @brief get status register
210 *
211 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
212 * @retval uint32_t value:
213 * @retval HALL_EVENT_WDOG_FLAG_MASK if watchdog counter timeout
214 * @retval HALL_EVENT_PHUPT_FLAG_MASK if U/V/W Flip any input signal
215 * @retval HALL_EVENT_PHPRE_FLAG_MASK if early trigger events occur
216 * @retval HALL_EVENT_PHDLYEN_FLAG_MASK if time delay events occur
217 * @retval HALL_EVENT_U_FLAG_MASK if U signal flip
218 * @retval HALL_EVENT_V_FLAG_MASK if V signal flip
219 * @retval HALL_EVENT_W_FLAG_MASK if W signal flip
220 */
hall_get_status(HALL_Type * hall_x)221 static inline uint32_t hall_get_status(HALL_Type *hall_x)
222 {
223 return hall_x->SR;
224 }
225
226 /**
227 * @brief enable irq
228 *
229 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
230 * @param[in] mask hall event flag
231 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
232 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
233 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
234 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
235 * @arg @ref HALL_EVENT_U_FLAG_MASK
236 * @arg @ref HALL_EVENT_V_FLAG_MASK
237 * @arg @ref HALL_EVENT_W_FLAG_MASK
238 */
hall_irq_enable(HALL_Type * hall_x,uint32_t mask)239 static inline void hall_irq_enable(HALL_Type *hall_x, uint32_t mask)
240 {
241 hall_x->IRQEN = (hall_x->IRQEN & ~mask) | mask;
242 }
243
244 /**
245 * @brief disable irq
246 *
247 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
248 * @param[in] mask hall event flag
249 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
250 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
251 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
252 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
253 * @arg @ref HALL_EVENT_U_FLAG_MASK
254 * @arg @ref HALL_EVENT_V_FLAG_MASK
255 * @arg @ref HALL_EVENT_W_FLAG_MASK
256 */
hall_irq_disable(HALL_Type * hall_x,uint32_t mask)257 static inline void hall_irq_disable(HALL_Type *hall_x, uint32_t mask)
258 {
259 hall_x->IRQEN &= ~mask;
260 }
261
262 /**
263 * @brief enable dma request
264 *
265 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
266 * @param[in] mask hall event flag
267 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
268 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
269 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
270 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
271 * @arg @ref HALL_EVENT_U_FLAG_MASK
272 * @arg @ref HALL_EVENT_V_FLAG_MASK
273 * @arg @ref HALL_EVENT_W_FLAG_MASK
274 */
hall_dma_request_enable(HALL_Type * hall_x,uint32_t mask)275 static inline void hall_dma_request_enable(HALL_Type *hall_x, uint32_t mask)
276 {
277 hall_x->DMAEN = (hall_x->DMAEN & ~mask) | mask;
278 }
279
280 /**
281 * @brief disable dma request
282 *
283 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
284 * @param[in] mask hall event flag
285 * @arg @ref HALL_EVENT_WDOG_FLAG_MASK
286 * @arg @ref HALL_EVENT_PHUPT_FLAG_MASK
287 * @arg @ref HALL_EVENT_PHPRE_FLAG_MASK
288 * @arg @ref HALL_EVENT_PHDLYEN_FLAG_MASK
289 * @arg @ref HALL_EVENT_U_FLAG_MASK
290 * @arg @ref HALL_EVENT_V_FLAG_MASK
291 * @arg @ref HALL_EVENT_W_FLAG_MASK
292 */
hall_dma_request_disable(HALL_Type * hall_x,uint32_t mask)293 static inline void hall_dma_request_disable(HALL_Type *hall_x, uint32_t mask)
294 {
295 hall_x->DMAEN &= ~mask;
296 }
297
298 /**
299 * @brief get rotate direction
300 *
301 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
302 * @retval hall_rotate_direction_t
303 */
hall_get_rotate_direction(HALL_Type * hall_x)304 static inline hall_rotate_direction_t hall_get_rotate_direction(HALL_Type *hall_x)
305 {
306 return (hall_rotate_direction_t)HALL_COUNT_U_DIR_GET(hall_x->COUNT[HALL_COUNT_CURRENT].U);
307 }
308
309 /**
310 * @brief get three bits indicate UVW state
311 *
312 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
313 * @retval three bits UVW state
314 */
hall_get_current_uvw_stat(HALL_Type * hall_x)315 static inline uint32_t hall_get_current_uvw_stat(HALL_Type *hall_x)
316 {
317 return (hall_x->COUNT[HALL_COUNT_CURRENT].U & (HALL_UVW_STAT_MASK)) >> HALL_COUNT_U_WSTAT_SHIFT;
318 }
319
320 /**
321 * @brief get current count U or V or W
322 *
323 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
324 * @param[in] type @ref hall_counter_type_t
325 * @retval count value
326 */
hall_get_current_count(HALL_Type * hall_x,hall_counter_type_t type)327 static inline uint32_t hall_get_current_count(HALL_Type *hall_x,
328 hall_counter_type_t type)
329 {
330 return *(&hall_x->COUNT[HALL_COUNT_CURRENT].W + type) & HALL_COUNT_U_UCNT_MASK;
331 }
332
333 /**
334 * @brief get count when read event generated
335 *
336 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
337 * @param[in] type hall_counter_type_t
338 * @retval count value
339 */
hall_get_count_on_read_event(HALL_Type * hall_x,hall_counter_type_t type)340 static inline uint32_t hall_get_count_on_read_event(HALL_Type *hall_x,
341 hall_counter_type_t type)
342 {
343 return *(&hall_x->COUNT[HALL_COUNT_READ].W + type);
344 }
345
346 /**
347 * @brief get count when snap0 event generated
348 *
349 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
350 * @param[in] type @ref hall_counter_type_t
351 * @retval count value
352 */
hall_get_count_on_snap0_event(HALL_Type * hall_x,hall_counter_type_t type)353 static inline uint32_t hall_get_count_on_snap0_event(HALL_Type *hall_x,
354 hall_counter_type_t type)
355 {
356 return *(&hall_x->COUNT[HALL_COUNT_SNAP0].W + type);
357 }
358
359 /**
360 * @brief get count when snap1 event generated
361 *
362 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
363 * @param[in] type @ref hall_counter_type_t
364 * @retval count value
365 */
hall_get_count_on_snap1_event(HALL_Type * hall_x,hall_counter_type_t type)366 static inline uint32_t hall_get_count_on_snap1_event(HALL_Type *hall_x,
367 hall_counter_type_t type)
368 {
369 return *(&hall_x->COUNT[HALL_COUNT_SNAP1].W + type);
370 }
371
372 /**
373 * @brief get the history count of u when u signal transition from 0 to 1
374 *
375 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
376 * @retval count value
377 */
hall_get_u_history0(HALL_Type * hall_x)378 static inline uint32_t hall_get_u_history0(HALL_Type *hall_x)
379 {
380 return hall_x->HIS[0].HIS0;
381 }
382
383 /**
384 * @brief get the history count of u when u signal transition from 1 to 0
385 *
386 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
387 * @retval count value
388 */
hall_get_u_history1(HALL_Type * hall_x)389 static inline uint32_t hall_get_u_history1(HALL_Type *hall_x)
390 {
391 return hall_x->HIS[0].HIS1;
392 }
393
394 /**
395 * @brief get the history count of v when v signal transition from 0 to 1
396 *
397 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
398 * @retval count value
399 */
hall_get_v_history0(HALL_Type * hall_x)400 static inline uint32_t hall_get_v_history0(HALL_Type *hall_x)
401 {
402 return hall_x->HIS[1].HIS0;
403 }
404
405 /**
406 * @brief get the history count of v when v signal transition from 1 to 0
407 *
408 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
409 * @retval count value
410 */
hall_get_v_history1(HALL_Type * hall_x)411 static inline uint32_t hall_get_v_history1(HALL_Type *hall_x)
412 {
413 return hall_x->HIS[1].HIS1;
414 }
415
416 /**
417 * @brief get the history count of w when w signal transition from 0 to 1
418 *
419 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
420 * @retval count value
421 */
hall_get_w_history0(HALL_Type * hall_x)422 static inline uint32_t hall_get_w_history0(HALL_Type *hall_x)
423 {
424 return hall_x->HIS[2].HIS0;
425 }
426
427 /**
428 * @brief get the history count of w when w signal transition from 1 to 0
429 *
430 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
431 * @retval count value
432 */
hall_get_w_history1(HALL_Type * hall_x)433 static inline uint32_t hall_get_w_history1(HALL_Type *hall_x)
434 {
435 return hall_x->HIS[2].HIS1;
436 }
437
438 /**
439 * @brief load ucnt, vcnt, wcnt and tmrcnt into their read registers.
440 * Hardware auto-clear;
441 *
442 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
443 */
hall_load_count_to_read_registers(HALL_Type * hall_x)444 static inline void hall_load_count_to_read_registers(HALL_Type *hall_x)
445 {
446 hall_x->CR |= HALL_CR_READ_MASK;
447 }
448
449 /**
450 * @brief enable hall snap
451 *
452 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
453 */
hall_snap_enable(HALL_Type * hall_x)454 static inline void hall_snap_enable(HALL_Type *hall_x)
455 {
456 hall_x->CR |= HALL_CR_SNAPEN_SET(1);
457 }
458
459 /**
460 * @brief disable hall snap
461 *
462 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
463 */
hall_snap_disable(HALL_Type * hall_x)464 static inline void hall_snap_disable(HALL_Type *hall_x)
465 {
466 hall_x->CR &= ~HALL_CR_SNAPEN_MASK;
467 }
468
469 /**
470 * @brief reset all counter and related snapshots assert
471 *
472 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
473 */
hall_counter_reset_assert(HALL_Type * hall_x)474 static inline void hall_counter_reset_assert(HALL_Type *hall_x)
475 {
476 hall_x->CR |= HALL_CR_RSTCNT_MASK;
477 }
478
479 /**
480 * @brief reset all counter and related snapshots release
481 *
482 * @param[in] hall_x HALL base address HPM_HALLx(x=0..n)
483 */
hall_counter_reset_release(HALL_Type * hall_x)484 static inline void hall_counter_reset_release(HALL_Type *hall_x)
485 {
486 hall_x->CR &= ~HALL_CR_RSTCNT_MASK;
487 }
488
489 #ifdef __cplusplus
490 }
491 #endif
492 /**
493 * @}
494 */
495
496 #endif /* HPM_HALL_DRV_H */
497