Main Site Documentation

RLPLite on FEZ Hydra Interrupt Handling


#1

Hi guys, I have a FEZ Hydra and I want to sample GPIO inputs every 100 microseconds, which is too fast for .NET and I need to use RLPLite and native code. Since I want to sample at 100 microseconds, I try to use Timer2 on FEZ Hydra, below is the code to do the timer initialization. The timer works fine and I can see the right waveform on the oscilliscope, however if I enable the interrupt handler by setting AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_TC2; the software hangs and I have to reflash the firmware. Any one has any idea how to handle interrupts of any sort in native code? Much appreciated.


void timer0_c_irq_handler(void)
{

	//* Acknowledge interrupt status
 	dummy = AT91C_BASE_TC0->TC_SR;
 	test++;
// 	
// 	AT91C_BASE_AIC->AIC_ICCR = (0x1 << AT91C_ID_TC0);
}

int init_timer(void *voidArray, int* intArray, unsigned char* byteArray)
{
	test = 1;
	AT91C_BASE_PIOD->PIO_PDR = AT91C_PD10_TIOA2;
	AT91C_BASE_PIOD->PIO_OER = AT91C_PD10_TIOA2;  

	AT91C_BASE_PIOD->PIO_BSR = AT91C_PD10_TIOA2;

// 	if(AT91C_BASE_TC2->TC_SR & AT91C_TC_CLKSTA){
// 		return 0; //somebody already enabled it, perhaps the .NET framework
// 	}
	
	AT91C_BASE_PMC->PMC_PCER = ((unsigned int) 1 << AT91C_ID_TC2);
	//setup timer
	AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS ;
	AT91C_BASE_TC2->TC_IDR = 0xFFFFFFFF; //disable interrupt
	dummy = AT91C_BASE_TC2->TC_SR;	//Clear status bit
	
	AT91C_BASE_TC2->TC_RA = 3750;
	AT91C_BASE_TC2->TC_RB = 4100;
	AT91C_BASE_TC2->TC_RC = 5000; //every 100 us
	
	AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK |
		AT91C_TC_BURST_NONE|
		AT91C_TC_ETRGEDG_NONE|
		AT91C_TC_EEVTEDG_NONE|
		AT91C_TC_EEVT_XC0 |
		AT91C_TC_WAVESEL_UP_AUTO|
		AT91C_TC_WAVE|
		AT91C_TC_ACPA_SET |
		AT91C_TC_ACPC_CLEAR |
		AT91C_TC_EEVT_XC0
	; //use TIMER_CLOCK1 @ 100 MHz, WAVE mode, WAVE mode with trigger on RC compare, bits set: 15,14,10

 	AT91C_BASE_TC2->TC_IER = AT91C_TC_CPCS | AT91C_TC_CPAS; //enable RA, RB, RC interrupt on compare match
	
	//set interrupt handler
 	AT91C_BASE_AIC->AIC_IDCR = 0x1 << AT91C_ID_TC2;//Disable the interrupt on the interrupt controller
	AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned int) timer0_c_irq_handler ;
	AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC2] = AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED | 0x4; //Positive edge triggered, priority 4
	AT91C_BASE_AIC->AIC_ICCR = 0x1 << AT91C_ID_TC2 ;//clear pending interrupt	
 	AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_TC2 ;//Enable interrupt handler
	
	AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN;	//Enable the clock
	AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG;	//Start the clock

	return 1;
}

#2

ARM9 processors have one interrupt handler, which is handled by NETMF internally. On full RLP, there is a way to install interrupt handlers but not on RLP Lite. If this was Cortex, like Cerberus then yes you can do it on RLP Lite.

Your options are:

  1. use premium board
  2. use a cortex processor board
  3. modify the firmware to build your handler in the firmware or into RLP extensions. This is the cheapest option but the most difficult. But you are up for a challenge right? :slight_smile:

Welcome to the community.


#3

Could one reinstall the interrupt handler as one’s RLPLite code, then from there, call the NETMF handler?

I don’t know the internals of the ARM9 or NETMF, so I’m stabbing in the dark here…


#4

Yes you know the NETMF interrupt handler address, which if found in the interrupt controller. This is for advanced users though.


#5

Yeah, I’m sure there’s all kinds of state and other requirements, I was mostly just pondering.