--- /dev/null
+/******************************************************************************
+ * Exception and interrupt vectors.
+ *
+ * This file has been built from the Newlib exception.S. It maps all events
+ * supported by a UC3.
+ *
+ * - Compiler: GNU GCC for AVR32
+ * - Supported devices: All AVR32A devices with an INTC module can be used.
+ * - AppNote:
+ *
+ * - author Atmel Corporation: http://www.atmel.com \n
+ * Support email: avr32@atmel.com
+ *
+ ******************************************************************************/
+
+/* 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"
+
+
+ .section .exception, "ax"
+
+
+// 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
+_evba:
+
+ .org 0x000
+ // Unrecoverable Exception.
+_handle_Unrecoverable_Exception:
+ rjmp $
+
+ .org 0x004
+ // TLB Multiple Hit: UNUSED IN AVR32A.
+_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 AVR32A.
+_handle_Floating_Point:
+ rjmp $
+
+ .org 0x030
+ // Coprocessor Absent: UNUSED IN AVR32A.
+_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 AVR32A.
+_handle_DTLB_Modified:
+ rjmp $
+
+ .org 0x050
+ // ITLB Miss: UNUSED IN AVR32A.
+_handle_ITLB_Miss:
+ rjmp $
+
+ .org 0x060
+ // DTLB Miss (Read): UNUSED IN AVR32A.
+_handle_DTLB_Miss_Read:
+ rjmp $
+
+ .org 0x070
+ // DTLB Miss (Write): UNUSED IN AVR32A.
+_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
+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)
--- /dev/null
+/*This file has been prepared for Doxygen automatic documentation generation.*/\r
+/*! \file *********************************************************************\r
+ *\r
+ * \brief FreeRTOS port source for AVR32 UC3.\r
+ *\r
+ * - Compiler: GNU GCC for AVR32\r
+ * - Supported devices: All AVR32 devices can be used.\r
+ * - AppNote:\r
+ *\r
+ * \author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ *****************************************************************************/\r
+\r
+/*\r
+ FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section\r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ See http://www.FreeRTOS.org for documentation, latest information, license\r
+ and contact details. Please ensure to read the configuration and relevant\r
+ port sections of the online documentation.\r
+ ***************************************************************************\r
+*/\r
+\r
+\r
+/* Standard includes. */\r
+#include <sys/cpu.h>\r
+#include <sys/usart.h>\r
+#include <malloc.h>\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* AVR32 UC3 includes. */\r
+#include <avr32/io.h>\r
+#include "gpio.h"\r
+#if( configTICK_USE_TC==1 )\r
+ #include "tc.h"\r
+#endif\r
+\r
+\r
+/* Constants required to setup the task context. */\r
+#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */\r
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )\r
+\r
+/* Each task maintains its own critical nesting variable. */\r
+#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )\r
+volatile unsigned portLONG ulCriticalNesting = 9999UL;\r
+\r
+#if( configTICK_USE_TC==0 )\r
+ static void prvScheduleNextTick( void );\r
+#endif\r
+\r
+/* Setup the timer to generate the tick interrupts. */\r
+static void prvSetupTimerInterrupt( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Low-level initialization routine called during Newlib's startup.\r
+ * This version comes in replacement to the default one provided by Newlib.\r
+ * Newlib's _init_startup only calls init_exceptions, but Newlib's exception\r
+ * vectors are not compatible with the SCALL management in the current FreeRTOS\r
+ * port. More low-level initializations are besides added here.\r
+ */\r
+void _init_startup(void)\r
+{\r
+ /* Import the Exception Vector Base Address. */\r
+ extern void _evba;\r
+\r
+ #if configHEAP_INIT\r
+ extern void __heap_start__;\r
+ extern void __heap_end__;\r
+ portBASE_TYPE *pxMem;\r
+ #endif\r
+\r
+ /* Load the Exception Vector Base Address in the corresponding system register. */\r
+ Set_system_register( AVR32_EVBA, ( int ) &_evba );\r
+\r
+ /* Enable exceptions. */\r
+ ENABLE_ALL_EXCEPTIONS();\r
+\r
+ /* Initialize interrupt handling. */\r
+ INTC_init_interrupts();\r
+\r
+ #if configHEAP_INIT\r
+\r
+ /* Initialize the heap used by malloc. */\r
+ for( pxMem = &__heap_start__; pxMem < ( portBASE_TYPE * )&__heap_end__; )\r
+ {\r
+ *pxMem++ = 0xA5A5A5A5;\r
+ }\r
+\r
+ #endif\r
+\r
+ /* Give the used CPU clock frequency to Newlib, so it can work properly. */\r
+ set_cpu_hz( configCPU_CLOCK_HZ );\r
+\r
+ /* Code section present if and only if the debug trace is activated. */\r
+ #if configDBG\r
+\r
+ /* Initialize the USART used for the debug trace with the configured parameters. */\r
+ set_usart_base( ( void * ) configDBG_USART );\r
+ gpio_enable_module_pin( configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION );\r
+ gpio_enable_module_pin( configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION );\r
+ usart_init( configDBG_USART_BAUDRATE );\r
+\r
+ #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * malloc, realloc and free are meant to be called through respectively\r
+ * pvPortMalloc, pvPortRealloc and vPortFree.\r
+ * The latter functions call the former ones from within sections where tasks\r
+ * are suspended, so the latter functions are task-safe. __malloc_lock and\r
+ * __malloc_unlock use the same mechanism to also keep the former functions\r
+ * task-safe as they may be called directly from Newlib's functions.\r
+ * However, all these functions are interrupt-unsafe and SHALL THEREFORE NOT BE\r
+ * CALLED FROM WITHIN AN INTERRUPT, because __malloc_lock and __malloc_unlock do\r
+ * not call portENTER_CRITICAL and portEXIT_CRITICAL in order not to disable\r
+ * interrupts during memory allocation management as this may be a very time-\r
+ * consuming process.\r
+ */\r
+\r
+/*\r
+ * Lock routine called by Newlib on malloc / realloc / free entry to guarantee a\r
+ * safe section as memory allocation management uses global data.\r
+ * See the aforementioned details.\r
+ */\r
+void __malloc_lock(struct _reent *ptr)\r
+{\r
+ vTaskSuspendAll();\r
+}\r
+\r
+/*\r
+ * Unlock routine called by Newlib on malloc / realloc / free exit to guarantee\r
+ * a safe section as memory allocation management uses global data.\r
+ * See the aforementioned details.\r
+ */\r
+void __malloc_unlock(struct _reent *ptr)\r
+{\r
+ xTaskResumeAll();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Added as there is no such function in FreeRTOS. */\r
+void *pvPortRealloc( void *pv, size_t xWantedSize )\r
+{\r
+void *pvReturn;\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ pvReturn = realloc( pv, xWantedSize );\r
+ }\r
+ xTaskResumeAll();\r
+\r
+ return pvReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The cooperative scheduler requires a normal IRQ service routine to\r
+simply increment the system tick. */\r
+/* The preemptive scheduler is defined as "naked" as the full context is saved\r
+on entry as part of the context switch. */\r
+__attribute__((__naked__)) static void vTick( void )\r
+{\r
+ /* Save the context of the interrupted task. */\r
+ portSAVE_CONTEXT_OS_INT();\r
+\r
+ /* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)\r
+ clock cycles from now. */\r
+ #if( configTICK_USE_TC==1 )\r
+ /* Clear the interrupt flag. */\r
+ AVR32_TC.channel[configTICK_TC_CHANNEL].sr;\r
+ #else\r
+ prvScheduleNextTick();\r
+ #endif\r
+ \r
+ /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS\r
+ calls in a critical section . */\r
+ portENTER_CRITICAL();\r
+ vTaskIncrementTick();\r
+ portEXIT_CRITICAL();\r
+\r
+ /* Restore the context of the "elected task". */\r
+ portRESTORE_CONTEXT_OS_INT();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+__attribute__((__naked__)) void SCALLYield( void )\r
+{\r
+ /* Save the context of the interrupted task. */\r
+ portSAVE_CONTEXT_SCALL();\r
+ vTaskSwitchContext();\r
+ portRESTORE_CONTEXT_SCALL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The code generated by the GCC compiler uses the stack in different ways at\r
+different optimisation levels. The interrupt flags can therefore not always\r
+be saved to the stack. Instead the critical section nesting level is stored\r
+in a variable, which is then saved as part of the stack context. */\r
+void vPortEnterCritical( void )\r
+{\r
+ /* Disable interrupts */\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ /* Now interrupts are disabled ulCriticalNesting can be accessed\r
+ directly. Increment ulCriticalNesting to keep a count of how many times\r
+ portENTER_CRITICAL() has been called. */\r
+ ulCriticalNesting++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortExitCritical( void )\r
+{\r
+ if(ulCriticalNesting > portNO_CRITICAL_NESTING)\r
+ {\r
+ ulCriticalNesting--;\r
+ if( ulCriticalNesting == portNO_CRITICAL_NESTING )\r
+ {\r
+ /* Enable all interrupt/exception. */\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*\r
+ * Initialise the stack of a task to look exactly as if a call to\r
+ * portSAVE_CONTEXT had been called.\r
+ *\r
+ * See header file for description.\r
+ */\r
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
+{\r
+ /* Setup the initial stack of the task. The stack is set exactly as\r
+ expected by the portRESTORE_CONTEXT() macro. */\r
+\r
+ /* When the task starts, it will expect to find the function parameter in R12. */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808; /* R8 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909; /* R9 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A; /* R10 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B; /* R11 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters; /* R12 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF; /* R14/LR */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; /* R15/PC */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR; /* SR */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF; /* R0 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101; /* R1 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202; /* R2 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303; /* R3 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */\r
+\r
+ return pxTopOfStack;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xPortStartScheduler( void )\r
+{\r
+ /* Start the timer that generates the tick ISR. Interrupts are disabled\r
+ here already. */\r
+ prvSetupTimerInterrupt();\r
+\r
+ /* Start the first task. */\r
+ portRESTORE_CONTEXT();\r
+\r
+ /* Should not get here! */\r
+ return 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEndScheduler( void )\r
+{\r
+ /* It is unlikely that the AVR32 port will require this function as there\r
+ is nothing to return to. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)\r
+clock cycles from now. */\r
+#if( configTICK_USE_TC==0 )\r
+ static void prvScheduleNextTick(void)\r
+ {\r
+ unsigned long lCountVal, lCompareVal;\r
+\r
+ lCountVal = Get_system_register(AVR32_COUNT);\r
+ lCompareVal = lCountVal + (configCPU_CLOCK_HZ/configTICK_RATE_HZ);\r
+ Set_system_register(AVR32_COMPARE, lCompareVal);\r
+ }\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Setup the timer to generate the tick interrupts. */\r
+static void prvSetupTimerInterrupt(void)\r
+{\r
+#if( configTICK_USE_TC==1 )\r
+\r
+ volatile avr32_tc_t *tc = &AVR32_TC;\r
+\r
+ // Options for waveform genration.\r
+ tc_waveform_opt_t waveform_opt =\r
+ {\r
+ .channel = configTICK_TC_CHANNEL, /* Channel selection. */\r
+\r
+ .bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */\r
+ .beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */\r
+ .bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */\r
+ .bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */\r
+\r
+ .aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */\r
+ .aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */\r
+ .acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */\r
+ .acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */\r
+\r
+ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */\r
+ .enetrg = FALSE, /* External event trigger enable. */\r
+ .eevt = 0, /* External event selection. */\r
+ .eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */\r
+ .cpcdis = FALSE, /* Counter disable when RC compare. */\r
+ .cpcstop = FALSE, /* Counter clock stopped with RC compare. */\r
+\r
+ .burst = FALSE, /* Burst signal selection. */\r
+ .clki = FALSE, /* Clock inversion. */\r
+ .tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */\r
+ };\r
+\r
+ tc_interrupt_t tc_interrupt =\r
+ {\r
+ .etrgs=0,\r
+ .ldrbs=0,\r
+ .ldras=0,\r
+ .cpcs =1,\r
+ .cpbs =0,\r
+ .cpas =0,\r
+ .lovrs=0,\r
+ .covfs=0,\r
+ };\r
+\r
+#endif\r
+\r
+ /* Disable all interrupt/exception. */\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ /* Register the compare interrupt handler to the interrupt controller and\r
+ enable the compare interrupt. */\r
+\r
+ #if( configTICK_USE_TC==1 )\r
+ {\r
+ INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0);\r
+\r
+ /* Initialize the timer/counter. */\r
+ tc_init_waveform(tc, &waveform_opt); \r
+\r
+ /* Set the compare triggers.\r
+ Remember TC counter is 16-bits, so counting second is not possible!\r
+ That's why we configure it to count ms. */\r
+ tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ/ 4) / 1000 );\r
+\r
+ tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );\r
+\r
+ /* Start the timer/counter. */\r
+ tc_start(tc, configTICK_TC_CHANNEL);\r
+ }\r
+ #else\r
+ {\r
+ INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0);\r
+ prvScheduleNextTick();\r
+ }\r
+ #endif\r
+}\r
--- /dev/null
+/*This file has been prepared for Doxygen automatic documentation generation.*/\r
+/*! \file *********************************************************************\r
+ *\r
+ * \brief FreeRTOS port header for AVR32 UC3.\r
+ *\r
+ * - Compiler: GNU GCC for AVR32\r
+ * - Supported devices: All AVR32 devices can be used.\r
+ * - AppNote:\r
+ *\r
+ * \author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ *****************************************************************************/\r
+\r
+/*\r
+ FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section\r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ See http://www.FreeRTOS.org for documentation, latest information, license\r
+ and contact details. Please ensure to read the configuration and relevant\r
+ port sections of the online documentation.\r
+ ***************************************************************************\r
+*/\r
+\r
+\r
+#ifndef PORTMACRO_H\r
+#define PORTMACRO_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Port specific definitions.\r
+ *\r
+ * The settings in this file configure FreeRTOS correctly for the\r
+ * given hardware and compiler.\r
+ *\r
+ * These settings should not be altered.\r
+ *-----------------------------------------------------------\r
+ */\r
+#include <avr32/io.h>\r
+#include "intc.h"\r
+#include "compiler.h"\r
+\r
+\r
+/* Type definitions. */\r
+#define portCHAR char\r
+#define portFLOAT float\r
+#define portDOUBLE double\r
+#define portLONG long\r
+#define portSHORT short\r
+#define portSTACK_TYPE unsigned portLONG\r
+#define portBASE_TYPE portLONG\r
+\r
+#define TASK_DELAY_MS(x) ( (x) /portTICK_RATE_MS )\r
+#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )\r
+#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )\r
+\r
+#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)\r
+\r
+#if( configUSE_16_BIT_TICKS == 1 )\r
+ typedef unsigned portSHORT portTickType;\r
+ #define portMAX_DELAY ( portTickType ) 0xffff\r
+#else\r
+ typedef unsigned portLONG portTickType;\r
+ #define portMAX_DELAY ( portTickType ) 0xffffffff\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Architecture specifics. */\r
+#define portSTACK_GROWTH ( -1 )\r
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )\r
+#define portBYTE_ALIGNMENT 4\r
+#define portNOP() {__asm__ __volatile__ ("nop");}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* INTC-specific. */\r
+#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()\r
+#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()\r
+\r
+#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()\r
+#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()\r
+\r
+#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)\r
+#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)\r
+\r
+\r
+/*\r
+ * Debug trace.\r
+ * Activated if and only if configDBG is nonzero.\r
+ * Prints a formatted string to stdout.\r
+ * The current source file name and line number are output with a colon before\r
+ * the formatted string.\r
+ * A carriage return and a linefeed are appended to the output.\r
+ * stdout is redirected by Newlib to the USART configured by configDBG_USART.\r
+ * The parameters are the same as for the standard printf function.\r
+ * There is no return value.\r
+ * SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,\r
+ * which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.\r
+ */\r
+#if configDBG\r
+#define portDBG_TRACE(...) \\r
+{\\r
+ fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout);\\r
+ printf(__VA_ARGS__);\\r
+ fputs("\r\n", stdout);\\r
+}\r
+#else\r
+#define portDBG_TRACE(...)\r
+#endif\r
+\r
+\r
+/* Critical section management. */\r
+#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()\r
+#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()\r
+\r
+\r
+extern void vPortEnterCritical( void );\r
+extern void vPortExitCritical( void );\r
+\r
+#define portENTER_CRITICAL() vPortEnterCritical();\r
+#define portEXIT_CRITICAL() vPortExitCritical();\r
+\r
+\r
+/* Added as there is no such function in FreeRTOS. */\r
+extern void *pvPortRealloc( void *pv, size_t xSize );\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*=============================================================================================*/\r
+\r
+/*\r
+ * Restore Context for cases other than INTi.\r
+ */\r
+#define portRESTORE_CONTEXT() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Set SP to point to new stack */ \\r
+ "mov r8, LO(%[pxCurrentTCB]) \n\t"\\r
+ "orh r8, HI(%[pxCurrentTCB]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0] \n\t"\\r
+ \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LO(%[ulCriticalNesting]) \n\t"\\r
+ "orh r8, HI(%[ulCriticalNesting]) \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ /* R0-R7 should not be used below this line */ \\r
+ /* Skip PC and SR (will do it at the end) */ \\r
+ "sub sp, -2*4 \n\t"\\r
+ /* Restore R8..R12 and LR */ \\r
+ "ldm sp++, r8-r12, lr \n\t"\\r
+ /* Restore SR */ \\r
+ "ld.w r0, sp[-8*4]\n\t" /* R0 is modified, is restored later. */ \\r
+ "mtsr %[SR], r0 \n\t"\\r
+ /* Restore r0 */ \\r
+ "ld.w r0, sp[-9*4] \n\t"\\r
+ /* Restore PC */ \\r
+ "ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting), \\r
+ [pxCurrentTCB] "i" (&pxCurrentTCB), \\r
+ [SR] "i" (AVR32_SR) \\r
+ ); \\r
+}\r
+\r
+\r
+/*\r
+ * portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.\r
+ * portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.\r
+ *\r
+ * Had to make different versions because registers saved on the system stack\r
+ * are not the same between INT0..3 exceptions and the scall exception.\r
+ */\r
+\r
+// Task context stack layout:\r
+ // R8 (*)\r
+ // R9 (*)\r
+ // R10 (*)\r
+ // R11 (*)\r
+ // R12 (*)\r
+ // R14/LR (*)\r
+ // R15/PC (*)\r
+ // SR (*)\r
+ // R0\r
+ // R1\r
+ // R2\r
+ // R3\r
+ // R4\r
+ // R5\r
+ // R6\r
+ // R7\r
+ // ulCriticalNesting\r
+// (*) automatically done for INT0..INT3, but not for SCALL\r
+\r
+/*\r
+ * The ISR used for the scheduler tick depends on whether the cooperative or\r
+ * the preemptive scheduler is being used.\r
+ */\r
+#if configUSE_PREEMPTION == 0\r
+\r
+/*\r
+ * portSAVE_CONTEXT_OS_INT() for OS Tick exception.\r
+ */\r
+#define portSAVE_CONTEXT_OS_INT() \\r
+{ \\r
+ /* Save R0..R7 */ \\r
+ __asm__ __volatile__ ("stm --sp, r0-r7"); \\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context save. */ \\r
+}\r
+\r
+/*\r
+ * portRESTORE_CONTEXT_OS_INT() for Tick exception.\r
+ */\r
+#define portRESTORE_CONTEXT_OS_INT() \\r
+{ \\r
+ __asm__ __volatile__ ( \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7\n\t" \\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context restore. */ \\r
+ "rete" \\r
+ ); \\r
+}\r
+\r
+#else\r
+\r
+/*\r
+ * portSAVE_CONTEXT_OS_INT() for OS Tick exception.\r
+ */\r
+#define portSAVE_CONTEXT_OS_INT() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* When we come here */ \\r
+ /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Save R0..R7 */ \\r
+ "stm --sp, r0-r7 \n\t"\\r
+ \\r
+ /* Save ulCriticalNesting variable - R0 is overwritten */ \\r
+ "mov r8, LO(%[ulCriticalNesting])\n\t" \\r
+ "orh r8, HI(%[ulCriticalNesting])\n\t" \\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w --sp, r0 \n\t"\\r
+ \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case we don't want to do a task switch because we don't know what the stack */ \\r
+ /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \\r
+ /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \\r
+ /* will just be restoring the interrupt handler, no way!!! */ \\r
+ /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \\r
+ "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \\r
+ "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \\r
+ "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \\r
+ "brhi LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\\r
+ \\r
+ /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \\r
+ /* NOTE: we don't enter a critical section here because all interrupt handlers */ \\r
+ /* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \\r
+ /* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \\r
+ /* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \\r
+ "mov r8, LO(%[pxCurrentTCB])\n\t" \\r
+ "orh r8, HI(%[pxCurrentTCB])\n\t" \\r
+ "ld.w r0, r8[0]\n\t" \\r
+ "st.w r0[0], sp\n" \\r
+ \\r
+ "LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:" \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting), \\r
+ [pxCurrentTCB] "i" (&pxCurrentTCB), \\r
+ [LINE] "i" (__LINE__) \\r
+ ); \\r
+}\r
+\r
+/*\r
+ * portRESTORE_CONTEXT_OS_INT() for Tick exception.\r
+ */\r
+#define portRESTORE_CONTEXT_OS_INT() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case we don't want to do a task switch because we don't know what the stack */ \\r
+ /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \\r
+ /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \\r
+ /* will just be restoring the interrupt handler, no way!!! */ \\r
+ __asm__ __volatile__ ( \\r
+ "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \\r
+ "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \\r
+ "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \\r
+ "brhi LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]" \\r
+ : \\r
+ : [LINE] "i" (__LINE__) \\r
+ ); \\r
+ \\r
+ /* Else */ \\r
+ /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \\r
+ /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\\r
+ portENTER_CRITICAL(); \\r
+ vTaskSwitchContext(); \\r
+ portEXIT_CRITICAL(); \\r
+ \\r
+ /* Restore all registers */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Set SP to point to new stack */ \\r
+ "mov r8, LO(%[pxCurrentTCB]) \n\t"\\r
+ "orh r8, HI(%[pxCurrentTCB]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0] \n"\\r
+ \\r
+ "LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\\r
+ \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t" \\r
+ "mov r8, LO(%[ulCriticalNesting]) \n\t"\\r
+ "orh r8, HI(%[ulCriticalNesting]) \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* Now, the stack should be R8..R12, LR, PC and SR */ \\r
+ "rete" \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting), \\r
+ [pxCurrentTCB] "i" (&pxCurrentTCB), \\r
+ [LINE] "i" (__LINE__) \\r
+ ); \\r
+}\r
+\r
+#endif\r
+\r
+\r
+/*\r
+ * portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.\r
+ *\r
+ * NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.\r
+ *\r
+ */\r
+#define portSAVE_CONTEXT_SCALL() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \\r
+ /* If SR[M2:M0] == 001 */ \\r
+ /* PC and SR are on the stack. */ \\r
+ /* Else (other modes) */ \\r
+ /* Nothing on the stack. */ \\r
+ \\r
+ /* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \\r
+ /* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \\r
+ /* in an interrupt|exception handler. */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* in order to save R0-R7 */ \\r
+ "sub sp, 6*4 \n\t"\\r
+ /* Save R0..R7 */ \\r
+ "stm --sp, r0-r7 \n\t"\\r
+ \\r
+ /* in order to save R8-R12 and LR */ \\r
+ /* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \\r
+ "sub r7, sp,-16*4 \n\t"\\r
+ /* Copy PC and SR in other places in the stack. */ \\r
+ "ld.w r0, r7[-2*4] \n\t" /* Read SR */\\r
+ "st.w r7[-8*4], r0 \n\t" /* Copy SR */\\r
+ "ld.w r0, r7[-1*4] \n\t" /* Read PC */\\r
+ "st.w r7[-7*4], r0 \n\t" /* Copy PC */\\r
+ \\r
+ /* Save R8..R12 and LR on the stack. */ \\r
+ "stm --r7, r8-r12, lr \n\t"\\r
+ \\r
+ /* Arriving here we have the following stack organizations: */ \\r
+ /* R8..R12, LR, PC, SR, R0..R7. */ \\r
+ \\r
+ /* Now we can finalize the save. */ \\r
+ \\r
+ /* Save ulCriticalNesting variable - R0 is overwritten */ \\r
+ "mov r8, LO(%[ulCriticalNesting]) \n\t"\\r
+ "orh r8, HI(%[ulCriticalNesting]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w --sp, r0" \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting) \\r
+ ); \\r
+ \\r
+ /* Disable the its which may cause a context switch (i.e. cause a change of */ \\r
+ /* pxCurrentTCB). */ \\r
+ /* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \\r
+ /* critical section because it is a global structure. */ \\r
+ portENTER_CRITICAL(); \\r
+ \\r
+ /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \\r
+ __asm__ __volatile__ ( \\r
+ "mov r8, LO(%[pxCurrentTCB]) \n\t"\\r
+ "orh r8, HI(%[pxCurrentTCB]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w r0[0], sp" \\r
+ : \\r
+ : [pxCurrentTCB] "i" (&pxCurrentTCB) \\r
+ ); \\r
+}\r
+\r
+/*\r
+ * portRESTORE_CONTEXT() for SupervisorCALL exception.\r
+ */\r
+#define portRESTORE_CONTEXT_SCALL() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* Restore all registers */ \\r
+ \\r
+ /* Set SP to point to new stack */ \\r
+ __asm__ __volatile__ ( \\r
+ "mov r8, LO(%[pxCurrentTCB]) \n\t"\\r
+ "orh r8, HI(%[pxCurrentTCB]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0]" \\r
+ : \\r
+ : [pxCurrentTCB] "i" (&pxCurrentTCB) \\r
+ ); \\r
+ \\r
+ /* Leave pxCurrentTCB variable access critical section */ \\r
+ portEXIT_CRITICAL(); \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LO(%[ulCriticalNesting]) \n\t"\\r
+ "orh r8, HI(%[ulCriticalNesting]) \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* skip PC and SR */ \\r
+ /* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \\r
+ "sub r7, sp, -10*4 \n\t"\\r
+ /* Restore r8-r12 and LR */ \\r
+ "ldm r7++, r8-r12, lr \n\t"\\r
+ \\r
+ /* RETS will take care of the extra PC and SR restore. */ \\r
+ /* So, we have to prepare the stack for this. */ \\r
+ "ld.w r0, r7[-8*4] \n\t" /* Read SR */\\r
+ "st.w r7[-2*4], r0 \n\t" /* Copy SR */\\r
+ "ld.w r0, r7[-7*4] \n\t" /* Read PC */\\r
+ "st.w r7[-1*4], r0 \n\t" /* Copy PC */\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ "sub sp, -6*4 \n\t"\\r
+ \\r
+ "rets" \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting) \\r
+ ); \\r
+}\r
+\r
+\r
+/*\r
+ * The ISR used depends on whether the cooperative or\r
+ * the preemptive scheduler is being used.\r
+ */\r
+#if configUSE_PREEMPTION == 0\r
+\r
+/*\r
+ * ISR entry and exit macros. These are only required if a task switch\r
+ * is required from the ISR.\r
+ */\r
+#define portENTER_SWITCHING_ISR() \\r
+{ \\r
+ /* Save R0..R7 */ \\r
+ __asm__ __volatile__ ("stm --sp, r0-r7"); \\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context save. */ \\r
+}\r
+\r
+/*\r
+ * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1\r
+ */\r
+#define portEXIT_SWITCHING_ISR() \\r
+{ \\r
+ __asm__ __volatile__ ( \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context restore. */ \\r
+ "rete" \\r
+ ); \\r
+}\r
+\r
+#else\r
+\r
+/*\r
+ * ISR entry and exit macros. These are only required if a task switch\r
+ * is required from the ISR.\r
+ */\r
+#define portENTER_SWITCHING_ISR() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* When we come here */ \\r
+ /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Save R0..R7 */ \\r
+ "stm --sp, r0-r7 \n\t"\\r
+ \\r
+ /* Save ulCriticalNesting variable - R0 is overwritten */ \\r
+ "mov r8, LO(%[ulCriticalNesting]) \n\t"\\r
+ "orh r8, HI(%[ulCriticalNesting]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w --sp, r0 \n\t"\\r
+ \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case we don't want to do a task switch because we don't know what the stack */ \\r
+ /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \\r
+ /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \\r
+ /* will just be restoring the interrupt handler, no way!!! */ \\r
+ /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \\r
+ "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\\r
+ "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\\r
+ "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
+ "brhi LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\\r
+ \\r
+ /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \\r
+ "mov r8, LO(%[pxCurrentTCB]) \n\t"\\r
+ "orh r8, HI(%[pxCurrentTCB]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w r0[0], sp \n"\\r
+ \\r
+ "LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:" \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting), \\r
+ [pxCurrentTCB] "i" (&pxCurrentTCB), \\r
+ [LINE] "i" (__LINE__) \\r
+ ); \\r
+}\r
+\r
+/*\r
+ * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1\r
+ */\r
+#define portEXIT_SWITCHING_ISR() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case it's of no use to switch context and restore a new SP because we purposedly */ \\r
+ /* did not previously save SP in its TCB. */ \\r
+ "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\\r
+ "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\\r
+ "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
+ "brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE] \n\t"\\r
+ \\r
+ /* If a switch is required then we just need to call */ \\r
+ /* vTaskSwitchContext() as the context has already been */ \\r
+ /* saved. */ \\r
+ "cp.w r12, 1 \n\t" /* Check if Switch context is required. */\\r
+ "brne LABEL_ISR_RESTORE_CONTEXT_%[LINE]" \\r
+ : \\r
+ : [LINE] "i" (__LINE__) \\r
+ ); \\r
+ \\r
+ /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \\r
+ portENTER_CRITICAL(); \\r
+ vTaskSwitchContext(); \\r
+ portEXIT_CRITICAL(); \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ "LABEL_ISR_RESTORE_CONTEXT_%[LINE]: \n\t"\\r
+ /* Restore the context of which ever task is now the highest */ \\r
+ /* priority that is ready to run. */ \\r
+ \\r
+ /* Restore all registers */ \\r
+ \\r
+ /* Set SP to point to new stack */ \\r
+ "mov r8, LO(%[pxCurrentTCB]) \n\t"\\r
+ "orh r8, HI(%[pxCurrentTCB]) \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0] \n"\\r
+ \\r
+ "LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\\r
+ \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LO(%[ulCriticalNesting]) \n\t"\\r
+ "orh r8, HI(%[ulCriticalNesting]) \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* Now, the stack should be R8..R12, LR, PC and SR */ \\r
+ "rete" \\r
+ : \\r
+ : [ulCriticalNesting] "i" (&ulCriticalNesting), \\r
+ [pxCurrentTCB] "i" (&pxCurrentTCB), \\r
+ [LINE] "i" (__LINE__) \\r
+ ); \\r
+}\r
+\r
+#endif\r
+\r
+\r
+#define portYIELD() {__asm__ __volatile__ ("scall");}\r
+\r
+/* Task function macros as described on the FreeRTOS.org WEB site. */\r
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+\r
+\r
+#endif /* PORTMACRO_H */\r
--- /dev/null
+/******************************************************************************\r
+ * Exception and interrupt vectors.\r
+ *\r
+ * This file has been built from the Newlib exception.S. It maps all events\r
+ * supported by a UC3.\r
+ *\r
+ * - Compiler: IAR EWAVR32\r
+ * - Supported devices: All AVR32A devices with an INTC module can be used.\r
+ * - AppNote:\r
+ *\r
+ * - author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ ******************************************************************************/\r
+\r
+/* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ * this list of conditions and the following disclaimer in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ *\r
+ * 3. The name of ATMEL may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
+ * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+\r
+#include <avr32/iouc3a0512.h>\r
+#include <avr32/uc3a0512.h>\r
+#include "intc.h"\r
+\r
+\r
+// Start of Exception Vector Table.\r
+\r
+ // EVBA must be aligned with a power of two strictly greater than the EVBA-\r
+ // relative offset of the last vector.\r
+ COMMON EVTAB:CODE:ROOT(9)\r
+\r
+\r
+ // Force EVBA initialization.\r
+ EXTERN ??init_EVBA\r
+ REQUIRE ??init_EVBA\r
+\r
+ // Export symbol.\r
+ PUBLIC ??EVBA\r
+ PUBLIC _evba\r
+??EVBA:\r
+_evba:\r
+\r
+ ORG 0x000\r
+ // Unrecoverable Exception.\r
+_handle_Unrecoverable_Exception:\r
+ rjmp $\r
+\r
+ ORG 0x004\r
+ // TLB Multiple Hit: UNUSED IN AVR32A.\r
+_handle_TLB_Multiple_Hit:\r
+ rjmp $\r
+\r
+ ORG 0x008\r
+ // Bus Error Data Fetch.\r
+_handle_Bus_Error_Data_Fetch:\r
+ rjmp $\r
+\r
+ ORG 0x00C\r
+ // Bus Error Instruction Fetch.\r
+_handle_Bus_Error_Instruction_Fetch:\r
+ rjmp $\r
+\r
+ ORG 0x010\r
+ // NMI.\r
+_handle_NMI:\r
+ rjmp $\r
+\r
+ ORG 0x014\r
+ // Instruction Address.\r
+_handle_Instruction_Address:\r
+ rjmp $\r
+\r
+ ORG 0x018\r
+ // ITLB Protection.\r
+_handle_ITLB_Protection:\r
+ rjmp $\r
+\r
+ ORG 0x01C\r
+ // Breakpoint.\r
+_handle_Breakpoint:\r
+ rjmp $\r
+\r
+ ORG 0x020\r
+ // Illegal Opcode.\r
+_handle_Illegal_Opcode:\r
+ rjmp $\r
+\r
+ ORG 0x024\r
+ // Unimplemented Instruction.\r
+_handle_Unimplemented_Instruction:\r
+ rjmp $\r
+\r
+ ORG 0x028\r
+ // Privilege Violation.\r
+_handle_Privilege_Violation:\r
+ rjmp $\r
+\r
+ ORG 0x02C\r
+ // Floating-Point: UNUSED IN AVR32A.\r
+_handle_Floating_Point:\r
+ rjmp $\r
+\r
+ ORG 0x030\r
+ // Coprocessor Absent: UNUSED IN AVR32A.\r
+_handle_Coprocessor_Absent:\r
+ rjmp $\r
+\r
+ ORG 0x034\r
+ // Data Address (Read).\r
+_handle_Data_Address_Read:\r
+ rjmp $\r
+\r
+ ORG 0x038\r
+ // Data Address (Write).\r
+_handle_Data_Address_Write:\r
+ rjmp $\r
+\r
+ ORG 0x03C\r
+ // DTLB Protection (Read).\r
+_handle_DTLB_Protection_Read:\r
+ rjmp $\r
+\r
+ ORG 0x040\r
+ // DTLB Protection (Write).\r
+_handle_DTLB_Protection_Write:\r
+ rjmp $\r
+\r
+ ORG 0x044\r
+ // DTLB Modified: UNUSED IN AVR32A.\r
+_handle_DTLB_Modified:\r
+ rjmp $\r
+\r
+ ORG 0x050\r
+ // ITLB Miss: UNUSED IN AVR32A.\r
+_handle_ITLB_Miss:\r
+ rjmp $\r
+\r
+ ORG 0x060\r
+ // DTLB Miss (Read): UNUSED IN AVR32A.\r
+_handle_DTLB_Miss_Read:\r
+ rjmp $\r
+\r
+ ORG 0x070\r
+ // DTLB Miss (Write): UNUSED IN AVR32A.\r
+_handle_DTLB_Miss_Write:\r
+ rjmp $\r
+\r
+ ORG 0x100\r
+ // Supervisor Call.\r
+_handle_Supervisor_Call:\r
+ lddpc pc, __SCALLYield\r
+\r
+\r
+// Interrupt support.\r
+// The interrupt controller must provide the offset address relative to EVBA.\r
+// Important note:\r
+// All interrupts call a C function named _get_interrupt_handler.\r
+// This function will read group and interrupt line number to then return in\r
+// R12 a pointer to a user-provided interrupt handler.\r
+\r
+ ALIGN 2\r
+\r
+_int0:\r
+ // R8-R12, LR, PC and SR are automatically pushed onto the system stack by the\r
+ // CPU upon interrupt entry.\r
+#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.\r
+ mfsr r12, AVR32_SR\r
+ bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE\r
+ cp.w r12, 110b\r
+ brlo _int0_normal\r
+ lddsp r12, sp[0 * 4]\r
+ stdsp sp[6 * 4], r12\r
+ lddsp r12, sp[1 * 4]\r
+ stdsp sp[7 * 4], r12\r
+ lddsp r12, sp[3 * 4]\r
+ sub sp, -6 * 4\r
+ rete\r
+_int0_normal:\r
+#endif\r
+ mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.\r
+ mcall __get_interrupt_handler\r
+ cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.\r
+ movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.\r
+ rete // If this was a spurious interrupt (R12 == NULL), return from event handler.\r
+\r
+_int1:\r
+ // R8-R12, LR, PC and SR are automatically pushed onto the system stack by the\r
+ // CPU upon interrupt entry.\r
+#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.\r
+ mfsr r12, AVR32_SR\r
+ bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE\r
+ cp.w r12, 110b\r
+ brlo _int1_normal\r
+ lddsp r12, sp[0 * 4]\r
+ stdsp sp[6 * 4], r12\r
+ lddsp r12, sp[1 * 4]\r
+ stdsp sp[7 * 4], r12\r
+ lddsp r12, sp[3 * 4]\r
+ sub sp, -6 * 4\r
+ rete\r
+_int1_normal:\r
+#endif\r
+ mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.\r
+ mcall __get_interrupt_handler\r
+ cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.\r
+ movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.\r
+ rete // If this was a spurious interrupt (R12 == NULL), return from event handler.\r
+\r
+_int2:\r
+ // R8-R12, LR, PC and SR are automatically pushed onto the system stack by the\r
+ // CPU upon interrupt entry.\r
+#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.\r
+ mfsr r12, AVR32_SR\r
+ bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE\r
+ cp.w r12, 110b\r
+ brlo _int2_normal\r
+ lddsp r12, sp[0 * 4]\r
+ stdsp sp[6 * 4], r12\r
+ lddsp r12, sp[1 * 4]\r
+ stdsp sp[7 * 4], r12\r
+ lddsp r12, sp[3 * 4]\r
+ sub sp, -6 * 4\r
+ rete\r
+_int2_normal:\r
+#endif\r
+ mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.\r
+ mcall __get_interrupt_handler\r
+ cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.\r
+ movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.\r
+ rete // If this was a spurious interrupt (R12 == NULL), return from event handler.\r
+\r
+_int3:\r
+ // R8-R12, LR, PC and SR are automatically pushed onto the system stack by the\r
+ // CPU upon interrupt entry.\r
+#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.\r
+ mfsr r12, AVR32_SR\r
+ bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE\r
+ cp.w r12, 110b\r
+ brlo _int3_normal\r
+ lddsp r12, sp[0 * 4]\r
+ stdsp sp[6 * 4], r12\r
+ lddsp r12, sp[1 * 4]\r
+ stdsp sp[7 * 4], r12\r
+ lddsp r12, sp[3 * 4]\r
+ sub sp, -6 * 4\r
+ rete\r
+_int3_normal:\r
+#endif\r
+ mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.\r
+ mcall __get_interrupt_handler\r
+ cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.\r
+ movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.\r
+ rete // If this was a spurious interrupt (R12 == NULL), return from event handler.\r
+\r
+\r
+// Constant data area.\r
+\r
+ ALIGN 2\r
+\r
+ // Import symbols.\r
+ EXTERN SCALLYield\r
+ EXTERN _get_interrupt_handler\r
+__SCALLYield:\r
+ DC32 SCALLYield\r
+__get_interrupt_handler:\r
+ DC32 _get_interrupt_handler\r
+\r
+ // Values to store in the interrupt priority registers for the various interrupt priority levels.\r
+ // The interrupt priority registers contain the interrupt priority level and\r
+ // the EVBA-relative interrupt vector offset.\r
+ PUBLIC ipr_val\r
+ipr_val:\r
+ DC32 (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\\r
+ (INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\\r
+ (INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\\r
+ (INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)\r
+\r
+\r
+ END\r
--- /dev/null
+/*This file has been prepared for Doxygen automatic documentation generation.*/\r
+/*! \file *********************************************************************\r
+ *\r
+ * \brief FreeRTOS port source for AVR32 UC3.\r
+ *\r
+ * - Compiler: IAR EWAVR32\r
+ * - Supported devices: All AVR32 devices can be used.\r
+ * - AppNote:\r
+ *\r
+ * \author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ *****************************************************************************/\r
+\r
+/*\r
+ FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section\r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ See http://www.FreeRTOS.org for documentation, latest information, license\r
+ and contact details. Please ensure to read the configuration and relevant\r
+ port sections of the online documentation.\r
+ ***************************************************************************\r
+*/\r
+\r
+\r
+/* Scheduler includes. */\r
+#include "FreeRTOS.h"\r
+\r
+/* Get rid of inline in task.h. */\r
+#include "task.h"\r
+\r
+/* AVR32 UC3 includes. */\r
+#include <avr32/iouc3a0512.h>\r
+#include <intrinsics.h>\r
+#include "gpio.h"\r
+\r
+#if configDBG\r
+ #include "usart.h"\r
+#endif\r
+\r
+#if( configTICK_USE_TC==1 )\r
+ #include "tc.h"\r
+#endif\r
+\r
+\r
+/* Constants required to setup the task context. */\r
+#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */\r
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )\r
+\r
+/* Each task maintains its own critical nesting variable. */\r
+#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )\r
+volatile unsigned portLONG ulCriticalNesting = 9999UL;\r
+\r
+#if( configTICK_USE_TC==0 )\r
+ static void prvScheduleNextTick( void );\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Low-level initialization routine called during startup, before the main\r
+ * function.\r
+ */\r
+int __low_level_init(void)\r
+{\r
+ #if configHEAP_INIT\r
+ #pragma segment = "HEAP"\r
+ portBASE_TYPE *pxMem;\r
+ #endif\r
+\r
+ /* Enable exceptions. */\r
+ ENABLE_ALL_EXCEPTIONS();\r
+\r
+ /* Initialize interrupt handling. */\r
+ INTC_init_interrupts();\r
+\r
+ #if configHEAP_INIT\r
+ {\r
+ /* Initialize the heap used by malloc. */\r
+ for( pxMem = __segment_begin( "HEAP" ); pxMem < ( portBASE_TYPE * ) __segment_end( "HEAP" ); )\r
+ {\r
+ *pxMem++ = 0xA5A5A5A5;\r
+ }\r
+ }\r
+ #endif\r
+\r
+ /* Code section present if and only if the debug trace is activated. */\r
+ #if configDBG\r
+ {\r
+ static const usart_options_t usart_opt =\r
+ {\r
+ .baudrate = configDBG_USART_BAUDRATE,\r
+ .charlength = 8,\r
+ .paritytype = USART_NO_PARITY,\r
+ .stopbits = USART_1_STOPBIT,\r
+ .channelmode = USART_MODE_NORMAL\r
+ };\r
+\r
+ /* Initialize the USART used for the debug trace with the configured parameters. */\r
+ extern volatile avr32_usart_t *volatile stdio_usart_base;\r
+ stdio_usart_base = configDBG_USART;\r
+ gpio_enable_module_pin(configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION);\r
+ gpio_enable_module_pin(configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION);\r
+ usart_init_rs232(configDBG_USART, &usart_opt, configCPU_CLOCK_HZ);\r
+ }\r
+ #endif\r
+\r
+ /* Request initialization of data segments. */\r
+ return 1;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Added as there is no such function in FreeRTOS. */\r
+void *pvPortRealloc( void *pv, size_t xWantedSize )\r
+{\r
+void *pvReturn;\r
+\r
+ vTaskSuspendAll();\r
+ {\r
+ pvReturn = realloc( pv, xWantedSize );\r
+ }\r
+ xTaskResumeAll();\r
+\r
+ return pvReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The cooperative scheduler requires a normal IRQ service routine to\r
+simply increment the system tick. */\r
+/* The preemptive scheduler is defined as "naked" as the full context is saved\r
+on entry as part of the context switch. */\r
+#pragma shadow_registers = full // Naked.\r
+static void vTick( void )\r
+{\r
+ /* Save the context of the interrupted task. */\r
+ portSAVE_CONTEXT_OS_INT();\r
+\r
+ /* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)\r
+ clock cycles from now. */\r
+ #if( configTICK_USE_TC==1 )\r
+ /* Clear the interrupt flag. */\r
+ AVR32_TC.channel[configTICK_TC_CHANNEL].sr;\r
+ #else\r
+ prvScheduleNextTick();\r
+ #endif\r
+ \r
+ /* Because FreeRTOS is not supposed to run with nested interrupts, put all OS\r
+ calls in a critical section . */\r
+ portENTER_CRITICAL();\r
+ vTaskIncrementTick();\r
+ portEXIT_CRITICAL();\r
+\r
+ /* Restore the context of the "elected task". */\r
+ portRESTORE_CONTEXT_OS_INT();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#pragma shadow_registers = full // Naked.\r
+void SCALLYield( void )\r
+{\r
+ /* Save the context of the interrupted task. */\r
+ portSAVE_CONTEXT_SCALL();\r
+ vTaskSwitchContext();\r
+ portRESTORE_CONTEXT_SCALL();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The code generated by the GCC compiler uses the stack in different ways at\r
+different optimisation levels. The interrupt flags can therefore not always\r
+be saved to the stack. Instead the critical section nesting level is stored\r
+in a variable, which is then saved as part of the stack context. */\r
+void vPortEnterCritical( void )\r
+{\r
+ /* Disable interrupts */\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ /* Now interrupts are disabled ulCriticalNesting can be accessed\r
+ directly. Increment ulCriticalNesting to keep a count of how many times\r
+ portENTER_CRITICAL() has been called. */\r
+ ulCriticalNesting++;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortExitCritical( void )\r
+{\r
+ if(ulCriticalNesting > portNO_CRITICAL_NESTING)\r
+ {\r
+ ulCriticalNesting--;\r
+ if( ulCriticalNesting == portNO_CRITICAL_NESTING )\r
+ {\r
+ /* Enable all interrupt/exception. */\r
+ portENABLE_INTERRUPTS();\r
+ }\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Setup the timer to generate the tick interrupts. */\r
+static void prvSetupTimerInterrupt( void );\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Initialise the stack of a task to look exactly as if a call to\r
+ * portSAVE_CONTEXT had been called.\r
+ *\r
+ * See header file for description.\r
+ */\r
+portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
+{\r
+ /* Setup the initial stack of the task. The stack is set exactly as\r
+ expected by the portRESTORE_CONTEXT() macro. */\r
+\r
+ /* When the task starts, it will expect to find the function parameter in R12. */\r
+ pxTopOfStack--;\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808; /* R8 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909; /* R9 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A; /* R10 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B; /* R11 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters; /* R12 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF; /* R14/LR */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; /* R15/PC */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR; /* SR */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF; /* R0 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101; /* R1 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202; /* R2 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303; /* R3 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */\r
+ *pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */\r
+ *pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */\r
+\r
+ return pxTopOfStack;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xPortStartScheduler( void )\r
+{\r
+ /* Start the timer that generates the tick ISR. Interrupts are disabled\r
+ here already. */\r
+ prvSetupTimerInterrupt();\r
+\r
+ /* Start the first task. */\r
+ portRESTORE_CONTEXT();\r
+\r
+ /* Should not get here! */\r
+ return 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortEndScheduler( void )\r
+{\r
+ /* It is unlikely that the AVR32 port will require this function as there\r
+ is nothing to return to. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)\r
+clock cycles from now. */\r
+#if( configTICK_USE_TC==0 )\r
+ static void prvScheduleNextTick(void)\r
+ {\r
+ unsigned long lCountVal, lCompareVal;\r
+\r
+ lCountVal = Get_system_register(AVR32_COUNT);\r
+ lCompareVal = lCountVal + (configCPU_CLOCK_HZ/configTICK_RATE_HZ);\r
+ Set_system_register(AVR32_COMPARE, lCompareVal);\r
+ }\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Setup the timer to generate the tick interrupts. */\r
+static void prvSetupTimerInterrupt(void)\r
+{\r
+ #if( configTICK_USE_TC==1 )\r
+\r
+ volatile avr32_tc_t *tc = &AVR32_TC;\r
+\r
+ // Options for waveform genration.\r
+ tc_waveform_opt_t waveform_opt =\r
+ {\r
+ .channel = configTICK_TC_CHANNEL, /* Channel selection. */\r
+\r
+ .bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */\r
+ .beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */\r
+ .bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */\r
+ .bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */\r
+\r
+ .aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */\r
+ .aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */\r
+ .acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */\r
+ .acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */\r
+\r
+ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */\r
+ .enetrg = FALSE, /* External event trigger enable. */\r
+ .eevt = 0, /* External event selection. */\r
+ .eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */\r
+ .cpcdis = FALSE, /* Counter disable when RC compare. */\r
+ .cpcstop = FALSE, /* Counter clock stopped with RC compare. */\r
+\r
+ .burst = FALSE, /* Burst signal selection. */\r
+ .clki = FALSE, /* Clock inversion. */\r
+ .tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */\r
+ };\r
+\r
+ tc_interrupt_t tc_interrupt =\r
+ {\r
+ .etrgs=0,\r
+ .ldrbs=0,\r
+ .ldras=0,\r
+ .cpcs =1,\r
+ .cpbs =0,\r
+ .cpas =0,\r
+ .lovrs=0,\r
+ .covfs=0,\r
+ };\r
+\r
+ #endif\r
+\r
+ /* Disable all interrupt/exception. */\r
+ portDISABLE_INTERRUPTS();\r
+\r
+ /* Register the compare interrupt handler to the interrupt controller and\r
+ enable the compare interrupt. */\r
+\r
+ #if( configTICK_USE_TC==1 )\r
+ {\r
+ INTC_register_interrupt((__int_handler)&vTick, configTICK_TC_IRQ, INT0);\r
+\r
+ /* Initialize the timer/counter. */\r
+ tc_init_waveform(tc, &waveform_opt);\r
+\r
+ /* Set the compare triggers.\r
+ Remember TC counter is 16-bits, so counting second is not possible!\r
+ That's why we configure it to count ms. */\r
+ tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / 1000 );\r
+\r
+ tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );\r
+\r
+ /* Start the timer/counter. */\r
+ tc_start(tc, configTICK_TC_CHANNEL);\r
+ }\r
+ #else\r
+ {\r
+ INTC_register_interrupt((__int_handler)&vTick, AVR32_CORE_COMPARE_IRQ, INT0);\r
+ prvScheduleNextTick();\r
+ }\r
+ #endif\r
+}\r
--- /dev/null
+/*This file has been prepared for Doxygen automatic documentation generation.*/\r
+/*! \file *********************************************************************\r
+ *\r
+ * \brief FreeRTOS port header for AVR32 UC3.\r
+ *\r
+ * - Compiler: IAR EWAVR32\r
+ * - Supported devices: All AVR32 devices can be used.\r
+ * - AppNote:\r
+ *\r
+ * \author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ *****************************************************************************/\r
+\r
+/*\r
+ FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.\r
+\r
+ This file is part of the FreeRTOS.org distribution.\r
+\r
+ FreeRTOS.org is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ FreeRTOS.org is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with FreeRTOS.org; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+\r
+ A special exception to the GPL can be applied should you wish to distribute\r
+ a combined work that includes FreeRTOS.org, without being obliged to provide\r
+ the source code for any proprietary components. See the licensing section\r
+ of http://www.FreeRTOS.org for full details of how and when the exception\r
+ can be applied.\r
+\r
+ ***************************************************************************\r
+ See http://www.FreeRTOS.org for documentation, latest information, license\r
+ and contact details. Please ensure to read the configuration and relevant\r
+ port sections of the online documentation.\r
+ ***************************************************************************\r
+*/\r
+\r
+\r
+\r
+#ifndef PORTMACRO_H\r
+#define PORTMACRO_H\r
+\r
+/*-----------------------------------------------------------\r
+ * Port specific definitions.\r
+ *\r
+ * The settings in this file configure FreeRTOS correctly for the\r
+ * given hardware and compiler.\r
+ *\r
+ * These settings should not be altered.\r
+ *-----------------------------------------------------------\r
+ */\r
+#include <avr32/iouc3a0512.h>\r
+#include "intc.h"\r
+#include "compiler.h"\r
+\r
+\r
+/* Type definitions. */\r
+#define portCHAR char\r
+#define portFLOAT float\r
+#define portDOUBLE double\r
+#define portLONG long\r
+#define portSHORT short\r
+#define portSTACK_TYPE unsigned portLONG\r
+#define portBASE_TYPE portLONG\r
+\r
+#define TASK_DELAY_MS(x) ( (x) /portTICK_RATE_MS )\r
+#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )\r
+#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )\r
+\r
+#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)\r
+\r
+#if( configUSE_16_BIT_TICKS == 1 )\r
+ typedef unsigned portSHORT portTickType;\r
+ #define portMAX_DELAY ( portTickType ) 0xffff\r
+#else\r
+ typedef unsigned portLONG portTickType;\r
+ #define portMAX_DELAY ( portTickType ) 0xffffffff\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Architecture specifics. */\r
+#define portSTACK_GROWTH ( -1 )\r
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )\r
+#define portBYTE_ALIGNMENT 4\r
+#define portNOP() {__asm__ __volatile__ ("nop");}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* INTC-specific. */\r
+#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()\r
+#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()\r
+\r
+#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()\r
+#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()\r
+\r
+#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)\r
+#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)\r
+\r
+\r
+/*\r
+ * Debug trace.\r
+ * Activated if and only if configDBG is nonzero.\r
+ * Prints a formatted string to stdout.\r
+ * The current source file name and line number are output with a colon before\r
+ * the formatted string.\r
+ * A carriage return and a linefeed are appended to the output.\r
+ * stdout is redirected by Newlib to the USART configured by configDBG_USART.\r
+ * The parameters are the same as for the standard printf function.\r
+ * There is no return value.\r
+ * SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,\r
+ * which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.\r
+ */\r
+#if configDBG\r
+ #define portDBG_TRACE(...) \\r
+ { \\r
+ fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout); \\r
+ printf(__VA_ARGS__); \\r
+ fputs("\r\n", stdout); \\r
+ }\r
+#else\r
+ #define portDBG_TRACE(...)\r
+#endif\r
+\r
+\r
+/* Critical section management. */\r
+#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()\r
+#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()\r
+\r
+\r
+extern void vPortEnterCritical( void );\r
+extern void vPortExitCritical( void );\r
+\r
+#define portENTER_CRITICAL() vPortEnterCritical();\r
+#define portEXIT_CRITICAL() vPortExitCritical();\r
+\r
+\r
+/* Added as there is no such function in FreeRTOS. */\r
+extern void *pvPortRealloc( void *pv, size_t xSize );\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+/*=============================================================================================*/\r
+\r
+/*\r
+ * Restore Context for cases other than INTi.\r
+ */\r
+#define portRESTORE_CONTEXT() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Set SP to point to new stack */ \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0] \n\t"\\r
+ \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ /* R0-R7 should not be used below this line */ \\r
+ /* Skip PC and SR (will do it at the end) */ \\r
+ "sub sp, -2*4 \n\t"\\r
+ /* Restore R8..R12 and LR */ \\r
+ "ldm sp++, r8-r12, lr \n\t"\\r
+ /* Restore SR */ \\r
+ "ld.w r0, sp[-8*4] \n\t" /* R0 is modified, is restored later. */\\r
+ "mtsr "ASTRINGZ(AVR32_SR)", r0 \n\t"\\r
+ /* Restore r0 */ \\r
+ "ld.w r0, sp[-9*4] \n\t"\\r
+ /* Restore PC */ \\r
+ "ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \\r
+ ); \\r
+ \\r
+ /* Force import of global symbols from assembly */ \\r
+ ulCriticalNesting; \\r
+ pxCurrentTCB; \\r
+}\r
+\r
+\r
+/*\r
+ * portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.\r
+ * portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.\r
+ *\r
+ * Had to make different versions because registers saved on the system stack\r
+ * are not the same between INT0..3 exceptions and the scall exception.\r
+ */\r
+\r
+// Task context stack layout:\r
+ // R8 (*)\r
+ // R9 (*)\r
+ // R10 (*)\r
+ // R11 (*)\r
+ // R12 (*)\r
+ // R14/LR (*)\r
+ // R15/PC (*)\r
+ // SR (*)\r
+ // R0\r
+ // R1\r
+ // R2\r
+ // R3\r
+ // R4\r
+ // R5\r
+ // R6\r
+ // R7\r
+ // ulCriticalNesting\r
+// (*) automatically done for INT0..INT3, but not for SCALL\r
+\r
+/*\r
+ * The ISR used for the scheduler tick depends on whether the cooperative or\r
+ * the preemptive scheduler is being used.\r
+ */\r
+#if configUSE_PREEMPTION == 0\r
+\r
+/*\r
+ * portSAVE_CONTEXT_OS_INT() for OS Tick exception.\r
+ */\r
+#define portSAVE_CONTEXT_OS_INT() \\r
+{ \\r
+ /* Save R0..R7 */ \\r
+ __asm__ __volatile__ ("stm --sp, r0-r7"); \\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context save. */ \\r
+}\r
+\r
+/*\r
+ * portRESTORE_CONTEXT_OS_INT() for Tick exception.\r
+ */\r
+#define portRESTORE_CONTEXT_OS_INT() \\r
+{ \\r
+ __asm__ __volatile__ ( \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context restore. */ \\r
+ "rete" \\r
+ ); \\r
+}\r
+\r
+#else\r
+\r
+/*\r
+ * portSAVE_CONTEXT_OS_INT() for OS Tick exception.\r
+ */\r
+#define portSAVE_CONTEXT_OS_INT() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* When we come here */ \\r
+ /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Save R0..R7 */ \\r
+ "stm --sp, r0-r7 \n\t"\\r
+ \\r
+ /* Save ulCriticalNesting variable - R0 is overwritten */ \\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w --sp, r0 \n\t"\\r
+ \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case we don't want to do a task switch because we don't know what the stack */ \\r
+ /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \\r
+ /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \\r
+ /* will just be restoring the interrupt handler, no way!!! */ \\r
+ /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \\r
+ "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\\r
+ "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\\r
+ "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
+ "brhi LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\\r
+ \\r
+ /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \\r
+ /* NOTE: we don't enter a critical section here because all interrupt handlers */ \\r
+ /* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \\r
+ /* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \\r
+ /* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w r0[0], sp \n"\\r
+ \\r
+ "LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \\r
+ ); \\r
+}\r
+\r
+/*\r
+ * portRESTORE_CONTEXT_OS_INT() for Tick exception.\r
+ */\r
+#define portRESTORE_CONTEXT_OS_INT() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case we don't want to do a task switch because we don't know what the stack */ \\r
+ /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \\r
+ /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \\r
+ /* will just be restoring the interrupt handler, no way!!! */ \\r
+ __asm__ __volatile__ ( \\r
+ "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\\r
+ "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\\r
+ "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
+ "brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) \\r
+ ); \\r
+ \\r
+ /* Else */ \\r
+ /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \\r
+ /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\\r
+ portENTER_CRITICAL(); \\r
+ vTaskSwitchContext(); \\r
+ portEXIT_CRITICAL(); \\r
+ \\r
+ /* Restore all registers */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Set SP to point to new stack */ \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0] \n"\\r
+ \\r
+ "LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\\r
+ \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* Now, the stack should be R8..R12, LR, PC and SR */ \\r
+ "rete" \\r
+ ); \\r
+ \\r
+ /* Force import of global symbols from assembly */ \\r
+ ulCriticalNesting; \\r
+ pxCurrentTCB; \\r
+}\r
+\r
+#endif\r
+\r
+\r
+/*\r
+ * portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.\r
+ *\r
+ * NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.\r
+ *\r
+ */\r
+#define portSAVE_CONTEXT_SCALL() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \\r
+ /* If SR[M2:M0] == 001 */ \\r
+ /* PC and SR are on the stack. */ \\r
+ /* Else (other modes) */ \\r
+ /* Nothing on the stack. */ \\r
+ \\r
+ /* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \\r
+ /* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \\r
+ /* in an interrupt|exception handler. */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* in order to save R0-R7 */ \\r
+ "sub sp, 6*4 \n\t"\\r
+ /* Save R0..R7 */ \\r
+ "stm --sp, r0-r7 \n\t"\\r
+ \\r
+ /* in order to save R8-R12 and LR */ \\r
+ /* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \\r
+ "sub r7, sp,-16*4 \n\t"\\r
+ /* Copy PC and SR in other places in the stack. */ \\r
+ "ld.w r0, r7[-2*4] \n\t" /* Read SR */\\r
+ "st.w r7[-8*4], r0 \n\t" /* Copy SR */\\r
+ "ld.w r0, r7[-1*4] \n\t" /* Read PC */\\r
+ "st.w r7[-7*4], r0 \n\t" /* Copy PC */\\r
+ \\r
+ /* Save R8..R12 and LR on the stack. */ \\r
+ "stm --r7, r8-r12, lr \n\t"\\r
+ \\r
+ /* Arriving here we have the following stack organizations: */ \\r
+ /* R8..R12, LR, PC, SR, R0..R7. */ \\r
+ \\r
+ /* Now we can finalize the save. */ \\r
+ \\r
+ /* Save ulCriticalNesting variable - R0 is overwritten */ \\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w --sp, r0" \\r
+ ); \\r
+ \\r
+ /* Disable the its which may cause a context switch (i.e. cause a change of */ \\r
+ /* pxCurrentTCB). */ \\r
+ /* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \\r
+ /* critical section because it is a global structure. */ \\r
+ portENTER_CRITICAL(); \\r
+ \\r
+ /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \\r
+ __asm__ __volatile__ ( \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w r0[0], sp" \\r
+ ); \\r
+}\r
+\r
+/*\r
+ * portRESTORE_CONTEXT() for SupervisorCALL exception.\r
+ */\r
+#define portRESTORE_CONTEXT_SCALL() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* Restore all registers */ \\r
+ \\r
+ /* Set SP to point to new stack */ \\r
+ __asm__ __volatile__ ( \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0]" \\r
+ ); \\r
+ \\r
+ /* Leave pxCurrentTCB variable access critical section */ \\r
+ portEXIT_CRITICAL(); \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* skip PC and SR */ \\r
+ /* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \\r
+ "sub r7, sp, -10*4 \n\t"\\r
+ /* Restore r8-r12 and LR */ \\r
+ "ldm r7++, r8-r12, lr \n\t"\\r
+ \\r
+ /* RETS will take care of the extra PC and SR restore. */ \\r
+ /* So, we have to prepare the stack for this. */ \\r
+ "ld.w r0, r7[-8*4] \n\t" /* Read SR */\\r
+ "st.w r7[-2*4], r0 \n\t" /* Copy SR */\\r
+ "ld.w r0, r7[-7*4] \n\t" /* Read PC */\\r
+ "st.w r7[-1*4], r0 \n\t" /* Copy PC */\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ "sub sp, -6*4 \n\t"\\r
+ \\r
+ "rets" \\r
+ ); \\r
+ \\r
+ /* Force import of global symbols from assembly */ \\r
+ ulCriticalNesting; \\r
+ pxCurrentTCB; \\r
+}\r
+\r
+\r
+/*\r
+ * The ISR used depends on whether the cooperative or\r
+ * the preemptive scheduler is being used.\r
+ */\r
+#if configUSE_PREEMPTION == 0\r
+\r
+/*\r
+ * ISR entry and exit macros. These are only required if a task switch\r
+ * is required from the ISR.\r
+ */\r
+#define portENTER_SWITCHING_ISR() \\r
+{ \\r
+ /* Save R0..R7 */ \\r
+ __asm__ __volatile__ ("stm --sp, r0-r7"); \\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context save. */ \\r
+} \r
+ \r
+/* \r
+ * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1 \r
+ */ \r
+#define portEXIT_SWITCHING_ISR() \\r
+{ \\r
+ __asm__ __volatile__ ( \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* With the cooperative scheduler, as there is no context switch by interrupt, */ \\r
+ /* there is also no context restore. */ \\r
+ "rete" \\r
+ ); \\r
+} \r
+ \r
+#else \r
+ \r
+/* \r
+ * ISR entry and exit macros. These are only required if a task switch \r
+ * is required from the ISR. \r
+ */ \r
+#define portENTER_SWITCHING_ISR() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ /* When we come here */ \\r
+ /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Save R0..R7 */ \\r
+ "stm --sp, r0-r7 \n\t"\\r
+ \\r
+ /* Save ulCriticalNesting variable - R0 is overwritten */ \\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w --sp, r0 \n\t"\\r
+ \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case we don't want to do a task switch because we don't know what the stack */ \\r
+ /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \\r
+ /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \\r
+ /* will just be restoring the interrupt handler, no way!!! */ \\r
+ /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \\r
+ "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\\r
+ "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\\r
+ "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
+ "brhi LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\\r
+ \\r
+ /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "st.w r0[0], sp \n"\\r
+ \\r
+ "LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \\r
+ ); \\r
+}\r
+\r
+\r
+/*\r
+ * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1\r
+ */\r
+#define portEXIT_SWITCHING_ISR() \\r
+{ \\r
+ extern volatile unsigned portLONG ulCriticalNesting; \\r
+ extern volatile void *volatile pxCurrentTCB; \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \\r
+ /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \\r
+ /* level and allow other lower interrupt level to occur). */ \\r
+ /* In this case it's of no use to switch context and restore a new SP because we purposedly */ \\r
+ /* did not previously save SP in its TCB. */ \\r
+ "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\\r
+ "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\\r
+ "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
+ "brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\\r
+ \\r
+ /* If a switch is required then we just need to call */ \\r
+ /* vTaskSwitchContext() as the context has already been */ \\r
+ /* saved. */ \\r
+ "cp.w r12, 1 \n\t" /* Check if Switch context is required. */\\r
+ "brne LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":C" \\r
+ ); \\r
+ \\r
+ /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\\r
+ portENTER_CRITICAL(); \\r
+ vTaskSwitchContext(); \\r
+ portEXIT_CRITICAL(); \\r
+ \\r
+ __asm__ __volatile__ ( \\r
+ "LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\\r
+ /* Restore the context of which ever task is now the highest */ \\r
+ /* priority that is ready to run. */ \\r
+ \\r
+ /* Restore all registers */ \\r
+ \\r
+ /* Set SP to point to new stack */ \\r
+ "mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\\r
+ "ld.w r0, r8[0] \n\t"\\r
+ "ld.w sp, r0[0] \n"\\r
+ \\r
+ "LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\\r
+ \\r
+ /* Restore ulCriticalNesting variable */ \\r
+ "ld.w r0, sp++ \n\t"\\r
+ "mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\\r
+ "st.w r8[0], r0 \n\t"\\r
+ \\r
+ /* Restore R0..R7 */ \\r
+ "ldm sp++, r0-r7 \n\t"\\r
+ \\r
+ /* Now, the stack should be R8..R12, LR, PC and SR */ \\r
+ "rete" \\r
+ ); \\r
+ \\r
+ /* Force import of global symbols from assembly */ \\r
+ ulCriticalNesting; \\r
+ pxCurrentTCB; \\r
+}\r
+\r
+#endif\r
+\r
+\r
+#define portYIELD() {__asm__ __volatile__ ("scall");}\r
+\r
+/* Task function macros as described on the FreeRTOS.org WEB site. */\r
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
+\r
+#define inline\r
+\r
+#endif /* PORTMACRO_H */\r
--- /dev/null
+/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */\r
+\r
+/*This file is prepared for Doxygen automatic documentation generation.*/\r
+/*! \file *********************************************************************\r
+ *\r
+ * \brief System-specific implementation of the \ref __read function used by\r
+ the standard library.\r
+ *\r
+ * - Compiler: IAR EWAVR32\r
+ * - Supported devices: All AVR32 devices with a USART module can be used.\r
+ * - AppNote:\r
+ *\r
+ * \author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ ******************************************************************************/\r
+\r
+/* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ * this list of conditions and the following disclaimer in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ *\r
+ * 3. The name of ATMEL may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
+ * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+\r
+#include <yfuns.h>\r
+#include <avr32/iouc3a0512.h>\r
+#include "usart.h"\r
+\r
+\r
+_STD_BEGIN\r
+\r
+\r
+#pragma module_name = "?__read"\r
+\r
+\r
+extern volatile avr32_usart_t *volatile stdio_usart_base;\r
+\r
+\r
+/*! \brief Reads a number of bytes, at most \a size, into the memory area\r
+ * pointed to by \a buffer.\r
+ *\r
+ * \param handle File handle to read from.\r
+ * \param buffer Pointer to buffer to write read bytes to.\r
+ * \param size Number of bytes to read.\r
+ *\r
+ * \return The number of bytes read, \c 0 at the end of the file, or\r
+ * \c _LLIO_ERROR on failure.\r
+ */\r
+size_t __read(int handle, unsigned char *buffer, size_t size)\r
+{\r
+ int nChars = 0;\r
+\r
+ // This implementation only reads from stdin.\r
+ // For all other file handles, it returns failure.\r
+ if (handle != _LLIO_STDIN)\r
+ {\r
+ return _LLIO_ERROR;\r
+ }\r
+\r
+ for (; size > 0; --size)\r
+ {\r
+ int c = usart_getchar(stdio_usart_base);\r
+ if (c < 0)\r
+ break;\r
+\r
+ *buffer++ = c;\r
+ ++nChars;\r
+ }\r
+\r
+ return nChars;\r
+}\r
+\r
+\r
+_STD_END\r
--- /dev/null
+/* This source file is part of the ATMEL FREERTOS-0.9.0 Release */\r
+\r
+/*This file is prepared for Doxygen automatic documentation generation.*/\r
+/*! \file *********************************************************************\r
+ *\r
+ * \brief System-specific implementation of the \ref __write function used by\r
+ the standard library.\r
+ *\r
+ * - Compiler: IAR EWAVR32\r
+ * - Supported devices: All AVR32 devices with a USART module can be used.\r
+ * - AppNote:\r
+ *\r
+ * \author Atmel Corporation: http://www.atmel.com \n\r
+ * Support email: avr32@atmel.com\r
+ *\r
+ ******************************************************************************/\r
+\r
+/* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the following disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above copyright notice,\r
+ * this list of conditions and the following disclaimer in the documentation\r
+ * and/or other materials provided with the distribution.\r
+ *\r
+ * 3. The name of ATMEL may not be used to endorse or promote products derived\r
+ * from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
+ * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+\r
+#include <yfuns.h>\r
+#include <avr32/iouc3a0512.h>\r
+#include "usart.h"\r
+\r
+\r
+_STD_BEGIN\r
+\r
+\r
+#pragma module_name = "?__write"\r
+\r
+\r
+//! Pointer to the base of the USART module instance to use for stdio.\r
+__no_init volatile avr32_usart_t *volatile stdio_usart_base;\r
+\r
+\r
+/*! \brief Writes a number of bytes, at most \a size, from the memory area\r
+ * pointed to by \a buffer.\r
+ *\r
+ * If \a buffer is zero then \ref __write performs flushing of internal buffers,\r
+ * if any. In this case, \a handle can be \c -1 to indicate that all handles\r
+ * should be flushed.\r
+ *\r
+ * \param handle File handle to write to.\r
+ * \param buffer Pointer to buffer to read bytes to write from.\r
+ * \param size Number of bytes to write.\r
+ *\r
+ * \return The number of bytes written, or \c _LLIO_ERROR on failure.\r
+ */\r
+size_t __write(int handle, const unsigned char *buffer, size_t size)\r
+{\r
+ size_t nChars = 0;\r
+\r
+ if (buffer == 0)\r
+ {\r
+ // This means that we should flush internal buffers.\r
+ return 0;\r
+ }\r
+\r
+ // This implementation only writes to stdout and stderr.\r
+ // For all other file handles, it returns failure.\r
+ if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)\r
+ {\r
+ return _LLIO_ERROR;\r
+ }\r
+\r
+ for (; size != 0; --size)\r
+ {\r
+ if (usart_putchar(stdio_usart_base, *buffer++) < 0)\r
+ {\r
+ return _LLIO_ERROR;\r
+ }\r
+\r
+ ++nChars;\r
+ }\r
+\r
+ return nChars;\r
+}\r
+\r
+\r
+_STD_END\r