NetBurner 3.5.6
PDF Version
qtmr.h
1/*NB_REVISION*/
2
3/*NB_COPYRIGHT*/
4
5#ifndef __QTMR_H
6#define __QTMR_H
7
8
9#include <predef.h>
10#include <stdint.h>
11#include <stddef.h>
12#include <sim.h>
13
14enum QTMR_Channel
15{
16 QTMR_CH_0 = 0u,
17 QTMR_CH_1 = 1u,
18 QTMR_CH_2 = 2u,
19 QTMR_CH_3 = 3u,
20};
21
22enum QTMR_Primary
23{
24 QTMR_PRI_IN_CNTR0 = 0u, /* Counter 0 input pin */
25 QTMR_PRI_IN_CNTR1 = 1u, /* Counter 1 input pin */
26 QTMR_PRI_IN_CNTR2 = 2u, /* Counter 2 input pin */
27 QTMR_PRI_IN_CNTR3 = 3u, /* Counter 3 input pin */
28 QTMR_PRI_OUT_CNTR0 = 4u, /* Counter 0 output */
29 QTMR_PRI_OUT_CNTR1 = 5u, /* Counter 1 output */
30 QTMR_PRI_OUT_CNTR2 = 6u, /* Counter 2 output */
31 QTMR_PRI_OUT_CNTR3 = 7u, /* Counter 3 output */
32 QTMR_PRI_CLK_DIV_1 = 8u, /* IP bus clock, divided by 1 */
33 QTMR_PRI_CLK_DIV_2 = 9u, /* IP bus clock, divided by 2 */
34 QTMR_PRI_CLK_DIV_4 = 10u,/* IP bus clock, divided by 4 */
35 QTMR_PRI_CLK_DIV_8 = 11u,/* IP bus clock, divided by 8 */
36 QTMR_PRI_CLK_DIV_16 = 12u,/* IP bus clock, divided by 16 */
37 QTMR_PRI_CLK_DIV_32 = 13u,/* IP bus clock, divided by 32 */
38 QTMR_PRI_CLK_DIV_64 = 14u,/* IP bus clock, divided by 64 */
39 QTMR_PRI_CLK_DIV_128= 15u,/* IP bus clock, divided by 128 */
40};
41
42enum QTMR_Input
43{
44 QTMR_IN_0 = 0u,
45 QTMR_IN_1 = 1u,
46 QTMR_IN_2 = 2u,
47 QTMR_IN_3 = 3u,
48};
49
50enum QTMR_DbgMode
51{
52 QTMR_DBG_NORMAL = 0u, /* Continue as normal */
53 QTMR_DBG_HALT = 1u, /* Halt the counter */
54 QTMR_FORCE_OUT_ZERO = 2u, /* Force output to logic 0 */
55 QTMR_DBG_HALT_FORCE_OUT_ZERO= 3u, /* Halt and force output to logic 0 */
56};
57
58enum QTMR_CapEdge
59{
60 QTMR_CAP_NONE = 0u,
61 QTMR_CAP_RISING = 1u,
62 QTMR_CAP_FALLING= 2u,
63 QTMR_CAP_BOTH = 3u,
64};
65
66enum QTMR_CountMode
67{
68 QTMR_COUNT_NONE = 0u, /* No counting */
69 QTMR_COUNT_PRIM_RISING = 1u, /* Count rising edges on primary source */
70 QTMR_COUNT_PRIM_BOTH = 2u, /* Count both edges on primary source */
71 QTMR_COUNT_PRIM_RISING_IN_HIGH = 3u, /* Count rising of pri src while sec input high*/
72 QTMR_COUNT_QUADRATURE = 4u, /* Quadrature mode using pri and sec */
73 QTMR_COUNT_PRIM_RISING_IN_DIR = 5u, /* Rising on primary, input sets dir (up/down) */
74 QTMR_COUNT_IN_EDGE = 6u, /* Count edge of sec until comparison met */
75 QTMR_COUNT_CASCADE = 7u, /* Cascaded count */
76};
77
78enum QTMR_Preload
79{
80 QTMR_PRELOAD_NEVER = 0u,
81 QTMR_PRELOAD_COMP1 = 1u,
82 QTMR_PRELOAD_COMP2 = 2u,
83};
84
85enum QTMR_OutMode
86{
87 QTMR_OUT_WHEN_ACTIVE = 0u, /* Assert OFLAG when counter is active */
88 QTMR_OUT_CMP_CLR = 1u, /* Clear OFLAG on compare */
89 QTMR_OUT_CMP_SET = 2u, /* Set OFLAG on compare */
90 QTMR_OUT_CMP_TGL = 3u, /* Toggle OFLAG on compare */
91 QTMR_OUT_CMP_TGL_ALT = 4u, /* Toggle OFLAG on alternating compare regs */
92 QTMR_OUT_CMP_SET_IN_CLR = 5u, /* Set OFLAG on compare, clear on sec Src edge */
93 QTMR_OUT_CMP_SET_ROLL_CLR = 6u, /* Set OFLAG on compare, clear on rollover */
94 QTMR_OUT_GATE_CLK = 7u, /* Gated clock output when counter is active */
95};
96
97enum QTMR_IRQFlag
98{
99 QTMR_IRQ_CMP = (TMR_SCTRL_TCFIE_MASK << 16),
100 QTMR_IRQ_OVERFLOW = (TMR_SCTRL_TOFIE_MASK << 16),
101 QTMR_IRQ_IN_EDGE = (TMR_SCTRL_IEFIE_MASK << 16),
102 QTMR_IRQ_CMP1 = (TMR_CSCTRL_TCF1EN_MASK),
103 QTMR_IRQ_CMP2 = (TMR_CSCTRL_TCF2EN_MASK),
104};
105
106enum QTMR_StatusFlag
107{
108 QTMR_STAT_CMP = (TMR_SCTRL_TCF_MASK << 16),
109 QTMR_STAT_OVERFLOW = (TMR_SCTRL_TOF_MASK << 16),
110 QTMR_STAT_IN_EDGE = (TMR_SCTRL_IEF_MASK << 16),
111 QTMR_STAT_CMP1 = (TMR_CSCTRL_TCF1_MASK),
112 QTMR_STAT_CMP2 = (TMR_CSCTRL_TCF2_MASK),
113};
114
115enum QTMR_DMAFlag
116{
117 QTMR_DMA_IN_EDGE = (TMR_DMA_IEFDE_MASK),
118 QTMR_DMA_PLD_CMP1 = (TMR_DMA_CMPLD1DE_MASK),
119 QTMR_DMA_PLD_CMP2 = (TMR_DMA_CMPLD2DE_MASK),
120};
121
122struct QTimer;
123struct QTimer_Channel;
124
125typedef void (*QTimer_CB)(QTimer *);
126typedef void (*QTimer_Channel_CB)(QTimer *, QTMR_Channel);
127
128struct QTimer_Channel : TMR_Channel_Type
129{
130private:
131 struct ctx_t
132 {
133 QTimer_Channel_CB irqCB;
134 uint32_t irqCount;
135 };
136
137 static ctx_t *sGetCtx(QTimer_Channel *ch);
138
139 QTimer_Channel();
140
141 void isr(QTimer * tmr, QTMR_Channel chNum);
142 friend struct QTimer;
143public:
144 void Init(QTMR_Primary priSrc, QTMR_Input secSrc,
145 bool masterMode, bool enExtForce,
146 uint8_t faultFiltCount, uint8_t faultFiltPer,
147 QTMR_DbgMode dbgMode);
148 bool SetupPwm(uint32_t pwmFreq, uint8_t dutyPcnt,
149 bool invertPolarity, uint32_t srcFreq);
150 void SetupCapture(QTMR_Input pin, bool invertPolarity, bool reloadOnCapture, QTMR_CapEdge edge);
151 void SetupCascade(uint16_t countVal);
152
153 inline void ConfigOutput(bool enabled, bool invertPolarity, QTMR_OutMode mode);
154 inline void ForceOutput(bool val);
155 void EnableIRQs(uint32_t mask); // SCTRL flags in upper 16 bits, CSCTRL flags in lower
156 void DisableIRQs(uint32_t mask);
157 uint32_t GetEnabledIRQs();
158 uint32_t GetStatus();
159 void ClearStatus(uint32_t mask);
160 void SetPeriod(uint16_t period);
161 inline uint16_t GetCurCount();
162 inline uint16_t GetCurCap();
163 inline void Start(QTMR_CountMode mode);
164 inline QTMR_CountMode Stop();
165 void EnableDMA(uint32_t mask);
166 void DisableDMA(uint32_t mask);
167
168 uint8_t GetChNum();
169 QTimer *GetTimer();
170
171 bool IRQReady();
172 QTimer_Channel_CB SetIRQFn(QTimer_Channel_CB fn);
173};
174
175struct QTimer : TMR_Type
176{
177private:
178 struct ctx_t
179 {
180 QTimer_CB irqCB;
181 uint32_t irqCount;
182 QTimer_Channel::ctx_t ch[4];
183 };
184
185 static ctx_t sCtxs[4];
186 static ctx_t *sGetCtx(QTimer *timer)
187 {
188 switch ((uint32_t)timer) {
189 case TMR1_BASE: return sCtxs + 0;
190 case TMR2_BASE: return sCtxs + 1;
191 case TMR3_BASE: return sCtxs + 2;
192 case TMR4_BASE: return sCtxs + 3;
193 }
194 return NULL;
195 }
196
197 QTimer();
198 void isr();
199
200 friend QTimer_Channel::ctx_t * QTimer_Channel::sGetCtx(QTimer_Channel *ch);
201 friend QTimer_Channel_CB QTimer_Channel::SetIRQFn(QTimer_Channel_CB fn);
202
203 friend void isr_qtimer0();
204 friend void isr_qtimer1();
205 friend void isr_qtimer2();
206 friend void isr_qtimer3();
207public:
208 inline QTimer_Channel &operator[](int i);
209
210 static inline QTimer *TMR(TMR_Type *tmr);
211
212 inline void Init(QTMR_Channel chNum, QTMR_Primary priSrc, QTMR_Input secSrc,
213 bool masterMode, bool enExtForce, uint8_t faultFiltCount,
214 uint8_t faultFiltPer, QTMR_DbgMode dbgMode);
215 inline bool SetupPwm(QTMR_Channel chNum, uint32_t pwmFreq, uint8_t dutyPcnt,
216 bool invertPolarity, uint32_t srcFreq);
217 inline void SetupCapture(QTMR_Channel chNum, QTMR_Input pin,
218 bool invertPolarity, bool reloadOnCapture,
219 QTMR_CapEdge edge);
220 inline void ConfigOutput(QTMR_Channel chNum, bool enabled, bool invertPolarity, QTMR_OutMode mode);
221 inline void ForceOutput(QTMR_Channel chNum, bool val);
222 inline void EnableIRQs(QTMR_Channel chNum, uint32_t mask);
223 inline void DisableIRQs(QTMR_Channel chNum, uint32_t mask);
224 inline uint32_t GetEnabledIRQs(QTMR_Channel chNum);
225 inline uint32_t GetStatus(QTMR_Channel chNum);
226 inline void ClearStatus(QTMR_Channel chNum, uint32_t mask);
227 inline void SetPeriod(QTMR_Channel chNum, uint16_t period);
228 inline uint16_t GetCurCount(QTMR_Channel chNum);
229 inline void Start(QTMR_Channel chNum, QTMR_CountMode mode);
230 inline QTMR_CountMode Stop(QTMR_Channel chNum);
231 inline void EnableDMA(QTMR_Channel chNum, uint32_t mask);
232 inline void DisableDMA(QTMR_Channel chNum, uint32_t mask);
233 inline void EnableChannels(uint16_t mask);
234 inline void DisableChannels(uint16_t mask);
235
236 QTimer_CB SetIRQFn(QTimer_CB fn);
237 QTimer_Channel_CB SetChIRQFn(QTMR_Channel chNum, QTimer_Channel_CB fn);
238};
239
240inline void QTimer::
241Init(QTMR_Channel chNum, QTMR_Primary priSrc, QTMR_Input secSrc,
242 bool masterMode, bool enExtForce, uint8_t faultFiltCount,
243 uint8_t faultFiltPer, QTMR_DbgMode dbgMode)
244{
245 ((QTimer_Channel *)(CHANNEL+chNum))
246 ->Init(priSrc, secSrc, masterMode, enExtForce, faultFiltCount,
247 faultFiltPer, dbgMode);
248}
249
250inline bool QTimer::
251SetupPwm(QTMR_Channel chNum, uint32_t pwmFreq, uint8_t dutyPcnt,
252 bool invertPolarity, uint32_t srcFreq)
253{
254 return ((QTimer_Channel *)(CHANNEL+chNum))
255 ->SetupPwm(pwmFreq, dutyPcnt, invertPolarity, srcFreq);
256}
257
258
259inline void QTimer::
260SetupCapture(QTMR_Channel chNum, QTMR_Input pin, bool invertPolarity,
261 bool reloadOnCapture, QTMR_CapEdge edge)
262{
263 ((QTimer_Channel *)(CHANNEL+chNum))
264 ->SetupCapture(pin, invertPolarity, reloadOnCapture, edge);
265}
266
267inline void QTimer::
268ConfigOutput(QTMR_Channel chNum, bool enabled, bool invertPolarity, QTMR_OutMode mode)
269{
270 ((QTimer_Channel *)(CHANNEL+chNum))->ConfigOutput(enabled,invertPolarity,mode);
271}
272
273inline void QTimer::
274ForceOutput(QTMR_Channel chNum, bool val)
275{
276 ((QTimer_Channel *)(CHANNEL+chNum))->ForceOutput(val);
277}
278
279inline void QTimer::
280EnableIRQs(QTMR_Channel chNum, uint32_t mask)
281{
282 ((QTimer_Channel *)(CHANNEL+chNum))
283 ->EnableIRQs(mask);
284}
285
286inline void QTimer::
287DisableIRQs(QTMR_Channel chNum, uint32_t mask)
288{
289 ((QTimer_Channel *)(CHANNEL+chNum))
290 ->EnableIRQs(mask);
291}
292
293inline uint32_t QTimer::
294GetEnabledIRQs(QTMR_Channel chNum)
295{
296 return ((QTimer_Channel *)(CHANNEL+chNum))
297 ->GetEnabledIRQs();
298}
299
300inline uint32_t QTimer::
301GetStatus(QTMR_Channel chNum)
302{
303 return ((QTimer_Channel *)(CHANNEL+chNum))
304 ->GetStatus();
305}
306
307inline void QTimer::
308ClearStatus(QTMR_Channel chNum, uint32_t mask)
309{
310 ((QTimer_Channel *)(CHANNEL+chNum))
311 ->ClearStatus(mask);
312}
313
314inline void QTimer::
315SetPeriod(QTMR_Channel chNum, uint16_t period)
316{
317 ((QTimer_Channel *)(CHANNEL+chNum))
318 ->SetPeriod(period);
319}
320
321inline void QTimer::
322EnableDMA(QTMR_Channel chNum, uint32_t mask)
323{
324 ((QTimer_Channel *)(CHANNEL+chNum))
325 ->EnableDMA(mask);
326}
327
328inline void QTimer::
329DisableDMA(QTMR_Channel chNum, uint32_t mask)
330{
331 ((QTimer_Channel *)(CHANNEL+chNum))
332 ->DisableDMA(mask);
333}
334
335inline QTimer_Channel & QTimer::
336operator[](int i)
337{ return *(QTimer_Channel *)(CHANNEL+i); }
338
339inline QTimer *QTimer::
340TMR(TMR_Type *tmr)
341{ return (QTimer *)tmr; }
342
343inline uint16_t QTimer::GetCurCount(QTMR_Channel chNum){ return CHANNEL[chNum].CNTR; }
344
345inline void QTimer::Start(QTMR_Channel chNum, QTMR_CountMode mode)
346{
347 CHANNEL[chNum].CTRL =
348 (CHANNEL[chNum].CTRL & (uint16_t)(~(TMR_CTRL_CM_MASK)))
349 | TMR_CTRL_CM(mode);
350}
351
352inline QTMR_CountMode QTimer::
353Stop(QTMR_Channel chNum)
354{
355 uint8_t mode = (CHANNEL[chNum].CTRL & TMR_CTRL_CM_MASK) >> TMR_CTRL_CM_SHIFT;
356 CHANNEL[chNum].CTRL &= (uint16_t)(~(TMR_CTRL_CM_MASK));
357 return (QTMR_CountMode)mode;
358}
359
360inline void QTimer::
361EnableChannels(uint16_t mask)
362{
363 CHANNEL[0].ENBL |= mask;
364}
365
366
367
368inline void QTimer::
369DisableChannels(uint16_t mask)
370{
371 CHANNEL[0].ENBL &= ~mask;
372}
373
374inline uint16_t QTimer_Channel::GetCurCount(){ return CNTR; }
375inline uint16_t QTimer_Channel::GetCurCap(){ return CAPT; }
376
377inline void QTimer_Channel::
378Start(QTMR_CountMode mode)
379{
380 CTRL = (CTRL & (uint16_t)(~(TMR_CTRL_CM_MASK))) | TMR_CTRL_CM(mode);
381}
382
383inline QTMR_CountMode QTimer_Channel::
384Stop()
385{
386 uint8_t mode = (CTRL & TMR_CTRL_CM_MASK) >> TMR_CTRL_CM_SHIFT;
387 CTRL &= (uint16_t)(~(TMR_CTRL_CM_MASK));
388 return (QTMR_CountMode)mode;
389}
390
391inline void QTimer_Channel::
392ConfigOutput(bool enabled, bool invertPolarity, QTMR_OutMode mode)
393{
394 SCTRL = (SCTRL & ~(TMR_SCTRL_OPS_MASK | TMR_SCTRL_OEN_MASK))
395 | TMR_SCTRL_OPS(invertPolarity) | TMR_SCTRL_OEN(enabled);
396 CTRL = (CTRL & ~(TMR_CTRL_OUTMODE_MASK))
397 | TMR_CTRL_OUTMODE(mode);
398}
399
400inline void QTimer_Channel::
401ForceOutput(bool val)
402{
403 SCTRL = (SCTRL & ~(TMR_SCTRL_VAL_MASK))
404 | TMR_SCTRL_VAL(val) | TMR_SCTRL_FORCE(1);
405}
406
407
408
409#endif /* ----- #ifndef __QTMR_H ----- */