From 7ae254abf8e890ad83e47150e9aee1d08f50eab4 Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Fri, 11 Dec 2009 09:42:01 +0000 Subject: [PATCH] add the s3c2440 code from old s3c2410 port. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@196 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- bsp/mini2440/SConstruct | 51 +++ bsp/mini2440/application.c | 192 ++++++++++ bsp/mini2440/board.c | 181 +++++++++ bsp/mini2440/board.h | 25 ++ bsp/mini2440/console.c | 177 +++++++++ bsp/mini2440/lcd.c | 358 +++++++++++++++++ bsp/mini2440/lcd.h | 25 ++ bsp/mini2440/mini2440_ram.ld | 70 ++++ bsp/mini2440/rtconfig.h | 177 +++++++++ bsp/mini2440/rtconfig.py | 84 ++++ bsp/mini2440/sdcard.c | 613 ++++++++++++++++++++++++++++++ bsp/mini2440/sdcard.h | 11 + bsp/mini2440/startup.c | 171 +++++++++ bsp/mini2440/touch.c | 254 +++++++++++++ libcpu/arm/s3c24x0/clock.c | 77 ++++ libcpu/arm/s3c24x0/context_gcc.S | 99 +++++ libcpu/arm/s3c24x0/context_rvds.s | 107 ++++++ libcpu/arm/s3c24x0/cpu.c | 143 +++++++ libcpu/arm/s3c24x0/interrupt.c | 117 ++++++ libcpu/arm/s3c24x0/mmu.c | 248 ++++++++++++ libcpu/arm/s3c24x0/rtc.c | 152 ++++++++ libcpu/arm/s3c24x0/rtc.h | 40 ++ libcpu/arm/s3c24x0/s3c24x0.h | 611 +++++++++++++++++++++++++++++ libcpu/arm/s3c24x0/serial.c | 313 +++++++++++++++ libcpu/arm/s3c24x0/serial.h | 58 +++ libcpu/arm/s3c24x0/stack.c | 60 +++ libcpu/arm/s3c24x0/trap.c | 160 ++++++++ 27 files changed, 4574 insertions(+) create mode 100644 bsp/mini2440/SConstruct create mode 100644 bsp/mini2440/application.c create mode 100644 bsp/mini2440/board.c create mode 100644 bsp/mini2440/board.h create mode 100644 bsp/mini2440/console.c create mode 100644 bsp/mini2440/lcd.c create mode 100644 bsp/mini2440/lcd.h create mode 100644 bsp/mini2440/mini2440_ram.ld create mode 100644 bsp/mini2440/rtconfig.h create mode 100644 bsp/mini2440/rtconfig.py create mode 100644 bsp/mini2440/sdcard.c create mode 100644 bsp/mini2440/sdcard.h create mode 100644 bsp/mini2440/startup.c create mode 100644 bsp/mini2440/touch.c create mode 100644 libcpu/arm/s3c24x0/clock.c create mode 100644 libcpu/arm/s3c24x0/context_gcc.S create mode 100644 libcpu/arm/s3c24x0/context_rvds.s create mode 100644 libcpu/arm/s3c24x0/cpu.c create mode 100644 libcpu/arm/s3c24x0/interrupt.c create mode 100644 libcpu/arm/s3c24x0/mmu.c create mode 100644 libcpu/arm/s3c24x0/rtc.c create mode 100644 libcpu/arm/s3c24x0/rtc.h create mode 100644 libcpu/arm/s3c24x0/s3c24x0.h create mode 100644 libcpu/arm/s3c24x0/serial.c create mode 100644 libcpu/arm/s3c24x0/serial.h create mode 100644 libcpu/arm/s3c24x0/stack.c create mode 100644 libcpu/arm/s3c24x0/trap.c diff --git a/bsp/mini2440/SConstruct b/bsp/mini2440/SConstruct new file mode 100644 index 0000000000..a1e02a47cc --- /dev/null +++ b/bsp/mini2440/SConstruct @@ -0,0 +1,51 @@ +import os +import rtconfig + +RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') +target = 'rtthread-s3c2440' + +# search path for C compiler +bsp_path = RTT_ROOT + '/bsp/mini2440' + +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) +env.AppendUnique(CPPPATH = bsp_path) +env.AppendUnique(CCFLAGS = ' -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD') + +Export('env') +Export('RTT_ROOT') +Export('rtconfig') + +objs = SConscript(RTT_ROOT + '/src/SConscript', variant_dir='build/src', duplicate=0) +objs = objs + SConscript(RTT_ROOT + '/libcpu/SConscript', variant_dir='build/libcpu', duplicate=0) + +if rtconfig.RT_USING_MINILIBC: + objs = objs + SConscript(RTT_ROOT + '/libc/minilibc/SConscript', variant_dir='build/minilibc', duplicate=0) + +if rtconfig.RT_USING_FINSH: + objs = objs + SConscript(RTT_ROOT + '/finsh/SConscript', variant_dir='build/finsh', duplicate=0) + +if rtconfig.RT_USING_DFS: + objs = objs + SConscript(RTT_ROOT + '/filesystem/dfs/SConscript', variant_dir='build/filesystem', duplicate=0) + +if rtconfig.RT_USING_LWIP: + objs = objs + SConscript(RTT_ROOT + '/net/lwip/SConscript', variant_dir='build/net/lwip', duplicate=0) + +src_bsp = ['application.c', 'startup.c', 'board.c'] +src_drv = ['rtc.c', 'console.c'] + +if rtconfig.RT_USING_DFS: + src_drv += ['sdcard.c'] + +if rtconfig.RT_USING_LWIP: + src_drv += ['dm9000a.c'] + +objs = objs + env.Object(src_bsp + src_drv) + +TARGET = target + '.' + rtconfig.TARGET_EXT +env.Program(TARGET, objs) +env.AddPostAction(TARGET, rtconfig.POST_ACTION) diff --git a/bsp/mini2440/application.c b/bsp/mini2440/application.c new file mode 100644 index 0000000000..d2753d57ae --- /dev/null +++ b/bsp/mini2440/application.c @@ -0,0 +1,192 @@ +/* + * 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2007-11-20 Yi.Qiu add rtgui application + * 2008-6-28 Bernard no rtgui init + */ + +/** + * @addtogroup s3ceb2410 + */ + +/*@{*/ +#include + +#ifdef RT_USING_RTGUI +#include +#endif + +#ifdef RT_USING_DFS +/* dfs init */ +#include +/* dfs filesystem:FAT filesystem init */ +#include +/* dfs filesystem:EFS filesystem init */ +#include +/* dfs Filesystem APIs */ +#include + +void dfs_init_entry(void* parameter) +{ + /* init the device filesystem */ + dfs_init(); + /* init the fat filesystem */ + fatfs_init(); + /* init the efsl filesystam*/ + efsl_init(); + + /* mount sd card fat partition 1 as root directory */ + dfs_mount("sd1", "/", "efs", 0, 0); + /* mount sd card fat partition 0 */ + //dfs_mount("sd0", "/DEV", "efs", 0, 0); + + rt_kprintf("File System initialized!\n"); +} +#endif + +#ifdef RT_USING_LWIP +#include "lwip/sys.h" +#include "lwip/api.h" + +#ifdef RT_USING_WEBSERVER +extern void thread_webserver(void *parameter); +#endif + +#ifdef RT_USING_FTPSERVER +extern void thread_ftpserver(void *parameter); +#endif + +void thread_tcpecho(void *parameter) +{ + struct netconn *conn, *newconn; + err_t err; + + /* Create a new connection identifier. */ + conn = netconn_new(NETCONN_TCP); + + /* Bind connection to well known port number 7. */ + netconn_bind(conn, NULL, 7); + + /* Tell connection to go into listening mode. */ + netconn_listen(conn); + + while(1) + { + /* Grab new connection. */ + newconn = netconn_accept(conn); + /* Process the new connection. */ + if(newconn != NULL) + { + struct netbuf *buf; + void *data; + u16_t len; + + while((buf = netconn_recv(newconn)) != NULL) + { + do + { + netbuf_data(buf, &data, &len); + err = netconn_write(newconn, data, len, NETCONN_COPY); + if(err != ERR_OK){} + } + while(netbuf_next(buf) >= 0); + netbuf_delete(buf); + } + /* Close connection and discard connection identifier. */ + netconn_delete(newconn); + } + } +} + +void lwip_init_entry(void* parameter) +{ + /* init lwip system */ + lwip_sys_init(); + rt_kprintf("TCP/IP initialized!\n"); +} +#endif + +/* application start function */ +void rt_application_init() +{ +#ifdef RT_USING_DFS + rt_thread_t dfs_init; + + dfs_init = rt_thread_create("tdfs", + dfs_init_entry, RT_NULL, + 2048, 150, 20); + rt_thread_startup(dfs_init); +#endif + +#ifdef RT_USING_LWIP + rt_thread_t lwip_init; + rt_thread_t echo; + + lwip_init = rt_thread_create("tlwip", + lwip_init_entry, RT_NULL, + 1024, 100,20); + rt_thread_startup(lwip_init); + + echo = rt_thread_create("echo", + thread_tcpecho, RT_NULL, + 1024, 200,20); + rt_thread_startup(echo); + +#ifdef RT_USING_WEBSERVER + rt_thread_t webserver; + + webserver = rt_thread_create("twebserv", + thread_webserver, RT_NULL, + 4096, 140, 20); + rt_thread_startup(webserver); +#endif + +#ifdef RT_USING_FTPSERVER + rt_thread_t ftpserver; + + ftpserver = rt_thread_create("tftpserv", + thread_ftpserver, RT_NULL, + 1024, 200, 20); + rt_thread_startup(ftpserver); +#endif + +#endif + +#ifdef RT_USING_RTGUI + { + rtgui_rect_t rect; + + /* init rtgui system */ + rtgui_system_server_init(); + + /* init graphic driver */ + rt_hw_lcd_init(); + + /* register dock panel */ + rect.x1 = 0; + rect.y1 = 0; + rect.x2 = 240; + rect.y2 = 25; + rtgui_panel_register("dock", &rect); + + /* register main panel */ + rect.x1 = 0; + rect.y1 = 25; + rect.x2 = 240; + rect.y2 = 320; + rtgui_panel_register("main", &rect); + + rtgui_system_app_init(); + } +#endif +} + +/*@}*/ diff --git a/bsp/mini2440/board.c b/bsp/mini2440/board.c new file mode 100644 index 0000000000..8031f9fd79 --- /dev/null +++ b/bsp/mini2440/board.c @@ -0,0 +1,181 @@ +/* + * 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-03-24 Bernard first implementation + * 2006-05-05 Bernard add DATA_COUNT definition + * 2006-10-05 Alsor.Z for s3c2410x porting + * 2007-11-20 Yi.Qiu add lcd,touch,console + */ + +#include +#include + +#include "board.h" + +/** + * @addtogroup s3ceb2410 + */ +/*@{*/ + +extern rt_uint32_t PCLK, FCLK, HCLK, UCLK; +extern rt_uint8_t asc16_font[]; +extern rt_uint16_t _rt_hw_framebuffer[]; + +extern void rt_hw_lcd_init(void); +extern void rt_hw_mmu_init(void); +extern void rt_hw_touch_init(void); + +extern void rt_kbd_init(void); +extern void rt_console_init(rt_uint8_t*, rt_uint8_t*, rt_uint8_t); + +extern void rt_hw_get_clock(void); +extern void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn); +extern void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv); + +static rt_uint32_t timer_load_val = 0; + +#define UART0 ((struct uartport *)U0BASE) +struct serial_int_rx uart0_int_rx; +struct serial_device uart0 = +{ + UART0, + &uart0_int_rx, + RT_NULL +}; +struct rt_device uart0_device; + +/** + * This function will handle rtos timer + */ +void rt_timer_handler(int vector) +{ + /* reset TDATA0 */ + TCNTB4 = timer_load_val; + + rt_tick_increase(); +} + +/** + * This function will handle serial + */ +void rt_serial_handler(int vector) +{ + INTSUBMSK |= (BIT_SUB_RXD0); + + rt_hw_serial_isr(&uart0_device); + + SUBSRCPND |= BIT_SUB_RXD0; + + /* Unmask sub interrupt (RXD0) */ + INTSUBMSK &=~(BIT_SUB_RXD0); +} + +/** + * This function will handle init uart + */ +void rt_hw_uart_init(void) +{ + int i; + + GPHCON |= 0xa0; + /*PULLUP is enable */ + GPHUP |= 0x0c; + + /* FIFO enable, Tx/Rx FIFO clear */ + uart0.uart_device->ufcon = 0x1; + /* disable the flow control */ + uart0.uart_device->umcon = 0x0; + /* Normal,No parity,1 stop,8 bit */ + uart0.uart_device->ulcon = 0x3; + /* + * tx=level,rx=edge,disable timeout int.,enable rx error int., + * normal,interrupt or polling + */ + uart0.uart_device->ucon = 0x245; + + /* output PCLK to UART0/1, PWMTIMER */ + CLKCON |= 0x0D00; + + for (i = 0; i < 100; i++); + + /* install uart isr */ + INTSUBMSK &= ~(BIT_SUB_RXD0); + + rt_hw_interrupt_install(INTUART0, rt_serial_handler, RT_NULL); + rt_hw_interrupt_umask(INTUART0); +} + +/** + * This function will init s3ceb2410 board + */ +void rt_hw_board_init() +{ + /* FCLK = 304.8M */ + #define MDIV 68 + #define PDIV 1 + #define SDIV 1 + + //rt_hw_set_clock(SDIV, PDIV, MDIV); + /* HCLK = PCLK = FCLK */ + //rt_hw_set_dividor(0, 0); + + /* use PWM Timer 4 because it has no output */ + /* prescaler for Timer 4 is 16 */ + TCFG0 = 0x0f00; + + /* all divider = 1/2 */ + TCFG1 = 0x0; + + rt_hw_get_clock(); + + if (timer_load_val == 0) + { + /* + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 + * (default) and prescaler = 16. Should be 10390 + * @33.25MHz and 15625 @ 50 MHz + */ + timer_load_val = PCLK/(2 * 16 * 100); + } + /* load value for 10 ms timeout */ + TCNTB4 = timer_load_val; + /* auto load, manual update of Timer 4 */ + TCON = (TCON & ~0x0700000) | 0x600000; + /* auto load, start Timer 4 */ + TCON = (TCON & ~0x0700000) | 0x500000 | 0x3; + /*Enable NAND, USBD, PWM TImer, UART0,1 and GPIO clock,*/ + CLKCON = 0xfffff0; + + /* initialize uart */ + rt_hw_uart_init(); + + /* initialize mmu */ + rt_hw_mmu_init(); + + /* initialize keypad */ + rt_kbd_init(); + + /* initialize console */ + //rt_console_init(&_rt_hw_framebuffer[0], &asc16_font[0], 2); + +#ifdef RT_USING_RTGUI + rt_hw_touch_init(); +#endif + + /* install interrupt handler */ + rt_hw_interrupt_install(INTTIMER4, rt_timer_handler, RT_NULL); + rt_hw_interrupt_umask(INTTIMER4); + + /* stop timer */ + /* TCON = 0x0; */ +} + +/*@}*/ diff --git a/bsp/mini2440/board.h b/bsp/mini2440/board.h new file mode 100644 index 0000000000..83052428e7 --- /dev/null +++ b/bsp/mini2440/board.h @@ -0,0 +1,25 @@ +/* + * 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-10-08 Bernard add board.h to this bsp + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include +#include + +void rt_hw_board_init(void); + +void rt_hw_sdcard_init(void); + +#endif diff --git a/bsp/mini2440/console.c b/bsp/mini2440/console.c new file mode 100644 index 0000000000..a78caac039 --- /dev/null +++ b/bsp/mini2440/console.c @@ -0,0 +1,177 @@ +#include + +#include + +#define RT_CONSOLE_WIDTH 240 +#define RT_CONSOLE_HEIGHT 320 + +#define RT_CONSOLE_FONT_WIDTH 8 +#define RT_CONSOLE_FONT_HEIGHT 16 + +#define RT_CONSOLE_COL (RT_CONSOLE_WIDTH/RT_CONSOLE_FONT_WIDTH) +#define RT_CONSOLE_ROW (RT_CONSOLE_HEIGHT/RT_CONSOLE_FONT_HEIGHT) + +#define RT_CONSOLE_TAB 4 + +#define RT_CONSOLE_FOREPIXEL (0x001f) + +extern struct serial_device uart0; + +struct rt_console +{ + rt_uint8_t* video_ptr; + rt_uint8_t* font_ptr; + + /* bpp and pixel of width */ + rt_uint8_t bpp; + rt_uint32_t pitch; + + /* current cursor */ + rt_uint8_t current_col; + rt_uint8_t current_row; +}; +struct rt_console console; + +void rt_hw_console_init(rt_uint8_t* video_ptr, rt_uint8_t* font_ptr, rt_uint8_t bpp); +void rt_hw_console_newline(); +void rt_hw_console_putc(char c); +void rt_hw_console_clear(); + +void rt_hw_console_init(rt_uint8_t* video_ptr, rt_uint8_t* font_ptr, rt_uint8_t bpp) +{ + rt_memset(&console, 0, sizeof(struct rt_console)); + + console.video_ptr = video_ptr; + console.font_ptr = font_ptr; + console.bpp = bpp; + console.pitch = console.bpp * RT_CONSOLE_WIDTH; + + rt_hw_console_clear(); +} + +void rt_hw_console_putc(char c) +{ + switch (c) + { + case 10: + case 11: + case 12: + case 13: + /* to next line */ + rt_hw_console_newline(); + console.current_col = 0; + break; + + case 9: + console.current_col += RT_CONSOLE_TAB; + break; + + default: + { + if (console.current_col == RT_CONSOLE_COL) + { + rt_hw_console_newline(); + console.current_col = 0; + + rt_hw_console_putc(c); + return; + } + + rt_uint8_t* font_ptr = console.font_ptr + c * RT_CONSOLE_FONT_HEIGHT; + register rt_uint32_t cursor = (console.current_row * RT_CONSOLE_FONT_HEIGHT) * console.pitch + + console.current_col * RT_CONSOLE_FONT_WIDTH * console.bpp; + register rt_uint32_t i, j; + for (i = 0; i < RT_CONSOLE_FONT_HEIGHT; i ++ ) + { + for (j = 0; j < RT_CONSOLE_FONT_WIDTH; j ++) + { + if ( ((font_ptr[i] >> (7-j)) & 0x01) != 0 ) + { + /* draw a pixel */ + rt_uint8_t *ptr = &(console.video_ptr[cursor + i * console.pitch + j * console.bpp]); + switch(console.bpp) + { + case 1: + *ptr = RT_CONSOLE_FOREPIXEL; + break; + case 2: + *(rt_uint16_t*)ptr = RT_CONSOLE_FOREPIXEL; + break; + case 3: + ptr[0] = RT_CONSOLE_FOREPIXEL & 0xff; + ptr[1] = (RT_CONSOLE_FOREPIXEL >> 8) & 0xff; + ptr[2] = (RT_CONSOLE_FOREPIXEL >> 16) & 0xff; + break; + case 4: + *(rt_uint32_t*)ptr = RT_CONSOLE_FOREPIXEL; + break; + } + } + } + } + + console.current_col ++; + } + break; + } +} + +void rt_hw_console_newline() +{ + console.current_row ++; + if (console.current_row >= RT_CONSOLE_ROW) + { + rt_uint32_t i; + + /* scroll to next line */ + for (i = 0; i < RT_CONSOLE_ROW - 1; i ++) + { + rt_memcpy(console.video_ptr + i * RT_CONSOLE_FONT_HEIGHT * console.pitch, + console.video_ptr + (i + 1) * RT_CONSOLE_FONT_HEIGHT * console.pitch, + RT_CONSOLE_FONT_HEIGHT * console.pitch); + } + + /* clear last line */ + rt_memset(console.video_ptr + (RT_CONSOLE_ROW - 1) * RT_CONSOLE_FONT_HEIGHT * console.pitch, + 0, + RT_CONSOLE_FONT_HEIGHT * console.pitch); + + console.current_row = RT_CONSOLE_ROW - 1; + } +} + +void rt_hw_console_clear() +{ + console.current_col = 0; + console.current_row = 0; + + rt_memset(console.video_ptr, 0, RT_CONSOLE_HEIGHT * console.pitch); +} + +/* write one character to serial, must not trigger interrupt */ +void rt_hw_serial_putc(const char c) +{ + /* + to be polite with serial console add a line feed + to the carriage return character + */ + if (c=='\n')rt_hw_serial_putc('\r'); + + while (!(uart0.uart_device->ustat & USTAT_TXB_EMPTY)); + uart0.uart_device->utxh = (c & 0x1FF); +} + +/** + * This function is used by rt_kprintf to display a string on console. + * + * @param str the displayed string + */ +void rt_hw_console_output(const char* str) +{ + while (*str) + { + rt_hw_serial_putc(*str++); + //rt_hw_console_putc(*str++); + } +} + diff --git a/bsp/mini2440/lcd.c b/bsp/mini2440/lcd.c new file mode 100644 index 0000000000..8252c33aee --- /dev/null +++ b/bsp/mini2440/lcd.c @@ -0,0 +1,358 @@ +/* + * File : lcd.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 + * 2007-11-17 Yi.Qiu + */ + +#include + +#include + +#define MVAL (13) +#define MVAL_USED (0) //0=each frame 1=rate by MVAL +#define INVVDEN (1) //0=normal 1=inverted +#define BSWP (0) //Byte swap control +#define HWSWP (1) //Half word swap control + +#define M5D(n) ((n) & 0x1fffff) // To get lower 21bits + +//TFT 240320 +#define LCD_XSIZE_TFT_240320 (240) +#define LCD_YSIZE_TFT_240320 (320) + +#define SCR_XSIZE_TFT_240320 (240) +#define SCR_YSIZE_TFT_240320 (320) + +//TFT 240320 +#define HOZVAL_TFT_240320 (LCD_XSIZE_TFT_240320-1) +#define LINEVAL_TFT_240320 (LCD_YSIZE_TFT_240320-1) + +//Timing parameter for NEC3.5" +#define VBPD_240320 (1) //垂直同步信号的后肩 +#define VFPD_240320 (5) //垂直同步信号的前肩 +#define VSPW_240320 (1) //垂直同步信号的脉宽 + +#define HBPD_240320 (36) //水平同步信号的后肩 +#define HFPD_240320 (19) //水平同步信号的前肩 +#define HSPW_240320 (5) //水平同步信号的脉宽 + +#define CLKVAL_TFT_240320 (2) + +#define GPB1_TO_OUT() (GPBUP &= 0xfffd, GPBCON &= 0xfffffff3, GPBCON |= 0x00000004) +#define GPB1_TO_1() (GPBDAT |= 0x0002) +#define GPB1_TO_0() (GPBDAT &= 0xfffd) + +#define RT_HW_LCD_WIDTH LCD_XSIZE_TFT_240320 +#define RT_HW_LCD_HEIGHT SCR_YSIZE_TFT_240320 + +#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8) +#define S3C2410_LCDCON1_MMODE (1<<7) +#define S3C2410_LCDCON1_DSCAN4 (0<<5) +#define S3C2410_LCDCON1_STN4 (1<<5) +#define S3C2410_LCDCON1_STN8 (2<<5) +#define S3C2410_LCDCON1_TFT (3<<5) + +#define S3C2410_LCDCON1_STN1BPP (0<<1) +#define S3C2410_LCDCON1_STN2GREY (1<<1) +#define S3C2410_LCDCON1_STN4GREY (2<<1) +#define S3C2410_LCDCON1_STN8BPP (3<<1) +#define S3C2410_LCDCON1_STN12BPP (4<<1) + +#define S3C2410_LCDCON1_TFT1BPP (8<<1) +#define S3C2410_LCDCON1_TFT2BPP (9<<1) +#define S3C2410_LCDCON1_TFT4BPP (10<<1) +#define S3C2410_LCDCON1_TFT8BPP (11<<1) +#define S3C2410_LCDCON1_TFT16BPP (12<<1) +#define S3C2410_LCDCON1_TFT24BPP (13<<1) + +#define S3C2410_LCDCON1_ENVID (1) + +#define S3C2410_LCDCON1_MODEMASK 0x1E + +#define S3C2410_LCDCON2_VBPD(x) ((x) << 24) +#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14) +#define S3C2410_LCDCON2_VFPD(x) ((x) << 6) +#define S3C2410_LCDCON2_VSPW(x) ((x) << 0) + +#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF) +#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF) +#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F) + +#define S3C2410_LCDCON3_HBPD(x) ((x) << 19) +#define S3C2410_LCDCON3_WDLY(x) ((x) << 19) +#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8) +#define S3C2410_LCDCON3_HFPD(x) ((x) << 0) +#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0) + +#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F) +#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF) + +#define S3C2410_LCDCON4_MVAL(x) ((x) << 8) +#define S3C2410_LCDCON4_HSPW(x) ((x) << 0) +#define S3C2410_LCDCON4_WLH(x) ((x) << 0) + +#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF) + +#define S3C2410_LCDCON5_BPP24BL (1<<12) +#define S3C2410_LCDCON5_FRM565 (1<<11) +#define S3C2410_LCDCON5_INVVCLK (1<<10) +#define S3C2410_LCDCON5_INVVLINE (1<<9) +#define S3C2410_LCDCON5_INVVFRAME (1<<8) +#define S3C2410_LCDCON5_INVVD (1<<7) +#define S3C2410_LCDCON5_INVVDEN (1<<6) +#define S3C2410_LCDCON5_INVPWREN (1<<5) +#define S3C2410_LCDCON5_INVLEND (1<<4) +#define S3C2410_LCDCON5_PWREN (1<<3) +#define S3C2410_LCDCON5_ENLEND (1<<2) +#define S3C2410_LCDCON5_BSWP (1<<1) +#define S3C2410_LCDCON5_HWSWP (1<<0) + +#define LCDCON1_VALUE S3C2410_LCDCON1_TFT16BPP | \ + S3C2410_LCDCON1_TFT | \ + S3C2410_LCDCON1_CLKVAL(0x04) + +#define LCDCON2_VALUE S3C2410_LCDCON2_VBPD(1) | \ + S3C2410_LCDCON2_LINEVAL(319) | \ + S3C2410_LCDCON2_VFPD(5) | \ + S3C2410_LCDCON2_VSPW(1) + +#define LCDCON3_VALUE S3C2410_LCDCON3_HBPD(36) | \ + S3C2410_LCDCON3_HOZVAL(239) | \ + S3C2410_LCDCON3_HFPD(19) + +#define LCDCON4_VALUE S3C2410_LCDCON4_MVAL(13) | \ + S3C2410_LCDCON4_HSPW(5) + +#define LCDCON5_VALUE S3C2410_LCDCON5_FRM565 | \ + S3C2410_LCDCON5_INVVLINE | \ + S3C2410_LCDCON5_INVVFRAME | \ + S3C2410_LCDCON5_PWREN | \ + S3C2410_LCDCON5_HWSWP + +#define S3C2410_LCDINT_FRSYNC (1<<1) + +volatile rt_uint16_t _rt_hw_framebuffer[RT_HW_LCD_HEIGHT][RT_HW_LCD_WIDTH]; + +void lcd_power_enable(int invpwren,int pwren) +{ + /* GPG4 is setted as LCD_PWREN */ + GPGUP=(GPGUP&(~(1<<4)))|(1<<4); /* Pull-up disable */ + GPGCON=(GPGCON&(~(3<<8)))|(3<<8); /* GPG4=LCD_PWREN */ + GPGDAT = GPGDAT | (1<<4) ; + + /* Enable LCD POWER ENABLE Function */ + LCDCON5=(LCDCON5&(~(1<<3)))|(pwren<<3); /* PWREN */ + LCDCON5=(LCDCON5&(~(1<<5)))|(invpwren<<5); /* INVPWREN */ +} + +void lcd_envid_on_off(int onoff) +{ + if(onoff==1) + /*ENVID=ON*/ + LCDCON1|=1; + else + /*ENVID Off*/ + LCDCON1 =LCDCON1 & 0x3fffe; +} + +//********************** BOARD LCD backlight **************************** +void LcdBkLtSet(rt_uint32_t HiRatio) +{ +#define FREQ_PWM1 1000 + + if(!HiRatio) + { + GPBCON = GPBCON & (~(3<<2)) | (1<<2) ; //GPB1设置为output + GPBDAT &= ~(1<<1); + return; + } + GPBCON = GPBCON & (~(3<<2)) | (2<<2) ; + + if( HiRatio > 100 ) + HiRatio = 100 ; + + TCON = TCON & (~(0xf<<8)) ; // clear manual update bit, stop Timer1 + + TCFG0 &= 0xffffff00; // set Timer 0&1 prescaler 0 + TCFG0 |= 15; //prescaler = 15+1 + + TCFG1 &= 0xffffff0f; // set Timer 1 MUX 1/16 + TCFG1 |= 0x00000030; // set Timer 1 MUX 1/16 + + TCNTB1 = ( 100000000>>8 )/FREQ_PWM1; //if set inverter off, when TCNT2<=TCMP2, TOUT is high, TCNT2>TCMP2, TOUT is low + TCMPB1 = ( TCNTB1*(100-HiRatio))/100 ; //if set inverter on, when TCNT2<=TCMP2, TOUT is low, TCNT2>TCMP2, TOUT is high + + TCON = TCON & (~(0xf<<8)) | (0x0e<<8) ; + TCON = TCON & (~(0xf<<8)) | (0x0d<<8) ; +} + +rt_uint16_t color2index565(rt_uint32_t color) +{ + int r,g,b; + + r = (color>> (0+3)) & 0x1f; + g = (color>> (8+2)) & 0x3f; + b = (color>>(16+3)) & 0x1f; + + return (rt_uint16_t)(b+(g<<5)+(r<<11)); +} + +rt_uint32_t index2color565(int index) +{ + unsigned int r,g,b; + + r = index & 0x1f; + g = (index>>5) & 0x3f; + b = ((unsigned)index >> 11) & 0x1f; + + r = r * 255 / 31; + g = g * 255 / 63; + b = b * 255 / 31; + + return r + (g<<8) + (((rt_uint32_t)b)<<16); +} + +#ifdef RT_USING_RTGUI + +#include +#include + +void rt_hw_lcd_update() +{ + /* nothing */ +} + +rt_uint8_t * rt_hw_lcd_get_framebuffer(void) +{ + return (rt_uint8_t *)_rt_hw_framebuffer; +} + +void rt_hw_lcd_set_pixel(rtgui_color_t *c, int x, int y) +{ + if (x < SCR_XSIZE_TFT_240320 && y < SCR_YSIZE_TFT_240320) + { + _rt_hw_framebuffer[(y)][(x)] = color2index565(*c); + } +} + +void rt_hw_lcd_get_pixel(rtgui_color_t *c, int x, int y) +{ + return ; +} + +void rt_hw_lcd_draw_hline(rtgui_color_t *c, int x1, int x2, int y) +{ + rt_uint32_t idx; + rt_uint16_t color; + + color = color2index565(*c); + + for (idx = x1; idx < x2; idx ++) + { + _rt_hw_framebuffer[y][idx] = color; + } +} + +void rt_hw_lcd_draw_vline(rtgui_color_t *c, int x, int y1, int y2) +{ + rt_uint32_t idy; + rt_uint16_t color; + + color = color2index565(*c); + + for (idy = y1; idy < y2; idy ++) + { + _rt_hw_framebuffer[idy][x] = color; + } +} + +struct rtgui_graphic_driver _rtgui_lcd_driver = +{ + "lcd", + 2, + 240, + 320, + rt_hw_lcd_update, + rt_hw_lcd_get_framebuffer, + rt_hw_lcd_set_pixel, + rt_hw_lcd_get_pixel, + rt_hw_lcd_draw_hline, + rt_hw_lcd_draw_vline +}; + +#include "finsh.h" +void hline(rt_uint32_t c, int x1, int x2, int y) +{ + rtgui_color_t color = (rtgui_color_t)c; + rt_hw_lcd_draw_hline(&color, x1, x2, y); +} + +void vline(rt_uint32_t c, int x, int y1, int y2) +{ + rtgui_color_t color = (rtgui_color_t)c; + rt_hw_lcd_draw_vline(&color, x, y1, y2); +} + +void dump_vline(int x, int y1, int y2) +{ + rt_uint32_t idy; + + for (idy = y1; idy < y2; idy ++) + { + rt_kprintf("0x%04x ", _rt_hw_framebuffer[idy][x]); + + if ((idy + 1) % 8 == 0) + rt_kprintf("\n"); + } + rt_kprintf("\n"); +} + +void rt_hw_lcd_init() +{ + GPB1_TO_OUT(); + GPB1_TO_1(); + + GPCUP = 0x00000000; + GPCCON = 0xaaaa02a9; + + GPDUP = 0x00000000; + GPDCON = 0xaaaaaaaa; + + LCDCON1 = LCDCON1_VALUE; + LCDCON2 = LCDCON2_VALUE; + LCDCON3 = LCDCON3_VALUE; + LCDCON4 = LCDCON4_VALUE; + LCDCON5 = LCDCON5_VALUE; + + LCDSADDR1=(((rt_uint32_t)_rt_hw_framebuffer>>22)<<21)|M5D((rt_uint32_t)_rt_hw_framebuffer>>1); + LCDSADDR2=M5D( ((rt_uint32_t)_rt_hw_framebuffer+(SCR_XSIZE_TFT_240320*LCD_YSIZE_TFT_240320*2))>>1 ); + LCDSADDR3=(((SCR_XSIZE_TFT_240320-LCD_XSIZE_TFT_240320)/1)<<11)|(LCD_XSIZE_TFT_240320/1); + LCDINTMSK|=(3); + LPCSEL &= (~7) ; + TPAL=0; + + LcdBkLtSet( 70 ) ; + lcd_power_enable(0, 1); + lcd_envid_on_off(1); + + /* add lcd driver into graphic driver */ + rtgui_graphic_driver_add(&_rtgui_lcd_driver); + + /* finsh debug */ + finsh_syscall_append("vline", (syscall_func)vline); + finsh_syscall_append("hline", (syscall_func)hline); + finsh_syscall_append("dump_vline", (syscall_func)dump_vline); + + extern void rtgui_topwin_dump(); + finsh_syscall_append("wins", (syscall_func)rtgui_topwin_dump); +} + +#endif diff --git a/bsp/mini2440/lcd.h b/bsp/mini2440/lcd.h new file mode 100644 index 0000000000..dacd92a40b --- /dev/null +++ b/bsp/mini2440/lcd.h @@ -0,0 +1,25 @@ +/* + * File : lcd.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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2008-03-29 Yi.Qiu + */ +#ifndef __LCD_H__ +#define __LCD_H__ + +#include + +void rt_hw_lcd_init(); +void rt_hw_lcd_draw_pixel(int x, int y, rt_uint32_t p); +void rt_hw_lcd_draw_hline(int x1, int x2, int y, rt_uint32_t p); +void rt_hw_lcd_draw_vline(int x, int y1, int y2, rt_uint32_t p); +void rt_hw_lcd_update(); + +#endif diff --git a/bsp/mini2440/mini2440_ram.ld b/bsp/mini2440/mini2440_ram.ld new file mode 100644 index 0000000000..727e65ea0f --- /dev/null +++ b/bsp/mini2440/mini2440_ram.ld @@ -0,0 +1,70 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x30000000; + + . = ALIGN(4); + .text : { + *(.init) + *(.text) + *(.gnu.linkonce.t*) + } + + . = ALIGN(4); + .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) *(.eh_frame) } + + . = ALIGN(4); + .ctors : + { + PROVIDE(__ctors_start__ = .); + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + PROVIDE(__ctors_end__ = .); + } + + .dtors : + { + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + } + + . = ALIGN(4); + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + } + + . = ALIGN(4); + .nobss : { *(.nobss) } + + . = 0x30200000; + .mmu_table : { *(.mmu_table) } + + . = 0x30300000; + . = ALIGN(4); + __bss_start = .; + .bss : { *(.bss) } + __bss_end = .; + + /* stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } + + _end = .; +} diff --git a/bsp/mini2440/rtconfig.h b/bsp/mini2440/rtconfig.h new file mode 100644 index 0000000000..10d35ca3a9 --- /dev/null +++ b/bsp/mini2440/rtconfig.h @@ -0,0 +1,177 @@ +/* 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 256 + +/* Tick per Second*/ +#define RT_TICK_PER_SECOND 100 + +/* SECTION: RT_DEBUG */ +/* Thread Debug*/ +/* #define RT_THREAD_DEBUG */ + +/* Using Hook*/ +#define RT_USING_HOOK + +/* SECTION: IPC */ +/* Using Semaphore*/ +#define RT_USING_SEMAPHORE + +/* Using Mutex*/ +#define RT_USING_MUTEX + +/* Using Event*/ +#define RT_USING_EVENT + +/* Using Faset Event*/ +#define RT_USING_FASTEVENT + +/* Using MailBox*/ +#define RT_USING_MAILBOX + +/* Using Message Queue*/ +#define RT_USING_MESSAGEQUEUE + +/* SECTION: Memory Management */ +/* Using Memory Pool Management*/ +#define RT_USING_MEMPOOL + +/* Using Dynamic Heap Management*/ +#define RT_USING_HEAP + +/* Using Small MM*/ +/* #define RT_USING_SMALL_MEM */ + +/* Using SLAB Allocator*/ +#define RT_USING_SLAB + +/* SECTION: Device System */ +/* Using Device System*/ +#define RT_USING_DEVICE + +/* SECTION: Console options */ +/* the buffer size of console*/ +#define RT_CONSOLEBUF_SIZE 128 + +/* SECTION: FinSH shell options */ +/* Using FinSH as Shell*/ +#define RT_USING_FINSH + +/* SECTION: a runtime libc library */ +/* a runtime libc library*/ +#define RT_USING_NEWLIB + +/* SECTION: a mini libc */ +/* Using mini libc library*/ +/* #define RT_USING_MINILIBC */ + +/* SECTION: C++ support */ +/* Using C++ support*/ +/* #define RT_USING_CPLUSPLUS */ + +/* SECTION: RTGUI support */ +/* using RTGUI support*/ +#define RT_USING_RTGUI + +/* SECTION: Device filesystem support */ +/* using DFS support*/ +#define RT_USING_DFS + +#define RT_USING_WORKDIR + +/* SECTION: DFS options */ +/* the max number of mounted filesystem */ +#define DFS_FILESYSTEMS_MAX 2 +/* the max number of opened files */ +#define DFS_FD_MAX 16 +/* the max number of cached sector */ +#define DFS_CACHE_MAX_NUM 4 + +/* SECTION: lwip, a lighwight TCP/IP protocol stack */ +/* Using lighweight TCP/IP protocol stack*/ +#define RT_USING_LWIP +#define RT_LWIP_DNS + +/* Using webserver goahead support*/ +#define RT_USING_WEBSERVER + +/* Using ftpserver support*/ +#define RT_USING_FTPSERVER + +/* Trace LwIP protocol*/ +/* #define RT_LWIP_DEBUG */ + +/* Enable ICMP protocol*/ +#define RT_LWIP_ICMP + +/* Enable IGMP protocol*/ +#define RT_LWIP_IGMP + +/* Enable UDP protocol*/ +#define RT_LWIP_UDP + +/* Enable TCP protocol*/ +#define RT_LWIP_TCP + +/* the number of simulatenously active TCP connections*/ +#define RT_LWIP_TCP_PCB_NUM 5 + +/* TCP sender buffer space*/ +#define RT_LWIP_TCP_SND_BUF 10240 + +/* Enable SNMP protocol*/ +/* #define RT_LWIP_SNMP */ + +/* Using DHCP*/ +/* #define RT_LWIP_DHCP */ + +#define RT_LWIP_DNS + +/* ip address of target*/ +#define RT_LWIP_IPADDR0 192 +#define RT_LWIP_IPADDR1 168 +#define RT_LWIP_IPADDR2 0 +#define RT_LWIP_IPADDR3 30 + +/* gateway address of target*/ +#define RT_LWIP_GWADDR0 192 +#define RT_LWIP_GWADDR1 168 +#define RT_LWIP_GWADDR2 0 +#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 + +/* the number of blocks for pbuf*/ +#define RT_LWIP_PBUF_NUM 16 + +/* thread priority of tcpip thread*/ +#define RT_LWIP_TCPTHREAD_PRIORITY 128 + +/* mail box size of tcpip thread to wait for*/ +#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8 + +/* thread stack size of tcpip thread*/ +#define RT_LWIP_TCPTHREAD_STACKSIZE 4096 + +/* thread priority of ethnetif thread*/ +#define RT_LWIP_ETHTHREAD_PRIORITY 144 + +/* mail box size of ethnetif thread to wait for*/ +#define RT_LWIP_ETHTHREAD_MBOX_SIZE 32 + +/* thread stack size of ethnetif thread*/ +#define RT_LWIP_ETHTHREAD_STACKSIZE 1024 + +#endif diff --git a/bsp/mini2440/rtconfig.py b/bsp/mini2440/rtconfig.py new file mode 100644 index 0000000000..ab5bc5e1d6 --- /dev/null +++ b/bsp/mini2440/rtconfig.py @@ -0,0 +1,84 @@ +# component options +RT_USING_FINSH = True +RT_USING_DFS = True +RT_USING_DFS_YAFFS2 = False +RT_USING_DFS_EFSL = True +RT_USING_LWIP = True + +# toolchains options +ARCH='arm' +CPU='s3c24x0' +PLATFORM = 'gcc' +EXEC_PATH = 'd:/SourceryGCC/bin' +#PLATFORM = 'armcc' +#EXEC_PATH = 'C:/Keil' +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + 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 = ' -mcpu=arm920t' + CFLAGS = DEVICE + ' -DRT_USING_MINILIBC' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=main.elf.map,-cref,-u,Reset_Handler -T mini2440_rom.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' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --device DARMSTM' + CFLAGS = DEVICE + ' --apcs=interwork' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-stm32.map --scatter mini2440_rom.sct' + + CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC' + LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB' + + EXEC_PATH += '/arm/bin40/' + + if BUILD == 'debug': + CFLAGS += ' -g -O0' + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + RT_USING_MINILIBC = False + if RT_USING_FINSH: + LFLAGS += ' --keep __fsym_* --keep __vsym_*' + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + + CFLAGS = '' + AFLAGS = '' + LFLAGS = '' diff --git a/bsp/mini2440/sdcard.c b/bsp/mini2440/sdcard.c new file mode 100644 index 0000000000..771cb81d83 --- /dev/null +++ b/bsp/mini2440/sdcard.c @@ -0,0 +1,613 @@ +/* + * File : sd.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, 2007, 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 + * 2007-12-02 Yi.Qiu the first version + */ + +#include "sdcard.h" + +extern rt_uint32_t PCLK; +volatile rt_uint32_t rd_cnt; +volatile rt_uint32_t wt_cnt; +volatile rt_int32_t RCA; + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static void sd_delay(rt_uint32_t ms) +{ + ms *= 7326; + while(--ms); +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static int sd_cmd_end(int cmd, int be_resp) +{ + int finish0; + + if(!be_resp) + { + finish0=SDICSTA; + + while((finish0&0x800)!=0x800) + finish0=SDICSTA; + + SDICSTA=finish0; + + return RT_EOK; + } + else + { + finish0=SDICSTA; + + while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) )) + finish0=SDICSTA; + + if(cmd==1 || cmd==41) + { + if( (finish0&0xf00) != 0xa00 ) + { + SDICSTA=finish0; + if(((finish0&0x400)==0x400)) + return RT_ERROR; + } + SDICSTA=finish0; + } + else + { + if( (finish0&0x1f00) != 0xa00 ) + { + rt_kprintf("CMD%d:SDICSTA=0x%x, SDIRSP0=0x%x\n", + cmd, SDICSTA, SDIRSP0); + SDICSTA=finish0; + if(((finish0&0x400)==0x400)) + return RT_ERROR; + } + SDICSTA=finish0; + } + return RT_EOK; + } +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static int sd_data_end(void) +{ + int finish; + + finish=SDIDSTA; + + while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) )) + finish=SDIDSTA; + + if( (finish&0xfc) != 0x10 ) + { + SDIDSTA=0xec; + return RT_ERROR; + } + return RT_EOK; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static void sd_cmd0(void) +{ + SDICARG=0x0; + SDICCON=(1<<8)|0x40; + + sd_cmd_end(0, 0); +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static int sd_cmd55(void) +{ + SDICARG = RCA << 16; + SDICCON = (0x1 << 9) | (0x1 << 8) | 0x77; + + if(sd_cmd_end(55, 1) == RT_ERROR) + return RT_ERROR; + + return RT_EOK; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static void sd_sel_desel(char sel_desel) +{ + if(sel_desel) + { +RECMDS7: + SDICARG =RCA << 16; + SDICCON = (0x1 << 9) | (0x1 << 8) | 0x47; + + if(sd_cmd_end(7, 1) == RT_ERROR) + goto RECMDS7; + + if( SDIRSP0 & (0x1e00 != 0x800)) + goto RECMDS7; + } + else + { +RECMDD7: + SDICARG=0<<16; + SDICCON=(0x1<<8)|0x47; + + if(sd_cmd_end(7, 0) == RT_ERROR) + goto RECMDD7; + } +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static void sd_setbus(void) +{ +SET_BUS: + sd_cmd55(); + + SDICARG=1<<1; + SDICCON=(0x1<<9)|(0x1<<8)|0x46; + + if(sd_cmd_end(6, 1) == RT_ERROR) + goto SET_BUS; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +int sd_mmc_ocr(void) +{ + int i; + + /* Negotiate operating condition for MMC, it makes card ready state */ + for(i=0; i<100; i++) + { + SDICARG = 0xff8000; + SDICCON = (0x1<<9)|(0x1<<8)|0x41; + + /* Check end of CMD1 */ + if((sd_cmd_end(1, 1) == RT_EOK) && (SDIRSP0>>16)==0x80ff) + { + SDICSTA=0xa00; + return RT_EOK; + } + } + SDICSTA=0xa00; + + return RT_ERROR; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +int sd_ocr(void) +{ + int i; + + /* Negotiate operating condition for SD, it makes card ready state */ + for(i=0;i<50;i++) + { + sd_cmd55(); + + SDICARG=0xff8000; + SDICCON=(0x1<<9)|(0x1<<8)|0x69; + + /* if using real board, should replace code here. need to modify qemu in near future*/ + /* Check end of ACMD41 */ + //if( rt_hw_sd_cmd_end(41, 1) && SDIRSP0==0x80ff8000 ) + if( sd_cmd_end(41, 1) == RT_EOK) + { + SDICSTA=0xa00; + return RT_EOK; + } + + sd_delay(200); + } + SDICSTA=0xa00; + + return RT_ERROR; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +rt_uint8_t sd_init(void) +{ + //-- SD controller & card initialize + int i; + /* Important notice for MMC test condition */ + /* Cmd & Data lines must be enabled by pull up resister */ + SDIPRE=PCLK/(INICLK)-1; + SDICON=1; + SDIFSTA=SDIFSTA|(1<<16); + SDIBSIZE = 0x200; + SDIDTIMER=0x7fffff; + + /* Wait 74SDCLK for MMC card */ + for(i=0; i<0x1000; i++); + + sd_cmd0(); + /* Check MMC card OCR */ + if(sd_mmc_ocr() == RT_EOK) + { + rt_kprintf("In MMC ready\n"); + goto RECMD2; + } + rt_kprintf("MMC check end!!\n"); + /* Check SD card OCR */ + if(sd_ocr() == RT_EOK) + { + rt_kprintf("In SD ready\n"); + } + else + { + rt_kprintf("Initialize fail\nNo Card assertion\n"); + return RT_ERROR; + } + +RECMD2: + SDICARG=0x0; + SDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; + if(sd_cmd_end(2, 1) == RT_ERROR) + goto RECMD2; + +RECMD3: + SDICARG=0<<16; + SDICCON=(0x1<<9)|(0x1<<8)|0x43; + if(sd_cmd_end(3, 1) == RT_ERROR) + goto RECMD3; + + RCA=(SDIRSP0 & 0xffff0000 )>>16; + SDIPRE=(PCLK/(SDCLK*2))-1; + if( SDIRSP0 & (0x1e00!=0x600) ) + goto RECMD3; + + sd_sel_desel(1); + sd_delay(200); + sd_setbus(); + + return RT_EOK; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +rt_uint8_t sd_readblock(rt_uint32_t address, rt_uint8_t* buf) +{ + int status; + + rd_cnt=0; + // SDICON |= (1<<1); + SDIDCON = (2 << 22) | (1 << 19) | (1 << 17) | (1 << 16) | (1 << 14) | (2 << 12) | (1 << 0); + SDICARG = address; + +RERDCMD: + SDICCON = (0x1 << 9 ) | (0x1 << 8) | 0x51; + if(sd_cmd_end(17, 1) == RT_ERROR) + goto RERDCMD; + + SDICSTA = 0xa00; + + while(rd_cnt < 128) + { + if((SDIDSTA & 0x20) == 0x20) + { + SDIDSTA = 0x1 << 0x5; + break; + } + status = SDIFSTA; + if((status & 0x1000) == 0x1000) + { +#if 0 + register rt_uint32_t value; + + value = SDIDAT; + + /* swap 4 bytes */ + buf[0] = (value >> 24) & 0xff; + buf[1] = (value >> 16) & 0xff; + buf[2] = (value >> 8) & 0xff; + buf[3] = value & 0xff; +#endif + *(rt_uint32_t *)buf = SDIDAT; + rd_cnt++; + buf += 4; + } + } + if(sd_data_end() == RT_ERROR) + { + rt_kprintf("Dat error\n"); + return RT_ERROR; + } + SDIDSTA = 0x10; + SDIDCON = SDIDCON &~ (7<<12); + SDIFSTA = SDIFSTA & 0x200; + SDIDSTA = 0x10; + + return RT_EOK; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf) +{ + int status; + + wt_cnt=0; + SDIFSTA = SDIFSTA | (1 << 16); + SDIDCON = (2 << 22) | (1 << 20) | (1 << 17) | (1 << 16) | (1 << 14) | (3 << 12) | (1 << 0); + SDICARG = address; + +REWTCMD: + SDICCON = (0x1 << 9) | (0x1 << 8) |0x58; + + if(sd_cmd_end(24, 1) == RT_ERROR) + goto REWTCMD; + + SDICSTA=0xa00; + + while(wt_cnt < 128*1) + { + status = SDIFSTA; + if((status & 0x2000) == 0x2000) + { + SDIDAT=*(rt_uint32_t*)buf; + wt_cnt++; + buf += 4; + } + } + if(sd_data_end() == RT_ERROR) + { + rt_kprintf("Data Error\n"); + return RT_ERROR; + } + SDIDCON = SDIDCON &~ (7<<12); + SDIDSTA = 0x10; + + return RT_EOK; +} + +#ifdef RT_USING_DFS +/* RT-Thread Device Driver Interface */ +#include + +#include + +struct rt_device sdcard_device[4]; +struct dfs_partition part[4]; +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_err_t rt_sdcard_init(rt_device_t dev) +{ + return 0; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag) +{ + return 0; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_err_t rt_sdcard_close(rt_device_t dev) +{ + return 0; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + return 0; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + int i; + struct dfs_partition *part = (struct dfs_partition *)dev->private; + + if ( dev == RT_NULL ) return -DFS_STATUS_EINVAL; + + /* read all sectors */ + for (i = 0; i < size / SECTOR_SIZE; i ++) + { + rt_sem_take(part->lock, RT_WAITING_FOREVER); + sd_readblock((part->offset + i)*SECTOR_SIZE + pos, + (rt_uint8_t*)(buffer + i * SECTOR_SIZE)); + rt_sem_release(part->lock); + } + /* the length of reading must align to SECTOR SIZE */ + return size; +} + +/** + * This function will set a hook function, which will be invoked when a memory + * block is allocated from heap memory. + * + * @param hook the hook function + */ +static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + int i; + struct dfs_partition *part = (struct dfs_partition *)dev->private; + + if ( dev == RT_NULL ) return -DFS_STATUS_EINVAL; + + /* read all sectors */ + for (i = 0; i < size / SECTOR_SIZE; i++) + { + rt_sem_take(part->lock, RT_WAITING_FOREVER); + sd_writeblock((part->offset + i)*SECTOR_SIZE + pos, + (rt_uint8_t*)(buffer + i * SECTOR_SIZE)); + rt_sem_release(part->lock); + } + + /* the length of reading must align to SECTOR SIZE */ + return size; +} + +/** + * This function will register sd card to device system + * + * @param hook the hook function + */ +void rt_hw_sdcard_init() +{ + rt_uint8_t i, status; + rt_uint8_t *sector; + char dname[4]; + char sname[8]; + + if (sd_init() == RT_EOK) + { + /* get the first sector to read partition table */ + sector = (rt_uint8_t*) rt_malloc (512); + if (sector == RT_NULL) + { + rt_kprintf("allocate partition sector buffer failed\n"); + return; + } + status = sd_readblock(0, sector); + if (status == RT_EOK) + { + for(i=0; i<4; i++) + { + /* get the first partition */ + status = dfs_filesystem_get_partition(&part[i], sector, i); + if (status == RT_EOK) + { + rt_snprintf(dname, 4, "sd%d", i); + rt_snprintf(sname, 8, "sem_sd%d", i); + part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); + + /* register sdcard device */ + sdcard_device[i].init = rt_sdcard_init; + sdcard_device[i].open = rt_sdcard_open; + sdcard_device[i].close = rt_sdcard_close; + sdcard_device[i].read = rt_sdcard_read; + sdcard_device[i].write = rt_sdcard_write; + sdcard_device[i].control = rt_sdcard_control; + sdcard_device[i].private= &part[i]; + + rt_device_register(&sdcard_device[i], dname, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + } + else + { + if(i == 0) + { + /* there is no partition table */ + part[0].offset = 0; + part[0].size = 0; + part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO); + + /* register sdcard device */ + sdcard_device[0].init = rt_sdcard_init; + sdcard_device[0].open = rt_sdcard_open; + sdcard_device[0].close = rt_sdcard_close; + sdcard_device[0].read = rt_sdcard_read; + sdcard_device[0].write = rt_sdcard_write; + sdcard_device[0].control = rt_sdcard_control; + sdcard_device[0].private= &part[0]; + + rt_device_register(&sdcard_device[0], "sd0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); + + break; + } + } + } + } + else + { + rt_kprintf("read sdcard first sector failed\n"); + } + + /* release sector buffer */ + rt_free(sector); + + return; + } + else + { + rt_kprintf("sdcard init failed\n"); + } +} + +#endif diff --git a/bsp/mini2440/sdcard.h b/bsp/mini2440/sdcard.h new file mode 100644 index 0000000000..31cb15b797 --- /dev/null +++ b/bsp/mini2440/sdcard.h @@ -0,0 +1,11 @@ +#ifndef __SDCARD_H +#define __SDCARD_H + +#include + +#define INICLK 300000 +#define SDCLK 24000000 +#define MMCCLK 15000000 + +#endif + diff --git a/bsp/mini2440/startup.c b/bsp/mini2440/startup.c new file mode 100644 index 0000000000..169e72830f --- /dev/null +++ b/bsp/mini2440/startup.c @@ -0,0 +1,171 @@ +/* + * 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-02-26 Bernard first implementation + * 2006-05-05 Bernard add two test thread + * 2006-08-10 Bernard use rt_show_version to display version information + * 2008-07-14 Bernard modify the heap memory init parameter + */ + +#include +#include + +#include + +rt_uint8_t _irq_stack_start[1024]; +rt_uint8_t _fiq_stack_start[1024]; +rt_uint8_t _undefined_stack_start[512]; +rt_uint8_t _abort_stack_start[512]; +rt_uint8_t _svc_stack_start[1024] SECTION(".nobss"); + +extern void rt_hw_interrupt_init(void); +extern void rt_hw_board_init(void); +extern void rt_serial_init(void); +extern void rt_system_timer_init(void); +extern void rt_system_scheduler_init(void); +extern void rt_thread_idle_init(void); +extern void rt_hw_cpu_icache_enable(void); +extern void rt_show_version(void); +extern void rt_system_heap_init(void*, void*); +extern void rt_hw_finsh_init(void); +extern void rt_application_init(void); +extern int rtl8019_device_register(char*); + +extern struct serial_device uart0; +extern struct rt_device uart0_device; + +/** + * @addtogroup s3ceb2410 + */ + +/*@{*/ + +#ifdef __CC_ARM + extern rt_uint8_t* __bss_start; + extern rt_uint8_t* __bss_end; +#else + extern rt_uint8_t __bss_start; + extern rt_uint8_t __bss_end; +#endif + +/* + * 4 LEDs on S3CEB2410 : GPF4~GPF7 + */ +void led_set(rt_uint32_t led) +{ + GPFDAT = led; +} + +/* led loop */ +void led_flash(void) +{ + rt_uint32_t i; + + /* change the pin mux to enable the LED output */ + GPFCON = 0x5500; + + led_set(1 << 4); + for ( i = 0; i < 2000000; i++); + + led_set(1 << 5); + for ( i = 0; i < 2000000; i++); + + led_set(1 << 6); + for ( i = 0; i < 2000000; i++); + + led_set(1 << 17); + for ( i = 0; i < 2000000; i++); +} + +#ifdef RT_USING_FINSH +extern void finsh_system_init(void); +#endif + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* enable cpu cache */ + rt_hw_cpu_icache_enable(); + rt_hw_cpu_dcache_enable(); + + /* init hardware interrupt */ + rt_hw_interrupt_init(); + + /* 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(); + + /* init heap memory system */ +#ifdef __CC_ARM + rt_system_heap_init((void*)__bss_end, (void*)0x34000000); +#else + rt_system_heap_init(&__bss_end, (void*)0x34000000); +#endif + + /* init scheduler system */ + rt_system_scheduler_init(); + + /* set idle thread hook */ + rt_thread_idle_sethook(led_flash); + +#ifdef RT_USING_DEVICE + /* register uart1 */ + rt_hw_serial_register(&uart0_device, "uart0", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + &uart0); + rt_hw_sdcard_init(); +#ifdef RT_USING_LWIP + /* init ethernet task */ + eth_system_device_init(); + + /* init rtl8019 device */ + rt_rtl8019_device_register("e0"); +#endif + + /*init all registed devices */ + rt_device_init_all(); +#endif + + /* init application */ + rt_application_init(); + +#ifdef RT_USING_FINSH + /* init finsh */ + finsh_system_init(); +#ifdef RT_USING_DEVICE + finsh_set_device("uart0"); +#endif +#endif + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +/*@}*/ diff --git a/bsp/mini2440/touch.c b/bsp/mini2440/touch.c new file mode 100644 index 0000000000..6e8fb4d56b --- /dev/null +++ b/bsp/mini2440/touch.c @@ -0,0 +1,254 @@ +#include +#include +#include + +/* ADCCON Register Bits */ +#define S3C2410_ADCCON_ECFLG (1<<15) +#define S3C2410_ADCCON_PRSCEN (1<<14) +#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6) +#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6) +#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3) +#define S3C2410_ADCCON_MUXMASK (0x7<<3) +#define S3C2410_ADCCON_STDBM (1<<2) +#define S3C2410_ADCCON_READ_START (1<<1) +#define S3C2410_ADCCON_ENABLE_START (1<<0) +#define S3C2410_ADCCON_STARTMASK (0x3<<0) + + +/* ADCTSC Register Bits */ +#define S3C2410_ADCTSC_UD_SEN (1<<8) /* ghcstop add for s3c2440a */ +#define S3C2410_ADCTSC_YM_SEN (1<<7) +#define S3C2410_ADCTSC_YP_SEN (1<<6) +#define S3C2410_ADCTSC_XM_SEN (1<<5) +#define S3C2410_ADCTSC_XP_SEN (1<<4) +#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3) +#define S3C2410_ADCTSC_AUTO_PST (1<<2) +#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0) + +/* ADCDAT0 Bits */ +#define S3C2410_ADCDAT0_UPDOWN (1<<15) +#define S3C2410_ADCDAT0_AUTO_PST (1<<14) +#define S3C2410_ADCDAT0_XY_PST (0x3<<12) +#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF) + +/* ADCDAT1 Bits */ +#define S3C2410_ADCDAT1_UPDOWN (1<<15) +#define S3C2410_ADCDAT1_AUTO_PST (1<<14) +#define S3C2410_ADCDAT1_XY_PST (0x3<<12) +#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF) + +#define WAIT4INT(x) (((x)<<8) | \ + S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \ + S3C2410_ADCTSC_XY_PST(3)) + +#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \ + S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0)) + +struct s3c2410ts +{ + long xp; + long yp; + int count; + int shift; + + int delay; + int presc; + + char phys[32]; +}; +static struct s3c2410ts ts; + +#define X_MIN 74 +#define X_MAX 934 +#define Y_MIN 65 +#define Y_MAX 933 + +#ifdef RT_USING_RTGUI +#include +void report_touch_input(int updown) +{ + long tmp; + struct rtgui_event_mouse emouse; + + tmp = ts.xp; + ts.xp = ts.yp; + ts.yp = tmp; + + ts.xp >>= ts.shift; + ts.yp >>= ts.shift; + + ts.xp = 240 * (ts.xp-X_MIN)/(X_MAX-X_MIN); + ts.yp = 320 - (320*(ts.yp-Y_MIN)/(Y_MAX-Y_MIN)); + + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.parent.sender = RT_NULL; + + emouse.x = ts.xp; + emouse.y = ts.yp; + + /* set emouse button */ + if (updown) + { + emouse.button = RTGUI_MOUSE_BUTTON_DOWN; + } + else + { + emouse.button = RTGUI_MOUSE_BUTTON_UP; + } + + rt_kprintf("touch %s: ts.x: %d, ts.y: %d, count:%d\n", updown? "down" : "up", + ts.xp, ts.yp, ts.count); + + emouse.button |= RTGUI_MOUSE_BUTTON_LEFT; + + rtgui_server_post_event(&emouse, sizeof(struct rtgui_event_mouse)); +} +#endif + +static int first_down_report; +static void touch_timer_fire(void* parameter) +{ + rt_uint32_t data0; + rt_uint32_t data1; + int updown; + + data0 = ADCDAT0; + data1 = ADCDAT1; + + updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN)); + + if (updown) + { + if (ts.count != 0) + { + // if (first_down_report) + { +#ifdef RT_USING_RTGUI + report_touch_input(updown); + first_down_report = 0; +#endif + } + } + + ts.xp = 0; + ts.yp = 0; + ts.count = 0; + + ADCTSC = S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST; + ADCCON |= S3C2410_ADCCON_ENABLE_START; + } + else + { + // if (ts.xp >= 0 && ts.yp >= 0) + { +#ifdef RT_USING_RTGUI + report_touch_input(updown); + first_down_report = 1; +#endif + } + + ts.count = 0; + + rt_kprintf("touch time fire: up\n"); + + ADCTSC = WAIT4INT(0); + } +} + +void s3c2410_adc_stylus_action() +{ + rt_uint32_t data0; + rt_uint32_t data1; + + data0 = ADCDAT0; + data1 = ADCDAT1; + + ts.xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK; + ts.yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK; + ts.count++; + + if (ts.count < (1<= 0 && ts.yp >= 0) + { + #ifdef RT_USING_RTGUI + report_touch_input(updown); + first_down_report = 1; + #endif + } + + ADCTSC = WAIT4INT(0); + } + + SUBSRCPND |= BIT_SUB_TC; +} + +void rt_touch_handler(int irqno) +{ + if (SUBSRCPND & (1 << 10)) + { + /* INT_SUB_ADC */ + s3c2410_adc_stylus_action(); + } + + if (SUBSRCPND & (1 << 9)) + { + /* INT_SUB_TC */ + s3c2410_intc_stylus_updown(); + } + + /* clear interrupt */ + INTPND |= (1 << INTADC); +} + +void rt_hw_touch_init() +{ + /* init touch screen structure */ + rt_memset(&ts, 0, sizeof(struct s3c2410ts)); + + ts.delay = 5000; + ts.presc = 49; + ts.shift = 2; + + ADCCON = S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(ts.presc); + ADCDLY = ts.delay; + + ADCTSC = WAIT4INT(0); + + rt_hw_interrupt_install(INTADC, rt_touch_handler, RT_NULL); + rt_hw_interrupt_umask(INTADC); + + /* install interrupt handler */ + INTSUBMSK &= ~BIT_SUB_ADC; + INTSUBMSK &= ~BIT_SUB_TC; + + first_down_report = 1; +} diff --git a/libcpu/arm/s3c24x0/clock.c b/libcpu/arm/s3c24x0/clock.c new file mode 100644 index 0000000000..c701829449 --- /dev/null +++ b/libcpu/arm/s3c24x0/clock.c @@ -0,0 +1,77 @@ +/* + * File : clock.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 + * 2008-04-25 Yi.qiu first version + */ + +#include +#include "s3c24x0.h" + +#define CONFIG_SYS_CLK_FREQ 12000000 // Fin = 12.00MHz + +rt_uint32_t PCLK; +rt_uint32_t FCLK; +rt_uint32_t HCLK; +rt_uint32_t UCLK; + +void rt_hw_get_clock(void) +{ + rt_uint32_t val; + rt_uint8_t m, p, s; + + val = MPLLCON; + m = (val>>12)&0xff; + p = (val>>4)&0x3f; + s = val&3; + + FCLK = ((m+8)*(CONFIG_SYS_CLK_FREQ/100)*2)/((p+2)*(1<>1)&3; + p = val&1; + + switch (m) { + case 0: + HCLK = FCLK; + break; + case 1: + HCLK = FCLK>>1; + break; + case 2: + if(s&2) + HCLK = FCLK>>3; + else + HCLK = FCLK>>2; + break; + case 3: + if(s&1) + HCLK = FCLK/6; + else + HCLK = FCLK/3; + break; +} + + if(p) + PCLK = HCLK>>1; + else + PCLK = HCLK; +} + +void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv) +{ + MPLLCON = sdiv | pdiv<<4 | mdiv<<12; +} + +void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn) +{ + CLKDIVN = (hdivn<<1) | pdivn; +} + diff --git a/libcpu/arm/s3c24x0/context_gcc.S b/libcpu/arm/s3c24x0/context_gcc.S new file mode 100644 index 0000000000..80e9245698 --- /dev/null +++ b/libcpu/arm/s3c24x0/context_gcc.S @@ -0,0 +1,99 @@ +/* + * 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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-09-06 XuXinming first version + */ + +/*! + * \addtogroup S3C24X0 + */ +/*@{*/ + +#define NOINT 0xc0 + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mrs r0, cpsr + orr r1, r0, #NOINT + msr cpsr_c, r1 + mov pc, lr + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + msr cpsr, r0 + mov pc, lr + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * r0 --> from + * r1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC) + stmfd sp!, {r0-r12, lr} @ push lr & register file + + mrs r4, cpsr + stmfd sp!, {r4} @ push cpsr + mrs r4, spsr + stmfd sp!, {r4} @ push spsr + + str sp, [r0] @ store sp in preempted tasks TCB + ldr sp, [r1] @ get new task stack pointer + + ldmfd sp!, {r4} @ pop new task spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r4} @ pop new task cpsr + msr cpsr_cxsf, r4 + + ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * r0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + ldr sp, [r0] @ get new task stack pointer + + ldmfd sp!, {r4} @ pop new task spsr + msr spsr_cxsf, r4 + ldmfd sp!, {r4} @ pop new task cpsr + msr cpsr_cxsf, r4 + + ldmfd sp!, {r0-r12, lr, pc} @ pop new task r0-r12, lr & pc + +/* + * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); + */ +.globl rt_thread_switch_interrput_flag +.globl rt_interrupt_from_thread +.globl rt_interrupt_to_thread +.globl 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] + mov pc, lr diff --git a/libcpu/arm/s3c24x0/context_rvds.s b/libcpu/arm/s3c24x0/context_rvds.s new file mode 100644 index 0000000000..82c5adc574 --- /dev/null +++ b/libcpu/arm/s3c24x0/context_rvds.s @@ -0,0 +1,107 @@ +;/* +; * File : context_rvds.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-20 Bernard first version +; */ + +NOINT EQU 0xc0 ; disable interrupt in psr + + AREA |.text|, CODE, READONLY, ALIGN=2 + ARM + REQUIRE8 + PRESERVE8 + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ +rt_hw_interrupt_disable PROC + EXPORT rt_hw_interrupt_disable + MRS r0, cpsr + ORR r1, r0, #NOINT + MSR cpsr_c, r1 + BX lr + ENDP + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ +rt_hw_interrupt_enable PROC + EXPORT rt_hw_interrupt_enable + MSR cpsr_c, 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 + STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC) + STMFD sp!, {r0-r12, lr} ; push lr & register file + + MRS r4, cpsr + STMFD sp!, {r4} ; push cpsr + MRS r4, spsr + STMFD sp!, {r4} ; push spsr + + STR sp, [r0] ; store sp in preempted tasks TCB + LDR sp, [r1] ; get new task stack pointer + + LDMFD sp!, {r4} ; pop new task spsr + MSR spsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task cpsr + MSR cpsr_cxsf, r4 + + LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc + 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 sp, [r0] ; get new task stack pointer + + LDMFD sp!, {r4} ; pop new task spsr + MSR spsr_cxsf, r4 + LDMFD sp!, {r4} ; pop new task cpsr + MSR cpsr_cxsf, r4 + + LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc + ENDP + +;/* +; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); +; */ + IMPORT rt_thread_switch_interrput_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +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 + + END \ No newline at end of file diff --git a/libcpu/arm/s3c24x0/cpu.c b/libcpu/arm/s3c24x0/cpu.c new file mode 100644 index 0000000000..356254a9db --- /dev/null +++ b/libcpu/arm/s3c24x0/cpu.c @@ -0,0 +1,143 @@ +/* + * 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 +#include "s3c24x0.h" + +/** + * @addtogroup S3C24X0 + */ +/*@{*/ + +#define ICACHE_MASK (rt_uint32_t)(1 << 12) +#define DCACHE_MASK (rt_uint32_t)(1 << 2) + +static rt_uint32_t cp15_rd(void) +{ + rt_uint32_t i; + + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + return i; +} + +rt_inline void cache_enable(rt_uint32_t bit) +{ + __asm__ __volatile__( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "orr r0,r0,%0\n\t" \ + "mcr p15,0,r0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); +} +rt_inline void cache_disable(rt_uint32_t bit) +{ + __asm__ __volatile__( \ + "mrc p15,0,r0,c1,c0,0\n\t" \ + "bic r0,r0,%0\n\t" \ + "mcr p15,0,%0,c1,c0,0" \ + : \ + :"r" (bit) \ + :"memory"); +} + +/** + * enable I-Cache + * + */ +void rt_hw_cpu_icache_enable() +{ + cache_enable(ICACHE_MASK); +} + +/** + * disable I-Cache + * + */ +void rt_hw_cpu_icache_disable() +{ + cache_disable(ICACHE_MASK); +} + +/** + * return the status of I-Cache + * + */ +rt_base_t rt_hw_cpu_icache_status() +{ + return (cp15_rd() & ICACHE_MASK); +} + +/** + * enable D-Cache + * + */ +void rt_hw_cpu_dcache_enable() +{ + cache_enable(DCACHE_MASK); +} + +/** + * disable D-Cache + * + */ +void rt_hw_cpu_dcache_disable() +{ + cache_disable(DCACHE_MASK); +} + +/** + * return the status of D-Cache + * + */ +rt_base_t rt_hw_cpu_dcache_status() +{ + return (cp15_rd() & DCACHE_MASK); +} + +/** + * reset cpu by dog's time-out + * + */ +void rt_hw_cpu_reset() +{ + /* Disable all interrupt except the WDT */ + INTMSK = (~((rt_uint32_t)1 << INTWDT)); + + /* Disable watchdog */ + WTCON = 0x0000; + + /* Initialize watchdog timer count register */ + WTCNT = 0x0001; + + /* Enable watchdog timer; assert reset at timer timeout */ + WTCON = 0x0021; + + while(1); /* loop forever and wait for reset to happen */ + + /*NOTREACHED*/ +} + +/** + * shutdown CPU + * + */ +void rt_hw_cpu_shutdown() +{ + rt_kprintf("shutdown...\n"); + + RT_ASSERT(RT_NULL); +} + +/*@}*/ diff --git a/libcpu/arm/s3c24x0/interrupt.c b/libcpu/arm/s3c24x0/interrupt.c new file mode 100644 index 0000000000..4b46b312d0 --- /dev/null +++ b/libcpu/arm/s3c24x0/interrupt.c @@ -0,0 +1,117 @@ +/* + * 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 +#include "s3c24x0.h" + +#define MAX_HANDLERS 32 + +extern rt_uint32_t rt_interrupt_nest; + +/* exception and interrupt handler table */ +rt_isr_handler_t isr_table[MAX_HANDLERS]; +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrput_flag; + +/** + * @addtogroup S3C24X0 + */ +/*@{*/ + +rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) +{ + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); + return RT_NULL; +} + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init() +{ + register rt_uint32_t idx; + + /* all clear source pending */ + SRCPND = 0x0; + + /* all clear sub source pending */ + SUBSRCPND = 0x0; + + /* all=IRQ mode */ + INTMOD = 0x0; + + /* all interrupt disabled include global bit */ + INTMSK = BIT_ALLMSK; + + /* all sub interrupt disable */ + INTSUBMSK = BIT_SUB_ALLMSK; + + /* all clear interrupt pending */ + INTPND = BIT_ALLMSK; + + /* init exceptions table */ + for(idx=0; idx < MAX_HANDLERS; idx++) + { + isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle; + } + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrput_flag = 0; +} + +/** + * This function will mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_mask(rt_uint32_t vector) +{ + INTMSK |= 1 << vector; +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(rt_uint32_t vector) +{ + if (vector == INTNOTUSED6) + { + rt_kprintf("Interrupt vec %d is not used!\n", vector); + // while(1); + } + else if (vector == INTGLOBAL) + INTMSK = 0x0; + else + INTMSK &= ~(1 << vector); +} + +/** + * This function will install a interrupt service routine to a interrupt. + * @param vector the interrupt number + * @param new_handler the interrupt service routine to be installed + * @param old_handler the old interrupt service routine + */ +void rt_hw_interrupt_install(rt_uint32_t vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +{ + if(vector < MAX_HANDLERS) + { + if (*old_handler != RT_NULL) *old_handler = isr_table[vector]; + if (new_handler != RT_NULL) isr_table[vector] = new_handler; + } +} + +/*@}*/ diff --git a/libcpu/arm/s3c24x0/mmu.c b/libcpu/arm/s3c24x0/mmu.c new file mode 100644 index 0000000000..d86621fc53 --- /dev/null +++ b/libcpu/arm/s3c24x0/mmu.c @@ -0,0 +1,248 @@ +/* + * File : mmu.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 + * 2008-04-25 Yi.qiu first version + */ + +#include +#include "s3c24x0.h" + +// #define _MMUTT_STARTADDRESS 0x30080000 +#define _MMUTT_STARTADDRESS 0x30200000 + +#define DESC_SEC (0x2|(1<<4)) +#define CB (3<<2) //cache_on, write_back +#define CNB (2<<2) //cache_on, write_through +#define NCB (1<<2) //cache_off,WR_BUF on +#define NCNB (0<<2) //cache_off,WR_BUF off +#define AP_RW (3<<10) //supervisor=RW, user=RW +#define AP_RO (2<<10) //supervisor=RW, user=RO + +#define DOMAIN_FAULT (0x0) +#define DOMAIN_CHK (0x1) +#define DOMAIN_NOTCHK (0x3) +#define DOMAIN0 (0x0<<5) +#define DOMAIN1 (0x1<<5) + +#define DOMAIN0_ATTR (DOMAIN_CHK<<0) +#define DOMAIN1_ATTR (DOMAIN_FAULT<<2) + +#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) +#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) +#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) +#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) + +void rt_hw_mmu_init(void); + +void mmu_setttbase(register rt_uint32_t i) +{ + asm ("mcr p15, 0, %0, c2, c2, 0": :"r" (i)); +} + +void mmu_setdomain(register rt_uint32_t i) +{ + asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i)); +} + +void mmu_enablemmu() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= 0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disablemmu() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~0x1; + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enableicache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enabledcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disableicache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 12); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disabledcache() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 2); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_enablealignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i |= (1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_disablealignfault() +{ + register rt_uint32_t i; + + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + + i &= ~(1 << 1); + + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); +} + +void mmu_cleaninvalidatedcacheindex(int index) +{ + asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index)); +} + +void mmu_invalidatetlb() +{ + asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0)); +} + +void mmu_invalidateicache() +{ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0)); +} + +void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr) +{ + volatile rt_uint32_t *pTT; + volatile int i,nSec; + pTT=(rt_uint32_t *)_MMUTT_STARTADDRESS+(vaddrStart>>20); + nSec=(vaddrEnd>>20)-(vaddrStart>>20); + for(i=0;i<=nSec;i++) + { + *pTT = attr |(((paddrStart>>20)+i)<<20); + pTT++; + } +} + +void rt_hw_mmu_init(void) +{ + int i,j; + //========================== IMPORTANT NOTE ========================= + //The current stack and code area can't be re-mapped in this routine. + //If you want memory map mapped freely, your own sophiscated mmu + //initialization code is needed. + //=================================================================== + + mmu_disabledcache(); + mmu_disableicache(); + + //If write-back is used,the DCache should be cleared. + for(i=0;i<64;i++) + for(j=0;j<8;j++) + mmu_cleaninvalidatedcacheindex((i<<26)|(j<<5)); + + mmu_invalidateicache(); + + //To complete mmu_Init() fast, Icache may be turned on here. + mmu_enableicache(); + + mmu_disablemmu(); + mmu_invalidatetlb(); + + //mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr); + mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB); //bank0 + mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB); //bank0 + mmu_setmtt(0x04000000,0x07f00000,0,RW_NCNB); //bank0 + mmu_setmtt(0x08000000,0x0ff00000,0x08000000,RW_CNB); //bank1 + mmu_setmtt(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2 + mmu_setmtt(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3 + //mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4 + mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CNB); //bank4 for STRATA Flash + mmu_setmtt(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5 + //30f00000->30100000, 31000000->30200000 + mmu_setmtt(0x30000000,0x30100000,0x30000000,RW_CB); //bank6-1 + mmu_setmtt(0x30200000,0x33e00000,0x30200000,RW_NCNB); //bank6-2 + + mmu_setmtt(0x33f00000,0x33f00000,0x33f00000,RW_CB); //bank6-3 + mmu_setmtt(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7 + + mmu_setmtt(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR + mmu_setmtt(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR + mmu_setmtt(0x5b000000,0x5b000000,0x5b000000,RW_NCNB); //SFR + mmu_setmtt(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//not used + mmu_setmtt(0x60000000,0x67f00000,0x60000000,RW_NCNB); //SFR + + mmu_setttbase(_MMUTT_STARTADDRESS); + + /* DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked) */ + mmu_setdomain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR); + + //mmu_SetProcessId(0x0); + mmu_enablealignfault(); + + mmu_enablemmu(); + mmu_enableicache(); + + /* DCache should be turned on after mmu is turned on. */ + mmu_enabledcache(); +} diff --git a/libcpu/arm/s3c24x0/rtc.c b/libcpu/arm/s3c24x0/rtc.c new file mode 100644 index 0000000000..6f69840569 --- /dev/null +++ b/libcpu/arm/s3c24x0/rtc.c @@ -0,0 +1,152 @@ +/* + * File : rtc.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-04-26 yi.qiu first version + */ + +#include "rtc.h" + +/** + * This function access to rtc + */ +static inline void rt_hw_rtc_access(int a) +{ + switch (a) + { + case RTC_ENABLE: + RTCCON |= 0x01; + break; + + case RTC_DISABLE: + RTCCON &= ~0x01; + break; + } +} + +static inline rt_uint32_t BCD2BIN(rt_uint8_t n) +{ + return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F)); +} + +static inline rt_uint8_t BIN2BCD(rt_uint32_t n) +{ + return (((n / 10) << 4) | (n % 10)); +} + +/** + * This function get rtc time + */ +void rt_hw_rtc_get (struct rtc_time *tmp) +{ + rt_uint8_t sec, min, hour, mday, wday, mon, year; + rt_uint8_t a_sec,a_min, a_hour, a_date, a_mon, a_year, a_armed; + + /* enable access to RTC registers */ + rt_hw_rtc_access(RTC_ENABLE); + + /* read RTC registers */ + do + { + sec = BCDSEC; + min = BCDMIN; + hour = BCDHOUR; + mday = BCDDATE; + wday = BCDDAY; + mon = BCDMON; + year = BCDYEAR; + } while (sec != BCDSEC); + + /* read ALARM registers */ + a_sec = ALMSEC; + a_min = ALMMIN; + a_hour = ALMHOUR; + a_date = ALMDATE; + a_mon = ALMMON; + a_year = ALMYEAR; + a_armed = RTCALM; + + /* disable access to RTC registers */ + rt_hw_rtc_access(RTC_DISABLE); + +#ifdef RTC_DEBUG + rt_kprintf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " + "hr: %02x min: %02x sec: %02x\n", + year, mon, mday, wday, + hour, min, sec); + rt_kprintf ( "Alarms: %02x: year: %02x month: %02x date: %02x hour: %02x min: %02x sec: %02x\n", + a_armed, + a_year, a_mon, a_date, + a_hour, a_min, a_sec); +#endif + + tmp->tm_sec = BCD2BIN(sec & 0x7F); + tmp->tm_min = BCD2BIN(min & 0x7F); + tmp->tm_hour = BCD2BIN(hour & 0x3F); + tmp->tm_mday = BCD2BIN(mday & 0x3F); + tmp->tm_mon = BCD2BIN(mon & 0x1F); + tmp->tm_year = BCD2BIN(year); + tmp->tm_wday = BCD2BIN(wday & 0x07); + if(tmp->tm_year < 70) tmp->tm_year += 2000; + else tmp->tm_year += 1900; + tmp->tm_yday = 0; + tmp->tm_isdst = 0; +#ifdef RTC_DEBUG + rt_kprintf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif +} + +/** + * This function set rtc time + */ +void rt_hw_rtc_set (struct rtc_time *tmp) +{ + rt_uint8_t sec, min, hour, mday, wday, mon, year; + +#ifdef RTC_DEBUG + rt_kprintf ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif + year = BIN2BCD(tmp->tm_year % 100); + mon = BIN2BCD(tmp->tm_mon); + wday = BIN2BCD(tmp->tm_wday); + mday = BIN2BCD(tmp->tm_mday); + hour = BIN2BCD(tmp->tm_hour); + min = BIN2BCD(tmp->tm_min); + sec = BIN2BCD(tmp->tm_sec); + + /* enable access to RTC registers */ + rt_hw_rtc_access(RTC_ENABLE); + + /* write RTC registers */ + BCDSEC = sec; + BCDMIN = min; + BCDHOUR = hour; + BCDDATE = mday; + BCDDAY = wday; + BCDMON = mon; + BCDYEAR = year; + + /* disable access to RTC registers */ + rt_hw_rtc_access(RTC_DISABLE); +} + +/** + * This function reset rtc + */ +void rt_hw_rtc_reset (void) +{ + RTCCON = (RTCCON & ~0x06) | 0x08; + RTCCON &= ~(0x08|0x01); +} + diff --git a/libcpu/arm/s3c24x0/rtc.h b/libcpu/arm/s3c24x0/rtc.h new file mode 100644 index 0000000000..ef052b8acd --- /dev/null +++ b/libcpu/arm/s3c24x0/rtc.h @@ -0,0 +1,40 @@ +#ifndef __RT_HW_SERIAL_H__ +#define __RT_HW_SERIAL_H__ + +#include +#include + +#include "s3c24x0.h" + +#define RTC_DEBUG + +#define RTC_ENABLE 0x01 +#define RTC_DISABLE 0x02 + +static const unsigned char days_in_month[] = +{ + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400)) + +struct rtc_time +{ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +void rt_hw_rtc_get (struct rtc_time *tmp); +void rt_hw_rtc_set (struct rtc_time *tmp); +void rt_hw_rtc_reset (void); +void rt_rtc_time_to_tm(rt_uint32_t time, struct rtc_time *tm); + +#endif diff --git a/libcpu/arm/s3c24x0/s3c24x0.h b/libcpu/arm/s3c24x0/s3c24x0.h new file mode 100644 index 0000000000..f9e779cd23 --- /dev/null +++ b/libcpu/arm/s3c24x0/s3c24x0.h @@ -0,0 +1,611 @@ +/* + * File : s3c24x0.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://openlab.rt-thread.com/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-12-11 Bernard first version + */ + +#ifndef __S3C24X0_H__ +#define __S3C24X0_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @addtogroup S3C24X0 + */ +/*@{*/ + +// Memory control +#define BWSCON (*(volatile unsigned *)0x48000000) //Bus width & wait status +#define BANKCON0 (*(volatile unsigned *)0x48000004) //Boot ROM control +#define BANKCON1 (*(volatile unsigned *)0x48000008) //BANK1 control +#define BANKCON2 (*(volatile unsigned *)0x4800000c) //BANK2 cControl +#define BANKCON3 (*(volatile unsigned *)0x48000010) //BANK3 control +#define BANKCON4 (*(volatile unsigned *)0x48000014) //BANK4 control +#define BANKCON5 (*(volatile unsigned *)0x48000018) //BANK5 control +#define BANKCON6 (*(volatile unsigned *)0x4800001c) //BANK6 control +#define BANKCON7 (*(volatile unsigned *)0x48000020) //BANK7 control +#define REFRESH (*(volatile unsigned *)0x48000024) //DRAM/SDRAM efresh +#define BANKSIZE (*(volatile unsigned *)0x48000028) //Flexible Bank Size +#define MRSRB6 (*(volatile unsigned *)0x4800002c) //Mode egister set for SDRAM +#define MRSRB7 (*(volatile unsigned *)0x48000030) //Mode egister set for SDRAM + + +// USB Host + + +// INTERRUPT +#define SRCPND (*(volatile unsigned *)0x4a000000) //Interrupt request status +#define INTMOD (*(volatile unsigned *)0x4a000004) //Interrupt mode control +#define INTMSK (*(volatile unsigned *)0x4a000008) //Interrupt mask control +#define PRIORITY (*(volatile unsigned *)0x4a00000c) //IRQ priority control +#define INTPND (*(volatile unsigned *)0x4a000010) //Interrupt request status +#define INTOFFSET (*(volatile unsigned *)0x4a000014) //Interruot request source offset +#define SUBSRCPND (*(volatile unsigned *)0x4a000018) //Sub source pending +#define INTSUBMSK (*(volatile unsigned *)0x4a00001c) //Interrupt sub mask + + +// DMA +#define DISRC0 (*(volatile unsigned *)0x4b000000) //DMA 0 Initial source +#define DISRCC0 (*(volatile unsigned *)0x4b000004) //DMA 0 Initial source control +#define DIDST0 (*(volatile unsigned *)0x4b000008) //DMA 0 Initial Destination +#define DIDSTC0 (*(volatile unsigned *)0x4b00000c) //DMA 0 Initial Destination control +#define DCON0 (*(volatile unsigned *)0x4b000010) //DMA 0 Control +#define DSTAT0 (*(volatile unsigned *)0x4b000014) //DMA 0 Status +#define DCSRC0 (*(volatile unsigned *)0x4b000018) //DMA 0 Current source +#define DCDST0 (*(volatile unsigned *)0x4b00001c) //DMA 0 Current destination +#define DMASKTRIG0 (*(volatile unsigned *)0x4b000020) //DMA 0 Mask trigger + +#define DISRC1 (*(volatile unsigned *)0x4b000040) //DMA 1 Initial source +#define DISRCC1 (*(volatile unsigned *)0x4b000044) //DMA 1 Initial source control +#define DIDST1 (*(volatile unsigned *)0x4b000048) //DMA 1 Initial Destination +#define DIDSTC1 (*(volatile unsigned *)0x4b00004c) //DMA 1 Initial Destination control +#define DCON1 (*(volatile unsigned *)0x4b000050) //DMA 1 Control +#define DSTAT1 (*(volatile unsigned *)0x4b000054) //DMA 1 Status +#define DCSRC1 (*(volatile unsigned *)0x4b000058) //DMA 1 Current source +#define DCDST1 (*(volatile unsigned *)0x4b00005c) //DMA 1 Current destination +#define DMASKTRIG1 (*(volatile unsigned *)0x4b000060) //DMA 1 Mask trigger + +#define DISRC2 (*(volatile unsigned *)0x4b000080) //DMA 2 Initial source +#define DISRCC2 (*(volatile unsigned *)0x4b000084) //DMA 2 Initial source control +#define DIDST2 (*(volatile unsigned *)0x4b000088) //DMA 2 Initial Destination +#define DIDSTC2 (*(volatile unsigned *)0x4b00008c) //DMA 2 Initial Destination control +#define DCON2 (*(volatile unsigned *)0x4b000090) //DMA 2 Control +#define DSTAT2 (*(volatile unsigned *)0x4b000094) //DMA 2 Status +#define DCSRC2 (*(volatile unsigned *)0x4b000098) //DMA 2 Current source +#define DCDST2 (*(volatile unsigned *)0x4b00009c) //DMA 2 Current destination +#define DMASKTRIG2 (*(volatile unsigned *)0x4b0000a0) //DMA 2 Mask trigger + +#define DISRC3 (*(volatile unsigned *)0x4b0000c0) //DMA 3 Initial source +#define DISRCC3 (*(volatile unsigned *)0x4b0000c4) //DMA 3 Initial source control +#define DIDST3 (*(volatile unsigned *)0x4b0000c8) //DMA 3 Initial Destination +#define DIDSTC3 (*(volatile unsigned *)0x4b0000cc) //DMA 3 Initial Destination control +#define DCON3 (*(volatile unsigned *)0x4b0000d0) //DMA 3 Control +#define DSTAT3 (*(volatile unsigned *)0x4b0000d4) //DMA 3 Status +#define DCSRC3 (*(volatile unsigned *)0x4b0000d8) //DMA 3 Current source +#define DCDST3 (*(volatile unsigned *)0x4b0000dc) //DMA 3 Current destination +#define DMASKTRIG3 (*(volatile unsigned *)0x4b0000e0) //DMA 3 Mask trigger + + +// CLOCK & POWER MANAGEMENT +#define LOCKTIME (*(volatile unsigned *)0x4c000000) //PLL lock time counter +#define MPLLCON (*(volatile unsigned *)0x4c000004) //MPLL Control +#define UPLLCON (*(volatile unsigned *)0x4c000008) //UPLL Control +#define CLKCON (*(volatile unsigned *)0x4c00000c) //Clock generator control +#define CLKSLOW (*(volatile unsigned *)0x4c000010) //Slow clock control +#define CLKDIVN (*(volatile unsigned *)0x4c000014) //Clock divider control +#define CAMDIVN (*(volatile unsigned *)0x4c000018) //USB, CAM Clock divider control + + +// LCD CONTROLLER +#define LCDCON1 (*(volatile unsigned *)0x4d000000) //LCD control 1 +#define LCDCON2 (*(volatile unsigned *)0x4d000004) //LCD control 2 +#define LCDCON3 (*(volatile unsigned *)0x4d000008) //LCD control 3 +#define LCDCON4 (*(volatile unsigned *)0x4d00000c) //LCD control 4 +#define LCDCON5 (*(volatile unsigned *)0x4d000010) //LCD control 5 +#define LCDSADDR1 (*(volatile unsigned *)0x4d000014) //STN/TFT Frame buffer start address 1 +#define LCDSADDR2 (*(volatile unsigned *)0x4d000018) //STN/TFT Frame buffer start address 2 +#define LCDSADDR3 (*(volatile unsigned *)0x4d00001c) //STN/TFT Virtual screen address set +#define REDLUT (*(volatile unsigned *)0x4d000020) //STN Red lookup table +#define GREENLUT (*(volatile unsigned *)0x4d000024) //STN Green lookup table +#define BLUELUT (*(volatile unsigned *)0x4d000028) //STN Blue lookup table +#define DITHMODE (*(volatile unsigned *)0x4d00004c) //STN Dithering mode +#define TPAL (*(volatile unsigned *)0x4d000050) //TFT Temporary palette +#define LCDINTPND (*(volatile unsigned *)0x4d000054) //LCD Interrupt pending +#define LCDSRCPND (*(volatile unsigned *)0x4d000058) //LCD Interrupt source +#define LCDINTMSK (*(volatile unsigned *)0x4d00005c) //LCD Interrupt mask +#define LPCSEL (*(volatile unsigned *)0x4d000060) //LPC3600 Control +#define PALETTE 0x4d000400 //Palette start address + + +// NAND flash +#define NFCONF (*(volatile unsigned *)0x4e000000) //NAND Flash configuration +#define NFCMD (*(volatile U8 *)0x4e000004) //NADD Flash command +#define NFADDR (*(volatile U8 *)0x4e000008) //NAND Flash address +#define NFDATA (*(volatile U8 *)0x4e00000c) //NAND Flash data +#define NFSTAT (*(volatile unsigned *)0x4e000010) //NAND Flash operation status +#define NFECC (*(volatile unsigned *)0x4e000014) //NAND Flash ECC +#define NFECC0 (*(volatile U8 *)0x4e000014) +#define NFECC1 (*(volatile U8 *)0x4e000015) +#define NFECC2 (*(volatile U8 *)0x4e000016) + +// UART +#define U0BASE (volatile unsigned *)0x50000000 //UART 0 Line control +#define ULCON0 (*(volatile unsigned *)0x50000000) //UART 0 Line control +#define UCON0 (*(volatile unsigned *)0x50000004) //UART 0 Control +#define UFCON0 (*(volatile unsigned *)0x50000008) //UART 0 FIFO control +#define UMCON0 (*(volatile unsigned *)0x5000000c) //UART 0 Modem control +#define USTAT0 (*(volatile unsigned *)0x50000010) //UART 0 Tx/Rx status +#define URXB0 (*(volatile unsigned *)0x50000014) //UART 0 Rx error status +#define UFSTAT0 (*(volatile unsigned *)0x50000018) //UART 0 FIFO status +#define UMSTAT0 (*(volatile unsigned *)0x5000001c) //UART 0 Modem status +#define UBRD0 (*(volatile unsigned *)0x50000028) //UART 0 Baud ate divisor + +#define U1BASE *(volatile unsigned *)0x50004000 //UART 1 Line control +#define ULCON1 (*(volatile unsigned *)0x50004000) //UART 1 Line control +#define UCON1 (*(volatile unsigned *)0x50004004) //UART 1 Control +#define UFCON1 (*(volatile unsigned *)0x50004008) //UART 1 FIFO control +#define UMCON1 (*(volatile unsigned *)0x5000400c) //UART 1 Modem control +#define USTAT1 (*(volatile unsigned *)0x50004010) //UART 1 Tx/Rx status +#define URXB1 (*(volatile unsigned *)0x50004014) //UART 1 Rx error status +#define UFSTAT1 (*(volatile unsigned *)0x50004018) //UART 1 FIFO status +#define UMSTAT1 (*(volatile unsigned *)0x5000401c) //UART 1 Modem status +#define UBRD1 (*(volatile unsigned *)0x50004028) //UART 1 Baud ate divisor + +#define U2BASE *(volatile unsigned *)0x50008000 //UART 2 Line control +#define ULCON2 (*(volatile unsigned *)0x50008000) //UART 2 Line control +#define UCON2 (*(volatile unsigned *)0x50008004) //UART 2 Control +#define UFCON2 (*(volatile unsigned *)0x50008008) //UART 2 FIFO control +#define UMCON2 (*(volatile unsigned *)0x5000800c) //UART 2 Modem control +#define USTAT2 (*(volatile unsigned *)0x50008010) //UART 2 Tx/Rx status +#define URXB2 (*(volatile unsigned *)0x50008014) //UART 2 Rx error status +#define UFSTAT2 (*(volatile unsigned *)0x50008018) //UART 2 FIFO status +#define UMSTAT2 (*(volatile unsigned *)0x5000801c) //UART 2 Modem status +#define UBRD2 (*(volatile unsigned *)0x50008028) //UART 2 Baud ate divisor + +#ifdef __BIG_ENDIAN +#define UTXH0 (*(volatile unsigned char *)0x50000023) //UART 0 Transmission Hold +#define URXH0 (*(volatile unsigned char *)0x50000027) //UART 0 Receive buffer +#define UTXH1 (*(volatile unsigned char *)0x50004023) //UART 1 Transmission Hold +#define URXH1 (*(volatile unsigned char *)0x50004027) //UART 1 Receive buffer +#define UTXH2 (*(volatile unsigned char *)0x50008023) //UART 2 Transmission Hold +#define URXH2 (*(volatile unsigned char *)0x50008027) //UART 2 Receive buffer + +#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000023)=(unsigned char)(ch) +#define RdURXH0() (*(volatile unsigned char *)0x50000027) +#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004023)=(unsigned char)(ch) +#define RdURXH1() (*(volatile unsigned char *)0x50004027) +#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008023)=(unsigned char)(ch) +#define RdURXH2() (*(volatile unsigned char *)0x50008027) + +#else //Little Endian +#define UTXH0 (*(volatile unsigned char *)0x50000020) //UART 0 Transmission Hold +#define URXH0 (*(volatile unsigned char *)0x50000024) //UART 0 Receive buffer +#define UTXH1 (*(volatile unsigned char *)0x50004020) //UART 1 Transmission Hold +#define URXH1 (*(volatile unsigned char *)0x50004024) //UART 1 Receive buffer +#define UTXH2 (*(volatile unsigned char *)0x50008020) //UART 2 Transmission Hold +#define URXH2 (*(volatile unsigned char *)0x50008024) //UART 2 Receive buffer + +#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch) +#define RdURXH0() (*(volatile unsigned char *)0x50000024) +#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004020)=(unsigned char)(ch) +#define RdURXH1() (*(volatile unsigned char *)0x50004024) +#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008020)=(unsigned char)(ch) +#define RdURXH2() (*(volatile unsigned char *)0x50008024) + +#endif + + +// PWM TIMER +#define TCFG0 (*(volatile unsigned *)0x51000000) //Timer 0 configuration +#define TCFG1 (*(volatile unsigned *)0x51000004) //Timer 1 configuration +#define TCON (*(volatile unsigned *)0x51000008) //Timer control +#define TCNTB0 (*(volatile unsigned *)0x5100000c) //Timer count buffer 0 +#define TCMPB0 (*(volatile unsigned *)0x51000010) //Timer compare buffer 0 +#define TCNTO0 (*(volatile unsigned *)0x51000014) //Timer count observation 0 +#define TCNTB1 (*(volatile unsigned *)0x51000018) //Timer count buffer 1 +#define TCMPB1 (*(volatile unsigned *)0x5100001c) //Timer compare buffer 1 +#define TCNTO1 (*(volatile unsigned *)0x51000020) //Timer count observation 1 +#define TCNTB2 (*(volatile unsigned *)0x51000024) //Timer count buffer 2 +#define TCMPB2 (*(volatile unsigned *)0x51000028) //Timer compare buffer 2 +#define TCNTO2 (*(volatile unsigned *)0x5100002c) //Timer count observation 2 +#define TCNTB3 (*(volatile unsigned *)0x51000030) //Timer count buffer 3 +#define TCMPB3 (*(volatile unsigned *)0x51000034) //Timer compare buffer 3 +#define TCNTO3 (*(volatile unsigned *)0x51000038) //Timer count observation 3 +#define TCNTB4 (*(volatile unsigned *)0x5100003c) //Timer count buffer 4 +#define TCNTO4 (*(volatile unsigned *)0x51000040) //Timer count observation 4 + +// Added for 2440 +#define FLTOUT (*(volatile unsigned *)0x560000c0) // Filter output(Read only) +#define DSC0 (*(volatile unsigned *)0x560000c4) // Strength control register 0 +#define DSC1 (*(volatile unsigned *)0x560000c8) // Strength control register 1 +#define MSLCON (*(volatile unsigned *)0x560000cc) // Memory sleep control register + + +// USB DEVICE +#ifdef __BIG_ENDIAN +#define FUNC_ADDR_REG (*(volatile unsigned char *)0x52000143) //Function address +#define PWR_REG (*(volatile unsigned char *)0x52000147) //Power management +#define EP_INT_REG (*(volatile unsigned char *)0x5200014b) //EP Interrupt pending and clear +#define USB_INT_REG (*(volatile unsigned char *)0x5200015b) //USB Interrupt pending and clear +#define EP_INT_EN_REG (*(volatile unsigned char *)0x5200015f) //Interrupt enable +#define USB_INT_EN_REG (*(volatile unsigned char *)0x5200016f) +#define FRAME_NUM1_REG (*(volatile unsigned char *)0x52000173) //Frame number lower byte +#define FRAME_NUM2_REG (*(volatile unsigned char *)0x52000177) //Frame number higher byte +#define INDEX_REG (*(volatile unsigned char *)0x5200017b) //Register index +#define MAXP_REG (*(volatile unsigned char *)0x52000183) //Endpoint max packet +#define EP0_CSR (*(volatile unsigned char *)0x52000187) //Endpoint 0 status +#define IN_CSR1_REG (*(volatile unsigned char *)0x52000187) //In endpoint control status +#define IN_CSR2_REG (*(volatile unsigned char *)0x5200018b) +#define OUT_CSR1_REG (*(volatile unsigned char *)0x52000193) //Out endpoint control status +#define OUT_CSR2_REG (*(volatile unsigned char *)0x52000197) +#define OUT_FIFO_CNT1_REG (*(volatile unsigned char *)0x5200019b) //Endpoint out write count +#define OUT_FIFO_CNT2_REG (*(volatile unsigned char *)0x5200019f) +#define EP0_FIFO (*(volatile unsigned char *)0x520001c3) //Endpoint 0 FIFO +#define EP1_FIFO (*(volatile unsigned char *)0x520001c7) //Endpoint 1 FIFO +#define EP2_FIFO (*(volatile unsigned char *)0x520001cb) //Endpoint 2 FIFO +#define EP3_FIFO (*(volatile unsigned char *)0x520001cf) //Endpoint 3 FIFO +#define EP4_FIFO (*(volatile unsigned char *)0x520001d3) //Endpoint 4 FIFO +#define EP1_DMA_CON (*(volatile unsigned char *)0x52000203) //EP1 DMA interface control +#define EP1_DMA_UNIT (*(volatile unsigned char *)0x52000207) //EP1 DMA Tx unit counter +#define EP1_DMA_FIFO (*(volatile unsigned char *)0x5200020b) //EP1 DMA Tx FIFO counter +#define EP1_DMA_TTC_L (*(volatile unsigned char *)0x5200020f) //EP1 DMA total Tx counter +#define EP1_DMA_TTC_M (*(volatile unsigned char *)0x52000213) +#define EP1_DMA_TTC_H (*(volatile unsigned char *)0x52000217) +#define EP2_DMA_CON (*(volatile unsigned char *)0x5200021b) //EP2 DMA interface control +#define EP2_DMA_UNIT (*(volatile unsigned char *)0x5200021f) //EP2 DMA Tx unit counter +#define EP2_DMA_FIFO (*(volatile unsigned char *)0x52000223) //EP2 DMA Tx FIFO counter +#define EP2_DMA_TTC_L (*(volatile unsigned char *)0x52000227) //EP2 DMA total Tx counter +#define EP2_DMA_TTC_M (*(volatile unsigned char *)0x5200022b) +#define EP2_DMA_TTC_H (*(volatile unsigned char *)0x5200022f) +#define EP3_DMA_CON (*(volatile unsigned char *)0x52000243) //EP3 DMA interface control +#define EP3_DMA_UNIT (*(volatile unsigned char *)0x52000247) //EP3 DMA Tx unit counter +#define EP3_DMA_FIFO (*(volatile unsigned char *)0x5200024b) //EP3 DMA Tx FIFO counter +#define EP3_DMA_TTC_L (*(volatile unsigned char *)0x5200024f) //EP3 DMA total Tx counter +#define EP3_DMA_TTC_M (*(volatile unsigned char *)0x52000253) +#define EP3_DMA_TTC_H (*(volatile unsigned char *)0x52000257) +#define EP4_DMA_CON (*(volatile unsigned char *)0x5200025b) //EP4 DMA interface control +#define EP4_DMA_UNIT (*(volatile unsigned char *)0x5200025f) //EP4 DMA Tx unit counter +#define EP4_DMA_FIFO (*(volatile unsigned char *)0x52000263) //EP4 DMA Tx FIFO counter +#define EP4_DMA_TTC_L (*(volatile unsigned char *)0x52000267) //EP4 DMA total Tx counter +#define EP4_DMA_TTC_M (*(volatile unsigned char *)0x5200026b) +#define EP4_DMA_TTC_H (*(volatile unsigned char *)0x5200026f) + +#else // Little Endian +#define FUNC_ADDR_REG (*(volatile unsigned char *)0x52000140) //Function address +#define PWR_REG (*(volatile unsigned char *)0x52000144) //Power management +#define EP_INT_REG (*(volatile unsigned char *)0x52000148) //EP Interrupt pending and clear +#define USB_INT_REG (*(volatile unsigned char *)0x52000158) //USB Interrupt pending and clear +#define EP_INT_EN_REG (*(volatile unsigned char *)0x5200015c) //Interrupt enable +#define USB_INT_EN_REG (*(volatile unsigned char *)0x5200016c) +#define FRAME_NUM1_REG (*(volatile unsigned char *)0x52000170) //Frame number lower byte +#define FRAME_NUM2_REG (*(volatile unsigned char *)0x52000174) //Frame number higher byte +#define INDEX_REG (*(volatile unsigned char *)0x52000178) //Register index +#define MAXP_REG (*(volatile unsigned char *)0x52000180) //Endpoint max packet +#define EP0_CSR (*(volatile unsigned char *)0x52000184) //Endpoint 0 status +#define IN_CSR1_REG (*(volatile unsigned char *)0x52000184) //In endpoint control status +#define IN_CSR2_REG (*(volatile unsigned char *)0x52000188) +#define OUT_CSR1_REG (*(volatile unsigned char *)0x52000190) //Out endpoint control status +#define OUT_CSR2_REG (*(volatile unsigned char *)0x52000194) +#define OUT_FIFO_CNT1_REG (*(volatile unsigned char *)0x52000198) //Endpoint out write count +#define OUT_FIFO_CNT2_REG (*(volatile unsigned char *)0x5200019c) +#define EP0_FIFO (*(volatile unsigned char *)0x520001c0) //Endpoint 0 FIFO +#define EP1_FIFO (*(volatile unsigned char *)0x520001c4) //Endpoint 1 FIFO +#define EP2_FIFO (*(volatile unsigned char *)0x520001c8) //Endpoint 2 FIFO +#define EP3_FIFO (*(volatile unsigned char *)0x520001cc) //Endpoint 3 FIFO +#define EP4_FIFO (*(volatile unsigned char *)0x520001d0) //Endpoint 4 FIFO +#define EP1_DMA_CON (*(volatile unsigned char *)0x52000200) //EP1 DMA interface control +#define EP1_DMA_UNIT (*(volatile unsigned char *)0x52000204) //EP1 DMA Tx unit counter +#define EP1_DMA_FIFO (*(volatile unsigned char *)0x52000208) //EP1 DMA Tx FIFO counter +#define EP1_DMA_TTC_L (*(volatile unsigned char *)0x5200020c) //EP1 DMA total Tx counter +#define EP1_DMA_TTC_M (*(volatile unsigned char *)0x52000210) +#define EP1_DMA_TTC_H (*(volatile unsigned char *)0x52000214) +#define EP2_DMA_CON (*(volatile unsigned char *)0x52000218) //EP2 DMA interface control +#define EP2_DMA_UNIT (*(volatile unsigned char *)0x5200021c) //EP2 DMA Tx unit counter +#define EP2_DMA_FIFO (*(volatile unsigned char *)0x52000220) //EP2 DMA Tx FIFO counter +#define EP2_DMA_TTC_L (*(volatile unsigned char *)0x52000224) //EP2 DMA total Tx counter +#define EP2_DMA_TTC_M (*(volatile unsigned char *)0x52000228) +#define EP2_DMA_TTC_H (*(volatile unsigned char *)0x5200022c) +#define EP3_DMA_CON (*(volatile unsigned char *)0x52000240) //EP3 DMA interface control +#define EP3_DMA_UNIT (*(volatile unsigned char *)0x52000244) //EP3 DMA Tx unit counter +#define EP3_DMA_FIFO (*(volatile unsigned char *)0x52000248) //EP3 DMA Tx FIFO counter +#define EP3_DMA_TTC_L (*(volatile unsigned char *)0x5200024c) //EP3 DMA total Tx counter +#define EP3_DMA_TTC_M (*(volatile unsigned char *)0x52000250) +#define EP3_DMA_TTC_H (*(volatile unsigned char *)0x52000254) +#define EP4_DMA_CON (*(volatile unsigned char *)0x52000258) //EP4 DMA interface control +#define EP4_DMA_UNIT (*(volatile unsigned char *)0x5200025c) //EP4 DMA Tx unit counter +#define EP4_DMA_FIFO (*(volatile unsigned char *)0x52000260) //EP4 DMA Tx FIFO counter +#define EP4_DMA_TTC_L (*(volatile unsigned char *)0x52000264) //EP4 DMA total Tx counter +#define EP4_DMA_TTC_M (*(volatile unsigned char *)0x52000268) +#define EP4_DMA_TTC_H (*(volatile unsigned char *)0x5200026c) +#endif // __BIG_ENDIAN + + +// WATCH DOG TIMER +#define WTCON (*(volatile unsigned *)0x53000000) //Watch-dog timer mode +#define WTDAT (*(volatile unsigned *)0x53000004) //Watch-dog timer data +#define WTCNT (*(volatile unsigned *)0x53000008) //Eatch-dog timer count + + +// IIC +#define IICCON (*(volatile unsigned *)0x54000000) //IIC control +#define IICSTAT (*(volatile unsigned *)0x54000004) //IIC status +#define IICADD (*(volatile unsigned *)0x54000008) //IIC address +#define IICDS (*(volatile unsigned *)0x5400000c) //IIC data shift + + +// IIS +#define IISCON (*(volatile unsigned *)0x55000000) //IIS Control +#define IISMOD (*(volatile unsigned *)0x55000004) //IIS Mode +#define IISPSR (*(volatile unsigned *)0x55000008) //IIS Prescaler +#define IISFCON (*(volatile unsigned *)0x5500000c) //IIS FIFO control + +#ifdef __BIG_ENDIAN +#define IISFIFO ((volatile unsigned short *)0x55000012) //IIS FIFO entry + +#else //Little Endian +#define IISFIFO ((volatile unsigned short *)0x55000010) //IIS FIFO entry + +#endif + + +// I/O PORT +#define GPACON (*(volatile unsigned *)0x56000000) //Port A control +#define GPADAT (*(volatile unsigned *)0x56000004) //Port A data + +#define GPBCON (*(volatile unsigned *)0x56000010) //Port B control +#define GPBDAT (*(volatile unsigned *)0x56000014) //Port B data +#define GPBUP (*(volatile unsigned *)0x56000018) //Pull-up control B + +#define GPCCON (*(volatile unsigned *)0x56000020) //Port C control +#define GPCDAT (*(volatile unsigned *)0x56000024) //Port C data +#define GPCUP (*(volatile unsigned *)0x56000028) //Pull-up control C + +#define GPDCON (*(volatile unsigned *)0x56000030) //Port D control +#define GPDDAT (*(volatile unsigned *)0x56000034) //Port D data +#define GPDUP (*(volatile unsigned *)0x56000038) //Pull-up control D + +#define GPECON (*(volatile unsigned *)0x56000040) //Port E control +#define GPEDAT (*(volatile unsigned *)0x56000044) //Port E data +#define GPEUP (*(volatile unsigned *)0x56000048) //Pull-up control E + +#define GPFCON (*(volatile unsigned *)0x56000050) //Port F control +#define GPFDAT (*(volatile unsigned *)0x56000054) //Port F data +#define GPFUP (*(volatile unsigned *)0x56000058) //Pull-up control F + +#define GPGCON (*(volatile unsigned *)0x56000060) //Port G control +#define GPGDAT (*(volatile unsigned *)0x56000064) //Port G data +#define GPGUP (*(volatile unsigned *)0x56000068) //Pull-up control G + +#define GPHCON (*(volatile unsigned *)0x56000070) //Port H control +#define GPHDAT (*(volatile unsigned *)0x56000074) //Port H data +#define GPHUP (*(volatile unsigned *)0x56000078) //Pull-up control H + +#define GPJCON (*(volatile unsigned *)0x560000d0) //Port J control +#define GPJDAT (*(volatile unsigned *)0x560000d4) //Port J data +#define GPJUP (*(volatile unsigned *)0x560000d8) //Pull-up control J + +#define MISCCR (*(volatile unsigned *)0x56000080) //Miscellaneous control +#define DCLKCON (*(volatile unsigned *)0x56000084) //DCLK0/1 control +#define EXTINT0 (*(volatile unsigned *)0x56000088) //External interrupt control egister 0 +#define EXTINT1 (*(volatile unsigned *)0x5600008c) //External interrupt control egister 1 +#define EXTINT2 (*(volatile unsigned *)0x56000090) //External interrupt control egister 2 +#define EINTFLT0 (*(volatile unsigned *)0x56000094) //Reserved +#define EINTFLT1 (*(volatile unsigned *)0x56000098) //Reserved +#define EINTFLT2 (*(volatile unsigned *)0x5600009c) //External interrupt filter control egister 2 +#define EINTFLT3 (*(volatile unsigned *)0x560000a0) //External interrupt filter control egister 3 +#define EINTMASK (*(volatile unsigned *)0x560000a4) //External interrupt mask +#define EINTPEND (*(volatile unsigned *)0x560000a8) //External interrupt pending +#define GSTATUS0 (*(volatile unsigned *)0x560000ac) //External pin status +#define GSTATUS1 (*(volatile unsigned *)0x560000b0) //Chip ID(0x32410000) +#define GSTATUS2 (*(volatile unsigned *)0x560000b4) //Reset type +#define GSTATUS3 (*(volatile unsigned *)0x560000b8) //Saved data0(32-bit) before entering POWER_OFF mode +#define GSTATUS4 (*(volatile unsigned *)0x560000bc) //Saved data0(32-bit) before entering POWER_OFF mode + + +// RTC +#ifdef __BIG_ENDIAN +#define RTCCON (*(volatile unsigned char *)0x57000043) //RTC control +#define TICNT (*(volatile unsigned char *)0x57000047) //Tick time count +#define RTCALM (*(volatile unsigned char *)0x57000053) //RTC alarm control +#define ALMSEC (*(volatile unsigned char *)0x57000057) //Alarm second +#define ALMMIN (*(volatile unsigned char *)0x5700005b) //Alarm minute +#define ALMHOUR (*(volatile unsigned char *)0x5700005f) //Alarm Hour +#define ALMDATE (*(volatile unsigned char *)0x57000063) //Alarm day <-- May 06, 2002 SOP +#define ALMMON (*(volatile unsigned char *)0x57000067) //Alarm month +#define ALMYEAR (*(volatile unsigned char *)0x5700006b) //Alarm year +#define RTCRST (*(volatile unsigned char *)0x5700006f) //RTC ound eset +#define BCDSEC (*(volatile unsigned char *)0x57000073) //BCD second +#define BCDMIN (*(volatile unsigned char *)0x57000077) //BCD minute +#define BCDHOUR (*(volatile unsigned char *)0x5700007b) //BCD hour +#define BCDDATE (*(volatile unsigned char *)0x5700007f) //BCD day <-- May 06, 2002 SOP +#define BCDDAY (*(volatile unsigned char *)0x57000083) //BCD date <-- May 06, 2002 SOP +#define BCDMON (*(volatile unsigned char *)0x57000087) //BCD month +#define BCDYEAR (*(volatile unsigned char *)0x5700008b) //BCD year + +#else //Little Endian +#define RTCCON (*(volatile unsigned char *)0x57000040) //RTC control +#define TICNT (*(volatile unsigned char *)0x57000044) //Tick time count +#define RTCALM (*(volatile unsigned char *)0x57000050) //RTC alarm control +#define ALMSEC (*(volatile unsigned char *)0x57000054) //Alarm second +#define ALMMIN (*(volatile unsigned char *)0x57000058) //Alarm minute +#define ALMHOUR (*(volatile unsigned char *)0x5700005c) //Alarm Hour +#define ALMDATE (*(volatile unsigned char *)0x57000060) //Alarm day <-- May 06, 2002 SOP +#define ALMMON (*(volatile unsigned char *)0x57000064) //Alarm month +#define ALMYEAR (*(volatile unsigned char *)0x57000068) //Alarm year +#define RTCRST (*(volatile unsigned char *)0x5700006c) //RTC ound eset +#define BCDSEC (*(volatile unsigned char *)0x57000070) //BCD second +#define BCDMIN (*(volatile unsigned char *)0x57000074) //BCD minute +#define BCDHOUR (*(volatile unsigned char *)0x57000078) //BCD hour +#define BCDDATE (*(volatile unsigned char *)0x5700007c) //BCD day <-- May 06, 2002 SOP +#define BCDDAY (*(volatile unsigned char *)0x57000080) //BCD date <-- May 06, 2002 SOP +#define BCDMON (*(volatile unsigned char *)0x57000084) //BCD month +#define BCDYEAR (*(volatile unsigned char *)0x57000088) //BCD year +#endif //RTC + + +// ADC +#define ADCCON (*(volatile unsigned *)0x58000000) //ADC control +#define ADCTSC (*(volatile unsigned *)0x58000004) //ADC touch screen control +#define ADCDLY (*(volatile unsigned *)0x58000008) //ADC start or Interval Delay +#define ADCDAT0 (*(volatile unsigned *)0x5800000c) //ADC conversion data 0 +#define ADCDAT1 (*(volatile unsigned *)0x58000010) //ADC conversion data 1 + +// SPI +#define SPCON0 (*(volatile unsigned *)0x59000000) //SPI0 control +#define SPSTA0 (*(volatile unsigned *)0x59000004) //SPI0 status +#define SPPIN0 (*(volatile unsigned *)0x59000008) //SPI0 pin control +#define SPPRE0 (*(volatile unsigned *)0x5900000c) //SPI0 baud ate prescaler +#define SPTDAT0 (*(volatile unsigned *)0x59000010) //SPI0 Tx data +#define SPRDAT0 (*(volatile unsigned *)0x59000014) //SPI0 Rx data + +#define SPCON1 (*(volatile unsigned *)0x59000020) //SPI1 control +#define SPSTA1 (*(volatile unsigned *)0x59000024) //SPI1 status +#define SPPIN1 (*(volatile unsigned *)0x59000028) //SPI1 pin control +#define SPPRE1 (*(volatile unsigned *)0x5900002c) //SPI1 baud ate prescaler +#define SPTDAT1 (*(volatile unsigned *)0x59000030) //SPI1 Tx data +#define SPRDAT1 (*(volatile unsigned *)0x59000034) //SPI1 Rx data + + +// SD Interface +#define SDICON (*(volatile unsigned *)0x5a000000) //SDI control +#define SDIPRE (*(volatile unsigned *)0x5a000004) //SDI baud ate prescaler +#define SDICARG (*(volatile unsigned *)0x5a000008) //SDI command argument +#define SDICCON (*(volatile unsigned *)0x5a00000c) //SDI command control +#define SDICSTA (*(volatile unsigned *)0x5a000010) //SDI command status +#define SDIRSP0 (*(volatile unsigned *)0x5a000014) //SDI esponse 0 +#define SDIRSP1 (*(volatile unsigned *)0x5a000018) //SDI esponse 1 +#define SDIRSP2 (*(volatile unsigned *)0x5a00001c) //SDI esponse 2 +#define SDIRSP3 (*(volatile unsigned *)0x5a000020) //SDI esponse 3 +#define SDIDTIMER (*(volatile unsigned *)0x5a000024) //SDI data/busy timer +#define SDIBSIZE (*(volatile unsigned *)0x5a000028) //SDI block size +#define SDIDCON (*(volatile unsigned *)0x5a00002c) //SDI data control +#define SDIDCNT (*(volatile unsigned *)0x5a000030) //SDI data emain counter +#define SDIDSTA (*(volatile unsigned *)0x5a000034) //SDI data status +#define SDIFSTA (*(volatile unsigned *)0x5a000038) //SDI FIFO status +#define SDIIMSK (*(volatile unsigned *)0x5a000040) //SDI interrupt mask + +#ifdef __BIG_ENDIAN /* edited for 2440A */ +#define SDIDAT (*(volatile unsigned *)0x5a00004c) +#else // Little Endian +#define SDIDAT (*(volatile unsigned *)0x5a000040) +#endif //SD Interface + +// PENDING BIT +#define INTEINT0 (0) +#define INTEINT1 (1) +#define INTEINT2 (2) +#define INTEINT3 (3) +#define INTEINT4_7 (4) +#define INTEINT8_23 (5) +#define INTNOTUSED6 (6) +#define INTBAT_FLT (7) +#define INTTICK (8) +#define INTWDT (9) +#define INTTIMER0 (10) +#define INTTIMER1 (11) +#define INTTIMER2 (12) +#define INTTIMER3 (13) +#define INTTIMER4 (14) +#define INTUART2 (15) +#define INTLCD (16) +#define INTDMA0 (17) +#define INTDMA1 (18) +#define INTDMA2 (19) +#define INTDMA3 (20) +#define INTSDI (21) +#define INTSPI0 (22) +#define INTUART1 (23) +//#define INTNOTUSED24 (24) +#define INTNIC (24) +#define INTUSBD (25) +#define INTUSBH (26) +#define INTIIC (27) +#define INTUART0 (28) +#define INTSPI1 (29) +#define INTRTC (30) +#define INTADC (31) +#define BIT_ALLMSK (0xffffffff) + +#define BIT_SUB_ALLMSK (0x7ff) +#define INTSUB_ADC (10) +#define INTSUB_TC (9) +#define INTSUB_ERR2 (8) +#define INTSUB_TXD2 (7) +#define INTSUB_RXD2 (6) +#define INTSUB_ERR1 (5) +#define INTSUB_TXD1 (4) +#define INTSUB_RXD1 (3) +#define INTSUB_ERR0 (2) +#define INTSUB_TXD0 (1) +#define INTSUB_RXD0 (0) + +#define BIT_SUB_ADC (0x1<<10) +#define BIT_SUB_TC (0x1<<9) +#define BIT_SUB_ERR2 (0x1<<8) +#define BIT_SUB_TXD2 (0x1<<7) +#define BIT_SUB_RXD2 (0x1<<6) +#define BIT_SUB_ERR1 (0x1<<5) +#define BIT_SUB_TXD1 (0x1<<4) +#define BIT_SUB_RXD1 (0x1<<3) +#define BIT_SUB_ERR0 (0x1<<2) +#define BIT_SUB_TXD0 (0x1<<1) +#define BIT_SUB_RXD0 (0x1<<0) + +#define ClearPending(bit) {SRCPND = bit;INTPND = bit;INTPND;} +//Wait until INTPND is changed for the case that the ISR is very short. + +#define INTGLOBAL 32 + +/*****************************/ +/* CPU Mode */ +/*****************************/ +#define USERMODE 0x10 +#define FIQMODE 0x11 +#define IRQMODE 0x12 +#define SVCMODE 0x13 +#define ABORTMODE 0x17 +#define UNDEFMODE 0x1b +#define MODEMASK 0x1f +#define NOINT 0xc0 + +struct rt_hw_register +{ + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t fp; + rt_uint32_t ip; + rt_uint32_t sp; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t cpsr; + rt_uint32_t ORIG_r0; +}; + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif diff --git a/libcpu/arm/s3c24x0/serial.c b/libcpu/arm/s3c24x0/serial.c new file mode 100644 index 0000000000..2a572f0dfa --- /dev/null +++ b/libcpu/arm/s3c24x0/serial.c @@ -0,0 +1,313 @@ +/* + * 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 + * 2006-03-13 Bernard first version + * 2009-04-20 yi.qiu modified according bernard's stm32 version + */ + +#include + +#include "serial.h" + +/** + * @addtogroup S3C24X0 + */ +/*@{*/ + +/* RT-Thread Device Interface */ +/** + * This function initializes serial + */ +static rt_err_t rt_serial_init (rt_device_t dev) +{ + struct serial_device* uart = (struct 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 = uart->int_rx->read_index = 0; + } + + 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; + } + + dev->flag |= RT_DEVICE_FLAG_ACTIVATED; + } + + return RT_EOK; +} + +/** + * This function read a character from serial without interrupt enable mode + * + * @return the read char + */ +char rt_serial_getc(struct 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 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 serial_device* uart = (struct 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->ustat & USTAT_TXB_EMPTY)); + uart->uart_device->utxh = (c & 0x1FF); +} + +static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) +{ + RT_ASSERT(dev != RT_NULL); + + return RT_EOK; +} + +static rt_err_t rt_serial_close(rt_device_t dev) +{ + RT_ASSERT(dev != RT_NULL); + + 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 serial_device* uart; + + ptr = buffer; + err_code = RT_EOK; + uart = (struct 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 + { + /* polling mode */ + while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) + { + while (uart->uart_device->ustat & USTAT_RCV_READY) + { + *ptr = uart->uart_device->urxh & 0xff; + ptr ++; + } + } + } + + /* set error code */ + rt_set_errno(err_code); + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +} + +static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + rt_uint8_t* ptr; + rt_err_t err_code; + struct serial_device* uart; + + err_code = RT_EOK; + ptr = (rt_uint8_t*)buffer; + uart = (struct 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 + { + /* 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 serial_device* uart; + + RT_ASSERT(dev != RT_NULL); + + uart = (struct serial_device*)dev->private; + switch (cmd) + { + case RT_DEVICE_CTRL_SUSPEND: + /* suspend device */ + dev->flag |= RT_DEVICE_FLAG_SUSPENDED; + break; + + case RT_DEVICE_CTRL_RESUME: + /* resume device */ + dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED; + break; + } + + return RT_EOK; +} + +/* + * serial register + */ +rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct 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 serial_device* uart = (struct serial_device*) device->private; + + /* interrupt mode receive */ + RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); + + /* save on rx buffer */ + while (uart->uart_device->ustat & USTAT_RCV_READY) + { + rt_serial_savechar(uart, uart->uart_device->urxh & 0xff); + } + + /* 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); + } +} + +/*@}*/ diff --git a/libcpu/arm/s3c24x0/serial.h b/libcpu/arm/s3c24x0/serial.h new file mode 100644 index 0000000000..2869e56670 --- /dev/null +++ b/libcpu/arm/s3c24x0/serial.h @@ -0,0 +1,58 @@ +#ifndef __RT_HW_SERIAL_H__ +#define __RT_HW_SERIAL_H__ + +#include +#include + +#include "s3c24x0.h" + +#define USTAT_RCV_READY 0x01 /* receive data ready */ +#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */ +#define BPS 115200 /* serial baudrate */ + +#define UART_RX_BUFFER_SIZE 64 +#define UART_TX_BUFFER_SIZE 64 + +struct serial_int_rx +{ + rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE]; + rt_uint32_t read_index, save_index; +}; + +struct serial_int_tx +{ + rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE]; + rt_uint32_t write_index, save_index; +}; + +typedef struct uartport +{ + rt_uint32_t ulcon; + rt_uint32_t ucon; + rt_uint32_t ufcon; + rt_uint32_t umcon; + rt_uint32_t ustat; + rt_uint32_t urxb; + rt_uint32_t ufstat; + rt_uint32_t umstat; + rt_uint32_t utxh; + rt_uint32_t urxh; + rt_uint32_t ubrd; +}uartport; + +struct serial_device +{ + uartport* uart_device; + + /* rx structure */ + struct serial_int_rx* int_rx; + + /* tx structure */ + struct serial_int_tx* int_tx; +}; + +rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial); + +void rt_hw_serial_isr(rt_device_t device); + +#endif diff --git a/libcpu/arm/s3c24x0/stack.c b/libcpu/arm/s3c24x0/stack.c new file mode 100644 index 0000000000..a284989fe8 --- /dev/null +++ b/libcpu/arm/s3c24x0/stack.c @@ -0,0 +1,60 @@ +/* + * 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-03-13 Bernard the first version + */ +#include +#include "s3c24x0.h" + +/** + * @addtogroup S3C24X0 + */ +/*@{*/ + +/** + * 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) +{ + rt_uint32_t *stk; + + stk = (rt_uint32_t*)stack_addr; + *(stk) = (rt_uint32_t)tentry; /* entry point */ + *(--stk) = (rt_uint32_t)texit; /* lr */ + *(--stk) = 0; /* r12 */ + *(--stk) = 0; /* r11 */ + *(--stk) = 0; /* r10 */ + *(--stk) = 0; /* r9 */ + *(--stk) = 0; /* r8 */ + *(--stk) = 0; /* r7 */ + *(--stk) = 0; /* r6 */ + *(--stk) = 0; /* r5 */ + *(--stk) = 0; /* r4 */ + *(--stk) = 0; /* r3 */ + *(--stk) = 0; /* r2 */ + *(--stk) = 0; /* r1 */ + *(--stk) = (rt_uint32_t)parameter; /* r0 : argument */ + *(--stk) = SVCMODE; /* cpsr */ + *(--stk) = SVCMODE; /* spsr */ + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} + +/*@}*/ diff --git a/libcpu/arm/s3c24x0/trap.c b/libcpu/arm/s3c24x0/trap.c new file mode 100644 index 0000000000..0a99c54143 --- /dev/null +++ b/libcpu/arm/s3c24x0/trap.c @@ -0,0 +1,160 @@ +/* + * 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 + * 2006-05-27 Bernard add skyeye support + * 2007-11-19 Yi.Qiu fix rt_hw_trap_irq function + */ + +#include +#include + +#include "s3c24x0.h" + +/** + * @addtogroup S3C24X0 + */ +/*@{*/ + +extern struct rt_thread *rt_current_thread; + +/** + * this function will show registers of CPU + * + * @param regs the registers point + */ + +void rt_hw_show_register (struct rt_hw_register *regs) +{ + rt_kprintf("Execption:\n"); + rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3); + rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7); + rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10); + rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip); + rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc); + rt_kprintf("cpsr:0x%08x\n", regs->cpsr); +} + +/** + * When ARM7TDMI comes across an instruction which it cannot handle, + * it takes the undefined instruction trap. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_udef(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("undefined instruction\n"); + rt_kprintf("thread - %s stack:\n", rt_current_thread->name); + rt_hw_backtrace((rt_uint32_t *)regs->fp, (rt_uint32_t)rt_current_thread->entry); + + rt_hw_cpu_shutdown(); +} + +/** + * The software interrupt instruction (SWI) is used for entering + * Supervisor mode, usually to request a particular supervisor + * function. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_swi(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("software interrupt\n"); + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during an instruction prefetch. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_pabt(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("prefetch abort\n"); + rt_kprintf("thread - %s stack:\n", rt_current_thread->name); + rt_hw_backtrace((rt_uint32_t *)regs->fp, (rt_uint32_t)rt_current_thread->entry); + + rt_hw_cpu_shutdown(); +} + +/** + * An abort indicates that the current memory access cannot be completed, + * which occurs during a data access. + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_dabt(struct rt_hw_register *regs) +{ + rt_hw_show_register(regs); + + rt_kprintf("data abort\n"); + rt_kprintf("thread - %s stack:\n", rt_current_thread->name); + rt_hw_backtrace((rt_uint32_t *)regs->fp, (rt_uint32_t)rt_current_thread->entry); + + rt_hw_cpu_shutdown(); +} + +/** + * Normally, system will never reach here + * + * @param regs system registers + * + * @note never invoke this function in application + */ +void rt_hw_trap_resv(struct rt_hw_register *regs) +{ + rt_kprintf("not used\n"); + rt_hw_show_register(regs); + rt_hw_cpu_shutdown(); +} + +extern rt_isr_handler_t isr_table[]; + +void rt_hw_trap_irq() +{ + unsigned long intstat; + rt_isr_handler_t isr_func; + + intstat = INTOFFSET; + + if (intstat == INTGLOBAL) return; + + /* get interrupt service routine */ + isr_func = isr_table[intstat]; + + /* turn to interrupt service routine */ + isr_func(intstat); + + /* clear pending register */ + ClearPending(1 << intstat); +} + +void rt_hw_trap_fiq() +{ + rt_kprintf("fast interrupt request\n"); +} + +/*@}*/