💾 Archived View for gemini.djph.net › users › gemini › projects › sk6812 › pt2.gmi captured on 2020-09-24 at 00:55:32. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

SK6812 - Continued

Continued from here

It's been a few days (err, at least it's only felt like a few days), and I've finally sorted out the two interrupts to handle changing the output color. In order to not change things mid-stream, the interrupt handlers only set a flag that the main loop then uses in order to change the entire strip at once. Debouncing of the buttons is handled via a timer that only re-enables the INT0 interrupt after a few milliseconds, and ensures that there are no pending interrupt flags for INT0 before exiting the timer.

INT0

Interrupt 0 ("INT0") is an external interrupt pin that (on the ATTinyX5 series anyway) is on PB2 (Pin7). It can be triggered by one of four conditions - high level, low level, rising edge, or falling edge. For the project, I decided on falling edge. The pin itself is set initially as input with pullup, and external wiring is simply to a normally open momentary pushbutton that pulls the pin to ground.

INT0_ISR

The service routine is pretty short, comprising only about 5 or 6 real instructions. The remaining instructions primarily save / restore the stack pointer and r16, which is used as a working register.

push r16 ; r16 to stack

in r16, SREG ; SREG to r16

push r16 ; r16 (SREG) to stack

in r16, GIMSK ; load int. mask reg into r16

andi r16, ~(1<<INT0) ; disable INT0 pin

out GIMSK, r16 ; save to register

; enable a ~128 ms debounce timer

; TODO: shorten this

ldi r16, (1<<CS13) | (1<<CS12) | (1<<CS10)

out TCCR1, r16

inc r1 ; increment flag

pop r16 ; restore r16 (SREG)

out SREG, r16 ; restore r16 to SREG

pop r16 ; restore r16

reti

T1_OVF

The other interrupt that is in use is the Timer 1 overflow. In this project, the timer is set up to count from 0 to T_MAX once, then shut itself down. This interrupt is used to act as a software de-bouncing routine for the button.

T1_OVF_ISR

As with the INT0 routine, the overflow routine is quite short - 7 real commands and a handful of others to store / retrieve registers to the SRAM-based stack pointer.

push r16 ; save r16 to stack

in r16, SREG ; SREG to r16

push r16 ; r16 (SREG) to stack

in r16, GIMSK ; load interrupt register to r16

ori r16, (1<<INT0) ; enable INT0 pin

out GIMSK, r16 ; save back to GIMSK register

clr r16 ; clear r16

out TCCR1, r16 ; stop the clock

ldi r16,(1<<INTF0) ; force clear INT0 flag

out GIFR, r16 ; and save to flag register

pop r16 ; restore r16 (SREG)

out SREG, r16 ; restore r16 to SREG

pop r16 ; restore r16

reti ; return from interrupt