summaryrefslogtreecommitdiff
path: root/libcpu/arm
diff options
context:
space:
mode:
authorbernard.xiong <[email protected]>2009-07-02 22:48:23 +0000
committerbernard.xiong <[email protected]>2009-07-02 22:48:23 +0000
commitbda4730a9482c23083006abea939ee8d95d6ecff (patch)
tree83005121824bd50ac74e63688c0d5eac148665f8 /libcpu/arm
parent80c72e66de0b00b1a6de3e3508366a4c3eee458d (diff)
import RT-Thread RTOS 0.3.x to Google SVN
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu/arm')
-rw-r--r--libcpu/arm/stm32/context_iar.S170
-rw-r--r--libcpu/arm/stm32/context_rvds.S189
-rw-r--r--libcpu/arm/stm32/cpu.c42
-rw-r--r--libcpu/arm/stm32/fault.c34
-rw-r--r--libcpu/arm/stm32/fault_rvds.S31
-rw-r--r--libcpu/arm/stm32/interrupt.c25
-rw-r--r--libcpu/arm/stm32/serial.c586
-rw-r--r--libcpu/arm/stm32/serial.h69
-rw-r--r--libcpu/arm/stm32/stack.c59
-rw-r--r--libcpu/arm/stm32/start_iar.c176
-rw-r--r--libcpu/arm/stm32/start_rvds.s250
11 files changed, 1631 insertions, 0 deletions
diff --git a/libcpu/arm/stm32/context_iar.S b/libcpu/arm/stm32/context_iar.S
new file mode 100644
index 0000000000..d20cdf9dd4
--- /dev/null
+++ b/libcpu/arm/stm32/context_iar.S
@@ -0,0 +1,170 @@
+;/*
+; * File : context.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, 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-17 Bernard first version
+; */
+
+;/**
+; * @addtogroup STM32
+; */
+;/*@{*/
+
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ SECTION .text:CODE(2)
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+ EXPORT rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+ EXPORT rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ MSR PRIMASK, r0
+ BX LR
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+ EXPORT rt_hw_context_switch
+rt_hw_context_switch:
+ LDR r2, =rt_interrupt_from_thread
+ STR r0, [r2]
+
+ LDR r2, =rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ CPSIE I ; enable interrupts at processor level
+ BX LR
+
+; r0 --> swith from thread stack
+; r1 --> swith to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+ EXPORT rt_hw_pend_sv
+rt_hw_pend_sv:
+ LDR r0, =rt_interrupt_from_thread
+ LDR r1, [r0]
+ CBZ r1, swtich_to_thread ; skip register save at the first time
+
+ MRS r1, psp ; get from thread stack pointer
+ STMFD r1!, {r4 - r11} ; push r4 - r11 register
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+swtich_to_thread
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
+ MSR psp, r1 ; update stack pointer
+
+ ORR lr, lr, #0x04
+ BX lr
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+ EXPORT rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ ; set the PendSV exception priority
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ STR r1, [r0]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ CPSIE I ; enable interrupts at processor level
+
+ ; never reach here!
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
+; * {
+; * if (rt_thread_switch_interrput_flag == 1)
+; * {
+; * rt_interrupt_to_thread = to;
+; * }
+; * else
+; * {
+; * rt_thread_switch_interrput_flag = 1;
+; * rt_interrupt_from_thread = from;
+; * rt_interrupt_to_thread = to;
+; * }
+; * }
+; */
+ EXPORT rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_flag to 1
+ STR r3, [r2]
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+_reswitch:
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+ BX lr
+
+ EXPORT rt_hw_interrupt_thread_switch
+rt_hw_interrupt_thread_switch:
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CBZ r1, _no_switch
+
+ ; clear rt_thread_switch_interrput_flag to 0
+ MOV r1, #0x00
+ STR r1, [r0]
+
+ ; trigger context switch
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+_no_switch:
+ BX lr
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/stm32/context_rvds.S b/libcpu/arm/stm32/context_rvds.S
new file mode 100644
index 0000000000..7aeefb2257
--- /dev/null
+++ b/libcpu/arm/stm32/context_rvds.S
@@ -0,0 +1,189 @@
+;/*
+; * File : context.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, 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-17 Bernard first version
+; */
+
+;/**
+; * @addtogroup STM32
+; */
+;/*@{*/
+
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable PROC
+ EXPORT rt_hw_interrupt_disable
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable PROC
+ EXPORT rt_hw_interrupt_enable
+ MSR PRIMASK, r0
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch PROC
+ EXPORT rt_hw_context_switch
+
+ ; set rt_thread_switch_interrput_flag to 1
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2]
+ MOV r3, #1
+ STR r3, [r2]
+
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ ; CPSIE I ; enable interrupts at processor level
+ BX LR
+ ENDP
+
+; r0 --> swith from thread stack
+; r1 --> swith to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+rt_hw_pend_sv PROC
+ EXPORT rt_hw_pend_sv
+ ; clear rt_thread_switch_interrput_flag to 0
+ LDR r0, =rt_thread_switch_interrput_flag
+ MOV r1, #0x00
+ STR r1, [r0]
+
+ LDR r0, =rt_interrupt_from_thread
+ LDR r1, [r0]
+ CBZ r1, swtich_to_thread ; skip register save at the first time
+
+ MRS r1, psp ; get from thread stack pointer
+ STMFD r1!, {r4 - r11} ; push r4 - r11 register
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+swtich_to_thread
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
+ MSR psp, r1 ; update stack pointer
+
+ ORR lr, lr, #0x04
+ BX lr
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to PROC
+ EXPORT rt_hw_context_switch_to
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ ; set the PendSV exception priority
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ STR r1, [r0]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ CPSIE I ; enable interrupts at processor level
+
+ ; never reach here!
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
+; * {
+; * if (rt_thread_switch_interrput_flag == 1)
+; * {
+; * rt_interrupt_to_thread = to;
+; * }
+; * else
+; * {
+; * rt_thread_switch_interrput_flag = 1;
+; * rt_interrupt_from_thread = from;
+; * rt_interrupt_to_thread = to;
+; * }
+; * }
+; */
+rt_hw_context_switch_interrupt PROC
+ EXPORT rt_hw_context_switch_interrupt
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_flag to 1
+ STR r3, [r2]
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+_reswitch
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+ BX lr
+ ENDP
+
+rt_hw_interrupt_thread_switch PROC
+ EXPORT rt_hw_interrupt_thread_switch
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CBZ r1, _no_switch
+
+ ; clear rt_thread_switch_interrput_flag to 0
+ ; MOV r1, #0x00
+ ; STR r1, [r0]
+
+ ; trigger context switch
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+_no_switch
+ BX lr
+
+ ENDP
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/stm32/cpu.c b/libcpu/arm/stm32/cpu.c
new file mode 100644
index 0000000000..080634c2b9
--- /dev/null
+++ b/libcpu/arm/stm32/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-13 Bernard first version
+ */
+
+#include <rtthread.h>
+
+/**
+ * @addtogroup S3C2410
+ */
+/*@{*/
+
+/**
+ * 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);
+}
+
+/*@}*/
diff --git a/libcpu/arm/stm32/fault.c b/libcpu/arm/stm32/fault.c
new file mode 100644
index 0000000000..c3cf747018
--- /dev/null
+++ b/libcpu/arm/stm32/fault.c
@@ -0,0 +1,34 @@
+#include <rtthread.h>
+
+struct stack_contex
+{
+ rt_uint32_t r0;
+ rt_uint32_t r1;
+ rt_uint32_t r2;
+ rt_uint32_t r3;
+ rt_uint32_t r12;
+ rt_uint32_t lr;
+ rt_uint32_t pc;
+ rt_uint32_t psr;
+};
+
+extern void rt_hw_interrupt_thread_switch(void);
+extern void list_thread(void);
+extern rt_thread_t rt_current_thread;
+void rt_hw_hard_fault_exception(struct stack_contex* contex)
+{
+ rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
+ rt_kprintf("psr: 0x%08x\n", contex->psr);
+ rt_kprintf(" pc: 0x%08x\n", contex->pc);
+ rt_kprintf(" lr: 0x%08x\n", contex->lr);
+ rt_kprintf("r12: 0x%08x\n", contex->r12);
+ rt_kprintf("r03: 0x%08x\n", contex->r3);
+ rt_kprintf("r02: 0x%08x\n", contex->r2);
+ rt_kprintf("r01: 0x%08x\n", contex->r1);
+ rt_kprintf("r00: 0x%08x\n", contex->r0);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ while (1);
+}
diff --git a/libcpu/arm/stm32/fault_rvds.S b/libcpu/arm/stm32/fault_rvds.S
new file mode 100644
index 0000000000..e4f0aaa964
--- /dev/null
+++ b/libcpu/arm/stm32/fault_rvds.S
@@ -0,0 +1,31 @@
+;/*
+; * File : context.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, 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-17 Bernard first version
+; */
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_hw_hard_fault_exception
+
+rt_hw_hard_fault PROC
+ EXPORT rt_hw_hard_fault
+
+ ; get current context
+ MRS r0, psp ; get fault thread stack pointer
+ BL rt_hw_hard_fault_exception
+
+ ORR lr, lr, #0x04
+ BX lr
+ \ No newline at end of file
diff --git a/libcpu/arm/stm32/interrupt.c b/libcpu/arm/stm32/interrupt.c
new file mode 100644
index 0000000000..a57656c7fb
--- /dev/null
+++ b/libcpu/arm/stm32/interrupt.c
@@ -0,0 +1,25 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 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://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-03-13 Bernard first version
+ */
+
+#include <rtthread.h>
+
+#define MAX_HANDLERS 32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/*@}*/
diff --git a/libcpu/arm/stm32/serial.c b/libcpu/arm/stm32/serial.c
new file mode 100644
index 0000000000..c5dbb0b24e
--- /dev/null
+++ b/libcpu/arm/stm32/serial.c
@@ -0,0 +1,586 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 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://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-02-05 Bernard first version
+ */
+
+#include "serial.h"
+
+static void rt_serial_enable_dma(DMA_Channel_TypeDef* dma_channel,
+ rt_uint32_t address, rt_uint32_t size);
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+/**
+ * This function read a character from serial without interrupt enable mode
+ *
+ * @return the read char
+ */
+char rt_serial_getc(struct stm32_serial_device* uart)
+{
+ rt_base_t level;
+ char ch = 0;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ if (uart->int_rx->read_index != uart->int_rx->save_index)
+ {
+ ch = uart->int_rx->rx_buffer[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);
+
+ return ch;
+}
+
+/* save a char to serial buffer */
+void rt_serial_savechar(struct stm32_serial_device* uart, char ch)
+{
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
+ 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);
+}
+
+/**
+ * This function will write a character to serial without interrupt enable mode
+ *
+ * @param c the char to write
+ */
+void rt_serial_putc(rt_device_t device, const char c)
+{
+ struct stm32_serial_device* uart = (struct stm32_serial_device*) device->private;
+
+ /*
+ * to be polite with serial console add a line feed
+ * to the carriage return character
+ */
+ if (c=='\n' && (device->flag & RT_DEVICE_FLAG_STREAM))
+ rt_serial_putc(device, '\r');
+
+ while (!(uart->uart_device->SR & USART_FLAG_TXE));
+ uart->uart_device->DR = (c & 0x1FF);
+}
+
+/* RT-Thread Device Interface */
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+ struct stm32_serial_device* uart = (struct stm32_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->read_index = 0;
+ }
+
+ if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ RT_ASSERT(uart->dma_rx->dma_channel != RT_NULL);
+ uart->dma_rx->read_index = uart->dma_rx->read_descriptor = 0;
+ uart->dma_rx->is_full = RT_FALSE;
+ }
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+ {
+ rt_memset(uart->int_tx->tx_buffer, 0,
+ sizeof(uart->int_tx->tx_buffer));
+ uart->int_tx->write_index = uart->int_tx->save_index = 0;
+ }
+
+ if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+ {
+ RT_ASSERT(uart->dma_rx->dma_channel != RT_NULL);
+ uart->dma_tx->list_head = uart->dma_tx->list_tail = RT_NULL;
+ }
+
+ /* Enable USART */
+ USART_Cmd(uart->uart_device, ENABLE);
+
+ dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ struct stm32_serial_device* uart;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ uart = (struct stm32_serial_device*)dev->private;
+
+ if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* enable Rx DMA */
+ rt_serial_enable_dma(uart->dma_rx->dma_channel,
+ (rt_uint32_t)&(uart->dma_rx->rx_buffer[uart->dma_rx->save_descriptor][0]),
+ UART_DMA_RX_BUFFER_SIZE);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+ struct stm32_serial_device* uart;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ uart = (struct stm32_serial_device*)dev->private;
+
+ if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* disable DMA */
+ DMA_Cmd(uart->dma_rx->dma_channel, DISABLE);
+ }
+ 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 stm32_serial_device* uart;
+
+ ptr = buffer;
+ err_code = RT_EOK;
+ uart = (struct stm32_serial_device*)dev->private;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ rt_int32_t ch;
+
+ /* interrupt mode Rx */
+ while (size)
+ {
+ /* get a character */
+ ch = rt_serial_getc(uart);
+ if (ch < 0)
+ {
+ /* set error code */
+ err_code = -RT_EEMPTY;
+ }
+ else
+ {
+ *ptr++ = ch;
+ size --;
+ }
+ }
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+ {
+ /* check queue empty */
+ if ((uart->dma_rx->read_descriptor == uart->dma_rx->save_descriptor))
+ {
+ /* set error code */
+ err_code = -RT_EEMPTY;
+ }
+ else
+ {
+ /* read data */
+ while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+ {
+ /* read buffer */
+ *ptr ++ = uart->dma_rx->
+ rx_buffer[uart->dma_rx->read_descriptor][uart->dma_rx->read_index];
+
+ /* move to next position */
+ uart->dma_rx->read_index ++;
+
+ /* wrap read index */
+ if (uart->dma_rx->read_index >= UART_DMA_RX_BUFFER_SIZE)
+ {
+ /* wrap read index */
+ uart->dma_rx->read_index = 0;
+
+ /* move to next read descriptor */
+ uart->dma_rx->read_descriptor ++;
+ /* wrap read descriptor */
+ if (uart->dma_rx->read_descriptor >= UART_DMA_RX_DESCRIPTOR)
+ uart->dma_rx->read_descriptor = 0;
+
+ if (uart->dma_rx->is_full == RT_TRUE)
+ {
+ rt_uint32_t level;
+
+ level = rt_hw_interrupt_disable();
+ uart->dma_rx->save_descriptor ++;
+ if (uart->dma_rx->save_descriptor >= UART_DMA_RX_DESCRIPTOR)
+ uart->dma_rx->save_descriptor = 0;
+ rt_hw_interrupt_enable(level);
+
+ /* re-enable DMA to receive */
+ rt_serial_enable_dma(uart->dma_rx->dma_channel,
+ (rt_uint32_t)&(uart->dma_rx->rx_buffer[uart->dma_rx->save_descriptor][0]),
+ UART_DMA_RX_BUFFER_SIZE);
+ }
+
+ /* check queue empty */
+ if ((uart->dma_rx->read_descriptor == uart->dma_rx->save_descriptor))
+ {
+ /* set error code */
+ err_code = -RT_EEMPTY;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* polling mode */
+ while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+ {
+ while (uart->uart_device->SR & USART_FLAG_RXNE)
+ {
+ *ptr = uart->uart_device->DR & 0xff;
+ ptr ++;
+ }
+ }
+ }
+
+ /* set error code */
+ rt_set_errno(err_code);
+ return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+}
+
+static void rt_serial_enable_dma(DMA_Channel_TypeDef* dma_channel,
+ rt_uint32_t address, rt_uint32_t size)
+{
+ RT_ASSERT(dma_channel != RT_NULL);
+
+ /* disable DMA */
+ DMA_Cmd(dma_channel, DISABLE);
+
+ /* set buffer address */
+ dma_channel->CMAR = address;
+ /* set size */
+ dma_channel->CNDTR = size;
+
+ /* enable DMA */
+ DMA_Cmd(dma_channel, ENABLE);
+}
+
+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 stm32_serial_device* uart;
+
+ err_code = RT_EOK;
+ ptr = (rt_uint8_t*)buffer;
+ uart = (struct stm32_serial_device*)dev->private;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+ {
+ /* interrupt mode Tx */
+ while (uart->int_tx->save_index != uart->int_tx->write_index)
+ {
+ /* save on tx buffer */
+ uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
+
+ -- size;
+
+ /* move to next position */
+ uart->int_tx->save_index ++;
+
+ /* wrap save index */
+ if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
+ uart->int_tx->save_index = 0;
+ }
+
+ /* set error code */
+ if (size > 0)
+ err_code = -RT_EFULL;
+ }
+ else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+ {
+ /* DMA mode Tx */
+
+ /* allocate a data node */
+ struct stm32_serial_data_node* data_node =
+ (struct stm32_serial_data_node*) rt_malloc (sizeof(struct stm32_serial_data_node));
+ if (data_node == RT_NULL)
+ {
+ /* set error code */
+ err_code = -RT_ENOMEM;
+ }
+ else
+ {
+ rt_uint32_t level;
+
+ /* fill data node */
+ data_node->data_ptr = ptr;
+ data_node->data_size = size;
+
+ /* insert to data link */
+ data_node->next = RT_NULL;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ data_node->prev = uart->dma_tx->list_tail;
+ if (uart->dma_tx->list_tail != RT_NULL)
+ uart->dma_tx->list_tail->next = data_node;
+ uart->dma_tx->list_tail = data_node;
+
+ if (uart->dma_tx->list_head == RT_NULL)
+ {
+ /* start DMA to transmit data */
+ uart->dma_tx->list_head = data_node;
+
+ /* Enable DMA Channel */
+ rt_serial_enable_dma(uart->dma_tx->dma_channel,
+ (rt_uint32_t)uart->dma_tx->list_head->data_ptr,
+ uart->dma_tx->list_head->data_size);
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ }
+ }
+ else
+ {
+ /* polling mode */
+ while (size)
+ {
+ rt_serial_putc(dev, *ptr);
+ ++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 stm32_serial_device* uart;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ uart = (struct stm32_serial_device*)dev->private;
+ switch (cmd)
+ {
+ case RT_DEVICE_CTRL_SUSPEND:
+ /* suspend device */
+ dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
+ USART_Cmd(uart->uart_device, DISABLE);
+ break;
+
+ case RT_DEVICE_CTRL_RESUME:
+ /* resume device */
+ dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
+ USART_Cmd(uart->uart_device, ENABLE);
+ 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 stm32_serial_device *serial)
+{
+ RT_ASSERT(device != RT_NULL);
+
+ 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(rt_device_t device)
+{
+ struct stm32_serial_device* uart = (struct stm32_serial_device*) device->private;
+
+ if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
+ {
+ /* interrupt mode receive */
+ RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
+
+ /* save on rx buffer */
+ while (uart->uart_device->SR & USART_FLAG_RXNE)
+ {
+ rt_serial_savechar(uart, uart->uart_device->DR & 0xff);
+ }
+
+ /* clear interrupt */
+ USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
+
+ /* invoke callback */
+ if (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;
+
+ device->rx_indicate(device, rx_length);
+ }
+ }
+
+ if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
+ {
+ /* interrupt mode transmission */
+ RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_TX);
+
+ /* transmission completed */
+ uart->int_tx->write_index ++;
+ if (uart->int_tx->write_index >= UART_TX_BUFFER_SIZE)
+ uart->int_tx->write_index = 0;
+
+ /* clear interrupt */
+ USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
+
+ /* start next transmission */
+ if (uart->int_tx->write_index <
+ uart->int_tx->save_index)
+ {
+ uart->uart_device->DR = uart->int_tx
+ ->tx_buffer[uart->int_tx->write_index];
+ }
+ }
+}
+
+/*
+ * ISR for DMA mode Rx
+ */
+void rt_hw_serial_dma_rx_isr(rt_device_t device)
+{
+ rt_uint32_t next_descriptor;
+ struct stm32_serial_device* uart = (struct stm32_serial_device*) device->private;
+
+ /* DMA mode receive */
+ RT_ASSERT(device->flag & RT_DEVICE_FLAG_DMA_RX);
+
+ /* invoke callback */
+ if (device->rx_indicate != RT_NULL)
+ device->rx_indicate(device, UART_DMA_RX_BUFFER_SIZE);
+
+ next_descriptor = uart->dma_rx->save_descriptor;
+
+ /* move to next descriptor */
+ next_descriptor ++;
+ if (next_descriptor >= UART_DMA_RX_DESCRIPTOR)
+ next_descriptor = 0;
+
+ if (next_descriptor != uart->dma_rx->read_descriptor)
+ {
+ uart->dma_rx->save_descriptor = next_descriptor;
+ /* enable next DMA */
+ rt_serial_enable_dma(uart->dma_rx->dma_channel,
+ (rt_uint32_t)&(uart->dma_rx->rx_buffer[uart->dma_rx->save_descriptor][0]),
+ UART_DMA_RX_BUFFER_SIZE);
+ }
+ else
+ {
+ /* no descriptor yet, disable DMA */
+ DMA_Cmd(uart->dma_rx->dma_channel, DISABLE);
+ uart->dma_rx->is_full = RT_TRUE;
+ }
+}
+
+/*
+ * ISR for DMA mode Tx
+ */
+void rt_hw_serial_dma_tx_isr(rt_device_t device)
+{
+ rt_uint32_t level;
+ struct stm32_serial_data_node* data_node;
+ struct stm32_serial_device* uart = (struct stm32_serial_device*) device->private;
+
+ /* DMA mode receive */
+ RT_ASSERT(device->flag & RT_DEVICE_FLAG_DMA_TX);
+
+ /* get the first data node */
+ data_node = uart->dma_tx->list_head;
+ RT_ASSERT(data_node != RT_NULL);
+
+ /* invoke call to notify tx complete */
+ if (device->tx_complete != RT_NULL)
+ device->tx_complete(device, data_node->data_ptr);
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ /* remove list tail */
+ uart->dma_tx->list_tail = data_node->prev;
+ if (uart->dma_tx->list_tail == RT_NULL)
+ uart->dma_tx->list_head = RT_NULL;
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ /* free data node memory */
+ rt_free(data_node);
+
+ if (uart->dma_tx->list_tail != RT_NULL)
+ {
+ /* transmit next data node */
+ rt_serial_enable_dma(uart->dma_tx->dma_channel,
+ (rt_uint32_t)uart->dma_tx->list_tail->data_ptr,
+ uart->dma_tx->list_tail->data_size);
+ }
+ else
+ {
+ /* no data to be transmitted, disable DMA */
+ DMA_Cmd(uart->dma_tx->dma_channel, DISABLE);
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/stm32/serial.h b/libcpu/arm/stm32/serial.h
new file mode 100644
index 0000000000..a36cad79a2
--- /dev/null
+++ b/libcpu/arm/stm32/serial.h
@@ -0,0 +1,69 @@
+#ifndef __RT_HW_SERIAL_H__
+#define __RT_HW_SERIAL_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+/* STM32F10x library definitions */
+#include <stm32f10x_lib.h>
+
+#define UART_DMA_RX_DESCRIPTOR 2
+#define UART_DMA_RX_BUFFER_SIZE 16
+
+#define UART_RX_BUFFER_SIZE 64
+#define UART_TX_BUFFER_SIZE 64
+
+struct stm32_serial_dma_rx
+{
+ DMA_Channel_TypeDef* dma_channel;
+ rt_uint8_t rx_buffer[UART_DMA_RX_DESCRIPTOR][UART_RX_BUFFER_SIZE];
+ rt_uint32_t save_descriptor;
+ rt_uint32_t read_index, read_descriptor;
+ rt_bool_t is_full;
+};
+
+/* data node for Tx Mode */
+struct stm32_serial_data_node
+{
+ rt_uint8_t *data_ptr;
+ rt_size_t data_size;
+ struct stm32_serial_data_node *next, *prev;
+};
+struct stm32_serial_dma_tx
+{
+ DMA_Channel_TypeDef* dma_channel;
+ struct stm32_serial_data_node *list_head, *list_tail;
+};
+
+struct stm32_serial_int_rx
+{
+ rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
+ rt_uint32_t read_index, save_index;
+};
+
+struct stm32_serial_int_tx
+{
+ rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE];
+ rt_uint32_t write_index, save_index;
+};
+
+struct stm32_serial_device
+{
+ USART_TypeDef* uart_device;
+
+ /* rx structure */
+ struct stm32_serial_int_rx* int_rx;
+ struct stm32_serial_dma_rx* dma_rx;
+
+ /* tx structure */
+ struct stm32_serial_int_tx* int_tx;
+ struct stm32_serial_dma_tx* dma_tx;
+};
+
+rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct stm32_serial_device *serial);
+
+void rt_hw_serial_isr(rt_device_t device);
+void rt_hw_serial_dma_rx_isr(rt_device_t device);
+void rt_hw_serial_dma_tx_isr(rt_device_t device);
+
+#endif
diff --git a/libcpu/arm/stm32/stack.c b/libcpu/arm/stm32/stack.c
new file mode 100644
index 0000000000..c7f8c71ab4
--- /dev/null
+++ b/libcpu/arm/stm32/stack.c
@@ -0,0 +1,59 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 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://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard the first version
+ */
+#include <rtthread.h>
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+/**
+ * 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) = 0x01000000L; /* PSR */
+ *(--stk) = (unsigned long)tentry; /* entry point, pc */
+ *(--stk) = (unsigned long)texit; /* lr */
+ *(--stk) = 0; /* r12 */
+ *(--stk) = 0; /* r3 */
+ *(--stk) = 0; /* r2 */
+ *(--stk) = 0; /* r1 */
+ *(--stk) = (unsigned long)parameter; /* r0 : argument */
+
+ *(--stk) = 0; /* r11 */
+ *(--stk) = 0; /* r10 */
+ *(--stk) = 0; /* r9 */
+ *(--stk) = 0; /* r8 */
+ *(--stk) = 0; /* r7 */
+ *(--stk) = 0; /* r6 */
+ *(--stk) = 0; /* r5 */
+ *(--stk) = 0; /* r4 */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/stm32/start_iar.c b/libcpu/arm/stm32/start_iar.c
new file mode 100644
index 0000000000..3cc01ed9e8
--- /dev/null
+++ b/libcpu/arm/stm32/start_iar.c
@@ -0,0 +1,176 @@
+/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
+* File Name : stm32f10x_vector.c
+* Author : MCD Application Team
+* Version : V2.0.3
+* Date : 09/22/2008
+* Description : STM32F10x vector table for EWARM5.x toolchain.
+* This module performs:
+* - Set the initial SP
+* - Set the initial PC == __iar_program_start,
+* - Set the vector table entries with the exceptions ISR address,
+* - Configure external SRAM mounted on STM3210E-EVAL board
+* to be used as data memory (optional, to be enabled by user)
+* After Reset the Cortex-M3 processor is in Thread mode,
+* priority is Privileged, and the Stack is set to Main.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_lib.h"
+#include "stm32f10x_it.h"
+
+/* Private typedef -----------------------------------------------------------*/
+typedef void( *intfunc )( void );
+typedef union { intfunc __fun; void * __ptr; } intvec_elem;
+
+/* Private define ------------------------------------------------------------*/
+/* Uncomment the following line if you need to use external SRAM mounted on
+ STM3210E-EVAL board as data memory */
+/* #define DATA_IN_ExtSRAM */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+
+#pragma language=extended
+#pragma segment="CSTACK"
+
+void __iar_program_start( void );
+
+#pragma location = ".intvec"
+/* STM32F10x Vector Table entries */
+const intvec_elem __vector_table[] =
+{
+ { .__ptr = __sfe( "CSTACK" ) },
+ __iar_program_start,
+ NMIException,
+ HardFaultException,
+ MemManageException,
+ BusFaultException,
+ UsageFaultException,
+ 0, 0, 0, 0, /* Reserved */
+ SVCHandler,
+ DebugMonitor,
+ 0, /* Reserved */
+ rt_hw_pend_sv,
+ SysTickHandler,
+ WWDG_IRQHandler,
+ PVD_IRQHandler,
+ TAMPER_IRQHandler,
+ RTC_IRQHandler,
+ FLASH_IRQHandler,
+ RCC_IRQHandler,
+ EXTI0_IRQHandler,
+ EXTI1_IRQHandler,
+ EXTI2_IRQHandler,
+ EXTI3_IRQHandler,
+ EXTI4_IRQHandler,
+ DMA1_Channel1_IRQHandler,
+ DMA1_Channel2_IRQHandler,
+ DMA1_Channel3_IRQHandler,
+ DMA1_Channel4_IRQHandler,
+ DMA1_Channel5_IRQHandler,
+ DMA1_Channel6_IRQHandler,
+ DMA1_Channel7_IRQHandler,
+ ADC1_2_IRQHandler,
+ USB_HP_CAN_TX_IRQHandler,
+ USB_LP_CAN_RX0_IRQHandler,
+ CAN_RX1_IRQHandler,
+ CAN_SCE_IRQHandler,
+ EXTI9_5_IRQHandler,
+ TIM1_BRK_IRQHandler,
+ TIM1_UP_IRQHandler,
+ TIM1_TRG_COM_IRQHandler,
+ TIM1_CC_IRQHandler,
+ TIM2_IRQHandler,
+ TIM3_IRQHandler,
+ TIM4_IRQHandler,
+ I2C1_EV_IRQHandler,
+ I2C1_ER_IRQHandler,
+ I2C2_EV_IRQHandler,
+ I2C2_ER_IRQHandler,
+ SPI1_IRQHandler,
+ SPI2_IRQHandler,
+ USART1_IRQHandler,
+ USART2_IRQHandler,
+ USART3_IRQHandler,
+ EXTI15_10_IRQHandler,
+ RTCAlarm_IRQHandler,
+ USBWakeUp_IRQHandler,
+ TIM8_BRK_IRQHandler,
+ TIM8_UP_IRQHandler,
+ TIM8_TRG_COM_IRQHandler,
+ TIM8_CC_IRQHandler,
+ ADC3_IRQHandler,
+ FSMC_IRQHandler,
+ SDIO_IRQHandler,
+ TIM5_IRQHandler,
+ SPI3_IRQHandler,
+ UART4_IRQHandler,
+ UART5_IRQHandler,
+ TIM6_IRQHandler,
+ TIM7_IRQHandler,
+ DMA2_Channel1_IRQHandler,
+ DMA2_Channel2_IRQHandler,
+ DMA2_Channel3_IRQHandler,
+ DMA2_Channel4_5_IRQHandler,
+};
+
+#ifdef DATA_IN_ExtSRAM
+#pragma language=extended
+
+__interwork int __low_level_init(void);
+
+#pragma location="ICODE"
+__interwork int __low_level_init(void)
+{
+
+/* FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
+ required, then adjust the Register Addresses*/
+
+ /* Enable FSMC clock */
+ *(vu32 *)0x40021014 = 0x00000114;
+
+ /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
+ *(vu32 *)0x40021018 = 0x000001E0;
+
+/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
+/*---------------- SRAM Address lines configuration -------------------------*/
+/*---------------- NOE and NWE configuration --------------------------------*/
+/*---------------- NE3 configuration ----------------------------------------*/
+/*---------------- NBL0, NBL1 configuration ---------------------------------*/
+
+ *(vu32 *)0x40011400 = 0x44BB44BB;
+ *(vu32 *)0x40011404 = 0xBBBBBBBB;
+
+ *(vu32 *)0x40011800 = 0xB44444BB;
+ *(vu32 *)0x40011804 = 0xBBBBBBBB;
+
+ *(vu32 *)0x40011C00 = 0x44BBBBBB;
+ *(vu32 *)0x40011C04 = 0xBBBB4444;
+
+ *(vu32 *)0x40012000 = 0x44BBBBBB;
+ *(vu32 *)0x40012004 = 0x44444B44;
+
+/*---------------- FSMC Configuration ---------------------------------------*/
+/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
+
+ *(vu32 *)0xA0000010 = 0x00001011;
+ *(vu32 *)0xA0000014 = 0x00000200;
+
+
+ return (1);
+}
+#endif /*DATA_IN_ExtSRAM*/
+
+/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
+
+
diff --git a/libcpu/arm/stm32/start_rvds.s b/libcpu/arm/stm32/start_rvds.s
new file mode 100644
index 0000000000..ec9419fe07
--- /dev/null
+++ b/libcpu/arm/stm32/start_rvds.s
@@ -0,0 +1,250 @@
+;******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
+;* File Name : stm32f10x_vector.s
+;* Author : MCD Application Team
+;* Version : V1.1.2
+;* Date : 09/22/2008
+;* Description : STM32F10x vector table for RVMDK toolchain.
+;* This module performs:
+;* - Set the initial SP
+;* - Set the initial PC == Reset_Handler
+;* - Set the vector table entries with the exceptions ISR address
+;* - Configure external SRAM mounted on STM3210E-EVAL board
+;* to be used as data memory (optional, to be enabled by user)
+;* - Branches to __main in the C library (which eventually
+;* calls main()).
+;* After Reset the CortexM3 processor is in Thread mode,
+;* priority is Privileged, and the Stack is set to Main.
+;* <<< Use Configuration Wizard in Context Menu >>>
+;*******************************************************************************
+; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+;*******************************************************************************
+
+; Amount of memory (in bytes) allocated for Stack
+; Tailor this value to your application needs
+;// <h> Stack Configuration
+;// <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;// </h>
+Stack_Size EQU 0x00000200
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+Stack_Mem SPACE Stack_Size
+
+__initial_sp
+; If you need to use external SRAM mounted on STM3210E-EVAL board as data memory
+; and internal SRAM for Stack, uncomment the following line and comment the line above
+;__initial_sp EQU 0x20000000 + Stack_Size ; "Use MicroLIB" must be checked in
+ ; the Project->Options->Target window
+
+; Amount of memory (in bytes) allocated for Heap
+; Tailor this value to your application needs
+;// <h> Heap Configuration
+;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;// </h>
+
+Heap_Size EQU 0x00000000
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+ THUMB
+ PRESERVE8
+
+ ; Import exceptions handlers
+ IMPORT NMIException
+ IMPORT rt_hw_hard_fault
+ IMPORT MemManageException
+ IMPORT BusFaultException
+ IMPORT UsageFaultException
+ IMPORT SVCHandler
+ IMPORT DebugMonitor
+ IMPORT rt_hw_pend_sv
+ IMPORT SysTickHandler
+ IMPORT WWDG_IRQHandler
+ IMPORT PVD_IRQHandler
+ IMPORT TAMPER_IRQHandler
+ IMPORT RTC_IRQHandler
+ IMPORT FLASH_IRQHandler
+ IMPORT RCC_IRQHandler
+ IMPORT EXTI0_IRQHandler
+ IMPORT EXTI1_IRQHandler
+ IMPORT EXTI2_IRQHandler
+ IMPORT EXTI3_IRQHandler
+ IMPORT EXTI4_IRQHandler
+ IMPORT DMA1_Channel1_IRQHandler
+ IMPORT DMA1_Channel2_IRQHandler
+ IMPORT DMA1_Channel3_IRQHandler
+ IMPORT DMA1_Channel4_IRQHandler
+ IMPORT DMA1_Channel5_IRQHandler
+ IMPORT DMA1_Channel6_IRQHandler
+ IMPORT DMA1_Channel7_IRQHandler
+ IMPORT ADC1_2_IRQHandler
+ IMPORT USB_HP_CAN_TX_IRQHandler
+ IMPORT USB_LP_CAN_RX0_IRQHandler
+ IMPORT CAN_RX1_IRQHandler
+ IMPORT CAN_SCE_IRQHandler
+ IMPORT EXTI9_5_IRQHandler
+ IMPORT TIM1_BRK_IRQHandler
+ IMPORT TIM1_UP_IRQHandler
+ IMPORT TIM1_TRG_COM_IRQHandler
+ IMPORT TIM1_CC_IRQHandler
+ IMPORT TIM2_IRQHandler
+ IMPORT TIM3_IRQHandler
+ IMPORT TIM4_IRQHandler
+ IMPORT I2C1_EV_IRQHandler
+ IMPORT I2C1_ER_IRQHandler
+ IMPORT I2C2_EV_IRQHandler
+ IMPORT I2C2_ER_IRQHandler
+ IMPORT SPI1_IRQHandler
+ IMPORT SPI2_IRQHandler
+ IMPORT USART1_IRQHandler
+ IMPORT USART2_IRQHandler
+ IMPORT USART3_IRQHandler
+ IMPORT EXTI15_10_IRQHandler
+ IMPORT RTCAlarm_IRQHandler
+ IMPORT USBWakeUp_IRQHandler
+ IMPORT TIM8_BRK_IRQHandler
+ IMPORT TIM8_UP_IRQHandler
+ IMPORT TIM8_TRG_COM_IRQHandler
+ IMPORT TIM8_CC_IRQHandler
+ IMPORT ADC3_IRQHandler
+ IMPORT FSMC_IRQHandler
+ IMPORT SDIO_IRQHandler
+ IMPORT TIM5_IRQHandler
+ IMPORT SPI3_IRQHandler
+ IMPORT UART4_IRQHandler
+ IMPORT UART5_IRQHandler
+ IMPORT TIM6_IRQHandler
+ IMPORT TIM7_IRQHandler
+ IMPORT DMA2_Channel1_IRQHandler
+ IMPORT DMA2_Channel2_IRQHandler
+ IMPORT DMA2_Channel3_IRQHandler
+ IMPORT DMA2_Channel4_5_IRQHandler
+
+;*******************************************************************************
+; Fill-up the Vector Table entries with the exceptions ISR address
+;*******************************************************************************
+ AREA RESET, DATA, READONLY
+ EXPORT __Vectors
+
+__Vectors DCD __initial_sp ; Top of Stack
+ DCD Reset_Handler
+ DCD NMIException
+ DCD rt_hw_hard_fault
+ DCD MemManageException
+ DCD BusFaultException
+ DCD UsageFaultException
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD 0 ; Reserved
+ DCD SVCHandler
+ DCD DebugMonitor
+ DCD 0 ; Reserved
+ DCD rt_hw_pend_sv
+ DCD SysTickHandler
+ DCD WWDG_IRQHandler
+ DCD PVD_IRQHandler
+ DCD TAMPER_IRQHandler
+ DCD RTC_IRQHandler
+ DCD FLASH_IRQHandler
+ DCD RCC_IRQHandler
+ DCD EXTI0_IRQHandler
+ DCD EXTI1_IRQHandler
+ DCD EXTI2_IRQHandler
+ DCD EXTI3_IRQHandler
+ DCD EXTI4_IRQHandler
+ DCD DMA1_Channel1_IRQHandler
+ DCD DMA1_Channel2_IRQHandler
+ DCD DMA1_Channel3_IRQHandler
+ DCD DMA1_Channel4_IRQHandler
+ DCD DMA1_Channel5_IRQHandler
+ DCD DMA1_Channel6_IRQHandler
+ DCD DMA1_Channel7_IRQHandler
+ DCD ADC1_2_IRQHandler
+ DCD USB_HP_CAN_TX_IRQHandler
+ DCD USB_LP_CAN_RX0_IRQHandler
+ DCD CAN_RX1_IRQHandler
+ DCD CAN_SCE_IRQHandler
+ DCD EXTI9_5_IRQHandler
+ DCD TIM1_BRK_IRQHandler
+ DCD TIM1_UP_IRQHandler
+ DCD TIM1_TRG_COM_IRQHandler
+ DCD TIM1_CC_IRQHandler
+ DCD TIM2_IRQHandler
+ DCD TIM3_IRQHandler
+ DCD TIM4_IRQHandler
+ DCD I2C1_EV_IRQHandler
+ DCD I2C1_ER_IRQHandler
+ DCD I2C2_EV_IRQHandler
+ DCD I2C2_ER_IRQHandler
+ DCD SPI1_IRQHandler
+ DCD SPI2_IRQHandler
+ DCD USART1_IRQHandler
+ DCD USART2_IRQHandler
+ DCD USART3_IRQHandler
+ DCD EXTI15_10_IRQHandler
+ DCD RTCAlarm_IRQHandler
+ DCD USBWakeUp_IRQHandler
+ DCD TIM8_BRK_IRQHandler
+ DCD TIM8_UP_IRQHandler
+ DCD TIM8_TRG_COM_IRQHandler
+ DCD TIM8_CC_IRQHandler
+ DCD ADC3_IRQHandler
+ DCD FSMC_IRQHandler
+ DCD SDIO_IRQHandler
+ DCD TIM5_IRQHandler
+ DCD SPI3_IRQHandler
+ DCD UART4_IRQHandler
+ DCD UART5_IRQHandler
+ DCD TIM6_IRQHandler
+ DCD TIM7_IRQHandler
+ DCD DMA2_Channel1_IRQHandler
+ DCD DMA2_Channel2_IRQHandler
+ DCD DMA2_Channel3_IRQHandler
+ DCD DMA2_Channel4_5_IRQHandler
+
+ AREA |.text|, CODE, READONLY
+
+; Reset handler routine
+Reset_Handler PROC
+ EXPORT Reset_Handler
+
+ IMPORT __main
+ LDR R0, =__main
+ BX R0
+ ENDP
+
+ ALIGN
+
+;*******************************************************************************
+; User Stack and Heap initialization
+;*******************************************************************************
+ IF :DEF:__MICROLIB
+ EXPORT __initial_sp
+ EXPORT __heap_base
+ EXPORT __heap_limit
+ ELSE
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+
+__user_initial_stackheap
+ LDR R0, = Heap_Mem
+ LDR R1, = (Stack_Mem + Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+
+ ALIGN
+
+ ENDIF
+
+ END
+
+;******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE*****