hsk_libs-dev  163:b63ae088cc97
High Speed Karlsruhe XC878 library collection
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
hsk_pwc.h
Go to the documentation of this file.
1 /** \file
2  * HSK Pulse Width Counter headers
3  *
4  * This library uses the T2CCU to measure pulse width on the external
5  * interrupt pins.
6  *
7  * Every caputre channel blocks an external interrupt. Opening a channel
8  * will block this interrupt and change its configuration.
9  *
10  * Pulse with measurement has a window time that is configured with
11  * hsk_pwc_init() and defines the time frame within which pulses can be
12  * detected.
13  *
14  * If no pulse occurs during the window, the channel buffer is invalidated
15  * and the hsk_pwc_channel_getValue() function will returns invalid (0) until
16  * the buffer is repopulated with valid measurements.
17  *
18  * In order to guarantee the detection of invalid channels, the
19  * hsk_pwc_channel_getValue() function has to be called at least once every
20  * 256 window times.
21  *
22  * @author kami
23  */
24 
25 #ifndef _HSK_PWC_H_
26 #define _HSK_PWC_H_
27 
28 /*
29  * Required for SDCC to propagate ISR prototypes.
30  */
31 #ifdef SDCC
32 #include "../hsk_isr/hsk_isr.isr"
33 #endif /* SDCC */
34 
35 /**
36  * Typedef for PWC channel IDs.
37  */
38 typedef ubyte hsk_pwc_channel;
39 
40 /**
41  * Capture/Compare channel 0 on EXINT3.
42  */
43 #define PWC_CC0 0
44 
45 /**
46  * Capture/Compare channel 1 on EXINT4.
47  */
48 #define PWC_CC1 1
49 
50 /**
51  * Capture/Compare channel 2 on EXINT5.
52  */
53 #define PWC_CC2 2
54 
55 /**
56  * Capture/Compare channel 3 on EXINT6.
57  */
58 #define PWC_CC3 3
59 
60 /**
61  * Typedef for PWC input port.
62  */
63 typedef ubyte hsk_pwc_port;
64 
65 /**
66  * Capture/Compare channel 0 input port P3.0 configuration.
67  */
68 #define PWC_CC0_P30 0
69 
70 /**
71  * Capture/Compare channel 0 input port P4.0 configuration.
72  */
73 #define PWC_CC0_P40 1
74 
75 /**
76  * Capture/Compare channel 0 input port P5.5 configuration.
77  */
78 #define PWC_CC0_P55 2
79 
80 /**
81  * Capture/Compare channel 1 input port P3.2 configuration.
82  */
83 #define PWC_CC1_P32 3
84 
85 /**
86  * Capture/Compare channel 1 input port P4.1 configuration.
87  */
88 #define PWC_CC1_P41 4
89 
90 /**
91  * Capture/Compare channel 1 input port P5.6 configuration.
92  */
93 #define PWC_CC1_P56 5
94 
95 /**
96  * Capture/Compare channel 2 input port P3.3 configuration.
97  */
98 #define PWC_CC2_P33 6
99 
100 /**
101  * Capture/Compare channel 4 input port P4.4 configuration.
102  */
103 #define PWC_CC2_P44 7
104 
105 /**
106  * Capture/Compare channel 2 input port P5.2 configuration.
107  */
108 #define PWC_CC2_P52 8
109 
110 /**
111  * Capture/Compare channel 3 input port P3.4 configuration.
112  */
113 #define PWC_CC3_P34 9
114 
115 /**
116  * Capture/Compare channel 3 input port P4.5 configuration.
117  */
118 #define PWC_CC3_P45 10
119 
120 /**
121  * Capture/Compare channel 3 input port P5.7 configuration.
122  */
123 #define PWC_CC3_P57 11
124 
125 /**
126  * Configuration selection to trigger pulse detection on falling edge.
127  */
128 #define PWC_EDGE_FALLING 0
129 
130 /**
131  * Configuration selection to trigger pulse detection on rising edge.
132  */
133 #define PWC_EDGE_RISING 1
134 
135 /**
136  * Configuration selection to trigger pulse detection on both edges.
137  */
138 #define PWC_EDGE_BOTH 2
139 
140 /**
141  * Available capture modes, capture on external interrupt.
142  */
143 #define PWC_MODE_EXT 1
144 
145 /**
146  * Available capture modes, capture on sofware event.
147  */
148 #define PWC_MODE_SOFT 3
149 
150 /**
151  * This function initializes the T2CCU Capture/Compare Unit for capture mode.
152  *
153  * The capturing is based on the CCT timer. Timer T2 is not used and thus can
154  * be useed without interference.
155  *
156  * The window time is the time frame within which pulses should be detected.
157  * A smaller time frame results in higher precission, but detection of longer
158  * pulses will fail.
159  *
160  * Window times vary between ~1ms (\f$(2^{16} - 1) / (48 * 10^6)\f$) and ~5592ms
161  * (\f$(2^{16} - 1) * 2^{12} / (48 * 10^6)\f$). The shortest window time delivers
162  * ~20ns and the longest time ~85µs precision.
163  *
164  * The real window time is on a logarithmic scale (base 2), the init function
165  * will select the lowest scale that guarantees the required window time.
166  * I.e. the highest precision possible with the desired window time, which is
167  * at least \f$2^{15}\f$ for all windows below or equal 5592ms.
168  *
169  * @param window
170  * The time in ms to detect a pulse.
171  */
172 void hsk_pwc_init(ulong window);
173 
174 /**
175  * Configures a PWC channel without an input port.
176  *
177  * The channel is set up for software triggering (PWC_MODE_SOFT), and
178  * triggering on both edges (PWC_EDGE_BOTH).
179  *
180  * @param channel
181  * The PWC channel to open
182  * @param averageOver
183  * The number of pulse values to average over when returning a
184  * value or speed. The value must be between 1 and 8.
185  */
186 void hsk_pwc_channel_open(const hsk_pwc_channel channel,
187  ubyte __xdata averageOver);
188 
189 /**
190  * Opens an input port and the connected channel.
191  *
192  * The available configurations are available from the PWC_CCn_* defines.
193  *
194  * @param port
195  * The input port to open
196  * @param averageOver
197  * The number of pulse values to average over when returning a
198  * value or speed. The value must be between 1 and CHAN_BUF_SIZE
199  */
200 void hsk_pwc_port_open(const hsk_pwc_port port,
201  ubyte __xdata averageOver);
202 
203 /**
204  * Close a PWC channel.
205  *
206  * @param channel
207  * The channel to close.
208  */
209 void hsk_pwc_channel_close(const hsk_pwc_channel channel);
210 
211 /**
212  * Select the edge that is used to detect a pulse.
213  *
214  * Available edges are specified in the PWC_EDGE_* defines.
215  *
216  * @param channel
217  * The channel to configure the edge for.
218  * @param edgeMode
219  * The selected edge detection mode.
220  */
221 void hsk_pwc_channel_edgeMode(const hsk_pwc_channel channel,
222  const ubyte edgeMode);
223 
224 /**
225  * Allows switching between external and soft trigger.
226  *
227  * This does not reconfigure the input ports. Available modes are specified
228  * in the PWC_MODE_* defines. PWC_MODE_EXT is the default.
229  *
230  * @param channel
231  * The channel to configure.
232  * @param captureMode
233  * The mode to set the channel to.
234  */
236  const ubyte captureMode);
237 
238 /**
239  * Triggers a channel in soft trigger mode.
240  *
241  * @param channel
242  * The channel to trigger.
243  */
244 void hsk_pwc_channel_trigger(const hsk_pwc_channel channel);
245 
246 /**
247  * Enables T2CCU module if disabled.
248  */
249 void hsk_pwc_enable(void);
250 
251 /**
252  * Turns off the T2CCU clock to preserve power.
253  */
254 void hsk_pwc_disable(void);
255 
256 
257 /**
258  * \defgroup PWC_UNIT Pulse Width Detection Units
259  *
260  * This group of defines is used to select return format of
261  * hsk_pwc_channel_getValue().
262  *
263  * @{
264  */
265 
266 /**
267  * Sum of buffered pulse widths in multiples of \f$ 1/48 * 10^{-6} s \f$.
268  *
269  * This is the sum of the buffered values, not the average.
270  *
271  * Use this if precision is of the utmost importance.
272  */
273 #define PWC_UNIT_SUM_RAW 0
274 
275 /**
276  * \defgroup PWC_UNIT_WIDTH Pulse Width Times
277  *
278  * The defines are for returning average pulse width.
279  *
280  * @{
281  */
282 
283 /**
284  * Average of buffered pulse widths in multiples of \f$ 1/48 * 10^{-6} s \f$.
285  */
286 #define PWC_UNIT_WIDTH_RAW 1
287 
288 /**
289  * Average of buffered pulse widths in multiples of \f$ 10^{-9} s \f$.
290  */
291 #define PWC_UNIT_WIDTH_NS 2
292 
293 /**
294  * Average of buffered pulse widths in multiples of \f$ 10^{-6} s \f$.
295  */
296 #define PWC_UNIT_WIDTH_US 3
297 
298 /**
299  * Average of buffered pulse widths in multiples of \f$ 10^{-3} s \f$.
300  */
301 #define PWC_UNIT_WIDTH_MS 4
302 
303 /**
304  * @}
305  */
306 
307 /**
308  * \defgroup PWC_UNIT_FREQ Pulse Frequencies
309  *
310  * These defines are for returning average frequencies.
311  *
312  * @{
313  */
314 
315 /**
316  * Average frequency of buffered pulses in multiples of \f$ 1/s \f$.
317  */
318 #define PWC_UNIT_FREQ_S 5
319 
320 /**
321  * Average frequency of buffered pulses in multiples of \f$ 1/m \f$.
322  *
323  * To prevent overflow issues this value is always a multiple of the number
324  * of averaged values.
325  */
326 #define PWC_UNIT_FREQ_M 6
327 
328 /**
329  * Average frequency of buffered pulses in multiples of \f$ 1/h \f$.
330  *
331  * To prevent overflow issues this value is always a multiple of the number
332  * of averaged values * 60.
333  *
334  * This is just a convenience feature for quick testing, it is possible to
335  * achieve much better precision if the use case is known.
336  */
337 #define PWC_UNIT_FREQ_H 7
338 
339 /**
340  * @}
341  */
342 
343 /**
344  * \defgroup PWC_UNIT_DUTY Pulse Duty Times
345  *
346  * These defines are used for returning the duty time of the latest pulse.
347  *
348  * In order to use this return type, the channel buffer must hold at least
349  * 2 values. I.e. the averageOver argument of hsk_pwc_port_open() must
350  * be 2 or greater (there is no benefit to a value above 2).
351  *
352  * To produce correct results the channel must also be in edge mode
353  * \ref PWC_EDGE_BOTH.
354  *
355  * @{
356  */
357 
358 /**
359  * Latest high pulse in multiples of \f$ 1/48 * 10^{-6} s \f$.
360  */
361 #define PWC_UNIT_DUTYH_RAW 8
362 
363 /**
364  * Latest high pulse in multiples of \f$ 1 * 10^{-9} s \f$.
365  */
366 #define PWC_UNIT_DUTYH_NS 9
367 
368 /**
369  * Latest high pulse in multiples of \f$ 1 * 10^{-6} s \f$.
370  */
371 #define PWC_UNIT_DUTYH_US 10
372 
373 /**
374  * Latest high pulse in multiples of \f$ 1 * 10^{-3} s \f$.
375  */
376 #define PWC_UNIT_DUTYH_MS 11
377 
378 /**
379  * Latest low pulse in multiples of \f$ 1/48 * 10^{-6} s \f$.
380  */
381 #define PWC_UNIT_DUTYL_RAW 12
382 
383 /**
384  * Latest low pulse in multiples of \f$ 1 * 10^{-9} s \f$.
385  */
386 #define PWC_UNIT_DUTYL_NS 13
387 
388 /**
389  * Latest low pulse in multiples of \f$ 1 * 10^{-6} s \f$.
390  */
391 #define PWC_UNIT_DUTYL_US 14
392 
393 /**
394  * Latest low pulse in multiples of \f$ 1 * 10^{-3} s \f$.
395  */
396 #define PWC_UNIT_DUTYL_MS 15
397 
398 /**
399  * @}
400  */
401 
402 /**
403  * @}
404  */
405 
406 /**
407  * Returns a measure of the values in a channel buffer.
408  *
409  * It also takes care of invalidating channels that haven't been captured
410  * for too long.
411  *
412  * The value is returned in a requested unit, the units defined as
413  * PWC_UNIT_* are available.
414  *
415  * @param channel
416  * The channel to return the buffer sum of
417  * @param unit
418  ' The unit to return the channel value in
419  * @retval >0
420  * The channel value in the requested unit
421  * @retval 0
422  * Invalid channel, measurement timed out
423  */
424 ulong hsk_pwc_channel_getValue(const hsk_pwc_channel channel,
425  const ubyte unit);
426 
427 #endif /* _HSK_PWC_H_ */
428