lpcware

LPC810 ACMP interrupt loop

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
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;
}

Outcomes