@@ -466,3 +466,107 @@ var SPI0 = SPI{
466466 sdo : PB3 ,
467467 sdi : PB4 ,
468468 cs : PB2 }
469+
470+ // Pin Change Interrupts
471+ type PinChange uint8
472+
473+ const (
474+ PinRising PinChange = 1 << iota
475+ PinFalling
476+ PinToggle = PinRising | PinFalling
477+ )
478+
479+ func (pin Pin ) SetInterrupt (pinChange PinChange , callback func (Pin )) (err error ) {
480+
481+ switch {
482+ case pin >= PB0 && pin <= PB7 :
483+ // PCMSK0 - PCINT0-7
484+ pinStates [0 ] = avr .PINB .Get ()
485+ pinIndex := pin - PB0
486+ if pinChange & PinRising > 0 {
487+ pinCallbacks [0 ][pinIndex ][0 ] = callback
488+ }
489+ if pinChange & PinFalling > 0 {
490+ pinCallbacks [0 ][pinIndex ][1 ] = callback
491+ }
492+ if callback != nil {
493+ avr .PCMSK0 .SetBits (1 << pinIndex )
494+ } else {
495+ avr .PCMSK0 .ClearBits (1 << pinIndex )
496+ }
497+ avr .PCICR .SetBits (avr .PCICR_PCIE0 )
498+ interrupt .New (avr .IRQ_PCINT0 , handlePCINT0Interrupts )
499+ case pin >= PC0 && pin <= PC7 :
500+ // PCMSK1 - PCINT8-14
501+ pinStates [1 ] = avr .PINC .Get ()
502+ pinIndex := pin - PC0
503+ if pinChange & PinRising > 0 {
504+ pinCallbacks [1 ][pinIndex ][0 ] = callback
505+ }
506+ if pinChange & PinFalling > 0 {
507+ pinCallbacks [1 ][pinIndex ][1 ] = callback
508+ }
509+ if callback != nil {
510+ avr .PCMSK1 .SetBits (1 << pinIndex )
511+ } else {
512+ avr .PCMSK1 .ClearBits (1 << pinIndex )
513+ }
514+ avr .PCICR .SetBits (avr .PCICR_PCIE1 )
515+ interrupt .New (avr .IRQ_PCINT1 , handlePCINT1Interrupts )
516+ case pin >= PD0 && pin <= PD7 :
517+ // PCMSK2 - PCINT16-23
518+ pinStates [2 ] = avr .PIND .Get ()
519+ pinIndex := pin - PD0
520+ if pinChange & PinRising > 0 {
521+ pinCallbacks [2 ][pinIndex ][0 ] = callback
522+ }
523+ if pinChange & PinFalling > 0 {
524+ pinCallbacks [2 ][pinIndex ][1 ] = callback
525+ }
526+ if callback != nil {
527+ avr .PCMSK2 .SetBits (1 << pinIndex )
528+ } else {
529+ avr .PCMSK2 .ClearBits (1 << pinIndex )
530+ }
531+ avr .PCICR .SetBits (avr .PCICR_PCIE2 )
532+ interrupt .New (avr .IRQ_PCINT2 , handlePCINT2Interrupts )
533+ default :
534+ return ErrInvalidInputPin
535+ }
536+
537+ return nil
538+ }
539+
540+ var pinCallbacks [3 ][8 ][2 ]func (Pin )
541+ var pinStates [3 ]uint8
542+
543+ func handlePCINTInterrupts (intr uint8 , port * volatile.Register8 ) {
544+ current := port .Get ()
545+ change := pinStates [intr ] ^ current
546+ pinStates [intr ] = current
547+ for i := uint8 (0 ); i < 8 ; i ++ {
548+ if (change >> i )& 0x01 != 0x01 {
549+ continue
550+ }
551+ pin := Pin (intr * 8 + i )
552+ value := pin .Get ()
553+ if value && pinCallbacks [intr ][i ][0 ] != nil {
554+ pinCallbacks [intr ][i ][0 ](pin )
555+ }
556+ if ! value && pinCallbacks [intr ][i ][1 ] != nil {
557+ pinCallbacks [intr ][i ][1 ](pin )
558+ }
559+ }
560+ }
561+
562+ func handlePCINT0Interrupts (intr interrupt.Interrupt ) {
563+ handlePCINTInterrupts (0 , avr .PINB )
564+ }
565+
566+ func handlePCINT1Interrupts (intr interrupt.Interrupt ) {
567+ handlePCINTInterrupts (1 , avr .PINC )
568+ }
569+
570+ func handlePCINT2Interrupts (intr interrupt.Interrupt ) {
571+ handlePCINTInterrupts (2 , avr .PIND )
572+ }
0 commit comments