Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Timer interrupt problem

Timer interrupt problem

2004-01-23 by bobbruce000

I am using a LPC2106, and I need to monitor 16 pins for   
level changes.  Since there aren't that many external   
interrupt pins, I decided to use a timer interrupt and   
sample the pins every few microseconds.  Since this is   
the most frequent interrupt, I made it the "fast   
interrupt".   
  
But whenever I enable the timer interrupt, the interrupt   
completes one time and then everything freezes up.  I am   
pretty sure I am resetting the timer interrupt correctly.   
This is the routine (R10 is already set to 0xE0004000):   
  
fiq:    mov	r9,#0xff	// Set bottom eight bits   
	str	r9,[r10]	// Reset Timer interrupts   
	subs	pc,r14,#4	// Return from interrupt   
  
If I disable additional interrupts in the handler, then   
the interrupt returns okay, but (obviously) doesn't repeat.   
I know it is running because I added an instruction to   
turn on an LED:  
  
fiq:    mov	r9,#0xff	// Set bottom eight bits   
	str	r9,[r10]	// Reset Timer interrupts   
	str	r9,[r12]	// Light up LED   
	msr	spsr_c,#0xdf	// disable interrupts on return   
	subs	pc,r14,#4	// Return from interrupt   
  
But here is something even weirder:  If I add some nops, and   
make the routine a little longer, then it freezes up, even with   
interrupts disabled:   
  
fiq:	nop   
	nop   
	nop   
	nop   
        mov	r9,#0xff	// Set bottom eight bits   
	str	r9,[r10]	// Reset Timer interrupts   
	str	r9,[r12]	// Light up LED   
	msr	spsr_c,#0xdf	// disable interrupts on return   
	subs	pc,r14,#4	// Return from interrupt   
  
If there are three or fewer nops, the interrupt returns (once),   
but with four or more, it does not.	   
  
Please let me know if you have any idea what I am doing wrong.   
I have been fiddling with this for the last two days with no   
progress.   
	-bob   
  
ps:  Here is the C code that intializes the timer and VIC,  
     followed by the ASM startup code and FIQ handler.  
  
void   
timer0_init(void) {   
  TIMER0_PR  = 0x000000ff; // Prescaler   
  TIMER0_MR0 = 0x00000100; // Match register   
  TIMER0_MCR = 0x00000003; // Reset and interrupt on match   
  TIMER0_TCR = 0x3;	   // Enable and reset counter   
  TIMER0_TCR = 0x1;	   // Start counter   
  TIMER0_IR  = 0xff;	   // Clear any pending interrupts   
  return;   
}   
   
static void   
vic_init(void) {	// Page 61   
   
  VICIntSelect   = 0x00000010;  // The set bit is for FIQ -- Timer 0   
  VICIntEnable   = 0x00000010;  // Timer 0 interrupt is enabled   
  return;   
}   
-------------------------------------------------------------  
_start:	   
b   reset		//   0   Reset   
b   undef_isr      	//   1   Undefined Instruction   
b   swi_isr		//   2   Software Interrupt   
b   prefetch_isr	//   3   Prefetch abort   
b   data_abort_isr	//   4   Data abort   
b   reserved		//   5	 Replace with checksum   
b   irq			//   6   IRQ   
fiq:			//   7   Fast interrupt handler   
        mov	r9,#0xff	// Set bottom eight bits   
	str	r9,[r10]	// Reset Timer interrupts   
	str	r9,[r12]	// Light up LED   
	msr	spsr_c,#0xdf	// disable intrpts: fails if removed   
	subs	pc,r14,#4	// Return from interrupt   
   
.L_StackTop:	.word	0x4000ffe0  // RAM top minus 32 b for IAP   
.L_T0IR:	.word	0xE0004000  // Timer 0 IR port address   
.L_VVA:		.word	0xfffff030  // VIC Vect Addr port address   
.L_IOCLR:	.word	0xE002800C  // IOCLR address   
   
reset:   
	ldr	r0,.L_StackTop	// r0 = top of stack   
	msr	cpsr,#0xd1	// switch to FIQ mode 
	sub	sp,r0,#0x00	// Set FIQ stack pointer   
	ldr	r10,.L_T0IR	// R10 = timer0_ir address   
	ldr	r11,.L_VVA	// R11 = VICVectAddr address   
	ldr	r12,.L_IOCLR	// R12 = IOCLR address   
	// Set up stack pointers for each mode, etc.   
	mov	sp,r0		// Stack for FIQ   
	msr	cpsr,#0xd2	// Switch to IRQ mode   
	sub	sp,r0,#32	// sp_IRQ = sp_FIQ minus 32  
	msr	cpsr,#0xd7	// Switch to Abort mode   
	sub	sp,r0,#64	// Set Abort stack pointer   
	msr	cpsr,#0xdb	// Switch to Undef mode   
	sub	sp,r0,#96	// Set Undef stack pointer   
	msr	cpsr,#0xd3	// Switch to Supervisor mode   
	sub	sp,r0,#128	// Set Supervisor stack pointer   
	msr	cpsr,#0xdf	// Switch to System mode   
	sub	sp,r0,#160	// Set System (main) stack pointer   
	b	main		// Jump to main() C routine

Re: [lpc2100] Timer interrupt problem

2004-01-23 by Bogdan Marinescu

Are you sure you're using the right r10? r10 is shadowed in FIQ mode; this means that it doesn't have the same value as in user/system/supervisor mode. Try to set it explicitly in the FIQ interrupt or at system init. 

bobbruce000 <bobbruce000@...> wrote:I am using a LPC2106, and I need to monitor 16 pins for   
level changes.  Since there aren't that many external   
interrupt pins, I decided to use a timer interrupt and   
sample the pins every few microseconds.  Since this is   
the most frequent interrupt, I made it the "fast   
interrupt".   
  
But whenever I enable the timer interrupt, the interrupt   
completes one time and then everything freezes up.  I am   
pretty sure I am resetting the timer interrupt correctly.   
This is the routine (R10 is already set to 0xE0004000):   
  
fiq:    mov      r9,#0xff      // Set bottom eight bits   
      str      r9,[r10]      // Reset Timer interrupts   
      subs      pc,r14,#4      // Return from interrupt   
  
If I disable additional interrupts in the handler, then   
the interrupt returns okay, but (obviously) doesn't repeat.   
I know it is running because I added an instruction to   
turn on an LED:  
  
fiq:    mov      r9,#0xff      // Set bottom eight bits   
      str      r9,[r10]      // Reset Timer interrupts   
      str      r9,[r12]      // Light up LED   
      msr      spsr_c,#0xdf      // disable interrupts on return   
      subs      pc,r14,#4      // Return from interrupt   
  
But here is something even weirder:  If I add some nops, and   
make the routine a little longer, then it freezes up, even with   
interrupts disabled:   
  
fiq:      nop   
      nop   
      nop   
      nop   
        mov      r9,#0xff      // Set bottom eight bits   
      str      r9,[r10]      // Reset Timer interrupts   
      str      r9,[r12]      // Light up LED   
      msr      spsr_c,#0xdf      // disable interrupts on return   
      subs      pc,r14,#4      // Return from interrupt   
  
If there are three or fewer nops, the interrupt returns (once),   
but with four or more, it does not.         
  
Please let me know if you have any idea what I am doing wrong.   
I have been fiddling with this for the last two days with no   
progress.   
      -bob   
  
ps:  Here is the C code that intializes the timer and VIC,  
     followed by the ASM startup code and FIQ handler.  
  
void   
timer0_init(void) {   
  TIMER0_PR  = 0x000000ff; // Prescaler   
  TIMER0_MR0 = 0x00000100; // Match register   
  TIMER0_MCR = 0x00000003; // Reset and interrupt on match   
  TIMER0_TCR = 0x3;         // Enable and reset counter   
  TIMER0_TCR = 0x1;         // Start counter   
  TIMER0_IR  = 0xff;         // Clear any pending interrupts   
  return;   
}   
   
static void   
vic_init(void) {      // Page 61   
   
  VICIntSelect   = 0x00000010;  // The set bit is for FIQ -- Timer 0   
  VICIntEnable   = 0x00000010;  // Timer 0 interrupt is enabled   
  return;   
}   
-------------------------------------------------------------  
_start:         
b   reset            //   0   Reset   
b   undef_isr            //   1   Undefined Instruction   
b   swi_isr            //   2   Software Interrupt   
b   prefetch_isr      //   3   Prefetch abort   
b   data_abort_isr      //   4   Data abort   
b   reserved            //   5      Replace with checksum   
b   irq                  //   6   IRQ   
fiq:                  //   7   Fast interrupt handler   
        mov      r9,#0xff      // Set bottom eight bits   
      str      r9,[r10]      // Reset Timer interrupts   
      str      r9,[r12]      // Light up LED   
      msr      spsr_c,#0xdf      // disable intrpts: fails if removed   
      subs      pc,r14,#4      // Return from interrupt   
   
.L_StackTop:      .word      0x4000ffe0  // RAM top minus 32 b for IAP   
.L_T0IR:      .word      0xE0004000  // Timer 0 IR port address   
.L_VVA:            .word      0xfffff030  // VIC Vect Addr port address   
.L_IOCLR:      .word      0xE002800C  // IOCLR address   
   
reset:   
      ldr      r0,.L_StackTop      // r0 = top of stack   
      msr      cpsr,#0xd1      // switch to FIQ mode 
      sub      sp,r0,#0x00      // Set FIQ stack pointer   
      ldr      r10,.L_T0IR      // R10 = timer0_ir address   
      ldr      r11,.L_VVA      // R11 = VICVectAddr address   
      ldr      r12,.L_IOCLR      // R12 = IOCLR address   
      // Set up stack pointers for each mode, etc.   
      mov      sp,r0            // Stack for FIQ   
      msr      cpsr,#0xd2      // Switch to IRQ mode   
      sub      sp,r0,#32      // sp_IRQ = sp_FIQ minus 32  
      msr      cpsr,#0xd7      // Switch to Abort mode   
      sub      sp,r0,#64      // Set Abort stack pointer   
      msr      cpsr,#0xdb      // Switch to Undef mode   
      sub      sp,r0,#96      // Set Undef stack pointer   
      msr      cpsr,#0xd3      // Switch to Supervisor mode   
      sub      sp,r0,#128      // Set Supervisor stack pointer   
      msr      cpsr,#0xdf      // Switch to System mode   
      sub      sp,r0,#160      // Set System (main) stack pointer   
      b      main            // Jump to main() C routine   
  
   
        


Yahoo! Groups SponsorADVERTISEMENT


---------------------------------
Yahoo! Groups Links

   To visit your group on the web, go to:
http://groups.yahoo.com/group/lpc2100/
  
   To unsubscribe from this group, send an email to:
lpc2100-unsubscribe@yahoogroups.com
  
   Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service. 




---------------------------------
Do you Yahoo!?
Yahoo! SiteBuilder - Free web site building tool. Try it!

Re: Timer interrupt problem

2004-01-23 by Richard

Why not use timer/capture instead of polling pins?

Richard

--- In lpc2100@yahoogroups.com, Bogdan Marinescu 
<a_bogdan_marinescu@y...> wrote:
>     Are you sure you're using the right r10? r10 is shadowed in FIQ 
mode; this means that it doesn't have the same value as in 
user/system/supervisor mode. Try to set it explicitly in the FIQ 
interrupt or at system init. 
> 
> bobbruce000 <bobbruce000@y...> wrote:I am using a LPC2106, and I 
need to monitor 16 pins for   
> level changes.  Since there aren't that many external   
> interrupt pins, I decided to use a timer interrupt and   
> sample the pins every few microseconds.  Since this is   
> the most frequent interrupt, I made it the "fast   
> interrupt".   
>   
> But whenever I enable the timer interrupt, the interrupt   
> completes one time and then everything freezes up.  I am   
> pretty sure I am resetting the timer interrupt correctly.   
> This is the routine (R10 is already set to 0xE0004000):   
>   
> fiq:    mov      r9,#0xff      // Set bottom eight bits   
>       str      r9,[r10]      // Reset Timer interrupts   
>       subs      pc,r14,#4      // Return from interrupt   
>   
> If I disable additional interrupts in the handler, then   
> the interrupt returns okay, but (obviously) doesn't repeat.   
> I know it is running because I added an instruction to   
> turn on an LED:  
>   
> fiq:    mov      r9,#0xff      // Set bottom eight bits   
>       str      r9,[r10]      // Reset Timer interrupts   
>       str      r9,[r12]      // Light up LED   
>       msr      spsr_c,#0xdf      // disable interrupts on return   
>       subs      pc,r14,#4      // Return from interrupt   
>   
> But here is something even weirder:  If I add some nops, and   
> make the routine a little longer, then it freezes up, even with   
> interrupts disabled:   
>   
> fiq:      nop   
>       nop   
>       nop   
>       nop   
>         mov      r9,#0xff      // Set bottom eight bits   
>       str      r9,[r10]      // Reset Timer interrupts   
>       str      r9,[r12]      // Light up LED   
>       msr      spsr_c,#0xdf      // disable interrupts on return   
>       subs      pc,r14,#4      // Return from interrupt   
>   
> If there are three or fewer nops, the interrupt returns (once),   
> but with four or more, it does not.         
>   
> Please let me know if you have any idea what I am doing wrong.   
> I have been fiddling with this for the last two days with no   
> progress.   
>       -bob   
>   
> ps:  Here is the C code that intializes the timer and VIC,  
>      followed by the ASM startup code and FIQ handler.  
>   
> void   
> timer0_init(void) {   
>   TIMER0_PR  = 0x000000ff; // Prescaler   
>   TIMER0_MR0 = 0x00000100; // Match register   
>   TIMER0_MCR = 0x00000003; // Reset and interrupt on match   
>   TIMER0_TCR = 0x3;         // Enable and reset counter   
>   TIMER0_TCR = 0x1;         // Start counter   
>   TIMER0_IR  = 0xff;         // Clear any pending interrupts   
>   return;   
> }   
>    
> static void   
> vic_init(void) {      // Page 61   
>    
>   VICIntSelect   = 0x00000010;  // The set bit is for FIQ -- Timer 
0   
>   VICIntEnable   = 0x00000010;  // Timer 0 interrupt is enabled   
>   return;   
> }   
> -------------------------------------------------------------  
> _start:         
> b   reset            //   0   Reset   
> b   undef_isr            //   1   Undefined Instruction   
> b   swi_isr            //   2   Software Interrupt   
> b   prefetch_isr      //   3   Prefetch abort   
> b   data_abort_isr      //   4   Data abort   
> b   reserved            //   5      Replace with checksum   
> b   irq                  //   6   IRQ   
> fiq:                  //   7   Fast interrupt handler   
>         mov      r9,#0xff      // Set bottom eight bits   
>       str      r9,[r10]      // Reset Timer interrupts   
>       str      r9,[r12]      // Light up LED   
>       msr      spsr_c,#0xdf      // disable intrpts: fails if 
removed   
>       subs      pc,r14,#4      // Return from interrupt   
>    
> .L_StackTop:      .word      0x4000ffe0  // RAM top minus 32 b for 
IAP   
> .L_T0IR:      .word      0xE0004000  // Timer 0 IR port address   
> .L_VVA:            .word      0xfffff030  // VIC Vect Addr port 
address   
> .L_IOCLR:      .word      0xE002800C  // IOCLR address   
>    
> reset:   
>       ldr      r0,.L_StackTop      // r0 = top of stack   
>       msr      cpsr,#0xd1      // switch to FIQ mode 
>       sub      sp,r0,#0x00      // Set FIQ stack pointer   
>       ldr      r10,.L_T0IR      // R10 = timer0_ir address   
>       ldr      r11,.L_VVA      // R11 = VICVectAddr address   
>       ldr      r12,.L_IOCLR      // R12 = IOCLR address   
>       // Set up stack pointers for each mode, etc.   
>       mov      sp,r0            // Stack for FIQ   
>       msr      cpsr,#0xd2      // Switch to IRQ mode   
>       sub      sp,r0,#32      // sp_IRQ = sp_FIQ minus 32  
>       msr      cpsr,#0xd7      // Switch to Abort mode   
>       sub      sp,r0,#64      // Set Abort stack pointer   
>       msr      cpsr,#0xdb      // Switch to Undef mode   
>       sub      sp,r0,#96      // Set Undef stack pointer   
>       msr      cpsr,#0xd3      // Switch to Supervisor mode   
>       sub      sp,r0,#128      // Set Supervisor stack pointer   
>       msr      cpsr,#0xdf      // Switch to System mode   
>       sub      sp,r0,#160      // Set System (main) stack pointer   
>       b      main            // Jump to main() C routine   
>   
>    
>         
> 
> 
> Yahoo! Groups SponsorADVERTISEMENT
> 
> 
> ---------------------------------
> Yahoo! Groups Links
> 
>    To visit your group on the web, go to:
> http://groups.yahoo.com/group/lpc2100/
>   
>    To unsubscribe from this group, send an email to:
> lpc2100-unsubscribe@yahoogroups.com
>   
>    Your use of Yahoo! Groups is subject to the Yahoo! Terms of 
Service. 
Show quoted textHide quoted text
> 
> 
> 
> 
> ---------------------------------
> Do you Yahoo!?
> Yahoo! SiteBuilder - Free web site building tool. Try it!

Message 648

2004-01-24 by bobbruce000

--- In lpc2100@yahoogroups.com, Bogdan Marinescu  
<a_bogdan_marinescu@y...> wrote:  
>     Are you sure you're using the right r10? r10 is shadowed in 
> FIQ mode; this means that it doesn't have the same value as in 
> user/system/supervisor mode. Try to set it explicitly in the FIQ  
> interrupt or at system init.  
  
Yes, I am sure the value in R10 is correct.  It is set during  
system init while in FIQ mode.  To double check, I wrote a  
routine to send the value out the serial port, and I checked  
it before and after the interrupt to make sure it wasn't getting  
corrupted.  
  
Here is the reset routine that sets R10:  
  
> .L_StackTop:  .word      0x4000ffe0  // RAM top minus 32 b for IAP     
> .L_T0IR:      .word      0xE0004000  // Timer 0 IR port address     
> .L_VVA:       .word      0xfffff030  // VIC Vect Addr port address     
> .L_IOCLR:     .word      0xE002800C  // IOCLR address     
>      
> reset:     
>       ldr      r0,.L_StackTop   // r0 = top of stack     
>       msr      cpsr,#0xd1       // switch to FIQ mode   
>       sub      sp,r0,#0x00      // Set FIQ stack pointer     
>       ldr      r10,.L_T0IR      // R10 = timer0_ir address  
  
	-bob

Re: Timer interrupt problem

2004-01-24 by bobbruce000

--- In lpc2100@yahoogroups.com, "Richard" <richas@y...> wrote: 
> Why not use timer/capture instead of polling pins? 
 
Because I need to monitor 16 pins and there are only seven 
pins configurable as capture triggers. 
 
	-bob 
Show quoted textHide quoted text
> > bobbruce000 <bobbruce000@y...> wrote: 
> I am using a LPC2106, and I need to monitor 16 pins for    
> > level changes.  Since there aren't that many external    
> > interrupt pins, I decided to use a timer interrupt and    
> > sample the pins every few microseconds.  Since this is    
> > the most frequent interrupt, I made it the "fast    
> > interrupt".

Re: Timer interrupt problem

2004-01-26 by lpc2100_fan

Hi bob,

don't know your environment, so just a thought. In case the frequency
on the pins to monitor is predictable and different between the pins,
it might be an idea to use the capture pins for the pins with the
shortest time beteen pulses and the regular INT for the remaining 9
inputs, this would give you the option to use the FIQ for anything
(more?) urgent.

Cheers, Bob

--- In lpc2100@yahoogroups.com, "bobbruce000" <bobbruce000@y...> wrote:
> --- In lpc2100@yahoogroups.com, "Richard" <richas@y...> wrote: 
> > Why not use timer/capture instead of polling pins? 
>  
> Because I need to monitor 16 pins and there are only seven 
> pins configurable as capture triggers. 
>  
> 	-bob 
-snip --------
 Since there aren't that many external    
Show quoted textHide quoted text
> > > interrupt pins, I decided to use a timer interrupt and    
> > > sample the pins every few microseconds.  Since this is    
> > > the most frequent interrupt, I made it the "fast    
> > > interrupt".

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.