FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [May 2008 Threads] at91sam7x256 interrupts and FreeRTOS - gccPosted by John Pierce on May 3, 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... */ // // externvoid TimerSetup1(void); TimerSetup1();
// (Here is the code from TimerSetup1()): voidTimerSetup1(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 clockand 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_AICpAIC = AT91C_BASE_AIC; // enable the Timer's peripheral clocks volatile AT91PS_PMCpPMC = 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_PIOpPIO = 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???
RE: at91sam7x256 interrupts and FreeRTOS - gccPosted by Richard on May 5, 2008 Unfortunately I can't go through the timer setup code just at the moment (this is SAM7 specific), but just to clarify, are you saying that the timer works fine with exactly the same code when not using a FreeRTOS.org build, but never gets entered even once when using FreeRTOS.org in your build? Are there any significant differences in the way interrupts are handled within the startup code for the projects for which it works? I cannot see why all the other interrupts would work (EMAC, UART, PIT) but not this one, unless there is some sort of peripheral resource sharing clash somewhere.
The PIT uses the system interrupt, which is shared with the Debug COM port, are you using the Debug COM port? Is the RTOS tick itnerrupt working when you also use your extra timer?
Regards.
RE: at91sam7x256 interrupts and FreeRTOS - gccPosted by John Pierce on May 5, 2008 To clarify,
1. - exactly the same code? - All the setup code is the same, although in the other examples I'm running the timer in THUMB mode and I changed it to compile in ARM mode with the added entry header as in the FreeRTOS.org examples. 2. - "all the other interrupts." Unfortunately one of the clues is fuzzy, since I realized the UARTs are not using the interrupt examples, but just reading or writing the characters when the device buffer is ready. Although it is true that the EMAC interrupt is working. 3. - The RTOS tick interrupt is working fine. 4. - You are right in pointing out the obvious, and I just need to go through and find the difference, I think, in setup. I was hoping there was something basic I overlooked that someone would see.
Thanks for the feedback. I'll let you know if I find the issue.
RE: at91sam7x256 interrupts and FreeRTOS - gccPosted by John Pierce on May 5, 2008 Well, the issue is solved. It had to be fairly simple, I suppose. The Atmel startup file had its own IRQ handler written in assembly code, which then vectors to the user's routine. The FreeRTOS.org code just reads the AIC vector and branches to the routine. The difference was that on return, the Atmel code clears the AIC interrupt, and the user's routine has to do that in the FreeRTOS.org environment.
Although, there is still a little quirk, which I will eventually track down and is not a show-stopper. My timer setup routine is supposed to enable the timer and start it running, but after everything is set up I checked the timer and it wasn't running. So I wrote an extra enable+start command to the timer in my primary task, and then it started working..
Anyway, thanks. It looks good now.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|