提交 553d24f8 编写于 作者: K kyle.hu.gz

Add AVR32 UC3 port.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@605 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 5211e7ff
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle First version
*/
#include <rtthread.h>
#include "compiler.h"
#include "gpio.h"
char thread_led1_stack[1024];
struct rt_thread thread_led1;
static void rt_thread_entry_led1(void* parameter)
{
while (1)
{
/* led on */
rt_kprintf("LED1 on\r\n");
gpio_tgl_gpio_pin(AVR32_PIN_PA08);
rt_thread_delay(50); /* sleep 0.5 second and switch to other thread */
/* led off */
rt_kprintf("LED1 off\r\n");
gpio_tgl_gpio_pin(AVR32_PIN_PA08);
rt_thread_delay(50);
}
}
char thread_led2_stack[1024];
struct rt_thread thread_led2;
void rt_thread_entry_led2(void* parameter)
{
while (1)
{
/* led on */
rt_kprintf("LED2 on, count = %d\r\n", count);
gpio_tgl_gpio_pin(AVR32_PIN_PA07);
rt_thread_delay(RT_TICK_PER_SECOND);
/* led off */
rt_kprintf("LED2 off\r\n");
gpio_tgl_gpio_pin(AVR32_PIN_PA07);
rt_thread_delay(RT_TICK_PER_SECOND);
}
}
int rt_application_init()
{
/* create led1 thread */
rt_thread_init(&thread_led1,
"led1",
rt_thread_entry_led1,
RT_NULL,
&thread_led1_stack[0],
sizeof(thread_led1_stack), 5, 5);
rt_thread_startup(&thread_led1);
//------- init led2 thread
rt_thread_init(&thread_led2,
"led2",
rt_thread_entry_led2,
RT_NULL,
&thread_led2_stack[0],
sizeof(thread_led2_stack),5,10);
rt_thread_startup(&thread_led2);
return 0;
}
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr32", "elf32-avr32",
"elf32-avr32")
OUTPUT_ARCH(avr32:uc)
ENTRY(_start)
SEARCH_DIR("/home/mingwbuild/mingwavr32/avr32/lib");
/* Do we need any of these for elf?
__DYNAMIC = 0; */
MEMORY
{
FLASH (rxai!w) : ORIGIN = 0x80000000, LENGTH = 256K
CPUSRAM (wxa!ri) : ORIGIN = 0x00000004, LENGTH = 0x7FFC
USERPAGE : ORIGIN = 0x80800000, LENGTH = 512
FACTORYPAGE : ORIGIN = 0x80800200, LENGTH = 512
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = 0x80000000); . = 0x80000000;
.interp : { *(.interp) } >FLASH AT>FLASH
.reset : { *(.reset) } >FLASH AT>FLASH
.hash : { *(.hash) } >FLASH AT>FLASH
.dynsym : { *(.dynsym) } >FLASH AT>FLASH
.dynstr : { *(.dynstr) } >FLASH AT>FLASH
.gnu.version : { *(.gnu.version) } >FLASH AT>FLASH
.gnu.version_d : { *(.gnu.version_d) } >FLASH AT>FLASH
.gnu.version_r : { *(.gnu.version_r) } >FLASH AT>FLASH
.rel.init : { *(.rel.init) } >FLASH AT>FLASH
.rela.init : { *(.rela.init) } >FLASH AT>FLASH
.rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } >FLASH AT>FLASH
.rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } >FLASH AT>FLASH
.rel.fini : { *(.rel.fini) } >FLASH AT>FLASH
.rela.fini : { *(.rela.fini) } >FLASH AT>FLASH
.rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } >FLASH AT>FLASH
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } >FLASH AT>FLASH
.rel.data.rel.ro : { *(.rel.data.rel.ro*) } >FLASH AT>FLASH
.rela.data.rel.ro : { *(.rel.data.rel.ro*) } >FLASH AT>FLASH
.rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } >FLASH AT>FLASH
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } >FLASH AT>FLASH
.rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } >FLASH AT>FLASH
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } >FLASH AT>FLASH
.rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } >FLASH AT>FLASH
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } >FLASH AT>FLASH
.rel.ctors : { *(.rel.ctors) } >FLASH AT>FLASH
.rela.ctors : { *(.rela.ctors) } >FLASH AT>FLASH
.rel.dtors : { *(.rel.dtors) } >FLASH AT>FLASH
.rela.dtors : { *(.rela.dtors) } >FLASH AT>FLASH
.rel.got : { *(.rel.got) } >FLASH AT>FLASH
.rela.got : { *(.rela.got) } >FLASH AT>FLASH
.rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } >FLASH AT>FLASH
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } >FLASH AT>FLASH
.rel.plt : { *(.rel.plt) } >FLASH AT>FLASH
.rela.plt : { *(.rela.plt) } >FLASH AT>FLASH
.init :
{
KEEP (*(.init))
} >FLASH AT>FLASH =0xd703d703
.plt : { *(.plt) } >FLASH AT>FLASH
.text :
{
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
} >FLASH AT>FLASH =0xd703d703
.fini :
{
KEEP (*(.fini))
} >FLASH AT>FLASH =0xd703d703
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >FLASH AT>FLASH
.rodata1 : { *(.rodata1) } >FLASH AT>FLASH
.eh_frame_hdr : { *(.eh_frame_hdr) } >FLASH AT>FLASH
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } >FLASH AT>FLASH
.gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } >FLASH AT>FLASH
.dalign : { . = ALIGN(8); PROVIDE(_data_lma = .); } >FLASH AT>FLASH
PROVIDE (_data = ORIGIN(CPUSRAM));
. = ORIGIN(CPUSRAM);
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } >CPUSRAM AT>FLASH
.gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } >CPUSRAM AT>FLASH
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } >CPUSRAM AT>FLASH
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >CPUSRAM
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
PROVIDE (__preinit_array_start = ALIGN(32 / 8));
.preinit_array : { KEEP (*(.preinit_array)) } >CPUSRAM AT>FLASH
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { KEEP (*(.init_array)) } >CPUSRAM AT>FLASH
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { KEEP (*(.fini_array)) } >CPUSRAM AT>FLASH
PROVIDE (__fini_array_end = .);
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin*.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >CPUSRAM AT>FLASH
.dtors :
{
KEEP (*crtbegin*.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >CPUSRAM AT>FLASH
.jcr : { KEEP (*(.jcr)) } >CPUSRAM AT>FLASH
.data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } >CPUSRAM AT>FLASH
.dynamic : { *(.dynamic) } >CPUSRAM AT>FLASH
.got : { *(.got.plt) *(.got) } >CPUSRAM AT>FLASH
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
} >CPUSRAM AT>FLASH
.data1 : { *(.data1) } >CPUSRAM AT>FLASH
.balign : { . = ALIGN(8); _edata = .; } >CPUSRAM AT>FLASH
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(8);
} >CPUSRAM
. = ALIGN(8);
_end = .;
PROVIDE (end = .);
__heap_start__ = ALIGN(8);
. = ORIGIN(CPUSRAM) + LENGTH(CPUSRAM) - _stack_size;
__heap_end__ = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.stack ORIGIN(CPUSRAM) + LENGTH(CPUSRAM) - _stack_size :
{
_stack = .;
*(.stack)
. = _stack_size;
_estack = .;
} >CPUSRAM
.userpage : { *(.userpage .userpage.*) } >USERPAGE AT>USERPAGE
.factorypage : { *(.factorypage .factorypage.*) } >FACTORYPAGE AT>FACTORYPAGE
/DISCARD/ : { *(.note.GNU-stack) }
}
/*
* File : board.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle First version
*/
#include <rtthread.h>
#include "compiler.h"
#include "pm.h"
#include "gpio.h"
#include "usart.h"
#include "intc.h"
#include "serial.h"
#define FOSC0 12000000
#define FCPU 60000000
#define FHSB FCPU
#define FPBA FCPU
#define FPBB FCPU
extern void rt_hw_serial_isr(void);
extern void rt_hw_usart_init(void);
/**
* System tick interrupt handler.
*/
static void rt_hw_timer_handler(void)
{
// Clears the interrupt request.
Set_system_register(AVR32_COMPARE, FCPU / RT_TICK_PER_SECOND);
rt_tick_increase();
}
/**
* Initialize system clock and all peripherals.
*/
static void peripherals_init(void)
{
/*
* PM initialization: OSC0 = 12MHz XTAL, PLL0 = 60MHz System Clock
*/
pm_freq_param_t pm_freq_param =
{
.cpu_f = FCPU,
.pba_f = FPBA,
.osc0_f = FOSC0,
.osc0_startup = AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC
};
pm_configure_clocks(&pm_freq_param);
/*
* USART1 initialization
*/
gpio_enable_module_pin(AVR32_USART1_TXD_0_1_PIN, AVR32_USART1_TXD_0_1_FUNCTION);
gpio_enable_module_pin(AVR32_USART1_RXD_0_1_PIN, AVR32_USART1_RXD_0_1_FUNCTION);
static const usart_options_t usartOptions = {
.baudrate = 115200,
.charlength = 8,
.paritytype = USART_NO_PARITY,
.stopbits = USART_1_STOPBIT,
.channelmode = USART_NORMAL_CHMODE
};
usart_init_rs232(&AVR32_USART1, &usartOptions, FCPU);
INTC_init_interrupts();
INTC_register_interrupt(&rt_hw_serial_isr, AVR32_USART1_IRQ, AVR32_INTC_INT0);
AVR32_USART1.ier = AVR32_USART_IER_RXRDY_MASK;
}
/**
* Initialize CPU cycle counter for system tick.
*/
static void cpu_counter_init(void)
{
INTC_register_interrupt(&rt_hw_timer_handler, AVR32_CORE_COMPARE_IRQ, AVR32_INTC_INT3);
Set_system_register(AVR32_COMPARE, FCPU / RT_TICK_PER_SECOND);
Set_system_register(AVR32_COUNT, 0);
}
void rt_hw_board_init(void)
{
extern struct rt_device _rt_usart_device;
extern struct avr32_serial_device uart;
Disable_global_interrupt();
peripherals_init();
cpu_counter_init();
rt_hw_serial_register(&_rt_usart_device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, &uart);
rt_console_set_device("uart1");
}
/*
* File : rtconfig.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle First version
*/
#ifndef RTCONFIG_H_
#define RTCONFIG_H_
/* RT_NAME_MAX*/
#define RT_NAME_MAX 8
/* RT_ALIGN_SIZE*/
#define RT_ALIGN_SIZE 4
/* PRIORITY_MAX*/
#define RT_THREAD_PRIORITY_MAX 32
/* Tick per Second*/
#define RT_TICK_PER_SECOND 100
/* SECTION: RT_DEBUG */
/* Thread Debug*/
//#define RT_DEBUG
/* #define RT_THREAD_DEBUG */
#define RT_USING_OVERFLOW_CHECK
/* Using Hook*/
//#define RT_USING_HOOK
/* SECTION: IPC */
/* Using Semaphore*/
#define RT_USING_SEMAPHORE
/* Using Mutex*/
//#define RT_USING_MUTEX
/* Using Event*/
//#define RT_USING_EVENT
/* Using MailBox*/
//#define RT_USING_MAILBOX
/* Using Message Queue*/
//#define RT_USING_MESSAGEQUEUE
/* SECTION: Memory Management */
/* Using Memory Pool Management*/
#define RT_USING_MEMPOOL
/* Using Dynamic Heap Management*/
#define RT_USING_HEAP
/* Using Small MM*/
#define RT_USING_SMALL_MEM
/* Using SLAB Allocator*/
/* #define RT_USING_SLAB */
/* SECTION: Device System */
/* Using Device System*/
#define RT_USING_DEVICE
/* SECTION: Console options */
/* the buffer size of console*/
#define RT_CONSOLEBUF_SIZE 128
/* SECTION: FinSH shell options */
/* Using FinSH as Shell*/
#define RT_USING_FINSH
/* Using symbol table */
#define FINSH_USING_SYMTAB
#define FINSH_USING_DESCRIPTION
#define FINSH_DEVICE_NAME "uart1"
/* SECTION: RT-Thread/GUI */
//#define RT_USING_DFS
#define RT_USING_DFS_ELMFAT
#define RT_DFS_ELM_WORD_ACCESS
#define RT_DFS_ELM_DRIVES 2
/* SECTION: DFS options */
/* the max number of mounted filesystem */
#define DFS_FILESYSTEMS_MAX 2
/* the max number of opened files */
#define DFS_FD_MAX 8
/* the max number of cached sector */
#define DFS_CACHE_MAX_NUM 4
/* SECTION: RT-Thread/GUI */
//#define RT_USING_RTGUI
/* name length of RTGUI object */
#define RTGUI_NAME_MAX 12
/* support 16 weight font */
#define RTGUI_USING_FONT16
/* support Chinese font */
#define RTGUI_USING_FONTHZ
/* use DFS as file interface */
#define RTGUI_USING_DFS_FILERW
/* use font file as Chinese font */
#define RTGUI_USING_HZ_FILE
/* use small size in RTGUI */
#define RTGUI_USING_SMALL_SIZE
/* use mouse cursor */
/* #define RTGUI_USING_MOUSE_CURSOR */
/* default font size in RTGUI */
#define RTGUI_DEFAULT_FONT_SIZE 16
#endif /* RTCONFIG_H_ */
/*
* File : startup.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle First version
*/
#include <rtthread.h>
extern void rt_hw_board_init(void);
extern void rt_application_init(void);
#ifdef RT_USING_FINSH
extern void finsh_system_init(void);
extern void finsh_set_device(const char* device);
#endif
int main(void)
{
#ifdef RT_USING_HEAP
extern void __heap_start__;
extern void __heap_end__;
#endif
rt_hw_board_init();
rt_system_tick_init();
rt_system_object_init();
rt_system_timer_init();
#ifdef RT_USING_HEAP
rt_system_heap_init(&__heap_start__, &__heap_end__);
#endif
rt_system_scheduler_init();
rt_device_init_all();
rt_application_init();
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
finsh_set_device(FINSH_DEVICE_NAME);
#endif
rt_thread_idle_init();
rt_system_scheduler_start();
return 0;
}
/*
* File : context.S
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-27 Kyle First version
*/
#define AVR32_SR 0
#define AVR32_SR_GM_OFFSET 16
.text
/*
* rt_base_t rt_hw_interrupt_disable()
*/
.globl rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
rt_hw_interrupt_disable:
ssrf AVR32_SR_GM_OFFSET
mov pc, lr
/*
* void rt_hw_interrupt_enable(rt_base_t level)
*/
.globl rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
rt_hw_interrupt_enable:
csrf AVR32_SR_GM_OFFSET
mov pc, lr
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
* r8 --> from
* r9 --> to
*/
.globl rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch:
ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
stm --sp, r8-r12, lr /* Push R8-R12, LR */
st.w --sp, lr /* Push LR (instead of PC) */
mfsr r8, AVR32_SR /* Read Status Register */
cbr r8, AVR32_SR_GM_OFFSET /* Clear GM bit */
st.w --sp, r8 /* Push SR */
stm --sp, r0-r7 /* Push R0-R7 */
/* Stack layout: R8-R12, LR, PC, SR, R0-R7 */
st.w r12[0], sp /* Store SP in preempted tasks TCB */
ld.w sp, r11[0] /* Get new task stack pointer */
ldm sp++, r0-r7 /* pop R0-R7 */
ld.w r8, sp++ /* pop SR */
mtsr AVR32_SR, r8 /* Restore SR */
ldm sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume to thread */
/*
* void rt_hw_context_switch_to(rt_uint32 to)/*
* r0 --> to
*/
.globl rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
ld.w sp, r12[0] /* Get new task stack pointer */
ldm sp++, r0-r7 /* pop R0-R7 */
ld.w r8, sp++ /* pop SR */
mtsr AVR32_SR, r8 /* Restore SR */
ldm sp++, r8-r12, lr, pc/* Pop R8-R12, LR, PC and resume execution */
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
*/
.globl rt_thread_switch_interrupt_flag
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
rt_hw_context_switch_interrupt:
lda.w r8, rt_thread_switch_interrupt_flag
ld.w r9, r8[0]
cp.w r9, 1
breq _reswitch
mov r9, 1
st.w r8[0], r9
lda.w r8, rt_interrupt_from_thread
st.w r8[0], r12
_reswitch:
lda.w r8, rt_interrupt_to_thread
st.w r8[0], r11
mov pc, lr
/*
* File : cpu.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle First version
*/
#include <rtthread.h>
/**
* @addtogroup AVR32UC3
*/
/*@{*/
/**
* reset cpu by dog's time-out
*
*/
void rt_hw_cpu_reset()
{
/*NOTREACHED*/
}
/**
* shutdown CPU
*
*/
void rt_hw_cpu_shutdown()
{
rt_kprintf("shutdown...\n");
RT_ASSERT(0);
}
/*@}*/
/* This file is part of the ATMEL AVR32-UC3-SoftwareFramework-1.6.0 Release */
/*This file is prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief Exception and interrupt vectors.
*
* This file maps all events supported by an AVR32.
*
* - Compiler: GNU GCC for AVR32
* - Supported devices: All AVR32 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) 2009 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.
*
* 4. This software may only be redistributed and used in connection with an Atmel
* AVR product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 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
*
*/
#if !__AVR32_UC__ && !__AVR32_AP__
#error Implementation of the AVR32 architecture not supported by the INTC driver.
#endif
#include <avr32/io.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.
_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 and AVR32AP.
_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.
_handle_ITLB_Miss:
rjmp $
.org 0x060
// DTLB Miss (Read).
_handle_DTLB_Miss_Read:
rjmp $
.org 0x070
// DTLB Miss (Write).
_handle_DTLB_Miss_Write:
rjmp $
.org 0x100
// Supervisor Call.
_handle_Supervisor_Call:
rjmp $
// 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
.irp priority, 0, 1, 2, 3
_int\priority:
mov r12, \priority // Pass the int_level 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.
breq _spint\priority // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
call rt_interrupt_enter
icall r12
call rt_interrupt_leave
_spint\priority:
lda.w r12, rt_thread_switch_interrupt_flag
ld.w r11, r12[0]
cp.w r11, 1
breq rt_hw_context_switch_interrupt_do
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
.endr
rt_hw_context_switch_interrupt_do:
ssrf AVR32_SR_GM_OFFSET /* Disable global interrupt */
mov r11, 0
st.w r12[0], r11 /* Clear rt_thread_switch_interrupt_flag */
stm --sp, r0-r7 /* Push R0-R7 */
lda.w r12, rt_interrupt_from_thread /* Get old thread SP */
ld.w r12, r12[0]
lda.w r11, rt_interrupt_to_thread /* Get new thread SP */
ld.w r11, r11[0]
st.w r12[0], sp /* Store old thead SP */
ld.w sp, r11[0] /* Load new thread SP */
ldm sp++, r0-r7 /* Pop R0-R7 (new thread) */
rete /* RETE pops R8-R12, LR, PC, SR automatically */
// 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 (AVR32_INTC_INT0 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int0 - _evba),\
(AVR32_INTC_INT1 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int1 - _evba),\
(AVR32_INTC_INT2 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int2 - _evba),\
(AVR32_INTC_INT3 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int3 - _evba)
//! \endverbatim
//! @}
/*
* File : interrupt.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle Ported from STM32 to AVR32.
*/
#include <rtthread.h>
#include "compiler.h"
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag;
/*
* File : serial.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-02-05 Bernard first version
* 2009-10-25 Bernard fix rt_serial_read bug when there is no data
* in the buffer.
* 2010-03-29 Bernard cleanup code.
* 2010-03-30 Kyle Ported from STM32 to AVR32.
*/
#include "serial.h"
#include "compiler.h"
#include "usart.h"
#include "pdca.h"
struct rt_device _rt_usart_device;
struct avr32_serial_int_rx _rt_usart_rx;
struct avr32_serial_device uart =
{
.uart_device = (avr32_usart_t *) &AVR32_USART1,
.int_rx = &_rt_usart_rx
};
/**
* @addtogroup AVR32UC3
*/
/*@{*/
/* RT-Thread Device Interface */
static rt_err_t rt_serial_init (rt_device_t dev)
{
struct avr32_serial_device* uart = (struct avr32_serial_device*) dev->private;
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
{
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
rt_memset(uart->int_rx->rx_buffer, 0, sizeof(uart->int_rx->rx_buffer));
uart->int_rx->read_index = 0;
uart->int_rx->save_index = 0;
}
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
}
return RT_EOK;
}
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
static rt_err_t rt_serial_close(rt_device_t dev)
{
return RT_EOK;
}
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
rt_err_t err_code;
struct avr32_serial_device* uart;
ptr = buffer;
err_code = RT_EOK;
uart = (struct avr32_serial_device*)dev->private;
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{
/* interrupt mode Rx */
while (size)
{
rt_base_t level;
/* disable interrupt */
level = rt_hw_interrupt_disable();
if (uart->int_rx->read_index != uart->int_rx->save_index)
{
/* read a character */
*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
size--;
/* move to next position */
uart->int_rx->read_index ++;
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
uart->int_rx->read_index = 0;
}
else
{
/* set error code */
err_code = -RT_EEMPTY;
/* enable interrupt */
rt_hw_interrupt_enable(level);
break;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
}
}
else
{
/* polling mode */
while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
{
while (usart_test_hit(uart->uart_device))
{
*ptr = uart->uart_device->rhr & 0xff;
ptr ++;
}
}
}
/* set error code */
rt_set_errno(err_code);
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
rt_uint8_t* ptr;
rt_err_t err_code;
struct avr32_serial_device* uart;
err_code = RT_EOK;
ptr = (rt_uint8_t*)buffer;
uart = (struct avr32_serial_device*)dev->private;
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
{
/* interrupt mode Tx, does not support */
RT_ASSERT(0);
}
else
{
/* polling mode */
if (dev->flag & RT_DEVICE_FLAG_STREAM)
{
/* stream mode */
while (size)
{
usart_putchar(uart->uart_device, (int) *ptr);
++ptr; --size;
}
}
else
{
/* write data directly */
while (size)
{
while (usart_write_char(uart->uart_device, (int) *ptr) != USART_SUCCESS);
++ptr; --size;
}
}
}
/* set error code */
rt_set_errno(err_code);
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
}
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
{
struct avr32_serial_device* uart;
RT_ASSERT(dev != RT_NULL);
uart = (struct avr32_serial_device*)dev->private;
switch (cmd)
{
case RT_DEVICE_CTRL_SUSPEND:
/* suspend device */
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
break;
case RT_DEVICE_CTRL_RESUME:
/* resume device */
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
break;
}
return RT_EOK;
}
/*
* serial register for STM32
* support STM32F103VB and STM32F103ZE
*/
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct avr32_serial_device *serial)
{
RT_ASSERT(device != RT_NULL);
if ((flag & RT_DEVICE_FLAG_DMA_RX) ||
(flag & RT_DEVICE_FLAG_INT_TX))
{
RT_ASSERT(0);
}
device->type = RT_Device_Class_Char;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->init = rt_serial_init;
device->open = rt_serial_open;
device->close = rt_serial_close;
device->read = rt_serial_read;
device->write = rt_serial_write;
device->control = rt_serial_control;
device->private = serial;
/* register a character device */
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
}
/* ISR for serial interrupt */
void rt_hw_serial_isr(void)
{
struct avr32_serial_device* uart = (struct avr32_serial_device*) _rt_usart_device.private;
rt_base_t level;
if (usart_test_hit(uart->uart_device))
{
/* interrupt mode receive */
RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
/* disable interrupt */
level = rt_hw_interrupt_disable();
/* save character */
uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->rhr & 0xff;
uart->int_rx->save_index ++;
if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
uart->int_rx->save_index = 0;
/* if the next position is read index, discard this 'read char' */
if (uart->int_rx->save_index == uart->int_rx->read_index)
{
uart->int_rx->read_index ++;
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
uart->int_rx->read_index = 0;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
/* invoke callback */
if (_rt_usart_device.rx_indicate != RT_NULL)
{
rt_size_t rx_length;
/* get rx length */
rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
uart->int_rx->save_index - uart->int_rx->read_index;
_rt_usart_device.rx_indicate(&_rt_usart_device, rx_length);
}
}
else
{
usart_reset_status(uart->uart_device);
}
}
/*@}*/
/*
* File : serial.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009 - 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first version
* 2010-03-29 Bernard remove interrupt tx and DMA rx mode.
* 2010-03-30 Kyle Ported from STM32 to AVR32.
*/
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rthw.h>
#include <rtthread.h>
#include "compiler.h"
#include "usart.h"
#define UART_RX_BUFFER_SIZE 64
#define UART_TX_DMA_NODE_SIZE 4
/* data node for Tx Mode */
struct avr32_serial_data_node
{
rt_uint8_t *data_ptr;
rt_size_t data_size;
struct avr32_serial_data_node *next, *prev;
};
struct avr32_serial_int_rx
{
rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
rt_uint32_t read_index, save_index;
};
struct avr32_serial_device
{
avr32_usart_t *uart_device;
/* rx structure */
struct avr32_serial_int_rx* int_rx;
};
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct avr32_serial_device *serial);
void rt_hw_serial_isr();
#endif
/*
* File : stack.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2010-03-30 Kyle First version
*/
#include <rtthread.h>
/**
* @addtogroup AVR32UC3
*/
/*@{*/
/**
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
{
unsigned long *stk;
stk = (unsigned long *)stack_addr;
*(stk) = 0; /* r8 */
*(--stk) = 0; /* r9 */
*(--stk) = 0; /* r10 */
*(--stk) = 0; /* r11 */
*(--stk) = 0; /* r12 */
*(--stk) = (unsigned long)texit; /* lr */
*(--stk) = (unsigned long)tentry; /* entry point, pc */
*(--stk) = 0x00600000; /* sr */
*(--stk) = 0; /* r0 */
*(--stk) = 0; /* r1 */
*(--stk) = 0; /* r2 */
*(--stk) = 0; /* r3 */
*(--stk) = 0; /* r4 */
*(--stk) = 0; /* r5 */
*(--stk) = 0; /* r6 */
*(--stk) = 0; /* r7 */
/* return task's current stack address */
return (rt_uint8_t *)stk;
}
/*@}*/
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册