0

I haven't seen any examples of registering ISRs in Atmel Studio 7, but I've given the following code a go in my IDE.

/*
 * mainCode.cpp
 *
 * Created: 1/29/2020 11:30:58 AM
 * Author : tuskiomi
 */ 


#include "sam.h"
#define CPU_CLK 48000000 //CPU Clock Speed in Hz
#define SYSTICK_INTERVAL_MS 10 //System should always run at 100 Hz
#define SYSTICK_INTERVAL_CYCLES (CPU_CLK/1000*SYSTICK_INTERVAL_MS)-1
#define SYSTICK_CALIBRATION_VALUE (CPU_CLK/100)-1


void handleSysTick(){

}

int main(void)
{
    /* Initialize the SAM system */
    SystemInit();

        SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
        uint32_t CPU = SCB->CPUID;
        uint32_t CPU_MINOR_REV = CPU&0x000F;
        uint32_t CPU_PART_NO = (CPU>>4)&0x0FFF;
        uint32_t CPU_MAJOR_REV = (CPU>>20)&0x00F;
        uint32_t CPU_IMPLEMENTOR = (CPU>>24)&0x00FF;
        //uint32_t SCB->
        SysTick->CTRL = 0x05;
        SysTick->LOAD = SYSTICK_INTERVAL_CYCLES;

        __NVIC_SetVector(SysTick_IRQn, ((uint32_t) *handleSysTick));


    /* Replace with your application code */
    while (1) 
    {
    }
}

My main concern is with the line:

__NVIC_SetVector(SysTick_IRQn, ((uint32_t) *handleSysTick));

My c++ is very rusty, and what the expression ((uint32_t) *handleSysTick) is supposed to be is a uint32_t representation of the address that the function "handleSysTick" starts from. If this is indeed the case, then it is safe to say that the interrupt is properly configured.

tuskiomi
  • 585
  • 6
  • 23
  • Have you tried it? Seems pretty trivial to put this into the IDE and run it to see if it works... – Ron Beyer Jan 29 '20 at 19:11
  • @RonBeyer I can build it, but I do not have a device to program, and I do not have the ability to simulate the device – tuskiomi Jan 29 '20 at 19:25
  • SAMD21 boards are pretty easy to get, and relatively cheap. If you are going to be doing development for one, picking up a development board is almost as much of a requirement as downloading the IDE. [Here's one](https://www.sparkfun.com/products/13672), or an [even cheaper one](https://www.electrodragon.com/product/samd21-mini-devlopment-board-m0-atsamd21g18a-au/). – Ron Beyer Jan 29 '20 at 19:30
  • @RonBeyer I have one being shipped to me. That's not an issue – tuskiomi Jan 29 '20 at 19:37
  • I'm not sure what the issue is then, what you are saying is true about the address of the handler function, it is a 32-bit function pointer. – Ron Beyer Jan 29 '20 at 19:41
  • Even without a board you can look at the assembly code produced by the compiler, and check the linker to see what the actual address of `handleSysTick` would be. If you are going to program bare-metal ARM then you should be able to do this. – Elliot Alderson Jan 29 '20 at 20:27
  • And you should also verify that the address of `handleSysTick` gets shoved into the correct address for the SysTick interrupt in the vector table. – Elliot Alderson Jan 29 '20 at 20:29
  • @ElliotAlderson I can see the machine code, but I have no clue how to decompile that into assembly – tuskiomi Jan 29 '20 at 20:29
  • 1
    Set the appropriate switches for the compiler and linker you are using to force it to produce a disassembly of the code. You also need the linker to spit out a map of where everything is placed in memory. – Elliot Alderson Jan 29 '20 at 20:32
  • `*handleSysTick` is incorrect afaict. It should probably be `&handleSysTick`. The former (`*handleSysTick`) implies that you're getting a value in memory pointed to by `handleSysTick` (which here is not a pointer), whereas the latter (`&handleSysTick`) is "the address of `handleSysTick`". From there, the code is casting the address to a `uint32_t` so it's compatible with `__NVIC_SetVector()`'s prototype. – jkiv May 09 '20 at 14:36
  • I wouldn't bother using `__NVIC_SetVector()`. If you go to the startup file, you'll find that the interrupt vector is weakly defined as `SysTick_Handler()`. In other words, just use `SysTick_Handler` as the name of your ISR instead of `handleSysTick` and everything will work fine. – next-hack Jun 04 '20 at 08:05

0 Answers0