Greetings -
I've written a short test program to evaluate various implementations of a digital filter that I need to implement. I'll present the code and follow that with a short explanation and then a description of what I think I am seeing. AS7, gcc, Mega328P. The WHOLE program is in three files and the WHOLE program is listed, below.
main.c
/* * main.c * * Created: 7/9/2019 11:53:09 AM * Author : wagner */ #include <avr/io.h> #include <stdlib.h> #include <stdint.h> #include "cfile.h" //sensor data three samples made up int16_t x[] = {-500,-500,-500 }; int16_t y[] = {20,20,20 }; int16_t z[] = {10,10,10 }; volatile signal_t xSignal; volatile signal_t ySignal; volatile signal_t zSignal; volatile uint8_t flag; int main(void) { //INITIALIZATION uint8_t J = 0; while (1) { xSignal.xnew = x[J]; //xSignal.y0 will be assigned by filter() filter( &xSignal ); ySignal.xnew = y[J]; filter( &ySignal ); zSignal.xnew = z[J]; filter( &zSignal ); J ++; if ( J >= 3 ) J = 0; } } //end main.c
filter.h
/* * cfile.h * * Created: 7/9/2019 11:53:09 AM * Author : wagner */ #ifndef CFILE_H #define CFILE_H #include <stdlib.h> #include <stdint.h> //BASE 65536 0.002Hz #define BASE 65536 //e.g. 1<<16 #define A0 65532 //0.99937 #define B1 65528 //0.99874 #define FILDLY 500 //startup stabilization samples typedef struct{ int16_t x0; int16_t x1; int16_t y0; int16_t y1; int16_t xnew; //this avoids having to reference the new data globally inside the filter } signal_t; void filter( signal_t *); #endif
cfile.c
/* * cfile.c * * Created: 7/9/2019 11:53:09 AM * Author : wagner */ #include "cfile.h" // ===================================================================================== //Versioin for 16-bit unsquared data but with long coefficients to get low corner // // The filter is a first order high-pass that is intended to eliminate static offset, // background gravity, and temperature sensitivity in offset. // // Immplements the filter function y[n] = a0 (x[n] - x[n-1]) + b1 y[n-1] // where: x[n] is the current input sample // x[n-1] is the previous input sample // y[n] is the current output sample from this filter // y[n-1] is the previous output sample // // Note that a0 and b1 are fractions less than 1 and are implemented as fixed-point // values based on some base BASE (see cfile.h) plus defined constants A0 and B1 // // SEE cfiles.h for corner frequency // // It operates on the struct signal in which // on call operates on on exit // signal.x0 PREVIOUS input current input PREVIOUS input // signal.x1 2ND PREVIOUS input previous input 2ND PREVIOUS input // signal.y0 PREVIOUS output current output PREVIOUS output // signal.y1 2ND PREVIOUS output previous output 2ND PREVIOUS output // signal.xnew NEW input new signal value this input // ===================================================================================== void filter( signal_t *MySignal) { //the pointer references the struct signal_t xSignal, etc int32_t working; MySignal->x1 = MySignal->x0; MySignal->y1 = MySignal->y0; MySignal->x0 = MySignal->xnew; working = (MySignal->x0 - MySignal->x1) * A0; working = working + B1*MySignal->y1; working = working / BASE; MySignal->y0 = working; } //end filter()
OK, this compiles without errors or warning. Optimization is -O3
The arrays x[], y[], and z[] represent samples generated by my acceleration sensor. The struct signal_t is implemented 3 times, as XSignal, YSignal, and ZSignal. Each contains the old and new values of the input time series and the output time series for each axis' filter. The structs are passed, one at a time, to the function filter(signal_t *) to do the filtering for that axis for that sample. I've faked three samples of sensor data, just to get started. Also faked the sample index, J, just to get started.
Here are the odd things that happen:
1) When I run it through the simulator, it will not step into the function unless a breakpoint is present inside the function.
2) When the cursor has just passed the line xSignal.xnew = x[J]; the simulator does not know what xSignal is.
3) When the cursor is inside the function, the simulator does not know what MySignal is.
In the past, I would have written this off to "optimization" but I don't think that is what is happening, here. I've looked at the lst file, and to the extent that I understand what it shows, it seems to be OK.
I am assuming that I've made some kind of error here. Or, maybe just some invalid assumptions about how things ought to be. Can anyone help me out?
Thanks
Jim