I know that there are many CircularBuffer posts already. But they mostly cover the concept and several basic ways of doing it, even some classes (what I would normally do). But in a ISR they are Very SLOW mostly requiring the use of multiple of memory accesses and non-cpu-supported division.
In a ISR (Interrupt Service Request) we need to be fast, very fast.
The best I could think of was to use a Buffer of size that's a power of 2
BUFFSIZE being a Precompiler #Define, is just a constant.
a Constant - a constant (1), gcc should just replace with a constant
so in the case of BUFFSIZE = 8
The code should reduce to Buffer_Pos_Write=(Buffer_Pos_Write+1)&(7);
Then to
Memory fetch for "Buffer_Pos_Write" (X Cycles)
Inc (1 cycle, all AVR devices)
ANDI (1 cycle, all AVR devices)
Memory write for "Buffer_Pos_Write" (X Cycles)
That gets me a Memory read, Memory write + 2 Cpu cycles, for a CircularBuffer incrementor.
My question to all you is, is there a better way? Maybe some way to keep a ISR variable in a register between requests... etc
Note: The circular buffer isn't required for the isr function to work, it just gives the initial ramp-up of the return value and adds some averaging to provide a response that's closer to that of an analog guage.
I used the math operator X+1 instead of the C/C++ increment Operators ++X and X++, since both of those imply a immedate memory write, which I don't want to spend time doing, as I still need to apply the mask., after the increment
Yes. Being able to just add mask is the beautsy of using a power of two as the buffer size.
The other lines (methods) were offered for any buffer size, one was not quite right so I justposted what seemed to work in a test I did.
Using the modulo operator always seemed like overkill for something you can pretty well know is incremented past a point where it needs to be wrapped around.
Actually no, my read is much slower, as I only check to read all buffer data every 500ms or so. As for me data packets are small-ish and far between. so as long as the buffer can hold it, reads don't need to be fast, that's why there's a buffer in the first place. Its the ISR than I need on the 4µs range.