summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwuyangyong <[email protected]>2011-10-27 02:31:34 +0000
committerwuyangyong <[email protected]>2011-10-27 02:31:34 +0000
commita5f688d282b7526e22397219f43ae1d6c98598df (patch)
treef730653a20956c98599705fb82b305a70e001d43
parent8e7398e01094cfdede1090d36815baab9a425a7e (diff)
update stm32f40x bsp
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1774 bbd45198-f89e-11dd-88c7-29a3b14d5316
-rw-r--r--bsp/stm32f40x/applications/SConscript11
-rw-r--r--bsp/stm32f40x/applications/application.c145
-rw-r--r--bsp/stm32f40x/applications/startup.c131
-rw-r--r--bsp/stm32f40x/drivers/SConscript11
-rw-r--r--bsp/stm32f40x/drivers/board.c100
-rw-r--r--bsp/stm32f40x/drivers/board.h68
-rw-r--r--bsp/stm32f40x/drivers/serial.c419
-rw-r--r--bsp/stm32f40x/drivers/serial.h72
-rw-r--r--bsp/stm32f40x/drivers/stm32f4xx_conf.h94
-rw-r--r--bsp/stm32f40x/drivers/stm32f4xx_it.c184
-rw-r--r--bsp/stm32f40x/drivers/usart.c317
-rw-r--r--bsp/stm32f40x/drivers/usart.h23
12 files changed, 1575 insertions, 0 deletions
diff --git a/bsp/stm32f40x/applications/SConscript b/bsp/stm32f40x/applications/SConscript
new file mode 100644
index 0000000000..591734409c
--- /dev/null
+++ b/bsp/stm32f40x/applications/SConscript
@@ -0,0 +1,11 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = os.path.join(str(Dir('#')), 'applications')
+src = Glob('*.c')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/stm32f40x/applications/application.c b/bsp/stm32f40x/applications/application.c
new file mode 100644
index 0000000000..cc424ab857
--- /dev/null
+++ b/bsp/stm32f40x/applications/application.c
@@ -0,0 +1,145 @@
+/*
+ * File : application.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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-05 Bernard the first version
+ */
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+#include "stm32f4xx.h"
+#include <board.h>
+#include <rtthread.h>
+
+#ifdef RT_USING_LWIP
+#include <lwip/sys.h>
+#include <lwip/api.h>
+#include <netif/ethernetif.h>
+#include "stm32_eth.h"
+#endif
+
+void rt_init_thread_entry(void* parameter)
+{
+ /* LwIP Initialization */
+#ifdef RT_USING_LWIP
+ {
+ extern void lwip_sys_init(void);
+
+ /* register ethernetif device */
+ eth_system_device_init();
+
+ rt_hw_stm32_eth_init();
+ /* re-init device driver */
+ rt_device_init_all();
+
+ /* init lwip system */
+ lwip_sys_init();
+ rt_kprintf("TCP/IP initialized!\n");
+ }
+
+ {
+ extern void eth_to_can_init(void);
+ extern void can_to_eth_init(void);
+ extern void upnp_init(void);
+ extern void setting_init(void);
+
+ setting_init();
+ eth_to_can_init();
+ can_to_eth_init();
+ upnp_init();
+ }
+#endif
+}
+
+ALIGN(RT_ALIGN_SIZE)
+static char thread_led_stack[1024];
+struct rt_thread thread_led;
+static void rt_thread_entry_led(void* parameter)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ /* GPIOD Periph clock enable */
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
+
+ /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ while (1)
+ {
+ /* PD12 to be toggled */
+ GPIO_SetBits(GPIOD, GPIO_Pin_12);
+
+ /* Insert delay */
+ rt_thread_delay(RT_TICK_PER_SECOND/2);
+
+ /* PD13 to be toggled */
+ GPIO_SetBits(GPIOD, GPIO_Pin_13);
+
+ /* Insert delay */
+ rt_thread_delay(RT_TICK_PER_SECOND/2);
+
+ /* PD14 to be toggled */
+ GPIO_SetBits(GPIOD, GPIO_Pin_14);
+
+ /* Insert delay */
+ rt_thread_delay(RT_TICK_PER_SECOND/2);
+
+ /* PD15 to be toggled */
+ GPIO_SetBits(GPIOD, GPIO_Pin_15);
+
+ /* Insert delay */
+ rt_thread_delay(RT_TICK_PER_SECOND*2);
+
+ GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
+
+ /* Insert delay */
+ rt_thread_delay(RT_TICK_PER_SECOND);
+ }
+}
+
+int rt_application_init()
+{
+// rt_thread_t init_thread;
+//
+//#if (RT_THREAD_PRIORITY_MAX == 32)
+// init_thread = rt_thread_create("init",
+// rt_init_thread_entry, RT_NULL,
+// 2048, 8, 20);
+//#else
+// init_thread = rt_thread_create("init",
+// rt_init_thread_entry, RT_NULL,
+// 2048, 80, 20);
+//#endif
+//
+// if (init_thread != RT_NULL)
+// rt_thread_startup(init_thread);
+
+ //------- init led1 thread
+ rt_thread_init(&thread_led,
+ "led",
+ rt_thread_entry_led,
+ RT_NULL,
+ &thread_led_stack[0],
+ 1024,11,5);
+// sizeof(thread_led_stack),11,5);
+ rt_thread_startup(&thread_led);
+
+ return 0;
+}
+
+/*@}*/
diff --git a/bsp/stm32f40x/applications/startup.c b/bsp/stm32f40x/applications/startup.c
new file mode 100644
index 0000000000..04ecf32026
--- /dev/null
+++ b/bsp/stm32f40x/applications/startup.c
@@ -0,0 +1,131 @@
+/*
+ * File : startup.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-08-31 Bernard first implementation
+ * 2011-06-05 Bernard modify for STM32F107 version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "stm32f4xx.h"
+#include "board.h"
+
+/**
+ * @addtogroup STM32
+ */
+
+/*@{*/
+
+extern int rt_application_init(void);
+#ifdef RT_USING_FINSH
+extern void finsh_system_init(void);
+extern void finsh_set_device(const char* device);
+#endif
+
+#ifdef __CC_ARM
+//extern int Image$$RW_IRAM1$$ZI$$Limit;
+extern int Image$$ER_ZI$$ZI$$Limit;
+#elif __ICCARM__
+#pragma section="HEAP"
+#else
+extern int __bss_end;
+#endif
+
+/*******************************************************************************
+* Function Name : assert_failed
+* Description : Reports the name of the source file and the source line number
+* where the assert error has occurred.
+* Input : - file: pointer to the source file name
+* - line: assert error line source number
+* Output : None
+* Return : None
+*******************************************************************************/
+void assert_failed(u8* file, u32 line)
+{
+ rt_kprintf("\n\r Wrong parameter value detected on\r\n");
+ rt_kprintf(" file %s\r\n", file);
+ rt_kprintf(" line %d\r\n", line);
+
+ while (1) ;
+}
+
+/**
+ * This function will startup RT-Thread RTOS.
+ */
+void rtthread_startup(void)
+{
+ /* init board */
+ rt_hw_board_init();
+
+ /* show version */
+ rt_show_version();
+
+ /* init tick */
+ rt_system_tick_init();
+
+ /* init kernel object */
+ rt_system_object_init();
+
+ /* init timer system */
+ rt_system_timer_init();
+
+#ifdef RT_USING_HEAP
+ #ifdef __CC_ARM
+ rt_system_heap_init((void*)&Image$$ER_ZI$$ZI$$Limit, (void*)STM32_SRAM_END);
+ #elif __ICCARM__
+ rt_system_heap_init(__segment_end("HEAP"), (void*)STM32_SRAM_END);
+ #else
+ /* init memory system */
+ rt_system_heap_init((void*)&__bss_end, (void*)STM32_SRAM_END);
+ #endif
+#endif
+
+ /* init scheduler system */
+ rt_system_scheduler_init();
+
+ /* init all device */
+ rt_device_init_all();
+
+ /* init application */
+ rt_application_init();
+
+#ifdef RT_USING_FINSH
+ /* init finsh */
+ finsh_system_init();
+ finsh_set_device( FINSH_DEVICE_NAME );
+#endif
+
+ /* init timer thread */
+ rt_system_timer_thread_init();
+
+ /* init idle thread */
+ rt_thread_idle_init();
+
+ /* start scheduler */
+ rt_system_scheduler_start();
+
+ /* never reach here */
+ return ;
+}
+
+int main(void)
+{
+ /* disable interrupt first */
+ rt_hw_interrupt_disable();
+
+ /* startup RT-Thread RTOS */
+ rtthread_startup();
+
+ return 0;
+}
+
+/*@}*/
diff --git a/bsp/stm32f40x/drivers/SConscript b/bsp/stm32f40x/drivers/SConscript
new file mode 100644
index 0000000000..ef01580e52
--- /dev/null
+++ b/bsp/stm32f40x/drivers/SConscript
@@ -0,0 +1,11 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = os.path.join(str(Dir('#')), 'drivers')
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/stm32f40x/drivers/board.c b/bsp/stm32f40x/drivers/board.c
new file mode 100644
index 0000000000..f23172dea9
--- /dev/null
+++ b/bsp/stm32f40x/drivers/board.c
@@ -0,0 +1,100 @@
+/*
+ * File : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009 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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-05 Bernard first implementation
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "stm32f4xx.h"
+#include "board.h"
+
+/**
+ * @addtogroup STM32
+ */
+
+/*@{*/
+
+/*******************************************************************************
+* Function Name : NVIC_Configuration
+* Description : Configures Vector Table base location.
+* Input : None
+* Output : None
+* Return : None
+*******************************************************************************/
+void NVIC_Configuration(void)
+{
+#ifdef VECT_TAB_RAM
+ /* Set the Vector Table base location at 0x20000000 */
+ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
+#else /* VECT_TAB_FLASH */
+ /* Set the Vector Table base location at 0x08000000 */
+ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
+#endif
+
+ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
+}
+
+/*******************************************************************************
+ * Function Name : SysTick_Configuration
+ * Description : Configures the SysTick for OS tick.
+ * Input : None
+ * Output : None
+ * Return : None
+ *******************************************************************************/
+void SysTick_Configuration(void)
+{
+ RCC_ClocksTypeDef rcc_clocks;
+ rt_uint32_t cnts;
+
+ RCC_GetClocksFreq(&rcc_clocks);
+
+ cnts = (rt_uint32_t)rcc_clocks.HCLK_Frequency / RT_TICK_PER_SECOND;
+ cnts = cnts / 8;
+
+ SysTick_Config(cnts);
+ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
+}
+
+/**
+ * This is the timer interrupt service routine.
+ *
+ */
+void SysTick_Handler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ rt_tick_increase();
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+/**
+ * This function will initial STM32 board.
+ */
+void rt_hw_board_init()
+{
+ /* NVIC Configuration */
+ NVIC_Configuration();
+
+ /* Configure the SysTick */
+ SysTick_Configuration();
+
+ rt_hw_usart_init();
+#ifdef RT_USING_CONSOLE
+ rt_console_set_device(CONSOLE_DEVICE);
+#endif
+}
+
+/*@}*/
diff --git a/bsp/stm32f40x/drivers/board.h b/bsp/stm32f40x/drivers/board.h
new file mode 100644
index 0000000000..2df191588c
--- /dev/null
+++ b/bsp/stm32f40x/drivers/board.h
@@ -0,0 +1,68 @@
+/*
+ * File : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, 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-09-22 Bernard add board.h to this bsp
+ */
+
+// <<< Use Configuration Wizard in Context Menu >>>
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+/* board configuration */
+// <o> SDCard Driver <1=>SDIO sdcard <0=>SPI MMC card
+// <i>Default: 1
+#define STM32_USE_SDIO 0
+
+/* whether use board external SRAM memory */
+// <e>Use external SRAM memory on the board
+// <i>Enable External SRAM memory
+#define STM32_EXT_SRAM 0
+// <o>Begin Address of External SRAM
+// <i>Default: 0x68000000
+#define STM32_EXT_SRAM_BEGIN 0x68000000 /* the begining address of external SRAM */
+// <o>End Address of External SRAM
+// <i>Default: 0x68080000
+#define STM32_EXT_SRAM_END 0x68080000 /* the end address of external SRAM */
+// </e>
+
+// <o> Internal SRAM memory size[Kbytes] <8-64>
+// <i>Default: 64
+#define STM32_SRAM_SIZE 64
+#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024)
+
+#define RT_USING_UART2
+
+// <o> Console on USART: <0=> no console <1=>USART 1 <2=>USART 2 <3=> USART 3
+// <i>Default: 1
+#define STM32_CONSOLE_USART 2
+
+void rt_hw_board_init(void);
+
+#if STM32_CONSOLE_USART == 0
+#define CONSOLE_DEVICE "no"
+#elif STM32_CONSOLE_USART == 1
+#define CONSOLE_DEVICE "uart1"
+#elif STM32_CONSOLE_USART == 2
+#define CONSOLE_DEVICE "uart2"
+#elif STM32_CONSOLE_USART == 3
+#define CONSOLE_DEVICE "uart3"
+#endif
+
+#define FINSH_DEVICE_NAME CONSOLE_DEVICE
+
+void rt_hw_usart_init(void);
+
+/* SD Card init function */
+void rt_hw_msd_init(void);
+
+#endif
+
+// <<< Use Configuration Wizard in Context Menu >>>
diff --git a/bsp/stm32f40x/drivers/serial.c b/bsp/stm32f40x/drivers/serial.c
new file mode 100644
index 0000000000..adee92736c
--- /dev/null
+++ b/bsp/stm32f40x/drivers/serial.c
@@ -0,0 +1,419 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, 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.
+ */
+
+#include "serial.h"
+#include "stm32f4xx.h"
+//#include <stm32f10x_dma.h>
+//#include <stm32f10x_usart.h>
+
+static void rt_serial_enable_dma(DMA_Stream_TypeDef* dma_channel,
+ rt_uint32_t address, rt_uint32_t size);
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+/* 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->user_data;
+
+ 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;
+ }
+
+ if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+ {
+ RT_ASSERT(uart->dma_tx->dma_channel != RT_NULL);
+ uart->dma_tx->list_head = uart->dma_tx->list_tail = RT_NULL;
+
+ /* init data node memory pool */
+ rt_mp_init(&(uart->dma_tx->data_node_mp), "dn",
+ uart->dma_tx->data_node_mem_pool,
+ sizeof(uart->dma_tx->data_node_mem_pool),
+ sizeof(struct stm32_serial_data_node));
+ }
+
+ /* 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)
+{
+ 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 stm32_serial_device* uart;
+
+ ptr = buffer;
+ err_code = RT_EOK;
+ uart = (struct stm32_serial_device*)dev->user_data;
+
+ 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 (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_Stream_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->user_data;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+ {
+ /* interrupt mode Tx, does not support */
+ RT_ASSERT(0);
+ }
+ 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_mp_alloc (&(uart->dma_tx->data_node_mp), RT_WAITING_FOREVER);
+ 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 */
+ if (dev->flag & RT_DEVICE_FLAG_STREAM)
+ {
+ /* stream mode */
+ while (size)
+ {
+ if (*ptr == '\n')
+ {
+ while (!(uart->uart_device->SR & USART_FLAG_TXE));
+ uart->uart_device->DR = '\r';
+ }
+
+ while (!(uart->uart_device->SR & USART_FLAG_TXE));
+ uart->uart_device->DR = (*ptr & 0x1FF);
+
+ ++ptr; --size;
+ }
+ }
+ else
+ {
+ /* write data directly */
+ while (size)
+ {
+ while (!(uart->uart_device->SR & USART_FLAG_TXE));
+ uart->uart_device->DR = (*ptr & 0x1FF);
+
+ ++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->user_data;
+ 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);
+
+ 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->user_data = 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->user_data;
+
+ 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_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ /* save character */
+ uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->DR & 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);
+ }
+
+ /* 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)
+ {
+ /* clear interrupt */
+ USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
+ }
+}
+
+/*
+ * 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->user_data;
+
+ /* 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 head */
+ uart->dma_tx->list_head = data_node->next;
+ if (uart->dma_tx->list_head == RT_NULL) /* data link empty */
+ uart->dma_tx->list_tail = RT_NULL;
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ /* release data node memory */
+ rt_mp_free(data_node);
+
+ if (uart->dma_tx->list_head != RT_NULL)
+ {
+ /* transmit next data node */
+ 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);
+ }
+ else
+ {
+ /* no data to be transmitted, disable DMA */
+ DMA_Cmd(uart->dma_tx->dma_channel, DISABLE);
+ }
+}
+
+/*@}*/
diff --git a/bsp/stm32f40x/drivers/serial.h b/bsp/stm32f40x/drivers/serial.h
new file mode 100644
index 0000000000..bc762a3aa5
--- /dev/null
+++ b/bsp/stm32f40x/drivers/serial.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+#ifndef __RT_HW_SERIAL_H__
+#define __RT_HW_SERIAL_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+/* STM32F10x library definitions */
+#include "stm32f4xx.h"
+//#include <stm32f10x.h>
+
+#define UART_RX_BUFFER_SIZE 128
+#define UART_TX_DMA_NODE_SIZE 4
+
+/* 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 */
+// DMA_Channel_TypeDef* dma_channel;
+ DMA_Stream_TypeDef* dma_channel;
+
+ /* data list head and tail */
+ struct stm32_serial_data_node *list_head, *list_tail;
+
+ /* data node memory pool */
+ struct rt_mempool data_node_mp;
+ rt_uint8_t data_node_mem_pool[UART_TX_DMA_NODE_SIZE *
+ (sizeof(struct stm32_serial_data_node) + sizeof(void*))];
+};
+
+struct stm32_serial_int_rx
+{
+ rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
+ rt_uint32_t read_index, save_index;
+};
+
+struct stm32_serial_device
+{
+ USART_TypeDef* uart_device;
+
+ /* rx structure */
+ struct stm32_serial_int_rx* int_rx;
+
+ /* tx structure */
+ 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_tx_isr(rt_device_t device);
+
+#endif
diff --git a/bsp/stm32f40x/drivers/stm32f4xx_conf.h b/bsp/stm32f40x/drivers/stm32f4xx_conf.h
new file mode 100644
index 0000000000..a56acc932d
--- /dev/null
+++ b/bsp/stm32f40x/drivers/stm32f4xx_conf.h
@@ -0,0 +1,94 @@
+/**
+ ******************************************************************************
+ * @file IO_Toggle/stm32f4xx_conf.h
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 19-September-2011
+ * @brief Library configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * 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.
+ *
+ * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_CONF_H
+#define __STM32F4xx_CONF_H
+
+#if defined (HSE_VALUE)
+/* Redefine the HSE value; it's equal to 8 MHz on the STM32F4-DISCOVERY Kit */
+ #undef HSE_VALUE
+ #define HSE_VALUE ((uint32_t)8000000)
+#endif /* HSE_VALUE */
+
+/* Includes ------------------------------------------------------------------*/
+/* Uncomment the line below to enable peripheral header file inclusion */
+#include "stm32f4xx_adc.h"
+#include "stm32f4xx_can.h"
+#include "stm32f4xx_crc.h"
+#include "stm32f4xx_cryp.h"
+#include "stm32f4xx_dac.h"
+#include "stm32f4xx_dbgmcu.h"
+#include "stm32f4xx_dcmi.h"
+#include "stm32f4xx_dma.h"
+#include "stm32f4xx_exti.h"
+#include "stm32f4xx_flash.h"
+#include "stm32f4xx_fsmc.h"
+#include "stm32f4xx_hash.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_i2c.h"
+#include "stm32f4xx_iwdg.h"
+#include "stm32f4xx_pwr.h"
+#include "stm32f4xx_rcc.h"
+#include "stm32f4xx_rng.h"
+#include "stm32f4xx_rtc.h"
+#include "stm32f4xx_sdio.h"
+#include "stm32f4xx_spi.h"
+#include "stm32f4xx_syscfg.h"
+#include "stm32f4xx_tim.h"
+#include "stm32f4xx_usart.h"
+#include "stm32f4xx_wwdg.h"
+#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* If an external clock source is used, then the value of the following define
+ should be set to the value of the external clock source, else, if no external
+ clock is used, keep this define commented */
+/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */
+
+
+/* Uncomment the line below to expanse the "assert_param" macro in the
+ Standard Peripheral Library drivers code */
+#define USE_FULL_ASSERT 1
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr: If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+#endif /* __STM32F4xx_CONF_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/bsp/stm32f40x/drivers/stm32f4xx_it.c b/bsp/stm32f40x/drivers/stm32f4xx_it.c
new file mode 100644
index 0000000000..b5ccb100be
--- /dev/null
+++ b/bsp/stm32f40x/drivers/stm32f4xx_it.c
@@ -0,0 +1,184 @@
+/**
+ ******************************************************************************
+ * @file IO_Toggle/stm32f4xx_it.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 19-September-2011
+ * @brief Main Interrupt Service Routines.
+ * This file provides template for all exceptions handler and
+ * peripherals interrupt service routine.
+ ******************************************************************************
+ * @attention
+ *
+ * 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.
+ *
+ * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx.h"
+#include <rtthread.h>
+#include "board.h"
+
+/** @addtogroup STM32F4_Discovery_Peripheral_Examples
+ * @{
+ */
+
+/** @addtogroup IO_Toggle
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/******************************************************************************/
+/* Cortex-M4 Processor Exceptions Handlers */
+/******************************************************************************/
+
+/**
+ * @brief This function handles NMI exception.
+ * @param None
+ * @retval None
+ */
+void NMI_Handler(void)
+{
+}
+
+/**
+ * @brief This function handles Hard Fault exception.
+ * @param None
+ * @retval None
+ */
+//void HardFault_Handler(void)
+//{
+// // definition in libcpu/arm/cortex-m4/context_*.S
+//}
+
+/**
+ * @brief This function handles Memory Manage exception.
+ * @param None
+ * @retval None
+ */
+void MemManage_Handler(void)
+{
+ /* Go to infinite loop when Memory Manage exception occurs */
+ while (1)
+ {
+ }
+}
+
+/**
+ * @brief This function handles Bus Fault exception.
+ * @param None
+ * @retval None
+ */
+void BusFault_Handler(void)
+{
+ /* Go to infinite loop when Bus Fault exception occurs */
+ while (1)
+ {
+ }
+}
+
+/**
+ * @brief This function handles Usage Fault exception.
+ * @param None
+ * @retval None
+ */
+void UsageFault_Handler(void)
+{
+ /* Go to infinite loop when Usage Fault exception occurs */
+ while (1)
+ {
+ }
+}
+
+/**
+ * @brief This function handles SVCall exception.
+ * @param None
+ * @retval None
+ */
+void SVC_Handler(void)
+{
+}
+
+/**
+ * @brief This function handles Debug Monitor exception.
+ * @param None
+ * @retval None
+ */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+ * @brief This function handles PendSVC exception.
+ * @param None
+ * @retval None
+ */
+//void PendSV_Handler(void)
+//{
+// // definition in libcpu/arm/cortex-m4/context_*.S
+//}
+
+/**
+ * @brief This function handles SysTick Handler.
+ * @param None
+ * @retval None
+ */
+//void SysTick_Handler(void)
+//{
+// // definition in boarc.c
+//}
+
+/******************************************************************************/
+/* STM32F4xx Peripherals Interrupt Handlers */
+/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
+/* available peripheral interrupt handler's name please refer to the startup */
+/* file (startup_stm32f4xx.s). */
+/******************************************************************************/
+
+/**
+ * @brief This function handles PPP interrupt request.
+ * @param None
+ * @retval None
+ */
+/*void PPP_IRQHandler(void)
+{
+}*/
+
+void USART2_IRQHandler(void)
+{
+#ifdef RT_USING_UART2
+ extern struct rt_device uart2_device;
+ extern void rt_hw_serial_isr(struct rt_device *device);
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ rt_hw_serial_isr(&uart2_device);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+#endif
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/bsp/stm32f40x/drivers/usart.c b/bsp/stm32f40x/drivers/usart.c
new file mode 100644
index 0000000000..063d230650
--- /dev/null
+++ b/bsp/stm32f40x/drivers/usart.c
@@ -0,0 +1,317 @@
+/*
+ * File : usart.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, 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 the first version
+ * 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode
+ */
+
+#include "stm32f4xx.h"
+#include "usart.h"
+#include "board.h"
+#include <serial.h>
+
+/*
+ * Use UART1 as console output and finsh input
+ * interrupt Rx and poll Tx (stream mode)
+ *
+ * Use UART2 with interrupt Rx and poll Tx
+ * Use UART3 with DMA Tx and interrupt Rx -- DMA channel 2
+ *
+ * USART DMA setting on STM32
+ * USART1 Tx --> DMA Channel 4
+ * USART1 Rx --> DMA Channel 5
+ * USART2 Tx --> DMA Channel 7
+ * USART2 Rx --> DMA Channel 6
+ * USART3 Tx --> DMA Channel 2
+ * USART3 Rx --> DMA Channel 3
+ */
+
+#ifdef RT_USING_UART1
+struct stm32_serial_int_rx uart1_int_rx;
+struct stm32_serial_device uart1 =
+{
+ USART1,
+ &uart1_int_rx,
+ RT_NULL
+};
+struct rt_device uart1_device;
+#endif
+
+#ifdef RT_USING_UART2
+struct stm32_serial_int_rx uart2_int_rx;
+struct stm32_serial_device uart2 =
+{
+ USART2,
+ &uart2_int_rx,
+ RT_NULL
+};
+struct rt_device uart2_device;
+#endif
+
+#ifdef RT_USING_UART3
+struct stm32_serial_int_rx uart3_int_rx;
+struct stm32_serial_dma_tx uart3_dma_tx;
+struct stm32_serial_device uart3 =
+{
+ USART3,
+ &uart3_int_rx,
+ &uart3_dma_tx
+};
+struct rt_device uart3_device;
+#endif
+
+#define USART1_DR_Base 0x40013804
+#define USART2_DR_Base 0x40004404
+#define USART3_DR_Base 0x40004804
+
+/* USART1_REMAP = 0 */
+#define UART1_GPIO_TX GPIO_Pin_9
+#define UART1_GPIO_RX GPIO_Pin_10
+#define UART1_GPIO GPIOA
+#define RCC_APBPeriph_UART1 RCC_APB2Periph_USART1
+#define UART1_TX_DMA DMA1_Channel4
+#define UART1_RX_DMA DMA1_Channel5
+
+#define UART2_GPIO_TX GPIO_Pin_2
+#define UART2_GPIO_RX GPIO_Pin_3
+#define UART2_GPIO GPIOA
+#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2
+
+/* USART3_REMAP[1:0] = 00 */
+#define UART3_GPIO_RX GPIO_Pin_11
+#define UART3_GPIO_TX GPIO_Pin_10
+#define UART3_GPIO GPIOB
+#define RCC_APBPeriph_UART3 RCC_APB1Periph_USART3
+#define UART3_TX_DMA DMA1_Channel2
+#define UART3_RX_DMA DMA1_Channel3
+
+static void RCC_Configuration(void)
+{
+#ifdef RT_USING_UART1
+ /* Enable USART1 and GPIOA clocks */
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
+#endif
+
+#ifdef RT_USING_UART2
+ /* Enable USART2 and GPIOA clocks */
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
+ /* Enable USART2 clock */
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
+#endif
+
+#ifdef RT_USING_UART3
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+ /* Enable USART3 clock */
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
+
+ /* DMA clock enable */
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
+#endif
+}
+
+static void GPIO_Configuration(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+
+#ifdef RT_USING_UART1
+ /* Configure USART1 Rx (PA.10) as input floating */
+ GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX;
+ GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
+
+ /* Configure USART1 Tx (PA.09) as alternate function push-pull */
+ GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX;
+ GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
+#endif
+
+#ifdef RT_USING_UART2
+ GPIO_InitStructure.GPIO_Pin = UART2_GPIO_TX|UART2_GPIO_RX;
+ GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
+
+ /* Connect alternate function */
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
+#endif
+
+#ifdef RT_USING_UART3
+ /* Configure USART3 Rx as input floating */
+ GPIO_InitStructure.GPIO_Pin = UART3_GPIO_RX;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+ GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
+
+ /* Configure USART3 Tx as alternate function push-pull */
+ GPIO_InitStructure.GPIO_Pin = UART3_GPIO_TX;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
+#endif
+}
+
+static void NVIC_Configuration(void)
+{
+ NVIC_InitTypeDef NVIC_InitStructure;
+
+#ifdef RT_USING_UART1
+ /* Enable the USART1 Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+#endif
+
+#ifdef RT_USING_UART2
+ /* Enable the USART2 Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+#endif
+
+#ifdef RT_USING_UART3
+ /* Enable the USART3 Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+
+ /* Enable the DMA1 Channel2 Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+#endif
+}
+
+static void DMA_Configuration(void)
+{
+#if defined (RT_USING_UART3)
+ DMA_InitTypeDef DMA_InitStructure;
+
+ /* fill init structure */
+ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
+ DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
+ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
+
+ /* DMA1 Channel5 (triggered by USART3 Tx event) Config */
+ DMA_DeInit(UART3_TX_DMA);
+ DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
+ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
+ DMA_InitStructure.DMA_MemoryBaseAddr = (u32)0;
+ DMA_InitStructure.DMA_BufferSize = 0;
+ DMA_Init(UART3_TX_DMA, &DMA_InitStructure);
+ DMA_ITConfig(UART3_TX_DMA, DMA_IT_TC | DMA_IT_TE, ENABLE);
+ DMA_ClearFlag(DMA1_FLAG_TC5);
+#endif
+}
+
+volatile USART_TypeDef * uart2_debug = USART2;
+/*
+ * Init all related hardware in here
+ * rt_hw_serial_init() will register all supported USART device
+ */
+void rt_hw_usart_init()
+{
+ USART_InitTypeDef USART_InitStructure;
+ USART_ClockInitTypeDef USART_ClockInitStructure;
+
+ RCC_Configuration();
+
+ GPIO_Configuration();
+
+ NVIC_Configuration();
+
+ DMA_Configuration();
+
+ /* uart init */
+#ifdef RT_USING_UART1
+ USART_InitStructure.USART_BaudRate = 115200;
+ USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+ USART_InitStructure.USART_StopBits = USART_StopBits_1;
+ USART_InitStructure.USART_Parity = USART_Parity_No;
+ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
+ USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
+ USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
+ USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
+ USART_Init(USART1, &USART_InitStructure);
+ USART_ClockInit(USART1, &USART_ClockInitStructure);
+
+ /* register uart1 */
+ rt_hw_serial_register(&uart1_device, "uart1",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
+ &uart1);
+
+ /* enable interrupt */
+ USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
+#endif
+
+#ifdef RT_USING_UART2
+ USART_InitStructure.USART_BaudRate = 115200;
+ USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+ USART_InitStructure.USART_StopBits = USART_StopBits_1;
+ USART_InitStructure.USART_Parity = USART_Parity_No;
+ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
+ USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
+ USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
+ USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
+ USART_Init(USART2, &USART_InitStructure);
+ USART_ClockInit(USART2, &USART_ClockInitStructure);
+
+ /* register uart2 */
+ rt_hw_serial_register(&uart2_device, "uart2",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
+ &uart2);
+
+ /* Enable USART2 DMA Rx request */
+ USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
+#endif
+
+#ifdef RT_USING_UART3
+ USART_InitStructure.USART_BaudRate = 115200;
+ USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+ USART_InitStructure.USART_StopBits = USART_StopBits_1;
+ USART_InitStructure.USART_Parity = USART_Parity_No;
+ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+ USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
+ USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
+ USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
+ USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
+ USART_Init(USART3, &USART_InitStructure);
+ USART_ClockInit(USART3, &USART_ClockInitStructure);
+
+ uart3_dma_tx.dma_channel= UART3_TX_DMA;
+
+ /* register uart3 */
+ rt_hw_serial_register(&uart3_device, "uart3",
+ RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_TX,
+ &uart3);
+
+ /* Enable USART3 DMA Tx request */
+ USART_DMACmd(USART3, USART_DMAReq_Tx , ENABLE);
+
+ /* enable interrupt */
+ USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
+#endif
+}
diff --git a/bsp/stm32f40x/drivers/usart.h b/bsp/stm32f40x/drivers/usart.h
new file mode 100644
index 0000000000..36c5f19b1e
--- /dev/null
+++ b/bsp/stm32f40x/drivers/usart.h
@@ -0,0 +1,23 @@
+/*
+ * File : usart.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2009, 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 the first version
+ */
+
+#ifndef __USART_H__
+#define __USART_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+void rt_hw_usart_init(void);
+
+#endif