EmbeddedRelated.com
Forums

LPC2106 Timer0 configuration & Interrupt ..newbie..!

Started by gtpats June 19, 2009
Hi

I am trying to configure timer0 and get an interrupt on match.

Using LPC2106 olimex board. 14.7456MHz crystal.
I am not able to get into the ISR where i am trying to ON a LED. Please let me know what I must do, here is the code
#define VICINTSEL (*((volatile unsigned long *) 0xFFFFF00C))
#define VICINTEN (*((volatile unsigned long *) 0xFFFFF010))
#define VICCNTL0 (*((volatile unsigned long *) 0xFFFFF200))
#define VICVADDR0 (*((volatile unsigned long *) 0xFFFFF100))
#define VICVADDR (*((volatile unsigned long *) 0xFFFFF030))
#define T0_TCR (*((volatile unsigned long *) 0xE0004004))
#define T0_TC (*((volatile unsigned long *) 0xE0004008))
#define T0_MCR (*((volatile unsigned long *) 0xE0004014))
#define T0_MR0 (*((volatile unsigned long *) 0xE0004018))
#define T0_PR (*((volatile unsigned long *) 0xE000400C))

void T0_init(void);
void T0_ISR(void) __attribute__ ((interrupt("IRQ")));

volatile unsigned int Counter = 0; // to keep track of counter

void PLL_Init(void)
{
// Olimex 2106 board had 14.7456Mhz external crystal
// To run the clk as close to 60Mhz
// M = cclk/Fosc; M= 60/14.7456 = 4.0
// Fcco = cclk * 2 * P where: Fcco = CCO frequency
// 156< Fcco <320 = 60*2*P => (say Fcco) 240 = 120P => P=2
// Finally PLLCFG = 0 10 00011 = 0x0000 0023
PLLCFG = 0x00000023; // P = 2 ; M = 4-1 = 3
PLLFEED = 0x000000AA; // Update PLL registers with feed sequence
PLLFEED = 0x00000055;

PLLCON = 0x00000001; //PLL Enable.
PLLFEED = 0x000000AA; // Update PLL registers with feed sequence
PLLFEED = 0x00000055;

// Wait for the PLL to lock to set frequency
while (!(PLLSTAT & 0x00000400)); // test Lock bit
// Connect the PLL as the clock source
PLLCON = 0x00000003;
PLLFEED = 0x000000AA; // Update PLL registers with feed sequence
PLLFEED = 0x00000055;

// Enabling MAM
MAM_MAMCR=0x2;
MAMTIM=0x4;

// Setting peripheral Clock (pclk) to System Clock (cclk)
VPBDIV=0x1;

}

void T0_init(void)
{
T0_TC = 0; // clear the timer count
T0_PR = 0; // prescale divide by 1, TC increments every pclk
T0_TCR = 0x03; // start the timer
T0_MR0 = 589824000; // Interrupt when TC reaches this val 1 sec
T0_MCR = 0x03; // interrupt on match, reset on match
T0_TCR = 0x01; // start the timer
T0_PC=0x0;

VICINTSEL = 0x20;
VICVectCntl0 = 0x00000024; // set priority for Timer 0
VICVectAddr0 = (unsigned long) T0_ISR; // pass the address of the ISR
VICIntEnable = 0x00000010; // enable interrupt
}

void T0_ISR(void) // interrupt handler - see timer.h
{
Counter++;
GPIO_IOCLR |= (1<
T0_IR = 0x01;
VICVectAddr = 0xff;
}

int main(void)
{
GPIO_IODIR |= (1<
PLL_Init();
T0_init();

while(1)
{

}

}

have been struggling to get this going...!!

An Engineer's Guide to the LPC2100 Series

--- In l..., "gtpats" wrote:
>
> Hi
>
> I am trying to configure timer0 and get an interrupt on match.
>
> Using LPC2106 olimex board. 14.7456MHz crystal.
> I am not able to get into the ISR where i am trying to ON a LED. Please let me know what I must do, here is the code
> #define VICINTSEL (*((volatile unsigned long *) 0xFFFFF00C))
> #define VICINTEN (*((volatile unsigned long *) 0xFFFFF010))
> #define VICCNTL0 (*((volatile unsigned long *) 0xFFFFF200))
> #define VICVADDR0 (*((volatile unsigned long *) 0xFFFFF100))
> #define VICVADDR (*((volatile unsigned long *) 0xFFFFF030))
> #define T0_TCR (*((volatile unsigned long *) 0xE0004004))
> #define T0_TC (*((volatile unsigned long *) 0xE0004008))
> #define T0_MCR (*((volatile unsigned long *) 0xE0004014))
> #define T0_MR0 (*((volatile unsigned long *) 0xE0004018))
> #define T0_PR (*((volatile unsigned long *) 0xE000400C))
>
> void T0_init(void);
> void T0_ISR(void) __attribute__ ((interrupt("IRQ")));

No... If you want to use the VIC, the proper prototype is:

void T0_ISR(void) __attribute__ ((interrupt));

>
> volatile unsigned int Counter = 0; // to keep track of counter
>
> void PLL_Init(void)
> {
> // Olimex 2106 board had 14.7456Mhz external crystal
> // To run the clk as close to 60Mhz
> // M = cclk/Fosc; M= 60/14.7456 = 4.0
> // Fcco = cclk * 2 * P where: Fcco = CCO frequency
> // 156< Fcco <320 = 60*2*P => (say Fcco) 240 = 120P => P=2
> // Finally PLLCFG = 0 10 00011 = 0x0000 0023
> PLLCFG = 0x00000023; // P = 2 ; M = 4-1 = 3
> PLLFEED = 0x000000AA; // Update PLL registers with feed sequence
> PLLFEED = 0x00000055;
>
> PLLCON = 0x00000001; //PLL Enable.
> PLLFEED = 0x000000AA; // Update PLL registers with feed sequence
> PLLFEED = 0x00000055;
>
> // Wait for the PLL to lock to set frequency
> while (!(PLLSTAT & 0x00000400)); // test Lock bit
> // Connect the PLL as the clock source
> PLLCON = 0x00000003;
> PLLFEED = 0x000000AA; // Update PLL registers with feed sequence
> PLLFEED = 0x00000055;
>
> // Enabling MAM
> MAM_MAMCR=0x2;
> MAMTIM=0x4;
>
> // Setting peripheral Clock (pclk) to System Clock (cclk)
> VPBDIV=0x1;
>
> }
>
> void T0_init(void)
> {
> T0_TC = 0; // clear the timer count
> T0_PR = 0; // prescale divide by 1, TC increments every pclk
> T0_TCR = 0x03; // start the timer
> T0_MR0 = 589824000; // Interrupt when TC reaches this val 1 sec
> T0_MCR = 0x03; // interrupt on match, reset on match
> T0_TCR = 0x01; // start the timer
> T0_PC=0x0;
>

> VICINTSEL = 0x20;
Hm... I don't use this... In any event, it sets up Timer1 as FIQ and we're working with Timer0. You don't want to use FIQ anyway because you are using VIC

> VICVectCntl0 = 0x00000024; // set priority for Timer 0
> VICVectAddr0 = (unsigned long) T0_ISR; // pass the address of the ISR
I am using priority 3 but it doesn't matter...

> VICIntEnable = 0x00000010; // enable interrupt
> }
>
> void T0_ISR(void) // interrupt handler - see timer.h
> {
> Counter++;
> GPIO_IOCLR |= (1<

This absolutely won't work! You have to use IOSET and IOCLR as

Counter++;
if ( (Counter & 0x00000001) )
GPIO_IOSET = (1 << LED);
else
GPIO_IOCLR = (1 << LED);
>
> T0_IR = 0x01;
> VICVectAddr = 0xff;
> }
>
> int main(void)
> {
> GPIO_IODIR |= (1< >
> PLL_Init();
> T0_init();
>
> while(1)
> {
>
> }
>
> }
>
> have been struggling to get this going...!!
>
Finally, unless the line of code before 'b main' in crt.s (or whatever your startup code is named) has something like

MSR CPSR_c,#MODE_SVC

you aren't going to get any interrupts no matter how hard you try.

I suggest starting in Supervisor mode now because FreeRTOS requires it and you'll get there sooner or later.

Every previous incantation of MSR CPSR_C in the code has had |I_BIT|F_BIT set which DISABLES interrupts for that mode.

Richard

Hi Richard,

Thank you for the help, i have revised my code as suggested

> Finally, unless the line of code before 'b main' in crt.s (or whatever
your startup code is named) has something like
>
> MSR CPSR_c,#MODE_SVC

In my crt0.s file i already have the following

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------
ldr r0,=_stack
msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
mov sp,r0
sub r0,r0,#UND_STACK_SIZE
msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
mov sp,r0
sub r0,r0,#ABT_STACK_SIZE
msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
mov sp,r0
sub r0,r0,#FIQ_STACK_SIZE
msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
mov sp,r0
sub r0,r0,#IRQ_STACK_SIZE
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
mov sp,r0
sub r0,r0,#SVC_STACK_SIZE
msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
mov sp,r0
>

> Every previous incantation of MSR CPSR_C in the code has had
|I_BIT|F_BIT set which DISABLES interrupts for that mode.

I am sorry i did not understand the above line.

Is there any other code that I should include?

Thanx
cal,



--- In l..., "gtpats" wrote:
>
> Hi Richard,
>
> Thank you for the help, i have revised my code as suggested
>
> > Finally, unless the line of code before 'b main' in crt.s (or whatever
> your startup code is named) has something like
> >
> > MSR CPSR_c,#MODE_SVC
>
> In my crt0.s file i already have the following
>
> // Initialize Interrupt System
> // - Set stack location for each mode
> // - Leave in System Mode with Interrupts Disabled
> // -----------
> ldr r0,=_stack
> msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
> mov sp,r0
> sub r0,r0,#UND_STACK_SIZE
> msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
> mov sp,r0
> sub r0,r0,#ABT_STACK_SIZE
> msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
> mov sp,r0
> sub r0,r0,#FIQ_STACK_SIZE
> msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
> mov sp,r0
> sub r0,r0,#IRQ_STACK_SIZE
> msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
> mov sp,r0
> sub r0,r0,#SVC_STACK_SIZE
> msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
> mov sp,r0
> > > Every previous incantation of MSR CPSR_C in the code has had
> |I_BIT|F_BIT set which DISABLES interrupts for that mode.
>
> I am sorry i did not understand the above line.
>
> Is there any other code that I should include?
>
> Thanx
> cal,

Absolutely you need to add code. Note that in every mode switch the interrupt bits were turned OFF. They stay off. So, no matter which mode you run in, you won't get any interrupts. Ever...

Put this one line of code just before the line that branches to main:

MSR CPSR_c,#MODE_SVC <----- add this line!
b main

This will start your code in supervisor mode (you don't care) with both IRQ and FIQ interrupts enabled.

Richard

Thank you again..

this is my crt0.S file you had asked me to add
> MSR CPSR_c,#MODE_SVC <----- add this line!
Maybe this is too trivial, but am not able to figure out where to add
this line,

where in the below code should I add the above line?

.global main // int main(void)

.global _etext // -> .data initial values in
ROM
.global _data // -> .data area in RAM
.global _edata // end of .data area
.global __bss_start // -> .bss area in RAM
.global __bss_end__ // end of .bss area
.global _stack // top of stack

// Stack Sizes
.set UND_STACK_SIZE, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000004
.set IRQ_STACK_SIZE, 0X00000080
.set SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
.set MODE_USR, 0x10 // User Mode
.set MODE_FIQ, 0x11 // FIQ Mode
.set MODE_IRQ, 0x12 // IRQ Mode
.set MODE_SVC, 0x13 // Supervisor Mode
.set MODE_ABT, 0x17 // Abort Mode
.set MODE_UND, 0x1B // Undefined Mode
.set MODE_SYS, 0x1F // System Mode

.equ I_BIT, 0x80 // when I bit is set, IRQ is
disabled
.equ F_BIT, 0x40 // when F bit is set, FIQ is
disabled

.text
.code 32
.align 2

.global _boot
.func _boot
_boot:

// Runtime Interrupt Vectors
// -------------------------
Vectors:
b _start // reset - _start
ldr pc,_undf // undefined - _undf
ldr pc,_swi // SWI - _swi
ldr pc,_pabt // program abort - _pabt
ldr pc,_dabt // data abort - _dabt
nop // reserved
ldr pc,[pc,#-0xFF0] // IRQ - read the VIC
ldr pc,_fiq // FIQ - _fiq

#if 0
// Use this group for production
_undf: .word _reset // undefined - _reset
_swi: .word _reset // SWI - _reset
_pabt: .word _reset // program abort - _reset
_dabt: .word _reset // data abort - _reset
_irq: .word _reset // IRQ - _reset
_fiq: .word _reset // FIQ - _reset

#else
// Use this group for development
_undf: .word __undf // undefined
_swi: .word __swi // SWI
_pabt: .word __pabt // program abort
_dabt: .word __dabt // data abort
_irq: .word __irq // IRQ
_fiq: .word __fiq // FIQ

__undf: b . // undefined
__swi: b . // SWI
__pabt: b . // program abort
__dabt: b . // data abort
__irq: b . // IRQ
__fiq: b . // FIQ
#endif
.size _boot, . - _boot
.endfunc
// Setup the operating mode & stack.
// ---------------------------------
.global _start, start, _mainCRTStartup
.func _start

_start:
start:
_mainCRTStartup:

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------
ldr r0,=_stack
msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
mov sp,r0
sub r0,r0,#UND_STACK_SIZE
msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
mov sp,r0
sub r0,r0,#ABT_STACK_SIZE
msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
mov sp,r0
sub r0,r0,#FIQ_STACK_SIZE
msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
mov sp,r0
sub r0,r0,#IRQ_STACK_SIZE
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
mov sp,r0
sub r0,r0,#SVC_STACK_SIZE
msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
mov sp,r0

// Copy initialized data to its execution address in RAM
// -----------------
#ifdef ROM_RUN
ldr r1,=_etext // -> ROM data start
ldr r2,=_data // -> data start
ldr r3,=_edata // -> end of data
1: cmp r2,r3 // check if data to move
ldrlo r0,[r1],#4 // copy it
strlo r0,[r2],#4
blo 1b // loop until done
#endif
// Clear .bss
// ----------
mov r0,#0 // get a zero
ldr r1,=__bss_start // -> bss start
ldr r2,=__bss_end__ // -> bss end
2: cmp r1,r2 // check if data to clear
strlo r0,[r1],#4 // clear 4 bytes
blo 2b // loop until done

// Call main program: main(0)
// --------------------------
mov r0,#0 // no arguments (argc = 0)
mov r1,r0
mov r2,r0
mov fp,r0 // null frame pointer
mov r7,r0 // null frame pointer for thumb
ldr r10,=main
mov lr,pc
bx r10 // enter main()

.size _start, . - _start
.endfunc

.global _reset, reset, exit, abort
.func _reset
_reset:
reset:
exit:
abort:
#if 0
// Disable interrupts, then force a hardware reset by driving P23 low
// -------------------------------
mrs r0,cpsr // get PSR
orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ
msr cpsr,r0 // set up status register

ldr r1,=(PS_BASE) // PS Base Address
ldr r0,=(PS_PIO) // PIO Module
str r0,[r1,#PS_PCER_OFF] // enable its clock
ldr r1,=(PIO_BASE) // PIO Base Address
ldr r0,=(1<<23) // P23
str r0,[r1,#PIO_PER_OFF] // make sure pin is contolled by
PIO
str r0,[r1,#PIO_CODR_OFF] // set the pin low
str r0,[r1,#PIO_OER_OFF] // make it an output

#endif

b . // loop until reset

.size _reset, . - _reset
.endfunc

.end



--- In l..., "gtpats" wrote:
>
> Thank you again..
>
> this is my crt0.S file you had asked me to add
> > MSR CPSR_c,#MODE_SVC <----- add this line!
> Maybe this is too trivial, but am not able to figure out where to add
> this line,
>
> where in the below code should I add the above line?
>
> .global main // int main(void)
>
> .global _etext // -> .data initial values in
> ROM
> .global _data // -> .data area in RAM
> .global _edata // end of .data area
> .global __bss_start // -> .bss area in RAM
> .global __bss_end__ // end of .bss area
> .global _stack // top of stack
>
> // Stack Sizes
> .set UND_STACK_SIZE, 0x00000004
> .set ABT_STACK_SIZE, 0x00000004
> .set FIQ_STACK_SIZE, 0x00000004
> .set IRQ_STACK_SIZE, 0X00000080
> .set SVC_STACK_SIZE, 0x00000004
>
> // Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
> .set MODE_USR, 0x10 // User Mode
> .set MODE_FIQ, 0x11 // FIQ Mode
> .set MODE_IRQ, 0x12 // IRQ Mode
> .set MODE_SVC, 0x13 // Supervisor Mode
> .set MODE_ABT, 0x17 // Abort Mode
> .set MODE_UND, 0x1B // Undefined Mode
> .set MODE_SYS, 0x1F // System Mode
>
> .equ I_BIT, 0x80 // when I bit is set, IRQ is
> disabled
> .equ F_BIT, 0x40 // when F bit is set, FIQ is
> disabled
>
> .text
> .code 32
> .align 2
>
> .global _boot
> .func _boot
> _boot:
>
> // Runtime Interrupt Vectors
> // -------------------------
> Vectors:
> b _start // reset - _start
> ldr pc,_undf // undefined - _undf
> ldr pc,_swi // SWI - _swi
> ldr pc,_pabt // program abort - _pabt
> ldr pc,_dabt // data abort - _dabt
> nop // reserved
> ldr pc,[pc,#-0xFF0] // IRQ - read the VIC
> ldr pc,_fiq // FIQ - _fiq
>
> #if 0
> // Use this group for production
> _undf: .word _reset // undefined - _reset
> _swi: .word _reset // SWI - _reset
> _pabt: .word _reset // program abort - _reset
> _dabt: .word _reset // data abort - _reset
> _irq: .word _reset // IRQ - _reset
> _fiq: .word _reset // FIQ - _reset
>
> #else
> // Use this group for development
> _undf: .word __undf // undefined
> _swi: .word __swi // SWI
> _pabt: .word __pabt // program abort
> _dabt: .word __dabt // data abort
> _irq: .word __irq // IRQ
> _fiq: .word __fiq // FIQ
>
> __undf: b . // undefined
> __swi: b . // SWI
> __pabt: b . // program abort
> __dabt: b . // data abort
> __irq: b . // IRQ
> __fiq: b . // FIQ
> #endif
> .size _boot, . - _boot
> .endfunc
> // Setup the operating mode & stack.
> // ---------------------------------
> .global _start, start, _mainCRTStartup
> .func _start
>
> _start:
> start:
> _mainCRTStartup:
>
> // Initialize Interrupt System
> // - Set stack location for each mode
> // - Leave in System Mode with Interrupts Disabled
> // -----------
> ldr r0,=_stack
> msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
> mov sp,r0
> sub r0,r0,#UND_STACK_SIZE
> msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
> mov sp,r0
> sub r0,r0,#ABT_STACK_SIZE
> msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
> mov sp,r0
> sub r0,r0,#FIQ_STACK_SIZE
> msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
> mov sp,r0
> sub r0,r0,#IRQ_STACK_SIZE
> msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
> mov sp,r0
> sub r0,r0,#SVC_STACK_SIZE
> msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
> mov sp,r0
>
> // Copy initialized data to its execution address in RAM
> // -----------------
> #ifdef ROM_RUN
> ldr r1,=_etext // -> ROM data start
> ldr r2,=_data // -> data start
> ldr r3,=_edata // -> end of data
> 1: cmp r2,r3 // check if data to move
> ldrlo r0,[r1],#4 // copy it
> strlo r0,[r2],#4
> blo 1b // loop until done
> #endif
> // Clear .bss
> // ----------
> mov r0,#0 // get a zero
> ldr r1,=__bss_start // -> bss start
> ldr r2,=__bss_end__ // -> bss end
> 2: cmp r1,r2 // check if data to clear
> strlo r0,[r1],#4 // clear 4 bytes
> blo 2b // loop until done
>

// **************************************************
// Put it here
// **************************************************

msr CPSR_c,#MODE_SVC // enable interrupts, supervisor mode

>
> // Call main program: main(0)
> // --------------------------
> mov r0,#0 // no arguments (argc = 0)
> mov r1,r0
> mov r2,r0
> mov fp,r0 // null frame pointer
> mov r7,r0 // null frame pointer for thumb
> ldr r10,=main
> mov lr,pc
> bx r10 // enter main()
>
> .size _start, . - _start
> .endfunc
>
> .global _reset, reset, exit, abort
> .func _reset
> _reset:
> reset:
> exit:
> abort:
> #if 0
> // Disable interrupts, then force a hardware reset by driving P23 low
> // -------------------------------
> mrs r0,cpsr // get PSR
> orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ
> msr cpsr,r0 // set up status register
>
> ldr r1,=(PS_BASE) // PS Base Address
> ldr r0,=(PS_PIO) // PIO Module
> str r0,[r1,#PS_PCER_OFF] // enable its clock
> ldr r1,=(PIO_BASE) // PIO Base Address
> ldr r0,=(1<<23) // P23
> str r0,[r1,#PIO_PER_OFF] // make sure pin is contolled by
> PIO
> str r0,[r1,#PIO_CODR_OFF] // set the pin low
> str r0,[r1,#PIO_OER_OFF] // make it an output
> #endif
>
> b . // loop until reset
>
> .size _reset, . - _reset
> .endfunc
>
> .end
>
>
See above embedded...

That's a pretty complex way to enter (actually CALL) an embedded program that, by definition, can not return. However, it does trap the errant program that DOES return so I guess it might be a good idea.

In fact, that code is worrisome in other ways. Who says P23 is reserved for a hardware reset?

Richard

Quoting rtstofer :



>> .global _reset, reset, exit, abort
>> .func _reset
>> _reset:
>> reset:
>> exit:
>> abort:
>> #if 0
>> // Disable interrupts, then force a hardware reset by driving P23 low
>> // -------------------------------
>> mrs r0,cpsr // get PSR
>> orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ
>> msr cpsr,r0 // set up status register
>>
>> ldr r1,=(PS_BASE) // PS Base Address
>> ldr r0,=(PS_PIO) // PIO Module
>> str r0,[r1,#PS_PCER_OFF] // enable its clock
>> ldr r1,=(PIO_BASE) // PIO Base Address
>> ldr r0,=(1<<23) // P23
>> str r0,[r1,#PIO_PER_OFF] // make sure pin is contolled by
>> PIO
>> str r0,[r1,#PIO_CODR_OFF] // set the pin low
>> str r0,[r1,#PIO_OER_OFF] // make it an output
>> #endif
>>
>> b . // loop until reset
>>
>> .size _reset, . - _reset
>> .endfunc
>>
>> .end

< rtstofer wrote....>

>
> See above embedded...
>
> That's a pretty complex way to enter (actually CALL) an embedded
> program that, by definition, can not return. However, it does trap
> the errant program that DOES return so I guess it might be a good
> idea.
>
> In fact, that code is worrisome in other ways. Who says P23 is
> reserved for a hardware reset?
>
> Richard
>
Richard, if you look closely at the code you'll notice that this
persons reset/abort code has a large portion compiled out with an #if
0 and then only sits in an "infinite" do nothing loop - without
referencing P23..

Just saying... :-)

----------------------------------
Jim Norton

"Wrong is wrong even if everyone is doing it; Right is right even if no
one is doing it." -St. Augustine.
-----------------------------------
--- In l..., Jim Norton wrote:
>
> Richard, if you look closely at the code you'll notice that this
> persons reset/abort code has a large portion compiled out with an #if
> 0 and then only sits in an "infinite" do nothing loop - without
> referencing P23..
>
> Just saying... :-)
>
> ----------------------------------
> Jim Norton
>

Yup! It's commented out.

By way of 'mea culpa', I have posted a file 'Blinky.zip' which is a complete interrupt driven blinking LED for the Olimex LPC-P2106 board.

This code started life as a 'heartbeat' for another project so if there appear to be odd remnants, that's why.

The Makefile is the most likely target for platform related changes. The location of lpc21isp (the device programmer) is a candidate (ISP macro) as is the fact that I used YAGARTO under WinXP.

But the code should result in an LED that blinks on-off about once per second.

Richard

Thank you very much Richard..!!

blinky example was really helpful..

thankx
calvin