EmbeddedRelated.com
Forums

Capture pin inconsistencies

Started by jase_ko February 14, 2006
Hi guys,

We are after a bit of help with the LPC2124.
We are trying to use the capture pin (CAP 0.2) to determine the 
speed of a vehicle based on the number of pulses we receive.

We find that we are getting consistant stray outliers.

Below is the source code we are using and the results we are getting 
to a terminal program.

Any help would be ace.

void main()
{

// init tick timer
  T0MR0 = 0xFFFFFFFF;
  T0MCR = 0x03;						

  // Interrupt and Reset on MR0
  VICVectAddr2 = (unsigned long)IRQTickTimer;	// set interrupt 
vector in 0
  VICVectCntl2 = 0x20 | 4;	// use it for Timer 0 Interrupt
  VICIntEnable |= 0x00000010;	// Enable Timer0 Interrupt

// init capture
  PINSEL1 |= 0x00000003;  // select capture pin on pin 16. (uses 
timer 0)
  T0CCR |= 0x00000040;	  // rising edge active (not falling 
edge)
  T0TCR = 0x00000001;	  // TC and PC are enabled for 
counting
  T0PR = 0x00000000;
	// init serial comms
  // Initialise the UART0 serial communications.
  PINSEL0 |= 0x00000005;  // Enable RxD1 and TxD1
  U0LCR = 0x83;		  // 8N1 with DLAB enabled.
  U0DLL = 97;		  // 9600 Baud Rate @ 15MHz VPB Clock
  U0LCR = 0x03;		  // DLAB = 0
  U0FCR = 0xc7;		  // turn on fifo buffer

  // Initialise the UART1 serial communications.
  PINSEL0 |= 0x00050000;  // Enable RxD1 and TxD1
  U1LCR = 0x83;		  // 8N1 with DLAB enabled.
  SetUART1BaudRate();
  U1LCR = 0x03;		  // DLAB = 0
	  static unsigned long prevTC = 0;
  unsigned long currTC = T0CR2;
  unsigned long prevTicks = 0;
  // ssv1.speed.ticks is an unsigned long

  while (1)
  {
    currTC = T0CR2;
    if (currTC > prevTC)
    {
      ssv1.speed.ticks = currTC - prevTC;
      prevTC = currTC;
      SerialSendLongInt (ssv1.speed.ticks); SerialSendString ("  ");
      SerialSendLongInt (ssv1.speed.ticks-prevTicks);
      SerialSendString ("\n");
      prevTicks = ssv1.speed.ticks;
    }
  }
}
	Printout from the terminal
185078  -6
185085  7
185083  -2
185097  14
185096  -1
185056  -40
370182  185126
185082  -185100
185090  8
185068  -22
185088  20
185080  -8
185077  -3
185096  19
185105  9
185085  -20
185107  22
185108  1
185100  -8
185097  -3
185111  14
185099  -12
185112  13
185087  -25
185074  -13
370156  185082
185089  -185067
185096  7
185058  -38
185114  56
185088  -26
185095  7
185117  22
183515  -1602
371311  187796
555767  184456
185071  -370696
173318  -11753
	

An Engineer's Guide to the LPC2100 Series

Hello,

I don't see your interrupt code, but you really need to read the errata
sheet.

http://www.standardics.philips.com/support/documents/microcontrollers/pdf/er
rata.lpc2124.pdf

Found here:
http://www.standardics.philips.com/products/lpc2000/all/~LPC2124/#LPC2124
	Joel
	
Hi

 I am assuming that this is also using a serial polling routine and
with numbers and space that you are sending out at 9600 baud (1ms per
character) you take about 11ms per string. Change it to an interrupt
type so you do not have to wait for the Txd. An alternative is to
boost the baud rate to like 57.6K or even 115.2K.

You should also change the capture to an interrupt to collect the time
and save it into a simple stack in case you get locked up waiting for
communications if you need to keep the baud rate at 9600.

regards,
Charles

--- In lpc2000@lpc2..., "jase_ko" <jase.ko@...> wrote:
>
> Hi guys,
> 
> We are after a bit of help with the LPC2124.
> We are trying to use the capture pin (CAP 0.2) to determine the 
> speed of a vehicle based on the number of pulses we receive.
> 
> We find that we are getting consistant stray outliers.
> 
> Below is the source code we are using and the results we are getting 
> to a terminal program.
> 
> Any help would be ace.
> 
> void main()
> {
> 
> // init tick timer
>   T0MR0 = 0xFFFFFFFF;
>   T0MCR = 0x03;						
> 
>   // Interrupt and Reset on MR0
>   VICVectAddr2 = (unsigned long)IRQTickTimer;	// set interrupt 
> vector in 0
>   VICVectCntl2 = 0x20 | 4;	// use it for Timer 0 Interrupt
>   VICIntEnable |= 0x00000010;	// Enable Timer0 Interrupt
> 
> // init capture
>   PINSEL1 |= 0x00000003;  // select capture pin on pin 16. (uses 
> timer 0)
>   T0CCR |= 0x00000040;	  // rising edge active (not falling 
> edge)
>   T0TCR = 0x00000001;	  // TC and PC are enabled for 
> counting
>   T0PR = 0x00000000;
> 
> 
> // init serial comms
>   // Initialise the UART0 serial communications.
>   PINSEL0 |= 0x00000005;  // Enable RxD1 and TxD1
>   U0LCR = 0x83;		  // 8N1 with DLAB enabled.
>   U0DLL = 97;		  // 9600 Baud Rate @ 15MHz VPB Clock
>   U0LCR = 0x03;		  // DLAB = 0
>   U0FCR = 0xc7;		  // turn on fifo buffer
> 
>   // Initialise the UART1 serial communications.
>   PINSEL0 |= 0x00050000;  // Enable RxD1 and TxD1
>   U1LCR = 0x83;		  // 8N1 with DLAB enabled.
>   SetUART1BaudRate();
>   U1LCR = 0x03;		  // DLAB = 0
> 
> 
>   static unsigned long prevTC = 0;
>   unsigned long currTC = T0CR2;
>   unsigned long prevTicks = 0;
>   // ssv1.speed.ticks is an unsigned long
> 
>   while (1)
>   {
>     currTC = T0CR2;
>     if (currTC > prevTC)
>     {
>       ssv1.speed.ticks = currTC - prevTC;
>       prevTC = currTC;
>       SerialSendLongInt (ssv1.speed.ticks); SerialSendString (" 
");
>       SerialSendLongInt (ssv1.speed.ticks-prevTicks);
>       SerialSendString ("\n");
>       prevTicks = ssv1.speed.ticks;
>     }
>   }
> }
> 
> 
> 
> Printout from the terminal
> 185078  -6
> 185085  7
> 185083  -2
> 185097  14
> 185096  -1
> 185056  -40
> 370182  185126
> 185082  -185100
> 185090  8
> 185068  -22
> 185088  20
> 185080  -8
> 185077  -3
> 185096  19
> 185105  9
> 185085  -20
> 185107  22
> 185108  1
> 185100  -8
> 185097  -3
> 185111  14
> 185099  -12
> 185112  13
> 185087  -25
> 185074  -13
> 370156  185082
> 185089  -185067
> 185096  7
> 185058  -38
> 185114  56
> 185088  -26
> 185095  7
> 185117  22
> 183515  -1602
> 371311  187796
> 555767  184456
> 185071  -370696
> 173318  -11753
>
	
>  I am assuming that this is also using a serial polling routine and
> with numbers and space that you are sending out at
9600 baud (1ms per
> character) you take about 11ms per string. Change it to an interrupt
> type so you do not have to wait for the Txd. An alternative is to
> boost the baud rate to like 57.6K or even 115.2K.
> 
> You should also change the capture to an interrupt to collect the time
> and save it into a simple stack in case you get locked up waiting for
> communications if you need to keep the baud rate at 9600.

Indeed.  I didn't look at that while loop, that's not so good.

Be sure to check the errata sheet when implementing interrupt capture code.

Joel
	
Here is the IRQ code for the timer.
We dont use interrupts for the capture pin. (We tried once, but it 
then stuffed up IRQ serial comms).
When the pin fires it updates the capture pin counter and then we 
read this at our leisure.

I had a look at the errata. The only thing it mentions about a 
capture pin is for pin P0.21. We use P0.16, CAP0.2
	void IRQTickTimer() __attribute__ ((interrupt));
void IRQTickTimer()
{
	T0IR = 1;		// Clear interrupt flag
	VICVectAddr = 0;	// Acknowledge Interrupt
}
	
Since this is interrupt driven for the capture, then the serial
routine is killing the counters by missing them. I would move the
currTC = T0CR2 into the IRQ routien and make it a volatile global so
that you can read it and clear it off. I would also do the prevTC currTC in the
interrupt routine as well.

regards,
Charles

--- In lpc2000@lpc2..., "jase_ko" <jase.ko@...> wrote:
>
> Here is the IRQ code for the timer.
> We dont use interrupts for the capture pin. (We tried once, but it 
> then stuffed up IRQ serial comms).
> When the pin fires it updates the capture pin counter and then we 
> read this at our leisure.
> 
> I had a look at the errata. The only thing it mentions about a 
> capture pin is for pin P0.21. We use P0.16, CAP0.2
> 
> 
> void IRQTickTimer() __attribute__ ((interrupt));
> void IRQTickTimer()
> {
> 	T0IR = 1;		// Clear interrupt flag
> 	VICVectAddr = 0;	// Acknowledge Interrupt
> }
>
	
Sorry about that, I quickly read the email and realized that you did
not use IRQ's. Well your only option then is to use a faster baudrate
but there will be no gurantee that you are not going to miss some time
counts.

If your IRQ did not work, then maybe you had nested IRQ's active but
did not save/restore the registers?

regards,
Charles

--- In lpc2000@lpc2..., "jase_ko" <jase.ko@...> wrote:
>
> Here is the IRQ code for the timer.
> We dont use interrupts for the capture pin. (We tried once, but it 
> then stuffed up IRQ serial comms).
> When the pin fires it updates the capture pin counter and then we 
> read this at our leisure.
> 
> I had a look at the errata. The only thing it mentions about a 
> capture pin is for pin P0.21. We use P0.16, CAP0.2
> 
> 
> void IRQTickTimer() __attribute__ ((interrupt));
> void IRQTickTimer()
> {
> 	T0IR = 1;		// Clear interrupt flag
> 	VICVectAddr = 0;	// Acknowledge Interrupt
> }
>
	
> I had a look at the errata. The only thing it mentions about a
> capture pin is for pin P0.21. We use P0.16, CAP0.2

Read Page 7 titled "TIMER.1 Missed Interrupt Potential".

Note this is not a problem with the LPC214x or the LPC2101/2/3.
	Joel
	
Thanks for the comment Glen,

I checked the timing with an Oscilloscope and it's fine.  The pulses stay 
for about 500nS (I'm using legacy GPIO mapping so it's slower).  A
complete 
write cycle takes 940nS.  If anything I think it may be too slow, but I've 
seem this used with a 8051 (much slower) without any issues, unfortunately 
I don't have the source code for that.  Maybe I'll try using FGPIO and
see 
if that makes a difference.

Does anyone know of any alternatives to SED13305 (that's cheap?)

Thanks!

-- Sean

At 07:15 2/16/2006, you wrote:
>Sean,
>
>I have used the SED 1335 in the past.  One thing that is too
>obvious is that the SED part is probably not the fastest thing
>in the world, and you may be exceeding it speed capability.
>
>I never had this problem with the Z80 family I was using at the
>time, but the new ARM chips are way too fast for the 1335, I do not
>know about the chip you are using.
>
>Just a thought.
>
>Glen
>
>
>Sean wrote:
>
> > Hello all,
> >
> > I am having an issue here and I hope someone has some suggestions. 
I'm
> > trying to interface some LCDs to my micro, I have a graphical 128x64
which
> > has an embedded controller chip interfaced fine, using P1.16-P1.23 as 
> 8-bit
> > parallel IO.  However when I try to hook up a SED13305 the data seems
to
> > get corrupted.  I'll issue a write to the device to store
something in
> > VRAM, then immediately try to read it back.  Here's where things
get weird.
> >
> > If I try to use the WR and RD signals like they should be used (RD
always
> > high, Clear WR, Set Byte, Set WR), the write appears to work, however
> > repeated reads of the same memory area return different results each
> > time.  Enough reads show that the data was written successfully. 
However
> > if I modify only the write routine to use the WR and RD signals in a
> > different (wrong) way (Clear WR, Set RD, Set Byte, Set WR, Clear RD)
then
> > repeated reads return the same data every time, however bits 7:8 are 
> always
> > "10".  Note that the read routine is the exact same both
times.
> >
> > How is it possible to have a small change to the write routine effect
how
> > the read routine works?
> >
> > I have tried playing with timing to no avail.  I looked at everything
with
> > an oscilloscope and the timing and data look correct.  I've
verified all
> > connections with a multimeter. I have both the micro and the SED
running
> > off of 3.3V.  Note that if the SED is running at 5V then I get
complete
> > garbage on read (meaning probably nothing worked), even though the SED

> says
> > it works from 2.7V to 5.5V.
> >
> > I think I'm going to have to try to make another test board, but
before I
> > run out to do that does anyone have any ideas as to why this is
happening?
> >
> > Thanks,
> >
> > -- Sean
> >
> >
> >
> >
> > >Yahoo! Terms of Service.
>
>
>----------
	
Sean,

did you read my comment about the 6800 and 8080 mode - resp. did you check 
if you are running the correct mode?

Herbert

At 12:04 16.02.2006 -0500, you wrote:

>Thanks for the comment Glen,
>
>I checked the timing with an Oscilloscope and it's fine.  The pulses
stay
>for about 500nS (I'm using legacy GPIO mapping so it's slower).  A
complete
>write cycle takes 940nS.  If anything I think it may be too slow, but
I've
>seem this used with a 8051 (much slower) without any issues, unfortunately
>I don't have the source code for that.  Maybe I'll try using FGPIO
and see
>if that makes a difference.
>
>Does anyone know of any alternatives to SED13305 (that's cheap?)
>
>Thanks!
>
>-- Sean
>
>At 07:15 2/16/2006, you wrote:
> >Sean,
> >
> >I have used the SED 1335 in the past.  One thing that is too
> >obvious is that the SED part is probably not the fastest thing
> >in the world, and you may be exceeding it speed capability.
> >
> >I never had this problem with the Z80 family I was using at the
> >time, but the new ARM chips are way too fast for the 1335, I do not
> >know about the chip you are using.
> >
> >Just a thought.
> >
> >Glen
> >
> >
> >Sean wrote:
> >
> > > Hello all,
> > >
> > > I am having an issue here and I hope someone has some
suggestions.  I'm
> > > trying to interface some LCDs to my micro, I have a graphical
128x64 
> which
> > > has an embedded controller chip interfaced fine, using
P1.16-P1.23 as
> > 8-bit
> > > parallel IO.  However when I try to hook up a SED13305 the data
seems to
> > > get corrupted.  I'll issue a write to the device to store
something in
> > > VRAM, then immediately try to read it back.  Here's where
things get 
> weird.
> > >
> > > If I try to use the WR and RD signals like they should be used
(RD always
> > > high, Clear WR, Set Byte, Set WR), the write appears to work,
however
> > > repeated reads of the same memory area return different results
each
> > > time.  Enough reads show that the data was written successfully. 
However
> > > if I modify only the write routine to use the WR and RD signals
in a
> > > different (wrong) way (Clear WR, Set RD, Set Byte, Set WR, Clear
RD) then
> > > repeated reads return the same data every time, however bits 7:8
are
> > always
> > > "10".  Note that the read routine is the exact same
both times.
> > >
> > > How is it possible to have a small change to the write routine
effect how
> > > the read routine works?
> > >
> > > I have tried playing with timing to no avail.  I looked at
everything 
> with
> > > an oscilloscope and the timing and data look correct.  I've
verified all
> > > connections with a multimeter. I have both the micro and the SED
running
> > > off of 3.3V.  Note that if the SED is running at 5V then I get
complete
> > > garbage on read (meaning probably nothing worked), even though
the SED
> > says
> > > it works from 2.7V to 5.5V.
> > >
> > > I think I'm going to have to try to make another test board,
but before I
> > > run out to do that does anyone have any ideas as to why this is 
> happening?
> > >
> > > Thanks,
> > >
> > > -- Sean
> > >
> > >
> > >
> > >
> > > >http://docs.yahoo.com/info/terms/>Yahoo! 
> Terms of Service.
> >
> >
> >----------
>
>
>
>SPONSORED LINKS
><http://groups.yahoo.com/gads?t=ms&k=Microcontrollers&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s&.sig=mfaAujKZXA2Z_vxre9sGnQ>Microcontrollers

><http://groups.yahoo.com/gads?t=ms&k=Microprocessor&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s&.sig=9jjd2D3GOLIESVQssLmLsA>Microprocessor

><http://groups.yahoo.com/gads?t=ms&k=Intel+microprocessors&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s&.sig=OMnZuqMZX95mgutt4B-tDw>Intel

>microprocessors
><http://groups.yahoo.com/gads?t=ms&k=Pic+microcontrollers&w1=Microcontrollers&w2=Microprocessor&w3=Intel+microprocessors&w4=Pic+microcontrollers&c=4&s&.sig=Malspbd0T4Rq3M4Q0nHrfw>Pic

>microcontrollers
>
>
>----------
>>Yahoo! Terms of Service.
>
>
>----------

----------------------
demmel products
Radnitzkygasse 43
A-1100 Vienna / Austria / Europe
Voice: +43-1-6894700-0
Fax: +43-1-6894700-40
Email: dh@dh@....
WWW: http://www.demmel.com