1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_TRGM_DRV_H
9 #define HPM_TRGM_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_trgm_regs.h"
13 #include "hpm_trgmmux_src.h"
14
15 /**
16 *
17 * @brief TRGM driver APIs
18 * @defgroup trgm_interface TRGM driver APIs
19 * @{
20 */
21
22 /**
23 * @brief Filter mode
24 */
25 typedef enum trgm_filter_mode {
26 trgm_filter_mode_bypass = 0,
27 trgm_filter_mode_rapid_change = 4,
28 trgm_filter_mode_delay = 5,
29 trgm_filter_mode_stable_high = 6,
30 trgm_filter_mode_stable_low = 7,
31 } trgm_filter_mode_t;
32
33 /**
34 * @brief Output type
35 */
36 typedef enum trgm_output_type {
37 trgm_output_same_as_input = 0,
38 trgm_output_pulse_at_input_falling_edge = TRGM_TRGOCFG_FEDG2PEN_MASK,
39 trgm_output_pulse_at_input_rising_edge = TRGM_TRGOCFG_REDG2PEN_MASK,
40 trgm_output_pulse_at_input_both_edge = trgm_output_pulse_at_input_falling_edge
41 | trgm_output_pulse_at_input_rising_edge,
42 } trgm_output_type_t;
43
44 /**
45 * @brief Input filter configuration
46 */
47 typedef struct trgm_input_filter {
48 bool invert; /**< Invert output */
49 bool sync; /**< Sync with TRGM clock */
50 uint32_t filter_length; /**< Filter length in TRGM clock cycle */
51 trgm_filter_mode_t mode; /**< Filter working mode */
52 } trgm_input_filter_t;
53
54 /**
55 * @brief Output configuration
56 */
57 typedef struct trgm_output {
58 bool invert; /**< Invert output */
59 trgm_output_type_t type; /**< Output type */
60 uint8_t input; /**< Input selection */
61 } trgm_output_t;
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 /**
68 * @brief Enable IO output
69 *
70 * @param[in] ptr TRGM base address
71 * @param[in] mask Mask of IOs to be enabled
72 */
trgm_enable_io_output(TRGM_Type * ptr,uint32_t mask)73 static inline void trgm_enable_io_output(TRGM_Type *ptr, uint32_t mask)
74 {
75 ptr->GCR |= mask;
76 }
77
78 /**
79 * @brief Disable IO output
80 *
81 * @param[in] ptr TRGM base address
82 * @param[in] mask Mask of IOs to be disabled
83 */
trgm_disable_io_output(TRGM_Type * ptr,uint32_t mask)84 static inline void trgm_disable_io_output(TRGM_Type *ptr, uint32_t mask)
85 {
86 ptr->GCR &= ~mask;
87 }
88
89 /**
90 * @brief Set filter length
91 *
92 * @param[in] ptr TRGM base address
93 * @param[in] input Input selection
94 * @param[in] length Filter length in TRGM clock cycles
95 */
trgm_input_filter_set_filter_length(TRGM_Type * ptr,uint8_t input,uint32_t length)96 static inline void trgm_input_filter_set_filter_length(TRGM_Type *ptr, uint8_t input, uint32_t length)
97 {
98 #if defined(TRGM_SOC_HAS_FILTER_SHIFT) && TRGM_SOC_HAS_FILTER_SHIFT
99 uint32_t len = length;
100 uint8_t shift;
101 for (shift = 0; shift <= (TRGM_FILTCFG_FILTLEN_SHIFT_MASK >> TRGM_FILTCFG_FILTLEN_SHIFT_SHIFT); shift++) {
102 if (shift > 0) {
103 len >>= 1u;
104 }
105 if (len <= (TRGM_FILTCFG_FILTLEN_BASE_MASK >> TRGM_FILTCFG_FILTLEN_BASE_SHIFT)) {
106 break;
107 }
108 }
109 if (len > (TRGM_FILTCFG_FILTLEN_BASE_MASK >> TRGM_FILTCFG_FILTLEN_BASE_SHIFT)) {
110 len = (TRGM_FILTCFG_FILTLEN_BASE_MASK >> TRGM_FILTCFG_FILTLEN_BASE_SHIFT);
111 shift = (TRGM_FILTCFG_FILTLEN_SHIFT_MASK >> TRGM_FILTCFG_FILTLEN_SHIFT_SHIFT);
112 }
113 ptr->FILTCFG[input] = (ptr->FILTCFG[input] & ~(TRGM_FILTCFG_FILTLEN_BASE_MASK | TRGM_FILTCFG_FILTLEN_SHIFT_MASK))
114 | TRGM_FILTCFG_FILTLEN_BASE_SET(len) | TRGM_FILTCFG_FILTLEN_SHIFT_SET(shift);
115 #else
116 ptr->FILTCFG[input] = (ptr->FILTCFG[input] & ~TRGM_FILTCFG_FILTLEN_MASK)
117 | TRGM_FILTCFG_FILTLEN_SET(length);
118 #endif
119 }
120
121 /**
122 * @brief Set filter length
123 *
124 * @param[in] ptr TRGM base address
125 * @param[in] input Input selection
126 * @param[in] length Filter length in TRGM clock cycles (0 ~ 0xFFF)
127 */
trgm_input_filter_set_filter_shift(TRGM_Type * ptr,uint8_t input,uint8_t shift)128 static inline void trgm_input_filter_set_filter_shift(TRGM_Type *ptr, uint8_t input, uint8_t shift)
129 {
130 #if defined(TRGM_SOC_HAS_FILTER_SHIFT) && TRGM_SOC_HAS_FILTER_SHIFT
131 ptr->FILTCFG[input] = (ptr->FILTCFG[input] & ~TRGM_FILTCFG_FILTLEN_SHIFT_MASK)
132 | TRGM_FILTCFG_FILTLEN_SHIFT_SET(shift);
133 #else
134 (void) ptr;
135 (void) input;
136 (void) shift;
137 #endif
138 }
139
140 /**
141 * @brief Enable sync input with TRGM clock
142 *
143 * @param[in] ptr TRGM base address
144 * @param[in] input Input selection
145 */
trgm_input_filter_enable_sync(TRGM_Type * ptr,uint8_t input)146 static inline void trgm_input_filter_enable_sync(TRGM_Type *ptr, uint8_t input)
147 {
148 ptr->FILTCFG[input] |= TRGM_FILTCFG_SYNCEN_MASK;
149 }
150
151 /**
152 * @brief Disable sync input with TRGM clock
153 *
154 * @param[in] ptr TRGM base address
155 * @param[in] input Input selection
156 */
trgm_input_filter_disable_sync(TRGM_Type * ptr,uint8_t input)157 static inline void trgm_input_filter_disable_sync(TRGM_Type *ptr, uint8_t input)
158 {
159 ptr->FILTCFG[input] &= ~TRGM_FILTCFG_SYNCEN_MASK;
160 }
161
162 /**
163 * @brief Set filter working mode
164 *
165 * @param[in] ptr TRGM base address
166 * @param[in] input Input selection
167 * @param[in] mode Working mode
168 */
trgm_input_filter_set_mode(TRGM_Type * ptr,uint8_t input,trgm_filter_mode_t mode)169 static inline void trgm_input_filter_set_mode(TRGM_Type *ptr, uint8_t input, trgm_filter_mode_t mode)
170 {
171 ptr->FILTCFG[input] = (ptr->FILTCFG[input] & ~TRGM_FILTCFG_MODE_MASK)
172 | TRGM_FILTCFG_MODE_SET(mode);
173 }
174
175 /**
176 * @brief Invert filter output
177 *
178 * @param[in] ptr TRGM base address
179 * @param[in] input Input selection
180 * @param[in] invert Set true to invert output
181 */
trgm_input_filter_invert(TRGM_Type * ptr,uint8_t input,bool invert)182 static inline void trgm_input_filter_invert(TRGM_Type *ptr, uint8_t input, bool invert)
183 {
184 ptr->FILTCFG[input] = (ptr->FILTCFG[input] & ~TRGM_FILTCFG_OUTINV_MASK)
185 | TRGM_FILTCFG_OUTINV_SET(invert);
186 }
187
188 /**
189 * @brief Configure filter
190 *
191 * @param[in] ptr TRGM base address
192 * @param[in] input Input selection
193 * @param[in] filter Pointer to filter configuration
194 */
trgm_input_filter_config(TRGM_Type * ptr,uint8_t input,trgm_input_filter_t * filter)195 static inline void trgm_input_filter_config(TRGM_Type *ptr, uint8_t input, trgm_input_filter_t *filter)
196 {
197 ptr->FILTCFG[input] = TRGM_FILTCFG_OUTINV_SET(filter->invert)
198 | TRGM_FILTCFG_MODE_SET(filter->mode)
199 | TRGM_FILTCFG_SYNCEN_SET(filter->sync);
200 trgm_input_filter_set_filter_length(ptr, input, filter->filter_length);
201 }
202
203 /**
204 * @brief Update source for TRGM output
205 *
206 * @param[in] ptr TRGM base address
207 * @param[in] output Target output
208 * @param[in] source Source for output
209 */
trgm_output_update_source(TRGM_Type * ptr,uint8_t output,uint8_t source)210 static inline void trgm_output_update_source(TRGM_Type *ptr, uint8_t output, uint8_t source)
211 {
212 ptr->TRGOCFG[output] = (ptr->TRGOCFG[output] & ~TRGM_TRGOCFG_TRIGOSEL_MASK)
213 | TRGM_TRGOCFG_TRIGOSEL_SET(source);
214 }
215
216 /**
217 * @brief Configure output
218 *
219 * @param[in] ptr TRGM base address
220 * @param[in] output Target output
221 * @param[in] config Pointer to output configuration
222 */
trgm_output_config(TRGM_Type * ptr,uint8_t output,trgm_output_t * config)223 static inline void trgm_output_config(TRGM_Type *ptr, uint8_t output, trgm_output_t *config)
224 {
225 ptr->TRGOCFG[output] = TRGM_TRGOCFG_TRIGOSEL_SET(config->input)
226 | (config->type & TRGM_TRGOCFG_FEDG2PEN_MASK)
227 | (config->type & TRGM_TRGOCFG_REDG2PEN_MASK)
228 | TRGM_TRGOCFG_OUTINV_SET(config->invert);
229 }
230
231 /**
232 * @brief Configure DMA request
233 *
234 * @param[in] ptr TRGM base address
235 * @param[in] dma_out Target DMA out
236 * @param[in] dma_src DMA source selection
237 */
trgm_dma_request_config(TRGM_Type * ptr,uint8_t dma_out,uint8_t dma_src)238 static inline void trgm_dma_request_config(TRGM_Type *ptr, uint8_t dma_out, uint8_t dma_src)
239 {
240 #if defined(TRGM_SOC_HAS_DMAMUX_EN) && TRGM_SOC_HAS_DMAMUX_EN
241 ptr->DMACFG[dma_out] = TRGM_DMACFG_DMASRCSEL_SET(dma_src) | TRGM_DMACFG_DMAMUX_EN_MASK;
242 #else
243 ptr->DMACFG[dma_out] = TRGM_DMACFG_DMASRCSEL_SET(dma_src);
244 #endif
245 }
246
247 #ifdef __cplusplus
248 }
249 #endif
250 /**
251 * @}
252 */
253
254 #endif /* HPM_TRGM_DRV_H */
255
256
257