maixbit: add GPIOHS pin interrupt support

Этот коммит содержится в:
Yannis Huber 2020-06-25 14:37:12 +02:00 коммит произвёл Ron Evans
родитель 53c83fa445
коммит 5446c6927e
2 изменённых файлов: 183 добавлений и 2 удалений

Просмотреть файл

@ -12,6 +12,8 @@ func CPUFrequency() uint32 {
}
type PinMode uint8
type fpioaPullMode uint8
type PinChange uint8
const (
PinInput PinMode = iota
@ -20,14 +22,20 @@ const (
PinOutput
)
type fpioaPullMode uint8
const (
fpioaPullNone fpioaPullMode = iota
fpioaPullDown
fpioaPullUp
)
const (
PinRising PinChange = iota + 1
PinFalling
PinToggle
PinHigh
PinLow = 8
)
func (p Pin) fpioaSetIOPull(pull fpioaPullMode) {
switch pull {
case fpioaPullNone:
@ -122,6 +130,174 @@ func (p Pin) Get() bool {
return (val > 0)
}
// Callbacks to be called for GPIOHS pins configured with SetInterrupt.
var pinCallbacks [32]func(Pin)
// SetInterrupt sets an interrupt to be executed when a particular pin changes
// state.
//
// 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).
// If the pin is already configured with a callback, you must first unset
// this pins interrupt before you can set a new callback.
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
// Check if the pin is a GPIOHS pin.
if p < P16 && p > P47 {
return ErrInvalidDataPin
}
gpioPin := uint8(p) - 16
// Clear all interrupts.
kendryte.GPIOHS.RISE_IE.ClearBits(1 << gpioPin)
kendryte.GPIOHS.FALL_IE.ClearBits(1 << gpioPin)
kendryte.GPIOHS.HIGH_IE.ClearBits(1 << gpioPin)
kendryte.GPIOHS.LOW_IE.ClearBits(1 << gpioPin)
// Clear all the pending bits for this pin.
kendryte.GPIOHS.RISE_IP.SetBits(1 << gpioPin)
kendryte.GPIOHS.FALL_IP.SetBits(1 << gpioPin)
kendryte.GPIOHS.HIGH_IP.SetBits(1 << gpioPin)
kendryte.GPIOHS.LOW_IP.SetBits(1 << gpioPin)
if callback == nil {
if pinCallbacks[gpioPin] != nil {
pinCallbacks[gpioPin] = nil
}
return nil
}
if pinCallbacks[gpioPin] != nil {
// The pin was already configured.
// To properly re-configure a pin, unset it first and set a new
// configuration.
return ErrNoPinChangeChannel
}
pinCallbacks[gpioPin] = callback
// Enable interrupts.
if change&PinRising != 0 {
kendryte.GPIOHS.RISE_IE.SetBits(1 << gpioPin)
}
if change&PinFalling != 0 {
kendryte.GPIOHS.FALL_IE.SetBits(1 << gpioPin)
}
if change&PinHigh != 0 {
kendryte.GPIOHS.HIGH_IE.SetBits(1 << gpioPin)
}
if change&PinLow != 0 {
kendryte.GPIOHS.LOW_IE.SetBits(1 << gpioPin)
}
handleInterrupt := func(inter interrupt.Interrupt) {
pin := uint8(inter.GetNumber() - kendryte.IRQ_GPIOHS0)
if kendryte.GPIOHS.RISE_IE.HasBits(1 << pin) {
kendryte.GPIOHS.RISE_IE.ClearBits(1 << pin)
kendryte.GPIOHS.RISE_IP.SetBits(1 << pin)
kendryte.GPIOHS.RISE_IE.SetBits(1 << pin)
}
if kendryte.GPIOHS.FALL_IE.HasBits(1 << pin) {
kendryte.GPIOHS.FALL_IE.ClearBits(1 << pin)
kendryte.GPIOHS.FALL_IP.SetBits(1 << pin)
kendryte.GPIOHS.FALL_IE.SetBits(1 << pin)
}
if kendryte.GPIOHS.HIGH_IE.HasBits(1 << pin) {
kendryte.GPIOHS.HIGH_IE.ClearBits(1 << pin)
kendryte.GPIOHS.HIGH_IP.SetBits(1 << pin)
kendryte.GPIOHS.HIGH_IE.SetBits(1 << pin)
}
if kendryte.GPIOHS.LOW_IE.HasBits(1 << pin) {
kendryte.GPIOHS.LOW_IE.ClearBits(1 << pin)
kendryte.GPIOHS.LOW_IP.SetBits(1 << pin)
kendryte.GPIOHS.LOW_IE.SetBits(1 << pin)
}
pinCallbacks[pin](Pin(pin))
}
var ir interrupt.Interrupt
switch p {
case P16:
ir = interrupt.New(kendryte.IRQ_GPIOHS0, handleInterrupt)
case P17:
ir = interrupt.New(kendryte.IRQ_GPIOHS1, handleInterrupt)
case P18:
ir = interrupt.New(kendryte.IRQ_GPIOHS2, handleInterrupt)
case P19:
ir = interrupt.New(kendryte.IRQ_GPIOHS3, handleInterrupt)
case P20:
ir = interrupt.New(kendryte.IRQ_GPIOHS4, handleInterrupt)
case P21:
ir = interrupt.New(kendryte.IRQ_GPIOHS5, handleInterrupt)
case P22:
ir = interrupt.New(kendryte.IRQ_GPIOHS6, handleInterrupt)
case P23:
ir = interrupt.New(kendryte.IRQ_GPIOHS7, handleInterrupt)
case P24:
ir = interrupt.New(kendryte.IRQ_GPIOHS8, handleInterrupt)
case P25:
ir = interrupt.New(kendryte.IRQ_GPIOHS9, handleInterrupt)
case P26:
ir = interrupt.New(kendryte.IRQ_GPIOHS10, handleInterrupt)
case P27:
ir = interrupt.New(kendryte.IRQ_GPIOHS11, handleInterrupt)
case P28:
ir = interrupt.New(kendryte.IRQ_GPIOHS12, handleInterrupt)
case P29:
ir = interrupt.New(kendryte.IRQ_GPIOHS13, handleInterrupt)
case P30:
ir = interrupt.New(kendryte.IRQ_GPIOHS14, handleInterrupt)
case P31:
ir = interrupt.New(kendryte.IRQ_GPIOHS15, handleInterrupt)
case P32:
ir = interrupt.New(kendryte.IRQ_GPIOHS16, handleInterrupt)
case P33:
ir = interrupt.New(kendryte.IRQ_GPIOHS17, handleInterrupt)
case P34:
ir = interrupt.New(kendryte.IRQ_GPIOHS18, handleInterrupt)
case P35:
ir = interrupt.New(kendryte.IRQ_GPIOHS19, handleInterrupt)
case P36:
ir = interrupt.New(kendryte.IRQ_GPIOHS20, handleInterrupt)
case P37:
ir = interrupt.New(kendryte.IRQ_GPIOHS21, handleInterrupt)
case P38:
ir = interrupt.New(kendryte.IRQ_GPIOHS22, handleInterrupt)
case P39:
ir = interrupt.New(kendryte.IRQ_GPIOHS23, handleInterrupt)
case P40:
ir = interrupt.New(kendryte.IRQ_GPIOHS24, handleInterrupt)
case P41:
ir = interrupt.New(kendryte.IRQ_GPIOHS25, handleInterrupt)
case P42:
ir = interrupt.New(kendryte.IRQ_GPIOHS26, handleInterrupt)
case P43:
ir = interrupt.New(kendryte.IRQ_GPIOHS27, handleInterrupt)
case P44:
ir = interrupt.New(kendryte.IRQ_GPIOHS28, handleInterrupt)
case P45:
ir = interrupt.New(kendryte.IRQ_GPIOHS29, handleInterrupt)
case P46:
ir = interrupt.New(kendryte.IRQ_GPIOHS30, handleInterrupt)
case P47:
ir = interrupt.New(kendryte.IRQ_GPIOHS31, handleInterrupt)
}
ir.SetPriority(5)
ir.Enable()
return nil
}
type UART struct {
Bus *kendryte.UARTHS_Type
Buffer *RingBuffer

Просмотреть файл

@ -20,3 +20,8 @@ func (irq Interrupt) Enable() {
func (irq Interrupt) SetPriority(priority uint8) {
kendryte.PLIC.PRIORITY[irq.num].Set(uint32(priority))
}
// GetNumber returns the interrupt number for this interrupt.
func (irq Interrupt) GetNumber() int {
return irq.num
}