• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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