Atmel Cortex-M0+ SAMC21 hangs after SysTick_Config

0

So, I have recently acquired a SAMC21 Xplained dev board to begin trying to learn to program for ARM. My previous experience is predominantly with PIC's. As an example application I have started an ASF Board project targeting the SAMC21 Xplained board and written the following main function:

#include <asf.h>
#include <stdbool.h>

int main (void) {
    system_init();  
    SysTick_Config(SystemCoreClock/1000);
    system_interrupt_enable(SYSTEM_INTERRUPT_SYSTICK);

    while(true);
}

void SysTick_Handler(void) {
    port_pin_toggle_output_level(LED_0_PIN);
}

When I start debugging I successfully reach main and execute the system_init() function. After that, the program counter hangs forever. The Disassembly looks like this:

int main (void) {
000004D0  ???       Memory out of bounds or read error 
    system_init();  
000004D2   ldr  r3, #60      
000004D4   blx  r3       
    SysTick_Config(SystemCoreClock/1000);
000004D6   ldr  r3, #60      
000004D8   ldr  r0, [r3]         
000004DA   movs r1, #250         
000004DC   lsls r1, r1, #2       
000004DE   ldr  r3, #56      
000004E0   blx  r3       
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
000004E2   subs r0, #1       
000004E4   ldr  r3, #52      
000004E6   cmp  r0, r3       
000004E8   bhi  #26      
SysTick->LOAD  = ticks - 1;                                  /* set reload register */
000004EA   ldr  r3, #52      
000004EC   str  r0, [r3, #4]         
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
000004EE   ldr  r2, #52      
000004F0   ldr  r0, [r2, #32]        
000004F2   lsls r0, r0, #8       
000004F4   lsrs r0, r0, #8       
000004F6   movs r1, #192         
000004F8   lsls r1, r1, #24      
000004FA   orrs r1, r0       
000004FC   str  r1, [r2, #32]        
SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
000004FE   movs r2, #0       
00000500   str  r2, [r3, #8]         
SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
00000502   movs r2, #7       
00000504   str  r2, [r3]         
NVIC->ISER[0] = (uint32_t)(1 << ((uint32_t)vector & 0x0000001f));
00000506   movs r2, #128         
00000508   lsls r2, r2, #24      
0000050A   ldr  r3, #28      
0000050C   str  r2, [r3]         
0000050E   b    #-4                     // Debugger PC Hangs
00000510   lsls r1, r2, #16      
00000512   movs r0, r0       
00000514   movs r4, r0       
00000516   movs r0, #0       
00000518   lsls r1, r7, #20      
0000051A   movs r0, r0       
0000051C  ???       Memory out of bounds or read error 
0000051E   lsls r7, r7, #3       
00000520   b    #32      
00000522   b    #0       
00000524  ???       Memory out of bounds or read error 
00000526   b    #0       
00000528   b    #512          
0000052A   b    #0       
    port_base->OUTTGL.reg = pin_mask;
0000052C   movs r2, #128         
0000052E   lsls r2, r2, #8       
00000530   movs r3, #130         
00000532   lsls r3, r3, #23      
00000534   str  r2, [r3, #28]    
}
00000536   bx   lr

I've added a comment to the line where the PC hangs (0x0000050E). I'm confused because it looks like the b #-4 assembly instruction is behaving correctly by repeatedly branching to itself. What I don't understand is why it's there in the first place.

EDIT First off, thank you to everyone for the responses! Secondly, I should have included more of the code (sorry about that ) but wasn't sure what was relevant. I have edited my code above to show the entire main.c file. It almost looks like the while(true) has been misplaced in the code, but I'm still struggling to make sense of it.

Also adding some (hopefully!) useful snippets from my .lss file:

00000000 <_sfixed>:
*         Initialize the System and update the SystemCoreClock variable.
*/
void SystemInit(void)
{
    // Keep the default device state after reset
    SystemCoreClock = __SYSTEM_CLOCK;
0:  20002030    .word   0x20002030
4:  00000441    .word   0x00000441
    return;
}
8:  0000043d    .word   0x0000043d
c:  0000043d    .word   0x0000043d
    ...
2c: 0000043d    .word   0x0000043d
    ...
38: 0000043d    .word   0x0000043d
3c: 0000052d    .word   0x0000052d
40: 0000043d    .word   0x0000043d
44: 0000043d    .word   0x0000043d
48: 0000043d    .word   0x0000043d
4c: 0000043d    .word   0x0000043d
50: 0000043d    .word   0x0000043d
54: 0000043d    .word   0x0000043d
58: 0000043d    .word   0x0000043d
5c: 0000043d    .word   0x0000043d
60: 0000043d    .word   0x0000043d
64: 0000043d    .word   0x0000043d
68: 0000043d    .word   0x0000043d
6c: 0000043d    .word   0x0000043d
70: 0000043d    .word   0x0000043d
74: 0000043d    .word   0x0000043d
78: 0000043d    .word   0x0000043d
7c: 0000043d    .word   0x0000043d
80: 0000043d    .word   0x0000043d
84: 0000043d    .word   0x0000043d
88: 0000043d    .word   0x0000043d
8c: 0000043d    .word   0x0000043d
90: 0000043d    .word   0x0000043d
94: 0000043d    .word   0x0000043d
98: 0000043d    .word   0x0000043d
9c: 0000043d    .word   0x0000043d
a0: 0000043d    .word   0x0000043d
a4: 0000043d    .word   0x0000043d
a8: 0000043d    .word   0x0000043d
ac: 0000043d    .word   0x0000043d
b0: 0000043d    .word   0x0000043d
b4: 0000043d    .word   0x0000043d
b8: 0000043d    .word   0x0000043d

000004d0 <main>:
#include <asf.h>
#include <stdbool.h>

int main (void) {
4d0:    b508        push    {r3, lr}
    system_init();  
4d2:    4b0f        ldr r3, [pc, #60]   ; (510 <main+0x40>)
4d4:    4798        blx r3
    SysTick_Config(SystemCoreClock/1000);
4d6:    4b0f        ldr r3, [pc, #60]   ; (514 <main+0x44>)
4d8:    6818        ldr r0, [r3, #0]
4da:    21fa        movs    r1, #250    ; 0xfa
4dc:    0089        lsls    r1, r1, #2
4de:    4b0e        ldr r3, [pc, #56]   ; (518 <main+0x48>)
4e0:    4798        blx r3
    must contain a vendor-specific implementation of this function.

*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */
4e2:    3801        subs    r0, #1
4e4:    4b0d        ldr r3, [pc, #52]   ; (51c <main+0x4c>)
4e6:    4298        cmp r0, r3
4e8:    d80d        bhi.n   506 <main+0x36>

SysTick->LOAD  = ticks - 1;                                  /* set reload register */
4ea:    4b0d        ldr r3, [pc, #52]   ; (520 <main+0x50>)
4ec:    6058        str r0, [r3, #4]
    \param [in]  priority  Priority to set.
*/
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
    SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
4ee:    4a0d        ldr r2, [pc, #52]   ; (524 <main+0x54>)
4f0:    6a10        ldr r0, [r2, #32]
4f2:    0200        lsls    r0, r0, #8
4f4:    0a00        lsrs    r0, r0, #8
4f6:    21c0        movs    r1, #192    ; 0xc0
4f8:    0609        lsls    r1, r1, #24
4fa:    4301        orrs    r1, r0
4fc:    6211        str r1, [r2, #32]
{
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 */
4fe:    2200        movs    r2, #0
500:    609a        str r2, [r3, #8]
SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
502:    2207        movs    r2, #7
504:    601a        str r2, [r3, #0]
* \param[in] vector Interrupt vector to enable
*/
static inline void system_interrupt_enable(
        const enum system_interrupt_vector vector)
{
    NVIC->ISER[0] = (uint32_t)(1 << ((uint32_t)vector & 0x0000001f));
506:    2280        movs    r2, #128    ; 0x80
508:    0612        lsls    r2, r2, #24
50a:    4b07        ldr r3, [pc, #28]   ; (528 <main+0x58>)
50c:    601a        str r2, [r3, #0]
50e:    e7fe        b.n 50e <main+0x3e>
510:    00000411    .word   0x00000411
514:    20000004    .word   0x20000004
518:    00000539    .word   0x00000539
51c:    00ffffff    .word   0x00ffffff
520:    e000e010    .word   0xe000e010
524:    e000ed00    .word   0xe000ed00
528:    e000e100    .word   0xe000e100

0000052c <SysTick_Handler>:
{
    PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin);
    uint32_t pin_mask  = (1UL << (gpio_pin % 32));

    /* Toggle pin output level */
    port_base->OUTTGL.reg = pin_mask;
52c:    2280        movs    r2, #128    ; 0x80
52e:    0212        lsls    r2, r2, #8
530:    2382        movs    r3, #130    ; 0x82
532:    05db        lsls    r3, r3, #23
534:    61da        str r2, [r3, #28]
    while(true);
}

void SysTick_Handler(void) {
    port_pin_toggle_output_level(LED_0_PIN);
}
536:    4770        bx  lr
c
arm
microcontroller
atmel
cortex-m
asked on Stack Overflow Sep 1, 2015 by KevinGrumble • edited Sep 1, 2015 by KevinGrumble

1 Answer

0

Recently faced same systick issue. On analyzing and changing the linker script (.ld) the problem got resolved. I was using a custom linker script. Check your linker script, MSR, vector address (at location 0x0000003C)

answered on Stack Overflow Jan 7, 2016 by AvadhanaSolutions

User contributions licensed under CC BY-SA 3.0