Systick Exception on KL25Z

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Systick Exception on KL25Z

1,635 Views
drsmith_yorku
Contributor III

I am trying to implement a Systick exception handler that can flash an LED on the FRDM KL25Z board.  The code compiles but when I go to debug it I get the following error: "Error in services launch sequence"

 screenshot_1171.png

The code is intended to flash an LED on the FRDM board around 1 Hz.  I've been able to poll the SysTick without using exceptions/interrupts, but for whatever reason I am missing something while setting this up that blocks execution.  I'm trying to write code that is as CMSIS-compliant as possible, so no KDS calls.

If anyone has a hint about what I should be doing differently with setting up the SysTick exception, I'm all ears.  Code below...

Thanks!

James

#Kinetis #Systick #CMSIS #frdm–kl25z#exception_handler

#include <stdio.h>

#include "board.h"

#include "peripherals.h"

#include "pin_mux.h"

#include "clock_config.h"

#include "MKL25Z4.h"

/* TODO: insert other include files here. */

/* TODO: insert other definitions and declarations here. */

/* The system tick interrupt handler vector (and name) is defined in startup_mkl25z4.c

 *

 * */

void SysTick_Handler(void)

{

static int n = 0;

/* every 500 interrupts / exceptions toggle the LED */

if (n <= 500)

{

/* increment the counter. */

n= n+1;

}

else

{

/* "Port Toggle" on Port B: Toggle green LED on PTB19 */

PTB->PTOR = 0x080000;

/* reset the counter */

n=0;

}

}

/*

 * @brief   Application entry point.

 */

int main (void) {

    /* Step 1: Turn on Port B via System Integration Module SIM's SCGC5 register.

     *         Keep existing state of SCGC5 & only set bit 10 to 1. */

    SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; // The "mask" is 0x400

    /* Step 2: Make Port B, Pin 19 a "General Purpose Input or Output" (GPIO)

     *         Look up section 10.3.1 in the manual.  Alt1 mode is GPIO for Port B 19.

     *         Look up section 11.5.1 in the manual. The MUX bits are bits 10,9 and 8 of the PCR.

     *         key terms for searching: "alt0" and "pin control register" in the PDF (https://bit.ly/2J2751t)

     */

    PORTB->PCR[19] = 0x100; // Mux @ Alt1 is GPIO: Bits 10,9,8 = 0b001

   

    /* Step 3: Make Port B, pin 19 an output (instead of an input) */

    PTB->PDDR |= 0x080000;      /* Bit 19 is a binary "1" (output).  A "0" would be input. */

    // Interrupt / Exception with SysTick

    // https://electronics.stackexchange.com/questions/331650/whats-the-difference-between-setting-systick-...

    // http://homepage.cem.itesm.mx/carbajal/Microcontrollers/SLIDES/Interrupts.pdf

    //  https://community.nxp.com/thread/311713

    //  https://mcuoneclipse.com/2016/08/14/arm-cortex-m-interrupts-and-freertos-part-1/#more-19365

    __disable_irq();            /* disable all IRQs */

    /* Delay = (N+1)/sysclk

      * 0.001 [sec] = (N+1) / (48000000/2) ---> N = 0.001[sec]*2400000[MHz] - 1

      * So N is 24000-1.

      */

     SysTick->LOAD = 24000-1;

     NVIC_SetPriority(SysTick_IRQn, (1UL<<__NVIC_PRIO_BITS)-1UL); /* set Priority for Systick Interrupt to lowest interrupt */

     SysTick->VAL = 24000-1;

     /* Enable the timer and choose processor clock as the clock source  via Bits 0 and 2

      * Also, enable Systick to generate Exceptions / Interrupts via Bit 1*/

SysTick->CTRL      = 0b0111;

/* = 0b0111

  * ^^^^

  * ||||_________ Bit 0: Enable ( 0 = disable; 1 = enable)

  * |||__________ Bit 1: TickInt  (interrupt/exception enabling)

  * ||___________ Bit 2: Clock Source (0 = ext; 1 = proc. clock)

  * |____________ Bit 3: Reserved

      */

/* Enable IRQs within NVIC */

     NVIC_EnableIRQ(SysTick_IRQn); /* Enable NVIC interrupt */

     /* Enable IRQs globally */

     __enable_irq();             /* global enable IRQs */

    /* Toggle LED every 0.5 second to give 1Hz */

    while (1) {

    /* do nothing */

    }

}

1 Reply

930 Views
mjbcswitzerland
Specialist V

Hi James

Here is a 1ms SYSTICK interrupt and handler (works on any Kinetis part):

#define TICK_RESOLUTION 1000                                         // 1ms tick

#define LED_GREEN   PORTB_BIT19                                      // output to be toggled

#define REQUIRED_US (1000000/(TICK_RESOLUTION))                      // the TICK frequency we require in MHz
#define TICK_DIVIDE (((CORE_CLOCK + REQUIRED_US/2)/REQUIRED_US) - 1) // the divide ratio required (for systick)

VECTOR_TABLE *ptrVect = (VECTOR_TABLE *)VECTOR_TABLE_OFFSET_REG;
ptrVect->ptrSysTick = _RealTimeInterrupt;                            // enter interrupt handler
SYSTICK_RELOAD = TICK_DIVIDE;                                        // set reload value to determine the period
SYSTICK_CURRENT = TICK_DIVIDE;                                       // write to synchronise the Systick counter after configuration
SYSTEM_HANDLER_12_15_PRIORITY_REGISTER |= (unsigned long)(SYSTICK_PRIORITY << (24 + __NVIC_PRIORITY_SHIFT)); // enter the SYSTICK priority
SYSTICK_CSR = (SYSTICK_CORE_CLOCK | SYSTICK_ENABLE | SYSTICK_TICKINT); // enable timer and its interrupt

_CONFIG_DRIVE_PORT_OUTPUT_VALUE(B, (LED_GREEN), (LED_GREEN), (PORT_ODE | PORT_SRE_SLOW | PORT_DSE_HIGH)); // configure and drive high

Handler:
// Tick interrupt
//
static __interrupt void _RealTimeInterrupt(void)
{
    static int iDiv = 0;
    INT_CONT_STATE_REG = PENDSTCLR;                                      // reset interrupt
    if (++iDiv >= 500) {                                                 // every 500ms
        _TOGGLE_PORT(B, LED_GREEN);
        iDiv = 0;
    }
}

Your problem looks to be a debugger issue - try loading a binary at these links or using the uTasker's KL25 simulator.
http://www.utasker.com/kinetis/FRDM-KL25Z.html
http://www.utasker.com/kinetis/TWR-KL25Z48M.html

However, your handler is not resetting the Systick interrupt flag which would mean that it would never stop firing.


Regards

Mark

uTasker developer and supporter (+5'000 hours experience on +60 Kinetis derivatives in +80 product developments)
Kinetis: http://www.utasker.com/kinetis.html