2020-10-22 07:04 PM
As an exploration into MCUs I'm doing everything as close to "deserted island" as I can and using assembly instead of the HAL and all that, but I'm having an issue. I was following in general this tutorial and just setting the registers as needed, but as soon as I unmask the interrupt it gets into the handler (configuring falling vs rising makes no difference). And no matter what I do it keeps firing. I tried polling first before this and it worked with no issues, so I know the configs are right. And if I change EXTI to trigger on PC12 which isn't connected there's no issues, just doesn't fire. And the schematic shows a 100k pulldown which I suppose is fairly weak but should be strong enough I'd think, so I didn't bother with more pulldowns in the config (again, this worked for polling).
I've checked with my multimeter for 0v when not pressed, 3.3v when pressed. I saw that there's a big issue with clearing the EXTI PR's bit at the end of the handler so I read it back a few times, put in a dmb instruction (saw that somewhere), and I'm updating a variable after. No matter what I do, the PR register stays the same. The only thing that's gotten it to not stay is if I clear the FTSR/RTSR and then clear the PR, but once I re-enable it goes back on. I've tried clearing the pending bit in the NVIC, which works for a few instructions then pops me back into the handler. I'm at such a loss. I'll put my interrupt and IRQ code:
//............. other configuration, including RCC enabling SYSCFG and GPIOC
// setup SYSCFG's EXTICR4 (page 592)
ldr r3, =SYSCFG_BASE
ldr r0, [r3, #EXTICR4]
bic r0, #0x00F0
orr r0, #0x0020
str r0, [r3, #EXTICR4]
// setup EXTI. Note that the event number here is 13
ldr r3, =EXTI_BASE
ldr r0, [r3] // EXTI_RTSR1
orr r0, #(1 << BITn)
str r0, [r3]
ldr r0, [r3, #0x4] // EXTI_FTSR1
bic r0, #(1 << BITn)
str r0, [r3, #0x4]
ldr r0, [r3, #0x80] // EXTI_CPUIMR1 (C1IMR1 in manual)
orr r0, #(1 << BITn)
str r0, [r3, #0x80]
// setup NVIC priority and enable, EXTI10_15 is NVIC 40
ldr r3, =NVIC_BASE
ldr r0, [r3, #0x4]
orr r0, #(1 << (40 - 32))
str r0, [r3, #0x4]
ldr r0, [r3, #0x328] // priority reister 10, first position, set to 0x10?
orr r0, #0x10
str r0, [r3, #0x328]
bx lr
.global EXTI15_10_IRQHandler
.thumb_func
EXTI15_10_IRQHandler:
ldr r3, =EXTI_BASE
ldr r0, [r3, #0x88] // EXTIC1PR1
// check if the correct bit fired
tst r0, #(1 << BITn)
it eq
// if it wasn't (mentally this should be ne but it works out to eq)
// branch out
bxeq lr
// was indeed our interrupt
// need to ACK it
mov r0, #(1 << BITn)
str r0, [r3, #0x88]
// clear in NVIC?
ldr r3, =NVIC_BASE
mov r0, #(1 << (40 - 32))
str r0, [r3, #0x184]
// toggle state
ldr r3, =state
ldr r0, [r3]
eor r0, #0b1
str r0, [r3]
bx lr
BITn = 13 because the button is on PC13. I've checked that the addresses are correct. I've written a 1 and a 0 to the PR. Writing 0 seemed to change it for a tiny bit but that's it, and also that's not how it's supposed to work.