ADC zero crossing interrupt

Discussion to talk about software related topics only.
Post Reply
sulliwk06
Posts: 118
Joined: Tue Sep 17, 2013 7:14 am

ADC zero crossing interrupt

Post by sulliwk06 »

So I've been trying to set up the AtoD converter on the NANO54415 to trigger an interrupt at every zero crossing. And it seems to not be triggering. I have verified that I am getting positive and negative values from the result register on channel 0. I'm wondering if I have the interrupt vector set up right. The reference manual says that I add the source number to 64 for INTC0, and 128 for INTC1, but it doesn't say anything for INTC2 which is where I find ADC_ZCSR for source 34. I assume its just another 64 up, but something isn't working.

Can anyone tell me what I'm doing wrong?


Edit: I have also confirmed that the appropriate bit in the zero crossing status bit is being set. And I have tried using the force interrupt register sim2.intc[2].intfrch |= 0x0004; and the interrupt isn't being called. So does that narrow it down to the SetIntc call?

Code: Select all

void ZeroCrossingInterrupt()
{
	zeroCrossingCount++;
}

void CreateZeroCrossingInterrupt(int fd)
{
	if(!zeroCrossingInterruptCreated)
	{
		volatile WORD vw;

		//initialize ADC, taken from periodic AD
		sim2.adc.cr1 = 0;
		sim2.adc.cr2 = 0;
		sim2.adc.zccr = 0;
		sim2.adc.lst1 = 0x3210; //Ch 0....
		sim2.adc.lst2 = 0x7654; //ch 7 in result 0..7
		sim2.adc.sdis = 0; //All channels enabled
		sim2.adc.sr = 0xFFFF;
		for (int i = 0; i < 8; i++)
		{
		  vw = sim2.adc.rslt[i];
		  sim2.adc.ofs[i] = 0;
		}

		sim2.adc.lsr = 0xFFFF;
		sim2.adc.zcsr = 0xFFFF;

		sim2.adc.pwr = 0; //Everything is turned on
		sim2.adc.cal = 0x0000;
		sim2.adc.pwr2 = 0x0005;
		sim2.adc.div = 0x505;
		sim2.adc.asdiv = 0x13;
		//end of init

		if(SetADCZeroCrossingISR(ZeroCrossingInterrupt) == INT_NO_ERROR)
		{
			dprintf(fd,"\r\nZero crossing interrupt created");
			zeroCrossingInterruptCreated = true;
		}
		else
		{
			dprintf(fd,"\r\nfailed to create zero crossing interrupt");
		}
	}
}

INTERRUPT(adc_zc_int_isr, 0x2200 ) //analog to digital zero crossing interrupt
{
	ADC_ZCFunction();

	//Write 1 to respective bit in ADC_ZCSR
	sim2.adc.zcsr |= 0x0001; //reset interrupt
}

int SetADCZeroCrossingISR(void (*isrPointer)())
{
	if(ADC_ZCTaken)
	{
		return INT_TAKEN;
	}
	ADC_ZCTaken = TRUE;

	ADC_ZCFunction = isrPointer;

	sim2.adc.ofs[0]=0x07D0 << 3;//set mid point

	sim2.adc.zccr = 0x0003;//set interrupt for any sign change on channel 0


	SetIntc(INTERRUPT_CONTROLLER_NUMBER,/* interrupt controller 2 */
	(long)&adc_zc_int_isr, /* Our interrupt function */
	((INTERRUPT_CONTROLLER_NUMBER + 1) * 64)+34, /* The vector number is the interrupt source number plus the offset of the interrupt controller */ //source 34
	2 /* priority.*/
	);

	//start reading AD input
	sim2.adc.sr = 0xffff;
//	sim2.adc.cr1 |= 0x0400;//enable zero crossing interrupt
	sim2.adc.cr1 |= (ADC_CR1_START | ADC_CR1_LOOP | 0x0400);

	return INT_NO_ERROR;
}
sulliwk06
Posts: 118
Joined: Tue Sep 17, 2013 7:14 am

Re: ADC zero crossing interrupt

Post by sulliwk06 »

So I figured it out. I thought I'd post here in case someone comes along having the same problem.

In all the app notes for interrupts, I've seen the 3rd parameter of the SetIntc call commented as "vector number" and the freescale manual describes the vector number as
"The 8-bit interrupt vector is formed using the following algorithm:
For INTC0, vector_number = 64 + interrupt source number
For INTC1, vector_number = 128 + interrupt source number"

It seems that the 3rd parameter needs to be the source number, not the vector number. Once I changed that everything worked fine.
Post Reply