LPC810 ACMP interrupt loop

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC810 ACMP interrupt loop

1,539 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Fri Dec 20 17:24:12 MST 2013
I get a problem using the ACMP interrupt.
As soon as the interrupt is enabled, the MCU does nothing else but call CMP_IRQHandler in a loop.
Seems either it permanent detect edges or the interrupt is not reset.
After hours of debugging and reading the documentation i run out of ideas.
MRT and SCT interrupts are working fine.
Either I read something wrong or i may have a problem in hardware ?
Does someone has an idea ?

Here a code snippet:
#define DEFBITS(last,first,val) ( (val&((1UL << ((last+1)-first))-1)) << first)

#define ACMP_CTRL_EDGESEL(val) DEFBITS(4,3,val)
#define ACMP_CTRL_COMPSA(val) DEFBITS(6,6,val)
#define ACMP_CTRL_COMP_VP_SEL(val) DEFBITS(10,8,val)
#define ACMP_CTRL_COMP_VM_SEL(val) DEFBITS(13,11,val)
#define ACMP_CTRL_EDGECLR(val) DEFBITS(20,20,val)
#define ACMP_CTRL_COMPSTAT(val) DEFBITS(21,21,val)
#define ACMP_CTRL_COMPEDGE(val) DEFBITS(23,23,val)
#define ACMP_CTRL_HYS(val) DEFBITS(26,25,val)

void acmp_init() 
{ 
  LPC_SYSCON->PDRUNCFG &= ~( (0x1 << 15) );
  LPC_SYSCON->SYSAHBCLKCTRL |= (0x1 << 19);
  LPC_SYSCON->PRESETCTRL &= ~(0x1 << 12);
  LPC_SYSCON->PRESETCTRL |= (0x1 << 12);

  LPC_CMP->CTRL=0;
  LPC_CMP->LAD=(1<<6)|(1<<0);
  LPC_CMP->CTRL=ACMP_CTRL_COMP_VM_SEL(0)|ACMP_CTRL_COMP_VP_SEL(2)|ACMP_CTRL_EDGESEL(2)|ACMP_CTRL_EDGECLR(1);
  LPC_CMP->CTRL&=~(ACMP_CTRL_EDGECLR(1));
  NVIC_EnableIRQ( CMP_IRQn );
}

#define _COMPSA(0x1 << 6)
#define _EDGECLR                (0x1 << 20)
#define _COMPSTAT(0x1 << 21)
#define _COMPEDGE(0x1 << 23)
/* statistics of all the interrupts */
volatile uint32_t CompStatCnt = 0;
volatile uint32_t CompEdgeCnt = 0;
void CMP_IRQHandler(void);

void CMP_IRQHandler(void)
{
  uint32_t regVal;
  regVal = LPC_CMP->CTRL;
  LPC_GPIO_PORT->CLR0 = 1 << LED_LOCATION;
  if (regVal & _COMPSTAT)
  {
CompStatCnt++;
  }
  if (regVal & _COMPEDGE)
  {
CompEdgeCnt++;
  }
  LPC_GPIO_PORT->SET0 = 1 << LED_LOCATION; 
  LPC_CMP->CTRL = regVal | _EDGECLR;
  LPC_CMP->CTRL = regVal & (~_EDGECLR);

  return;
}
Labels (1)
0 Kudos
Reply
17 Replies

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Thu Apr 23 11:20:21 MST 2015
Hi Sebi,

unfortunately not.
I got attracted by some other problems coming from real world, like fix our cars and house foundation since and did not find time
to work on the topic.
The demo board since then still sit on table in the corner ...

But maybe some ideas:

What about to check what happens on output with interrupt disabled ?
Does the ACMP do switch the output if input changes ?
Maybe the interrupt has to be configured for the other edge every time it occurs ?
So if it fires on raising edge set it to falling edge and via versa ?
Maybe this is how the HW behaves ?

I don't remember all the experiments I did, I this I worked about 2 or 3 weeks on that ....

Hope the ideas help you ?

also pls have a look there:
https://github.com/mikef5410/lpcopen/blob/master/lpcopen/applications/lpc8xx/examples/periph/periph_...
and there:
http://rancidbacon.com/lpcopen/docs/lpcopen_docs_v2_00a_11xx/acmp__11xx_8c_source.html

Maybe using these functions will make it work ? Then you could compare whats different.
Or maybe we both have an early version of the chip that has a problem ????
Thomas
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sebi on Thu Apr 23 02:25:30 MST 2015
Hi OnkelJack,

did you solve your Problem? I have the same problem and have no idea to fix it. Once the interrupt occures, it "fires" permanently...

Thank you
Sebastian
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Tue Dec 31 17:11:44 MST 2013
Hi Marc,

a thousand thanks for check that out for me.
You arere right with the hint at the voltage.
I will check the power supply too. Fortuntnately,
I not only own a digital analyzer but a oscilloscope too.
I also will order a new chip.

Have a happy new year !
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Mon Dec 30 17:04:51 MST 2013
Hi OnkelJack,

i just run your binary an my LPC812 board.
After a 1.5s low on P0.2 it toggles at 1 Hz. No interrupt loop.

All pins on my board were left open in this test, except for the programming pins PIO0.0, PIO0.1, PIO0.4, PIO0.5.
The crystal is populated, too. See schematic. The device is a sample, Rev 2A, not the ones available today (PIO0.12 as BOOT).

This result seems to confirm you have a hardware problem.

But when I reduced the operating voltage down to 2.0V - to my surprise - I have a randomly toggling P0.2 at an average about 2..4.5kHz.
I don't know, if you handle brown-out so far and if that can be an explanation.
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Mon Dec 30 15:30:18 MST 2013
Marc,

Thanks for looking at that.
I just put some update in my last post.
Using same reference on both inputs is intended, just to make sure no noise is trouble me.
I also tried with max hsyeresis (30 mv I think) and different inputs, voltage ladder, I1 I2.
Still the same behaviour.

I spend a lot of time on the topic try out different approaches and also re-wrote the code from scratch,
always getting the same results.

The NXP stuff is in the sample zip and get pulled in by the Makefile.
The only symbol pulled from C runtime is __aeabi_uidiv, the unsigned interger division.
Unfortunately it is needed to calculate clock speed, otherwise it would link with -nostdlib

I did experiment a little further.
Interestingly, if ACMP configured and the pins tied to Vss/Vdd so that ACMP_O should be low,
I get a 70 us wide low pulse on ACMP_O then it switches back to high and the interrupt fired in a loop.
If I configure and tie the pins in a way ACMP_O is high, nothing happens, no pulse and no interrupt.

So, since output and interrupt both behaves in a similar strange way, I think its really a hardware problem.

But a confirmation still is highly welcome.
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Sun Dec 29 13:15:54 MST 2013
Here are the binaries.
LED pin is P0.2

I did experiment a little further.
Interestingly, if ACMP configured and the pins tied to ACMP_O should be low,
I get a 70 us wide low pulse on ACMP_O then it switches back to high and the interrupt fired in a loop.
If I configure and tie the pins in a way ACMP_O is high, nothing happens, no pulse and no interrupt.

So, since output and interrupt  both behaves in a similar strange way, I think its really a hardware problem.

But a confirmation still is highly welcome.
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Sun Dec 29 12:42:12 MST 2013
Hi OnkelJack,

I've not yet tested your binary nor am I able to compile your code in my so different environment (no NXP stuff, no libc BS, no nothing whatever - that makes my programs fat and dull).
But one thing puzzles me: you seem to use as input to the comparator the *SAME* internal reference voltage.
Without hysteresis that would be a good explanation for your ISR keeping up firing. Imagine some input noise...
Just a thought.
I'm old and slow. Will get a closer look at your program later, once I've completely understood the ACMP 0:)
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Sun Dec 29 07:05:31 MST 2013

Quote: onkel.jack@t-online.de


Sending the binary makes not sense since LED pins are different betwenn our boards.



...unless I have a board that has all pins accessible. ;-)
I do have.
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Sat Dec 28 15:51:05 MST 2013
Hi Marc,

here my sample project showing the problem.
go into test/sonic and call make from there.

For running on LPC812 LPCexpresso board the define -DLPC810_MINIBOARD in makefile line 117 need to get removed to address the correct LED pin.

If the code works correctly, the LED should go on for 1,5 sec then go off and then toggle every 0,5 sec.
If the interrupt fires permanent, the LED will dimm indicating the interrupt routine runs continually.

Sending the binary makes not sense since LED pins are different betwenn our boards.

Thanks in advance
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Mon Dec 23 17:21:57 MST 2013
Thanks for beeing so kind to let the stuff run on yor board.
I do have gcc toolchain too, but have LPC810 mini board, so maybe the pins need to be changed for that thest.
Nevertheless, I will post that in the next days if i do not have success with the link sent by wells.

Have a merry x-mas
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Mon Dec 23 17:18:37 MST 2013
Thanks for posting that link.
I will try that out in the next days.
Have a merry x-mas
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Mon Dec 23 11:22:48 MST 2013

Quote: onkel.jack@t-online.de

Maybe someone who own a LPC810 mini board can try to run the code on his hardware to see if it behaves same ?


I have LPC812 boards and gcc toolchain.
Put your code into a .c file and I'll give it a try. I'll have to use the comparator myself, soon.
Also maybe post your binary and we'll see if that behaves exactly as the one I'll compile.
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by wells on Mon Dec 23 10:40:00 MST 2013
The LPCOpen ACMP example woprked fine at last check and only triggered the interrupt when going through a threshold.
It's very similar to yours, but uses different names and functions. Maybe you can pull that one and give it a try?

http://www.lpcware.com/content/nxpfile/lpcopen-software-development-platform-lpc8xx-packages
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Mon Dec 23 09:45:10 MST 2013
I know from ISR does toggle a pin (LED) . Measurement show its just a couple of cycles.
LED is switched on at entry and off at exit of the ISR.
So ISR is processed completely.

The main program is just a loop toggle another pin, then wait 500 ms at MRT timer.
This works correctly if ACMP is disabled.
Abort with restart would lead to 1,5 sec pause before init ACMP (in main() so this would be visible on the LED.

Have also removed all other code except system clock and gpio init.
Main is a while(1);
LED still toggles.

Maybe someone who own a LPC810 mini board can try to run the code on his hardware to see if it behaves same ?
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MarcVonWindscooting on Mon Dec 23 09:05:00 MST 2013
How do you know, it's the ISR your program is looping?
What if it loops because of a corrupt stack or some kind of abort?
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by onkel.jack@t-online.de on Sun Dec 22 19:03:44 MST 2013
Thanks for the hint.
I inserted
NVIC_ClearPendingIRQ(CMP_IRQn);

at the end of the IRQ routine.
It does not have any effect on the problem.

I also tried:
- do not power up
- do not enable clock and
- held acmp in reset

in all these cases the interrupt does not fire.

But as soon acmp is set up correctly, MCU does nothing else but running CMP_IRQHandler.

I also tried this seuence at end of CMP_IRQHandler:
- disable acmp irq,
- clear acmp irq
- enable acmp irq
it still run the irq handler in a loop.
To make sure its not from real edge detection I connected both VP and NP to voltage ladder and set hysteresis to 30 mv.
So no edge detection can happen.
Tried same with internal bandgap.
All this ends up with the interrupt loop.
0 Kudos
Reply

1,370 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Sat Dec 21 04:51:51 MST 2013
How about clearing the interrupt in the NVIC?
0 Kudos
Reply