Example for the FlexTimer Module with interrupts on the FRDM-K20D50

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

Example for the FlexTimer Module with interrupts on the FRDM-K20D50

Jump to solution
21,385 Views
juanm
Contributor III

Hi! I'm starting with the Kinetis microcontrollers, and I have an FRDM-K20D50. At first I was using processor expert, but now I want to use it without it. For this, I was following this examples:

KWIKSTIK K40 Getting Started

FREEDOM BOARD / CORTEX M0+ GETTING STARTED

I didn't have any trouble adapting the firsts examples to the Freedom Board, but I'm not sure with the FTM module.

The problem is with the interrupt vector table. In the code attached in those videos, in the file kinetis_sysinit.c for the KL25, there's an array with all the IRQ handlers declared like this:

/* The Interrupt Vector Table */

void (* const InterruptVector[])() __attribute__ ((section(".vectortable"))) = {

    /* Processor exceptions */

    (void(*)(void)) &_estack,

    __thumb_startup,

    NMI_Handler,

    HardFault_Handler,

    0,

    0,

    0,

    0,

    0,

    0,

    0,

    SVC_Handler,

    0,

    0,

    PendSV_Handler,

    SysTick_Handler,

    /* Interrupts */

    DMA0_IRQHandler, /* DMA Channel 0 Transfer Complete and Error */

    DMA1_IRQHandler, /* DMA Channel 1 Transfer Complete and Error */

    DMA2_IRQHandler, /* DMA Channel 2 Transfer Complete and Error */

    DMA3_IRQHandler, /* DMA Channel 3 Transfer Complete and Error */

    MCM_IRQHandler, /* Normal Interrupt */

    FTFL_IRQHandler, /* FTFL Interrupt */

    PMC_IRQHandler, /* PMC Interrupt */

    LLW_IRQHandler, /* Low Leakage Wake-up */

    I2C0_IRQHandler, /* I2C0 interrupt */

    I2C1_IRQHandler, /* I2C1 interrupt */

    SPI0_IRQHandler, /* SPI0 Interrupt */

    SPI1_IRQHandler, /* SPI1 Interrupt */

    UART0_IRQHandler, /* UART0 Status and Error interrupt */

    UART1_IRQHandler, /* UART1 Status and Error interrupt */

    UART2_IRQHandler, /* UART2 Status and Error interrupt */

    ADC0_IRQHandler, /* ADC0 interrupt */

    CMP0_IRQHandler, /* CMP0 interrupt */

    FTM0_IRQHandler, /* FTM0 fault, overflow and channels interrupt */

    FTM1_IRQHandler, /* FTM1 fault, overflow and channels interrupt */

    FTM2_IRQHandler, /* FTM2 fault, overflow and channels interrupt */

    RTC_Alarm_IRQHandler, /* RTC Alarm interrupt */

    RTC_Seconds_IRQHandler, /* RTC Seconds interrupt */

    PIT_IRQHandler, /* PIT timer all channels interrupt */

    Default_Handler, /* Reserved interrupt 39/23 */

    USBOTG_IRQHandler, /* USB interrupt */

    DAC0_IRQHandler, /* DAC0 interrupt */

    TSI0_IRQHandler, /* TSI0 Interrupt */

    MCG_IRQHandler, /* MCG Interrupt */

    LPTimer_IRQHandler, /* LPTimer interrupt */

    Default_Handler, /* Reserved interrupt 45/29 */

    PORTA_IRQHandler, /* Port A interrupt */

    PORTD_IRQHandler /* Port D interrupt */

};

But with the K20, Codewarrior generate this kinetis_sysinit.c:

/* The Interrupt Vector Table */

void (* const InterruptVector[])() __attribute__ ((section(".vectortable"))) = {

    /* Processor exceptions */

    (void(*)(void)) &_estack,

    __thumb_startup,

    NMI_Handler,

    HardFault_Handler,

    MemManage_Handler,

    BusFault_Handler,

    UsageFault_Handler,

    0,

    0,

    0,

    0,

    SVC_Handler,

    DebugMonitor_Handler,

    0,

    PendSV_Handler,

    SysTick_Handler,

    /* Interrupts */

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

    Default_Handler,

};

The question is how can I generate a table for K20 with all the IRQ handlers defined like in the KL25?

I hope that I have made myself clear with the question, English isn't my first language.

PD: Also I would like to know if there's a working example for the TFM with interrupts for the FRDM-K20D50.

Thanks!!!!!!

1 Solution
1,572 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Juan:

That vector table is for you to fill with your required interrupt service routine names. There is an order for the interrupt vectors, which you can check in the reference manual for your specific device, in chapter 3.2.2.3 Interrupt channel assignments. The document you need is called "K20P64M50SF0RM" and you can download it from the next link:

K20_50: Kinetis K20 USB 50 MHz MCUs

Once you checked the vector number, match the number with the vector position in the list (&_estack is vector 0, __thumb_startup is vector 1, and so on). Then you just need to replace the "Default_handler" with the name of your ISR function. And obviously that function needs to be declared somewhere in your code.

Also you need to enable the required interrupt from the peripheral itself and from the NVIC module. I have attached a pdf showing how to use interrupts in the Kinetis L family, but it is the same for Kinetis K.

As for the sample code, you can find a source code package called "KINETIS_50MHHZ_SC" under Lab and Test Sofware.

K20_50: Kinetis K20 USB 50 MHz MCUs

Also, for the FRDM-K20D50 board, there is a Quick Start Package called "FRDM-K20D50M-QSP" downloadable from the next place:

FRDM-K20D50M: Freescale Freedom Development Platform for the Kinetis K20 USB MCUs

Hope this is helpful. If it is not clear please let me know.

/Jorge Gonzalez

View solution in original post

0 Kudos
5 Replies
1,573 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Juan:

That vector table is for you to fill with your required interrupt service routine names. There is an order for the interrupt vectors, which you can check in the reference manual for your specific device, in chapter 3.2.2.3 Interrupt channel assignments. The document you need is called "K20P64M50SF0RM" and you can download it from the next link:

K20_50: Kinetis K20 USB 50 MHz MCUs

Once you checked the vector number, match the number with the vector position in the list (&_estack is vector 0, __thumb_startup is vector 1, and so on). Then you just need to replace the "Default_handler" with the name of your ISR function. And obviously that function needs to be declared somewhere in your code.

Also you need to enable the required interrupt from the peripheral itself and from the NVIC module. I have attached a pdf showing how to use interrupts in the Kinetis L family, but it is the same for Kinetis K.

As for the sample code, you can find a source code package called "KINETIS_50MHHZ_SC" under Lab and Test Sofware.

K20_50: Kinetis K20 USB 50 MHz MCUs

Also, for the FRDM-K20D50 board, there is a Quick Start Package called "FRDM-K20D50M-QSP" downloadable from the next place:

FRDM-K20D50M: Freescale Freedom Development Platform for the Kinetis K20 USB MCUs

Hope this is helpful. If it is not clear please let me know.

/Jorge Gonzalez

0 Kudos
1,572 Views
dave408
Senior Contributor II

Hi Jorge, thanks for sharing that PDF -- it was very helpful, since I didn't really know where to start with setting up ISRs on my K series.  However, where is information about mapping the actual ISR function pointer, i.e.  void (* const InterruptVector[])() __attribute__ ((section(".vectortable")))?  I haven't found any template code like that anywhere in my KSDK or KSDK + PEx projects.

0 Kudos
1,572 Views
dave408
Senior Contributor II

err... I just saw the links with the videos in juanm's post.  Perhaps I should start there.  :smileyhappy:

0 Kudos
1,572 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Dave:

With KDS/KSDK the ISR function pointers are treated differently. The ISR entry names are declared in an assembly file called "startup_<device>.S".

For example a small part of the ISR entries list for K64 is below:

pastedImage_3.png

If you are interested on interrupt handling with KSDK I released a document a few days ago: Interrupt handling with KSDK and Kinetis Design Studio

About the videos, you can watch them, just keep in mind that they are a bit old and made for CodeWarrior, some things will not apply for latest development tools (KDS or KSDK).

Regards!

Jorge Gonzalez

0 Kudos
1,572 Views
juanm
Contributor III

Thanks for your answer! I have figured it out and now I have the FTM working with the interrupts. But I'm wondering why Codewarrior generate the table automatically for the KL25, but no for the K20.

I was using the enable_irq function available on the arm_cm4.c file, but I don't know why it didn't work. This is the function:

void enable_irq (int irq)

{

    int div;

   

    /* Make sure that the IRQ is an allowable number. Right now up to 61 is

     * used.

     */

    if (irq > 61)

        //printf("\nERR! Invalid IRQ value passed to enable irq function!\n");

   

    /* Determine which of the NVICISERs corresponds to the irq */

    div = irq/32;

   

    switch (div)

    {

    case 0x0:

              NVICICPR0 = 1 << (irq%32);

              NVICISER0 = 1 << (irq%32);

              break;

    case 0x1:

              NVICICPR1 = 1 << (irq%32);

              NVICISER1 = 1 << (irq%32);

              break;

    case 0x2:

              NVICICPR2 = 1 << (irq%32);

              NVICISER2 = 1 << (irq%32);

              break;

    }             

}

I put a breakpoint inside the case, but the program never enter in there. My solution was to use this:

NVICICPR0 = 1 << ((INT_FTM0-16)%32);

NVICISER0 = 1 << ((INT_FTM0-16)%32);

Instead of the enable_irq function, and the interrupts work fine now.

0 Kudos