提交 7ae254ab 编写于 作者: B bernard.xiong

add the s3c2440 code from old s3c2410 port.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@196 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 a7b56e9c
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)
/*
* 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 <rtthread.h>
#ifdef RT_USING_RTGUI
#include <rtgui/rtgui.h>
#endif
#ifdef RT_USING_DFS
/* dfs init */
#include <dfs_init.h>
/* dfs filesystem:FAT filesystem init */
#include <dfs_fat.h>
/* dfs filesystem:EFS filesystem init */
#include <dfs_efs.h>
/* dfs Filesystem APIs */
#include <dfs_fs.h>
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
}
/*@}*/
/*
* 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 <rtthread.h>
#include <rthw.h>
#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; */
}
/*@}*/
/*
* 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 <s3c2410.h>
#include <serial.h>
void rt_hw_board_init(void);
void rt_hw_sdcard_init(void);
#endif
#include <rtthread.h>
#include <serial.h>
#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++);
}
}
/*
* 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 <rtthread.h>
#include <s3c2410.h>
#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 <rtgui/driver.h>
#include <rtgui/color.h>
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
/*
* 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 <rtthread.h>
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
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 = .;
}
/* 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
# 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 = ''
/*
* 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 <rtthread.h>
#include <dfs_fs.h>
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
#ifndef __SDCARD_H
#define __SDCARD_H
#include <s3c2410.h>
#define INICLK 300000
#define SDCLK 24000000
#define MMCCLK 15000000
#endif
/*
* 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 <rtthread.h>
#include <rthw.h>
#include <s3c2410.h>
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 ;
}
/*@}*/
#include <rthw.h>
#include <rtthread.h>
#include <s3c2410.h>
/* 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 <rtgui/event.h>
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<<ts.shift))
{
ADCTSC = S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST;
ADCCON |= S3C2410_ADCCON_ENABLE_START;
}
else
{
touch_timer_fire(0);
ADCTSC = WAIT4INT(1);
}
SUBSRCPND |= BIT_SUB_ADC;
}
void s3c2410_intc_stylus_updown()
{
rt_uint32_t data0;
rt_uint32_t data1;
int updown;
data0 = ADCDAT0;
data1 = ADCDAT1;
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
rt_kprintf("stylus: %s\n", updown? "down" : "up");
if (updown) touch_timer_fire(RT_NULL);
else
{
if (ts.xp >= 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;
}
/*
* 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 <rtthread.h>
#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<<s))*100;
val = CLKDIVN;
m = (val>>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;
}
/*
* 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
;/*
; * 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
/*
* File : cpu.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-03-13 Bernard first version
*/
#include <rtthread.h>
#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);
}
/*@}*/
/*
* File : trap.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-03-13 Bernard first version
*/
#include <rtthread.h>
#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;
}
}
/*@}*/
/*
* 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 <rtthread.h>
#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();
}
/*
* 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);
}
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rthw.h>
#include <rtthread.h>
#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
此差异已折叠。
/*
* 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 <rtthread.h>
#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);
}
}
/*@}*/
#ifndef __RT_HW_SERIAL_H__
#define __RT_HW_SERIAL_H__
#include <rthw.h>
#include <rtthread.h>
#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
/*
* 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 <rtthread.h>
#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;
}
/*@}*/
/*
* 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 <rtthread.h>
#include <rthw.h>
#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");
}
/*@}*/
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册