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

pull/4/head
Richard Barry 15 years ago
parent 8f6f5820aa
commit 18f5af7195

@ -0,0 +1,297 @@
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Exception and interrupt vectors.
*
* This file maps all events supported by an AVR32UC.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32UC devices with an INTC module can be used.
* - AppNote:
*
* \author Atmel Corporation: http://www.atmel.com \n
* Support and FAQ: http://support.atmel.no/
*
******************************************************************************/
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <avr32/io.h>
#include "intc.h"
//! @{
//! \verbatim
.section .exception, "ax", @progbits
// Start of Exception Vector Table.
// EVBA must be aligned with a power of two strictly greater than the EVBA-
// relative offset of the last vector.
.balign 0x200
// Export symbol.
.global _evba
.type _evba, @function
_evba:
.org 0x000
// Unrecoverable Exception.
_handle_Unrecoverable_Exception:
rjmp $
.org 0x004
// TLB Multiple Hit: UNUSED IN AVR32UC.
_handle_TLB_Multiple_Hit:
rjmp $
.org 0x008
// Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
rjmp $
.org 0x00C
// Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
rjmp $
.org 0x010
// NMI.
_handle_NMI:
rjmp $
.org 0x014
// Instruction Address.
_handle_Instruction_Address:
rjmp $
.org 0x018
// ITLB Protection.
_handle_ITLB_Protection:
rjmp $
.org 0x01C
// Breakpoint.
_handle_Breakpoint:
rjmp $
.org 0x020
// Illegal Opcode.
_handle_Illegal_Opcode:
rjmp $
.org 0x024
// Unimplemented Instruction.
_handle_Unimplemented_Instruction:
rjmp $
.org 0x028
// Privilege Violation.
_handle_Privilege_Violation:
rjmp $
.org 0x02C
// Floating-Point: UNUSED IN AVR32UC.
_handle_Floating_Point:
rjmp $
.org 0x030
// Coprocessor Absent: UNUSED IN AVR32UC.
_handle_Coprocessor_Absent:
rjmp $
.org 0x034
// Data Address (Read).
_handle_Data_Address_Read:
rjmp $
.org 0x038
// Data Address (Write).
_handle_Data_Address_Write:
rjmp $
.org 0x03C
// DTLB Protection (Read).
_handle_DTLB_Protection_Read:
rjmp $
.org 0x040
// DTLB Protection (Write).
_handle_DTLB_Protection_Write:
rjmp $
.org 0x044
// DTLB Modified: UNUSED IN AVR32UC.
_handle_DTLB_Modified:
rjmp $
.org 0x050
// ITLB Miss: UNUSED IN AVR32UC.
_handle_ITLB_Miss:
rjmp $
.org 0x060
// DTLB Miss (Read): UNUSED IN AVR32UC.
_handle_DTLB_Miss_Read:
rjmp $
.org 0x070
// DTLB Miss (Write): UNUSED IN AVR32UC.
_handle_DTLB_Miss_Write:
rjmp $
.org 0x100
// Supervisor Call.
_handle_Supervisor_Call:
lda.w pc, SCALLYield
// Interrupt support.
// The interrupt controller must provide the offset address relative to EVBA.
// Important note:
// All interrupts call a C function named _get_interrupt_handler.
// This function will read group and interrupt line number to then return in
// R12 a pointer to a user-provided interrupt handler.
.balign 4
_int0:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int0_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int0_normal:
#endif
mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int1:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int1_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int1_normal:
#endif
mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int2:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int2_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int2_normal:
#endif
mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
_int3:
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
// CPU upon interrupt entry.
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
mfsr r12, AVR32_SR
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
cp.w r12, 0b110
brlo _int3_normal
lddsp r12, sp[0 * 4]
stdsp sp[6 * 4], r12
lddsp r12, sp[1 * 4]
stdsp sp[7 * 4], r12
lddsp r12, sp[3 * 4]
sub sp, -6 * 4
rete
_int3_normal:
#endif
mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.
call _get_interrupt_handler
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
// Constant data area.
.balign 4
// Values to store in the interrupt priority registers for the various interrupt priority levels.
// The interrupt priority registers contain the interrupt priority level and
// the EVBA-relative interrupt vector offset.
.global ipr_val
.type ipr_val, @object
ipr_val:
.word (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\
(INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\
(INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\
(INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)
//! \endverbatim
//! @}

@ -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
}
/*-----------------------------------------------------------*/

@ -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.
@ -86,6 +100,8 @@ extern "C" {
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
#if( configUSE_16_BIT_TICKS == 1 )
typedef unsigned portSHORT portTickType;
#define portMAX_DELAY ( portTickType ) 0xffff
@ -182,7 +198,7 @@ extern void *pvPortRealloc( void *pv, size_t xSize );
"st.w r8[0], r0 \n\t"\
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7 \n\t"\
"ldm sp++, r0-r7 \n\t"\
/* R0-R7 should not be used below this line */ \
/* Skip PC and SR (will do it at the end) */ \
"sub sp, -2*4 \n\t"\

Loading…
Cancel
Save