Hi all,
I'm a newby to Keil tools, lpc2138 microcontroller, and C programming
language. I'm doing this on a Keil MCB2130 dev board. I have some code
that I have either pieced together or wrote that works for a bit and
then stops. I have been reading, researching, debugging, and trial and
erroring it for about 2 weeks and I just can't seem to solve it. I set
up timer0 for interrupts to kick off the A2D. The timer count is a
number that is derived from a number that is recieved from an I2C
master. The lpc2138 is configured as an I2C slave using the app note
from NXP (TN06005). I wouldn't have thought this would be too difficult
as interrupts for the I2C code and for timer0 do not occur at the same
time. Therefore I have tried disabling I2C interrupts and only
re-enabling them right before it is required. And the same with timer0,
I enable it right before it is needed and then disable them after the
function is completed. Whether I do this or just leave both enabled from
the start I end up with the same results. The I2C communication never
fails however, it appears that timer0 interrupts will fail to occur at
the same point. When it fails, after the command to enable timer0
interrupt occurs, it is stuck in a Do-While loop waiting for an
interrupt that never happens. I don't know much yet about using the
debugger but when I stop it when it fails, it is always at this point. I
put a couple of statements in the timer0 isr to turn on and off an LED
and it does not light when it fails again further confirming to me that
the interrupt is failing. Being an absolute novice I don't doubt that I
am missing something very basic but I just don't see it. I would
appreciate it if anyone could take a look at it and see if you spot
anything that may be causing this. Once this is solved, everything is
working fine. I just don't know why, seemingly randomly, the interrupt
for timer0 would quit working. I will try to attach what I think is
just the pertinent parts of my code.
Thanks,
Fran
// This routine intializes the timer0 interrupt
void timer0_init(void)
{
T0MR0 = sample_time; // This is varied and set up by the I2C value
received
T0MCR = 3; // timer 0 triggers on match and resets itself
T0TCR = 1; // start the clock
VICVectAddr0 = (unsigned long) tc0;
VICVectCntl0 = 0x20 | 4;
}
// This is the start of a function that starts timer0 interrupting and
then disables it when it is complete
void calculate(void)
{
VICIntEnable = (1 << 4); // start sampling
do
{
// Pertinent code goes here.
}
}
while(counter < CYCLE_COUNT);
VICIntEnClr = (1 << 4); // stop interrupting
// This is the pertinent part of timer0 ISR
void tc0 (void) __irq
// Timer 0 interrupt routine
{
LED_on(); //*** here for testing purposes only
// ISR related code for sampling the A2D here
LED_off(); //*** here for testing purposes only
T0IR = 0x01; // clear the flag
VICVectAddr = 0;
}
// Note that this is NXP code from their appnote, because their example
used Addr0,
// I changed it to 1 as timer0 needs to be highest priority, once I get
this working
// I will try and change timer0 interrupts to FIQ as my understanding is
that will reduce latency.
void I2C0_Init(void)
{
PINSEL0 |= 0x50; // P0.3 = SDA, P0.2 = SCL
I2C0ADR = 0xD0; // set I2C slave address
I2C0CONSET = 0x44; // enable I2C hardwar and set AA (ack)
I2C0SCLH=0x4B; // 100 KHz 0x4B
I2C0SCLL=0x4B; // 0x4B
VICVectAddr1 = (unsigned int) &I2C0_Isr;
VICVectCntl1 = 0x29; // Channel1 on Source#9 ... enabled
VICIntEnable |= 0x200; // 9th bit is the I2C
}
// This is the ISR for I2C slave communications out of the NXP app note
void I2C0_Isr(void) __irq
{
unsigned char st;
st = I2C0STAT;
I2C0CONCLR = 0x2C; // clear STA, AA and SI
switch(st)
{
case 0x60: // own SLA+W received, Ack returned (slave
receiver)
case 0x68: // Addressed as slave
I2C0CONSET = 0x04; // set AA, return ACK on first byte
break;
case 0x80: // Data received, ACK returned
SlaveRcv = I2C0DAT; // read and store data, NACK on next byte
break;
case 0x88: // data received, NACK returned
case 0xA0: // STOP or REP.START received while addressed as
slave
case 0xC0: // Data transmitted, NOT ACK received
case 0xC8: // Last data transmitted, ACK received
I2C0CONSET = 0x04; // set AA, switch to not addressed slave
mode
donecheck = 1;
break;
case 0xA8: // own SLA+R received, Ack returned (slave
transmitter)
case 0xB8: // Data transmitted, ACK received
I2C0DAT = SlaveSnd; // Transmit last data AA = 0
break;
default:
break;
}
VICVectAddr = 0x01; // reset VIC
}
(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )