ADC interrupt is not triggering

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

ADC interrupt is not triggering

2,070 Views
Nandini_19
Contributor I

In LPC54606 I used ADC0 seqA  with Following Code But Interrupt is not occured atleast once.

void ADC0_init(void)
{

SYSCON->PDRUNCFG[0] &=~(1<<9|1<<10|1<<19|1<<23); //ADC Powered
SYSCON->PDRUNCFG[1] &=~(1<<3);
DelayMs(25); //Least of 20Microsec delay before enabling clock to ADC

SYSCON->AHBCLKCTRL[0] |= (1 << 27); // Clock to ADC0
SYSCON->PRESETCTRL[0] &=~(1 << 27); //Clear Reset to ADC0

ADC0->CTRL |=(1<<0)|(1<<2); //ADC clock as 30MHZ

ADC0->SEQ_CTRL[0] |=1<<28 ; //mode as single step
ADC0->SEQ_CTRL[0] &=~(1<<30) ; //mode as end of conversion

vDisable_adc_fun(); //Disable all ADC chnls to avoid error

IOCON->PIO[0][ADCPinno[Chnlno]]&=~(1<<8); //Analog mode enable chnl by chnl

ADC0->FLAGS = ADC0->FLAGS ; //Clear all pending interrupts
ADC0->INTEN = 0x01<<0;
NVIC_SetPriority(ADC0_SEQA_IRQn,3);
NVIC_EnableIRQ(ADC0_SEQA_IRQn);

ADC0->SEQ_CTRL[0]&=(~(1UL << 31));
ADC0->SEQ_CTRL[0]&= ~(0xFFF);
// ADC0->SEQ_CTRL[0]|=1<<12|1<<13; //ADC trigger by SCT_OUT4
// ADC0->SEQ_CTRL[0]|= (1 << 18); //HW trigger polarity - positive edge

ADC0->SEQ_CTRL[0]|=(0x01<<(ADCChnlno[Chnlno])); //Enable ADC chnl bit

ADC0->SEQ_CTRL[0] |=0x08000000;
ADC0->SEQ_CTRL[0]|= (1UL << 31); //Enable Sequence
}

void ADC0_SEQA_IRQHandler()
{

     //body of code

}

 

Thanks&Regards

Nandini

0 Kudos
Reply
5 Replies

2,059 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

This is my suggestion, firstly, you use software triggering mode to start ADC sampling with interrupt mode. After software triggering is okay, then you use SCT_OUT7 to trigger ADC.

I have tried to use LPC54114 and use SCT to trigger ADC, pls refer to the code:

Because the ADC triggering source is different between 54114 and 54606, pls note it.

Hope it can help you

BR

XiangJun Rong

//PIO0_7 SCT0_OUT0(Func_2)
//PIO0_8 SCT0_OUT1(Func_2)
//PIO0_9 SCT0_OUT2(Func_2)
//PIO0_10 SCT0_OUT3(Func_2)
//use SCT0_OUT7 signal to trigger ADC
void ADC_Init_HardWareTrigger_DMA(void)
{
//power-on ADC
//SYSCON->PDRUNCFGCLR[0]=1<<10;
//enable ADC clock
SYSCON->AHBCLKCTRLSET[0]=1<<27|1<<13; //enable both IOCON and ADC0

//ADC prereset
//select ADC clock, main clock is selected as ADC clock
SYSCON->ADCCLKSEL=0x00;;
SYSCON->ADCCLKDIV=0x01;
//SYSCON->PRESETCTRLSET[0]|=0x1<<27; //set ADC0_RST
asm("nop");
asm("nop");
asm("nop");
//SYSCON->PRESETCTRLCLR[0]=0x01<<27; //set ADC0_RST
Delay_mSec(2);
ADC0->STARTUP|=0x01;
Delay_mSec(2);
ADC0->STARTUP|=0x01<<1;

//ADC pin is selected, PIO1_0/ADC0_3
IOCON->PIO[1][0]=0x00;

//set up ADC register
ADC0->CTRL=0x3F00; //12 bit resolution, synchronous mode, bypass calibration
ADC0->INSEL=0x00; //select ADC input channel
//hardware triggering mode, trigger source SCT0_OUT7, positive edge, bypass mode
ADC0->SEQ_CTRL[0]|=1<<3|2<<12|0x0C<<16|1<<30; //|1<<30;
ADC0->SEQ_CTRL[0]|=1<<31; //enable sequence A
//software trigger ADC
// ADC0->SEQ_CTRL[0]|=1<<26;
//poll ADC status reg and read ADC sample
for(;;)
{
//ADC_conversion_hardware();
//if interrupt mode is enabled, just use nop
__asm("nop");
}
}

void PWMInit(void)
{
//enable PWM module clock
SYSCON->AHBCLKCTRLSET[0]=1<<20|1<<13; //enable both IOCON and DMA
SYSCON->AHBCLKCTRLSET[1]=1<<2; //enable both IOCON and ADC0
//initialize the PWM module pins
IOCON->PIO[0][7]=0x82;
IOCON->PIO[0][8]=0x82;
IOCON->PIO[0][9]=0x82;
IOCON->PIO[0][10]=0x82;

//select PWM clock source
SCT0->CONFIG |= 1; // unified timer
SCT0->SCTMATCHREL[0] = (SystemCoreClock/10)-1; // match 0 @ 10 Hz = 100 msec
SCT0->SCTMATCHREL[1] = ((SystemCoreClock/10)/4)-1; // match 0 @ 10 Hz = 100 msec
SCT0->SCTMATCHREL[2] = ((SystemCoreClock/10)/2)-1; // match 0 @ 10 Hz = 100 msec

SCT0->EVENT[0].STATE = 0xFFFFFFFF; // event0 happen in all state
SCT0->EVENT[0].CTRL = (0 << 0) | (1 << 12);

SCT0->EVENT[1].STATE = 0xFFFFFFFF; // event1 happen in all state
SCT0->EVENT[1].CTRL = (1 << 0) | (1 << 12);

SCT0->EVENT[2].STATE = 0xFFFFFFFF; // event2 happen in all state
SCT0->EVENT[2].CTRL = (2 << 0) | (1 << 12);

SCT0->OUT[0].SET = (1 << 1); // event 1 will set SCT_OUT0
SCT0->OUT[0].CLR = (1 << 2); // event 2 will clear SCT_OUT0
SCT0->OUT[7].SET = (1 << 1); // event 1 will set SCT_OUT0
SCT0->OUT[7].CLR = (1 << 2); // event 2 will clear SCT_OUT0
SCT0->LIMIT = 0x0001; // events 0 and 1 are used as counter limit
SCT0->CTRL &= ~(1 << 2); // unhalt by clearing bit 2 of CTRL register

}

0 Kudos
Reply

2,055 Views
Nandini_19
Contributor I

Yes i tried with Software triggering Put it in Burst mode  

 

But Same Result Interrupt is not occurring and Conversion Complete bit never set to 1

 

Thanks&Regards

Nandini 

0 Kudos
Reply

2,043 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I do not see the software triggering code, pls try to use the line to start ADC:

ADC0->SEQ_CTRL[0] |=1<<26;

BTW, pls refer to the code for the ADC initilization:

unsigned int sample;
void ADC_Init_SoftWareTrigger(void)
{
//power-on ADC
//SYSCON->PDRUNCFGCLR[0]=1<<10;
//enable ADC clock
SYSCON->AHBCLKCTRLSET[0]=1<<27|1<<13; //enable both IOCON and ADC0
//ADC prereset
//select ADC clock, main clock is selected as ADC clock
SYSCON->ADCCLKSEL=0x00;;
SYSCON->ADCCLKDIV=0x01;
//SYSCON->PRESETCTRLSET[0]|=0x1<<27; //set ADC0_RST
asm("nop");
asm("nop");
asm("nop");
//SYSCON->PRESETCTRLCLR[0]=0x01<<27; //set ADC0_RST
Delay_mSec(2);
ADC0->STARTUP|=0x01;
Delay_mSec(2);
ADC0->STARTUP|=0x01<<1;

//ADC pin is selected, PIO1_0/ADC0_3
IOCON->PIO[1][0]=0x00;

//set up ADC register
ADC0->CTRL=0x3F00; //12 bit resolution, synchronous mode, bypass calibration
ADC0->INSEL=0x00; //select ADC input channel
ADC0->SEQ_CTRL[0]|=1<<3|1<<30; //|1<<30;
ADC0->SEQ_CTRL[0]|=1<<31; //enable sequence A
//software trigger ADC
// ADC0->SEQ_CTRL[0]|=1<<26;

//poll ADC status reg and read ADC sample
for(;;)
{
ADC_conversion_software();
}
}

void ADC_conversion_software(void)
{
unsigned int temp;
//ADC0->CTRL &= 0x00000000;
//ADC0->SEQ_CTRL[0] |= (1<<ADC_3);
//Delay_mSec(10);
//temp=ADC0->DAT[3];
//ADC0->SEQ_CTRL[0] |= 0x80040000;
ADC0->SEQ_CTRL[0]|=1<<26;
while(!(ADC0->DAT[3]&(0x80000000))) {}
sample=(ADC0->DAT[3]&0xFFF0)>>4;
//asm("nop");
}

BR

XiangJun Rong

0 Kudos
Reply

2,034 Views
Nandini_19
Contributor I

Yes Thank you , Software Triggering is working now 

But Hardware Triggering Through SCTimer is not working

here is the code for SCTimer initializations in LPC54606

void SCT0_Init(void)
{
SYSCON->AHBCLKCTRL[1] |= (1 << 2); // Clock to SCTimer
SYSCON->PRESETCTRL[0] &=~(1 << 2); //Clear Reset to ADC0

SCT0->CONFIG |= (1 << 0)|(1<<17) ; // unified 32-bit timer, auto limit
SCT0->MATCHREL[0] = ui32Sct0_load_value ; // match 0

SCT0->MATCHREL[1] = 100 ; // match 1

SCT0->EV[0].STATE =0xFFFFFFFF ; // event 0 happens in all states
SCT0->EV[0].CTRL &=~((1 << 0) );

SCT0->EV[0].CTRL = (1 << 12) ;


SCT0->EV[1].STATE = 0xFFFFFFFF; // event 1 happens in state1
SCT0->EV[1].CTRL = (1<<0|1 << 12); // match 1 condition only

SCT0->OUT[5].SET =0x01;
SCT0->OUT[5].CLR =0x02;

SCT0->CTRL &= ~(1 << 2); // un halt by clearing bit 2 of the CTRL (to start timer)

}

ADC initializations are

 

void ADC0_init(void)
{

SYSCON->PDRUNCFG[0] &=~(1<<9|1<<19|1<<23|1<<10); //ADC Powered
SYSCON->PDRUNCFG[1] &=~(1<<3);

DelayMs(250); //Least of 20Microsec delay before enabling clock to ADC

SYSCON->AHBCLKCTRL[0] |= (1 << 27); // Clock to ADC0
SYSCON->PRESETCTRL[0] &=~(1 << 27); //Clear Reset to ADC0

DelayMs(200);
ADC0->STARTUP|=0x01;
DelayMs(200);
ADC0->STARTUP|=0x01<<1;

ADC0->INTEN = 0x01<<0;
NVIC_SetPriority(ADC0_SEQA_IRQn,3);
NVIC_EnableIRQ(ADC0_SEQA_IRQn);

vDisable_adc_fun(); //Disable all ADC chnls to avoid error

IOCON->PIO[0][ADCPinno[Chnlno]]&=~(1<<8); //Analog mode enable chnl by chnl

ADC0->CTRL =0x0659; //ADC clock as 30MHZ

ADC0->SEQ_CTRL[0]&=(~(1UL << 31));
ADC0->SEQ_CTRL[0]&= ~(0xFFF);

ADC0->SEQ_CTRL[0] |=(1<<14);
ADC0->SEQ_CTRL[0] |=1<<18 ;
ADC0->SEQ_CTRL[0] |=1<<28 ; //mode as single step
ADC0->SEQ_CTRL[0] &=~(1<<30) ; //mode as end of conversion
ADC0->SEQ_CTRL[0]|=(0x01<<(ADCChnlno[Chnlno])); //Enable ADC chnl bit

ADC0->SEQ_CTRL[0]|= (1UL << 31); //Enable Sequence



}

 

Thanks&Regards

Nandini

0 Kudos
Reply

2,022 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

good news that the software triggering mode is okay.

For the SCT initilization code, pls refer to the code. It is developed based on LPC54114, maybe you have to change for LPC546xx. I suggest you output the PWM signal to a SCT_OUTx so that you know that the PWM works fine.

 

BR

XiangJun Rong

void PWMInit(void)
{
//enable PWM module clock
SYSCON->AHBCLKCTRLSET[0]=1<<20|1<<13; //enable both IOCON and DMA
SYSCON->AHBCLKCTRLSET[1]=1<<2; //enable both IOCON and ADC0
//initialize the PWM module pins
IOCON->PIO[0][7]=0x82;
IOCON->PIO[0][8]=0x82;
IOCON->PIO[0][9]=0x82;
IOCON->PIO[0][10]=0x82;

//select PWM clock source
SCT0->CONFIG |= 1; // unified timer
SCT0->SCTMATCHREL[0] = (SystemCoreClock/10)-1; // match 0 @ 10 Hz = 100 msec
SCT0->SCTMATCHREL[1] = ((SystemCoreClock/10)/4)-1; // match 0 @ 10 Hz = 100 msec
SCT0->SCTMATCHREL[2] = ((SystemCoreClock/10)/2)-1; // match 0 @ 10 Hz = 100 msec

SCT0->EVENT[0].STATE = 0xFFFFFFFF; // event0 happen in all state
SCT0->EVENT[0].CTRL = (0 << 0) | (1 << 12);

SCT0->EVENT[1].STATE = 0xFFFFFFFF; // event1 happen in all state
SCT0->EVENT[1].CTRL = (1 << 0) | (1 << 12);

SCT0->EVENT[2].STATE = 0xFFFFFFFF; // event2 happen in all state
SCT0->EVENT[2].CTRL = (2 << 0) | (1 << 12);

SCT0->OUT[0].SET = (1 << 1); // event 1 will set SCT_OUT0
SCT0->OUT[0].CLR = (1 << 2); // event 2 will clear SCT_OUT0
SCT0->OUT[7].SET = (1 << 1); // event 1 will set SCT_OUT0
SCT0->OUT[7].CLR = (1 << 2); // event 2 will clear SCT_OUT0
SCT0->LIMIT = 0x0001; // events 0 and 1 are used as counter limit
SCT0->CTRL &= ~(1 << 2); // unhalt by clearing bit 2 of CTRL register

}

0 Kudos
Reply