Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

at91sam7x256 interrupts and FreeRTOS - gcc

Posted 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 - gcc

Posted 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 - gcc

Posted 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 - gcc

Posted 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.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists