Yahoo Groups archive

Lpc2000

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

Message

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!

Attachments

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.