diff --git a/bsp/jz47xx/SConscript b/bsp/jz47xx/SConscript new file mode 100644 index 0000000000..a3ff4c0a51 --- /dev/null +++ b/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') diff --git a/bsp/jz47xx/SConstruct b/bsp/jz47xx/SConstruct new file mode 100644 index 0000000000..21e393cf98 --- /dev/null +++ b/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) diff --git a/bsp/jz47xx/application.c b/bsp/jz47xx/application.c new file mode 100644 index 0000000000..53881435a2 --- /dev/null +++ b/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 + +int rt_application_init() +{ + return 0; +} + +/*@}*/ diff --git a/bsp/jz47xx/board.c b/bsp/jz47xx/board.c new file mode 100644 index 0000000000..a548581be2 --- /dev/null +++ b/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 +#include + +#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 +} +/*@}*/ diff --git a/bsp/jz47xx/board.h b/bsp/jz47xx/board.h new file mode 100644 index 0000000000..e70d32c2af --- /dev/null +++ b/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 diff --git a/bsp/jz47xx/rtconfig.h b/bsp/jz47xx/rtconfig.h new file mode 100644 index 0000000000..acafa7efbf --- /dev/null +++ b/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 diff --git a/bsp/jz47xx/rtconfig.py b/bsp/jz47xx/rtconfig.py new file mode 100644 index 0000000000..a63f96e1a5 --- /dev/null +++ b/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' diff --git a/bsp/jz47xx/startup.c b/bsp/jz47xx/startup.c new file mode 100644 index 0000000000..c718d93732 --- /dev/null +++ b/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 +#include + +#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 ; +} + +/*@}*/ diff --git a/bsp/jz47xx/uart.c b/bsp/jz47xx/uart.c new file mode 100644 index 0000000000..96d8359776 --- /dev/null +++ b/bsp/jz47xx/uart.c @@ -0,0 +1,354 @@ +#include +#include + +/** + * @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 */ + +/*@}*/ diff --git a/bsp/jz47xx/uart.h b/bsp/jz47xx/uart.h new file mode 100644 index 0000000000..7b4663aa3d --- /dev/null +++ b/bsp/jz47xx/uart.h @@ -0,0 +1,6 @@ +#ifndef __UART_H__ +#define __UART_H__ + +void rt_hw_uart_init(void); + +#endif