1 |
%$Header: /home/dashley/cvsrep/uculib01/uculib01/doc/manual/c_lfi0/c_lfi0.tex,v 1.10 2010/02/24 19:37:49 dashley Exp $ |
2 |
|
3 |
\chapter{Linear Filter Functions} |
4 |
|
5 |
\label{clfi0} |
6 |
|
7 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
8 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
9 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
10 |
\section{Introduction and Overview} |
11 |
%Section tag: iov0 |
12 |
\label{clfi0:siov0} |
13 |
|
14 |
This chapter describes functions that approximate linear filters. |
15 |
Here, \emph{linear} filter means a filter which satisfies |
16 |
additive and homogeneity properties. |
17 |
|
18 |
In order to satisfy the additive property, given two input signals $x_1(k)$ and $x_2(k)$, $\forall k>0$: |
19 |
|
20 |
\begin{equation} |
21 |
\label{eq:clfi0:siov0:01} |
22 |
y(x_1(k) + x_2(k)) = y(x_1(k)) + y(x_2(k)). |
23 |
\end{equation} |
24 |
|
25 |
\noindent{}In order to satisfy the homogeneity property, |
26 |
|
27 |
\begin{equation} |
28 |
\label{eq:clfi0:siov0:02} |
29 |
y(\alpha x_1(k)) = \alpha y(x_1(k)). |
30 |
\end{equation} |
31 |
|
32 |
\noindent{}A filter that does not satisfy both |
33 |
(\ref{eq:clfi0:siov0:01}) and (\ref{eq:clfi0:siov0:02}) is by |
34 |
definition a non-linear filter (see Chapter |
35 |
\ref{cnfi0}, p. \pageref{cnfi0}). |
36 |
|
37 |
It is hard to find appropriate names for linear filters (especially if |
38 |
filters differ from each other only in precision of arithmetic or the |
39 |
size and range of input arguments), so for now the filters |
40 |
are simply named using letters of the alphabet (\emph{Linear Filter A}, for |
41 |
example). |
42 |
|
43 |
|
44 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
45 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
46 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
47 |
\section{Linear Filter A} |
48 |
%Section tag: lfa0 |
49 |
\label{clfi0:slfa0} |
50 |
|
51 |
|
52 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
53 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
54 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
55 |
\subsection{Design} |
56 |
%Subsection tag: dsn0 |
57 |
\label{clfi0:slfa0:dsn0} |
58 |
|
59 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
60 |
|
61 |
\paragraph{General Design} |
62 |
|
63 |
\emph{Linear Filter A} approximates the |
64 |
discrete time difference equation |
65 |
|
66 |
\begin{equation} |
67 |
\label{eq:clfi0:slfa0:dsn0:01} |
68 |
y_{k} = \frac{2^{16}-h}{2^{16}}x_k + \frac{h}{2^{16}}y_{k-1}, |
69 |
\end{equation} |
70 |
|
71 |
\noindent{}where $x_k$ is the input and $y_k$ is the output |
72 |
of the filter at discrete time $k$. |
73 |
$h$ specifies the ``stiffness'' of the filter---a |
74 |
larger value of $h$ causes the filter to attenuate high frequencies more |
75 |
aggressively. |
76 |
|
77 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
78 |
|
79 |
\paragraph{Design Equivalence} |
80 |
|
81 |
In technical discussions, a filter of the design |
82 |
|
83 |
\begin{equation} |
84 |
\label{eq:clfi0:slfa0:dsn0:01a} |
85 |
y_{k} = y_{k-1} + \frac{x_k - y_{k-1}}{c} |
86 |
\end{equation} |
87 |
|
88 |
\noindent{}was discussed, where $c$ specifies the |
89 |
stiffness of the filter. |
90 |
|
91 |
(\ref{eq:clfi0:slfa0:dsn0:01a}) can be rearranged to |
92 |
|
93 |
\begin{equation} |
94 |
\label{eq:clfi0:slfa0:dsn0:01b} |
95 |
y_{k} = |
96 |
x_k \left( \frac{1}{c} \right) |
97 |
+ y_{k-1} \left( {1-\frac{1}{c}} \right). |
98 |
\end{equation} |
99 |
|
100 |
\noindent{}It can be seen by comparing |
101 |
(\ref{eq:clfi0:slfa0:dsn0:01}) with |
102 |
(\ref{eq:clfi0:slfa0:dsn0:01b}) that the substitution |
103 |
|
104 |
\begin{equation} |
105 |
\label{eq:clfi0:slfa0:dsn0:01c} |
106 |
c = \frac{1}{1-h/2^{16}} |
107 |
\end{equation} |
108 |
|
109 |
\noindent{}equates (\ref{eq:clfi0:slfa0:dsn0:01}) with |
110 |
(\ref{eq:clfi0:slfa0:dsn0:01b}), i.e. the filter described by |
111 |
(\ref{eq:clfi0:slfa0:dsn0:01}) and the filter |
112 |
described by (\ref{eq:clfi0:slfa0:dsn0:01b}) are |
113 |
mathematically equivalent. |
114 |
|
115 |
(\ref{eq:clfi0:slfa0:dsn0:01c}) can also be solved for $h$: |
116 |
|
117 |
\begin{equation} |
118 |
\label{eq:clfi0:slfa0:dsn0:01d} |
119 |
h = 2^{16}\left( 1 - \frac{1}{c} \right). |
120 |
\end{equation} |
121 |
|
122 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
123 |
|
124 |
\paragraph{Time Constant} |
125 |
|
126 |
The filter time constant $\tau$ can be expressed as |
127 |
|
128 |
\begin{equation} |
129 |
\label{eq:clfi0:slfa0:dsn0:02} |
130 |
\tau = \frac{h \Delta t}{2^{16} - h} , |
131 |
\end{equation} |
132 |
|
133 |
\noindent{}where $\Delta t$ is the discrete time interval.% |
134 |
\footnote{(\ref{eq:clfi0:slfa0:dsn0:02}) comes from the |
135 |
\emph{Discrete-time realization} section of the Wikipedia |
136 |
entry on low-pass filters \cite{bibref:w:wikipedialowpassfilter}---at this |
137 |
time I do not |
138 |
know how it is derived.} |
139 |
|
140 |
Alternatively, (\ref{eq:clfi0:slfa0:dsn0:02}) may be solved for $h$: |
141 |
|
142 |
\begin{equation} |
143 |
\label{eq:clfi0:slfa0:dsn0:03} |
144 |
h = \frac{2^{16} \tau}{\Delta t + \tau} . |
145 |
\end{equation} |
146 |
|
147 |
For example, at 100Hz ($\Delta t$=0.01 seconds) with a desired time constant |
148 |
of 100ms ($\tau$=0.1 seconds), the required value of $h$ is: |
149 |
|
150 |
\begin{equation} |
151 |
\label{eq:clfi0:slfa0:dsn0:04} |
152 |
h = \frac{(65536) (0.1)}{0.01 + 0.1} = 59578 . |
153 |
\end{equation} |
154 |
|
155 |
\begin{table} |
156 |
\caption{Values of $h$ for Common Choices of $\Delta t$ and $\tau$} |
157 |
\label{tbl:clfi0:slfa0:dsn0:01} |
158 |
\begin{center} |
159 |
\begin{tabular}{|c|c|c|c|} |
160 |
\hline |
161 |
& \small{$f$=100Hz} & \small{$f$=400Hz} & \small{$f$=1000Hz} \\ |
162 |
\small{$\tau$} & \small{$\Delta t$=0.01} & \small{$\Delta t$=0.0025} & \small{$\Delta t$=0.001} \\ |
163 |
\hline |
164 |
\hline |
165 |
\small{0.01} & \small{32,768} & \small{52,429} & \small{59,578} \\ |
166 |
\hline |
167 |
\small{0.05} & \small{54,613} & \small{62,415} & \small{64,251} \\ |
168 |
\hline |
169 |
\small{0.1} & \small{59,578} & \small{63,938} & \small{64,887} \\ |
170 |
\hline |
171 |
\small{0.2} & \small{62,415} & \small{64,727} & \small{65,210} \\ |
172 |
\hline |
173 |
\small{0.3} & \small{63,422} & \small{64,994} & \small{65,318} \\ |
174 |
\hline |
175 |
\small{0.4} & \small{63,938} & \small{65,129} & \small{65,373} \\ |
176 |
\hline |
177 |
\small{0.5} & \small{64,251} & \small{65,210} & \small{65,405} \\ |
178 |
\hline |
179 |
\small{1.0} & \small{64,887} & \small{65,373} & \small{65,470} \\ |
180 |
\hline |
181 |
\end{tabular} |
182 |
\end{center} |
183 |
\end{table} |
184 |
|
185 |
Table \ref{tbl:clfi0:slfa0:dsn0:01} provides the correct values of $h$ for common |
186 |
choices of $\Delta t$ and $\tau$. |
187 |
|
188 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
189 |
|
190 |
\paragraph{Numeric Implementation} |
191 |
|
192 |
The software uses large integers to implement the filter. The filter state |
193 |
($y_k$) is implemented as a 48-bit fixed-point integer with the radix point after the first |
194 |
16 bits. An upper-case ``y'' ($Y_k$ rather than $y_k$) is used to denote the |
195 |
48-bit integer corresponding to $y_k$. |
196 |
|
197 |
The implementation of the filter can be described by the following steps: |
198 |
|
199 |
\begin{enumerate} |
200 |
\item $Y_k$ is calculated: |
201 |
\begin{equation} |
202 |
\label{eq:clfi0:slfa0:dsn0:05} |
203 |
Y_k = \left\lfloor \frac{2^{32}(2^{16}-h)x_k + h Y_{k-1}}{2^{16}} \right\rfloor . |
204 |
\end{equation} |
205 |
\item $y_k$ is calculated from $Y_k$: |
206 |
\begin{equation} |
207 |
\label{eq:clfi0:slfa0:dsn0:06} |
208 |
y_k = \left\lfloor \frac{Y_k + 2^{31}}{2^{32}} \right\rfloor . |
209 |
\end{equation} |
210 |
\end{enumerate} |
211 |
|
212 |
The steps are implemented differently than directly suggested by |
213 |
(\ref{eq:clfi0:slfa0:dsn0:05}) and (\ref{eq:clfi0:slfa0:dsn0:06}). For example, |
214 |
the division by $2^{16}$ and the floor function |
215 |
in (\ref{eq:clfi0:slfa0:dsn0:05}) are implemented by discarding the last two bytes of |
216 |
an integer multiplication. As a second example, the |
217 |
addition of $2^{31}$ and the floor function in (\ref{eq:clfi0:slfa0:dsn0:06}) are implemented |
218 |
by testing bit 31 of $Y_k$ and conditionally incrementing $y_k$ rather than by adding. |
219 |
|
220 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
221 |
|
222 |
\paragraph{Overflow} |
223 |
|
224 |
It needs to be verified that the filter cannot state $Y_k$ cannot overflow |
225 |
(exceed $2^{48}-1$). |
226 |
In order overflow to occur, the numerator of |
227 |
(\ref{eq:clfi0:slfa0:dsn0:05}) would have to reach $2^{64}$\@. Guaranteeing that the |
228 |
filter cannot overflow is equivalent to guaranteeing that $\forall h$, |
229 |
$\forall x_k$, $\forall Y_{k-1}$: |
230 |
|
231 |
\begin{equation} |
232 |
\label{eq:clfi0:slfa0:dsn0:10} |
233 |
2^{32}(2^{16}-h)x_k + h Y_{k-1} < 2^{64} . |
234 |
\end{equation} |
235 |
|
236 |
We can substitute the worst cases of $x_k = 2^{16}-1$ and $Y_{k-1} = 2^{48}-1$ into |
237 |
(\ref{eq:clfi0:slfa0:dsn0:10}): |
238 |
|
239 |
\begin{equation} |
240 |
\label{eq:clfi0:slfa0:dsn0:11} |
241 |
2^{48}(2^{16}-1) + (2^{32}-1)h < 2^{64} . |
242 |
\end{equation} |
243 |
|
244 |
The worst case of $h=2^{16}-1$ can be substituted into |
245 |
(\ref{eq:clfi0:slfa0:dsn0:11}) to yield: |
246 |
|
247 |
\begin{equation} |
248 |
\label{eq:clfi0:slfa0:dsn0:12} |
249 |
2^{64} - 2^{32} - 2^{16} + 1 < 2^{64} . |
250 |
\end{equation} |
251 |
|
252 |
By inspection, (\ref{eq:clfi0:slfa0:dsn0:12}) is met, so filter overflow is not |
253 |
possible. |
254 |
|
255 |
In addition to the analysis above, as part of the unit test plan, |
256 |
the filter was tested extensively to be |
257 |
sure it could not roll over beyond $Y_k = 2^{48}-1$\@. |
258 |
|
259 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
260 |
|
261 |
\paragraph{Convergence} |
262 |
|
263 |
By \emph{convergence} of the filter I mean that, given enough time with |
264 |
a constant $x_k$, $y_k$ will reach the same value. |
265 |
|
266 |
Convergence wasn't formally analyzed (it should be), but there are three |
267 |
clues that the filter will probably always converge. |
268 |
|
269 |
\begin{enumerate} |
270 |
\item In unit testing with typical values of $h$, the filter always converged. |
271 |
\item In unit testing, one test performed (not in the test plan) was to set |
272 |
the initial value of the filter to 65534, the input to $x_k=65535$, and |
273 |
$h=65535$. The filter output did reach 65535. The fact that the filter |
274 |
will close a gap of $\Delta x_k = 1$ with $h=65535$ implies that the filter will probably |
275 |
always converge. |
276 |
\item In unit testing, a second test performed (not in the test plan) was to |
277 |
set the initial value of the filter to 65000, $h=65535$, |
278 |
$x_k = 65535$ and to measure the number of discrete time |
279 |
quanta required to reach $65535 - (65535-65000)/e = 65338.18$ (i.e. |
280 |
to measure the time constant). |
281 |
|
282 |
The number of time quanta required can be predicted from |
283 |
(\ref{eq:clfi0:slfa0:dsn0:02}) by removing the $\Delta t$ term: |
284 |
|
285 |
\begin{equation} |
286 |
\label{eq:clfi0:slfa0:dsn0:20} |
287 |
n = \frac{h}{2^{16} - h} = \frac{65535}{65536-65535} = 65535. |
288 |
\end{equation} |
289 |
|
290 |
In testing, this was the exact number of quanta required. This suggests |
291 |
that the precision of the filter (32 bits after the radix point) is |
292 |
adequate even with the largest valid $h$. |
293 |
\end{enumerate} |
294 |
|
295 |
Convergence should still be formally analyzed. |
296 |
|
297 |
|
298 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
299 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
300 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
301 |
\subsection[\emph{UcuLfU16FiltAInitRxn(\protect\mbox{\protect$\cdot$})}] |
302 |
{\emph{UcuLfU16FiltAInitRxn(\protect\mbox{\protect\boldmath $\cdot$})}} |
303 |
%Section tag: lcp0 |
304 |
\label{clfi0:slai0} |
305 |
|
306 |
\index{UcuLfU16FiltAInitRxn()@\emph{UcuLfU16FiltAInitRxn($\cdot$)}}% |
307 |
|
308 |
\noindent\textbf{PROTOTYPE} |
309 |
\begin {list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
310 |
\item |
311 |
\begin{verbatim} |
312 |
void UcuLfU16FiltAInitRxn(UCU_UNION48 *in_fs, |
313 |
UCU_UINT16 in_x_k_initial) |
314 |
\end{verbatim} |
315 |
\end{list} |
316 |
\vspace{2.8ex} |
317 |
|
318 |
\noindent\textbf{SYNOPSIS} |
319 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
320 |
\item Initializes the state \texttt{in\_fs} of a Linear Filter A |
321 |
to the passed value \texttt{in\_x\_k\_initial}. This consists of |
322 |
setting the most significant two bytes of the state to \texttt{in\_x\_k\_initial} |
323 |
and the least significant four bytes to zero. |
324 |
\item This function is typically used to either: |
325 |
\begin{itemize} |
326 |
\item Set the filter state to be the same as the input value (for example, |
327 |
at software startup). |
328 |
\item Eliminate filtering lag on a one-time basis and cause the filter output to track a step jump |
329 |
in the filter input (for example, when the software makes a major mode change |
330 |
or wishes to produce a step jump in output). |
331 |
\end{itemize} |
332 |
\end{list} |
333 |
\vspace{2.8ex} |
334 |
|
335 |
\noindent\textbf{INPUTS} |
336 |
\begin{list}{}{\setlength{\leftmargin}{0.5in}\setlength{\itemindent}{-0.25in}\setlength{\topsep}{0.0in}\setlength{\partopsep}{0.0in}} |
337 |
\item \emph{\textbf{in\_fs}}\\ |
338 |
The filter state. |
339 |
\item \emph{\textbf{in\_x\_k\_initial}}\\ |
340 |
The value to initialize the filter state to. |
341 |
\end{list} |
342 |
\vspace{2.8ex} |
343 |
|
344 |
\noindent\textbf{OUTPUTS} |
345 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
346 |
\item None. |
347 |
\end{list} |
348 |
\vspace{2.8ex} |
349 |
|
350 |
\noindent\textbf{INTERRUPT CONSIDERATIONS} |
351 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
352 |
\item This function can be used from both ISR and non-ISR software. |
353 |
\item This function does not ensure atomic access to \texttt{in\_fs}, so it is |
354 |
not thread-safe when processes in different threads use this function |
355 |
to access the \emph{same} filter state. |
356 |
\end{list} |
357 |
\vspace{2.8ex} |
358 |
|
359 |
\noindent\textbf{EXECUTION TIME} |
360 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
361 |
\item TBD. |
362 |
\end{list} |
363 |
\vspace{2.8ex} |
364 |
|
365 |
\noindent\textbf{FUNCTION NAME MNEMONIC} |
366 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
367 |
\item \emph{U16}: the data type to be filtered is UCU\_UINT16. |
368 |
\emph{FiltA}: Linear Filter A. |
369 |
\emph{Init}: initialize. |
370 |
\end{list} |
371 |
|
372 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
373 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
374 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
375 |
\subsection[\emph{UcuLfU16FiltAFiltRxn(\protect\mbox{\protect$\cdot$})}] |
376 |
{\emph{UcuLfU16FiltAFiltRxn(\protect\mbox{\protect\boldmath $\cdot$})}} |
377 |
%Section tag: lcp0 |
378 |
\label{clfi0:slaf0} |
379 |
|
380 |
\index{UcuLfU16FiltAFiltRxn()@\emph{UcuLfU16FiltAFiltRxn($\cdot$)}}% |
381 |
|
382 |
\noindent\textbf{PROTOTYPE} |
383 |
\begin {list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
384 |
\item |
385 |
\begin{verbatim} |
386 |
UCU_UINT16 UcuLfU16FiltAFiltRxn( |
387 |
UCU_UNION48 *in_fs, |
388 |
UCU_UINT16 in_x_k, |
389 |
UCU_UINT16 in_h |
390 |
) |
391 |
\end{verbatim} |
392 |
\end{list} |
393 |
\vspace{2.8ex} |
394 |
|
395 |
\noindent\textbf{SYNOPSIS} |
396 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
397 |
\item Filters the data input \texttt{in\_x\_k} using the specified |
398 |
time constant specifier \texttt{in\_h} and filter state |
399 |
\texttt{in\_fs}, and returns the filtered value. |
400 |
The filtering applied is defined by |
401 |
(\ref{eq:clfi0:slfa0:dsn0:05}) and (\ref{eq:clfi0:slfa0:dsn0:06}). |
402 |
\end{list} |
403 |
\vspace{2.8ex} |
404 |
|
405 |
\noindent\textbf{INPUTS} |
406 |
\begin{list}{}{\setlength{\leftmargin}{0.5in}\setlength{\itemindent}{-0.25in}\setlength{\topsep}{0.0in}\setlength{\partopsep}{0.0in}} |
407 |
\item \emph{\textbf{in\_fs}}\\ |
408 |
The filter state. |
409 |
\item \emph{\textbf{in\_x\_k}}\\ |
410 |
The input value to be filtered (i.e. $x_k$). |
411 |
\item \emph{\textbf{in\_h}}\\ |
412 |
The time constant of the filter as defined by (\ref{eq:clfi0:slfa0:dsn0:03}). |
413 |
\end{list} |
414 |
\vspace{2.8ex} |
415 |
|
416 |
\noindent\textbf{OUTPUTS} |
417 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
418 |
\item The filtered value, as defined by |
419 |
(\ref{eq:clfi0:slfa0:dsn0:05}) and (\ref{eq:clfi0:slfa0:dsn0:06}). |
420 |
\end{list} |
421 |
\vspace{2.8ex} |
422 |
|
423 |
\noindent\textbf{USAGE NOTES} |
424 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
425 |
\item The filter state is a fixed-point number, and this function |
426 |
implements a simple difference equation. It is safe to modify |
427 |
$h$ on the fly without unexpected effects (although this would be very |
428 |
rare, as most applications would always apply the same time constant to |
429 |
a given filter state). There is no state retained beyond the filter state block |
430 |
and no requirement |
431 |
that $h$ be the same value on every function call involving the same filter |
432 |
state block. |
433 |
\end{list} |
434 |
\vspace{2.8ex} |
435 |
|
436 |
\noindent\textbf{INTERRUPT CONSIDERATIONS} |
437 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
438 |
\item This function can be used from both ISR and non-ISR software. |
439 |
\item This function does not ensure atomic access to \texttt{in\_fs}, so it is |
440 |
not thread-safe when processes in different threads use this function |
441 |
to access the \emph{same} filter state. |
442 |
\end{list} |
443 |
\vspace{2.8ex} |
444 |
|
445 |
\noindent\textbf{EXECUTION TIME} |
446 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
447 |
\item TBD. |
448 |
\end{list} |
449 |
\vspace{2.8ex} |
450 |
|
451 |
\noindent\textbf{FUNCTION NAME MNEMONIC} |
452 |
\begin{list}{}{\setlength{\leftmargin}{0.25in}\setlength{\topsep}{0.0in}} |
453 |
\item \emph{U16}: the data type to be filtered is UCU\_UINT16. |
454 |
\emph{FiltA}: Linear Filter A. |
455 |
\emph{Filt}: filter. |
456 |
\end{list} |
457 |
|
458 |
|
459 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
460 |
\noindent\begin{figure}[!b] |
461 |
\noindent\rule[-0.25in]{\textwidth}{1pt} |
462 |
\begin{tiny} |
463 |
\begin{verbatim} |
464 |
$RCSfile: c_lfi0.tex,v $ |
465 |
$Source: /home/dashley/cvsrep/uculib01/uculib01/doc/manual/c_lfi0/c_lfi0.tex,v $ |
466 |
$Revision: 1.10 $ |
467 |
$Author: dashley $ |
468 |
$Date: 2010/02/24 19:37:49 $ |
469 |
\end{verbatim} |
470 |
\end{tiny} |
471 |
\noindent\rule[0.25in]{\textwidth}{1pt} |
472 |
\end{figure} |
473 |
|
474 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
475 |
%$Log: c_lfi0.tex,v $ |
476 |
%Revision 1.10 2010/02/24 19:37:49 dashley |
477 |
%Linear Filter A documentation corrected and enhanced. |
478 |
% |
479 |
%Revision 1.9 2010/01/28 21:18:32 dashley |
480 |
%a)Chapter start quotes removed. |
481 |
%b)Aesthetic comment line added at the bottom of most files. |
482 |
% |
483 |
%Revision 1.8 2010/01/28 02:45:46 dashley |
484 |
%Information about Linear Filter A completed. |
485 |
% |
486 |
%Revision 1.7 2010/01/27 16:08:53 dashley |
487 |
%Formatting difficulties corrected. |
488 |
% |
489 |
%Revision 1.6 2010/01/27 16:04:16 dashley |
490 |
%Formatting difficulty corrections. |
491 |
% |
492 |
%Revision 1.5 2010/01/27 00:26:33 dashley |
493 |
%Name change of Linear Filter A functions. |
494 |
% |
495 |
%Revision 1.4 2010/01/26 21:49:44 dashley |
496 |
%Edits. |
497 |
% |
498 |
%Revision 1.3 2010/01/26 21:10:26 dashley |
499 |
%Linear Filter A design section completed. |
500 |
% |
501 |
%Revision 1.2 2010/01/24 05:40:22 dashley |
502 |
%Minor title changes. |
503 |
% |
504 |
%Revision 1.1 2010/01/24 05:38:26 dashley |
505 |
%Initial checkin. |
506 |
%End of $RCSfile: c_lfi0.tex,v $. |
507 |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
508 |
|