Discussion Forum

lpc3131 rtx example for mdk

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
richard irving
Posted
13-Mar-2010 19:53 GMT
Toolset
ARM
New! lpc3131 rtx example for mdk

Has anyone configured RTX under MDK for an NXP LPC3131 (using the Embedded Artists dev. board)?
I saw Jeanne-Pierre's post from last year and the recommendation to use the Phytec lpc3180 blinky_rtx example as a starting point and wondered if anyone else had gotten this going yet on the lpc3131 (orlpc3130)?

Thanks

Richard Irving

Read-Only
Author
Richard Irving
Posted
18-Mar-2010 22:34 GMT
Toolset
ARM
New! RE: lpc3131 rtx example for mdk

OK, I kind of answered my own question. Got a basic port of RTX to an lpc3131 working. Had to fix up the timer irq routine and the OX_XXXX macros because the lpc3131 uses different timer IP than the lpc3180. Be glad to share if anyone is interested, with the usual "at your own risk" clauses, as it is a bit of a hack job.
Richard

Read-Only
Author
Jean-Pierre Poulin
Posted
17-Jun-2010 15:27 GMT
Toolset
ARM
New! RE: lpc3131 rtx example for mdk

Hi Richard, great work.

Would you mind sharing this port of RTX to the EA LPC313x board? I can help with testing & debugging.

Many thanks!

Jean-Pierre

Read-Only
Author
Richard Irving
Posted
17-Jun-2010 18:58 GMT
Toolset
ARM
New! RE: lpc3131 rtx example for mdk

Hello Jean-Pierre,

What I did was modify the timer code in RTX_config.c to use one of the lpc3131 timers. This has been tested in an RTX Blinky project. Here are the important code fragments. first in RTX_Config.c starting at about line 140:

/*----------------------------------------------------------------------------
 *      Global Functions
 *---------------------------------------------------------------------------*/
#include "os_macro.h"

extern void os_clock_interrupt (void) __irq;
extern void os_def_interrupt   (void) __irq;

#define INTC_VECTOR0                    (*(volatile unsigned long *)(INTC_BASE + 0x0100))
#define GPIO_MODE0_SET                  (*((volatile UNS_32 *) 0x130031D4))
#define GPIO_MODE0_RESET                (*((volatile UNS_32 *) 0x130031D8))


//__asm void IRQ_Handler_RTX (void) {
__asm void IRQ_Handler( void )
{
   /* Common IRQ Handler */
        PRESERVE8
        ARM

        STMDB   SP!,{R0}                       ; Save R0

        LDR     R0,=__cpp((U32)&INTC_VECTOR0)  ; Load INTC_VECTOR0 Address
        LDR     R0,[R0]                        ; Load INTC_VECTOR0 Value

        CMP     R0,#OS_TINT_SRC                ; Check if Timer n is source
        LDMEQIA SP!,{R0}                       ; Restore R0
        LDREQ   PC,=__cpp(os_clock_interrupt)  ; OS Clock IRQ Function

        LDMIA   SP!,{R0}                       ; Restore R0
        LDR     PC,=__cpp(os_def_interrupt)    ; OS Default IRQ Function

}

here is the include file I added, os_macro.h:

/* os_macro.h */

#ifndef _OS_MACRO_H
#define _OS_MACRO_H

#if   (OS_TIMER == 0)                                   /* Timer/Counter 0  */
 #define IRQ_TIMERn                             (5)
 #define TIMER_CNTRn                    TIMER_CNTR0
 #define CGU_SB_TIMERn_PCLK_ID  CGU_SB_TIMER0_PCLK_ID
#elif (OS_TIMER == 1)                                   /* Timer/Counter 1  */
 #define IRQ_TIMERn                             (6)
 #define TIMER_CNTRn                    TIMER_CNTR1
 #define CGU_SB_TIMERn_PCLK_ID  CGU_SB_TIMER1_PCLK_ID
#elif (OS_TIMER == 2)                                   /* Timer/Counter 2  */
 #define IRQ_TIMERn                             (7)
 #define TIMER_CNTRn                    TIMER_CNTR2
 #define CGU_SB_TIMERn_PCLK_ID  CGU_SB_TIMER2_PCLK_ID
#elif (OS_TIMER == 3)                                   /* PIT              */
 #define IRQ_TIMERn                             (8)
 #define TIMER_CNTRn                    TIMER_CNTR3
 #define CGU_SB_TIMERn_PCLK_ID  CGU_SB_TIMER3_PCLK_ID
#else
 #error OS_TIMER invalid
#endif


#define OS_TINT_SRC             (IRQ_TIMERn << 3)
#define OS_TRV                  (6000000/OS_TICK)                                          /* reload value: 1 ms                     */
#define OS_TVAL                 (0xFFFFFFFF - TIMER_CNTRn->value)              /* down counter                           */
#define OS_TIID                 ((INTC->irq_vec >> 3) & 0xFF)                  /* interrupt source id                    */
#define OS_TOVF                 (INTC->pending & IRQ_TIMERn)                   /* irq pending: overflow flag (hopefully) */
#define OS_TFIRQ()              INTC->request[IRQ_TIMERn] = (1 << 30);         /* Force Interrupt: SET_SWIT              */
/* timer interrupt acknowledge - clear it in the timer, clear it in the intc register, then toggle TICK_GPIO     */
#define OS_TIACK()              TIMER_CNTRn->clear = 0;                                                                                              \ 
                                                INTC->request[IRQ_TIMERn] = (1 << 29);                                                         \ 
                                                GPIO_MODE0_SET   = (1 << TICK_GPIO);                                                              \ 
                                                GPIO_MODE0_RESET = (1 << TICK_GPIO);                                                              \ 

#define OS_TREL()               TIMER_CNTRn->load = OS_TRV;

/* general note: timer 3 input is from CGU_SB_TIMER3_PCLK_ID which is clock #44, which is   */
/* FDC9 or FDC10 (?), anyway it is set to 6 MHz in Ext_SDRAM.ini                            */
/* !!!!!! if you use a timer other than timer3, i suppose you will have to set it's !!!!!!  */
/* !!!!!! clock also. this code does NOT futz with the clocks other than OS_TINIT() macro !!!!!!  */
/* timer clear: write to this clears the interrupt in the timer ip                          */
/* timer load: bits [31:0] is the u32 countdown value, also reload value in periodic mode   */
/* timer control: bit 7 is timer enable, bit 6 set to 1 is periodic, else free running mode */
/* intc  request: bit 30 is set sw int, bit 29 is clear sw int */
/* intc  request: bit 28 is we priority, bit 26 is we enable, bit 16 is enable interrupt    */
/* intc  request: bits [7:0] are priority level  */
#define OS_TINIT()      CGU_SB->clk_pcr[CGU_SB_TIMERn_PCLK_ID] |= 1;                            \ 
                                                TIMER_CNTRn->load         = OS_TRV;                                                  \ 
                                                TIMER_CNTRn->control      = (1 << 7) | (1 << 6);                 \ 
                                                INTC->irq_vec             = 0;                                                                               \ 
                                                INTC->irq_prio_mask       = 0;                                                                               \ 
                                                INTC->request[IRQ_TIMERn] = (1 << 28) | (1 << 26) | (1 << 16) | 1;

/* Interrupt Ack                                                                                                                                                        */
#define OS_IACK()               ;

/* OS_LOCK and OS_UNLOCK are implemented at the interrupt controller level                      */
#define OS_LOCK()       INTC->request[IRQ_TIMERn] &= ~(1 << 16);    /* disable timer interrupts */
#define OS_UNLOCK()     INTC->request[IRQ_TIMERn] |=  (1 << 16);    /* enable timer interrupts  */

#endif

Regards,
Richard

Next Thread | Thread List | Previous Thread Start a Thread | Settings