Hi,
for a project here at Ghent University, our group has been instructed to build a laser projector. We are using an Olimex LPC P2148 prototype board to do all the processing and modulation but we are very unexperienced at programming or designing an ARM project. For the next step we need to get interrupts working on the P2148 but this is causing us some problems.
I am trying to run interrupts and I am using [this topic as a guideline. I basically copied the code and made a few adjustments to see if I can get everything to work as I want, which is not the case right now. The main code is running a small SOS script flashing the onboard LED2. The interrupt code is flashing an LED externally connected to pin P1.20 every second. When I upload this code (I am using Crossworks), everything works great: SOS is fine and the external LED is flashing as well, but the thing is: everything stops after 8 interrupts!
After the 8th interrupt (the external LED flashes 8 times) the board gets locked up into some eternal loop because the LED2 stays on (no action anymore) and the external LED won’t flash anymore. I have really no idea what is causing this, but I think it has something to do with interrupt registers or flags not set correctly?
I am hoping that somebody can take the time to find out what is wrong and tell me what mistake I made so I can understand this problem? Below is the code I use: one thing, the VIClowlevel.c wouldn’t compile until I replaced arm volatile … (line 6 and 12) with __asm volatile … Does this have anything to do with the problem?
Also: to set or clear a pin I have written a function called setPin and clrPin. Is this a good way of working or is there a good reason why not to do it like this? It’s very convenient since it takes a pin number as input and enables or disables that pin but it has been causing me some trouble, maybe I should start looking there?
Thank you very much in advance!
Nils
/* *********************************************************
Function declarations
********************************************************* */
void Initialize(void);
void feed(void);
void IRQ_Routine (void) __attribute__ ((interrupt("IRQ")));
void FIQ_Routine (void) __attribute__ ((interrupt("FIQ")));
void SWI_Routine (void) __attribute__ ((interrupt("SWI")));
void UNDEF_Routine (void) __attribute__ ((interrupt("UNDEF")));
/**********************************************************
Header files
**********************************************************/
#include <math.h>
#include "LPC214x.h"
#include "VIClowlevel.h"
#define PLOCK 0x400
/**********************************************************
FUNCTIES
**********************************************************/
// BEREKEN 2 TOT DE INPUT MACHT
int macht(int input)
{
int resultaat = 1;
resultaat = resultaat << input;
return resultaat;
}
// ZET EEN BEPAALDE OUTPUT PIN AAN
void setPin(int groep, int nummer)
{
if(groep == 0)
{
//IODIR0 |= macht(nummer);
IOSET0 = macht(nummer);
}
else if(groep == 1)
{
//IODIR1 |= macht(nummer);
IOSET1 = macht(nummer);
}
}
// ZET EEN BEPAALDE OUTPUT PIN UIT
void clrPin(int groep, int nummer)
{
if(groep == 0)
{
//IODIR0 |= macht(nummer);
IOCLR0 = macht(nummer);
}
else if(groep == 1)
{
//IODIR1 |= macht(nummer);
IOCLR1 = macht(nummer);
}
}
/**********************************************************
MAIN
**********************************************************/
int main (void)
{
int i,j,k;
T0TCR = 0x02; //reset counter
T0IR = 0xff;
T0MCR = 0x0003; //interrupt and reset on MR0
T0MR0 = 0x03938700; //compare-hit count
VICVectCntl0 = 0x00000024; //use it for Timer 0 Interrupt:
VICVectAddr0 = (unsigned)IRQ_Routine; //set interrupt vector in 0
VICIntEnable = 0x00000010; //enable TIMER0 interrupt
T0TCR = 0x01; //enable Timer0
enableIRQ();
while(1)
{
for(k=0; k<3; k++)
{
for(i=0; i<50000; i++)
setPin(0,11);
for(j=0; j<50000; j++)
clrPin(0,11);
}
for(k=0; k<3; k++)
{
for(i=0; i<100000; i++)
setPin(0,11);
for(j=0; j<100000; j++)
clrPin(0,11);
}
for(k=0; k<3; k++)
{
for(i=0; i<50000; i++)
setPin(0,11);
for(j=0; j<50000; j++)
clrPin(0,11);
}
for(k=0; k<500000; k++)
clrPin(0,11);
}
}
/**********************************************************
INITIALIZE
**********************************************************/
void Initialize(void)
{
// Setting Multiplier and Divider values
PLL0CFG=0x24;
feed();
// Enabling the PLL */
PLL0CON=0x01;
feed();
// Wait for the PLL to lock to set frequency
while(!(PLL0STAT & PLOCK)) ;
// Connect the PLL as the clock source
PLL0CON=0x3;
feed();
// Enabling MAM and setting number of clocks used for Flash memory fetch (4 cclks in this case)
MAMCR=0x02;
MAMTIM=0x04;
// Setting peripheral Clock (pclk) to System Clock (cclk)
VPBDIV=0x01;
}
void feed(void)
{
PLL0FEED=0xAA;
PLL0FEED=0x55;
}
/* Stubs for various interrupts (may be replaced later) */
/* ---------------------------------------------------- */
void IRQ_Routine (void)
{
int i;
//IOSET0 = 0x30600000; //4 LEDs blink
setPin(1,20);
for(i=0;i<10000;i++);
clrPin(1,20);
T0IR = 0x01; //clear interrupt
VICVectAddr = 0; //end of interrupt - dummy write
}
void FIQ_Routine (void) {
int i;
while (1) ;
}
void SWI_Routine (void) {
int i;
while (1) ;
}
void UNDEF_Routine (void) {
int i;
while (1) ;
}