STM32F4 EXTI problem - Page 1
Forum section: electronics / general

author: Ribster
author_rank: Frequent Contributor
timestamp: July 29, 2014, 08:44:50 am
content: Hey everyone,I'm working on a project with the allknown nRF24L01+. I'm using an STM32F4-discovery to get my proof of concept working, connected with STLINK V2 via SWD.Software setup is eclipse with the C++ library from Andy's workshop with GDB.https://github.com/andysworkshop/stm32plus. Not that it matters, but some background..Issue:External Interrupts.Description:I've got the pushbutton(PA0) set-up as an EXTI-line, SPI via DMA to the nRF module, and the IRQ-pin from the nRF module also configured as EXTI, UART for printing to terminal.Sopheriperals used:2 EXTI, 1 SPI via DMA, UART, Systick Timer set to 1ms.Problem:So i'm setting everything up, and looping a string to the UART-bus.The moment i push the button on the PA0-line, the activity on the UART stops.I've set a breakpoint to my interrupt function, but it doesn't stop at the breakpoint.Solutions:I think the pointer reference became invalid. Maybe it was a heap-problem. Fixed it by putting the functions into the right place.EDIT: The PA EXTI interrupt is from an example so normally it works. I've got some peripheral compliancy issues is guess.. Is the Systick timer interrupting everything ?EDIT: Added the 'solution'. Quite dicky solution, but hey.Any help is welcome, also debugging-tips are welcome. For instance, how can you detect a hardfault failure via GDB&SWD ?

author: andersm
author_rank: Super Contributor
timestamp: July 29, 2014, 10:12:54 am
content: Quote from: Ribster on July 29, 2014, 08:44:50 amAn interrupt with a lower preemption priority can interrupt another with a higher preemption priority. Download ST'sCortex-M4 programming manualand read the chapters on exceptions, interrupts and the NVIC.QuoteInstall a default handler for all unused interrupts and exceptions, set a breakpoint there.

author: andyturk
author_rank: Frequent Contributor
timestamp: July 29, 2014, 03:37:05 pm
content: Double-check your EXTI vector (e.g., read the address at runtime in the debugger). Sounds like the core is jumping to something other than what you think and crashing there.

author: dannyf
author_rank: Super Contributor
timestamp: July 29, 2014, 05:42:56 pm
content: QuoteWithout knowing what you are doing, it is impossible to help you.QuoteIt is interrupting anything with a lower priority.QuoteThe simpler approach is to set through the code and see when you end up in the fault handler.A more fulsome approach is to save the stacked registers in the fault handler and print them out (mostly LR and PC registers) and go through the assembly file to see what triggered the hard fault. Yiu gave a pretty detailed example in his book and I can confirm for you that it works (99.9% of the time).

author: dannyf
author_rank: Super Contributor
timestamp: July 29, 2014, 05:50:45 pm
content: BTW, the whole EXTI module from ST is fully messed up.

author: andyturk
author_rank: Frequent Contributor
timestamp: July 29, 2014, 07:39:06 pm
content: Quote from: dannyf on July 29, 2014, 05:50:45 pmLOL

author: Ribster
author_rank: Frequent Contributor
timestamp: July 29, 2014, 10:15:12 pm
content: To start, thank you everyone for trying to help. It's a learn process these STM's. I've already learned a lot, but still a lot left.Quote from: andersm on July 29, 2014, 10:12:54 amQuote from: andyturk on July 29, 2014, 03:37:05 pmIs that the EXTI->SWIER register ? Tried making a watchpoint out of it but failed. Think i'll need to use the absolute adress to set the watchpoint.Quote from: dannyf on July 29, 2014, 05:42:56 pmWhat do you mean with LR and PC registers ? Assembly is sadly not one of my skills at the moment..So i've played around with it today for a few hours. Just a loop with the interrupt works. When i add the systick timer, no problems.If i implement everything back again, the thing freezes like a horse on antartica.I'll be troubleshooting it again tomorrow after work, so i'll keep you guys updated.A general thing that i have, is the fact that i sometimes need to reprogram my uC via GDB a few times and hit reset a few times before the new program loads / starts correctly. Is this something that you guys have noticed before on those discovery boards ?Greetings and cheers for all the effort guys!

author: mrflibble
author_rank: Super Contributor
timestamp: July 29, 2014, 10:15:59 pm
content: Quote from: dannyf on July 29, 2014, 05:50:45 pmI thought we were already doing Microcontroller Mad Libsin the other thread.

author: dannyf
author_rank: Super Contributor
timestamp: July 29, 2014, 10:20:19 pm
content: QuoteRead Yiu's book.If that's too much, just step through your code and see when you jump into the hard fault handler.

author: Kjelt
author_rank: Super Contributor
timestamp: July 29, 2014, 10:32:10 pm
content: QuoteBe sure that you fully erase the chip on reprogramming (this is an option in most IDE settings), see if that works better, it did for me in the past.

author: andyturk
author_rank: Frequent Contributor
timestamp: July 29, 2014, 10:41:18 pm
content: Quote from: Ribster on July 29, 2014, 10:15:12 pmNo, not a register. There's a table of pointers-to-code that define what happens when an interrupt is serviced. One of the entries in that table holds the address for your EXTI0 interrupt routine. Take a look at Section 9.1.3 of the STM32 Reference Manual (RM0090).Each entry in the vector table is 32-bits, so figure out which one corresponds to EXTI0, read the actual contents of what's in *your* vector table from memory at runtime and place a breakpoint on that address.

author: mikerj
author_rank: Super Contributor
timestamp: July 29, 2014, 11:08:20 pm
content: Adding a proper hard fault hander before you start coding the guts of your project is always worthwhile on the Cortex M parts.Have a look at thissimple example, and a morecomplex implementation.Adding a BKPT instruction to the end of the handler means you don't even need to remember to add a hard breakpoint when debugging.

author: Ribster
author_rank: Frequent Contributor
timestamp: August 06, 2014, 03:28:41 pm
content: To give some feedback to everyone, the problem is fixed.Code:GpioA<DefaultDigitalInputFeature<BUTTON_PIN> > pa;// enable EXTI on the button pin and subscribe to interruptsExti8 exti(EXTI_Mode_Interrupt,EXTI_Trigger_Rising_Falling,pa);exti.ExtiInterruptEventSender.insertSubscriber(ExtiInterruptEventSourceSlot::bind(this,&ExtiTest::onInterrupt));I'm using a c++ implementation wich uses a slot (don't quite get the actual workings but whatever), to execute the wanted function when the interrupt occurs.If i use the 'insertSubscriber' routine to set things up, i'm passing the pointer of the function that i want to execute. In this case it's '&ExtiTest::onInterrupt'.ExtiTest being the current class, onInterrupt being the interrupt routine.The problem was that if i didn't place this 'insertSubscriber-function' in the correct place where the infinite loop was executing, i had a hardware freeze.Thanks everybody for the valuable debug tips, i'll keep them in my troubleshooting toolbox.When the project is done in february, i'll do a writeup about it.Greetings and thanks to everybody