Skip to content

Commit 8a5ab5a

Browse files
kenbelldeadprogram
authored andcommitted
rp2040: fix gpio interrupts
1 parent 77cf60e commit 8a5ab5a

File tree

1 file changed

+25
-30
lines changed

1 file changed

+25
-30
lines changed

src/machine/machine_rp2040_gpio.go

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ type io struct {
1717

1818
type irqCtrl struct {
1919
intE [4]volatile.Register32
20-
intS [4]volatile.Register32
2120
intF [4]volatile.Register32
21+
intS [4]volatile.Register32
2222
}
2323

2424
type ioBank0Type struct {
@@ -237,8 +237,8 @@ const (
237237

238238
// Callbacks to be called for pins configured with SetInterrupt.
239239
var (
240-
pinCallbacks [2]func(Pin)
241-
setInt [2]bool
240+
pinCallbacks [2][_NUMBANK0_GPIOS]func(Pin)
241+
setInt [2][_NUMBANK0_GPIOS]bool
242242
)
243243

244244
// SetInterrupt sets an interrupt to be executed when a particular pin changes
@@ -256,20 +256,19 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
256256
if callback == nil {
257257
// disable current interrupt
258258
p.setInterrupt(change, false)
259-
pinCallbacks[core] = nil
259+
pinCallbacks[core][p] = nil
260260
return nil
261261
}
262262

263-
if pinCallbacks[core] != nil {
263+
if pinCallbacks[core][p] != nil {
264264
// Callback already configured. Should disable callback by passing a nil callback first.
265265
return ErrNoPinChangeChannel
266266
}
267267
p.setInterrupt(change, true)
268-
pinCallbacks[core] = callback
268+
pinCallbacks[core][p] = callback
269269

270-
if setInt[core] {
270+
if setInt[core][p] {
271271
// interrupt has already been set. Exit.
272-
println("core set")
273272
return nil
274273
}
275274
interrupt.New(rp.IRQ_IO_IRQ_BANK0, gpioHandleInterrupt).Enable()
@@ -280,31 +279,27 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
280279
// gpioHandleInterrupt finds the corresponding pin for the interrupt.
281280
// C SDK equivalent of gpio_irq_handler
282281
func gpioHandleInterrupt(intr interrupt.Interrupt) {
283-
// panic("END") // if program is not ended here rp2040 will call interrupt again when finished, a vicious spin cycle.
282+
284283
core := CurrentCore()
285-
callback := pinCallbacks[core]
286-
if callback != nil {
287-
// TODO fix gpio acquisition (see below)
288-
// For now all callbacks get pin 255 (nonexistent).
289-
callback(0xff)
290-
}
291284
var gpio Pin
292285
for gpio = 0; gpio < _NUMBANK0_GPIOS; gpio++ {
293-
// Acknowledge all GPIO interrupts for now
294-
// since we are yet unable to acquire interrupt status
295-
gpio.acknowledgeInterrupt(0xff) // TODO fix status get. For now we acknowledge all pending interrupts.
296-
// Commented code below from C SDK not working.
297-
// statreg := base.intS[gpio>>3]
298-
// change := getIntChange(gpio, statreg.Get())
299-
// if change != 0 {
300-
// gpio.acknowledgeInterrupt(change)
301-
// if callback != nil {
302-
// callback(gpio)
303-
// return
304-
// } else {
305-
// panic("unset callback in handler")
306-
// }
307-
// }
286+
var base *irqCtrl
287+
switch core {
288+
case 0:
289+
base = &ioBank0.proc0IRQctrl
290+
case 1:
291+
base = &ioBank0.proc1IRQctrl
292+
}
293+
294+
statreg := base.intS[gpio>>3]
295+
change := getIntChange(gpio, statreg.Get())
296+
if change != 0 {
297+
gpio.acknowledgeInterrupt(change)
298+
callback := pinCallbacks[core][gpio]
299+
if callback != nil {
300+
callback(gpio)
301+
}
302+
}
308303
}
309304
}
310305

0 commit comments

Comments
 (0)