Greetings: I am experiencing interrupt detection failures with multiple LPC2103 timer IRQs assigned to different VIC channels. My installation is from the Olimex ARM-USB-OCD distribution CD. The GCC compiler version is 4.0.2. With "timer0", match register 0 interrupt assigned to IRQ0 the timer0 interrupt works as expected. When I add a second IRQ, in this case "timer3", match register 1 to IRQ1 then the IRQ0 interrupt is no longer detected. I have read the VIC registers and confirmed both interrupt channels are enabled and have the proper VIC channel vector addresses. I have swapped interrupt channels and found the timer0 interrupt still works by itself but stops when the timer3 IRQ is placed in this case on IRQ0. The code execution does seem to exit the first handler OK and return to the main program but then the second pending interrupt is not detected. If I disable the "timer3" IRQ then the original timer0 interrupt again works normally. Sometimes the execution becomes trapped within the "UnDef" forever loop. For reference I have included my interrupt related code to the end of this post. I noticed there is an outstanding GCC bug registered for "arm-elf-gcc" regarding incorrect IRQ code generation but I don't understand GCC well enough to determine if it might apply to this case. It would be most helpful if I could find examples of GCC code for multiple LPC2xxx VIC IRQs. The examples I have seen so far are for single interrupt sources. I wonder if anyone in this group knows of working GCC code with multiple VIC IRQ interrupts that I could study? If so please either point me to it or post the initialization code and the associated IRQ handler routines here. Many thanks in advance for any enlightenment! Tom Alldread Here are some snips of my interrupt related code: #define VICVectCntl_ENABLE (1<<5) #define VIC_Channel_Timer0 4 #define VIC_Channel_Timer3 27 #define TxTCR_COUNTER_ENABLE (1<<0) #define TxTCR_COUNTER_RESET (1<<1) #define TxEMR_MAT0_Toggle ((1<<5)|(1<<4)) // #define TxEMR_MAT1_Toggle ((1<<6)|(1<<7)) // //Function declarations void tc0_cmp(void) _attribute_ ((interrupt("IRQ"))); void tc3_cmp(void) _attribute_ ((interrupt("IRQ"))); /*************************ISR Functions*******************************/ /* Timer0 Compare-Match Interrupt Handler (ISR) */ void tc0_cmp(void) { timeval++; T0_IR = MR0Int; // Clear interrupt flag by writing 1 to Bit 0 VICVectAddr = 0xff; // Acknowledge Interrupt (rough?) } /* Timer3 Compare-Match Interrupt Handler (ISR) */ void tc3_cmp(void) { unsigned int a,b,c,d,e,f; a = VICVectAddr; b = T0_IR; c = T3_IR; d = VICVectAddr; //test e = VICDefVectAddr; if (T3_IR && MR1Int){//end of 1200 baud period phaseStepPntr_ui16=0;//point to phase 0 degree 50% duty cycle datum T3_MR0 = lowToneSinPW_ui16[phaseStepPntr_ui16++];// next set output high count // Phase 0 set high count 50% duty cycle T3_IR = MR1Int; // Clear match register 1 interrupt flag (by writing 1 to it) } if (T3_IR && MR0Int){ // else { T3_MR0 = lowToneSinPW_ui16[phaseStepPntr_ui16++];// set next toggle count T3_IR = MR0Int; // Clear match register 0 interrupt flag (by writing 1 to it) } VICVectAddr = 0xff; // Acknowledge Interrupt (rough?) a = T0_MR0; b = T0_IR; c = T3_IR; d = VICVectAddr; //test e = VICDefVectAddr; f = VICVectAddr0; } /********************************Initialization************************* *************/ /* Setup Timer0 Compare-Match Interrupt */ /* no prescaler timer runs at cclk = FOSC*PLL_M */ void init_timer0 (void) { T0_MR0 = ((FOSC*PLL_M)/(1000/10))-1; // Compare-hit at 10mSec (-1 reset "tick") T0_MCR = MR0I | MR0R; // Interrupt and Reset on MR0 T0_TCR = TxTCR_COUNTER_ENABLE; // Timer0 Enable VICVectAddr1 = (unsigned long)tc0_cmp; // set interrupt vector ISR address VICVectCntl1 = VICVectCntl_ENABLE | VIC_Channel_Timer0; // use it for Timer 0 Interrupt: T0_IR = 0xff; // clear the interrupt register VICIntEnable |= (1<<VIC_Channel_Timer0); // Enable Timer0 Interrupt } /* no prescaler timer runs at cclk = FOSC*PLL_M */ /* MR1 used to generate an interrupt at the baud rate */ /* MR0 used to toggle the output pin*/ void init_timer3 (void) { // unsigned int a,b,c,d,e; T3_TC = 0; T3_PC = 0; T3_PR = 100; // go slow for initial testing T3_MR1 = ((FOSC*PLL_M)/1200)-1; // Compare-hit at baud rate (-1 reset "tick") T3_MCR = MR1I | MR1R | MR0I; //Interrupt and Reset on MR1, int only MR0 phaseStepPntr_ui16 = 1; T3_MR0 = 1024; // Phase 0 set high count 50% duty cycle T3_EMR = TxEMR_MAT0_Toggle; //Output I/O P0.21, MPU pin #3 T3_TCR = TxTCR_COUNTER_ENABLE; // Timer3 Enable VICVectAddr0 = (unsigned long)tc3_cmp; // set int vector ISR Address for the vector channel VICVectCntl0 = VICVectCntl_ENABLE | VIC_Channel_Timer3; // use it for Timer 3 Interrupt: // VICIntSelect = (1<<VIC_Channel_Timer3); // classify Timer3 Int as FIQ T3_IR = 0xff; // clear the interrupt register VICIntEnable |= (1<<VIC_Channel_Timer3); /* a = VICIntEnable; // check b = T3_TC; c = T3_IR; d = VICVectAddr; //test */ }
Thomas m. Alldread wrote: > ... > With "timer0", match register 0 interrupt assigned to IRQ0 the timer0 > interrupt works as expected. When I add a second IRQ, in this case > "timer3", match register 1 to IRQ1 then the IRQ0 interrupt is no longer > detected. Shoot in the dark: Did you add a default interrupt-handler (an ISR to which VICDefVectAddr points to which just acknowledges the interrupt)? If yes, is this handler called (set breakpoint in it, blink led, increase a counter...)? Did you test with Timer0 and Timer1 (not 3)? Did you read the Errata? I don't know it the "timer issue"-errata has been corrected in the LPC2103 (So far I have not worked the "small" LPCs). >... > I noticed there is an outstanding GCC bug registered for "arm-elf-gcc" > regarding incorrect IRQ code generation but I don't understand GCC well > enough to determine if it might apply to this case. Did you compile the complete code in ARM-Mode (no thumb/thumb-iw)? So far I have not had any problems with this bug as long as the complete code is build for ARM-mode. > It would be most helpful if I could find examples of GCC code for > multiple LPC2xxx VIC IRQs. The examples I have seen so far are for > single interrupt sources. I wonder if anyone in this group knows of > working GCC code with multiple VIC IRQ interrupts that I could study? If > so please either point me to it or post the initialization code and the > associated IRQ handler routines here. There should be several codes available which use more than on interrupt. For example there is Bill Knight's / R O Software LPC2000 UART code. Where both UARTs can be served in "interrupt-mode". Bill's unmodified code is in the lpc2000 yahoo-group file-archive. Slightly modified versions are available from my web-page www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects. Also see the newlib-lpc code. Both codes also demonstrate using the naked-attribute and macros to work around the GCC problem with the IRQ attribute. Martin Thomas
Greetings Martin: Thank you very much for responding to my post!!! Martin Thomas wrote: > > Shoot in the dark: Did you add a default interrupt-handler (an ISR to > which VICDefVectAddr points to which just acknowledges the interrupt)? > If yes, is this handler called (set breakpoint in it, blink led, > increase a counter...)? I now have VICDefVectAddr set to an IRQ_Routine forever loop trap. So far the code has never ended up in the trap. Here is a dump i did of some of the key VIC registers after initialization. They appear exactly correct to me: a = VICIntEnable; // 0x30 = (timer0 | timer1) int flag bit positions b = T1_TC; // 0x1 c = T1_IR; // 0x0 d = VICVectCntl0; // 0x25 = vector slot 0 enabled and timer1 is on channel 5 e = VICVectAddr; // 0x2ec = timer 1 ISR entry f = VICVectAddr0; // 0x2ec = timer 1 ISR entry g = VICVectAddr1; // 0x294 = timer 0 ISR entry h = VICVectCntl1; // 0x24 = vector slot 1 enabled and timer0 is on channel 4 i = VICDefVectAddr; // 0x9a4 = IRQ_Routine - forever loop trap entry >Did you test with Timer0 and Timer1 (not 3)? I have now moved over to Timer1 and have the same problem. >Did you read the Errata? I don't know it the "timer issue"-errata has been > corrected in the LPC2103 (So far I have not worked the "small" LPCs). The Feb 2007 Errata refers to a problem with Timer1 when used in counter mode. It has to do with the timer counter reset not happening until the second input pulse. I don't think it is related to this problem. > Did you compile the complete code in ARM-Mode (no thumb/thumb-iw)? So > far I have not had any problems with this bug as long as the complete > code is build for ARM-mode. As far as I know the program is all in ARM-Mode. The startup file has the ".arm" statement. I do not know if possibly Thumb could be specified elsewhere. The word "thumb" does not appear in any of my project files. I am not sure how to do a positive check. Any suggestions where I should look? In Eclipse? > > There should be several codes available which use more than on > interrupt. For example there is Bill Knight's / R O Software LPC2000 > UART code. Where both UARTs can be served in "interrupt-mode". Bill's > unmodified code is in the lpc2000 yahoo-group file-archive. Slightly > modified versions are available from my web-page > www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects. > Also see the newlib-lpc code. Both codes also demonstrate using the > naked-attribute and macros to work around the GCC problem with the IRQ > attribute. > > Martin Thomas I must get these examples and study them. Many thanks!!! With the latest tests I have done the IRQ detection fails for both vector 0 and 1 when I enable the Timer1 interrupt. I wonder if I need additional IRQ mode stack size for multi interrupts? I guess I can find out by taking a look at the examples and doing some more tests. I will do some more tests tomorrow. Thanks again for the help! Tom Alldread
Hi, I had similar problems when using 2 interrupts one for ADC (adc started from timer match) and the other one from USB on LPC2148. Well, after trying many things like increasing the call stack for IRQs I did my last try turning off optimizations (-O0) with gcc 4.2.2. And the problem has gone. I also tried gcc 4.1.1 and the same happens when optimizations (even -O1) are on. I know very well about using volatile variables related things for avoiding incorrect optimizations and I'm sure my code is not having such problems. I'm thinking about disabling one optimization at a time and maybe moving back to older gcc versions. Well, I suggest you try rebuilding your code with -O0 and see what happens. Please let me know what you find out. Thomas m. Alldread wrote: > Greetings Martin: > > Thank you very much for responding to my post!!! > > > Martin Thomas wrote: >> >> Shoot in the dark: Did you add a default interrupt-handler (an ISR to >> which VICDefVectAddr points to which just acknowledges the interrupt)? >> If yes, is this handler called (set breakpoint in it, blink led, >> increase a counter...)? > > I now have VICDefVectAddr set to an IRQ_Routine forever loop trap. So > far the code has never ended up in the trap. Here is a dump i did of > some of the key VIC registers after initialization. They appear exactly > correct to me: > > a = VICIntEnable; // 0x30 = (timer0 | timer1) int flag bit > positions > b = T1_TC; // 0x1 > c = T1_IR; // 0x0 > d = VICVectCntl0; // 0x25 = vector slot 0 enabled and timer1 is on > channel 5 > e = VICVectAddr; // 0x2ec = timer 1 ISR entry > f = VICVectAddr0; // 0x2ec = timer 1 ISR entry > g = VICVectAddr1; // 0x294 = timer 0 ISR entry > h = VICVectCntl1; // 0x24 = vector slot 1 enabled and timer0 is on > channel 4 > i = VICDefVectAddr; // 0x9a4 = IRQ_Routine - forever loop trap > entry > > >>Did you test with Timer0 and Timer1 (not 3)? > > I have now moved over to Timer1 and have the same problem. > >>Did you read the Errata? I don't know it the "timer issue"-errata has been >> corrected in the LPC2103 (So far I have not worked the "small" LPCs). > > The Feb 2007 Errata refers to a problem with Timer1 when used in counter > mode. It has to do with the timer counter reset not happening until the > second input pulse. I don't think it is related to this problem. > >> Did you compile the complete code in ARM-Mode (no thumb/thumb-iw)? So >> far I have not had any problems with this bug as long as the complete >> code is build for ARM-mode. > > As far as I know the program is all in ARM-Mode. The startup file has > the ".arm" statement. I do not know if possibly Thumb could be specified > elsewhere. The word "thumb" does not appear in any of my project files. > I am not sure how to do a positive check. Any suggestions where I should > look? In Eclipse? > >> >> There should be several codes available which use more than on >> interrupt. For example there is Bill Knight's / R O Software LPC2000 >> UART code. Where both UARTs can be served in "interrupt-mode". Bill's >> unmodified code is in the lpc2000 yahoo-group file-archive. Slightly >> modified versions are available from my web-page >> www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects. >> Also see the newlib-lpc code. Both codes also demonstrate using the >> naked-attribute and macros to work around the GCC problem with the IRQ >> attribute. >> >> Martin Thomas > > I must get these examples and study them. Many thanks!!! > > With the latest tests I have done the IRQ detection fails for both > vector 0 and 1 when I enable the Timer1 interrupt. > > I wonder if I need additional IRQ mode stack size for multi interrupts? > I guess I can find out by taking a look at the examples and doing some > more tests. > > I will do some more tests tomorrow. > > Thanks again for the help! > Tom Alldread
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.