avr: pin change interrupt
Этот коммит содержится в:
родитель
01d2ef327d
коммит
00d46bd25d
7 изменённых файлов: 120 добавлений и 2 удалений
11
src/examples/pininterrupt/arduino.go
Обычный файл
11
src/examples/pininterrupt/arduino.go
Обычный файл
|
@ -0,0 +1,11 @@
|
|||
//go:build arduino
|
||||
|
||||
package main
|
||||
|
||||
import "machine"
|
||||
|
||||
const (
|
||||
button = machine.D2
|
||||
buttonMode = machine.PinInputPullup
|
||||
buttonPinChange = machine.PinRising
|
||||
)
|
|
@ -5,6 +5,7 @@ package main
|
|||
import "machine"
|
||||
|
||||
const (
|
||||
button = machine.BUTTON
|
||||
buttonMode = machine.PinInputPulldown
|
||||
buttonPinChange = machine.PinFalling
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ package main
|
|||
import "machine"
|
||||
|
||||
const (
|
||||
button = machine.BUTTON
|
||||
buttonMode = machine.PinInputPullup
|
||||
buttonPinChange = machine.PinRising
|
||||
)
|
||||
|
|
|
@ -12,8 +12,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
button = machine.BUTTON
|
||||
led = machine.LED
|
||||
led = machine.LED
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
|
@ -5,6 +5,7 @@ package main
|
|||
import "machine"
|
||||
|
||||
const (
|
||||
button = machine.BUTTON
|
||||
buttonMode = machine.PinInputPulldown
|
||||
buttonPinChange = machine.PinRising | machine.PinFalling
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ package main
|
|||
import "machine"
|
||||
|
||||
const (
|
||||
button = machine.BUTTON
|
||||
buttonMode = machine.PinInput
|
||||
buttonPinChange = machine.PinFalling
|
||||
)
|
||||
|
|
|
@ -466,3 +466,107 @@ var SPI0 = SPI{
|
|||
sdo: PB3,
|
||||
sdi: PB4,
|
||||
cs: PB2}
|
||||
|
||||
// Pin Change Interrupts
|
||||
type PinChange uint8
|
||||
|
||||
const (
|
||||
PinRising PinChange = 1 << iota
|
||||
PinFalling
|
||||
PinToggle = PinRising | PinFalling
|
||||
)
|
||||
|
||||
func (pin Pin) SetInterrupt(pinChange PinChange, callback func(Pin)) (err error) {
|
||||
|
||||
switch {
|
||||
case pin >= PB0 && pin <= PB7:
|
||||
// PCMSK0 - PCINT0-7
|
||||
pinStates[0] = avr.PINB.Get()
|
||||
pinIndex := pin - PB0
|
||||
if pinChange&PinRising > 0 {
|
||||
pinCallbacks[0][pinIndex][0] = callback
|
||||
}
|
||||
if pinChange&PinFalling > 0 {
|
||||
pinCallbacks[0][pinIndex][1] = callback
|
||||
}
|
||||
if callback != nil {
|
||||
avr.PCMSK0.SetBits(1 << pinIndex)
|
||||
} else {
|
||||
avr.PCMSK0.ClearBits(1 << pinIndex)
|
||||
}
|
||||
avr.PCICR.SetBits(avr.PCICR_PCIE0)
|
||||
interrupt.New(avr.IRQ_PCINT0, handlePCINT0Interrupts)
|
||||
case pin >= PC0 && pin <= PC7:
|
||||
// PCMSK1 - PCINT8-14
|
||||
pinStates[1] = avr.PINC.Get()
|
||||
pinIndex := pin - PC0
|
||||
if pinChange&PinRising > 0 {
|
||||
pinCallbacks[1][pinIndex][0] = callback
|
||||
}
|
||||
if pinChange&PinFalling > 0 {
|
||||
pinCallbacks[1][pinIndex][1] = callback
|
||||
}
|
||||
if callback != nil {
|
||||
avr.PCMSK1.SetBits(1 << pinIndex)
|
||||
} else {
|
||||
avr.PCMSK1.ClearBits(1 << pinIndex)
|
||||
}
|
||||
avr.PCICR.SetBits(avr.PCICR_PCIE1)
|
||||
interrupt.New(avr.IRQ_PCINT1, handlePCINT1Interrupts)
|
||||
case pin >= PD0 && pin <= PD7:
|
||||
// PCMSK2 - PCINT16-23
|
||||
pinStates[2] = avr.PIND.Get()
|
||||
pinIndex := pin - PD0
|
||||
if pinChange&PinRising > 0 {
|
||||
pinCallbacks[2][pinIndex][0] = callback
|
||||
}
|
||||
if pinChange&PinFalling > 0 {
|
||||
pinCallbacks[2][pinIndex][1] = callback
|
||||
}
|
||||
if callback != nil {
|
||||
avr.PCMSK2.SetBits(1 << pinIndex)
|
||||
} else {
|
||||
avr.PCMSK2.ClearBits(1 << pinIndex)
|
||||
}
|
||||
avr.PCICR.SetBits(avr.PCICR_PCIE2)
|
||||
interrupt.New(avr.IRQ_PCINT2, handlePCINT2Interrupts)
|
||||
default:
|
||||
return ErrInvalidInputPin
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var pinCallbacks [3][8][2]func(Pin)
|
||||
var pinStates [3]uint8
|
||||
|
||||
func handlePCINTInterrupts(intr uint8, port *volatile.Register8) {
|
||||
current := port.Get()
|
||||
change := pinStates[intr] ^ current
|
||||
pinStates[intr] = current
|
||||
for i := uint8(0); i < 8; i++ {
|
||||
if (change>>i)&0x01 != 0x01 {
|
||||
continue
|
||||
}
|
||||
pin := Pin(intr*8 + i)
|
||||
value := pin.Get()
|
||||
if value && pinCallbacks[intr][i][0] != nil {
|
||||
pinCallbacks[intr][i][0](pin)
|
||||
}
|
||||
if !value && pinCallbacks[intr][i][1] != nil {
|
||||
pinCallbacks[intr][i][1](pin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handlePCINT0Interrupts(intr interrupt.Interrupt) {
|
||||
handlePCINTInterrupts(0, avr.PINB)
|
||||
}
|
||||
|
||||
func handlePCINT1Interrupts(intr interrupt.Interrupt) {
|
||||
handlePCINTInterrupts(1, avr.PINC)
|
||||
}
|
||||
|
||||
func handlePCINT2Interrupts(intr interrupt.Interrupt) {
|
||||
handlePCINTInterrupts(2, avr.PIND)
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче