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
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
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
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