I'm working on a project where I need to debounce 6 input buttons independently of each other. I need to keep a debounced volatile inputstate and also feed a ringbuffer of key presses and key releases. The buttons are split across two ports PINA/PINB and putting the 6 of them in a loop in the ISR means that far less optimization takes place and the ISR takes 400-500 cycles, but unwinding it to 6 repeating sections where each button has its own reduces the time in the ISR greatly down to 100uS if activity occurred and 50-60 if it doesn't. I've found that putting the code that feeds the ringbuffer in its own function saves flash space without significantly affecting speed. I've tried it as a regular function, static inline function, or even a function within the ISR function - all perform identically. Any other ideas for improving this code? I also found that loading the inputstate into a local variable once at the beginning of the 6 sections and setting it once at the end was an improvement as well.
static inline void addkey(uint8_t key) { if (inputcount<KEYBOARD_BUFFER_SIZE) { inputbuffer[inputin]=key; inputin++; if (inputin==KEYBOARD_BUFFER_SIZE) inputin=0; inputcount++; } } ISR(TIM0_COMPA_vect) { uint8_t c1; c1=inputstate; //this section repeats 6 times for each button if (PINB & _BV(PB_BUTTON0_PIN)) { if (!(c1 & _BV(PB_BUTTON0_PIN))) { dbcount[0]++; if (dbcount[0]>=20) { c1 |= _BV(PB_BUTTON0_PIN); addkey(0); } } else dbcount[0]=0; } else { if (c1 & _BV(PB_BUTTON0_PIN)) { dbcount[0]++; if (dbcount[0]>=20) { c1 &= ~_BV(PB_BUTTON0_PIN); addkey(8); } } else dbcount[0]=0; } inputstate=c1; }