mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-20 05:21:59 -04:00
Create an updated AVR32 UC3A project.
This commit is contained in:
parent
d31b403659
commit
8405dbe3d5
|
@ -1,297 +0,0 @@
|
||||||
/*This file is prepared for Doxygen automatic documentation generation.*/
|
|
||||||
/*! \file *********************************************************************
|
|
||||||
*
|
|
||||||
* \brief Exception and interrupt vectors.
|
|
||||||
*
|
|
||||||
* This file maps all events supported by an AVR32UC.
|
|
||||||
*
|
|
||||||
* - Compiler: GNU GCC for AVR32
|
|
||||||
* - Supported devices: All AVR32UC devices with an INTC module can be used.
|
|
||||||
* - AppNote:
|
|
||||||
*
|
|
||||||
* \author Atmel Corporation: http://www.atmel.com \n
|
|
||||||
* Support and FAQ: http://support.atmel.no/
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* 3. The name of ATMEL may not be used to endorse or promote products derived
|
|
||||||
* from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
|
|
||||||
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
|
|
||||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <avr32/io.h>
|
|
||||||
#include "intc.h"
|
|
||||||
|
|
||||||
|
|
||||||
//! @{
|
|
||||||
//! \verbatim
|
|
||||||
|
|
||||||
|
|
||||||
.section .exception, "ax", @progbits
|
|
||||||
|
|
||||||
|
|
||||||
// Start of Exception Vector Table.
|
|
||||||
|
|
||||||
// EVBA must be aligned with a power of two strictly greater than the EVBA-
|
|
||||||
// relative offset of the last vector.
|
|
||||||
.balign 0x200
|
|
||||||
|
|
||||||
// Export symbol.
|
|
||||||
.global _evba
|
|
||||||
.type _evba, @function
|
|
||||||
_evba:
|
|
||||||
|
|
||||||
.org 0x000
|
|
||||||
// Unrecoverable Exception.
|
|
||||||
_handle_Unrecoverable_Exception:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x004
|
|
||||||
// TLB Multiple Hit: UNUSED IN AVR32UC.
|
|
||||||
_handle_TLB_Multiple_Hit:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x008
|
|
||||||
// Bus Error Data Fetch.
|
|
||||||
_handle_Bus_Error_Data_Fetch:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x00C
|
|
||||||
// Bus Error Instruction Fetch.
|
|
||||||
_handle_Bus_Error_Instruction_Fetch:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x010
|
|
||||||
// NMI.
|
|
||||||
_handle_NMI:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x014
|
|
||||||
// Instruction Address.
|
|
||||||
_handle_Instruction_Address:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x018
|
|
||||||
// ITLB Protection.
|
|
||||||
_handle_ITLB_Protection:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x01C
|
|
||||||
// Breakpoint.
|
|
||||||
_handle_Breakpoint:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x020
|
|
||||||
// Illegal Opcode.
|
|
||||||
_handle_Illegal_Opcode:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x024
|
|
||||||
// Unimplemented Instruction.
|
|
||||||
_handle_Unimplemented_Instruction:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x028
|
|
||||||
// Privilege Violation.
|
|
||||||
_handle_Privilege_Violation:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x02C
|
|
||||||
// Floating-Point: UNUSED IN AVR32UC.
|
|
||||||
_handle_Floating_Point:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x030
|
|
||||||
// Coprocessor Absent: UNUSED IN AVR32UC.
|
|
||||||
_handle_Coprocessor_Absent:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x034
|
|
||||||
// Data Address (Read).
|
|
||||||
_handle_Data_Address_Read:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x038
|
|
||||||
// Data Address (Write).
|
|
||||||
_handle_Data_Address_Write:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x03C
|
|
||||||
// DTLB Protection (Read).
|
|
||||||
_handle_DTLB_Protection_Read:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x040
|
|
||||||
// DTLB Protection (Write).
|
|
||||||
_handle_DTLB_Protection_Write:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x044
|
|
||||||
// DTLB Modified: UNUSED IN AVR32UC.
|
|
||||||
_handle_DTLB_Modified:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x050
|
|
||||||
// ITLB Miss: UNUSED IN AVR32UC.
|
|
||||||
_handle_ITLB_Miss:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x060
|
|
||||||
// DTLB Miss (Read): UNUSED IN AVR32UC.
|
|
||||||
_handle_DTLB_Miss_Read:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x070
|
|
||||||
// DTLB Miss (Write): UNUSED IN AVR32UC.
|
|
||||||
_handle_DTLB_Miss_Write:
|
|
||||||
rjmp $
|
|
||||||
|
|
||||||
.org 0x100
|
|
||||||
// Supervisor Call.
|
|
||||||
_handle_Supervisor_Call:
|
|
||||||
lda.w pc, SCALLYield
|
|
||||||
|
|
||||||
|
|
||||||
// Interrupt support.
|
|
||||||
// The interrupt controller must provide the offset address relative to EVBA.
|
|
||||||
// Important note:
|
|
||||||
// All interrupts call a C function named _get_interrupt_handler.
|
|
||||||
// This function will read group and interrupt line number to then return in
|
|
||||||
// R12 a pointer to a user-provided interrupt handler.
|
|
||||||
|
|
||||||
.balign 4
|
|
||||||
|
|
||||||
_int0:
|
|
||||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
|
||||||
// CPU upon interrupt entry.
|
|
||||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
|
||||||
mfsr r12, AVR32_SR
|
|
||||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
|
||||||
cp.w r12, 0b110
|
|
||||||
brlo _int0_normal
|
|
||||||
lddsp r12, sp[0 * 4]
|
|
||||||
stdsp sp[6 * 4], r12
|
|
||||||
lddsp r12, sp[1 * 4]
|
|
||||||
stdsp sp[7 * 4], r12
|
|
||||||
lddsp r12, sp[3 * 4]
|
|
||||||
sub sp, -6 * 4
|
|
||||||
rete
|
|
||||||
_int0_normal:
|
|
||||||
#endif
|
|
||||||
mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
|
||||||
call _get_interrupt_handler
|
|
||||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
|
||||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
|
||||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
|
||||||
|
|
||||||
_int1:
|
|
||||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
|
||||||
// CPU upon interrupt entry.
|
|
||||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
|
||||||
mfsr r12, AVR32_SR
|
|
||||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
|
||||||
cp.w r12, 0b110
|
|
||||||
brlo _int1_normal
|
|
||||||
lddsp r12, sp[0 * 4]
|
|
||||||
stdsp sp[6 * 4], r12
|
|
||||||
lddsp r12, sp[1 * 4]
|
|
||||||
stdsp sp[7 * 4], r12
|
|
||||||
lddsp r12, sp[3 * 4]
|
|
||||||
sub sp, -6 * 4
|
|
||||||
rete
|
|
||||||
_int1_normal:
|
|
||||||
#endif
|
|
||||||
mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
|
||||||
call _get_interrupt_handler
|
|
||||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
|
||||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
|
||||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
|
||||||
|
|
||||||
_int2:
|
|
||||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
|
||||||
// CPU upon interrupt entry.
|
|
||||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
|
||||||
mfsr r12, AVR32_SR
|
|
||||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
|
||||||
cp.w r12, 0b110
|
|
||||||
brlo _int2_normal
|
|
||||||
lddsp r12, sp[0 * 4]
|
|
||||||
stdsp sp[6 * 4], r12
|
|
||||||
lddsp r12, sp[1 * 4]
|
|
||||||
stdsp sp[7 * 4], r12
|
|
||||||
lddsp r12, sp[3 * 4]
|
|
||||||
sub sp, -6 * 4
|
|
||||||
rete
|
|
||||||
_int2_normal:
|
|
||||||
#endif
|
|
||||||
mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
|
||||||
call _get_interrupt_handler
|
|
||||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
|
||||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
|
||||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
|
||||||
|
|
||||||
_int3:
|
|
||||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
|
||||||
// CPU upon interrupt entry.
|
|
||||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
|
||||||
mfsr r12, AVR32_SR
|
|
||||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
|
||||||
cp.w r12, 0b110
|
|
||||||
brlo _int3_normal
|
|
||||||
lddsp r12, sp[0 * 4]
|
|
||||||
stdsp sp[6 * 4], r12
|
|
||||||
lddsp r12, sp[1 * 4]
|
|
||||||
stdsp sp[7 * 4], r12
|
|
||||||
lddsp r12, sp[3 * 4]
|
|
||||||
sub sp, -6 * 4
|
|
||||||
rete
|
|
||||||
_int3_normal:
|
|
||||||
#endif
|
|
||||||
mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
|
||||||
call _get_interrupt_handler
|
|
||||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
|
||||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
|
||||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
|
||||||
|
|
||||||
|
|
||||||
// Constant data area.
|
|
||||||
|
|
||||||
.balign 4
|
|
||||||
|
|
||||||
// Values to store in the interrupt priority registers for the various interrupt priority levels.
|
|
||||||
// The interrupt priority registers contain the interrupt priority level and
|
|
||||||
// the EVBA-relative interrupt vector offset.
|
|
||||||
.global ipr_val
|
|
||||||
.type ipr_val, @object
|
|
||||||
ipr_val:
|
|
||||||
.word (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\
|
|
||||||
(INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\
|
|
||||||
(INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\
|
|
||||||
(INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)
|
|
||||||
|
|
||||||
|
|
||||||
//! \endverbatim
|
|
||||||
//! @}
|
|
|
@ -1,17 +1,3 @@
|
||||||
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
|
||||||
/*! \file *********************************************************************
|
|
||||||
*
|
|
||||||
* \brief FreeRTOS port source for AVR32 UC3.
|
|
||||||
*
|
|
||||||
* - Compiler: GNU GCC for AVR32
|
|
||||||
* - Supported devices: All AVR32 devices can be used.
|
|
||||||
* - AppNote:
|
|
||||||
*
|
|
||||||
* \author Atmel Corporation: http://www.atmel.com \n
|
|
||||||
* Support and FAQ: http://support.atmel.no/
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
|
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
@ -65,10 +51,8 @@
|
||||||
licensing and training services.
|
licensing and training services.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <sys/cpu.h>
|
|
||||||
#include <sys/usart.h>
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
/* Scheduler includes. */
|
/* Scheduler includes. */
|
||||||
|
@ -78,10 +62,8 @@
|
||||||
/* AVR32 UC3 includes. */
|
/* AVR32 UC3 includes. */
|
||||||
#include <avr32/io.h>
|
#include <avr32/io.h>
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#if( configTICK_USE_TC==1 )
|
#include <nlao_cpu.h>
|
||||||
#include "tc.h"
|
#include <nlao_usart.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Constants required to setup the task context. */
|
/* Constants required to setup the task context. */
|
||||||
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
|
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
|
||||||
|
@ -91,11 +73,8 @@
|
||||||
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
#define portNO_CRITICAL_NESTING ( ( unsigned long ) 0 )
|
||||||
volatile unsigned long ulCriticalNesting = 9999UL;
|
volatile unsigned long ulCriticalNesting = 9999UL;
|
||||||
|
|
||||||
#if( configTICK_USE_TC==0 )
|
/* Clear the COUNT&COMPARE match Interrupt Flag. */
|
||||||
static void prvScheduleNextTick( void );
|
static void prvClearCcInt( void );
|
||||||
#else
|
|
||||||
static void prvClearTcInt( void );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Setup the timer to generate the tick interrupts. */
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
static void prvSetupTimerInterrupt( void );
|
static void prvSetupTimerInterrupt( void );
|
||||||
|
@ -140,8 +119,8 @@ void _init_startup(void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Give the used CPU clock frequency to Newlib, so it can work properly. */
|
/* Give the used PBA clock frequency to Newlib, so it can work properly. */
|
||||||
set_cpu_hz( configCPU_CLOCK_HZ );
|
set_cpu_hz( configPBA_CLOCK_HZ );
|
||||||
|
|
||||||
/* Code section present if and only if the debug trace is activated. */
|
/* Code section present if and only if the debug trace is activated. */
|
||||||
#if configDBG
|
#if configDBG
|
||||||
|
@ -213,22 +192,16 @@ void *pvReturn;
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||||
simply increment the system tick. */
|
simply increment the system tick.
|
||||||
/* The preemptive scheduler is defined as "naked" as the full context is saved
|
The preemptive scheduler is defined as "naked" as the full context is saved
|
||||||
on entry as part of the context switch. */
|
on entry as part of the context switch. */
|
||||||
__attribute__((__naked__)) static void vTick( void )
|
__attribute__((__naked__)) static void vTick( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
portSAVE_CONTEXT_OS_INT();
|
portSAVE_CONTEXT_OS_INT();
|
||||||
|
|
||||||
#if( configTICK_USE_TC==1 )
|
/* Clear the interrupt flag. */
|
||||||
/* Clear the interrupt flag. */
|
prvClearCcInt();
|
||||||
prvClearTcInt();
|
|
||||||
#else
|
|
||||||
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
|
||||||
clock cycles from now. */
|
|
||||||
prvScheduleNextTick();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
||||||
calls in a critical section . */
|
calls in a critical section . */
|
||||||
|
@ -241,6 +214,13 @@ __attribute__((__naked__)) static void vTick( void )
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Note that the scall handler in the framework 'exception.x' must
|
||||||
|
* jump to this handler.
|
||||||
|
* In file: 'AVR32_UC3/Drivers/INTC/exception.x' replace the line after
|
||||||
|
* '_handle_Supervisor_Call:' which might be 'rjmp $'
|
||||||
|
* with the instruction:
|
||||||
|
* 'lda.w pc, SCALLYield'
|
||||||
|
*/
|
||||||
__attribute__((__naked__)) void SCALLYield( void )
|
__attribute__((__naked__)) void SCALLYield( void )
|
||||||
{
|
{
|
||||||
/* Save the context of the interrupted task. */
|
/* Save the context of the interrupted task. */
|
||||||
|
@ -308,7 +288,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE
|
||||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x00000000; /* R7 aka Frame Pointer */
|
||||||
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
|
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
|
||||||
|
|
||||||
return pxTopOfStack;
|
return pxTopOfStack;
|
||||||
|
@ -338,124 +318,28 @@ void vPortEndScheduler( void )
|
||||||
|
|
||||||
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||||
clock cycles from now. */
|
clock cycles from now. */
|
||||||
#if( configTICK_USE_TC==0 )
|
static void prvScheduleFirstTick(void)
|
||||||
static void prvScheduleFirstTick(void)
|
{
|
||||||
{
|
Set_system_register(AVR32_COMPARE, configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||||
unsigned long lCycles;
|
Set_system_register(AVR32_COUNT, 0);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
lCycles = Get_system_register(AVR32_COUNT);
|
__attribute__((__noinline__)) static void prvClearCcInt(void)
|
||||||
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
{
|
||||||
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
Set_system_register(AVR32_COMPARE, Get_system_register(AVR32_COMPARE));
|
||||||
// generation feature does not get disabled.
|
}
|
||||||
if(0 == lCycles)
|
|
||||||
{
|
|
||||||
lCycles++;
|
|
||||||
}
|
|
||||||
Set_system_register(AVR32_COMPARE, lCycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((__noinline__)) static void prvScheduleNextTick(void)
|
|
||||||
{
|
|
||||||
unsigned long lCycles, lCount;
|
|
||||||
|
|
||||||
lCycles = Get_system_register(AVR32_COMPARE);
|
|
||||||
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
|
||||||
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
|
||||||
// generation feature does not get disabled.
|
|
||||||
if(0 == lCycles)
|
|
||||||
{
|
|
||||||
lCycles++;
|
|
||||||
}
|
|
||||||
lCount = Get_system_register(AVR32_COUNT);
|
|
||||||
if( lCycles < lCount )
|
|
||||||
{ // We missed a tick, recover for the next.
|
|
||||||
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
|
||||||
}
|
|
||||||
Set_system_register(AVR32_COMPARE, lCycles);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
__attribute__((__noinline__)) static void prvClearTcInt(void)
|
|
||||||
{
|
|
||||||
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Setup the timer to generate the tick interrupts. */
|
/* Setup the timer to generate the tick interrupts. */
|
||||||
static void prvSetupTimerInterrupt(void)
|
static void prvSetupTimerInterrupt(void)
|
||||||
{
|
{
|
||||||
#if( configTICK_USE_TC==1 )
|
|
||||||
|
|
||||||
volatile avr32_tc_t *tc = &AVR32_TC;
|
|
||||||
|
|
||||||
// Options for waveform genration.
|
|
||||||
tc_waveform_opt_t waveform_opt =
|
|
||||||
{
|
|
||||||
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
|
|
||||||
|
|
||||||
.bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */
|
|
||||||
.beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */
|
|
||||||
.bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */
|
|
||||||
.bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */
|
|
||||||
|
|
||||||
.aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */
|
|
||||||
.aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */
|
|
||||||
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
|
|
||||||
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
|
|
||||||
|
|
||||||
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
|
|
||||||
.enetrg = FALSE, /* External event trigger enable. */
|
|
||||||
.eevt = 0, /* External event selection. */
|
|
||||||
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
|
|
||||||
.cpcdis = FALSE, /* Counter disable when RC compare. */
|
|
||||||
.cpcstop = FALSE, /* Counter clock stopped with RC compare. */
|
|
||||||
|
|
||||||
.burst = FALSE, /* Burst signal selection. */
|
|
||||||
.clki = FALSE, /* Clock inversion. */
|
|
||||||
.tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */
|
|
||||||
};
|
|
||||||
|
|
||||||
tc_interrupt_t tc_interrupt =
|
|
||||||
{
|
|
||||||
.etrgs=0,
|
|
||||||
.ldrbs=0,
|
|
||||||
.ldras=0,
|
|
||||||
.cpcs =1,
|
|
||||||
.cpbs =0,
|
|
||||||
.cpas =0,
|
|
||||||
.lovrs=0,
|
|
||||||
.covfs=0,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable all interrupt/exception. */
|
/* Disable all interrupt/exception. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
/* Register the compare interrupt handler to the interrupt controller and
|
/* Register the compare interrupt handler to the interrupt controller and
|
||||||
enable the compare interrupt. */
|
enable the compare interrupt. */
|
||||||
|
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, AVR32_INTC_INT0);
|
||||||
#if( configTICK_USE_TC==1 )
|
prvScheduleFirstTick();
|
||||||
{
|
|
||||||
INTC_register_interrupt(&vTick, configTICK_TC_IRQ, INT0);
|
|
||||||
|
|
||||||
/* Initialize the timer/counter. */
|
|
||||||
tc_init_waveform(tc, &waveform_opt);
|
|
||||||
|
|
||||||
/* Set the compare triggers.
|
|
||||||
Remember TC counter is 16-bits, so counting second is not possible!
|
|
||||||
That's why we configure it to count ms. */
|
|
||||||
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
|
|
||||||
|
|
||||||
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
|
|
||||||
|
|
||||||
/* Start the timer/counter. */
|
|
||||||
tc_start(tc, configTICK_TC_CHANNEL);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
INTC_register_interrupt(&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
|
|
||||||
prvScheduleFirstTick();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
|
||||||
/*! \file *********************************************************************
|
|
||||||
*
|
|
||||||
* \brief FreeRTOS port source for AVR32 UC3.
|
|
||||||
*
|
|
||||||
* - Compiler: GNU GCC for AVR32
|
|
||||||
* - Supported devices: All AVR32 devices can be used.
|
|
||||||
* - AppNote:
|
|
||||||
*
|
|
||||||
* \author Atmel Corporation: http://www.atmel.com \n
|
|
||||||
* Support and FAQ: http://support.atmel.no/
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
|
FreeRTOS V6.0.5 - Copyright (C) 2010 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
@ -100,8 +86,6 @@ extern "C" {
|
||||||
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
|
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
|
||||||
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
|
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
|
||||||
|
|
||||||
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
|
|
||||||
|
|
||||||
#if( configUSE_16_BIT_TICKS == 1 )
|
#if( configUSE_16_BIT_TICKS == 1 )
|
||||||
typedef unsigned portSHORT portTickType;
|
typedef unsigned portSHORT portTickType;
|
||||||
#define portMAX_DELAY ( portTickType ) 0xffff
|
#define portMAX_DELAY ( portTickType ) 0xffff
|
||||||
|
@ -198,7 +182,7 @@ extern void *pvPortRealloc( void *pv, size_t xSize );
|
||||||
"st.w r8[0], r0 \n\t"\
|
"st.w r8[0], r0 \n\t"\
|
||||||
\
|
\
|
||||||
/* Restore R0..R7 */ \
|
/* Restore R0..R7 */ \
|
||||||
"ldm sp++, r0-r7 \n\t"\
|
"ldm sp++, r0-r7 \n\t"\
|
||||||
/* R0-R7 should not be used below this line */ \
|
/* R0-R7 should not be used below this line */ \
|
||||||
/* Skip PC and SR (will do it at the end) */ \
|
/* Skip PC and SR (will do it at the end) */ \
|
||||||
"sub sp, -2*4 \n\t"\
|
"sub sp, -2*4 \n\t"\
|
||||||
|
|
Loading…
Reference in a new issue