From 178579173363d5693097e5a2bb09f0394547b70f Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Sat, 8 Oct 2011 13:23:20 +0000 Subject: [PATCH] Change source code to UNIX end of line git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1743 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- bsp/fm3/mb9bf506r/SConscript | 32 +- bsp/fm3/mb9bf506r/SConstruct | 78 +- bsp/fm3/mb9bf506r/application.c | 142 ++-- bsp/fm3/mb9bf506r/board.c | 128 +-- bsp/fm3/mb9bf506r/board.h | 62 +- bsp/fm3/mb9bf506r/console.c | 360 ++++----- bsp/fm3/mb9bf506r/led.c | 282 +++---- bsp/fm3/mb9bf506r/led.h | 86 +- bsp/fm3/mb9bf506r/nand.c | 1334 +++++++++++++++---------------- bsp/fm3/mb9bf506r/nand.h | 114 +-- bsp/fm3/mb9bf506r/rtconfig.py | 226 +++--- bsp/fm3/mb9bf506r/serial.c | 696 ++++++++-------- bsp/fm3/mb9bf506r/serial.h | 198 ++--- bsp/fm3/mb9bf506r/startup.c | 244 +++--- 14 files changed, 1991 insertions(+), 1991 deletions(-) diff --git a/bsp/fm3/mb9bf506r/SConscript b/bsp/fm3/mb9bf506r/SConscript index 2ca7f0721d..d09b858deb 100644 --- a/bsp/fm3/mb9bf506r/SConscript +++ b/bsp/fm3/mb9bf506r/SConscript @@ -1,16 +1,16 @@ -import rtconfig -Import('RTT_ROOT') -from building import * - -src_bsp = ['application.c', 'startup.c', 'board.c', 'led.c', 'console.c'] -src_drv = ['serial.c', 'nand.c'] - -if GetDepend('RT_USING_RTGUI'): - src_drv += ['info.c'] - -src = src_bsp + src_drv -CPPPATH = [GetCurrentDir()] -CPPDEFINES = [] -group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) - -Return('group') +import rtconfig +Import('RTT_ROOT') +from building import * + +src_bsp = ['application.c', 'startup.c', 'board.c', 'led.c', 'console.c'] +src_drv = ['serial.c', 'nand.c'] + +if GetDepend('RT_USING_RTGUI'): + src_drv += ['info.c'] + +src = src_bsp + src_drv +CPPPATH = [GetCurrentDir()] +CPPDEFINES = [] +group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/fm3/mb9bf506r/SConstruct b/bsp/fm3/mb9bf506r/SConstruct index 5289674c12..1fac2c8cd8 100644 --- a/bsp/fm3/mb9bf506r/SConstruct +++ b/bsp/fm3/mb9bf506r/SConstruct @@ -1,39 +1,39 @@ -import os -import sys -import rtconfig - -if os.getenv('RTT_ROOT'): - RTT_ROOT = os.getenv('RTT_ROOT') -else: - RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') - -sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] -from building import * - -TARGET = 'rtthread.' + rtconfig.TARGET_EXT - -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) - -if rtconfig.PLATFORM == 'iar': - env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) - env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map']) - env.Replace(ARFLAGS = '') - -Export('RTT_ROOT') -Export('rtconfig') - -# prepare building environment -objs = PrepareBuilding(env, RTT_ROOT) - -objs = objs + SConscript('../CMSIS/SConscript', variant_dir='build/bsp/Libraries', duplicate=0) - -# build program -env.Program(TARGET, objs) - -# end building -EndBuilding(TARGET) +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread.' + rtconfig.TARGET_EXT + +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) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map']) + env.Replace(ARFLAGS = '') + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT) + +objs = objs + SConscript('../CMSIS/SConscript', variant_dir='build/bsp/Libraries', duplicate=0) + +# build program +env.Program(TARGET, objs) + +# end building +EndBuilding(TARGET) diff --git a/bsp/fm3/mb9bf506r/application.c b/bsp/fm3/mb9bf506r/application.c index d5fa30419e..94ffe4819d 100644 --- a/bsp/fm3/mb9bf506r/application.c +++ b/bsp/fm3/mb9bf506r/application.c @@ -1,71 +1,71 @@ -/* - * File : application.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2009 - 2011, 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 - * 2011-05-24 Bernard the first version - */ - -/** - * @addtogroup FM3 - */ -/*@{*/ - -#include -#include "board.h" -#include "led.h" - -#ifdef RT_USING_DFS -/* dfs init */ -#include -/* dfs filesystem:ELM filesystem init */ -#include -/* dfs Filesystem APIs */ -#include -#endif - -void rt_init_thread_entry(void *parameter) -{ - /* Filesystem Initialization */ -#ifdef RT_USING_DFS - { - /* init the device filesystem */ - dfs_init(); - -#ifdef RT_USING_DFS_ELMFAT - /* init the elm chan FatFs filesystam*/ - elm_init(); - - /* mount ELM FatFs on NAND flash as root directory */ - if (dfs_mount("nand", "/", "elm", 0, 0) == 0) - { - rt_kprintf("File System initialized!\n"); - } - else - rt_kprintf("File System initialzation failed!\n"); -#endif - } -#endif - /* LED Initialization */ - rt_hw_led_init(); -} - -int rt_application_init() -{ - rt_thread_t tid; - - tid = rt_thread_create("init", - rt_init_thread_entry, RT_NULL, - 2048, 8, 20); - if (tid != RT_NULL) rt_thread_startup(tid); - - return 0; -} - -/*@}*/ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 - 2011, 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 + * 2011-05-24 Bernard the first version + */ + +/** + * @addtogroup FM3 + */ +/*@{*/ + +#include +#include "board.h" +#include "led.h" + +#ifdef RT_USING_DFS +/* dfs init */ +#include +/* dfs filesystem:ELM filesystem init */ +#include +/* dfs Filesystem APIs */ +#include +#endif + +void rt_init_thread_entry(void *parameter) +{ + /* Filesystem Initialization */ +#ifdef RT_USING_DFS + { + /* init the device filesystem */ + dfs_init(); + +#ifdef RT_USING_DFS_ELMFAT + /* init the elm chan FatFs filesystam*/ + elm_init(); + + /* mount ELM FatFs on NAND flash as root directory */ + if (dfs_mount("nand", "/", "elm", 0, 0) == 0) + { + rt_kprintf("File System initialized!\n"); + } + else + rt_kprintf("File System initialzation failed!\n"); +#endif + } +#endif + /* LED Initialization */ + rt_hw_led_init(); +} + +int rt_application_init() +{ + rt_thread_t tid; + + tid = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 2048, 8, 20); + if (tid != RT_NULL) rt_thread_startup(tid); + + return 0; +} + +/*@}*/ diff --git a/bsp/fm3/mb9bf506r/board.c b/bsp/fm3/mb9bf506r/board.c index 9c95c3c41b..82005cb298 100644 --- a/bsp/fm3/mb9bf506r/board.c +++ b/bsp/fm3/mb9bf506r/board.c @@ -1,64 +1,64 @@ -/* - * File : board.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2009 - 2011 RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-02-24 Bernard first implementation - */ - -#include -#include - -#include "board.h" -#include "mb9bf506r.h" - -#include "serial.h" -#include "nand.h" - -extern const uint32_t SystemFrequency; - -/** - * @addtogroup FM3 - */ - -/*@{*/ - -/** - * This is the timer interrupt service routine. - * - */ -void rt_hw_timer_handler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - rt_tick_increase(); - - /* leave interrupt */ - rt_interrupt_leave(); -} - -/** -* This function will initial FM3 Easy Kit board. - */ -void rt_hw_board_init() -{ - /* init systick */ - SysTick_Config(SystemFrequency/RT_TICK_PER_SECOND); - - /* initialize UART device */ - rt_hw_serial_init(); - /* set console as UART device */ - rt_console_set_device("uart2"); - - /* initialize nand flash device */ - rt_hw_nand_init(); -} - -/*@}*/ +/* + * File : board.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 - 2011 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-02-24 Bernard first implementation + */ + +#include +#include + +#include "board.h" +#include "mb9bf506r.h" + +#include "serial.h" +#include "nand.h" + +extern const uint32_t SystemFrequency; + +/** + * @addtogroup FM3 + */ + +/*@{*/ + +/** + * This is the timer interrupt service routine. + * + */ +void rt_hw_timer_handler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +/** +* This function will initial FM3 Easy Kit board. + */ +void rt_hw_board_init() +{ + /* init systick */ + SysTick_Config(SystemFrequency/RT_TICK_PER_SECOND); + + /* initialize UART device */ + rt_hw_serial_init(); + /* set console as UART device */ + rt_console_set_device("uart2"); + + /* initialize nand flash device */ + rt_hw_nand_init(); +} + +/*@}*/ diff --git a/bsp/fm3/mb9bf506r/board.h b/bsp/fm3/mb9bf506r/board.h index 93c0bcb947..b96f8a167a 100644 --- a/bsp/fm3/mb9bf506r/board.h +++ b/bsp/fm3/mb9bf506r/board.h @@ -1,31 +1,31 @@ -/* - * File : board.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2009, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2009-09-22 Bernard add board.h to this bsp - * 2011-03-04 lgnq add board.h to FM3 bsp - */ - -#ifndef __BOARD_H__ -#define __BOARD_H__ - -#include "serial.h" - -//Internal SRAM memory size[Kbytes] <8-64> -//MB9BF500 : 32 -//MB9BF504 : 32 -//MB9BF505 : 48 -//MB9BF506 : 64 -#define FM3_SRAM_SIZE 64 -#define FM3_SRAM_END (0x1FFF8000 + FM3_SRAM_SIZE * 1024) - -void rt_hw_board_init(void); - -#endif +/* + * File : board.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-09-22 Bernard add board.h to this bsp + * 2011-03-04 lgnq add board.h to FM3 bsp + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "serial.h" + +//Internal SRAM memory size[Kbytes] <8-64> +//MB9BF500 : 32 +//MB9BF504 : 32 +//MB9BF505 : 48 +//MB9BF506 : 64 +#define FM3_SRAM_SIZE 64 +#define FM3_SRAM_END (0x1FFF8000 + FM3_SRAM_SIZE * 1024) + +void rt_hw_board_init(void); + +#endif diff --git a/bsp/fm3/mb9bf506r/console.c b/bsp/fm3/mb9bf506r/console.c index c96483c38e..084a7d6a08 100644 --- a/bsp/fm3/mb9bf506r/console.c +++ b/bsp/fm3/mb9bf506r/console.c @@ -1,180 +1,180 @@ -#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 uart2; - -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); -void rt_hw_console_putc(char c); -void rt_hw_console_clear(void); - -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: - { - rt_uint8_t* font_ptr; - register rt_uint32_t cursor; - register rt_uint32_t i, j; - - if (console.current_col == RT_CONSOLE_COL) - { - rt_hw_console_newline(); - console.current_col = 0; - - rt_hw_console_putc(c); - return; - } - - font_ptr = console.font_ptr + c * RT_CONSOLE_FONT_HEIGHT; - cursor = (console.current_row * RT_CONSOLE_FONT_HEIGHT) * console.pitch - + console.current_col * RT_CONSOLE_FONT_WIDTH * console.bpp; - - 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 (!(uart2.uart_device->SSR & SSR_TDRE)); - uart2.uart_device->TDR = (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++); - } -} - +#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 uart2; + +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); +void rt_hw_console_putc(char c); +void rt_hw_console_clear(void); + +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: + { + rt_uint8_t* font_ptr; + register rt_uint32_t cursor; + register rt_uint32_t i, j; + + if (console.current_col == RT_CONSOLE_COL) + { + rt_hw_console_newline(); + console.current_col = 0; + + rt_hw_console_putc(c); + return; + } + + font_ptr = console.font_ptr + c * RT_CONSOLE_FONT_HEIGHT; + cursor = (console.current_row * RT_CONSOLE_FONT_HEIGHT) * console.pitch + + console.current_col * RT_CONSOLE_FONT_WIDTH * console.bpp; + + 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 (!(uart2.uart_device->SSR & SSR_TDRE)); + uart2.uart_device->TDR = (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++); + } +} + diff --git a/bsp/fm3/mb9bf506r/led.c b/bsp/fm3/mb9bf506r/led.c index b2a90cb9df..a1ab6a0592 100644 --- a/bsp/fm3/mb9bf506r/led.c +++ b/bsp/fm3/mb9bf506r/led.c @@ -1,141 +1,141 @@ -/* - * File : led.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-03-03 lgnq - */ - -#include -#include - -#include "mb9bf506r.h" -#include "led.h" - -void rt_hw_led_on(rt_uint8_t num) -{ - RT_ASSERT(num < LEDS_MAX_NUMBER); - - switch (num) - { - case 1: - USER_LED_PDOR &= ~USER_LED1; - break; - case 2: - USER_LED_PDOR &= ~USER_LED2; - break; - case 3: - USER_LED_PDOR &= ~USER_LED3; - break; - default: - break; - } -} - -void rt_hw_led_off(rt_uint8_t num) -{ - RT_ASSERT(num < LEDS_MAX_NUMBER); - - switch (num) - { - case 1: - USER_LED_PDOR |= USER_LED1; - break; - case 2: - USER_LED_PDOR |= USER_LED2; - break; - case 3: - USER_LED_PDOR |= USER_LED3; - break; - default: - break; - } -} - -void rt_hw_led_toggle(rt_uint8_t num) -{ - RT_ASSERT(num < LEDS_MAX_NUMBER); - - switch (num) - { - case 1: - if (USER_LED_PDOR&USER_LED1) - USER_LED_PDOR &= ~USER_LED1; - else - USER_LED_PDOR |= USER_LED1; - break; - case 2: - if (USER_LED_PDOR&USER_LED2) - USER_LED_PDOR &= ~USER_LED2; - else - USER_LED_PDOR |= USER_LED2; - break; - case 3: - if (USER_LED_PDOR&USER_LED3) - USER_LED_PDOR &= ~USER_LED3; - else - USER_LED_PDOR |= USER_LED3; - break; - default: - break; - } -} - -void led_init(void) -{ - /*Select CPIO function*/ - USER_LED_PFR &= ~USER_LED_MASK; - /* disable analog input */ - FM3_GPIO->ADE &= ~USER_LED_MASK; - /*Set CPIO Pull-Up function*/ - USER_LED_PCR |= USER_LED_MASK; - /*Make led pins outputs*/ - USER_LED_DDR |= USER_LED_MASK; - USER_LED_PDOR |= USER_LED_MASK; -} - -void pwm_update(rt_uint16_t value) -{ - FM3_BT2_PWM->PDUT = value; -} - -static void led1_thread_entry(void *parameter) -{ - while (1) - { - rt_hw_led_toggle(1); - rt_thread_delay(RT_TICK_PER_SECOND); - } -} - -static void led2_thread_entry(void *parameter) -{ - while (1) - { - rt_hw_led_toggle(2); - rt_thread_delay(RT_TICK_PER_SECOND/2); - } -} - -static rt_thread_t led1_thread; -static rt_thread_t led2_thread; -void rt_hw_led_init(void) -{ - led_init(); - - led1_thread = rt_thread_create("led1", led1_thread_entry, RT_NULL, 384, 29, 5); - if (led1_thread != RT_NULL) - rt_thread_startup(led1_thread); - - led2_thread = rt_thread_create("led2", led2_thread_entry, RT_NULL, 384, 30, 5); - if (led2_thread != RT_NULL) - rt_thread_startup(led2_thread); -} - - +/* + * File : led.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-03-03 lgnq + */ + +#include +#include + +#include "mb9bf506r.h" +#include "led.h" + +void rt_hw_led_on(rt_uint8_t num) +{ + RT_ASSERT(num < LEDS_MAX_NUMBER); + + switch (num) + { + case 1: + USER_LED_PDOR &= ~USER_LED1; + break; + case 2: + USER_LED_PDOR &= ~USER_LED2; + break; + case 3: + USER_LED_PDOR &= ~USER_LED3; + break; + default: + break; + } +} + +void rt_hw_led_off(rt_uint8_t num) +{ + RT_ASSERT(num < LEDS_MAX_NUMBER); + + switch (num) + { + case 1: + USER_LED_PDOR |= USER_LED1; + break; + case 2: + USER_LED_PDOR |= USER_LED2; + break; + case 3: + USER_LED_PDOR |= USER_LED3; + break; + default: + break; + } +} + +void rt_hw_led_toggle(rt_uint8_t num) +{ + RT_ASSERT(num < LEDS_MAX_NUMBER); + + switch (num) + { + case 1: + if (USER_LED_PDOR&USER_LED1) + USER_LED_PDOR &= ~USER_LED1; + else + USER_LED_PDOR |= USER_LED1; + break; + case 2: + if (USER_LED_PDOR&USER_LED2) + USER_LED_PDOR &= ~USER_LED2; + else + USER_LED_PDOR |= USER_LED2; + break; + case 3: + if (USER_LED_PDOR&USER_LED3) + USER_LED_PDOR &= ~USER_LED3; + else + USER_LED_PDOR |= USER_LED3; + break; + default: + break; + } +} + +void led_init(void) +{ + /*Select CPIO function*/ + USER_LED_PFR &= ~USER_LED_MASK; + /* disable analog input */ + FM3_GPIO->ADE &= ~USER_LED_MASK; + /*Set CPIO Pull-Up function*/ + USER_LED_PCR |= USER_LED_MASK; + /*Make led pins outputs*/ + USER_LED_DDR |= USER_LED_MASK; + USER_LED_PDOR |= USER_LED_MASK; +} + +void pwm_update(rt_uint16_t value) +{ + FM3_BT2_PWM->PDUT = value; +} + +static void led1_thread_entry(void *parameter) +{ + while (1) + { + rt_hw_led_toggle(1); + rt_thread_delay(RT_TICK_PER_SECOND); + } +} + +static void led2_thread_entry(void *parameter) +{ + while (1) + { + rt_hw_led_toggle(2); + rt_thread_delay(RT_TICK_PER_SECOND/2); + } +} + +static rt_thread_t led1_thread; +static rt_thread_t led2_thread; +void rt_hw_led_init(void) +{ + led_init(); + + led1_thread = rt_thread_create("led1", led1_thread_entry, RT_NULL, 384, 29, 5); + if (led1_thread != RT_NULL) + rt_thread_startup(led1_thread); + + led2_thread = rt_thread_create("led2", led2_thread_entry, RT_NULL, 384, 30, 5); + if (led2_thread != RT_NULL) + rt_thread_startup(led2_thread); +} + + diff --git a/bsp/fm3/mb9bf506r/led.h b/bsp/fm3/mb9bf506r/led.h index d7bbfc6646..5db0980520 100644 --- a/bsp/fm3/mb9bf506r/led.h +++ b/bsp/fm3/mb9bf506r/led.h @@ -1,43 +1,43 @@ -/* - * File : led.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2011, RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2011-03-03 lgnq - */ - -#ifndef __LED_H__ -#define __LED_H__ - -#include "mb9bf506r.h" - -#define LEDS_MAX_NUMBER 4 - -/* LED */ -#define USER_LED1 (1UL<<0x9) -#define USER_LED2 (1UL<<0xa) -#define USER_LED3 (1UL<<0xb) - -#define USER_LED_MASK (USER_LED1 | USER_LED2 | USER_LED3) -#define USER_LED_PFR FM3_GPIO->PFR1 -#define USER_LED_PCR FM3_GPIO->PCR1 -#define USER_LED_PDOR FM3_GPIO->PDOR1 -#define USER_LED_DDR FM3_GPIO->DDR1 - -#define RT_DEVICE_CTRL_LED_ON 0 -#define RT_DEVICE_CTRL_LED_OFF 1 -#define RT_DEVICE_CTRL_LED_TOGGLE 2 - -void rt_hw_led_init(void); -void rt_hw_led_on(rt_uint8_t num); -void rt_hw_led_off(rt_uint8_t num); -void rt_hw_led_toggle(rt_uint8_t num); -void pwm_update(rt_uint16_t value); - -#endif +/* + * File : led.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2011, RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2011-03-03 lgnq + */ + +#ifndef __LED_H__ +#define __LED_H__ + +#include "mb9bf506r.h" + +#define LEDS_MAX_NUMBER 4 + +/* LED */ +#define USER_LED1 (1UL<<0x9) +#define USER_LED2 (1UL<<0xa) +#define USER_LED3 (1UL<<0xb) + +#define USER_LED_MASK (USER_LED1 | USER_LED2 | USER_LED3) +#define USER_LED_PFR FM3_GPIO->PFR1 +#define USER_LED_PCR FM3_GPIO->PCR1 +#define USER_LED_PDOR FM3_GPIO->PDOR1 +#define USER_LED_DDR FM3_GPIO->DDR1 + +#define RT_DEVICE_CTRL_LED_ON 0 +#define RT_DEVICE_CTRL_LED_OFF 1 +#define RT_DEVICE_CTRL_LED_TOGGLE 2 + +void rt_hw_led_init(void); +void rt_hw_led_on(rt_uint8_t num); +void rt_hw_led_off(rt_uint8_t num); +void rt_hw_led_toggle(rt_uint8_t num); +void pwm_update(rt_uint16_t value); + +#endif diff --git a/bsp/fm3/mb9bf506r/nand.c b/bsp/fm3/mb9bf506r/nand.c index 27d6a634b4..ada61e3f92 100644 --- a/bsp/fm3/mb9bf506r/nand.c +++ b/bsp/fm3/mb9bf506r/nand.c @@ -1,667 +1,667 @@ -/* - * File : nand.h - * 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 - * 2011-05-25 Bernard first version - */ - -#include "nand.h" -#include "mb9bf506r.h" - -/* - * NandFlash driver for SamSung K9F5608 - * 32M x 8bit - */ -#define PAGE_SIZE 512 -#define PAGE_PER_BLOCK 32 -#define BLOCK_NUM 2048 - -/* device driver debug trace */ -/* #define NAND_DEBUG */ -#ifdef NAND_DEBUG -#define trace_log rt_kprintf -#else -#define trace_log(...) -#endif - -/* - * OOB, - * when block has been erased, OOB is 0xff. - * when block has been written, OOB is 0x00. - */ -struct rt_device_nand -{ - struct rt_device parent; /* which is inherited from rt_device */ - - rt_uint16_t block_num; /* total block number in device */ - rt_uint16_t page_per_block; /* pages in one block */ - rt_uint16_t page_size; /* page size */ - - /* this buffer which used as to save data before erase block */ - rt_uint8_t block_buffer[PAGE_SIZE * PAGE_PER_BLOCK]; -}; -static struct rt_device_nand _nand; - -/* Flash operation definition */ -#define NF_CMD(cmd) {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_CMD_OFFSET) = (unsigned char)(cmd);} -#define NF_ADDR(addr) {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_ADDR_OFFSET)= (unsigned char)(addr);} -#define NF_RDDATA() (*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_DATA_OFFSET)) -#define NF_WRDATA(data) {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_DATA_OFFSET)= (unsigned char)(data);} -#define NF_CLR_ALE() {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_ALE_OFFSET) = (unsigned char)0;} - -/* Flash Control IO definition */ -#define NF_OE_H() {IO_NF_PDOR |= NF_EN;} -#define NF_OE_L() {IO_NF_PDOR &= ~NF_EN;} - -#define NF_DATA_OUT() {IO_NF_PDOR &= ~NF_DATA_DIR;} -#define NF_DATA_IN() {IO_NF_PDOR |= NF_DATA_DIR;} - -static unsigned char NF_ReadStatus(void); -static void Wait(unsigned int cnt); -static void NF_Reset(void); - -static void Wait(unsigned int cnt) -{ - while(cnt--); -} - -static void NF_Reset(void) -{ - NF_OE_L(); - NF_DATA_OUT(); - NF_CMD(NAND_CMD_RESET); - NF_OE_H(); - - Wait(10000); /* wait for Trst */ -} - -static unsigned char NF_ReadStatus(void) -{ - unsigned int timeout=0; - NF_DATA_OUT(); - NF_CMD(NAND_CMD_STATUS); - NF_DATA_IN(); - - while(!(NF_RDDATA() & 0x40)) - { - timeout++; - if(timeout == 0x00080000) - return FLASH_NG; - } - if(NF_RDDATA() & 0x01)return FLASH_NG; - - return FLASH_OK; -} - -/* - * @ Funciton: NF_Init - * Parameter: None - * Return: None - */ -static void NF_Init(void) -{ - FM3_GPIO->PFR5 |= (0x7ff); /* D0-D5, CS7, ALE, CLE, WEX, REX */ - FM3_GPIO->PFR3 |= (0x3); /* D6-D7 */ - FM3_GPIO->EPFR10 |= (1<<13 /* CS enable */ - |1<<6 /* ALE, CLE, WEX, REX enable */ - |1<<0); /* D0-D7 enable */ - FM3_EXBUS->AREA7 = 0x001f00e0; /* Select CS7 area, 32Mbyte size */ - FM3_EXBUS->MODE7 |= (1<<4); /* Nand Flash mode turn on, set 8 bit width */ - - IO_NF_PFR = IO_NF_PFR & ~(NF_EN|NF_DATA_DIR); - IO_NF_DDR = IO_NF_DDR | (NF_EN|NF_DATA_DIR); - IO_NF_PDOR = IO_NF_PDOR | (NF_EN | NF_DATA_DIR); /* disable Flash operation */ - - /*Reset NAND*/ - NF_Reset(); -} - -static void NF_UnInit(void) -{ - FM3_GPIO->PFR5 &= ~(0x7ff); /* disable D0-D5, CS7, ALE, CLE, WEX, REX */ - FM3_GPIO->PFR3 &= ~(0x3); /* disable D6-D7 */ - FM3_GPIO->EPFR10 &= ~(1<<13 /* disable CS enable */ - |1<<6 /* disable ALE, CLE, WEX, REX enable */ - |1<<0); /* disable D0-D7 enable */ - FM3_EXBUS->MODE7 &= ~(1<<4); - IO_NF_PFR = IO_NF_PFR & ~(NF_EN|NF_DATA_DIR); - IO_NF_DDR = IO_NF_DDR | (NF_EN|NF_DATA_DIR); - IO_NF_PDOR = IO_NF_PDOR | (NF_EN | NF_DATA_DIR); /* disable Flash operation */ -} - -/* - * @ Funciton: NF_ReadPage - * Parameter: block (max: 2048) - * page (max:32) - * buffer: pointer to data buffer - * Return: 0: Flash Operation OK - * 1: Flash Operation NG - */ -int NF_ReadPage(unsigned int block, unsigned int page, unsigned char *buffer, - unsigned char *oob) -{ - unsigned int blockPage,i; - - NF_Init(); - blockPage=(block<<5)+page; /* 1 block=32 page */ - NF_OE_L(); - NF_DATA_OUT(); - if (buffer != RT_NULL) - { - volatile unsigned char ch; - - NF_CMD(NAND_CMD_READ0); /* send read data */ - - NF_ADDR(0); - NF_ADDR(blockPage & 0xff); - NF_ADDR((blockPage>>8) & 0xff); /* send 3 byte address */ - NF_CLR_ALE(); - NF_DATA_IN(); - - Wait(500); - - for(i=0;i<512;i++) /* read 512 bytes data */ - buffer[i] = NF_RDDATA(); - for(i=0;i<16;i++) /* read 16 bytes oob */ - if (oob != RT_NULL) - oob[i] = NF_RDDATA(); - else - ch = NF_RDDATA(); - } - else - { - NF_CMD(NAND_CMD_READOOB); /* send read data */ - - NF_ADDR(0); - NF_ADDR(blockPage & 0xff); - NF_ADDR((blockPage>>8) & 0xff); /* send 3 byte address */ - NF_CLR_ALE(); - NF_DATA_IN(); - - Wait(500); - - for (i=0; i<16; i++) /* read 16 bytes oob */ - oob[i] = NF_RDDATA(); - } - - NF_OE_H(); - NF_UnInit(); - return 0; -} - -/* - * @ Funciton: NF_EraseBlock - * Parameter: block (max: 2048) - * Return: 0: Flash Operation OK - * 1: Flash Operation NG - */ -int NF_EraseBlock(unsigned int block) -{ - rt_uint32_t blockPage; - - trace_log("Erase block %d: ", block); - - NF_Init(); - blockPage = (block << 5); - NF_OE_L(); - NF_DATA_OUT(); - NF_CMD(NAND_CMD_ERASE1); /* send erase command */ - NF_ADDR(blockPage & 0xff); - NF_ADDR((blockPage >> 8) & 0xff); - NF_CMD(NAND_CMD_ERASE2); /* start erase */ - - if(NF_ReadStatus()) - { - NF_Reset(); - NF_OE_H(); - NF_UnInit(); - trace_log("Failed\n"); - rt_kprintf("erase block failed\n"); - - return FLASH_NG; - } - - NF_OE_H(); - NF_UnInit(); - - trace_log("OK\n"); - - return FLASH_OK; -} - -/* - * @ Funciton: NF_WritePage - * Parameter: block (max: 2048) - * page (max:32) - * buffer: pointer to data buffer - * Return: 0: Flash Operation OK - * 1: Flash Operation NG - */ -int NF_WritePage(unsigned block, unsigned page, const rt_uint8_t *buffer) -{ - unsigned int blockPage,i; - unsigned char se[16] = {0}; - unsigned char data; - - blockPage = (block<<5)+page; - NF_Init(); - NF_OE_L(); - NF_DATA_OUT(); - NF_CMD(0x00); /* set programming area */ - NF_CMD(NAND_CMD_SEQIN); /* send write command */ - NF_ADDR(0); - NF_ADDR(blockPage & 0xff); - NF_ADDR((blockPage>>8) & 0xff); - NF_CLR_ALE(); - - for(i=0;i<512;i++) NF_WRDATA(buffer[i]); /* write data */ - for(i=0;i<16;i++) NF_WRDATA(se[i]); /* dummy write */ - - NF_CMD(NAND_CMD_PAGEPROG); /* start programming */ - - if(NF_ReadStatus()) - { - NF_Reset(); - NF_OE_H(); - NF_UnInit(); - - trace_log("write failed\n"); - return FLASH_NG; - } - - /* verify the write data */ - NF_DATA_OUT(); - NF_CMD(NAND_CMD_READ0); /* send read command */ - NF_ADDR(0); - NF_ADDR(blockPage & 0xff); - NF_ADDR((blockPage>>8) & 0xff); - NF_CLR_ALE(); - NF_DATA_IN(); - - Wait(500); - for(i=0; i<512; i++) - { - data=NF_RDDATA(); /* verify 1-512 byte */ - if(data != buffer[i]) - { - trace_log("block %d, page %d\n", block , page); - trace_log("write data failed[%d]: %02x %02x\n", i, data, buffer[i]); - - NF_Reset(); - NF_OE_H(); - NF_UnInit(); - return FLASH_NG; - } - } - - for(i=0; i<16; i++) - { - data=NF_RDDATA(); /* verify 16 byte dummy data */ - if(data != se[i]) - { - trace_log("block %d, page %d\n", block , page); - trace_log("write oob failed[%d]: %02x %02x\n", i, data, se[i]); - NF_Reset(); - NF_OE_H(); - NF_UnInit(); - return FLASH_NG; - } - } - - NF_OE_H(); - NF_UnInit(); - return FLASH_OK; -} - -/* - * @ Funciton: NF_ReadID - * Parameter: id: pointer to device ID - * Return: None - */ -void NF_ReadID(unsigned char *id) -{ - unsigned char maker_code; - NF_Init(); - NF_OE_L(); - NF_DATA_OUT(); - NF_CMD(NAND_CMD_READID); - NF_ADDR(0x00); - NF_CLR_ALE(); - Wait(10); - NF_DATA_IN(); - maker_code = NF_RDDATA(); - maker_code = maker_code; - *id = NF_RDDATA(); - NF_OE_H(); - NF_UnInit(); -} - -static rt_err_t rt_nand_init (rt_device_t dev) -{ - /* empty implementation */ - return RT_EOK; -} - -static rt_err_t rt_nand_open(rt_device_t dev, rt_uint16_t oflag) -{ - /* empty implementation */ - return RT_EOK; -} - -static rt_err_t rt_nand_close(rt_device_t dev) -{ - /* empty implementation */ - return RT_EOK; -} - -/* nand device read */ -static rt_size_t rt_nand_read (rt_device_t dev, rt_off_t pos, void* buffer, - rt_size_t size) -{ - rt_ubase_t block; /* block of position */ - rt_ubase_t page, index; /* page in block of position */ - rt_uint8_t *page_ptr, oob[16]; - struct rt_device_nand *nand; - - /* get nand device */ - nand = (struct rt_device_nand*) dev; - RT_ASSERT(nand != RT_NULL); - - /* get block and page */ - block = pos / nand->page_per_block; - page = pos % nand->page_per_block; - - trace_log("nand read: position %d, block %d, page %d, size %d\n", - pos, block, page, size); - - /* set page buffer pointer */ - page_ptr = (rt_uint8_t*) buffer; - for (index = 0; index < size; index ++) - { - NF_ReadPage(block, page + index, page_ptr, oob); - page_ptr += nand->page_size; - - if (page + index > nand->page_per_block) - { - block += 1; - page = 0; - } - } - - /* return read size (count of block) */ - return size; -} - -/* - * write pages by erase block first - * @param nand the nand device driver - * @param block the block of page - * @param page the page - * @param buffer the data buffer to be written - * @param pages the number of pages to be written - */ -static int rt_nand_eraseblock_writepage(struct rt_device_nand* nand, - rt_ubase_t block, rt_ubase_t page, - const rt_uint8_t *buffer, rt_ubase_t pages) -{ - rt_ubase_t index; - rt_uint32_t page_status; - rt_uint8_t *page_ptr, oob[16]; - - /* set page status */ - page_status = 0; - - /* read each page in block */ - page_ptr = nand->block_buffer; - for (index = 0; index < nand->page_per_block; index ++) - { - NF_ReadPage(block, index, page_ptr, oob); - if (!oob[0]) - page_status |= (1 << index); - page_ptr += nand->page_size; - } - - /* erase block */ - NF_EraseBlock(block); - - page_ptr = &(nand->block_buffer[page * nand->page_size]); - /* merge buffer to page buffer */ - for (index = 0; index < pages; index ++) - { - rt_memcpy(page_ptr, buffer, nand->page_size); - - /* set page status */ - page_status |= (1 << (page + index)); - - /* move to next page */ - page_ptr += nand->page_size; - buffer += nand->page_size; - } - - /* write to flash */ - page_ptr = nand->block_buffer; - for (index = 0; index < nand->page_per_block; index ++) - { - if (page_status & (1 << index)) - NF_WritePage(block, index, page_ptr); - - /* move to next page */ - page_ptr += nand->page_size; - } - - return 0; -} - -/* nand device write */ -static rt_size_t rt_nand_write (rt_device_t dev, rt_off_t pos, - const void* buffer, rt_size_t size) -{ - rt_ubase_t block, page; - rt_uint8_t oob[16]; - struct rt_device_nand *nand; - - nand = (struct rt_device_nand*) dev; - RT_ASSERT(nand != RT_NULL); - - /* get block and page */ - block = pos / nand->page_per_block; - page = pos % nand->page_per_block; - - trace_log("nand write: position %d, block %d, page %d, size %d\n", - pos, block, page, size); - - if (size == 1) - { - /* write one page */ - - /* read oob to get page status */ - NF_ReadPage(block, page, RT_NULL, oob); - if (oob[0]) - NF_WritePage(block, page, buffer); - else - /* erase block and then write page */ - rt_nand_eraseblock_writepage(nand, block, page, buffer, 1); - } - else if (size > 1) - { - rt_ubase_t index; - rt_ubase_t need_erase_block; - const rt_uint8_t *page_ptr; - rt_ubase_t chunk_pages, pages; - - pages = size; - page_ptr = (const rt_uint8_t*) buffer; - do - { - need_erase_block = 0; - /* calculate pages in current chunk */ - if (pages > nand->page_per_block - page) - chunk_pages = nand->page_per_block - page; - else - chunk_pages = pages; - - /* get page status in current block */ - for (index = page; index < page + chunk_pages; index ++) - { - NF_ReadPage(block, index, RT_NULL, oob); - if (!oob[0]) - { - /* this page has data, need erase this block firstly */ - need_erase_block = 1; - break; - } - } - - if (need_erase_block) - { - /* erase block and then write it */ - rt_nand_eraseblock_writepage(nand, block, page, page_ptr, chunk_pages); - page_ptr += chunk_pages * nand->page_size; - } - else - { - /* write pages directly */ - for (index = page; index < page + chunk_pages; index ++) - { - NF_WritePage(block, index, page_ptr); - page_ptr += nand->page_size; - } - } - - pages -= chunk_pages; - page = 0; block ++; /* move to next block */ - } - while (pages); - } - - return size; -} - -static rt_err_t rt_nand_control (rt_device_t dev, rt_uint8_t cmd, void *args) -{ - struct rt_device_nand *nand; - - nand = (struct rt_device_nand*) dev; - RT_ASSERT(dev != RT_NULL); - - switch (cmd) - { - case RT_DEVICE_CTRL_BLK_GETGEOME: - { - struct rt_device_blk_geometry *geometry; - - geometry = (struct rt_device_blk_geometry *)args; - if (geometry == RT_NULL) return -RT_ERROR; - - geometry->bytes_per_sector = nand->page_size; - geometry->block_size = nand->page_size * nand->page_per_block; - geometry->sector_count = nand->block_num * nand->page_per_block; - } - break; - } - - return RT_EOK; -} - -void rt_hw_nand_init(void) -{ - /* initialize nand flash structure */ - _nand.block_num = BLOCK_NUM; - _nand.page_per_block = PAGE_PER_BLOCK; - _nand.page_size = PAGE_SIZE; - - rt_memset(_nand.block_buffer, 0, sizeof(_nand.block_buffer)); - - _nand.parent.type = RT_Device_Class_MTD; - _nand.parent.rx_indicate = RT_NULL; - _nand.parent.tx_complete = RT_NULL; - _nand.parent.init = rt_nand_init; - _nand.parent.open = rt_nand_open; - _nand.parent.close = rt_nand_close; - _nand.parent.read = rt_nand_read; - _nand.parent.write = rt_nand_write; - _nand.parent.control = rt_nand_control; - - /* register a MTD device */ - rt_device_register(&(_nand.parent), "nand", RT_DEVICE_FLAG_RDWR); -} - -#ifdef NAND_DEBUG -#include -unsigned char nand_buffer[512]; -unsigned char nand_oob[16]; - -void dump_mem(unsigned char* buffer, int length) -{ - int i; - - if (length > 64) length = 64; - for (i = 0; i < length; i ++) - { - rt_kprintf("%02x ", *buffer++); - if (((i+1) % 16) == 0) - rt_kprintf("\n"); - } - rt_kprintf("\n"); -} - -void nand_read(int block, int page) -{ - rt_kprintf("read block %d, page %d\n", block, page); - - NF_ReadPage(block, page, nand_buffer, nand_oob); - rt_kprintf("page data:\n"); - dump_mem(nand_buffer, 512); - rt_kprintf("oob data:\n"); - dump_mem(nand_oob, 16); -} -FINSH_FUNCTION_EXPORT_ALIAS(nand_read, read_page, read page[block/page]); - -void nand_write(int block, int page) -{ - int i; - for (i = 0; i < 512; i ++) - nand_buffer[i] = i; - - NF_WritePage(block, page, nand_buffer); -} -FINSH_FUNCTION_EXPORT_ALIAS(nand_write, write_page, write page[block/page]); - -void nand_erase(int block) -{ - NF_EraseBlock(block); -} -FINSH_FUNCTION_EXPORT_ALIAS(nand_erase, erase_block, erase block[block]); - -void nand_readoob(int block, int page) -{ - rt_kprintf("read oob on block %d, page %d\n", block, page); - - NF_ReadPage(block, page, RT_NULL, (unsigned char*)nand_oob); - rt_kprintf("oob data:\n"); - dump_mem(nand_oob, 16); -} -FINSH_FUNCTION_EXPORT_ALIAS(nand_readoob, readoob, read oob[block/page]); - -void nand_erase_chip() -{ - int i; - unsigned char id; - - NF_ReadID(&id); - rt_kprintf("id: %02x\n", id); - - for (i = 0; i < 2048; i ++) - { - NF_EraseBlock(i); - } -} -FINSH_FUNCTION_EXPORT_ALIAS(nand_erase_chip, erase_chip, erase whole chip); -#endif +/* + * File : nand.h + * 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 + * 2011-05-25 Bernard first version + */ + +#include "nand.h" +#include "mb9bf506r.h" + +/* + * NandFlash driver for SamSung K9F5608 + * 32M x 8bit + */ +#define PAGE_SIZE 512 +#define PAGE_PER_BLOCK 32 +#define BLOCK_NUM 2048 + +/* device driver debug trace */ +/* #define NAND_DEBUG */ +#ifdef NAND_DEBUG +#define trace_log rt_kprintf +#else +#define trace_log(...) +#endif + +/* + * OOB, + * when block has been erased, OOB is 0xff. + * when block has been written, OOB is 0x00. + */ +struct rt_device_nand +{ + struct rt_device parent; /* which is inherited from rt_device */ + + rt_uint16_t block_num; /* total block number in device */ + rt_uint16_t page_per_block; /* pages in one block */ + rt_uint16_t page_size; /* page size */ + + /* this buffer which used as to save data before erase block */ + rt_uint8_t block_buffer[PAGE_SIZE * PAGE_PER_BLOCK]; +}; +static struct rt_device_nand _nand; + +/* Flash operation definition */ +#define NF_CMD(cmd) {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_CMD_OFFSET) = (unsigned char)(cmd);} +#define NF_ADDR(addr) {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_ADDR_OFFSET)= (unsigned char)(addr);} +#define NF_RDDATA() (*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_DATA_OFFSET)) +#define NF_WRDATA(data) {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_DATA_OFFSET)= (unsigned char)(data);} +#define NF_CLR_ALE() {*(volatile unsigned char*)(NF_FLASH_BASE_ADDR+NF_ALE_OFFSET) = (unsigned char)0;} + +/* Flash Control IO definition */ +#define NF_OE_H() {IO_NF_PDOR |= NF_EN;} +#define NF_OE_L() {IO_NF_PDOR &= ~NF_EN;} + +#define NF_DATA_OUT() {IO_NF_PDOR &= ~NF_DATA_DIR;} +#define NF_DATA_IN() {IO_NF_PDOR |= NF_DATA_DIR;} + +static unsigned char NF_ReadStatus(void); +static void Wait(unsigned int cnt); +static void NF_Reset(void); + +static void Wait(unsigned int cnt) +{ + while(cnt--); +} + +static void NF_Reset(void) +{ + NF_OE_L(); + NF_DATA_OUT(); + NF_CMD(NAND_CMD_RESET); + NF_OE_H(); + + Wait(10000); /* wait for Trst */ +} + +static unsigned char NF_ReadStatus(void) +{ + unsigned int timeout=0; + NF_DATA_OUT(); + NF_CMD(NAND_CMD_STATUS); + NF_DATA_IN(); + + while(!(NF_RDDATA() & 0x40)) + { + timeout++; + if(timeout == 0x00080000) + return FLASH_NG; + } + if(NF_RDDATA() & 0x01)return FLASH_NG; + + return FLASH_OK; +} + +/* + * @ Funciton: NF_Init + * Parameter: None + * Return: None + */ +static void NF_Init(void) +{ + FM3_GPIO->PFR5 |= (0x7ff); /* D0-D5, CS7, ALE, CLE, WEX, REX */ + FM3_GPIO->PFR3 |= (0x3); /* D6-D7 */ + FM3_GPIO->EPFR10 |= (1<<13 /* CS enable */ + |1<<6 /* ALE, CLE, WEX, REX enable */ + |1<<0); /* D0-D7 enable */ + FM3_EXBUS->AREA7 = 0x001f00e0; /* Select CS7 area, 32Mbyte size */ + FM3_EXBUS->MODE7 |= (1<<4); /* Nand Flash mode turn on, set 8 bit width */ + + IO_NF_PFR = IO_NF_PFR & ~(NF_EN|NF_DATA_DIR); + IO_NF_DDR = IO_NF_DDR | (NF_EN|NF_DATA_DIR); + IO_NF_PDOR = IO_NF_PDOR | (NF_EN | NF_DATA_DIR); /* disable Flash operation */ + + /*Reset NAND*/ + NF_Reset(); +} + +static void NF_UnInit(void) +{ + FM3_GPIO->PFR5 &= ~(0x7ff); /* disable D0-D5, CS7, ALE, CLE, WEX, REX */ + FM3_GPIO->PFR3 &= ~(0x3); /* disable D6-D7 */ + FM3_GPIO->EPFR10 &= ~(1<<13 /* disable CS enable */ + |1<<6 /* disable ALE, CLE, WEX, REX enable */ + |1<<0); /* disable D0-D7 enable */ + FM3_EXBUS->MODE7 &= ~(1<<4); + IO_NF_PFR = IO_NF_PFR & ~(NF_EN|NF_DATA_DIR); + IO_NF_DDR = IO_NF_DDR | (NF_EN|NF_DATA_DIR); + IO_NF_PDOR = IO_NF_PDOR | (NF_EN | NF_DATA_DIR); /* disable Flash operation */ +} + +/* + * @ Funciton: NF_ReadPage + * Parameter: block (max: 2048) + * page (max:32) + * buffer: pointer to data buffer + * Return: 0: Flash Operation OK + * 1: Flash Operation NG + */ +int NF_ReadPage(unsigned int block, unsigned int page, unsigned char *buffer, + unsigned char *oob) +{ + unsigned int blockPage,i; + + NF_Init(); + blockPage=(block<<5)+page; /* 1 block=32 page */ + NF_OE_L(); + NF_DATA_OUT(); + if (buffer != RT_NULL) + { + volatile unsigned char ch; + + NF_CMD(NAND_CMD_READ0); /* send read data */ + + NF_ADDR(0); + NF_ADDR(blockPage & 0xff); + NF_ADDR((blockPage>>8) & 0xff); /* send 3 byte address */ + NF_CLR_ALE(); + NF_DATA_IN(); + + Wait(500); + + for(i=0;i<512;i++) /* read 512 bytes data */ + buffer[i] = NF_RDDATA(); + for(i=0;i<16;i++) /* read 16 bytes oob */ + if (oob != RT_NULL) + oob[i] = NF_RDDATA(); + else + ch = NF_RDDATA(); + } + else + { + NF_CMD(NAND_CMD_READOOB); /* send read data */ + + NF_ADDR(0); + NF_ADDR(blockPage & 0xff); + NF_ADDR((blockPage>>8) & 0xff); /* send 3 byte address */ + NF_CLR_ALE(); + NF_DATA_IN(); + + Wait(500); + + for (i=0; i<16; i++) /* read 16 bytes oob */ + oob[i] = NF_RDDATA(); + } + + NF_OE_H(); + NF_UnInit(); + return 0; +} + +/* + * @ Funciton: NF_EraseBlock + * Parameter: block (max: 2048) + * Return: 0: Flash Operation OK + * 1: Flash Operation NG + */ +int NF_EraseBlock(unsigned int block) +{ + rt_uint32_t blockPage; + + trace_log("Erase block %d: ", block); + + NF_Init(); + blockPage = (block << 5); + NF_OE_L(); + NF_DATA_OUT(); + NF_CMD(NAND_CMD_ERASE1); /* send erase command */ + NF_ADDR(blockPage & 0xff); + NF_ADDR((blockPage >> 8) & 0xff); + NF_CMD(NAND_CMD_ERASE2); /* start erase */ + + if(NF_ReadStatus()) + { + NF_Reset(); + NF_OE_H(); + NF_UnInit(); + trace_log("Failed\n"); + rt_kprintf("erase block failed\n"); + + return FLASH_NG; + } + + NF_OE_H(); + NF_UnInit(); + + trace_log("OK\n"); + + return FLASH_OK; +} + +/* + * @ Funciton: NF_WritePage + * Parameter: block (max: 2048) + * page (max:32) + * buffer: pointer to data buffer + * Return: 0: Flash Operation OK + * 1: Flash Operation NG + */ +int NF_WritePage(unsigned block, unsigned page, const rt_uint8_t *buffer) +{ + unsigned int blockPage,i; + unsigned char se[16] = {0}; + unsigned char data; + + blockPage = (block<<5)+page; + NF_Init(); + NF_OE_L(); + NF_DATA_OUT(); + NF_CMD(0x00); /* set programming area */ + NF_CMD(NAND_CMD_SEQIN); /* send write command */ + NF_ADDR(0); + NF_ADDR(blockPage & 0xff); + NF_ADDR((blockPage>>8) & 0xff); + NF_CLR_ALE(); + + for(i=0;i<512;i++) NF_WRDATA(buffer[i]); /* write data */ + for(i=0;i<16;i++) NF_WRDATA(se[i]); /* dummy write */ + + NF_CMD(NAND_CMD_PAGEPROG); /* start programming */ + + if(NF_ReadStatus()) + { + NF_Reset(); + NF_OE_H(); + NF_UnInit(); + + trace_log("write failed\n"); + return FLASH_NG; + } + + /* verify the write data */ + NF_DATA_OUT(); + NF_CMD(NAND_CMD_READ0); /* send read command */ + NF_ADDR(0); + NF_ADDR(blockPage & 0xff); + NF_ADDR((blockPage>>8) & 0xff); + NF_CLR_ALE(); + NF_DATA_IN(); + + Wait(500); + for(i=0; i<512; i++) + { + data=NF_RDDATA(); /* verify 1-512 byte */ + if(data != buffer[i]) + { + trace_log("block %d, page %d\n", block , page); + trace_log("write data failed[%d]: %02x %02x\n", i, data, buffer[i]); + + NF_Reset(); + NF_OE_H(); + NF_UnInit(); + return FLASH_NG; + } + } + + for(i=0; i<16; i++) + { + data=NF_RDDATA(); /* verify 16 byte dummy data */ + if(data != se[i]) + { + trace_log("block %d, page %d\n", block , page); + trace_log("write oob failed[%d]: %02x %02x\n", i, data, se[i]); + NF_Reset(); + NF_OE_H(); + NF_UnInit(); + return FLASH_NG; + } + } + + NF_OE_H(); + NF_UnInit(); + return FLASH_OK; +} + +/* + * @ Funciton: NF_ReadID + * Parameter: id: pointer to device ID + * Return: None + */ +void NF_ReadID(unsigned char *id) +{ + unsigned char maker_code; + NF_Init(); + NF_OE_L(); + NF_DATA_OUT(); + NF_CMD(NAND_CMD_READID); + NF_ADDR(0x00); + NF_CLR_ALE(); + Wait(10); + NF_DATA_IN(); + maker_code = NF_RDDATA(); + maker_code = maker_code; + *id = NF_RDDATA(); + NF_OE_H(); + NF_UnInit(); +} + +static rt_err_t rt_nand_init (rt_device_t dev) +{ + /* empty implementation */ + return RT_EOK; +} + +static rt_err_t rt_nand_open(rt_device_t dev, rt_uint16_t oflag) +{ + /* empty implementation */ + return RT_EOK; +} + +static rt_err_t rt_nand_close(rt_device_t dev) +{ + /* empty implementation */ + return RT_EOK; +} + +/* nand device read */ +static rt_size_t rt_nand_read (rt_device_t dev, rt_off_t pos, void* buffer, + rt_size_t size) +{ + rt_ubase_t block; /* block of position */ + rt_ubase_t page, index; /* page in block of position */ + rt_uint8_t *page_ptr, oob[16]; + struct rt_device_nand *nand; + + /* get nand device */ + nand = (struct rt_device_nand*) dev; + RT_ASSERT(nand != RT_NULL); + + /* get block and page */ + block = pos / nand->page_per_block; + page = pos % nand->page_per_block; + + trace_log("nand read: position %d, block %d, page %d, size %d\n", + pos, block, page, size); + + /* set page buffer pointer */ + page_ptr = (rt_uint8_t*) buffer; + for (index = 0; index < size; index ++) + { + NF_ReadPage(block, page + index, page_ptr, oob); + page_ptr += nand->page_size; + + if (page + index > nand->page_per_block) + { + block += 1; + page = 0; + } + } + + /* return read size (count of block) */ + return size; +} + +/* + * write pages by erase block first + * @param nand the nand device driver + * @param block the block of page + * @param page the page + * @param buffer the data buffer to be written + * @param pages the number of pages to be written + */ +static int rt_nand_eraseblock_writepage(struct rt_device_nand* nand, + rt_ubase_t block, rt_ubase_t page, + const rt_uint8_t *buffer, rt_ubase_t pages) +{ + rt_ubase_t index; + rt_uint32_t page_status; + rt_uint8_t *page_ptr, oob[16]; + + /* set page status */ + page_status = 0; + + /* read each page in block */ + page_ptr = nand->block_buffer; + for (index = 0; index < nand->page_per_block; index ++) + { + NF_ReadPage(block, index, page_ptr, oob); + if (!oob[0]) + page_status |= (1 << index); + page_ptr += nand->page_size; + } + + /* erase block */ + NF_EraseBlock(block); + + page_ptr = &(nand->block_buffer[page * nand->page_size]); + /* merge buffer to page buffer */ + for (index = 0; index < pages; index ++) + { + rt_memcpy(page_ptr, buffer, nand->page_size); + + /* set page status */ + page_status |= (1 << (page + index)); + + /* move to next page */ + page_ptr += nand->page_size; + buffer += nand->page_size; + } + + /* write to flash */ + page_ptr = nand->block_buffer; + for (index = 0; index < nand->page_per_block; index ++) + { + if (page_status & (1 << index)) + NF_WritePage(block, index, page_ptr); + + /* move to next page */ + page_ptr += nand->page_size; + } + + return 0; +} + +/* nand device write */ +static rt_size_t rt_nand_write (rt_device_t dev, rt_off_t pos, + const void* buffer, rt_size_t size) +{ + rt_ubase_t block, page; + rt_uint8_t oob[16]; + struct rt_device_nand *nand; + + nand = (struct rt_device_nand*) dev; + RT_ASSERT(nand != RT_NULL); + + /* get block and page */ + block = pos / nand->page_per_block; + page = pos % nand->page_per_block; + + trace_log("nand write: position %d, block %d, page %d, size %d\n", + pos, block, page, size); + + if (size == 1) + { + /* write one page */ + + /* read oob to get page status */ + NF_ReadPage(block, page, RT_NULL, oob); + if (oob[0]) + NF_WritePage(block, page, buffer); + else + /* erase block and then write page */ + rt_nand_eraseblock_writepage(nand, block, page, buffer, 1); + } + else if (size > 1) + { + rt_ubase_t index; + rt_ubase_t need_erase_block; + const rt_uint8_t *page_ptr; + rt_ubase_t chunk_pages, pages; + + pages = size; + page_ptr = (const rt_uint8_t*) buffer; + do + { + need_erase_block = 0; + /* calculate pages in current chunk */ + if (pages > nand->page_per_block - page) + chunk_pages = nand->page_per_block - page; + else + chunk_pages = pages; + + /* get page status in current block */ + for (index = page; index < page + chunk_pages; index ++) + { + NF_ReadPage(block, index, RT_NULL, oob); + if (!oob[0]) + { + /* this page has data, need erase this block firstly */ + need_erase_block = 1; + break; + } + } + + if (need_erase_block) + { + /* erase block and then write it */ + rt_nand_eraseblock_writepage(nand, block, page, page_ptr, chunk_pages); + page_ptr += chunk_pages * nand->page_size; + } + else + { + /* write pages directly */ + for (index = page; index < page + chunk_pages; index ++) + { + NF_WritePage(block, index, page_ptr); + page_ptr += nand->page_size; + } + } + + pages -= chunk_pages; + page = 0; block ++; /* move to next block */ + } + while (pages); + } + + return size; +} + +static rt_err_t rt_nand_control (rt_device_t dev, rt_uint8_t cmd, void *args) +{ + struct rt_device_nand *nand; + + nand = (struct rt_device_nand*) dev; + RT_ASSERT(dev != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_BLK_GETGEOME: + { + struct rt_device_blk_geometry *geometry; + + geometry = (struct rt_device_blk_geometry *)args; + if (geometry == RT_NULL) return -RT_ERROR; + + geometry->bytes_per_sector = nand->page_size; + geometry->block_size = nand->page_size * nand->page_per_block; + geometry->sector_count = nand->block_num * nand->page_per_block; + } + break; + } + + return RT_EOK; +} + +void rt_hw_nand_init(void) +{ + /* initialize nand flash structure */ + _nand.block_num = BLOCK_NUM; + _nand.page_per_block = PAGE_PER_BLOCK; + _nand.page_size = PAGE_SIZE; + + rt_memset(_nand.block_buffer, 0, sizeof(_nand.block_buffer)); + + _nand.parent.type = RT_Device_Class_MTD; + _nand.parent.rx_indicate = RT_NULL; + _nand.parent.tx_complete = RT_NULL; + _nand.parent.init = rt_nand_init; + _nand.parent.open = rt_nand_open; + _nand.parent.close = rt_nand_close; + _nand.parent.read = rt_nand_read; + _nand.parent.write = rt_nand_write; + _nand.parent.control = rt_nand_control; + + /* register a MTD device */ + rt_device_register(&(_nand.parent), "nand", RT_DEVICE_FLAG_RDWR); +} + +#ifdef NAND_DEBUG +#include +unsigned char nand_buffer[512]; +unsigned char nand_oob[16]; + +void dump_mem(unsigned char* buffer, int length) +{ + int i; + + if (length > 64) length = 64; + for (i = 0; i < length; i ++) + { + rt_kprintf("%02x ", *buffer++); + if (((i+1) % 16) == 0) + rt_kprintf("\n"); + } + rt_kprintf("\n"); +} + +void nand_read(int block, int page) +{ + rt_kprintf("read block %d, page %d\n", block, page); + + NF_ReadPage(block, page, nand_buffer, nand_oob); + rt_kprintf("page data:\n"); + dump_mem(nand_buffer, 512); + rt_kprintf("oob data:\n"); + dump_mem(nand_oob, 16); +} +FINSH_FUNCTION_EXPORT_ALIAS(nand_read, read_page, read page[block/page]); + +void nand_write(int block, int page) +{ + int i; + for (i = 0; i < 512; i ++) + nand_buffer[i] = i; + + NF_WritePage(block, page, nand_buffer); +} +FINSH_FUNCTION_EXPORT_ALIAS(nand_write, write_page, write page[block/page]); + +void nand_erase(int block) +{ + NF_EraseBlock(block); +} +FINSH_FUNCTION_EXPORT_ALIAS(nand_erase, erase_block, erase block[block]); + +void nand_readoob(int block, int page) +{ + rt_kprintf("read oob on block %d, page %d\n", block, page); + + NF_ReadPage(block, page, RT_NULL, (unsigned char*)nand_oob); + rt_kprintf("oob data:\n"); + dump_mem(nand_oob, 16); +} +FINSH_FUNCTION_EXPORT_ALIAS(nand_readoob, readoob, read oob[block/page]); + +void nand_erase_chip() +{ + int i; + unsigned char id; + + NF_ReadID(&id); + rt_kprintf("id: %02x\n", id); + + for (i = 0; i < 2048; i ++) + { + NF_EraseBlock(i); + } +} +FINSH_FUNCTION_EXPORT_ALIAS(nand_erase_chip, erase_chip, erase whole chip); +#endif diff --git a/bsp/fm3/mb9bf506r/nand.h b/bsp/fm3/mb9bf506r/nand.h index 5a1f1467a1..ffb4bae2c3 100644 --- a/bsp/fm3/mb9bf506r/nand.h +++ b/bsp/fm3/mb9bf506r/nand.h @@ -1,57 +1,57 @@ -/* - * File : nand.h - * 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 - * 2011-05-25 Bernard first version - */ - -#ifndef __NAND_H__ -#define __NAND_H__ - -#include - -#define IO_NF_PFR FM3_GPIO->PFR3 -#define IO_NF_DDR FM3_GPIO->DDR3 -#define IO_NF_PDOR FM3_GPIO->PDOR3 - -#define NF_EN 0x0008 -#define NF_DATA_DIR 0x0004 - -#define EXT_BUS_BASE_ADDR 0x60000000 -#define EXT_CS7_OFFSET 0x0E000000 -#define EXT_CS7_SIZE 0x02000000 - -#define NF_FLASH_BASE_ADDR (EXT_BUS_BASE_ADDR+EXT_CS7_OFFSET) - -#define NF_ALE_OFFSET 0x00003000 -#define NF_ADDR_OFFSET 0x00002000 -#define NF_CMD_OFFSET 0x00001000 -#define NF_DATA_OFFSET 0x00000000 - -/* NAND command */ -#define NAND_CMD_READ0 0x00 -#define NAND_CMD_READ1 0x01 -#define NAND_CMD_PAGEPROG 0x10 -#define NAND_CMD_READOOB 0x50 -#define NAND_CMD_ERASE1 0x60 -#define NAND_CMD_STATUS 0x70 -#define NAND_CMD_SEQIN 0x80 -#define NAND_CMD_READID 0x90 -#define NAND_CMD_READID1 0x91 -#define NAND_CMD_ERASE2 0xd0 -#define NAND_CMD_RESET 0xff - -#define FLASH_OK 0 -#define FLASH_NG 1 - -/* nand flash device initialization */ -void rt_hw_nand_init(void); - -#endif +/* + * File : nand.h + * 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 + * 2011-05-25 Bernard first version + */ + +#ifndef __NAND_H__ +#define __NAND_H__ + +#include + +#define IO_NF_PFR FM3_GPIO->PFR3 +#define IO_NF_DDR FM3_GPIO->DDR3 +#define IO_NF_PDOR FM3_GPIO->PDOR3 + +#define NF_EN 0x0008 +#define NF_DATA_DIR 0x0004 + +#define EXT_BUS_BASE_ADDR 0x60000000 +#define EXT_CS7_OFFSET 0x0E000000 +#define EXT_CS7_SIZE 0x02000000 + +#define NF_FLASH_BASE_ADDR (EXT_BUS_BASE_ADDR+EXT_CS7_OFFSET) + +#define NF_ALE_OFFSET 0x00003000 +#define NF_ADDR_OFFSET 0x00002000 +#define NF_CMD_OFFSET 0x00001000 +#define NF_DATA_OFFSET 0x00000000 + +/* NAND command */ +#define NAND_CMD_READ0 0x00 +#define NAND_CMD_READ1 0x01 +#define NAND_CMD_PAGEPROG 0x10 +#define NAND_CMD_READOOB 0x50 +#define NAND_CMD_ERASE1 0x60 +#define NAND_CMD_STATUS 0x70 +#define NAND_CMD_SEQIN 0x80 +#define NAND_CMD_READID 0x90 +#define NAND_CMD_READID1 0x91 +#define NAND_CMD_ERASE2 0xd0 +#define NAND_CMD_RESET 0xff + +#define FLASH_OK 0 +#define FLASH_NG 1 + +/* nand flash device initialization */ +void rt_hw_nand_init(void); + +#endif diff --git a/bsp/fm3/mb9bf506r/rtconfig.py b/bsp/fm3/mb9bf506r/rtconfig.py index 900e067b14..361062cc29 100644 --- a/bsp/fm3/mb9bf506r/rtconfig.py +++ b/bsp/fm3/mb9bf506r/rtconfig.py @@ -1,113 +1,113 @@ -# toolchains options -ARCH='arm' -CPU='fm3' -CROSS_TOOL='gcc' - -# cross_tool provides the cross compiler -# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR - -if CROSS_TOOL == 'gcc': - PLATFORM = 'gcc' - EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin' -elif CROSS_TOOL == 'keil': - PLATFORM = 'armcc' - EXEC_PATH = 'C:/Keil' -elif CROSS_TOOL == 'iar': - PLATFORM = 'iar' - IAR_PATH = 'C:\Program Files\IAR Systems\Embedded Workbench 6.0 Evaluation' - -BUILD = 'debug' - -if PLATFORM == 'gcc': - # toolchains - PREFIX = 'arm-none-eabi-' - CC = PREFIX + 'gcc' - AS = PREFIX + 'gcc' - AR = PREFIX + 'ar' - LINK = PREFIX + 'gcc' - TARGET_EXT = 'axf' - SIZE = PREFIX + 'size' - OBJDUMP = PREFIX + 'objdump' - OBJCPY = PREFIX + 'objcopy' - - DEVICE = ' -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections' - CFLAGS = DEVICE - AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-fm3.map,-cref,-u,Reset_Handler -T fm3_rom.ld' - - CPATH = '' - LPATH = '' - - if BUILD == 'debug': - CFLAGS += ' -O0 -gdwarf-2' - AFLAGS += ' -gdwarf-2' - else: - CFLAGS += ' -O2' - - 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 stm32_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' - - POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' - -elif PLATFORM == 'iar': - # toolchains - CC = 'iccarm' - AS = 'iasmarm' - AR = 'iarchive' - LINK = 'ilinkarm' - TARGET_EXT = 'out' - - CFLAGS = '' - CFLAGS += ' --diag_suppress Pa050' - CFLAGS += ' --no_cse' - CFLAGS += ' --no_unroll' - CFLAGS += ' --no_inline' - CFLAGS += ' --no_code_motion' - CFLAGS += ' --no_tbaa' - CFLAGS += ' --no_clustering' - CFLAGS += ' --no_scheduling' - CFLAGS += ' --debug' - CFLAGS += ' --endian=little' - CFLAGS += ' --cpu=Cortex-M3' - CFLAGS += ' -e' - CFLAGS += ' --fpu=None' - CFLAGS += ' --dlib_config "' + IAR_PATH + '/arm/INC/c/DLib_Config_Normal.h"' - CFLAGS += ' -Ol' - CFLAGS += ' --use_c++_inline' - - AFLAGS = '' - AFLAGS += ' -s+' - AFLAGS += ' -w+' - AFLAGS += ' -r' - AFLAGS += ' --cpu Cortex-M3' - AFLAGS += ' --fpu None' - AFLAGS += ' -I"' + IAR_PATH + '/arm/INC"' - - LFLAGS = ' --config mb9bf506.icf' - LFLAGS += ' --semihosting' - LFLAGS += ' --entry __iar_program_start' - - EXEC_PATH = IAR_PATH + '/arm/bin/' - POST_ACTION = 'ielftool.exe --srec --verbose $TARGET rtthread.srec' +# toolchains options +ARCH='arm' +CPU='fm3' +CROSS_TOOL='gcc' + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR + +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = '/media/workspace/arm-2011.03/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = 'C:/Keil' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + IAR_PATH = 'C:\Program Files\IAR Systems\Embedded Workbench 6.0 Evaluation' + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'axf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-fm3.map,-cref,-u,Reset_Handler -T fm3_rom.ld' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + 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 stm32_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' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iar': + # toolchains + CC = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + CFLAGS = '' + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --debug' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M3' + CFLAGS += ' -e' + CFLAGS += ' --fpu=None' + CFLAGS += ' --dlib_config "' + IAR_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' -Ol' + CFLAGS += ' --use_c++_inline' + + AFLAGS = '' + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M3' + AFLAGS += ' --fpu None' + AFLAGS += ' -I"' + IAR_PATH + '/arm/INC"' + + LFLAGS = ' --config mb9bf506.icf' + LFLAGS += ' --semihosting' + LFLAGS += ' --entry __iar_program_start' + + EXEC_PATH = IAR_PATH + '/arm/bin/' + POST_ACTION = 'ielftool.exe --srec --verbose $TARGET rtthread.srec' diff --git a/bsp/fm3/mb9bf506r/serial.c b/bsp/fm3/mb9bf506r/serial.c index c8e08ad47e..a5116fc7e3 100644 --- a/bsp/fm3/mb9bf506r/serial.c +++ b/bsp/fm3/mb9bf506r/serial.c @@ -1,348 +1,348 @@ -/* - * 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://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2006-03-13 Bernard first version - * 2011-05-15 lgnq modified according bernard's implementaion. - */ - -#include - -#include "serial.h" - -/** - * @addtogroup FM3 MB9B500 - */ -/*@{*/ - -/* 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->user_data; - - if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) - { - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - rt_memset(uart->int_rx->rx_buffer, 0, - sizeof(uart->int_rx->rx_buffer)); - uart->int_rx->read_index = uart->int_rx->save_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; -} - -/* save a char to serial buffer */ -static 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); -} - -static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) -{ - struct serial_device* uart; - - RT_ASSERT(dev != RT_NULL); - uart = (struct serial_device*) dev->user_data; - - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* enable interrupt */ - UART_ENABLE_IRQ(uart->rx_irq); - } - - return RT_EOK; -} - -static rt_err_t rt_serial_close(rt_device_t dev) -{ - struct serial_device* uart; - - RT_ASSERT(dev != RT_NULL); - uart = (struct serial_device*) dev->user_data; - - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* disable interrupt */ - UART_DISABLE_IRQ(uart->rx_irq); - } - - 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->user_data; - - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - rt_base_t level; - - /* interrupt mode Rx */ - while (size) - { - if (uart->int_rx->read_index != uart->int_rx->save_index) - { - *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; - size --; - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - - 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); - } - else - { - /* set error code */ - err_code = -RT_EEMPTY; - break; - } - } - } - else - { - /* polling mode */ - while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) - { - while (uart->uart_device->SSR & SSR_RDRF) - { - *ptr = uart->uart_device->RDR & 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->user_data; - - 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) - { - /* - * to be polite with serial console add a line feed - * to the carriage return character - */ - if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) - { - while (!(uart->uart_device->SSR & SSR_TDRE)); - uart->uart_device->TDR = '\r'; - } - - while (!(uart->uart_device->SSR & SSR_TDRE)); - uart->uart_device->TDR = (*ptr & 0x1FF); - - ++ptr; --size; - } - } - - /* set error code */ - rt_set_errno(err_code); - - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; -} - -static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args) -{ - RT_ASSERT(dev != RT_NULL); - - 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->user_data = serial; - - /* register a character device */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); -} - -/* ISR for serial interrupt */ -void rt_hw_serial_isr(rt_device_t device) -{ - struct serial_device* uart = (struct serial_device*) device->user_data; - - /* interrupt mode receive */ - RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); - - /* save on rx buffer */ - while (uart->uart_device->SSR & SSR_RDRF) - { - rt_serial_savechar(uart, uart->uart_device->RDR & 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); - } -} - -#ifdef RT_USING_UART2 -/* UART2 device driver structure */ -#define UART2 FM3_MFS2_UART -struct serial_int_rx uart2_int_rx; -struct serial_device uart2 = -{ - UART2, - MFS2RX_IRQn, - MFS2TX_IRQn, - &uart2_int_rx, - RT_NULL -}; -struct rt_device uart2_device; - -void MFS2RX_IRQHandler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - rt_hw_serial_isr(&uart2_device); - /* leave interrupt */ - rt_interrupt_leave(); -} -#endif - -void rt_hw_serial_init(void) -{ -#ifdef RT_USING_UART2 - /* initialize UART2 */ - /* Set Uart Ch2 Port, SIN2_1, SOT2_1 */ - FM3_GPIO->PFR2 = FM3_GPIO->PFR2 | 0x0030; - FM3_GPIO->EPFR07 = FM3_GPIO->EPFR07 | 0x000a0000; - - uart2.uart_device->SMR = SMR_MD_UART | SMR_SOE;; - uart2.uart_device->BGR = (40000000UL + (BPS/2))/BPS - 1; - uart2.uart_device->ESCR = ESCR_DATABITS_8; - uart2.uart_device->SCR = SCR_RXE | SCR_TXE | SCR_RIE; - - /* register UART2 device */ - rt_hw_serial_register(&uart2_device, - "uart2", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, - &uart2); -#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://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2006-03-13 Bernard first version + * 2011-05-15 lgnq modified according bernard's implementaion. + */ + +#include + +#include "serial.h" + +/** + * @addtogroup FM3 MB9B500 + */ +/*@{*/ + +/* 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->user_data; + + if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) + { + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_memset(uart->int_rx->rx_buffer, 0, + sizeof(uart->int_rx->rx_buffer)); + uart->int_rx->read_index = uart->int_rx->save_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; +} + +/* save a char to serial buffer */ +static 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); +} + +static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) +{ + struct serial_device* uart; + + RT_ASSERT(dev != RT_NULL); + uart = (struct serial_device*) dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* enable interrupt */ + UART_ENABLE_IRQ(uart->rx_irq); + } + + return RT_EOK; +} + +static rt_err_t rt_serial_close(rt_device_t dev) +{ + struct serial_device* uart; + + RT_ASSERT(dev != RT_NULL); + uart = (struct serial_device*) dev->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + /* disable interrupt */ + UART_DISABLE_IRQ(uart->rx_irq); + } + + 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->user_data; + + if (dev->flag & RT_DEVICE_FLAG_INT_RX) + { + rt_base_t level; + + /* interrupt mode Rx */ + while (size) + { + if (uart->int_rx->read_index != uart->int_rx->save_index) + { + *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index]; + size --; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + 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); + } + else + { + /* set error code */ + err_code = -RT_EEMPTY; + break; + } + } + } + else + { + /* polling mode */ + while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size) + { + while (uart->uart_device->SSR & SSR_RDRF) + { + *ptr = uart->uart_device->RDR & 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->user_data; + + 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) + { + /* + * to be polite with serial console add a line feed + * to the carriage return character + */ + if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM)) + { + while (!(uart->uart_device->SSR & SSR_TDRE)); + uart->uart_device->TDR = '\r'; + } + + while (!(uart->uart_device->SSR & SSR_TDRE)); + uart->uart_device->TDR = (*ptr & 0x1FF); + + ++ptr; --size; + } + } + + /* set error code */ + rt_set_errno(err_code); + + return (rt_uint32_t)ptr - (rt_uint32_t)buffer; +} + +static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args) +{ + RT_ASSERT(dev != RT_NULL); + + 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->user_data = serial; + + /* register a character device */ + return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag); +} + +/* ISR for serial interrupt */ +void rt_hw_serial_isr(rt_device_t device) +{ + struct serial_device* uart = (struct serial_device*) device->user_data; + + /* interrupt mode receive */ + RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); + + /* save on rx buffer */ + while (uart->uart_device->SSR & SSR_RDRF) + { + rt_serial_savechar(uart, uart->uart_device->RDR & 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); + } +} + +#ifdef RT_USING_UART2 +/* UART2 device driver structure */ +#define UART2 FM3_MFS2_UART +struct serial_int_rx uart2_int_rx; +struct serial_device uart2 = +{ + UART2, + MFS2RX_IRQn, + MFS2TX_IRQn, + &uart2_int_rx, + RT_NULL +}; +struct rt_device uart2_device; + +void MFS2RX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + rt_hw_serial_isr(&uart2_device); + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + +void rt_hw_serial_init(void) +{ +#ifdef RT_USING_UART2 + /* initialize UART2 */ + /* Set Uart Ch2 Port, SIN2_1, SOT2_1 */ + FM3_GPIO->PFR2 = FM3_GPIO->PFR2 | 0x0030; + FM3_GPIO->EPFR07 = FM3_GPIO->EPFR07 | 0x000a0000; + + uart2.uart_device->SMR = SMR_MD_UART | SMR_SOE;; + uart2.uart_device->BGR = (40000000UL + (BPS/2))/BPS - 1; + uart2.uart_device->ESCR = ESCR_DATABITS_8; + uart2.uart_device->SCR = SCR_RXE | SCR_TXE | SCR_RIE; + + /* register UART2 device */ + rt_hw_serial_register(&uart2_device, + "uart2", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, + &uart2); +#endif +} + +/*@}*/ diff --git a/bsp/fm3/mb9bf506r/serial.h b/bsp/fm3/mb9bf506r/serial.h index 5be2d53c21..1fd05d429d 100644 --- a/bsp/fm3/mb9bf506r/serial.h +++ b/bsp/fm3/mb9bf506r/serial.h @@ -1,99 +1,99 @@ -/* - * File : serial.h - * 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 - * 2006-03-13 Bernard first version - * 2011-05-15 lgnq modified according bernard's implementaion. - */ - -#ifndef __RT_HW_SERIAL_H__ -#define __RT_HW_SERIAL_H__ - -#include -#include - -#include "mb9bf506r.h" - -#define SMR_SOE 0x01U -#define SMR_BDS 0x04U -#define SMR_SBL 0x08U -#define SMR_WUCR 0x10U -#define SMR_MD_UART 0x00U -#define SMR_MD_UART_MP 0x20U -#define SMR_MD_SIO 0x40U -#define SMR_MD_LIN 0x60U -#define SMR_MD_I2C 0x80U - -#define SCR_TXE 0x01U -#define SCR_RXE 0x02U -#define SCR_TBIE 0x04U -#define SCR_TIE 0x08U -#define SCR_RIE 0x10U -#define SCR_UPGL 0x80U - -#define SSR_TBI 0x01U -#define SSR_TDRE 0x02U -#define SSR_RDRF 0x04U -#define SSR_ORE 0x08U -#define SSR_FRE 0x10U -#define SSR_PE 0x20U -#define SSR_REC 0x80U - -#define ESCR_P 0x08U -#define ESCR_PEN 0x10U -#define ESCR_INV 0x20U -#define ESCR_ESBL 0x40U -#define ESCR_FLWEN 0x80U -#define ESCR_DATABITS_8 0x00U -#define ESCR_DATABITS_5 0x01U -#define ESCR_DATABITS_6 0x02U -#define ESCR_DATABITS_7 0x03U -#define ESCR_DATABITS_9 0x04U - -#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; -}; - -/* - * Enable/DISABLE Interrupt Controller - */ -/* deviation from MISRA-C:2004 Rule 19.7 */ -#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) -#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) - -struct serial_device -{ - FM3_MFS03_UART_TypeDef* uart_device; - /* irq number */ - IRQn_Type rx_irq, tx_irq; - - /* rx structure */ - struct serial_int_rx* int_rx; - /* tx structure */ - struct serial_int_tx* int_tx; -}; - -void rt_hw_serial_isr(rt_device_t device); -void rt_hw_serial_init(void); - -#endif +/* + * File : serial.h + * 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 + * 2006-03-13 Bernard first version + * 2011-05-15 lgnq modified according bernard's implementaion. + */ + +#ifndef __RT_HW_SERIAL_H__ +#define __RT_HW_SERIAL_H__ + +#include +#include + +#include "mb9bf506r.h" + +#define SMR_SOE 0x01U +#define SMR_BDS 0x04U +#define SMR_SBL 0x08U +#define SMR_WUCR 0x10U +#define SMR_MD_UART 0x00U +#define SMR_MD_UART_MP 0x20U +#define SMR_MD_SIO 0x40U +#define SMR_MD_LIN 0x60U +#define SMR_MD_I2C 0x80U + +#define SCR_TXE 0x01U +#define SCR_RXE 0x02U +#define SCR_TBIE 0x04U +#define SCR_TIE 0x08U +#define SCR_RIE 0x10U +#define SCR_UPGL 0x80U + +#define SSR_TBI 0x01U +#define SSR_TDRE 0x02U +#define SSR_RDRF 0x04U +#define SSR_ORE 0x08U +#define SSR_FRE 0x10U +#define SSR_PE 0x20U +#define SSR_REC 0x80U + +#define ESCR_P 0x08U +#define ESCR_PEN 0x10U +#define ESCR_INV 0x20U +#define ESCR_ESBL 0x40U +#define ESCR_FLWEN 0x80U +#define ESCR_DATABITS_8 0x00U +#define ESCR_DATABITS_5 0x01U +#define ESCR_DATABITS_6 0x02U +#define ESCR_DATABITS_7 0x03U +#define ESCR_DATABITS_9 0x04U + +#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; +}; + +/* + * Enable/DISABLE Interrupt Controller + */ +/* deviation from MISRA-C:2004 Rule 19.7 */ +#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) +#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) + +struct serial_device +{ + FM3_MFS03_UART_TypeDef* uart_device; + /* irq number */ + IRQn_Type rx_irq, tx_irq; + + /* rx structure */ + struct serial_int_rx* int_rx; + /* tx structure */ + struct serial_int_tx* int_tx; +}; + +void rt_hw_serial_isr(rt_device_t device); +void rt_hw_serial_init(void); + +#endif diff --git a/bsp/fm3/mb9bf506r/startup.c b/bsp/fm3/mb9bf506r/startup.c index 36bc107ae9..073318abeb 100644 --- a/bsp/fm3/mb9bf506r/startup.c +++ b/bsp/fm3/mb9bf506r/startup.c @@ -1,122 +1,122 @@ -/* - * File : startup.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2009 - 2011, 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 - * 2011-02-24 Bernard first implementation - */ - -#include -#include - -#include "board.h" -#include "mb9bf506r.h" -#ifdef RT_USING_FINSH -#include -#endif - -/** - * @addtogroup FM3 - */ - -extern struct serial_device uart0; -extern struct rt_device uart0_device; -extern struct serial_device uart2; -extern struct rt_device uart2_device; - -/*@{*/ - -extern int rt_application_init(void); -#ifdef RT_USING_FINSH -extern void finsh_system_init(void); -#endif - -#ifdef __CC_ARM -extern int Image$$RW_IRAM1$$ZI$$Limit; -#elif __ICCARM__ -#pragma section="HEAP" -#else -extern int __bss_end; -#endif - -/** - * This function will startup RT-Thread RTOS. - */ -void rtthread_startup(void) -{ - /* init board */ - rt_hw_board_init(); - - /* show version */ - rt_show_version(); - - /* init tick */ - rt_system_tick_init(); - /* init timer system */ - rt_system_timer_init(); - -#ifdef RT_USING_HEAP - #ifdef __CC_ARM - rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)FM3_SRAM_END); - #elif __ICCARM__ - rt_system_heap_init(__segment_end("HEAP"), (void*)FM3_SRAM_END); - #else - /* init memory system */ - rt_system_heap_init((void*)&__bss_end, (void*)FM3_SRAM_END); - #endif -#endif - - /* init scheduler system */ - rt_system_scheduler_init(); - -#ifdef RT_USING_DFS -#ifdef RT_USING_DFS_UFFS - rt_hw_nand_init(); -#endif -#endif - - /* init application */ - rt_application_init(); - -#ifdef RT_USING_FINSH - /* init finsh */ - finsh_system_init(); -#ifdef RT_USING_DEVICE - finsh_set_device("uart2"); -#endif -#endif - - /* init timer thread */ - rt_system_timer_thread_init(); - - /* init idle thread */ - rt_thread_idle_init(); - - /* start scheduler */ - rt_system_scheduler_start(); - - /* never reach here */ - return ; -} - -int main(void) -{ - /* disable interrupt first */ - rt_hw_interrupt_disable(); - - /* init system setting */ - SystemInit(); - - /* startup RT-Thread RTOS */ - rtthread_startup(); - - return 0; -} - -/*@}*/ +/* + * File : startup.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 - 2011, 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 + * 2011-02-24 Bernard first implementation + */ + +#include +#include + +#include "board.h" +#include "mb9bf506r.h" +#ifdef RT_USING_FINSH +#include +#endif + +/** + * @addtogroup FM3 + */ + +extern struct serial_device uart0; +extern struct rt_device uart0_device; +extern struct serial_device uart2; +extern struct rt_device uart2_device; + +/*@{*/ + +extern int rt_application_init(void); +#ifdef RT_USING_FINSH +extern void finsh_system_init(void); +#endif + +#ifdef __CC_ARM +extern int Image$$RW_IRAM1$$ZI$$Limit; +#elif __ICCARM__ +#pragma section="HEAP" +#else +extern int __bss_end; +#endif + +/** + * This function will startup RT-Thread RTOS. + */ +void rtthread_startup(void) +{ + /* init board */ + rt_hw_board_init(); + + /* show version */ + rt_show_version(); + + /* init tick */ + rt_system_tick_init(); + /* init timer system */ + rt_system_timer_init(); + +#ifdef RT_USING_HEAP + #ifdef __CC_ARM + rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)FM3_SRAM_END); + #elif __ICCARM__ + rt_system_heap_init(__segment_end("HEAP"), (void*)FM3_SRAM_END); + #else + /* init memory system */ + rt_system_heap_init((void*)&__bss_end, (void*)FM3_SRAM_END); + #endif +#endif + + /* init scheduler system */ + rt_system_scheduler_init(); + +#ifdef RT_USING_DFS +#ifdef RT_USING_DFS_UFFS + rt_hw_nand_init(); +#endif +#endif + + /* init application */ + rt_application_init(); + +#ifdef RT_USING_FINSH + /* init finsh */ + finsh_system_init(); +#ifdef RT_USING_DEVICE + finsh_set_device("uart2"); +#endif +#endif + + /* init timer thread */ + rt_system_timer_thread_init(); + + /* init idle thread */ + rt_thread_idle_init(); + + /* start scheduler */ + rt_system_scheduler_start(); + + /* never reach here */ + return ; +} + +int main(void) +{ + /* disable interrupt first */ + rt_hw_interrupt_disable(); + + /* init system setting */ + SystemInit(); + + /* startup RT-Thread RTOS */ + rtthread_startup(); + + return 0; +} + +/*@}*/ -- GitLab