johnkpierce wrote on Saturday, May 03, 2008:
I realize there have been other posts on this issue, but I still am up a creek.
I followed the atmel code which doesn’t use the RTOS and have 3 timer interrupts, a PIO interrupt, and 3 uarts working. The UART code ports seamlessly to the RTOS. I followed examples in the RTOS for the uIP EMAC, and also looked at another implementation example that had a full interrupt-setup interface as models for my setup routines.
My issue is that I don’t appear to be getting my PIO or my Timer interrupts. Code compiles correctly, everything is in place, the interrupts are running in ARM mode, but they never trigger. For the PIO, pins are set correctly. For the timers, pins are not an issue.
In the port.c code for the at91sam7, I placed my timer interrupt setup along with the PIT setup, figuring that would be the right time to do it. The actual interrupt is in a timer interrupt module that is compiled for ARM. Here is the code:
in port.c:
/*
* Setup the timer 0 to generate the tick interrupts at the required frequency.
*/
static void prvSetupTimerInterrupt( void )
{
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
//! This is the original code !
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
on whether the preemptive or cooperative scheduler is being used. */
#if configUSE_PREEMPTION == 0
extern void ( vNonPreemptiveTick ) ( void );
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vNonPreemptiveTick );
#else
extern void ( vPreemptiveTick )( void );
AT91F_AIC_ConfigureIt( AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPreemptiveTick );
#endif
/* Configure the PIT period. */
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
/* Enable the interrupt. Global interrupts are disables at this point so
this is safe. */
AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_SYS;
//! This is the code I added !
/* See if we can do timer interrupt here… */
//
//
extern void TimerSetup1(void);
TimerSetup1();
// (Here is the code from TimerSetup1()):
void TimerSetup1(void) {
AT91PS_TCB pTCB = AT91C_BASE_TCB; // create a pointer to TC Global Register structure
pTCB->TCB_BCR = 0; // SYNC trigger not used
pTCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; // external clocks not used
AT91PS_TC pTC = AT91C_BASE_TC1; // create a pointer to channel 1 Register structure
pTC->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable the clock and start it
pTC->TC_CMR = AT91C_TC_CPCTRG | AT91C_TC_CLKS_TIMER_DIV4_CLOCK;
pTC->TC_RC = 125; // clk4
pTC->TC_IER = AT91C_TC_CPCS; // RC compare interrupt
pTC->TC_IDR = ~AT91C_TC_CPCS; // disable all except RC compare interrupt
}
// and here we are back to what is in port.c
volatile AT91PS_AIC pAIC = AT91C_BASE_AIC;
// enable the Timer’s peripheral clocks
volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; // pointer to PMC data structure
pPMC->PMC_PCER = (1<<AT91C_ID_TC1);
// Set up the AIC registers for Timer 1
extern void ( Timer1IrqHandler )( void );
AT91F_AIC_ConfigureIt( AT91C_ID_TC1, 0x4, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)(void) ) Timer1IrqHandler );
pAIC->AIC_ICCR = (1<<AT91C_ID_TC1); // Clear the TC1 interrupt in AIC Interrupt Clear Command Register
pAIC->AIC_IDCR &= (~(1<<AT91C_ID_TC1)); // Remove disable timer 1 interrupt in AIC Interrupt Disable Command Reg
pAIC->AIC_IECR = (1<<AT91C_ID_TC1); // Enable the TC1 interrupt in AIC Interrupt Enable Command Register
}
Finally, here is the actual interrupt:
void Timer1IrqHandler( void ) __attribute__ ((interrupt ("IRQ")));
void Timer1IrqHandler (void) {
volatile AT91PS_TC pTC = AT91C_BASE_TC1; // pointer to timer channel 1 register structure
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOB; // pointer to PIO register structure
unsigned int dummy; // temporary
dummy = pTC->TC_SR; // read TC1 Status Register to clear interrupt
// just a test function
if (tickcount1++ >= 200)
{
tickcount1 = 0;
}
if ((BUZZER_BASE->PIO_ODSR & BUZZER_PIN) == BUZZER_PIN)
{
BUZZER_BASE->PIO_CODR = BUZZER_PIN;
}
else
BUZZER_BASE->PIO_SODR = BUZZER_PIN;
#endif
}
The buzzer never sounds, although in the other Atmel example it buzzes just fine.
What am I missing???