Skip to content

Commit 00d46bd

Browse files
ysoldakdeadprogram
authored andcommitted
avr: pin change interrupt
1 parent 01d2ef3 commit 00d46bd

File tree

7 files changed

+120
-2
lines changed

7 files changed

+120
-2
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//go:build arduino
2+
3+
package main
4+
5+
import "machine"
6+
7+
const (
8+
button = machine.D2
9+
buttonMode = machine.PinInputPullup
10+
buttonPinChange = machine.PinRising
11+
)

src/examples/pininterrupt/circuitplay-express.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package main
55
import "machine"
66

77
const (
8+
button = machine.BUTTON
89
buttonMode = machine.PinInputPulldown
910
buttonPinChange = machine.PinFalling
1011
)

src/examples/pininterrupt/pca10040.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package main
55
import "machine"
66

77
const (
8+
button = machine.BUTTON
89
buttonMode = machine.PinInputPullup
910
buttonPinChange = machine.PinRising
1011
)

src/examples/pininterrupt/pininterrupt.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import (
1212
)
1313

1414
const (
15-
button = machine.BUTTON
16-
led = machine.LED
15+
led = machine.LED
1716
)
1817

1918
func main() {

src/examples/pininterrupt/stm32.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package main
55
import "machine"
66

77
const (
8+
button = machine.BUTTON
89
buttonMode = machine.PinInputPulldown
910
buttonPinChange = machine.PinRising | machine.PinFalling
1011
)

src/examples/pininterrupt/wioterminal.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package main
55
import "machine"
66

77
const (
8+
button = machine.BUTTON
89
buttonMode = machine.PinInput
910
buttonPinChange = machine.PinFalling
1011
)

src/machine/machine_atmega328p.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)