stm32: support pin input interrupts
Этот коммит содержится в:
родитель
c017ed2242
коммит
5f9e339cf3
16 изменённых файлов: 527 добавлений и 0 удалений
10
src/examples/pininterrupt/stm32.go
Обычный файл
10
src/examples/pininterrupt/stm32.go
Обычный файл
|
@ -0,0 +1,10 @@
|
|||
// +build stm32
|
||||
|
||||
package main
|
||||
|
||||
import "machine"
|
||||
|
||||
const (
|
||||
buttonMode = machine.PinInputPulldown
|
||||
buttonPinChange = machine.PinRising | machine.PinFalling
|
||||
)
|
|
@ -11,6 +11,12 @@ const (
|
|||
LED = PC13
|
||||
)
|
||||
|
||||
const (
|
||||
// This board does not have a user button, so
|
||||
// use first GPIO pin by default
|
||||
BUTTON = PA0
|
||||
)
|
||||
|
||||
var Serial = UART1
|
||||
|
||||
// UART pins
|
||||
|
|
|
@ -13,6 +13,12 @@ const (
|
|||
LED_GREEN = PB3
|
||||
)
|
||||
|
||||
const (
|
||||
// This board does not have a user button, so
|
||||
// use first GPIO pin by default
|
||||
BUTTON = PA0
|
||||
)
|
||||
|
||||
const (
|
||||
// Arduino Pins
|
||||
A0 = PA0 // ADC_IN0
|
||||
|
|
|
@ -13,6 +13,12 @@ const (
|
|||
LED_GREEN = PB3
|
||||
)
|
||||
|
||||
const (
|
||||
// This board does not have a user button, so
|
||||
// use first GPIO pin by default
|
||||
BUTTON = PA0
|
||||
)
|
||||
|
||||
const (
|
||||
// Arduino Pins
|
||||
A0 = PA0
|
||||
|
|
|
@ -20,6 +20,10 @@ const (
|
|||
LED_BLUE = PD15
|
||||
)
|
||||
|
||||
const (
|
||||
BUTTON = PA0
|
||||
)
|
||||
|
||||
// UART pins
|
||||
const (
|
||||
UART_TX_PIN = PA2
|
||||
|
|
|
@ -31,6 +31,13 @@ const (
|
|||
// Also, the stm32f1xx series handles things differently from the stm32f0/2/3/4
|
||||
|
||||
// ---------- General pin operations ----------
|
||||
type PinChange uint8
|
||||
|
||||
const (
|
||||
PinRising PinChange = 1 << iota
|
||||
PinFalling
|
||||
PinToggle = PinRising | PinFalling
|
||||
)
|
||||
|
||||
// Set the pin to high or low.
|
||||
// Warning: only use this on an output pin!
|
||||
|
|
27
src/machine/machine_stm32_exti_afio.go
Обычный файл
27
src/machine/machine_stm32_exti_afio.go
Обычный файл
|
@ -0,0 +1,27 @@
|
|||
// +build stm32f1
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
func getEXTIConfigRegister(pin uint8) *volatile.Register32 {
|
||||
switch (pin & 0xf) / 4 {
|
||||
case 0:
|
||||
return &stm32.AFIO.EXTICR1
|
||||
case 1:
|
||||
return &stm32.AFIO.EXTICR2
|
||||
case 2:
|
||||
return &stm32.AFIO.EXTICR3
|
||||
case 3:
|
||||
return &stm32.AFIO.EXTICR4
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableEXTIConfigRegisters() {
|
||||
// Enable AFIO
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_AFIOEN)
|
||||
}
|
26
src/machine/machine_stm32_exti_exti.go
Обычный файл
26
src/machine/machine_stm32_exti_exti.go
Обычный файл
|
@ -0,0 +1,26 @@
|
|||
// +build stm32l5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
func getEXTIConfigRegister(pin uint8) *volatile.Register32 {
|
||||
switch (pin & 0xf) / 4 {
|
||||
case 0:
|
||||
return &stm32.EXTI.EXTICR1
|
||||
case 1:
|
||||
return &stm32.EXTI.EXTICR2
|
||||
case 2:
|
||||
return &stm32.EXTI.EXTICR3
|
||||
case 3:
|
||||
return &stm32.EXTI.EXTICR4
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableEXTIConfigRegisters() {
|
||||
// No-op
|
||||
}
|
27
src/machine/machine_stm32_exti_syscfg.go
Обычный файл
27
src/machine/machine_stm32_exti_syscfg.go
Обычный файл
|
@ -0,0 +1,27 @@
|
|||
// +build stm32,!stm32f1,!stm32l5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
func getEXTIConfigRegister(pin uint8) *volatile.Register32 {
|
||||
switch (pin & 0xf) / 4 {
|
||||
case 0:
|
||||
return &stm32.SYSCFG.EXTICR1
|
||||
case 1:
|
||||
return &stm32.SYSCFG.EXTICR2
|
||||
case 2:
|
||||
return &stm32.SYSCFG.EXTICR3
|
||||
case 3:
|
||||
return &stm32.SYSCFG.EXTICR4
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func enableEXTIConfigRegisters() {
|
||||
// Enable SYSCFG
|
||||
stm32.RCC.APB2ENR.SetBits(stm32.RCC_APB2ENR_SYSCFGEN)
|
||||
}
|
92
src/machine/machine_stm32_gpio_reva.go
Обычный файл
92
src/machine/machine_stm32_gpio_reva.go
Обычный файл
|
@ -0,0 +1,92 @@
|
|||
// +build stm32,!stm32l4,!stm32l5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
)
|
||||
|
||||
// This variant of the GPIO input interrupt logic is for
|
||||
// chips with a smaller number of interrupt channels
|
||||
// (that fits in a single register).
|
||||
|
||||
//
|
||||
// STM32 allows one interrupt source per pin number, with
|
||||
// the same pin number in different ports sharing a single
|
||||
// interrupt source (so PA0, PB0, PC0 all share). Only a
|
||||
// single physical pin can be connected to each interrupt
|
||||
// line.
|
||||
//
|
||||
// To call interrupt callbacks, we record here for each
|
||||
// pin number the callback and the actual associated pin.
|
||||
//
|
||||
|
||||
// Callbacks for pin interrupt events
|
||||
var pinCallbacks [16]func(Pin)
|
||||
|
||||
// The pin currently associated with interrupt callback
|
||||
// for a given slot.
|
||||
var interruptPins [16]Pin
|
||||
|
||||
// SetInterrupt sets an interrupt to be executed when a particular pin changes
|
||||
// state. The pin should already be configured as an input, including a pull up
|
||||
// or down if no external pull is provided.
|
||||
//
|
||||
// This call will replace a previously set callback on this pin. You can pass a
|
||||
// nil func to unset the pin change interrupt. If you do so, the change
|
||||
// parameter is ignored and can be set to any value (such as 0).
|
||||
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
|
||||
port := uint32(uint8(p) / 16)
|
||||
pin := uint8(p) % 16
|
||||
|
||||
enableEXTIConfigRegisters()
|
||||
|
||||
if callback == nil {
|
||||
stm32.EXTI.IMR.ClearBits(1 << pin)
|
||||
pinCallbacks[pin] = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
if pinCallbacks[pin] != nil {
|
||||
// The pin was already configured.
|
||||
// To properly re-configure a pin, unset it first and set a new
|
||||
// configuration.
|
||||
return ErrNoPinChangeChannel
|
||||
}
|
||||
|
||||
// Set the callback now (before the interrupt is enabled) to avoid
|
||||
// possible race condition
|
||||
pinCallbacks[pin] = callback
|
||||
interruptPins[pin] = p
|
||||
|
||||
crReg := getEXTIConfigRegister(pin)
|
||||
shift := (pin & 0x3) * 4
|
||||
crReg.ReplaceBits(port, 0xf, shift)
|
||||
|
||||
if (change & PinRising) != 0 {
|
||||
stm32.EXTI.RTSR.SetBits(1 << pin)
|
||||
}
|
||||
if (change & PinFalling) != 0 {
|
||||
stm32.EXTI.FTSR.SetBits(1 << pin)
|
||||
}
|
||||
stm32.EXTI.IMR.SetBits(1 << pin)
|
||||
|
||||
intr := p.registerInterrupt()
|
||||
intr.SetPriority(0)
|
||||
intr.Enable()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePinInterrupt(pin uint8) {
|
||||
if stm32.EXTI.PR.HasBits(1 << pin) {
|
||||
// Writing 1 to the pending register clears the
|
||||
// pending flag for that bit
|
||||
stm32.EXTI.PR.Set(1 << pin)
|
||||
|
||||
callback := pinCallbacks[pin]
|
||||
if callback != nil {
|
||||
callback(interruptPins[pin])
|
||||
}
|
||||
}
|
||||
}
|
79
src/machine/machine_stm32_gpio_revb.go
Обычный файл
79
src/machine/machine_stm32_gpio_revb.go
Обычный файл
|
@ -0,0 +1,79 @@
|
|||
// +build stm32l4 stm32l5
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
)
|
||||
|
||||
// This variant of the GPIO input interrupt logic is for
|
||||
// chips with a larger number of interrupt channels (more
|
||||
// than fits in a single register).
|
||||
|
||||
//
|
||||
// STM32 allows one interrupt source per pin number, with
|
||||
// the same pin number in different ports sharing a single
|
||||
// interrupt source (so PA0, PB0, PC0 all share). Only a
|
||||
// single physical pin can be connected to each interrupt
|
||||
// line.
|
||||
//
|
||||
// To call interrupt callbacks, we record here for each
|
||||
// pin number the callback and the actual associated pin.
|
||||
//
|
||||
|
||||
// Callbacks for pin interrupt events
|
||||
var pinCallbacks [16]func(Pin)
|
||||
|
||||
// The pin currently associated with interrupt callback
|
||||
// for a given slot.
|
||||
var interruptPins [16]Pin
|
||||
|
||||
// SetInterrupt sets an interrupt to be executed when a particular pin changes
|
||||
// state. The pin should already be configured as an input, including a pull up
|
||||
// or down if no external pull is provided.
|
||||
//
|
||||
// This call will replace a previously set callback on this pin. You can pass a
|
||||
// nil func to unset the pin change interrupt. If you do so, the change
|
||||
// parameter is ignored and can be set to any value (such as 0).
|
||||
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
|
||||
port := uint32(uint8(p) / 16)
|
||||
pin := uint8(p) % 16
|
||||
|
||||
enableEXTIConfigRegisters()
|
||||
|
||||
if callback == nil {
|
||||
stm32.EXTI.IMR1.ClearBits(1 << pin)
|
||||
pinCallbacks[pin] = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
if pinCallbacks[pin] != nil {
|
||||
// The pin was already configured.
|
||||
// To properly re-configure a pin, unset it first and set a new
|
||||
// configuration.
|
||||
return ErrNoPinChangeChannel
|
||||
}
|
||||
|
||||
// Set the callback now (before the interrupt is enabled) to avoid
|
||||
// possible race condition
|
||||
pinCallbacks[pin] = callback
|
||||
interruptPins[pin] = p
|
||||
|
||||
crReg := getEXTIConfigRegister(pin)
|
||||
shift := (pin & 0x3) * 4
|
||||
crReg.ReplaceBits(port, 0xf, shift)
|
||||
|
||||
if (change & PinRising) != 0 {
|
||||
stm32.EXTI.RTSR1.SetBits(1 << pin)
|
||||
}
|
||||
if (change & PinFalling) != 0 {
|
||||
stm32.EXTI.FTSR1.SetBits(1 << pin)
|
||||
}
|
||||
stm32.EXTI.IMR1.SetBits(1 << pin)
|
||||
|
||||
intr := p.registerInterrupt()
|
||||
intr.SetPriority(0)
|
||||
intr.Enable()
|
||||
|
||||
return nil
|
||||
}
|
|
@ -200,6 +200,47 @@ func (p Pin) enableClock() {
|
|||
}
|
||||
}
|
||||
|
||||
func (p Pin) registerInterrupt() interrupt.Interrupt {
|
||||
pin := uint8(p) % 16
|
||||
|
||||
switch pin {
|
||||
case 0:
|
||||
return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) })
|
||||
case 1:
|
||||
return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
|
||||
case 2:
|
||||
return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) })
|
||||
case 3:
|
||||
return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
|
||||
case 4:
|
||||
return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) })
|
||||
case 5:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
||||
case 6:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
||||
case 7:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
||||
case 8:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
||||
case 9:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
||||
case 10:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
||||
case 11:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
||||
case 12:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
||||
case 13:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
||||
case 14:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
||||
case 15:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
// Enable peripheral clock
|
||||
func enableAltFuncClock(bus unsafe.Pointer) {
|
||||
switch bus {
|
||||
|
|
|
@ -309,6 +309,47 @@ func enableAltFuncClock(bus unsafe.Pointer) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p Pin) registerInterrupt() interrupt.Interrupt {
|
||||
pin := uint8(p) % 16
|
||||
|
||||
switch pin {
|
||||
case 0:
|
||||
return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) })
|
||||
case 1:
|
||||
return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
|
||||
case 2:
|
||||
return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) })
|
||||
case 3:
|
||||
return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
|
||||
case 4:
|
||||
return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) })
|
||||
case 5:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
||||
case 6:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
||||
case 7:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
||||
case 8:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
||||
case 9:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
||||
case 10:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
||||
case 11:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
||||
case 12:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
||||
case 13:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
||||
case 14:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
||||
case 15:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
//---------- Timer related code
|
||||
|
||||
var (
|
||||
|
|
|
@ -6,6 +6,7 @@ package machine
|
|||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
func CPUFrequency() uint32 {
|
||||
|
@ -147,6 +148,47 @@ func (p Pin) enableClock() {
|
|||
}
|
||||
}
|
||||
|
||||
func (p Pin) registerInterrupt() interrupt.Interrupt {
|
||||
pin := uint8(p) % 16
|
||||
|
||||
switch pin {
|
||||
case 0:
|
||||
return interrupt.New(stm32.IRQ_EXTI0_1, func(interrupt.Interrupt) { handlePinInterrupt(0) })
|
||||
case 1:
|
||||
return interrupt.New(stm32.IRQ_EXTI0_1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
|
||||
case 2:
|
||||
return interrupt.New(stm32.IRQ_EXTI2_3, func(interrupt.Interrupt) { handlePinInterrupt(2) })
|
||||
case 3:
|
||||
return interrupt.New(stm32.IRQ_EXTI2_3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
|
||||
case 4:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(4) })
|
||||
case 5:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
||||
case 6:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
||||
case 7:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
||||
case 8:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
||||
case 9:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
||||
case 10:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
||||
case 11:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
||||
case 12:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
||||
case 13:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
||||
case 14:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
||||
case 15:
|
||||
return interrupt.New(stm32.IRQ_EXTI4_15, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
//---------- UART related types and code
|
||||
|
||||
// Configure the UART.
|
||||
|
|
|
@ -203,6 +203,60 @@ func enableAltFuncClock(bus unsafe.Pointer) {
|
|||
}
|
||||
}
|
||||
|
||||
func handlePinInterrupt(pin uint8) {
|
||||
if stm32.EXTI.PR1.HasBits(1 << pin) {
|
||||
// Writing 1 to the pending register clears the
|
||||
// pending flag for that bit
|
||||
stm32.EXTI.PR1.Set(1 << pin)
|
||||
|
||||
callback := pinCallbacks[pin]
|
||||
if callback != nil {
|
||||
callback(interruptPins[pin])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p Pin) registerInterrupt() interrupt.Interrupt {
|
||||
pin := uint8(p) % 16
|
||||
|
||||
switch pin {
|
||||
case 0:
|
||||
return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) })
|
||||
case 1:
|
||||
return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
|
||||
case 2:
|
||||
return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) })
|
||||
case 3:
|
||||
return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
|
||||
case 4:
|
||||
return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) })
|
||||
case 5:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
||||
case 6:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
||||
case 7:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
||||
case 8:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
||||
case 9:
|
||||
return interrupt.New(stm32.IRQ_EXTI9_5, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
||||
case 10:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
||||
case 11:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
||||
case 12:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
||||
case 13:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
||||
case 14:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
||||
case 15:
|
||||
return interrupt.New(stm32.IRQ_EXTI15_10, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
//---------- SPI related types and code
|
||||
|
||||
// SPI on the STM32Fxxx using MODER / alternate function pins
|
||||
|
|
|
@ -271,6 +271,65 @@ func enableAltFuncClock(bus unsafe.Pointer) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p Pin) registerInterrupt() interrupt.Interrupt {
|
||||
pin := uint8(p) % 16
|
||||
|
||||
switch pin {
|
||||
case 0:
|
||||
return interrupt.New(stm32.IRQ_EXTI0, func(interrupt.Interrupt) { handlePinInterrupt(0) })
|
||||
case 1:
|
||||
return interrupt.New(stm32.IRQ_EXTI1, func(interrupt.Interrupt) { handlePinInterrupt(1) })
|
||||
case 2:
|
||||
return interrupt.New(stm32.IRQ_EXTI2, func(interrupt.Interrupt) { handlePinInterrupt(2) })
|
||||
case 3:
|
||||
return interrupt.New(stm32.IRQ_EXTI3, func(interrupt.Interrupt) { handlePinInterrupt(3) })
|
||||
case 4:
|
||||
return interrupt.New(stm32.IRQ_EXTI4, func(interrupt.Interrupt) { handlePinInterrupt(4) })
|
||||
case 5:
|
||||
return interrupt.New(stm32.IRQ_EXTI5, func(interrupt.Interrupt) { handlePinInterrupt(5) })
|
||||
case 6:
|
||||
return interrupt.New(stm32.IRQ_EXTI6, func(interrupt.Interrupt) { handlePinInterrupt(6) })
|
||||
case 7:
|
||||
return interrupt.New(stm32.IRQ_EXTI7, func(interrupt.Interrupt) { handlePinInterrupt(7) })
|
||||
case 8:
|
||||
return interrupt.New(stm32.IRQ_EXTI8, func(interrupt.Interrupt) { handlePinInterrupt(8) })
|
||||
case 9:
|
||||
return interrupt.New(stm32.IRQ_EXTI9, func(interrupt.Interrupt) { handlePinInterrupt(9) })
|
||||
case 10:
|
||||
return interrupt.New(stm32.IRQ_EXTI10, func(interrupt.Interrupt) { handlePinInterrupt(10) })
|
||||
case 11:
|
||||
return interrupt.New(stm32.IRQ_EXTI11, func(interrupt.Interrupt) { handlePinInterrupt(11) })
|
||||
case 12:
|
||||
return interrupt.New(stm32.IRQ_EXTI12, func(interrupt.Interrupt) { handlePinInterrupt(12) })
|
||||
case 13:
|
||||
return interrupt.New(stm32.IRQ_EXTI13, func(interrupt.Interrupt) { handlePinInterrupt(13) })
|
||||
case 14:
|
||||
return interrupt.New(stm32.IRQ_EXTI14, func(interrupt.Interrupt) { handlePinInterrupt(14) })
|
||||
case 15:
|
||||
return interrupt.New(stm32.IRQ_EXTI15, func(interrupt.Interrupt) { handlePinInterrupt(15) })
|
||||
}
|
||||
|
||||
return interrupt.Interrupt{}
|
||||
}
|
||||
|
||||
func handlePinInterrupt(pin uint8) {
|
||||
// The pin abstraction doesn't differentiate pull-up
|
||||
// events from pull-down events, so combine them to
|
||||
// a single call here.
|
||||
|
||||
if stm32.EXTI.RPR1.HasBits(1<<pin) || stm32.EXTI.FPR1.HasBits(1<<pin) {
|
||||
// Writing 1 to the pending register clears the
|
||||
// pending flag for that bit
|
||||
stm32.EXTI.RPR1.Set(1 << pin)
|
||||
stm32.EXTI.FPR1.Set(1 << pin)
|
||||
|
||||
callback := pinCallbacks[pin]
|
||||
if callback != nil {
|
||||
callback(interruptPins[pin])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------- Timer related code
|
||||
|
||||
var (
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче