Create an updated AVR32 UC3A project.

This commit is contained in:
Richard Barry 2010-06-13 14:10:42 +00:00
parent d31b403659
commit 8405dbe3d5
3 changed files with 33 additions and 462 deletions

View file

@ -1,17 +1,3 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief FreeRTOS port source for AVR32 UC3.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 devices can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
*****************************************************************************/
/*
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
@ -65,10 +51,8 @@
licensing and training services.
*/
/* Standard includes. */
#include <sys/cpu.h>
#include <sys/usart.h>
#include <malloc.h>
/* Scheduler includes. */
@ -78,10 +62,8 @@
/* AVR32 UC3 includes. */
#include <avr32/io.h>
#include "gpio.h"
#if( configTICK_USE_TC==1 )
#include "tc.h"
#endif
#include <nlao_cpu.h>
#include <nlao_usart.h>
/* Constants required to setup the task context. */
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
@ -91,11 +73,8 @@
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
volatile unsigned long ulCriticalNesting = 9999UL;
#if( configTICK_USE_TC==0 )
static void prvScheduleNextTick( void );
#else
static void prvClearTcInt( void );
#endif
/* Clear the COUNT&COMPARE match Interrupt Flag. */
static void prvClearCcInt( void );
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
@ -140,8 +119,8 @@ void _init_startup(void)
#endif
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
set_cpu_hz( configCPU_CLOCK_HZ );
/* Give the used PBA clock frequency to Newlib, so it can work properly. */
set_cpu_hz( configPBA_CLOCK_HZ );
/* Code section present if and only if the debug trace is activated. */
#if configDBG
@ -213,22 +192,16 @@ void *pvReturn;
/*-----------------------------------------------------------*/
/* The cooperative scheduler requires a normal IRQ service routine to
simply increment the system tick. */
/* The preemptive scheduler is defined as "naked" as the full context is saved
simply increment the system tick.
The preemptive scheduler is defined as "naked" as the full context is saved
on entry as part of the context switch. */
__attribute__((__naked__)) static void vTick( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT_OS_INT();
#if( configTICK_USE_TC==1 )
/* Clear the interrupt flag. */
prvClearTcInt();
#else
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
prvScheduleNextTick();
#endif
/* Clear the interrupt flag. */
prvClearCcInt();
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
calls in a critical section . */
@ -241,6 +214,13 @@ __attribute__((__naked__)) static void vTick( void )
}
/*-----------------------------------------------------------*/
/* Note that the scall handler in the framework 'exception.x' must
* jump to this handler.
* In file: 'AVR32_UC3/Drivers/INTC/exception.x' replace the line after
* '_handle_Supervisor_Call:' which might be 'rjmp $'
* with the instruction:
* 'lda.w pc, SCALLYield'
*/
__attribute__((__naked__)) void SCALLYield( void )
{
/* Save the context of the interrupted task. */
@ -308,7 +288,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x00000000; /* R7 aka Frame Pointer */
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
return pxTopOfStack;
@ -338,124 +318,28 @@ void vPortEndScheduler( void )
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
#if( configTICK_USE_TC==0 )
static void prvScheduleFirstTick(void)
{
unsigned long lCycles;
static void prvScheduleFirstTick(void)
{
Set_system_register(AVR32_COMPARE, configCPU_CLOCK_HZ/configTICK_RATE_HZ);
Set_system_register(AVR32_COUNT, 0);
}
/*-----------------------------------------------------------*/
lCycles = Get_system_register(AVR32_COUNT);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
Set_system_register(AVR32_COMPARE, lCycles);
}
__attribute__((__noinline__)) static void prvScheduleNextTick(void)
{
unsigned long lCycles, lCount;
lCycles = Get_system_register(AVR32_COMPARE);
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
// generation feature does not get disabled.
if(0 == lCycles)
{
lCycles++;
}
lCount = Get_system_register(AVR32_COUNT);
if( lCycles < lCount )
{ // We missed a tick, recover for the next.
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
}
Set_system_register(AVR32_COMPARE, lCycles);
}
#else
__attribute__((__noinline__)) static void prvClearTcInt(void)
{
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
}
#endif
__attribute__((__noinline__)) static void prvClearCcInt(void)
{
Set_system_register(AVR32_COMPARE, Get_system_register(AVR32_COMPARE));
}
/*-----------------------------------------------------------*/
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt(void)
{
#if( configTICK_USE_TC==1 )
volatile avr32_tc_t *tc = &AVR32_TC;
// Options for waveform genration.
tc_waveform_opt_t waveform_opt =
{
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
.bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */
.beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */
.bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */
.bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */
.aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */
.aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
.enetrg = FALSE, /* External event trigger enable. */
.eevt = 0, /* External event selection. */
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
.cpcdis = FALSE, /* Counter disable when RC compare. */
.cpcstop = FALSE, /* Counter clock stopped with RC compare. */
.burst = FALSE, /* Burst signal selection. */
.clki = FALSE, /* Clock inversion. */
.tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */
};
tc_interrupt_t tc_interrupt =
{
.etrgs=0,
.ldrbs=0,
.ldras=0,
.cpcs =1,
.cpbs =0,
.cpas =0,
.lovrs=0,
.covfs=0,
};
#endif
/* Disable all interrupt/exception. */
portDISABLE_INTERRUPTS();
/* Register the compare interrupt handler to the interrupt controller and
enable the compare interrupt. */
#if( configTICK_USE_TC==1 )
{
INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0);
/* Initialize the timer/counter. */
tc_init_waveform(tc, &waveform_opt);
/* Set the compare triggers.
Remember TC counter is 16-bits, so counting second is not possible!
That's why we configure it to count ms. */
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
/* Start the timer/counter. */
tc_start(tc, configTICK_TC_CHANNEL);
}
#else
{
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
prvScheduleFirstTick();
}
#endif
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, AVR32_INTC_INT0);
prvScheduleFirstTick();
}
/*-----------------------------------------------------------*/