Temporarily revert the AVR32 port back to the V6.0.5 files. Work will continue on the reverted files following the next release.

This commit is contained in:
Richard Barry 2010-09-20 11:08:39 +00:00
parent 8f6f5820aa
commit 18f5af7195
3 changed files with 462 additions and 33 deletions

View file

@ -1,3 +1,17 @@
/*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.
@ -51,8 +65,10 @@
licensing and training services.
*/
/* Standard includes. */
/* Standard includes. */
#include <sys/cpu.h>
#include <sys/usart.h>
#include <malloc.h>
/* Scheduler includes. */
@ -62,8 +78,10 @@
/* AVR32 UC3 includes. */
#include <avr32/io.h>
#include "gpio.h"
#include <nlao_cpu.h>
#include <nlao_usart.h>
#if( configTICK_USE_TC==1 )
#include "tc.h"
#endif
/* Constants required to setup the task context. */
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
@ -73,8 +91,11 @@
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
volatile unsigned long ulCriticalNesting = 9999UL;
/* Clear the COUNT&COMPARE match Interrupt Flag. */
static void prvClearCcInt( void );
#if( configTICK_USE_TC==0 )
static void prvScheduleNextTick( void );
#else
static void prvClearTcInt( void );
#endif
/* Setup the timer to generate the tick interrupts. */
static void prvSetupTimerInterrupt( void );
@ -119,8 +140,8 @@ void _init_startup(void)
#endif
/* Give the used PBA clock frequency to Newlib, so it can work properly. */
set_cpu_hz( configPBA_CLOCK_HZ );
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
set_cpu_hz( configCPU_CLOCK_HZ );
/* Code section present if and only if the debug trace is activated. */
#if configDBG
@ -192,16 +213,22 @@ 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();
/* Clear the interrupt flag. */
prvClearCcInt();
#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
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
calls in a critical section . */
@ -214,13 +241,6 @@ __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. */
@ -288,7 +308,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 ) 0x00000000; /* R7 aka Frame Pointer */
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
return pxTopOfStack;
@ -318,28 +338,124 @@ void vPortEndScheduler( void )
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
clock cycles from now. */
static void prvScheduleFirstTick(void)
{
Set_system_register(AVR32_COMPARE, configCPU_CLOCK_HZ/configTICK_RATE_HZ);
Set_system_register(AVR32_COUNT, 0);
}
/*-----------------------------------------------------------*/
#if( configTICK_USE_TC==0 )
static void prvScheduleFirstTick(void)
{
unsigned long lCycles;
__attribute__((__noinline__)) static void prvClearCcInt(void)
{
Set_system_register(AVR32_COMPARE, Get_system_register(AVR32_COMPARE));
}
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
/*-----------------------------------------------------------*/
/* 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. */
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, AVR32_INTC_INT0);
prvScheduleFirstTick();
#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
}
/*-----------------------------------------------------------*/