Eli Hughes

Codewarrior Interrupt Example with Proper Clock Init

Discussion created by Eli Hughes on Mar 2, 2011
Latest reply on Apr 1, 2011 by Jason Mitchell

This example shows how to use interrupts within CodeWarrior 10.1 on the kinetis K40 tower board.   Since there are no examples of how to do this yet on the Freescale website, I thought I would put this together for the rest of the world.




The example will blink LEDs E1,E2 and E3 at different rates using a combination of a SysTick Interrupt, a Flex Timer Overflow interrupt and a delay function that uses the SysTick interrupt.


The MCG is setup to use the external clock for the PLL with a target core frequency of 96MHz.  Note that this code shows how to place the clock init stuff in RAM per the errata e2448 so you can properly execute from FLASH!   Also, the Device initialization wizard generates bad code!  It will generate a fault exception.   This code is from the Kinetis Peripheral Module Quick Reference and works well.


I setup the Cortex System Tick Timer (documented in the generic Cortex M4 Generic User Guide as it is part of every cortex M4: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/index.html) to interrupt at a 10mS rate.  The System Tick DOES NOT go through the NVIC.  All you have to do is hit a couple registers to set it up and place the IRQ service routine in the function pointer table in kinetis_sysinit.c   Inside my irq routine, I toggle LED_E1 every 250mS.   I also increment a generic counter that is used for a delay routine in the main() loop


I setup the Flex Timer 0 for overflow interrupts at a rate of 10mS.   Since the FlexTimer is a Freescale peripheral,  its interrupts go through the NVIC.   You must enable interrupts in the module, then the NVIC registers (documented in the generic Cortex user guide).   Arm_cm4.c has some useful functions for enabling an interrupt on the NVIC.  Hopefully someday Freescale will support CMSIS!   Page 72 – 75 has the NVIC irq/vector assignments.  The IRQ# is used for the NVIC registers (the enable_irq() function) and the vector # is used for the table entry in kinetis_sysinit.c.  Note that they are not the same as the first 16 vectors are reserved for the Cortex core standard exceptions.   Vectors for a specific chip start after #16.  Once you enable the interrupt for an module, enable the NVIC channel, and then populate the vector table,  interrupts should just work.  Note that assembly language instruction to enable all interrupts  (CPSIE i) is already done for you in the start up routines.



Hope this is helpful.