0

Very simple setup - I'm using Arduino Sketches from Arduino.cc on a Cortex M0 based arduino.

In the setup() method, I call:

void setup()
{
SysTick_Config(SystemCoreClock / 1000 ); //for a 1ms timer
}

In the sketch body, I declare:

void SysTick_Handler(void)
{
// print a message to serial port 
}

This handler is never called (the loop() function is working). The Cortex M0 technical reference manual says this is how to do it, however the Arduino sketch programming language doesn't document how these things are exposed inside the sketch. I am importing the board interface for my board, and it compiles and runs, but no handler is called.

Any tips here on how to figure out what the method declaration should be, or why it isn't being called?

Should I be using my own IRQ instead? I tried that but also could not find the way to configure what function is the IRQ handler.

Spectre22
  • 1
  • 1
  • 1
  • I found this definition in the Arduino source, and tried overriding in the sketch, but no dice: https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/cores/arduino/cortex_handlers.c – Spectre22 May 15 '15 at 20:07

3 Answers3

0

A couple of thoughts:

1 - does SysTick_Config actually enable the SYSTICK interrupt?

2 - we have to "connect" the interrupt vector to your handler; often this is done in an assembler file. Perhaps the Arduino's attachInterrupt() would work here.

Mike
  • 11
0

If your program would work, you'd call the handler 1000 times a second. That would have confused the serial port. I'm pretty sure.

I have a link for you: https://wiki.nottinghack.org.uk/wiki/Project:Arduino_Due . Search for SysTick. You'll find an arduino programm using SysTick and printing over serial.

Peter Paul Kiefer
  • 2,114
  • 1
  • 11
  • 16
0

I am also having this problem. First, for the questions above

1 - does SysTick_Config actually enable the SYSTICK interrupt?

Yes. This is a CMSIS function:

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */

  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}

2 - we have to "connect" the interrupt vector to your handler; often this is done in an assembler file. Perhaps the Arduino's attachInterrupt() would work here.

The function Systick_Handler is associated to the Systick interrupt vector in the Atmel libraries. Pretty sure this part is done.

There is an instructive thread here https://groups.google.com/a/arduino.cc/forum/#!msg/developers/ziJQT2SX1eI/jiml1rcHHZIJ

which suggests why a definition of Systick_Handler in the users sketch will not be called (because the default implementation in cortex_handlers.c is not defined as weak). In this case the sketch should instead implement

int sysTickHook(void);

Returning a 1 in the implementation will cause the default Arduino handler to be bypassed, and allow you to implement your own handler code instead. Returning a 0 will cause the default handler to execute after your implementation.

It appears that the default implementation in cortex_handlers.c is designed to reset the processor when the USB port detects a connection at 1200 baud. You can see this in CDC.cpp where cancelReset and initiateReset (defined in Reset.cpp) are called. By default, the reset is disabled in Reset.cpp because the local variable "ticks" is initialized to -1. The default implementation in cortex_handlers.c also calls TimeTick_Increment, which is required for delay() to work (note delay is called in main.cpp, so it needs to work!). So you probably want to return a 0 from sysTickHook().

With all of this in mind, delay() does not work on my board, and I have no idea why. It appears that Systick_Handler() is not being called in cortex_handlers.c. So the problem is similar to the OP.

Update: Got this working after stumbling on the answer by harper in this thread Can weak symbol be resolved among libraries during linking? Arduino moved the weak defines from startup_sam3xa.c to cortex_handlers.c, and you need to do the same if you are porting to a different sam.

Also, and I don't know why, I had to add cpu_irq_enable() somewhere in my initialization upstream of delay(1) in main.cpp. Otherwise SysTick_Handler refused to fire. Doesn't look like the Due code does this though.

Hope this helps.

dougcl
  • 116
  • 9