From 6314c322010a67c2c6cd09ae549c98e5c36245fa Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 13 Jun 2010 14:10:42 +0000 Subject: [PATCH] Create an updated AVR32 UC3A project. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1032 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Source/portable/GCC/AVR32_UC3/exception.S | 297 ---------------------- Source/portable/GCC/AVR32_UC3/port.c | 180 +++---------- Source/portable/GCC/AVR32_UC3/portmacro.h | 18 +- 3 files changed, 33 insertions(+), 462 deletions(-) delete mode 100644 Source/portable/GCC/AVR32_UC3/exception.S diff --git a/Source/portable/GCC/AVR32_UC3/exception.S b/Source/portable/GCC/AVR32_UC3/exception.S deleted file mode 100644 index 9a2833f2e..000000000 --- a/Source/portable/GCC/AVR32_UC3/exception.S +++ /dev/null @@ -1,297 +0,0 @@ -/*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 -#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 -//! @} diff --git a/Source/portable/GCC/AVR32_UC3/port.c b/Source/portable/GCC/AVR32_UC3/port.c index 9f49e4b15..ecb39aea6 100644 --- a/Source/portable/GCC/AVR32_UC3/port.c +++ b/Source/portable/GCC/AVR32_UC3/port.c @@ -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 -#include + #include /* Scheduler includes. */ @@ -78,10 +62,8 @@ /* AVR32 UC3 includes. */ #include #include "gpio.h" -#if( configTICK_USE_TC==1 ) - #include "tc.h" -#endif - +#include +#include /* 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; - - 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; +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_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(); } +/*-----------------------------------------------------------*/ diff --git a/Source/portable/GCC/AVR32_UC3/portmacro.h b/Source/portable/GCC/AVR32_UC3/portmacro.h index e7ecb2daa..87e640770 100644 --- a/Source/portable/GCC/AVR32_UC3/portmacro.h +++ b/Source/portable/GCC/AVR32_UC3/portmacro.h @@ -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. @@ -100,8 +86,6 @@ 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 @@ -198,7 +182,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"\ -- 2.39.5