Преглед изворни кода

add init Jz47xx porting.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@791 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong пре 15 година
родитељ
комит
64a7365af5

+ 29 - 0
bsp/jz47xx/SConscript

@@ -0,0 +1,29 @@
+Import('env')
+Import('projects')
+Import('RTT_ROOT')
+Import('rtconfig')
+
+# group definitions
+group = {}
+group['name'] = 'Startup'
+group['CCFLAGS'] = ''
+group['CPPPATH'] = [RTT_ROOT + '/bsp/jz47xx']
+group['CPPDEFINES'] = []
+group['LINKFLAGS'] = ''
+
+src_bsp   = ['application.c', 'startup.c', 'board.c']
+src_drv   = ['uart.c']
+
+group['src'] = File(src_bsp + src_drv)
+
+# add group to project list
+projects.append(group)
+
+env.Append(CCFLAGS = group['CCFLAGS'])
+env.Append(CPPPATH = group['CPPPATH'])
+env.Append(CPPDEFINES = group['CPPDEFINES'])
+env.Append(LINKFLAGS = group['LINKFLAGS'])
+
+obj = env.Object(group['src'])
+
+Return('obj')

+ 38 - 0
bsp/jz47xx/SConstruct

@@ -0,0 +1,38 @@
+import os
+import sys
+import rtconfig
+
+RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+import mdk
+
+target = 'rtthread-jz47xx'
+projects = []
+
+env = Environment(tools = ['mingw'],
+	AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+	CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+	AR = rtconfig.AR, ARFLAGS = '-rc',
+	LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+Export('env')
+Export('RTT_ROOT')
+Export('rtconfig')
+Export('projects')
+
+# kernel building script
+objs = SConscript(RTT_ROOT + '/src/SConscript', variant_dir='build/src', duplicate=0)
+# arch building script
+objs = objs + SConscript(RTT_ROOT + '/libcpu/SConscript', variant_dir='build/libcpu', duplicate=0)
+
+# component script 
+Repository(RTT_ROOT)
+objs = objs + SConscript('components/SConscript')
+
+# board build script
+objs = objs + SConscript('SConscript', variant_dir='build/bsp', duplicate=0)
+
+TARGET = target + '.' + rtconfig.TARGET_EXT
+env.Program(TARGET, objs)
+env.AddPostAction(TARGET, rtconfig.POST_ACTION)

+ 26 - 0
bsp/jz47xx/application.c

@@ -0,0 +1,26 @@
+/*
+ * File      : app.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
+ * 2010-06-25     Bernard      first version
+ */
+
+/**
+ * @addtogroup JZ47xx
+ */
+/*@{*/
+#include <rtthread.h>
+
+int rt_application_init()
+{
+	return 0;
+}
+
+/*@}*/

+ 54 - 0
bsp/jz47xx/board.c

@@ -0,0 +1,54 @@
+/*
+ * File      : board.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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-06-25     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "board.h"
+#include "uart.h"
+
+/**
+ * @addtogroup JZ47xx
+ */
+/*@{*/
+
+/**
+ * This is the timer interrupt service routine.
+ */
+void rt_hw_timer_handler()
+{
+	/* enter interrupt */
+	rt_interrupt_enter();
+
+	rt_tick_increase();
+
+	/* leave interrupt */
+	rt_interrupt_leave();
+}
+
+/**
+ * This function will initial sam7s64 board.
+ */
+void rt_hw_board_init()
+{
+#ifdef RT_USING_UART
+	/* init hardware UART device */
+	rt_hw_uart_init();
+#endif
+#ifdef RT_USING_CONSOLE
+	/* set console device */
+	rt_console_set_device("uart");
+#endif
+}
+/*@}*/

+ 22 - 0
bsp/jz47xx/board.h

@@ -0,0 +1,22 @@
+/*
+ * File      : board.h
+ * 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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-06-25     Bernard      first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+void rt_hw_board_init(void);
+
+#define RT_HW_HEAP_END	(0x80000000 + 32 * 1024 * 1024)
+
+#endif

+ 151 - 0
bsp/jz47xx/rtconfig.h

@@ -0,0 +1,151 @@
+/* RT-Thread config file */
+#ifndef __RTTHREAD_CFG_H__
+#define __RTTHREAD_CFG_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_USING_OVERFLOW_CHECK
+
+/* Using Hook */
+#define RT_USING_HOOK
+
+/* Using Software Timer */
+/* #define RT_USING_TIMER_SOFT */
+#define RT_TIMER_THREAD_PRIO		4
+#define RT_TIMER_THREAD_STACK_SIZE	512
+#define RT_TIMER_TICK_PER_SECOND	10
+
+/* 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
+
+/* SECTION: Device System */
+/* Using Device System */
+#define RT_USING_DEVICE
+/* RT_USING_UART */
+#define RT_USING_UART0
+#define RT_UART_RX_BUFFER_SIZE	64
+
+/* SECTION: Console options */
+/* the buffer size of console */
+#define RT_CONSOLEBUF_SIZE	128
+
+/* SECTION: finsh, a C-Express shell */
+/* Using FinSH as Shell*/
+#define RT_USING_FINSH
+/* Using symbol table */
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_DEVICE_NAME "uart"
+
+/* SECTION: device filesystem support */
+#define RT_USING_DFS
+#define RT_USING_DFS_ELMFAT
+
+/* the max number of mounted filesystem */
+#define DFS_FILESYSTEMS_MAX			2
+/* the max number of opened files 		*/
+#define DFS_FD_MAX					4
+/* the max number of cached sector 		*/
+#define DFS_CACHE_MAX_NUM   		4
+
+/* SECTION: lwip, a lighwight TCP/IP protocol stack */
+/* #define RT_USING_LWIP */
+#define RT_LWIP_USING_RT_MEM
+
+/* Enable ICMP protocol*/
+#define RT_LWIP_ICMP
+/* Enable UDP protocol*/
+#define RT_LWIP_UDP
+/* Enable TCP protocol*/
+#define RT_LWIP_TCP
+/* Enable DNS */
+#define RT_LWIP_DNS
+
+/* the number of simulatenously active TCP connections*/
+#define RT_LWIP_TCP_PCB_NUM	5
+
+/* ip address of target*/
+#define RT_LWIP_IPADDR0	192
+#define RT_LWIP_IPADDR1	168
+#define RT_LWIP_IPADDR2	1
+#define RT_LWIP_IPADDR3	30
+
+/* gateway address of target*/
+#define RT_LWIP_GWADDR0	192
+#define RT_LWIP_GWADDR1	168
+#define RT_LWIP_GWADDR2	1
+#define RT_LWIP_GWADDR3	1
+
+/* mask address of target*/
+#define RT_LWIP_MSKADDR0	255
+#define RT_LWIP_MSKADDR1	255
+#define RT_LWIP_MSKADDR2	255
+#define RT_LWIP_MSKADDR3	0
+
+/* tcp thread options */
+#define RT_LWIP_TCPTHREAD_PRIORITY		12
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE		4
+#define RT_LWIP_TCPTHREAD_STACKSIZE		1024
+
+/* ethernet if thread options */
+#define RT_LWIP_ETHTHREAD_PRIORITY		15
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE		4
+#define RT_LWIP_ETHTHREAD_STACKSIZE		512
+
+/* 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

+ 80 - 0
bsp/jz47xx/rtconfig.py

@@ -0,0 +1,80 @@
+import SCons.cpp
+
+# component options
+
+# make all component false
+RT_USING_FINSH 		= False
+RT_USING_DFS 		= False
+RT_USING_DFS_ELMFAT 	= False
+RT_USING_DFS_YAFFS2	= False
+RT_USING_LWIP 		= False
+RT_USING_WEBSERVER	= False
+RT_USING_RTGUI 		= False
+
+# parse rtconfig.h to get used component
+PreProcessor = SCons.cpp.PreProcessor()
+f = file('rtconfig.h', 'r')
+contents = f.read()
+f.close()
+PreProcessor.process_contents(contents)
+rtconfig_ns = PreProcessor.cpp_namespace
+
+# finsh shell options
+if rtconfig_ns.has_key('RT_USING_FINSH'):
+	RT_USING_FINSH = True
+
+# device virtual filesystem options
+if rtconfig_ns.has_key('RT_USING_DFS'):
+    RT_USING_DFS = True
+
+    if rtconfig_ns.has_key('RT_USING_DFS_ELMFAT'):
+        RT_USING_DFS_ELMFAT = True
+    if rtconfig_ns.has_key('RT_USING_DFS_YAFFS2'):
+        RT_USING_DFS_YAFFS2 = True
+
+# lwip options
+if rtconfig_ns.has_key('RT_USING_LWIP'):
+    RT_USING_LWIP = True
+    if rtconfig_ns.has_key('RT_USING_WEBSERVER'):
+        RT_USING_WEBSERVER = True
+
+# rtgui options
+if rtconfig_ns.has_key('RT_USING_RTGUI'):
+    RT_USING_RTGUI = True
+
+# toolchains options
+ARCH='mips'
+CPU='jz47xx'
+
+CROSS_TOOL      = 'gcc'
+PLATFORM 	= 'gcc'
+EXEC_PATH 	= 'E:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
+BUILD		= 'debug'
+
+# toolchains
+PREFIX = 'mips-sde-elf-'
+CC = PREFIX + 'gcc'
+AS = PREFIX + 'gcc'
+AR = PREFIX + 'ar'
+LINK = PREFIX + 'gcc'
+TARGET_EXT = 'elf'
+SIZE = PREFIX + 'size'
+OBJDUMP = PREFIX + 'objdump'
+OBJCPY = PREFIX + 'objcopy'
+
+DEVICE = ' -mips32 -msoft-float'
+CFLAGS = DEVICE + ' -G0 -DRT_USING_MINILIBC -mno-abicalls -fno-pic -fno-builtin -fno-exceptions -ffunction-sections -fomit-frame-pointer'
+AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp'
+LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-jz47xx.map,-cref,-u,Reset_Handler -T jz47xx_ram.ld'
+
+CPATH = ''
+LPATH = ''
+
+if BUILD == 'debug':
+	CFLAGS += ' -O0 -gdwarf-2'
+	AFLAGS += ' -gdwarf-2'
+else:
+	CFLAGS += ' -O2'
+
+RT_USING_MINILIBC = True
+POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'

+ 74 - 0
bsp/jz47xx/startup.c

@@ -0,0 +1,74 @@
+/*
+ * 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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-06-25     Bernard      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+
+/**
+ * @addtogroup jz47xx
+ */
+
+/*@{*/
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+extern int  rt_application_init(void);
+
+/**
+ * This function will startup RT-Thread RTOS.
+ */
+void rtthread_startup(void)
+{
+	/* init board */
+	rt_hw_board_init();
+	rt_show_version();
+
+	/* init tick */
+	rt_system_tick_init();
+
+	/* init timer system */
+	rt_system_timer_init();
+
+	rt_system_heap_init((void*)&__bss_end, (void*)RT_HW_HEAP_END);
+
+	/* init scheduler system */
+	rt_system_scheduler_init();
+
+#ifdef RT_USING_DEVICE
+	/* init all device */
+	rt_device_init_all();
+#endif
+
+	/* init application */
+	rt_application_init();
+
+#ifdef RT_USING_FINSH
+	/* init finsh */
+	finsh_system_init();
+	finsh_set_device(FINSH_DEVICE_NAME);
+#endif
+
+	/* init idle thread */
+	rt_thread_idle_init();
+
+	/* start scheduler */
+	rt_system_scheduler_start();
+
+	/* never reach here */
+	return ;
+}
+
+/*@}*/

+ 354 - 0
bsp/jz47xx/uart.c

@@ -0,0 +1,354 @@
+#include <rthw.h>
+#include <rtthread.h>
+
+/**
+ * @addtogroup Jz47xx
+ */
+
+/*@{*/
+#if defined(RT_USING_UART) && defined(RT_USING_DEVICE)
+
+#define UART_BAUDRATE   115200
+#define DEV_CLK    12000000
+
+
+/*
+ * Define macros for UARTIER
+ * UART Interrupt Enable Register
+ */
+#define UARTIER_RIE	(1 << 0)	/* 0: receive fifo "full" interrupt disable */
+#define UARTIER_TIE	(1 << 1)	/* 0: transmit fifo "empty" interrupt disable */
+#define UARTIER_RLIE	(1 << 2)	/* 0: receive line status interrupt disable */
+#define UARTIER_MIE	(1 << 3)	/* 0: modem status interrupt disable */
+#define UARTIER_RTIE	(1 << 4)	/* 0: receive timeout interrupt disable */
+
+/*
+ * Define macros for UARTISR
+ * UART Interrupt Status Register
+ */
+#define UARTISR_IP	(1 << 0)	/* 0: interrupt is pending  1: no interrupt */
+#define UARTISR_IID	(7 << 1)	/* Source of Interrupt */
+#define UARTISR_IID_MSI		(0 << 1)	/* Modem status interrupt */
+#define UARTISR_IID_THRI	(1 << 1)	/* Transmitter holding register empty */
+#define UARTISR_IID_RDI		(2 << 1)	/* Receiver data interrupt */
+#define UARTISR_IID_RLSI	(3 << 1)	/* Receiver line status interrupt */
+#define UARTISR_FFMS	(3 << 6)	/* FIFO mode select, set when UARTFCR.FE is set to 1 */
+#define UARTISR_FFMS_NO_FIFO	(0 << 6)
+#define UARTISR_FFMS_FIFO_MODE	(3 << 6)
+
+/*
+ * Define macros for UARTFCR
+ * UART FIFO Control Register
+ */
+#define UARTFCR_FE	(1 << 0)	/* 0: non-FIFO mode  1: FIFO mode */
+#define UARTFCR_RFLS	(1 << 1)	/* write 1 to flush receive FIFO */
+#define UARTFCR_TFLS	(1 << 2)	/* write 1 to flush transmit FIFO */
+#define UARTFCR_DMS	(1 << 3)	/* 0: disable DMA mode */
+#define UARTFCR_UUE	(1 << 4)	/* 0: disable UART */
+#define UARTFCR_RTRG	(3 << 6)	/* Receive FIFO Data Trigger */
+#define UARTFCR_RTRG_1	(0 << 6)
+#define UARTFCR_RTRG_4	(1 << 6)
+#define UARTFCR_RTRG_8	(2 << 6)
+#define UARTFCR_RTRG_15	(3 << 6)
+
+/*
+ * Define macros for UARTLCR
+ * UART Line Control Register
+ */
+#define UARTLCR_WLEN	(3 << 0)	/* word length */
+#define UARTLCR_WLEN_5	(0 << 0)
+#define UARTLCR_WLEN_6	(1 << 0)
+#define UARTLCR_WLEN_7	(2 << 0)
+#define UARTLCR_WLEN_8	(3 << 0)
+#define UARTLCR_STOP	(1 << 2)	/* 0: 1 stop bit when word length is 5,6,7,8
+					   1: 1.5 stop bits when 5; 2 stop bits when 6,7,8 */
+#define UARTLCR_PE	(1 << 3)	/* 0: parity disable */
+#define UARTLCR_PROE	(1 << 4)	/* 0: even parity  1: odd parity */
+#define UARTLCR_SPAR	(1 << 5)	/* 0: sticky parity disable */
+#define UARTLCR_SBRK	(1 << 6)	/* write 0 normal, write 1 send break */
+#define UARTLCR_DLAB	(1 << 7)	/* 0: access UARTRDR/TDR/IER  1: access UARTDLLR/DLHR */
+
+/*
+ * Define macros for UARTLSR
+ * UART Line Status Register
+ */
+#define UARTLSR_DR	(1 << 0)	/* 0: receive FIFO is empty  1: receive data is ready */
+#define UARTLSR_ORER	(1 << 1)	/* 0: no overrun error */
+#define UARTLSR_PER	(1 << 2)	/* 0: no parity error */
+#define UARTLSR_FER	(1 << 3)	/* 0; no framing error */
+#define UARTLSR_BRK	(1 << 4)	/* 0: no break detected  1: receive a break signal */
+#define UARTLSR_TDRQ	(1 << 5)	/* 1: transmit FIFO half "empty" */
+#define UARTLSR_TEMT	(1 << 6)	/* 1: transmit FIFO and shift registers empty */
+#define UARTLSR_RFER	(1 << 7)	/* 0: no receive error  1: receive error in FIFO mode */
+
+/*
+ * Define macros for UARTMCR
+ * UART Modem Control Register
+ */
+#define UARTMCR_DTR	(1 << 0)	/* 0: DTR_ ouput high */
+#define UARTMCR_RTS	(1 << 1)	/* 0: RTS_ output high */
+#define UARTMCR_OUT1	(1 << 2)	/* 0: UARTMSR.RI is set to 0 and RI_ input high */
+#define UARTMCR_OUT2	(1 << 3)	/* 0: UARTMSR.DCD is set to 0 and DCD_ input high */
+#define UARTMCR_LOOP	(1 << 4)	/* 0: normal  1: loopback mode */
+#define UARTMCR_MCE	(1 << 7)	/* 0: modem function is disable */
+
+/*
+ * Define macros for UARTMSR
+ * UART Modem Status Register
+ */
+#define UARTMSR_DCTS	(1 << 0)	/* 0: no change on CTS_ pin since last read of UARTMSR */
+#define UARTMSR_DDSR	(1 << 1)	/* 0: no change on DSR_ pin since last read of UARTMSR */
+#define UARTMSR_DRI	(1 << 2)	/* 0: no change on RI_ pin since last read of UARTMSR */
+#define UARTMSR_DDCD	(1 << 3)	/* 0: no change on DCD_ pin since last read of UARTMSR */
+#define UARTMSR_CTS	(1 << 4)	/* 0: CTS_ pin is high */
+#define UARTMSR_DSR	(1 << 5)	/* 0: DSR_ pin is high */
+#define UARTMSR_RI	(1 << 6)	/* 0: RI_ pin is high */
+#define UARTMSR_DCD	(1 << 7)	/* 0: DCD_ pin is high */
+
+/*
+ * Define macros for SIRCR
+ * Slow IrDA Control Register
+ */
+#define SIRCR_TSIRE	(1 << 0)	/* 0: transmitter is in UART mode  1: IrDA mode */
+#define SIRCR_RSIRE	(1 << 1)	/* 0: receiver is in UART mode  1: IrDA mode */
+#define SIRCR_TPWS	(1 << 2)	/* 0: transmit 0 pulse width is 3/16 of bit length
+					   1: 0 pulse width is 1.6us for 115.2Kbps */
+#define SIRCR_TXPL	(1 << 3)	/* 0: encoder generates a positive pulse for 0 */
+#define SIRCR_RXPL	(1 << 4)	/* 0: decoder interprets positive pulse as 0 */
+
+struct rt_uart_jz
+{
+	struct rt_device parent;
+
+	rt_uint32_t hw_base;
+	rt_uint32_t irq;
+
+	/* buffer for reception */
+	rt_uint8_t read_index, save_index;
+	rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
+}uart_device;
+
+static void rt_uart_irqhandler(void)
+{
+	rt_ubase_t level, isr;
+    struct rt_uart_jz* uart = &uart_device;
+
+    /* read interrupt status and clear it */
+	isr = UART_ISR(uart->hw_base);
+
+	if (isr & UARTISR_IID_RDI)	    /* Receive Data Available */
+	{
+		/* Receive Data Available */
+		while (UART_LSR(uart->hw_base) & UARTLSR_DR)
+		{
+			uart->rx_buffer[uart->save_index] = UART_RDR(uart->hw_base);
+
+			level = rt_hw_interrupt_disable();
+			uart->save_index ++;
+			if (uart->save_index >= RT_UART_RX_BUFFER_SIZE)
+				uart->save_index = 0;
+			rt_hw_interrupt_enable(level);
+		}
+
+		/* invoke callback */
+		if(uart->parent.rx_indicate != RT_NULL)
+		{
+			rt_size_t length;
+			if (uart->read_index > uart->save_index)
+				length = RT_UART_RX_BUFFER_SIZE - uart->read_index + uart->save_index;
+			else
+				length = uart->save_index - uart->read_index;
+
+			uart->parent.rx_indicate(&uart->parent, length);
+		}
+	}
+
+	return;
+}
+
+static rt_err_t rt_uart_init (rt_device_t dev)
+{
+	rt_uint32_t baud_div;
+	struct rt_uart_jz *uart = (struct rt_uart_jz*)dev;
+
+	RT_ASSERT(uart != RT_NULL);
+
+	/* Init UART Hardware */
+	UART_IER(uart->hw_base) = 0; /* clear interrupt */
+	UART_FCR(uart->hw_base) = ~UARTFCR_UUE; /* disable UART unite */
+
+	/* Enable UART clock */
+
+	/* Set both receiver and transmitter in UART mode (not SIR) */
+	UART_SIRCR(uart->hw_base) = ~(SIRCR_RSIRE | SIRCR_TSIRE);
+
+	/* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */
+	UART_LCR(uart->hw_base) = UARTLCR_WLEN_8;
+
+    /* set baudrate */
+	baud_div = DEV_CLK / 16 / UART_BAUDRATE;
+	UART_LCR(uart->hw_base) |= UARTLCR_DLAB;
+
+	UART_DLHR(uart->hw_base) = (baud_div >> 8) & 0xff;
+	UART_DLLR(uart->hw_base) = baud_div & 0xff;
+
+	UART_LCR(uart->hw_base) &= ~UARTLCR_DLAB;
+
+	/* Enable UART unit, enable and clear FIFO */
+	UART_FCR(uart->hw_base) = UARTFCR_UUE | UARTFCR_FE | UARTFCR_TFLS | UARTFCR_RFLS;
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	struct rt_uart_jz *uart = (struct rt_uart_jz*)dev;
+
+	RT_ASSERT(uart != RT_NULL);
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* Enable the UART Interrupt */
+		UART_IER(uart->hw_base) |= (UARTIER_RIE | UARTIER_RTIE);
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_uart_close(rt_device_t dev)
+{
+	struct rt_uart_jz *uart = (struct rt_uart_jz*)dev;
+
+	RT_ASSERT(uart != RT_NULL);
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* Disable the UART Interrupt */
+		UART_IER(uart->hw_base) &= ~(UARTIER_RIE | UARTIER_RTIE);
+	}
+
+	return RT_EOK;
+}
+
+static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_uart_jz *uart = (struct rt_uart_jz*)dev;
+
+	RT_ASSERT(uart != RT_NULL);
+
+	/* point to buffer */
+	ptr = (rt_uint8_t*) buffer;
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		while (size)
+		{
+			/* interrupt receive */
+			rt_base_t level;
+
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+			if (uart->read_index != uart->save_index)
+			{
+				*ptr = uart->rx_buffer[uart->read_index];
+
+				uart->read_index ++;
+				if (uart->read_index >= RT_UART_RX_BUFFER_SIZE)
+					uart->read_index = 0;
+			}
+			else
+			{
+				/* no data in rx buffer */
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+				break;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+
+			ptr ++;
+			size --;
+		}
+
+		return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+	}
+
+	return 0;
+}
+
+static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	char *ptr;
+	struct rt_uart_jz *uart = (struct rt_uart_jz*)dev;
+
+	RT_ASSERT(uart != RT_NULL);
+
+	ptr = (char*)buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_STREAM)
+	{
+		/* stream mode */
+		while (size)
+		{
+			if (*ptr == '\n')
+			{
+				/* FIFO status, contain valid data */
+				while ( !(UART_LSR(uart->hw_base) & (UARTLSR_TDRQ | UARTLSR_TEMT) == 0x60) );
+				/* write data */
+				UART_TDR(uart->hw_base) = '\r';
+			}
+
+			/* FIFO status, contain valid data */
+			while ( !(UART_LSR(uart->hw_base) & (UARTLSR_TDRQ | UARTLSR_TEMT) == 0x60) );
+			/* write data */
+			UART_TDR(uart->hw_base) = *ptr;
+
+			ptr ++;
+			size --;
+		}
+	}
+	else
+	{
+		while ( size != 0 )
+		{
+			/* FIFO status, contain valid data */
+			while ( !(UART_LSR(uart->hw_base) & (UARTLSR_TDRQ | UARTLSR_TEMT) == 0x60) );
+
+			/* write data */
+			UART_TDR(uart->hw_base) = *ptr;
+
+			ptr++;
+			size--;
+		}
+	}
+
+	return (rt_size_t) ptr - (rt_size_t) buffer;
+}
+
+void rt_hw_uart_init(void)
+{
+	struct rt_uart_jz* uart;
+
+	/* get uart device */
+	uart = &uart_device;
+
+	/* device initialization */
+	uart->parent.type = RT_Device_Class_Char;
+	rt_memset(uart->rx_buffer, 0, sizeof(uart->rx_buffer));
+	uart->read_index = uart->save_index = 0;
+
+	/* device interface */
+	uart->parent.init 	    = rt_uart_init;
+	uart->parent.open 	    = rt_uart_open;
+	uart->parent.close      = rt_uart_close;
+	uart->parent.read 	    = rt_uart_read;
+	uart->parent.write      = rt_uart_write;
+	uart->parent.control    = RT_NULL;
+	uart->parent.private    = RT_NULL;
+
+	rt_device_register(&uart->parent,
+		"uart", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX);
+}
+#endif /* end of UART */
+
+/*@}*/

+ 6 - 0
bsp/jz47xx/uart.h

@@ -0,0 +1,6 @@
+#ifndef __UART_H__
+#define __UART_H__
+
+void rt_hw_uart_init(void);
+
+#endif