STM32 SysTick Interrupts

Everything ARM and LPC

Moderator: phalanx

STM32 SysTick Interrupts

Postby Jim_D » Sun Jan 24, 2010 11:53 am

I'm missing something obvious in trying to get systick interrupts working on an Olimex STM32-P103 board with an ARM-USB-OCD jtag probe and am wondering if anyone has seen something similar or sees where I went wrong?

I'm using the STM32 StdPeriph_Lib_V3.1.2 to do the setup with
SysTick_Config(SystemFrequency / 500) for 2ms ticks.
I placed a function call in the stm32f10x_it.c SysTick_Handler to call my timer routine which currently just pulses a GPIO pin.

The pin never pulses and the interrupt is never invoked. I verified that the handler is installed by dumping the memory at 0x0000_003C and that address does point to the SysTick_Handler. Disassembling SysTick_Handler shows a bl to my function call, so I think the vector table is properly loaded and contains valid calls.

Next, I added a poll of the SysTick control register in my main loop and pulse the GPIO pin when the CountFlag goes high. Sure enough, I get a pulse every 2ms and the Systick works as expected with the auto-reload functioning and the timebase is as expected. Still no interrupt called though, even though the systick control register interrupt enable is set.

The systick example in StdPeriph_Lib does no other setup other than the one call to SysTick_Config().

Any thoughts?
Jim
Jim_D
 
Posts: 17
Joined: Sun Jan 24, 2010 11:29 am

Postby gussy » Sun Jan 24, 2010 10:55 pm

A few things to check;

The definition SystemFrequency, that exists and is at 72000000 (72MHz) or similar?

You have ".word SysTickHandler" in your statup script file?

Are you calling "SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);"?
I had to comment this out to get SysTick to work for me.

Last thing "SysTick_Config(SystemFrequency / 100);" gives me 10mS "ticks", so your "... / 500" should be correct.
gussy
 
Posts: 460
Joined: Fri Jul 28, 2006 5:25 am

Postby mjbcswitzerland » Mon Jan 25, 2010 2:01 pm

Hi

It sounds as though interrupts are not enabled.

1) Enable the SYSTICK interrupt by writing its priority to 0xe000ed20

SYSTEM_HANDLER_12_15_PRIORITY_REGISTER |= (SYSTICK_PRIORITY << 24); // enter the SYSTICK priority

2) Enable interrupts globally - assembler is something like:
asm("cpsie i");

Regards

Mark
mjbcswitzerland
 
Posts: 85
Joined: Tue Jan 08, 2008 8:49 am
Location: Switzerland

Postby Jim_D » Mon Jan 25, 2010 4:59 pm

Thanks for the suggestions, but still no luck.

Priority is set with NVIC_SetPriority(SysTick_IRQn, Priority);
where SysTick_IRQn = -1.
When the requested irq is negative, this function sets the core interrupt priority:
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */

I also had previously tried __enable_irq(); with no effect and I also tried __enable_fault_irq(); with no effect.

As mentioned earlier, mem dumps and disassembly show that the vectors are loaded correctly and my function is called from within the SysTick_Handler.

This is so strange.
Jim
Jim_D
 
Posts: 17
Joined: Sun Jan 24, 2010 11:29 am

Postby mjbcswitzerland » Mon Jan 25, 2010 5:09 pm

Hi

Maybe it is getting to your interrupt once.

Assuming that the interrupt may arrive there, have you then cleared the SYSTICK interrupt?

INT_CONT_STATE_REG = PENDSTCLR; // reset interrupt

0x40004d04 written with 0x02000000

Without clearing the interrupt it would probably re-enter again immediately (port output would then toggle very fast), or maybe it doesn't come back in ever again (?)

Regards

Mark
mjbcswitzerland
 
Posts: 85
Joined: Tue Jan 08, 2008 8:49 am
Location: Switzerland

Postby Jim_D » Mon Jan 25, 2010 5:21 pm

I added

SCB->ICSR = SCB_ICSR_PENDSTCLR;

to the handler, but it (the handler) does not get invoked even once. My scope is set to normal triggering and the GPIO port never toggles even once.

Again, if I poll the control register 0xE000E010 and test the COUNTFLAG, toggling the GPIO bit when set, I get the expected pulse at the desired 2ms interval. The SysTick is functioning, but not the interrupt.

The control register setup reads back 0x7,
CLKSOURCE = 1
TICKINT = 1
ENABLE = 1
Jim_D
 
Posts: 17
Joined: Sun Jan 24, 2010 11:29 am

Postby mjbcswitzerland » Tue Jan 26, 2010 6:05 am

Hi

But if the interrupt is arriving it will either jump to your routine (which it seemingly isn't) or jump somewhere else. If that somewhere else is not defined it will result in a crash.

It may be that the code is crashing or it may be that the interrupt is being handled by a default handler - is it possible to identify this?

Furthermore, are you running from FLASH or SRAM? When running from FLASH the default interrupt vector table at 0x00000000 is correct. When running from SRAM the vector table may need to be moved by writing VTOR: offset 0xd08 in the Cortex M3 registers.

I haven't used the ST32 but have developed low level code for the Luminary Micro and LPC17X Cortex M3 parts - I would expect the ST32 to be identical in this area (the only difference I had with the ones I have used was to do with the vector table mapping since the LPC17XX doesn't fully respect the Cortex M3 memory layout. This was only an issue when the vector table was relocated to SRAM).

Regards

Mark

www.uTasker.com
mjbcswitzerland
 
Posts: 85
Joined: Tue Jan 08, 2008 8:49 am
Location: Switzerland

Postby Jim_D » Tue Jan 26, 2010 5:16 pm

Running from flash. There is something fundamental going wrong here.

Here is a dump of the vectors, with SysTick being the 15th pointing to 0x080007e1. A disassembly of that address shows the SysTick_Handler that calls my routine. I also tried the GPIO toggle here in this routine but it never gets called.

Code: Select all
x /16 0
0x00:   0x20005000   0x0800010c   0x08000791   0x0800079d
0x10:   0x080007a5   0x080007ad   0x080007b5   0x00000000
0x20:   0x00000000   0x00000000   0x00000000   0x080007bd
0x30:   0x080007c9   0x00000000   0x080007d5   0x080007e1

disassemble 0x080007e1
Dump of assembler code for function SysTick_Handler:
0x080007e0 <SysTick_Handler+0>:   push   {r7, lr}
0x080007e2 <SysTick_Handler+2>:   add   r7, sp, #0
0x080007e4 <SysTick_Handler+4>:   bl   0x8000450 <SysTickInterrupt>
0x080007e8 <SysTick_Handler+8>:   mov   sp, r7
0x080007ea <SysTick_Handler+10>:   pop   {r7, pc}
End of assembler dump.


As I mentioned, there is something fundamental wrong. I also tried implementing the timer with a peripheral timer and that one also refuses to generate interrupts.
I don't know if it is in the tools, OpenOCD, or in the startup assembly.

Jim
Jim_D
 
Posts: 17
Joined: Sun Jan 24, 2010 11:29 am

Postby mjbcswitzerland » Tue Jan 26, 2010 5:59 pm

Hi Jim

If neither SYSTICK or another timer is generating interrupts it either means that the global interrupt is masked or that the timers haven't been set up correctly to generate interrupts.

Check these:

1) The SYSTICK configuration (this example is for 50ms from a 96MHz clock)

Code: Select all
    SYSTICK_RELOAD = 0x00493dff; // set reload value to determine the period
    SYSTEM_HANDLER_12_15_PRIORITY_REGISTER |= (SYSTICK_PRIORITY << 24);  // enter the SYSTICK priority
    SYSTICK_CSR = (SYSTICK_CORE_CLOCK | SYSTICK_ENABLE | SYSTICK_TICKINT); // enable timer and its interrupt - value is 0x00000007


Make sure that the interrupt bit has also been set so that it will also interrupt on reload and not just count.

2) Check the PRIMASK in the core registers [CORTEX_M3_REGS.ulPRIMASK] It must be 0. If it is 1, all interrupts are masked.


The vector table configuration looks fine so I don't think that this has anything to do with the problem.

If you are still convinced that interrupts are occurring there is a simple test; set the vector base address to an invalid area of memory. The NVIC will always try to read the vector from this area and will fail with a hardware access error. Normally this will result in the fault interrupt being called, but is not possible since the fault is due to a vector table access and will fail itself. This will thus set the VECTTBL bit in the Cortex M3 HSFR register, signaling that a fault occurred on attempted NVIC read from the vector table. If you can detect that this bit is being set (the system is also in a crashed state now) it will confirm that an interrupt really occurred since there is no other possibility of setting it.

Regards

Mark

www.uTasker.com
mjbcswitzerland
 
Posts: 85
Joined: Tue Jan 08, 2008 8:49 am
Location: Switzerland

Postby Jim_D » Tue Jan 26, 2010 8:30 pm

Finally.

As I suspected, there was an issue in the startup assembly file. The closest supplied startup file with the ST peripheral library was for the Raisonance RIDE toolset. I switched back to the startup file and linker script from an example on Freddie Chopin's web site for my yagarto/eclipse/openocd setup.

SysTick interrupts now work as expected with just the few CMSIS calls as per the ST examples.
I suspect it had to do with the MSR setup for both main and process stacks, but I'm not sure and I need to move on for now.

Thanks for the help!
Jim
Jim_D
 
Posts: 17
Joined: Sun Jan 24, 2010 11:29 am


Return to Everything ARM and LPC

Who is online

Users browsing this forum: No registered users and 1 guest