Browse Source

update code according to stm32 radio board; add dm9000 eth driver; add nand/lcd test code.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@73 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 years ago
parent
commit
18fd853790

+ 146 - 34
bsp/stm32_radio/application.c

@@ -1,11 +1,11 @@
 /*
- * File      : app.c
+ * File      : application.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
+ * http://www.rt-thread.org/license/LICENSE
  *
  * Change Logs:
  * Date           Author       Notes
@@ -20,6 +20,8 @@
 #include <rtthread.h>
 #include <finsh.h>
 
+#include <stm32f10x.h>
+
 #ifdef RT_USING_DFS
 /* dfs init */
 #include <dfs_init.h>
@@ -29,19 +31,115 @@
 #include <dfs_efs.h>
 /* dfs Filesystem APIs */
 #include <dfs_fs.h>
-#endif
-
-#ifdef RT_USING_LWIP
-#include <lwip/sys.h>
-#include <lwip/api.h>
-#endif
-
-/* thread phase init */
-void rt_init_thread_entry(void *parameter)
-{
-/* Filesystem Initialization */
-#ifdef RT_USING_DFS
-	{
+#endif
+
+#ifdef RT_USING_LWIP
+#include <lwip/sys.h>
+#include <lwip/api.h>
+#endif
+
+/*
+key_enter   PA0
+key_down    PA1
+key_up      PA2
+key_right   PC2
+key_left    PC3
+*/
+#define key_enter_GETVALUE()  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
+#define key_down_GETVALUE()   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)
+#define key_up_GETVALUE()     GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)
+#define key_right_GETVALUE()  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
+#define key_left_GETVALUE()   GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
+
+void rt_key_entry(void *parameter)
+{
+    GPIO_InitTypeDef GPIO_InitStructure;
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC,ENABLE);
+
+    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
+    GPIO_Init(GPIOA,&GPIO_InitStructure);
+
+    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2 | GPIO_Pin_3;
+    GPIO_Init(GPIOC,&GPIO_InitStructure);
+
+    while (1)
+    {
+        if ( key_enter_GETVALUE() == 0 )rt_kprintf("key_enter\r\n");
+        if ( key_down_GETVALUE()  == 0 )rt_kprintf("key_down\r\n");
+        if ( key_up_GETVALUE()    == 0 )rt_kprintf("key_up\r\n");
+        if ( key_right_GETVALUE() == 0 )rt_kprintf("key_right\r\n");
+        if ( key_left_GETVALUE()  == 0 )rt_kprintf("key_left\r\n");
+        rt_thread_delay(20);
+    }
+}
+
+#include "fmt0371\fmt0371.h"
+// lcd test routine
+void fmt0371_test(void)
+{
+    unsigned int color[]={0xf800,0x07e0,0x001f,0xffe0,0x0000,0xffff,0x07ff,0xf81f};
+    unsigned int num;
+    unsigned int n,c;
+
+    for (c=0;c<8;c++)
+    {
+        LCD_ADDR = 0x02;
+        LCD_DATA = 0x00;
+
+        LCD_ADDR = 0x03;
+        LCD_DATA16(0x0000);
+
+        LCD_ADDR = 0x0E;
+        for (n=0;n<240;n++)
+        {
+            for (num=0;num<320;num++)
+            {
+                LCD_DATA16(color[c]);
+            }
+        }
+        rt_thread_delay(100);
+    }
+}
+
+void rt_lcd_entry(void *parameter)
+{
+    GPIO_InitTypeDef GPIO_InitStructure;
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);
+    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
+    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_Init(GPIOF,&GPIO_InitStructure);
+    GPIO_SetBits(GPIOF,GPIO_Pin_9);
+
+    ftm0371_port_init();
+    ftm0371_init();
+    rt_kprintf("Now test the LCD......\r\n");
+    while (1)
+    {
+        fmt0371_test();
+    }
+}
+
+void lcd_test()
+{
+	rt_thread_t lcd_tid;
+	lcd_tid = rt_thread_create("lcd",
+		rt_lcd_entry, RT_NULL,
+		512, 30, 5);
+	if (lcd_tid != RT_NULL) rt_thread_startup(lcd_tid);
+}
+FINSH_FUNCTION_EXPORT(lcd_test, test lcd)
+
+/* thread phase init */
+void rt_init_thread_entry(void *parameter)
+{
+/* Filesystem Initialization */
+#ifdef RT_USING_DFS
+	{
 		/* init the device filesystem */
 		dfs_init();
 		/* init the efsl filesystam*/
@@ -49,33 +147,47 @@ void rt_init_thread_entry(void *parameter)
 
 		/* mount sd card fat partition 1 as root directory */
 		if (dfs_mount("sd0", "/", "efs", 0, 0) == 0)
-			rt_kprintf("File System initialized!\n");
-		else
+			rt_kprintf("File System initialized!\n");
+		else
 			rt_kprintf("File System init failed!\n");
-	}
-#endif
-
-/* LwIP Initialization */
-#ifdef RT_USING_LWIP
-	{
-		extern void lwip_sys_init(void);
-		
-		/* init lwip system */
-		lwip_sys_init();
-		rt_kprintf("TCP/IP initialized!\n");
-	}
-#endif
-}
+	}
+#endif
+
+/* LwIP Initialization */
+#ifdef RT_USING_LWIP
+	{
+		extern void lwip_sys_init(void);
+		
+		/* init lwip system */
+		lwip_sys_init();
+		rt_kprintf("TCP/IP initialized!\n");
+	}
+#endif
+}
 
 int rt_application_init()
 {
-	rt_thread_t init_thread;
+	rt_thread_t init_thread;
 
+#if (RT_THREAD_PRIORITY_MAX == 32)
+	init_thread = rt_thread_create("init",
+								rt_init_thread_entry, RT_NULL,
+								2048, 8, 20);
+#else
 	init_thread = rt_thread_create("init",
 								rt_init_thread_entry, RT_NULL,
-								1024, 8, 20);
-	rt_thread_startup(init_thread);
+								2048, 80, 20);
+#endif
+	if (init_thread != RT_NULL) rt_thread_startup(init_thread);
 
+	/* create keypad thread */
+	{
+		rt_thread_t key_tid;
+		key_tid = rt_thread_create("key", 
+			rt_key_entry, RT_NULL,
+			512, 30, 5);
+		if (key_tid != RT_NULL) rt_thread_startup(key_tid);
+	}
 	return 0;
 }
 

+ 83 - 201
bsp/stm32_radio/board.c

@@ -5,7 +5,7 @@
  *
  * 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
+ * http://www.rt-thread.org/license/LICENSE
  *
  * Change Logs:
  * Date           Author       Notes
@@ -15,7 +15,8 @@
 #include <rthw.h>
 #include <rtthread.h>
 
-#include "stm32f10x_lib.h"
+#include "stm32f10x.h"
+#include "board.h"
 
 static void rt_hw_console_init(void);
 
@@ -33,7 +34,7 @@ static void rt_hw_console_init(void);
  * Return         : None
  *******************************************************************************/
 void RCC_Configuration(void)
-{
+{
 	ErrorStatus HSEStartUpStatus;
 
 	/* RCC system reset(for debug purpose) */
@@ -45,7 +46,7 @@ void RCC_Configuration(void)
 	/* Wait till HSE is ready */
 	HSEStartUpStatus = RCC_WaitForHSEStartUp();
 
-	if(HSEStartUpStatus == SUCCESS)
+    if (HSEStartUpStatus == SUCCESS)
 	{
 		/* HCLK = SYSCLK */
 		RCC_HCLKConfig(RCC_SYSCLK_Div1);
@@ -67,13 +68,13 @@ void RCC_Configuration(void)
 		RCC_PLLCmd(ENABLE);
 
 		/* Wait till PLL is ready */
-		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ;
+        while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ;
 
 		/* Select PLL as system clock source */
 		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
 
 		/* Wait till PLL is used as system clock source */
-		while(RCC_GetSYSCLKSource() != 0x08) ;
+        while (RCC_GetSYSCLKSource() != 0x08) ;
 	}
 }
 
@@ -120,7 +121,7 @@ void  SysTick_Configuration(void)
 extern void rt_hw_interrupt_thread_switch(void);
 /**
  * This is the timer interrupt service routine.
- * 
+ *
  */
 void rt_hw_timer_handler(void)
 {
@@ -128,225 +129,106 @@ void rt_hw_timer_handler(void)
 	rt_interrupt_enter();
 
 	rt_tick_increase();
-	
+
 	/* leave interrupt */
 	rt_interrupt_leave();
-	rt_hw_interrupt_thread_switch();
-}
-
-
-/*******************************************************************************
-* Function Name  : LCD_CtrlLinesConfig
-* Description    : Configures LCD Control lines (FSMC Pins) in alternate function
-                   Push-Pull mode.
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void LCD_CtrlLinesConfig(void)
-{
-	GPIO_InitTypeDef GPIO_InitStructure;
-	
-	/* Enable FSMC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks */
-	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
-	
-	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
-		RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG |
-		RCC_APB2Periph_AFIO, ENABLE);
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-	// GPIO_Init(GPIOA, &GPIO_InitStructure);
-	// GPIO_ResetBits(GPIOA, GPIO_Pin_8);
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
-	GPIO_Init(GPIOC, &GPIO_InitStructure);
-	GPIO_SetBits(GPIOC, GPIO_Pin_6);
-
-	/* Set PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14),
-	 PD.10(D15), PD.14(D0), PD.15(D1) as alternate 
-	 function push pull */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
-	                            GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | 
-	                            GPIO_Pin_15;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-	GPIO_Init(GPIOD, &GPIO_InitStructure);
-
-	/* Set PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10),
-	 PE.14(D11), PE.15(D12) as alternate function push pull */
-	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | 
-	                            GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | 
-	                            GPIO_Pin_15;
-	GPIO_Init(GPIOE, &GPIO_InitStructure);
-
-	// GPIO_WriteBit(GPIOE, GPIO_Pin_6, Bit_SET);
-	/* Set PF.00(A0 (RS)) as alternate function push pull */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-	GPIO_Init(GPIOF, &GPIO_InitStructure);
-	
-	/* Set PG.12(NE4 (LCD/CS)) as alternate function push pull - CE3(LCD /CS) */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
-	GPIO_Init(GPIOG, &GPIO_InitStructure);
-}
-
-/*******************************************************************************
-* Function Name  : LCD_FSMCConfig
-* Description    : Configures the Parallel interface (FSMC) for LCD(Parallel mode)
-* Input          : None
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void LCD_FSMCConfig(void)
-{
-	FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
-	FSMC_NORSRAMTimingInitTypeDef  p;
-	
-	/*-- FSMC Configuration ------------------------------------------------------*/
-	/*----------------------- SRAM Bank 4 ----------------------------------------*/
-	/* FSMC_Bank1_NORSRAM4 configuration */
-	p.FSMC_AddressSetupTime = 0;
-	p.FSMC_AddressHoldTime = 0;
-	p.FSMC_DataSetupTime = 2;
-	p.FSMC_BusTurnAroundDuration = 0;
-	p.FSMC_CLKDivision = 0;
-	p.FSMC_DataLatency = 0;
-	p.FSMC_AccessMode = FSMC_AccessMode_A;
-	
-	/* Color LCD configuration ------------------------------------
-	 LCD configured as follow:
-	    - Data/Address MUX = Disable
-	    - Memory Type = SRAM
-	    - Data Width = 16bit
-	    - Write Operation = Enable
-	    - Extended Mode = Enable
-	    - Asynchronous Wait = Disable */
-	FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
-	FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
-	FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
-	FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
-	FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
-	FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
-	FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
-	FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
-	FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
-	FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
-	FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
-	// FSMC_NORSRAMInitStructure.FSMC_AsyncWait = FSMC_AsyncWait_Disable;
-	FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
-	FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
-	FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
-	
-	FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);  
-	
-	/* BANK 4 (of NOR/SRAM Bank 1~4) is enabled */
-	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
-}
-
-/*******************************************************************************
-* Function Name  : FSMC_SRAM_Init
-* Description    : Configures the FSMC and GPIOs to interface with the SRAM memory.
-*                  This function must be called before any write/read operation
-*                  on the SRAM.
-* Input          : None 
-* Output         : None
-* Return         : None
-*******************************************************************************/
-void FSMC_SRAM_Init(void)
-{
-#define REG32(x)	(*(volatile unsigned long*)(x))
-
-	/* enable FSMC clock */
-	REG32(0x40021014) = 0x114;
-	
-	/* enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
-	REG32(0x40021018) = 0x1e0;
-	
-	/* SRAM Data lines, NOE and NWE configuration */
-	REG32(0x40011400) = 0x44BB44BB;
-	REG32(0x40011404) = 0xBBBBBBBB;
-	REG32(0x40011800) = 0xB44444BB;
-	REG32(0x40011804) = 0xBBBBBBBB;
-	REG32(0x40011C00) = 0x44BBBBBB;
-	REG32(0x40011C04) = 0xBBBB4444;
-	REG32(0x40012000) = 0x44BBBBBB;
-	REG32(0x40012004) = 0x44444B44;
-	
-	/* FSMC Configuration (enable FSMC Bank1_SRAM Bank) */
-	REG32(0xA0000010) = 0x00001011;
-	REG32(0xA0000014) = 0x00000200;	
-	
-	LCD_CtrlLinesConfig();
-	LCD_FSMCConfig();
-}
+}
+
+/* NAND Flash */
+#include "fsmc_nand.h"
 
 /**
- * This function will initial STM32 board.
+ * This function will initial STM32 Radio board.
  */
 void rt_hw_board_init()
 {
+	NAND_IDTypeDef NAND_ID;
+
 	/* Configure the system clocks */
 	RCC_Configuration();
 
 	/* NVIC Configuration */
-	NVIC_Configuration();
-	
-	/* SRAM init */
-	FSMC_SRAM_Init();
+	NVIC_Configuration();
 
 	/* Configure the SysTick */
-	SysTick_Configuration();
-	
-	rt_hw_console_init();
+	SysTick_Configuration();
+
+	/* Console Initialization*/
+	rt_hw_console_init();
+
+    /* FSMC Initialization */
+    FSMC_NAND_Init();
+
+    /* NAND read ID command */
+    FSMC_NAND_ReadID(&NAND_ID);
+    rt_kprintf("Read the NAND ID:%02X%02X%02X%02X\n",NAND_ID.Maker_ID,NAND_ID.Device_ID,NAND_ID.Third_ID,NAND_ID.Fourth_ID);
+
+    /* SRAM init */
+    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
+	FSMC_SRAM_Init();
+	
+	{
+		/* PC6 for SDCard Rst */
+        GPIO_InitTypeDef GPIO_InitStructure;
+
+        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+        GPIO_Init(GPIOC,&GPIO_InitStructure);
+        GPIO_SetBits(GPIOC,GPIO_Pin_6);
+	}
 }
 
 /* init console to support rt_kprintf */
 static void rt_hw_console_init()
 {
 	/* Enable USART1 and GPIOA clocks */
-	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1
+                           | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC
+                           | RCC_APB2Periph_GPIOF, ENABLE);
 
 	/* GPIO configuration */
 	{
-	GPIO_InitTypeDef GPIO_InitStructure;
-
-	/* Configure USART1 Tx (PA.09) as alternate function push-pull */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-	GPIO_Init(GPIOA, &GPIO_InitStructure);
-
-	/* Configure USART1 Rx (PA.10) as input floating */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
-	GPIO_Init(GPIOA, &GPIO_InitStructure);
+        GPIO_InitTypeDef GPIO_InitStructure;
+
+        /* Configure USART1 Tx (PA.09) as alternate function push-pull */
+        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+        GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+        /* Configure USART1 Rx (PA.10) as input floating */
+        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+        GPIO_Init(GPIOA, &GPIO_InitStructure);
 	}
 
 	/* USART configuration */
 	{
-	USART_InitTypeDef USART_InitStructure;
-	
-	/* USART1 configured as follow:
-		- BaudRate = 115200 baud
-		- Word Length = 8 Bits
-		- One Stop Bit
-		- No parity
-		- Hardware flow control disabled (RTS and CTS signals)
-		- Receive and transmit enabled
-		- USART Clock disabled
-		- USART CPOL: Clock is active low
-		- USART CPHA: Data is captured on the middle
-		- USART LastBit: The clock pulse of the last data bit is not output to
-		  the SCLK pin
-	*/
-	USART_InitStructure.USART_BaudRate = 115200;
-	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
-	USART_InitStructure.USART_StopBits = USART_StopBits_1;
-	USART_InitStructure.USART_Parity = USART_Parity_No;
-	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
-	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
-	USART_Init(USART1, &USART_InitStructure);
-	/* Enable USART1 */
-	USART_Cmd(USART1, ENABLE);
+        USART_InitTypeDef USART_InitStructure;
+
+        /* USART1 configured as follow:
+            - BaudRate = 115200 baud
+            - Word Length = 8 Bits
+            - One Stop Bit
+            - No parity
+            - Hardware flow control disabled (RTS and CTS signals)
+            - Receive and transmit enabled
+            - USART Clock disabled
+            - USART CPOL: Clock is active low
+            - USART CPHA: Data is captured on the middle
+            - USART LastBit: The clock pulse of the last data bit is not output to
+              the SCLK pin
+        */
+        USART_InitStructure.USART_BaudRate = 115200;
+        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+        USART_InitStructure.USART_StopBits = USART_StopBits_1;
+        USART_InitStructure.USART_Parity = USART_Parity_No;
+        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
+        USART_Init(USART1, &USART_InitStructure);
+        /* Enable USART1 */
+        USART_Cmd(USART1, ENABLE);
 	}
 }
 
@@ -365,7 +247,7 @@ static void rt_hw_console_putc(const char c)
 
 /**
  * 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)

+ 28 - 5
bsp/stm32_radio/board.h

@@ -5,23 +5,46 @@
  *
  * 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
+ * http://www.rt-thread.org/license/LICENSE
  *
  * Change Logs:
  * Date           Author       Notes
- * 2006-10-08     Bernard      add board.h to this bsp
+ * 2009-09-22     Bernard      add board.h to this bsp
  */
 
+// <<< Use Configuration Wizard in Context Menu >>>
 #ifndef __BOARD_H__
 #define __BOARD_H__
-
-#define RT_USING_SRAM
+
+/* board configuration */
+// <o> SDCard Driver <1=>SDIO sdcard <0=>SPI MMC card
+// 	<i>Default: 1
+#define STM32_USE_SDIO			1
+
+/* whether use board external SRAM memory */
+// <e>Use external SRAM memory on the board
+// 	<i>Enable External SRAM memory
+#define STM32_EXT_SRAM          0
+//	<o>Begin Address of External SRAM
+//		<i>Default: 0x68000000
+#define STM32_EXT_SRAM_BEGIN    0x68000000 /* the begining address of external SRAM */
+//	<o>End Address of External SRAM
+//		<i>Default: 0x68080000
+#define STM32_EXT_SRAM_END      0x68080000 /* the end address of external SRAM */
+// </e>
+
+// <o> Internal SRAM memory size[Kbytes] <8-64>
+//	<i>Default: 64
+#define STM32_SRAM_SIZE         64
+#define STM32_SRAM_END          (0x20000000 + STM32_SRAM_SIZE * 1024)
 
 void rt_hw_board_led_on(int n);
 void rt_hw_board_led_off(int n);
 void rt_hw_board_init(void);
 
 void rt_hw_usart_init(void);
-void rt_hw_sdcard_init(void);
+void rt_hw_sdcard_init(void);
 
 #endif
+
+// <<< Use Configuration Wizard in Context Menu >>>

+ 0 - 56
bsp/stm32_radio/dac.c

@@ -1,56 +0,0 @@
-#include <rtthread.h>
-
-#include "dac.h"
-
-short dac_buffer[MAX_BUFFERS][DAC_BUFFER_MAX_SIZE];
-int dac_buffer_size[MAX_BUFFERS];
-int stopped;
-unsigned long current_srate;
-unsigned int underruns;
-
-void dac_reset()
-{
-	stopped = 1;
-	underruns = 0;
-	dac_set_srate(44100);
-}
-
-// return the index of the next writeable buffer or -1 on failure
-int dac_get_writeable_buffer()
-{
-	return 0;
-}
-
-// returns -1 if there is no free DMA buffer
-int dac_fill_dma()
-{
-	return 0;
-}
-
-int dac_set_srate(unsigned long srate)
-{
-	if (current_srate == srate)
-		return 0;
-		
-	rt_kprintf("setting rate %lu\n", srate);
-	switch(srate) {
-	case 8000:	
-	case 8021:	
-	case 32000:	
-	case 44100:	
-	case 48000:	
-	case 88200:	
-	case 96000:	
-		break;
-	default:
-		return -1;
-	}
-
-	current_srate = srate;
-	return 0;
-}
-
-void dac_init(void)
-{
-	dac_reset();
-}

+ 0 - 33
bsp/stm32_radio/dac.h

@@ -1,33 +0,0 @@
-#ifndef _DAC_H_
-#define _DAC_H_
-
-#define MAX_BUFFERS 1
-#define DAC_BUFFER_MAX_SIZE 2400
-extern short dac_buffer[MAX_BUFFERS][DAC_BUFFER_MAX_SIZE];
-extern int dac_buffer_size[MAX_BUFFERS];
-extern unsigned long current_srate;
-extern unsigned int underruns;
-
-void dac_reset(void);
-int dac_get_writeable_buffer(void);
-int dac_get_readable_buffer(void);
-int dac_readable_buffers(void);
-int dac_writeable_buffers(void);
-int dac_busy_buffers(void);
-int adc_busy_buffers(void);
-int dac_fill_dma(void);
-
-void dac_enable_dma(void);
-void dac_disable_dma(void);
-int dac_next_dma_empty(void);
-int dac_first_dma_empty(void);
-int adc_next_dma_empty(void);
-int adc_first_dma_empty(void);
-void dac_set_first_dma(short *buffer, int n);
-void dac_set_next_dma(short *buffer, int n);
-int dma_endtx(void);
-void dac_write_reg(unsigned char reg, unsigned short value);
-int dac_set_srate(unsigned long srate);
-void dac_init(void);
-
-#endif /* _DAC_H_ */

+ 160 - 32
bsp/stm32_radio/dm9000.c

@@ -3,13 +3,16 @@
 
 #include <netif/ethernetif.h>
 #include "lwipopts.h"
+#include <stm32f10x_lib.h>
 
 /*
  * DM9000 interrupt line is connected to PF7
  */
 //--------------------------------------------------------
 
-#define DM9000_PHY              0x40    /* PHY address 0x01 */
+#define DM9000_PHY          0x40    /* PHY address 0x01 */
+#define RST_1()             GPIO_SetBits(GPIOF,GPIO_Pin_6)
+#define RST_0()             GPIO_ResetBits(GPIOF,GPIO_Pin_6)
 
 #define MAX_ADDR_LEN 6
 enum DM9000_PHY_mode
@@ -38,6 +41,9 @@ struct rt_dm9000_eth
 	rt_uint8_t  dev_addr[MAX_ADDR_LEN];			/* hw address	*/
 };
 static struct rt_dm9000_eth dm9000_device;
+static struct rt_semaphore sem_ack, sem_lock;
+
+void rt_dm9000_isr(void);
 
 static void delay_ms(rt_uint32_t ms)
 {
@@ -127,9 +133,12 @@ rt_inline void phy_mode_set(rt_uint32_t media_mode)
 }
 
 /* interrupt service routine */
-void rt_dm9000_isr(int irqno)
+void rt_dm9000_isr()
 {
     rt_uint32_t int_status;
+	rt_uint32_t last_io;
+
+	last_io = DM9000_IO;
 
     /* Disable all interrupts */
     dm9000_io_write(DM9000_IMR, IMR_PAR);
@@ -138,6 +147,17 @@ void rt_dm9000_isr(int irqno)
     int_status = dm9000_io_read(DM9000_ISR);               /* Got ISR */
     dm9000_io_write(DM9000_ISR, int_status);    /* Clear ISR status */
 
+	/* receive overflow */
+	if (int_status & ISR_ROS)
+	{
+		rt_kprintf("overflow\n");
+	}
+
+	if (int_status & ISR_ROOS)
+	{
+		rt_kprintf("overflow counter overflow\n");
+	}
+
     /* Received the coming packet */
     if (int_status & ISR_PRS)
     {
@@ -145,6 +165,7 @@ void rt_dm9000_isr(int irqno)
 
         /* a frame has been received */
         result = eth_device_ready(&(dm9000_device.parent));
+		if (result != RT_EOK) rt_kprintf("eth notification failed\n");
         RT_ASSERT(result == RT_EOK);
     }
 
@@ -157,11 +178,14 @@ void rt_dm9000_isr(int irqno)
         if (tx_status & (NSR_TX2END | NSR_TX1END))
         {
             /* One packet sent complete */
+			rt_sem_release(&sem_ack);
         }
     }
 
     /* Re-enable interrupt mask */
     dm9000_io_write(DM9000_IMR, dm9000_device.imr_all);
+
+	DM9000_IO = last_io;
 }
 
 /* RT-Thread Device Interface */
@@ -173,7 +197,7 @@ static rt_err_t rt_dm9000_init(rt_device_t dev)
 
 	/* RESET device */
 	dm9000_io_write(DM9000_NCR, NCR_RST);
-	delay_ms(1000);		/* delay 1ms */
+	delay_ms(100);		/* delay 1ms */
 
     /* identfy DM9000 */
 	value  = dm9000_io_read(DM9000_VIDL);
@@ -190,9 +214,9 @@ static rt_err_t rt_dm9000_init(rt_device_t dev)
     }
 
 	/* GPIO0 on pre-activate PHY */
-	dm9000_io_write(DM9000_GPR, 0x00);	            /*REG_1F bit0 activate phyxcer */
-	dm9000_io_write(DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */
-    dm9000_io_write(DM9000_GPR, 0);                 /* Enable PHY */
+	dm9000_io_write(DM9000_GPR, 0x00);	            /* REG_1F bit0 activate phyxcer */
+	// dm9000_io_write(DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */
+    // dm9000_io_write(DM9000_GPR, 0x00);                 /* Enable PHY */
 
 	/* Set PHY */
 	phy_mode_set(DM9000_AUTO);
@@ -206,24 +230,26 @@ static rt_err_t rt_dm9000_init(rt_device_t dev)
 	dm9000_io_write(DM9000_SMCR, 0);	/* Special Mode */
 	dm9000_io_write(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	/* clear TX status */
 	dm9000_io_write(DM9000_ISR, 0x0f);	/* Clear interrupt status */
-	dm9000_io_write(0x2D, 0x80);      	/* Switch LED to mode 1 */
+	dm9000_io_write(DM9000_TCR2, 0x90);	/* Switch LED to mode 1 and one packet mode */
 
 	/* set mac address */
 	for (i = 0, oft = 0x10; i < 6; i++, oft++)
 		dm9000_io_write(oft, dm9000_device.dev_addr[i]);
+	/* set multicast address */
 	for (i = 0, oft = 0x16; i < 8; i++, oft++)
 		dm9000_io_write(oft, 0xff);
 
 	/* Activate DM9000 */
 	dm9000_io_write(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	/* RX enable */
+	dm9000_io_write(DM9000_IMR, IMR_PAR);
 
 	i = 0;
 	while (!(phy_read(1) & 0x20))
 	{
         /* autonegation complete bit */
-		delay_ms(1000);
+		delay_ms(100);
 		i++;
-		if (i == 10000)
+		if (i == 100000)
 		{
 			rt_kprintf("could not establish link\n");
 			return 0;
@@ -307,11 +333,14 @@ static rt_err_t rt_dm9000_control(rt_device_t dev, rt_uint8_t cmd, void *args)
 rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
 {
 	struct pbuf* q;
-	rt_uint32_t len;
+	rt_int32_t len;
 	rt_uint16_t* ptr;
 
+	/* lock DM9000 device */
+	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
     /* Move data to DM9000 TX RAM */
-	DM9000_IO = DM9000_MWCMD;
+	DM9000_outb(DM9000_IO_BASE, DM9000_MWCMD);
 
 	for (q = p; q != NULL; q = q->next)
 	{
@@ -319,21 +348,25 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
 		ptr = q->payload;
 
         /* use 16bit mode to write data to DM9000 RAM */
-        while (len)
+        while (len > 0)
         {
-			DM9000_DATA = *ptr;
+			DM9000_outw(DM9000_DATA_BASE, *ptr);
             ptr ++; len -= 2;
-        }
+        }
 	}
 
-    if (p->tot_len < 64) /* add pading */
-    {
-    }
-
     /* Set TX length to DM9000 */
     dm9000_io_write(DM9000_TXPLL, p->tot_len & 0xff);
     dm9000_io_write(DM9000_TXPLH, (p->tot_len >> 8) & 0xff);
 
+	/* Issue TX polling command */
+	dm9000_io_write(DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
+
+	/* unlock DM9000 device */
+	rt_sem_release(&sem_lock);
+
+	rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
+
 	return RT_EOK;
 }
 
@@ -341,42 +374,49 @@ rt_err_t rt_dm9000_tx( rt_device_t dev, struct pbuf* p)
 struct pbuf *rt_dm9000_rx(rt_device_t dev)
 {
     struct pbuf* p;
-	rt_uint32_t len;
+	rt_uint32_t rxbyte;
 
     /* init p pointer */
     p = RT_NULL;
 
+	/* lock DM9000 device */
+	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+
 	/* Check packet ready or not */
 	dm9000_io_read(DM9000_MRCMDX);	    /* Dummy read */
-	len = DM9000_DATA;					/* Got most updated data */
-	if (len)
+	rxbyte = DM9000_inb(DM9000_DATA_BASE);		/* Got most updated data */
+	if (rxbyte)
     {
         rt_uint16_t rx_status, rx_len;
         rt_uint16_t* data;
 
+		if (rxbyte > 1)
+		{
 		dm9000_io_write(DM9000_RCR, 0x00);	/* Stop Device */
 		dm9000_io_write(DM9000_ISR, 0x80);	/* Stop INT request */
+		}
 
         /* A packet ready now  & Get status/length */
-        DM9000_IO = DM9000_MRCMD;
+        DM9000_outb(DM9000_IO_BASE, DM9000_MRCMD);
 
-        rx_status = DM9000_DATA;
-        rx_len = DM9000_DATA;
+        rx_status = DM9000_inw(DM9000_DATA_BASE);
+        rx_len = DM9000_inw(DM9000_DATA_BASE);
 
         /* allocate buffer */
         p = pbuf_alloc(PBUF_LINK, rx_len, PBUF_RAM);
         if (p != RT_NULL)
         {
             struct pbuf* q;
+			rt_int32_t len;
 
             for (q = p; q != RT_NULL; q= q->next)
             {
                 data = (rt_uint16_t*)q->payload;
                 len = q->len;
 
-                while (len)
+                while (len > 0)
                 {
-                    *data = DM9000_DATA;
+                    *data = DM9000_inw(DM9000_DATA_BASE);
                     data ++; len -= 2;
                 }
             }
@@ -389,7 +429,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
             data = &dummy;
             while (rx_len)
             {
-                *data = DM9000_DATA;
+                *data = DM9000_inw(DM9000_DATA_BASE);
                 rx_len -= 2;
             }
         }
@@ -414,7 +454,7 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
 
 				/* RESET device */
 				dm9000_io_write(DM9000_NCR, NCR_RST);
-				delay_ms(1000);		/* delay 1ms */
+				rt_thread_delay(1); /* delay 5ms */
             }
 
             /* it issues an error, release pbuf */
@@ -428,14 +468,83 @@ struct pbuf *rt_dm9000_rx(rt_device_t dev)
         dm9000_io_write(DM9000_IMR, dm9000_device.imr_all);
     }
 
+	/* unlock DM9000 device */
+	rt_sem_release(&sem_lock);
+
     return p;
 }
 
+
+static void RCC_Configuration(void)
+{
+    /* enable gpiob port clock */
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF | RCC_APB2Periph_AFIO, ENABLE);
+}
+
+static void NVIC_Configuration(void)
+{
+    NVIC_InitTypeDef NVIC_InitStructure;
+
+    /* Configure one bit for preemption priority */
+    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+
+    /* Enable the EXTI0 Interrupt */
+    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+}
+
+static void GPIO_Configuration()
+{
+	GPIO_InitTypeDef GPIO_InitStructure;
+    EXTI_InitTypeDef EXTI_InitStructure;
+
+    /* configure PF6 as eth RST */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_Init(GPIOF,&GPIO_InitStructure);
+    GPIO_ResetBits(GPIOF,GPIO_Pin_6);
+    RST_1();
+
+	/* configure PF7 as external interrupt */
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
+	GPIO_Init(GPIOF, &GPIO_InitStructure);
+
+    /* Connect DM9000 EXTI Line to GPIOF Pin 7 */
+    GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, GPIO_PinSource7);
+
+    /* Configure DM9000 EXTI Line to generate an interrupt on falling edge */
+    EXTI_InitStructure.EXTI_Line = EXTI_Line7;
+    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+    EXTI_Init(&EXTI_InitStructure);
+
+	/* Clear the Key Button EXTI line pending bit */
+	EXTI_ClearITPendingBit(EXTI_Line7);
+}
+
 void rt_hw_dm9000_init()
 {
+	RCC_Configuration();
+	NVIC_Configuration();
+	GPIO_Configuration();
+
+	rt_sem_init(&sem_ack, "tx_ack", 0, RT_IPC_FLAG_FIFO);
+	rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
+
     dm9000_device.type    = TYPE_DM9000A;
-    dm9000_device.imr_all = IMR_PAR | IMR_PTM | IMR_PRM;
-	
+	/*
+	 * SRAM Tx/Rx pointer automatically return to start address,
+	 * Packet Transmitted, Packet Received
+	 */
+    dm9000_device.imr_all = IMR_PAR | IMR_ROOM | IMR_ROM | IMR_PTM | IMR_PRM;
+
 	dm9000_device.dev_addr[0] = 0x01;
 	dm9000_device.dev_addr[1] = 0x60;
 	dm9000_device.dev_addr[2] = 0x6E;
@@ -454,8 +563,7 @@ void rt_hw_dm9000_init()
 	dm9000_device.parent.eth_rx     = rt_dm9000_rx;
 	dm9000_device.parent.eth_tx     = rt_dm9000_tx;
 
-	rt_device_register((rt_device_t)&dm9000_device,
-		"E0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX);
+	eth_device_init(&(dm9000_device.parent), "e0");
 }
 
 #ifdef RT_USING_FINSH
@@ -470,7 +578,27 @@ void dm9000(void)
 	rt_kprintf("TSRII (0x04): %02x\n", dm9000_io_read(DM9000_TSR2));
 	rt_kprintf("RCR   (0x05): %02x\n", dm9000_io_read(DM9000_RCR));
 	rt_kprintf("RSR   (0x06): %02x\n", dm9000_io_read(DM9000_RSR));
+	rt_kprintf("ORCR  (0x07): %02x\n", dm9000_io_read(DM9000_ROCR));
+	rt_kprintf("CRR   (0x2C): %02x\n", dm9000_io_read(DM9000_CHIPR));
+	rt_kprintf("CSCR  (0x31): %02x\n", dm9000_io_read(DM9000_CSCR));
+	rt_kprintf("RCSSR (0x32): %02x\n", dm9000_io_read(DM9000_RCSSR));
 	rt_kprintf("ISR   (0xFE): %02x\n", dm9000_io_read(DM9000_ISR));
+	rt_kprintf("IMR   (0xFF): %02x\n", dm9000_io_read(DM9000_IMR));
 	rt_kprintf("\n");
 }
+FINSH_FUNCTION_EXPORT(dm9000, dm9000 register dump);
+
+void rx(void)
+{
+	rt_err_t result;
+
+    dm9000_io_write(DM9000_ISR, ISR_PRS);		/* Clear rx status */
+
+	/* a frame has been received */
+	result = eth_device_ready(&(dm9000_device.parent));
+	if (result != RT_EOK) rt_kprintf("eth notification failed\n");
+	RT_ASSERT(result == RT_EOK);
+}
+FINSH_FUNCTION_EXPORT(rx, notify packet rx);
+
 #endif

+ 16 - 2
bsp/stm32_radio/dm9000.h

@@ -1,9 +1,17 @@
 #ifndef __DM9000_H__
 #define __DM9000_H__
 
+#define DM9000_IO_BASE		0x6C000000
+#define DM9000_DATA_BASE	0x6C000008
+
 #define    DM9000_IO 	(*((volatile rt_uint16_t *) 0x6C000000)) // CMD = 0
 #define    DM9000_DATA 	(*((volatile rt_uint16_t *) 0x6C000008)) // CMD = 1
 
+#define DM9000_inb(r) 		(*(volatile rt_uint8_t *)r)
+#define DM9000_outb(r, d) 	(*(volatile rt_uint8_t *)r = d)
+#define DM9000_inw(r) 		(*(volatile rt_uint16_t *)r)
+#define DM9000_outw(r, d) 	(*(volatile rt_uint16_t *)r = d)
+
 #define    RST_1()   GPIO_SetBits(GPIOF,GPIO_Pin_6)
 #define    RST_0()   GPIO_ResetBits(GPIOF,GPIO_Pin_6)
 
@@ -44,10 +52,13 @@
 #define DM9000_PIDH         0x2B
 
 #define DM9000_CHIPR        0x2C
+#define DM9000_TCR2			0x2D
+#define DM9000_OTCR			0x2E
 #define DM9000_SMCR         0x2F
 
-#define CHIPR_DM9000A       0x19
-#define CHIPR_DM9000B       0x1B
+#define DM9000_ETCR			0x30	/* early transmit control/status register */
+#define DM9000_CSCR			0x31	/* check sum control register */
+#define DM9000_RCSSR		0x32	/* receive check sum status register */
 
 #define DM9000_MRCMDX       0xF0
 #define DM9000_MRCMD        0xF2
@@ -62,6 +73,9 @@
 #define DM9000_ISR          0xFE
 #define DM9000_IMR          0xFF
 
+#define CHIPR_DM9000A       0x19
+#define CHIPR_DM9000B       0x1B
+
 #define NCR_EXT_PHY         (1<<7)
 #define NCR_WAKEEN          (1<<6)
 #define NCR_FCOL            (1<<4)

+ 0 - 727
bsp/stm32_radio/enc28j60.c

@@ -1,727 +0,0 @@
-#include "enc28j60.h"
-
-#include <netif/ethernetif.h>
-#include "lwipopts.h"
-#include "stm32f10x_lib.h"
-
-#define MAX_ADDR_LEN    6
-
-// #define CSACTIVE    GPIO_ResetBits(GPIOB,  GPIO_Pin_12);
-// #define CSPASSIVE   GPIO_SetBits(GPIOB,  GPIO_Pin_12);
-#define CSACTIVE 	GPIOB->BRR = GPIO_Pin_12;
-#define CSPASSIVE	GPIOB->BSRR = GPIO_Pin_12;
-
-struct net_device
-{
-	/* inherit from ethernet device */
-	struct eth_device parent;
-
-	/* interface address info. */
-	rt_uint8_t  dev_addr[MAX_ADDR_LEN];			/* hw address	*/
-};
-
-static struct net_device  enc28j60_dev_entry;
-static struct net_device *enc28j60_dev =&enc28j60_dev_entry;
-static rt_uint8_t  Enc28j60Bank;
-static rt_uint16_t NextPacketPtr;
-static struct rt_semaphore tx_sem;
-
-void _delay_us(rt_uint32_t us)
-{
-	rt_uint32_t len;
-	for (;us > 0; us --)
-		for (len = 0; len < 20; len++ );
-}
-
-void delay_ms(rt_uint32_t ms)
-{
-	rt_uint32_t len;
-	for (;ms > 0; ms --)
-		for (len = 0; len < 100; len++ );
-}
-
-rt_uint8_t spi_read_op(rt_uint8_t op, rt_uint8_t address)
-{
-	int temp=0;
-	CSACTIVE;
-
-	SPI_I2S_SendData(SPI2, (op | (address & ADDR_MASK)));
-	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-	SPI_I2S_ReceiveData(SPI2);
-	SPI_I2S_SendData(SPI2, 0x00);
-	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-
-	// do dummy read if needed (for mac and mii, see datasheet page 29)
-	if(address & 0x80)
-	{
-		SPI_I2S_ReceiveData(SPI2);
-		SPI_I2S_SendData(SPI2, 0x00);
-		while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-	}
-	// release CS
-
-	temp=SPI_I2S_ReceiveData(SPI2);
-	// for(t=0;t<20;t++);
-	CSPASSIVE;
-	return (temp);
-}
-
-void spi_write_op(rt_uint8_t op, rt_uint8_t address, rt_uint8_t data)
-{
-	rt_uint32_t level;
-	
-	level = rt_hw_interrupt_disable();
-	
-	CSACTIVE;
-	SPI_I2S_SendData(SPI2, op | (address & ADDR_MASK));
-	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-	SPI_I2S_SendData(SPI2,data);
-	while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-	CSPASSIVE;
-	
-	rt_hw_interrupt_enable(level);
-}
-
-void enc28j60_set_bank(rt_uint8_t address)
-{
-	// set the bank (if needed)
-	if((address & BANK_MASK) != Enc28j60Bank)
-	{
-		// set the bank
-		spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
-		spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
-		Enc28j60Bank = (address & BANK_MASK);
-	}
-}
-
-rt_uint8_t spi_read(rt_uint8_t address)
-{
-	// set the bank
-	enc28j60_set_bank(address);
-	// do the read
-	return spi_read_op(ENC28J60_READ_CTRL_REG, address);
-}
-
-void spi_write(rt_uint8_t address, rt_uint8_t data)
-{
-	// set the bank
-	enc28j60_set_bank(address);
-	// do the write
-	spi_write_op(ENC28J60_WRITE_CTRL_REG, address, data);
-}
-
-void enc28j60_phy_write(rt_uint8_t address, rt_uint16_t data)
-{
-	// set the PHY register address
-	spi_write(MIREGADR, address);
-
-	// write the PHY data
-	spi_write(MIWRL, data);
-	spi_write(MIWRH, data>>8);
-
-	// wait until the PHY write completes
-	while(spi_read(MISTAT) & MISTAT_BUSY)
-	{
-		_delay_us(15);
-	}
-}
-
-// read upper 8 bits
-rt_uint16_t enc28j60_phy_read(rt_uint8_t address)
-{
-	// Set the right address and start the register read operation
-	spi_write(MIREGADR, address);
-	spi_write(MICMD, MICMD_MIIRD);
-
-	_delay_us(15);
-
-	// wait until the PHY read completes
-	while(spi_read(MISTAT) & MISTAT_BUSY);
-
-	// reset reading bit
-	spi_write(MICMD, 0x00);
-
-	return (spi_read(MIRDH));
-}
-
-void enc28j60_clkout(rt_uint8_t clk)
-{
-	//setup clkout: 2 is 12.5MHz:
-	spi_write(ECOCON, clk & 0x7);
-}
-
-/*
- * Access the PHY to determine link status
- */
-static void enc28j60_check_link_status()
-{
-	rt_uint16_t reg;
-	int duplex;
-
-	reg = enc28j60_phy_read(PHSTAT2);
-	duplex = reg & PHSTAT2_DPXSTAT;
-
-	if (reg & PHSTAT2_LSTAT)
-	{
-	    /* on */
-	}
-	else
-	{
-	    /* off */
-	}
-}
-
-#ifdef RT_USING_FINSH
-#include <finsh.h>
-/*
- * Debug routine to dump useful register contents
- */
-static void enc28j60(void)
-{
-	rt_kprintf("-- enc28j60 registers:\n");
-	rt_kprintf("HwRevID: 0x%02x\n", spi_read(EREVID));
-	rt_kprintf("Cntrl: ECON1 ECON2 ESTAT  EIR  EIE\n");
-	rt_kprintf("       0x%02x  0x%02x  0x%02x  0x%02x  0x%02x\n",spi_read(ECON1), spi_read(ECON2), spi_read(ESTAT), spi_read(EIR), spi_read(EIE));
-	rt_kprintf("MAC  : MACON1 MACON3 MACON4\n");
-	rt_kprintf("       0x%02x   0x%02x   0x%02x\n", spi_read(MACON1), spi_read(MACON3), spi_read(MACON4));
-	rt_kprintf("Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\n");
-	rt_kprintf("       0x%04x 0x%04x 0x%04x  0x%04x  ",
-		(spi_read(ERXSTH) << 8) | spi_read(ERXSTL),
-		(spi_read(ERXNDH) << 8) | spi_read(ERXNDL),
-		(spi_read(ERXWRPTH) << 8) | spi_read(ERXWRPTL),
-		(spi_read(ERXRDPTH) << 8) | spi_read(ERXRDPTL));
-	rt_kprintf("0x%02x    0x%02x    0x%04x\n", spi_read(ERXFCON), spi_read(EPKTCNT),
-		(spi_read(MAMXFLH) << 8) | spi_read(MAMXFLL));
-
-	rt_kprintf("Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP\n");
-	rt_kprintf("       0x%04x 0x%04x 0x%02x     0x%02x     0x%02x\n",
-		(spi_read(ETXSTH) << 8) | spi_read(ETXSTL),
-		(spi_read(ETXNDH) << 8) | spi_read(ETXNDL),
-		spi_read(MACLCON1), spi_read(MACLCON2), spi_read(MAPHSUP));
-}
-FINSH_FUNCTION_EXPORT(enc28j60, dump enc28j60 registers)
-#endif
-
-/*
- * RX handler
- * ignore PKTIF because is unreliable! (look at the errata datasheet)
- * check EPKTCNT is the suggested workaround.
- * We don't need to clear interrupt flag, automatically done when
- * enc28j60_hw_rx() decrements the packet counter.
- * Returns how many packet processed.
- */
-void enc28j60_isr()
-{
-	/* Variable definitions can be made now. */
-	volatile rt_uint32_t eir, pk_counter;
-	volatile rt_bool_t rx_activiated;
-	
-	rx_activiated = RT_FALSE;
-	
-	/* get EIR */
-	eir = spi_read(EIR);
-	// rt_kprintf("eir: 0x%08x\n", eir);
-
-	do
-	{
-		/* errata #4, PKTIF does not reliable */
-	    pk_counter = spi_read(EPKTCNT);
-	    if (pk_counter)
-	    {
-	        rt_err_t result;
-	        /* a frame has been received */
-	        result = eth_device_ready((struct eth_device*)&(enc28j60_dev->parent));
-	        RT_ASSERT(result == RT_EOK);
-			
-			// switch to bank 0
-			enc28j60_set_bank(EIE);
-			// disable rx interrutps
-			spi_write_op(ENC28J60_BIT_FIELD_CLR, EIE, EIE_PKTIE);
-	    }
-	
-		/* clear PKTIF */
-		if (eir & EIR_PKTIF)
-		{
-			enc28j60_set_bank(EIR);
-			spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_PKTIF);
-			
-			rx_activiated = RT_TRUE;
-		}
-	
-		/* clear DMAIF */
-	    if (eir & EIR_DMAIF)
-		{
-			enc28j60_set_bank(EIR);
-			spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF);
-		}
-	
-	    /* LINK changed handler */
-	    if ( eir & EIR_LINKIF)
-	    {
-	        enc28j60_check_link_status();
-	
-	        /* read PHIR to clear the flag */
-	        enc28j60_phy_read(PHIR);
-	
-			enc28j60_set_bank(EIR);
-			spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_LINKIF);
-	    }
-	
-		if (eir & EIR_TXIF)
-		{
-			/* A frame has been transmitted. */
-			rt_sem_release(&tx_sem);
-	
-			enc28j60_set_bank(EIR);
-			spi_write_op(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXIF);
-		}
-		eir = spi_read(EIR);
-		// rt_kprintf("inner eir: 0x%08x\n", eir);
-	} while ((rx_activiated != RT_TRUE && eir != 0));
-}
-
-/* RT-Thread Device Interface */
-
-/* initialize the interface */
-rt_err_t enc28j60_init(rt_device_t dev)
-{
-	CSPASSIVE;
-
-	// perform system reset
-	spi_write_op(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
-	delay_ms(50);
-	NextPacketPtr = RXSTART_INIT;
-
-    // Rx start
-	spi_write(ERXSTL, RXSTART_INIT&0xFF);
-	spi_write(ERXSTH, RXSTART_INIT>>8);
-	// set receive pointer address
-	spi_write(ERXRDPTL, RXSTOP_INIT&0xFF);
-	spi_write(ERXRDPTH, RXSTOP_INIT>>8);
-	// RX end
-	spi_write(ERXNDL, RXSTOP_INIT&0xFF);
-	spi_write(ERXNDH, RXSTOP_INIT>>8);
-
-	// TX start
-	spi_write(ETXSTL, TXSTART_INIT&0xFF);
-	spi_write(ETXSTH, TXSTART_INIT>>8);
-	// set transmission pointer address
-	spi_write(EWRPTL, TXSTART_INIT&0xFF);
-	spi_write(EWRPTH, TXSTART_INIT>>8);
-	// TX end
-	spi_write(ETXNDL, TXSTOP_INIT&0xFF);
-	spi_write(ETXNDH, TXSTOP_INIT>>8);
-
-	// do bank 1 stuff, packet filter:
-    // For broadcast packets we allow only ARP packtets
-    // All other packets should be unicast only for our mac (MAADR)
-    //
-    // The pattern to match on is therefore
-    // Type     ETH.DST
-    // ARP      BROADCAST
-    // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
-    // in binary these poitions are:11 0000 0011 1111
-    // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
-	spi_write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_BCEN);
-
-	// do bank 2 stuff
-	// enable MAC receive
-	spi_write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
-	// enable automatic padding to 60bytes and CRC operations
-	// spi_write_op(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
-	spi_write_op(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
-	// bring MAC out of reset
-
-	// set inter-frame gap (back-to-back)
-	// spi_write(MABBIPG, 0x12);
-	spi_write(MABBIPG, 0x15);
-
-	spi_write(MACON4, MACON4_DEFER);
-	spi_write(MACLCON2, 63);
-
-	// set inter-frame gap (non-back-to-back)
-	spi_write(MAIPGL, 0x12);
-	spi_write(MAIPGH, 0x0C);
-
-	// Set the maximum packet size which the controller will accept
-	// Do not send packets longer than MAX_FRAMELEN:
-	spi_write(MAMXFLL, MAX_FRAMELEN&0xFF);
-	spi_write(MAMXFLH, MAX_FRAMELEN>>8);
-
-    // do bank 3 stuff
-    // write MAC address
-    // NOTE: MAC address in ENC28J60 is byte-backward
-    spi_write(MAADR0, enc28j60_dev->dev_addr[5]);
-    spi_write(MAADR1, enc28j60_dev->dev_addr[4]);
-    spi_write(MAADR2, enc28j60_dev->dev_addr[3]);
-    spi_write(MAADR3, enc28j60_dev->dev_addr[2]);
-    spi_write(MAADR4, enc28j60_dev->dev_addr[1]);
-    spi_write(MAADR5, enc28j60_dev->dev_addr[0]);
-
-	/* output off */
-	spi_write(ECOCON, 0x00);
-
-	// enc28j60_phy_write(PHCON1, 0x00);
-	enc28j60_phy_write(PHCON1, PHCON1_PDPXMD); // full duplex
-    // no loopback of transmitted frames
-	enc28j60_phy_write(PHCON2, PHCON2_HDLDIS);
-
-	enc28j60_set_bank(ECON2);
-	spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC);
-
-	// switch to bank 0
-	enc28j60_set_bank(ECON1);
-	// enable interrutps
-	spi_write_op(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE|EIR_TXIF);
-	// enable packet reception
-	spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
-
-	/* clock out */
-	// enc28j60_clkout(2);
-
-	enc28j60_phy_write(PHLCON, 0xD76);	//0x476
-	delay_ms(20);
-
-    rt_kprintf("enc28j60 init ok!\n");
-
-    return RT_EOK;
-}
-
-/* control the interface */
-rt_err_t enc28j60_control(rt_device_t dev, rt_uint8_t cmd, void *args)
-{
-	switch(cmd)
-	{
-	case NIOCTL_GADDR:
-		/* get mac address */
-		if(args) rt_memcpy(args, enc28j60_dev_entry.dev_addr, 6);
-		else return -RT_ERROR;
-		break;
-
-	default :
-		break;
-	}
-
-	return RT_EOK;
-}
-
-/* Open the ethernet interface */
-rt_err_t enc28j60_open(rt_device_t dev, rt_uint16_t oflag)
-{
-	return RT_EOK;
-}
-
-/* Close the interface */
-rt_err_t enc28j60_close(rt_device_t dev)
-{
-	return RT_EOK;
-}
-
-/* Read */
-rt_size_t enc28j60_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
-	rt_set_errno(-RT_ENOSYS);
-	return 0;
-}
-
-/* Write */
-rt_size_t enc28j60_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
-	rt_set_errno(-RT_ENOSYS);
-	return 0;
-}
-
-/* ethernet device interface */
-/*
- * Transmit packet.
- */
-rt_err_t enc28j60_tx( rt_device_t dev, struct pbuf* p)
-{
-	struct pbuf* q;
-	rt_uint32_t len;
-	rt_uint8_t* ptr;
-
-	// rt_kprintf("tx pbuf: 0x%08x\n", p);
-
-	/* lock tx operation */
-	rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
-
-	// Set the write pointer to start of transmit buffer area
-	spi_write(EWRPTL, TXSTART_INIT&0xFF);
-	spi_write(EWRPTH, TXSTART_INIT>>8);
-	// Set the TXND pointer to correspond to the packet size given
-	spi_write(ETXNDL, (TXSTART_INIT+ p->tot_len + 1)&0xFF);
-	spi_write(ETXNDH, (TXSTART_INIT+ p->tot_len + 1)>>8);
-
-	// write per-packet control byte (0x00 means use macon3 settings)
-	spi_write_op(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
-
-	for (q = p; q != NULL; q = q->next)
-	{
-        CSACTIVE;
-
-		SPI_I2S_SendData(SPI2, ENC28J60_WRITE_BUF_MEM);
-		while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-
-		len = q->len;
-		ptr = q->payload;
-        while(len)
-        {
-			SPI_I2S_SendData(SPI2,*ptr) ;
-			while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);;
-				ptr++;
-
-			len--;
-        }
-
-        CSPASSIVE;
-	}
-
-	// send the contents of the transmit buffer onto the network
-	spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
-	// Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
-	if( (spi_read(EIR) & EIR_TXERIF) )
-	{
-		spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
-	}
-
-	// rt_kprintf("tx ok\n");
-
-    return RT_EOK;
-}
-
-struct pbuf *enc28j60_rx(rt_device_t dev)
-{
-	struct pbuf* p;
-	rt_uint32_t len;
-	rt_uint16_t rxstat;
-	rt_uint32_t pk_counter;
-
-    p = RT_NULL;
-
-    pk_counter = spi_read(EPKTCNT);
-    if (pk_counter)
-    {
-        // Set the read pointer to the start of the received packet
-        spi_write(ERDPTL, (NextPacketPtr));
-        spi_write(ERDPTH, (NextPacketPtr)>>8);
-
-        // read the next packet pointer
-        NextPacketPtr  = spi_read_op(ENC28J60_READ_BUF_MEM, 0);
-        NextPacketPtr |= spi_read_op(ENC28J60_READ_BUF_MEM, 0)<<8;
-
-        // read the packet length (see datasheet page 43)
-        len  = spi_read_op(ENC28J60_READ_BUF_MEM, 0);	    //0x54
-        len |= spi_read_op(ENC28J60_READ_BUF_MEM, 0) <<8;	//5554
-
-        len-=4; //remove the CRC count
-
-        // read the receive status (see datasheet page 43)
-        rxstat  = spi_read_op(ENC28J60_READ_BUF_MEM, 0);
-        rxstat |= ((rt_uint16_t)spi_read_op(ENC28J60_READ_BUF_MEM, 0))<<8;
-
-        // check CRC and symbol errors (see datasheet page 44, table 7-3):
-        // The ERXFCON.CRCEN is set by default. Normally we should not
-        // need to check this.
-        if ((rxstat & 0x80)==0)
-        {
-            // invalid
-            len=0;
-        }
-        else
-        {
-            /* allocation pbuf */
-            p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
-            if (p != RT_NULL)
-            {
-                rt_uint8_t* data;
-                struct pbuf* q;
-
-                for (q = p; q != RT_NULL; q= q->next)
-                {
-                    data = q->payload;
-                    len = q->len;
-
-                    CSACTIVE;
-
-                    SPI_I2S_SendData(SPI2,ENC28J60_READ_BUF_MEM);
-                    while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-
-                    SPI_I2S_ReceiveData(SPI2);
-
-                    while(len)
-                    {
-                        len--;
-                        SPI_I2S_SendData(SPI2,0x00)	;
-                        while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY)==SET);
-
-                        *data= SPI_I2S_ReceiveData(SPI2);
-                        data++;
-                    }
-
-                    CSPASSIVE;
-                }
-            }
-        }
-
-        // Move the RX read pointer to the start of the next received packet
-        // This frees the memory we just read out
-        spi_write(ERXRDPTL, (NextPacketPtr));
-        spi_write(ERXRDPTH, (NextPacketPtr)>>8);
-
-        // decrement the packet counter indicate we are done with this packet
-        spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
-    }
-	else
-	{
-		rt_uint32_t level;
-		/* lock enc28j60 */
-		level = rt_hw_interrupt_disable();
-		
-		// switch to bank 0
-		enc28j60_set_bank(EIE);
-		// enable interrutps
-		spi_write_op(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE);
-		// switch to bank 0
-		enc28j60_set_bank(ECON1);
-		// enable packet reception
-		spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
-		
-		/* enable interrupt */
-		rt_hw_interrupt_enable(level);
-	}
-
-    return p;
-}
-
-static void RCC_Configuration(void)
-{
-    /* enable spi2 clock */
-    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
-
-    /* enable gpiob port clock */
-    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
-}
-
-static void NVIC_Configuration(void)
-{
-    NVIC_InitTypeDef NVIC_InitStructure;
-
-    /* Configure one bit for preemption priority */
-    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
-
-    /* Enable the EXTI0 Interrupt */
-    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
-    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
-    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
-    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
-    NVIC_Init(&NVIC_InitStructure);
-}
-
-static void GPIO_Configuration()
-{
-	GPIO_InitTypeDef GPIO_InitStructure;
-    EXTI_InitTypeDef EXTI_InitStructure;
-
-	/* configure PB0 as external interrupt */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
-    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
-	GPIO_Init(GPIOB, &GPIO_InitStructure);
-
-    /* Configure SPI2 pins:  SCK, MISO and MOSI ----------------------------*/
-    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
-    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
-    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
-    GPIO_Init(GPIOB, &GPIO_InitStructure);
-
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-	GPIO_Init(GPIOB, &GPIO_InitStructure);
-
-    /* Connect ENC28J60 EXTI Line to GPIOB Pin 0 */
-    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
-
-    /* Configure ENC28J60 EXTI Line to generate an interrupt on falling edge */
-    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
-    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
-    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
-    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
-    EXTI_Init(&EXTI_InitStructure);
-
-	/* Clear the Key Button EXTI line pending bit */
-	EXTI_ClearITPendingBit(EXTI_Line0);
-}
-
-static void SetupSPI (void)
-{
-    SPI_InitTypeDef SPI_InitStructure;
-    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
-    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
-    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
-    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
-    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
-    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
-    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
-    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
-    SPI_InitStructure.SPI_CRCPolynomial = 7;
-    SPI_Init(SPI2, &SPI_InitStructure);
-    SPI_Cmd(SPI2, ENABLE);
-}
-
-static rt_timer_t enc28j60_timer;
-void rt_hw_enc28j60_timeout(void* parameter)
-{
-	// switch to bank 0
-	enc28j60_set_bank(EIE);
-	// enable interrutps
-	spi_write_op(ENC28J60_BIT_FIELD_SET, EIE, EIE_PKTIE);
-	// switch to bank 0
-	enc28j60_set_bank(ECON1);
-	// enable packet reception
-	spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
-
-	enc28j60_isr();
-}
-
-int rt_hw_enc28j60_init()
-{
-	rt_err_t result;
-
-	/* configuration PB5 as INT */
-	RCC_Configuration();
-	NVIC_Configuration();
-	GPIO_Configuration();
-	SetupSPI();
-
-	/* init rt-thread device interface */
-	enc28j60_dev_entry.parent.parent.init		= enc28j60_init;
-	enc28j60_dev_entry.parent.parent.open		= enc28j60_open;
-	enc28j60_dev_entry.parent.parent.close		= enc28j60_close;
-	enc28j60_dev_entry.parent.parent.read		= enc28j60_read;
-	enc28j60_dev_entry.parent.parent.write		= enc28j60_write;
-	enc28j60_dev_entry.parent.parent.control	= enc28j60_control;
-	enc28j60_dev_entry.parent.eth_rx			= enc28j60_rx;
-	enc28j60_dev_entry.parent.eth_tx			= enc28j60_tx;
-
-	/* Update MAC address */
-	enc28j60_dev_entry.dev_addr[0] = 0x1e;
-	enc28j60_dev_entry.dev_addr[1] = 0x30;
-	enc28j60_dev_entry.dev_addr[2] = 0x6c;
-	enc28j60_dev_entry.dev_addr[3] = 0xa2;
-	enc28j60_dev_entry.dev_addr[4] = 0x45;
-	enc28j60_dev_entry.dev_addr[5] = 0x5e;
-
-	rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
-
-	result = eth_device_init(&(enc28j60_dev->parent), "E0");
-
-	/* workaround for enc28j60 interrupt */
-	enc28j60_timer = rt_timer_create("etimer", 
-		rt_hw_enc28j60_timeout, RT_NULL, 
-		50, RT_TIMER_FLAG_PERIODIC);
-	if (enc28j60_timer != RT_NULL)
-		rt_timer_start(enc28j60_timer);
-
-	return RT_EOK;
-}

+ 0 - 256
bsp/stm32_radio/enc28j60.h

@@ -1,256 +0,0 @@
-#ifndef __ENC28J60_H__
-#define __ENC28J60_H__
-
-#include <rtthread.h>
-
-// ENC28J60 Control Registers
-// Control register definitions are a combination of address,
-// bank number, and Ethernet/MAC/PHY indicator bits.
-// - Register address        (bits 0-4)
-// - Bank number        (bits 5-6)
-// - MAC/PHY indicator        (bit 7)
-#define ADDR_MASK        0x1F
-#define BANK_MASK        0x60
-#define SPRD_MASK        0x80
-// All-bank registers
-#define EIE              0x1B
-#define EIR              0x1C
-#define ESTAT            0x1D
-#define ECON2            0x1E
-#define ECON1            0x1F
-// Bank 0 registers
-#define ERDPTL           (0x00|0x00)
-#define ERDPTH           (0x01|0x00)
-#define EWRPTL           (0x02|0x00)
-#define EWRPTH           (0x03|0x00)
-#define ETXSTL           (0x04|0x00)
-#define ETXSTH           (0x05|0x00)
-#define ETXNDL           (0x06|0x00)
-#define ETXNDH           (0x07|0x00)
-#define ERXSTL           (0x08|0x00)
-#define ERXSTH           (0x09|0x00)
-#define ERXNDL           (0x0A|0x00)
-#define ERXNDH           (0x0B|0x00)
-#define ERXRDPTL         (0x0C|0x00)
-#define ERXRDPTH         (0x0D|0x00)
-#define ERXWRPTL         (0x0E|0x00)
-#define ERXWRPTH         (0x0F|0x00)
-#define EDMASTL          (0x10|0x00)
-#define EDMASTH          (0x11|0x00)
-#define EDMANDL          (0x12|0x00)
-#define EDMANDH          (0x13|0x00)
-#define EDMADSTL         (0x14|0x00)
-#define EDMADSTH         (0x15|0x00)
-#define EDMACSL          (0x16|0x00)
-#define EDMACSH          (0x17|0x00)
-// Bank 1 registers
-#define EHT0             (0x00|0x20)
-#define EHT1             (0x01|0x20)
-#define EHT2             (0x02|0x20)
-#define EHT3             (0x03|0x20)
-#define EHT4             (0x04|0x20)
-#define EHT5             (0x05|0x20)
-#define EHT6             (0x06|0x20)
-#define EHT7             (0x07|0x20)
-#define EPMM0            (0x08|0x20)
-#define EPMM1            (0x09|0x20)
-#define EPMM2            (0x0A|0x20)
-#define EPMM3            (0x0B|0x20)
-#define EPMM4            (0x0C|0x20)
-#define EPMM5            (0x0D|0x20)
-#define EPMM6            (0x0E|0x20)
-#define EPMM7            (0x0F|0x20)
-#define EPMCSL           (0x10|0x20)
-#define EPMCSH           (0x11|0x20)
-#define EPMOL            (0x14|0x20)
-#define EPMOH            (0x15|0x20)
-#define EWOLIE           (0x16|0x20)
-#define EWOLIR           (0x17|0x20)
-#define ERXFCON          (0x18|0x20)
-#define EPKTCNT          (0x19|0x20)
-// Bank 2 registers
-#define MACON1           (0x00|0x40|0x80)
-#define MACON2           (0x01|0x40|0x80)
-#define MACON3           (0x02|0x40|0x80)
-#define MACON4           (0x03|0x40|0x80)
-#define MABBIPG          (0x04|0x40|0x80)
-#define MAIPGL           (0x06|0x40|0x80)
-#define MAIPGH           (0x07|0x40|0x80)
-#define MACLCON1         (0x08|0x40|0x80)
-#define MACLCON2         (0x09|0x40|0x80)
-#define MAMXFLL          (0x0A|0x40|0x80)
-#define MAMXFLH          (0x0B|0x40|0x80)
-#define MAPHSUP          (0x0D|0x40|0x80)
-#define MICON            (0x11|0x40|0x80)
-#define MICMD            (0x12|0x40|0x80)
-#define MIREGADR         (0x14|0x40|0x80)
-#define MIWRL            (0x16|0x40|0x80)
-#define MIWRH            (0x17|0x40|0x80)
-#define MIRDL            (0x18|0x40|0x80)
-#define MIRDH            (0x19|0x40|0x80)
-// Bank 3 registers
-#define MAADR1           (0x00|0x60|0x80)
-#define MAADR0           (0x01|0x60|0x80)
-#define MAADR3           (0x02|0x60|0x80)
-#define MAADR2           (0x03|0x60|0x80)
-#define MAADR5           (0x04|0x60|0x80)
-#define MAADR4           (0x05|0x60|0x80)
-#define EBSTSD           (0x06|0x60)
-#define EBSTCON          (0x07|0x60)
-#define EBSTCSL          (0x08|0x60)
-#define EBSTCSH          (0x09|0x60)
-#define MISTAT           (0x0A|0x60|0x80)
-#define EREVID           (0x12|0x60)
-#define ECOCON           (0x15|0x60)
-#define EFLOCON          (0x17|0x60)
-#define EPAUSL           (0x18|0x60)
-#define EPAUSH           (0x19|0x60)
-// PHY registers
-#define PHCON1           0x00
-#define PHSTAT1          0x01
-#define PHHID1           0x02
-#define PHHID2           0x03
-#define PHCON2           0x10
-#define PHSTAT2          0x11
-#define PHIE             0x12
-#define PHIR             0x13
-#define PHLCON           0x14
-
-// ENC28J60 ERXFCON Register Bit Definitions
-#define ERXFCON_UCEN     0x80
-#define ERXFCON_ANDOR    0x40
-#define ERXFCON_CRCEN    0x20
-#define ERXFCON_PMEN     0x10
-#define ERXFCON_MPEN     0x08
-#define ERXFCON_HTEN     0x04
-#define ERXFCON_MCEN     0x02
-#define ERXFCON_BCEN     0x01
-// ENC28J60 EIE Register Bit Definitions
-#define EIE_INTIE        0x80
-#define EIE_PKTIE        0x40
-#define EIE_DMAIE        0x20
-#define EIE_LINKIE       0x10
-#define EIE_TXIE         0x08
-#define EIE_WOLIE        0x04
-#define EIE_TXERIE       0x02
-#define EIE_RXERIE       0x01
-// ENC28J60 EIR Register Bit Definitions
-#define EIR_PKTIF        0x40
-#define EIR_DMAIF        0x20
-#define EIR_LINKIF       0x10
-#define EIR_TXIF         0x08
-#define EIR_WOLIF        0x04
-#define EIR_TXERIF       0x02
-#define EIR_RXERIF       0x01
-// ENC28J60 ESTAT Register Bit Definitions
-#define ESTAT_INT        0x80
-#define ESTAT_LATECOL    0x10
-#define ESTAT_RXBUSY     0x04
-#define ESTAT_TXABRT     0x02
-#define ESTAT_CLKRDY     0x01
-// ENC28J60 ECON2 Register Bit Definitions
-#define ECON2_AUTOINC    0x80
-#define ECON2_PKTDEC     0x40
-#define ECON2_PWRSV      0x20
-#define ECON2_VRPS       0x08
-// ENC28J60 ECON1 Register Bit Definitions
-#define ECON1_TXRST      0x80
-#define ECON1_RXRST      0x40
-#define ECON1_DMAST      0x20
-#define ECON1_CSUMEN     0x10
-#define ECON1_TXRTS      0x08
-#define ECON1_RXEN       0x04
-#define ECON1_BSEL1      0x02
-#define ECON1_BSEL0      0x01
-// ENC28J60 MACON1 Register Bit Definitions
-#define MACON1_LOOPBK    0x10
-#define MACON1_TXPAUS    0x08
-#define MACON1_RXPAUS    0x04
-#define MACON1_PASSALL   0x02
-#define MACON1_MARXEN    0x01
-// ENC28J60 MACON2 Register Bit Definitions
-#define MACON2_MARST     0x80
-#define MACON2_RNDRST    0x40
-#define MACON2_MARXRST   0x08
-#define MACON2_RFUNRST   0x04
-#define MACON2_MATXRST   0x02
-#define MACON2_TFUNRST   0x01
-// ENC28J60 MACON3 Register Bit Definitions
-#define MACON3_PADCFG2   0x80
-#define MACON3_PADCFG1   0x40
-#define MACON3_PADCFG0   0x20
-#define MACON3_TXCRCEN   0x10
-#define MACON3_PHDRLEN   0x08
-#define MACON3_HFRMLEN   0x04
-#define MACON3_FRMLNEN   0x02
-#define MACON3_FULDPX    0x01
-// ENC28J60 MACON4 Register Bit Definitions
-#define	MACON4_DEFER	(1<<6)
-#define	MACON4_BPEN		(1<<5)
-#define	MACON4_NOBKOFF	(1<<4)
-// ENC28J60 MICMD Register Bit Definitions
-#define MICMD_MIISCAN    0x02
-#define MICMD_MIIRD      0x01
-// ENC28J60 MISTAT Register Bit Definitions
-#define MISTAT_NVALID    0x04
-#define MISTAT_SCAN      0x02
-#define MISTAT_BUSY      0x01
-// ENC28J60 PHY PHCON1 Register Bit Definitions
-#define PHCON1_PRST      0x8000
-#define PHCON1_PLOOPBK   0x4000
-#define PHCON1_PPWRSV    0x0800
-#define PHCON1_PDPXMD    0x0100
-// ENC28J60 PHY PHSTAT1 Register Bit Definitions
-#define PHSTAT1_PFDPX    0x1000
-#define PHSTAT1_PHDPX    0x0800
-#define PHSTAT1_LLSTAT   0x0004
-#define PHSTAT1_JBSTAT   0x0002
-/* ENC28J60 PHY PHSTAT2 Register Bit Definitions */
-#define PHSTAT2_TXSTAT	(1 << 13)
-#define PHSTAT2_RXSTAT	(1 << 12)
-#define PHSTAT2_COLSTAT	(1 << 11)
-#define PHSTAT2_LSTAT	(1 << 10)
-#define PHSTAT2_DPXSTAT	(1 << 9)
-#define PHSTAT2_PLRITY	(1 << 5)
-// ENC28J60 PHY PHCON2 Register Bit Definitions
-#define PHCON2_FRCLINK   0x4000
-#define PHCON2_TXDIS     0x2000
-#define PHCON2_JABBER    0x0400
-#define PHCON2_HDLDIS    0x0100
-
-// ENC28J60 Packet Control Byte Bit Definitions
-#define PKTCTRL_PHUGEEN  0x08
-#define PKTCTRL_PPADEN   0x04
-#define PKTCTRL_PCRCEN   0x02
-#define PKTCTRL_POVERRIDE 0x01
-
-// SPI operation codes
-#define ENC28J60_READ_CTRL_REG       0x00
-#define ENC28J60_READ_BUF_MEM        0x3A
-#define ENC28J60_WRITE_CTRL_REG      0x40
-#define ENC28J60_WRITE_BUF_MEM       0x7A
-#define ENC28J60_BIT_FIELD_SET       0x80
-#define ENC28J60_BIT_FIELD_CLR       0xA0
-#define ENC28J60_SOFT_RESET          0xFF
-
-// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
-// buffer boundaries applied to internal 8K ram
-// the entire available packet buffer space is allocated
-//
-
-// start with recbuf at 0/
-#define RXSTART_INIT	0x0
-// receive buffer end
-#define RXSTOP_INIT		(0x1FFF-0x0600) - 1
-// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes)
-
-#define TXSTART_INIT	(0x1FFF-0x0600)
-// stp TX buffer at end of mem
-#define TXSTOP_INIT		0x1FFF
-
-// max frame length which the conroller will accept:
-#define MAX_FRAMELEN	1518
-
-int rt_hw_enc28j60_init(void);
-
-#endif

+ 209 - 0
bsp/stm32_radio/fmt0371/fmt0371.c

@@ -0,0 +1,209 @@
+#include "FMT0371.h"
+#include "stm32f10x_lib.h"
+
+#define FSMC_GPIO_CONFIG
+
+static void delay_ms(unsigned int dt)
+{
+    volatile unsigned int u;
+    for (u=0;u<dt*30;u++);
+}
+
+static void FSMC_Init(void)
+{
+    FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
+    FSMC_NORSRAMTimingInitTypeDef  p;
+
+#ifdef FSMC_GPIO_CONFIG
+    GPIO_InitTypeDef GPIO_InitStructure;
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE |
+                           RCC_APB2Periph_GPIOF, ENABLE);
+
+    /*-- GPIO Configuration ------------------------------------------------------*/
+    /* SRAM Data lines configuration */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
+                                  GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+    GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
+                                  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
+                                  GPIO_Pin_15;
+    GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+    /* SRAM Address lines configuration */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
+                                  GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
+                                  GPIO_Pin_14 | GPIO_Pin_15;
+    GPIO_Init(GPIOF, &GPIO_InitStructure);
+
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
+                                  GPIO_Pin_4 | GPIO_Pin_5;
+    GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
+    GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+    /* NOE and NWE configuration */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
+    GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+    /* NE2 configuration */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
+    GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+    /* NBL0, NBL1 configuration */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
+    GPIO_Init(GPIOE, &GPIO_InitStructure);
+#endif
+
+    /*-- FSMC Configuration ------------------------------------------------------*/
+    p.FSMC_AddressSetupTime = 2; // safe value 2
+    p.FSMC_AddressHoldTime = 1;  // safe value 2
+    p.FSMC_DataSetupTime = 3;    // safe value 5
+    p.FSMC_BusTurnAroundDuration = 0;
+    p.FSMC_CLKDivision = 0;
+    p.FSMC_DataLatency = 0;
+    p.FSMC_AccessMode = FSMC_AccessMode_A;
+
+    FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
+    FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+    FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
+    FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
+    FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+    FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+    FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+    FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+    FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+    FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+    FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+    FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+    FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+    FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+
+    FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
+
+    /* Enable FSMC Bank1_SRAM Bank */
+    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
+}
+
+void ftm0371_port_init(void)
+{
+    GPIO_InitTypeDef GPIO_InitStructure;
+
+    RCC_APB2PeriphClockCmd(LCD_RST_RCC, ENABLE);
+    GPIO_InitStructure.GPIO_Pin   = LCD_RST_PIN;
+    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
+    GPIO_Init(LCD_RST_PORT, &GPIO_InitStructure);
+    LCD_RST_0; // reset the lcd
+
+    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
+    FSMC_Init();
+}
+
+//初始化函数
+void ftm0371_init(void)
+{
+    LCD_RST_1;
+	delay_ms(1000);
+
+    //initializing funciton 1
+    LCD_WR_REG(0xA1);
+    LCD_WR_DATA8(0x00);
+    LCD_WR_REG(0xA0);
+    LCD_WR_DATA8(0x00);
+    LCD_WR_CMD(0,0x70,0xC8);
+
+    LCD_WR_CMD(0,0x72,0xA3);
+    LCD_WR_CMD(0,0x73,0x04);
+    LCD_WR_CMD(0,0x75,0x45);
+    LCD_WR_CMD(0,0x76,0x23);
+    LCD_WR_CMD(0,0x77,0x08);
+    LCD_WR_CMD(0,0x78,0x08);
+    LCD_WR_CMD(0,0x79,0x00);
+    LCD_WR_CMD(0,0x7F,0xF0);
+    LCD_WR_CMD(0,0x71,0x81);	//
+
+    LCD_WR_CMD(0,0x0D,0x23);
+    LCD_WR_CMD(0,0x11,0x00);
+    LCD_WR_CMD(0,0x12,0x00);
+    LCD_WR_CMD(0,0x21,0x37);
+    LCD_WR_CMD(0,0x22,0x02);
+    LCD_WR_CMD(0,0x23,0x24);
+    LCD_WR_CMD(0,0x24,0x13);
+    LCD_WR_CMD(0,0x25,0x0A);
+    LCD_WR_CMD(0,0x26,0x82);
+    LCD_WR_CMD(0,0x27,0x01);
+    LCD_WR_CMD(0,0x1E,0x25);
+    LCD_WR_CMD(0,0x1F,0x59);
+
+    //GAMMA设置
+    LCD_WR_CMD(1,0x30,0x0777);
+    LCD_WR_CMD(1,0x31,0x0444);
+    LCD_WR_CMD(1,0x32,0x0555);
+    LCD_WR_CMD(1,0x33,0x0444);
+    LCD_WR_CMD(1,0x34,0x0333);
+    LCD_WR_CMD(1,0x35,0x0333);
+    LCD_WR_CMD(1,0x36,0x0333);
+    LCD_WR_CMD(1,0x37,0x0333);
+    LCD_WR_CMD(1,0x38,0x0444);
+    LCD_WR_CMD(1,0x39,0x0555);
+    LCD_WR_CMD(1,0x3A,0x0666);
+    LCD_WR_CMD(1,0x3B,0x0666);
+    LCD_WR_CMD(1,0x3C,0x0777);
+    LCD_WR_CMD(1,0x3D,0x0777);
+    LCD_WR_CMD(1,0x3E,0x0777);
+    LCD_WR_CMD(1,0x3F,0x0777);
+    LCD_WR_CMD(1,0x40,0x0777);
+    LCD_WR_CMD(1,0x41,0x0777);
+    LCD_WR_CMD(1,0x42,0x0777);
+    LCD_WR_CMD(1,0x43,0x0777);
+    LCD_WR_CMD(1,0x44,0x0777);
+    LCD_WR_CMD(1,0x45,0x0777);
+    LCD_WR_CMD(1,0x46,0x0777);
+    LCD_WR_CMD(1,0x47,0x0777);
+    LCD_WR_CMD(1,0x48,0x0777);
+    LCD_WR_CMD(1,0x49,0x0777);
+    LCD_WR_CMD(1,0x4A,0x0777);
+    LCD_WR_CMD(1,0x4B,0x0777);
+    LCD_WR_CMD(1,0x4C,0x0777);
+    LCD_WR_CMD(1,0x4D,0x0666);
+    LCD_WR_CMD(1,0x4E,0x0666);
+    LCD_WR_CMD(1,0x4F,0x0666);
+
+    LCD_WR_CMD(0,0x00,0x04);	//扫描方向控制
+    LCD_WR_CMD(0,0x01,0x07);	//扫描方向控制
+
+    LCD_WR_CMD(0,0x02,0x00);	//X
+    LCD_WR_CMD(1,0x03,0x0000);	//Y
+
+    //面板大小设置
+    LCD_WR_CMD(0,0x04,0xEF);	//结束列数(0~239)
+    LCD_WR_CMD(1,0x05,0x013F);	//结束行数(0~319)
+
+    //窗口设置
+    LCD_WR_CMD(0,0x06,0x00);	//水平起始位置
+    LCD_WR_CMD(1,0x07,0x0000);	//垂直起始位置
+    LCD_WR_CMD(0,0x08,0xEF);	//水平结束位置
+    LCD_WR_CMD(1,0x09,0x013F);	//垂直结束位置
+
+    LCD_WR_CMD(0,0x0A,0x00);
+    LCD_WR_CMD(0,0x0B,0x00);
+    LCD_WR_CMD(0,0x0C,0x00);
+    LCD_WR_CMD(0,0x14,0x00);
+    LCD_WR_CMD(0,0x15,0x00);
+    LCD_WR_CMD(0,0x16,0x00);
+    LCD_WR_CMD(1,0x17,0x01FF);
+    LCD_WR_CMD(1,0x18,0x01FF);
+    LCD_WR_CMD(0,0x13,0x00);
+    LCD_WR_CMD(1,0x19,0x01FF);
+    LCD_WR_CMD(1,0x1B,0x01FF);
+    LCD_WR_CMD(1,0x1C,0x01FF);
+    LCD_WR_CMD(1,0x1A,0x01FF);
+    LCD_WR_CMD(0,0x1D,0x0E);
+    LCD_WR_CMD(0,0x10,0x06);		//开显示
+    LCD_WR_REG(0x0E);
+}

+ 34 - 0
bsp/stm32_radio/fmt0371/fmt0371.h

@@ -0,0 +1,34 @@
+#ifndef FMT0371_H_INCLUDED
+#define FMT0371_H_INCLUDED
+
+//----------  LCD_RESET -------------
+#define LCD_RST_PORT          GPIOF
+#define LCD_RST_PIN           GPIO_Pin_10
+#define LCD_RST_RCC           RCC_APB2Periph_GPIOF
+/**************************************/
+#define LCD_RST_0             GPIO_ResetBits(LCD_RST_PORT,LCD_RST_PIN)
+#define LCD_RST_1             GPIO_SetBits(LCD_RST_PORT,LCD_RST_PIN)
+//----------  LCD_RESET -------------
+
+#define LCD_ADDR              (*((volatile unsigned char *) 0x64000000)) // RS = 0
+#define LCD_DATA              (*((volatile unsigned char *) 0x64000004)) // RS = 1
+
+
+#define LCD_DATA16(a)         LCD_DATA = (unsigned char)(a>>8);LCD_DATA = (unsigned char)a // RS = 1 & WIDHT = 16
+#define LCD_WR_CMD(a,b,c)     LCD_ADDR = b;LCD_DATA16(c)
+#define LCD_WR_REG(a)         LCD_ADDR = a
+#define LCD_WR_DATA8(a)       LCD_DATA = a
+
+extern void ftm0371_port_init(void);
+extern void ftm0371_init(void);
+
+/*
+16弇(R5G6B5)
+囀湔毓峓
+0x02   D7:D0  Xお宎華硊
+0x03   D8:D0  Yお宎華硊
+0x04   D7:D0  X賦旰華硊
+0x05   D8:D0  Y賦旰華硊
+*/
+
+#endif // FMT0371_H_INCLUDED

+ 498 - 0
bsp/stm32_radio/fsmc_nand.c

@@ -0,0 +1,498 @@
+/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
+* File Name          : fsmc_nand.c
+* Author             : MCD Application Team
+* Version            : V2.0.3
+* Date               : 09/22/2008
+* Description        : This file provides a set of functions needed to drive the
+*                      NAND512W3A2 memory mounted on STM3210E-EVAL board.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/* Includes ------------------------------------------------------------------*/
+#include "fsmc_nand.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define FSMC_Bank_NAND     FSMC_Bank2_NAND
+#define Bank_NAND_ADDR     Bank2_NAND_ADDR 
+#define Bank2_NAND_ADDR    ((u32)0x70000000)
+
+/* Private macro -------------------------------------------------------------*/
+#define ROW_ADDRESS (Address.Page + (Address.Block + (Address.Zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE)
+
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/*******************************************************************************
+* Function Name  : FSMC_NAND_Init
+* Description    : Configures the FSMC and GPIOs to interface with the NAND memory.
+*                  This function must be called before any write/read operation
+*                  on the NAND.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void FSMC_NAND_Init(void)
+{
+  GPIO_InitTypeDef GPIO_InitStructure; 
+  FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
+  FSMC_NAND_PCCARDTimingInitTypeDef  p;
+  
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | 
+                         RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
+  
+/*-- GPIO Configuration ------------------------------------------------------*/
+/* CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */
+  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |  
+                                 GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | 
+                                 GPIO_Pin_7;                                  
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+
+  GPIO_Init(GPIOD, &GPIO_InitStructure); 
+
+/* D4->D7 NAND pin configuration  */  
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
+
+  GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+
+/* NWAIT NAND pin configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;   							 
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
+
+  GPIO_Init(GPIOD, &GPIO_InitStructure); 
+
+/* INT2 NAND pin configuration */  
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;   							 
+  GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+  /*-- FSMC Configuration ------------------------------------------------------*/
+  p.FSMC_SetupTime = 0x1;
+  p.FSMC_WaitSetupTime = 0x3;
+  p.FSMC_HoldSetupTime = 0x2;
+  p.FSMC_HiZSetupTime = 0x1;
+
+  FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
+  FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
+  FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
+  FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
+  FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
+//  FSMC_NANDInitStructure.FSMC_AddressLowMapping = FSMC_AddressLowMapping_Direct;
+  FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
+  FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
+  FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
+  FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
+
+  FSMC_NANDInit(&FSMC_NANDInitStructure);
+
+  /* FSMC NAND Bank Cmd Test */
+  FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadID
+* Description    : Reads NAND memory's ID.
+* Input          : - NAND_ID: pointer to a NAND_IDTypeDef structure which will hold
+*                    the Manufacturer and Device ID.
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)
+{
+  u32 data = 0;
+
+  /* Send Command to the command area */ 	
+  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = 0x90;
+  *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
+
+   /* Sequence to read ID from NAND flash */	
+   data = *(vu32 *)(Bank_NAND_ADDR | DATA_AREA);
+
+   NAND_ID->Maker_ID   = ADDR_1st_CYCLE (data);
+   NAND_ID->Device_ID  = ADDR_2nd_CYCLE (data);
+   NAND_ID->Third_ID   = ADDR_3rd_CYCLE (data);
+   NAND_ID->Fourth_ID  = ADDR_4th_CYCLE (data);  
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_WriteSmallPage
+* Description    : This routine is for writing one or several 512 Bytes Page size.
+* Input          : - pBuffer: pointer on the Buffer containing data to be written   
+*                  - Address: First page address
+*                  - NumPageToWrite: Number of page to write  
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+u32 FSMC_NAND_WriteSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToWrite)
+{
+  u32 index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  u32 status = NAND_READY, size = 2048;
+
+  while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
+  {
+    /* Page write command and address */
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
+
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS); 
+
+    /* Calculate the size */
+    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
+
+
+    /* Write data */
+    for(; index < size; index++)
+    {
+      *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
+    }
+    
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
+
+    /* Check status for successful operation */
+    status = FSMC_NAND_GetStatus();
+    
+    if(status == NAND_READY)
+    {
+      numpagewritten++;
+
+      NumPageToWrite--;
+
+      /* Calculate Next small page Address */
+      addressstatus = FSMC_NAND_AddressIncrement(&Address);    
+    }    
+  }
+  
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadSmallPage
+* Description    : This routine is for sequential read from one or several 
+*                  512 Bytes Page size.
+* Input          : - pBuffer: pointer on the Buffer to fill  
+*                  - Address: First page address
+*                  - NumPageToRead: Number of page to read
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+u32 FSMC_NAND_ReadSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead)
+{
+  u32 index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  u32 status = NAND_READY, size = 2048, i = 0;
+
+  /* Calculate the size */
+  size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
+
+  while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
+  {	   
+    /* Page Read command and page address */
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A; 
+   
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS); 
+    
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1; 
+   for(i = 0; i <= 10000; i++);
+    
+    /* Get Data into Buffer */    
+    for(; index < size; index++)
+    {
+      pBuffer[index]= *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
+    }
+
+    numpageread++;
+    
+    NumPageToRead--;
+
+    /* Calculate page address */           			 
+    addressstatus = FSMC_NAND_AddressIncrement(&Address);
+  }
+
+  status = FSMC_NAND_GetStatus();
+  
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_WriteSpareArea
+* Description    : This routine write the spare area information for the specified 
+*                  pages addresses.
+* Input          : - pBuffer: pointer on the Buffer containing data to be written 
+*                  - Address: First page address
+*                  - NumSpareAreaTowrite: Number of Spare Area to write
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+u32 FSMC_NAND_WriteSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaTowrite)
+{
+  u32 index = 0x00, numsparesreawritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  u32 status = NAND_READY, size = 0x00; 
+
+  while((NumSpareAreaTowrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
+  {
+    /* Page write Spare area command and address */
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
+
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS); 
+    /* Calculate the size */ 
+    size = NAND_SPARE_AREA_SIZE + (NAND_SPARE_AREA_SIZE * numsparesreawritten);
+
+    /* Write the data */ 
+    for(; index < size; index++)
+    {
+      *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
+    }
+    
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
+
+    /* Check status for successful operation */
+    status = FSMC_NAND_GetStatus();
+
+    if(status == NAND_READY)
+    {
+      numsparesreawritten++;      
+
+      NumSpareAreaTowrite--;  
+    
+      /* Calculate Next page Address */
+      addressstatus = FSMC_NAND_AddressIncrement(&Address);
+    }       
+  }
+  
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadSpareArea
+* Description    : This routine read the spare area information from the specified
+*                  pages addresses.
+* Input          : - pBuffer: pointer on the Buffer to fill  
+*                  - Address: First page address
+*                  - NumSpareAreaToRead: Number of Spare Area to read
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*                  And the new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+u32 FSMC_NAND_ReadSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaToRead)
+{
+  u32 numsparearearead = 0x00, index = 0x00, addressstatus = NAND_VALID_ADDRESS;
+  u32 status = NAND_READY, size = 0x00;
+
+  while((NumSpareAreaToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
+  {     
+    /* Page Read command and page address */     
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
+
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS); 
+
+    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;
+
+    /* Data Read */
+    size = NAND_SPARE_AREA_SIZE +  (NAND_SPARE_AREA_SIZE * numsparearearead);
+	
+    /* Get Data into Buffer */
+    for ( ;index < size; index++)
+    {
+      pBuffer[index] = *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
+    }
+    
+    numsparearearead++;
+    
+    NumSpareAreaToRead--;
+
+    /* Calculate page address */           			 
+    addressstatus = FSMC_NAND_AddressIncrement(&Address);
+  }
+
+  status = FSMC_NAND_GetStatus();
+
+  return (status | addressstatus);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_EraseBlock
+* Description    : This routine erase complete block from NAND FLASH
+* Input          : - Address: Any address into block to be erased
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation 
+*******************************************************************************/
+u32 FSMC_NAND_EraseBlock(NAND_ADDRESS Address)
+{
+  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;
+
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS); 
+    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_5fh_CYCLE(ROW_ADDRESS); 
+  
+  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1; 
+
+  return (FSMC_NAND_GetStatus());
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_Reset
+* Description    : This routine reset the NAND FLASH
+* Input          : None
+* Output         : None
+* Return         : NAND_READY
+*******************************************************************************/
+u32 FSMC_NAND_Reset(void)
+{
+  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;
+
+  return (NAND_READY);
+}
+
+/******************************************************************************
+* Function Name  : FSMC_NAND_GetStatus
+* Description    : Get the NAND operation status
+* Input          : None
+* Output         : None
+* Return         : New status of the NAND operation. This parameter can be:
+*                   - NAND_TIMEOUT_ERROR: when the previous operation generate 
+*                     a Timeout error
+*                   - NAND_READY: when memory is ready for the next operation    
+*******************************************************************************/
+u32 FSMC_NAND_GetStatus(void)
+{
+  u32 timeout = 0x1000000, status = NAND_READY;
+
+  status = FSMC_NAND_ReadStatus(); 
+
+  /* Wait for a NAND operation to complete or a TIMEOUT to occur */
+  while ((status != NAND_READY) &&( timeout != 0x00))
+  {
+     status = FSMC_NAND_ReadStatus();
+     timeout --;      
+  }
+
+  if(timeout == 0x00)
+  {          
+    status =  NAND_TIMEOUT_ERROR;      
+  } 
+
+  /* Return the operation status */
+  return (status);      
+}
+/******************************************************************************
+* Function Name  : FSMC_NAND_ReadStatus
+* Description    : Reads the NAND memory status using the Read status command 
+* Input          : None
+* Output         : None
+* Return         : The status of the NAND memory. This parameter can be:
+*                   - NAND_BUSY: when memory is busy
+*                   - NAND_READY: when memory is ready for the next operation    
+*                   - NAND_ERROR: when the previous operation gererates error   
+*******************************************************************************/
+u32 FSMC_NAND_ReadStatus(void)
+{
+  u32 data = 0x00, status = NAND_BUSY;
+
+  /* Read status operation ------------------------------------ */
+  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
+  data = *(vu8 *)(Bank_NAND_ADDR);
+
+  if((data & NAND_ERROR) == NAND_ERROR)
+  {
+    status = NAND_ERROR;
+  } 
+  else if((data & NAND_READY) == NAND_READY)
+  {
+    status = NAND_READY;
+  }
+  else
+  {
+    status = NAND_BUSY; 
+  }
+  
+  return (status);
+}
+
+/******************************************************************************
+* Function Name  : NAND_AddressIncrement
+* Description    : Increment the NAND memory address
+* Input          : - Address: address to be incremented.
+* Output         : None
+* Return         : The new status of the increment address operation. It can be:
+*                  - NAND_VALID_ADDRESS: When the new address is valid address
+*                  - NAND_INVALID_ADDRESS: When the new address is invalid address
+*******************************************************************************/
+u32 FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address)
+{
+  u32 status = NAND_VALID_ADDRESS;
+ 
+  Address->Page++;
+
+  if(Address->Page == NAND_BLOCK_SIZE)
+  {
+    Address->Page = 0;
+    Address->Block++;
+    
+    if(Address->Block == NAND_ZONE_SIZE)
+    {
+      Address->Block = 0;
+      Address->Zone++;
+
+      if(Address->Zone == NAND_MAX_ZONE)
+      {
+        status = NAND_INVALID_ADDRESS;
+      }
+    }
+  } 
+  
+  return (status);
+}
+
+/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

+ 106 - 0
bsp/stm32_radio/fsmc_nand.h

@@ -0,0 +1,106 @@
+/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
+* File Name          : fsmc_nand.h
+* Author             : MCD Application Team
+* Version            : V2.0.3
+* Date               : 09/22/2008
+* Description        : Header for fsmc_nand.c file.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __FSMC_NAND_H
+#define __FSMC_NAND_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f10x_lib.h"
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct
+{
+  u8 Maker_ID;
+  u8 Device_ID;
+  u8 Third_ID;
+  u8 Fourth_ID;
+}NAND_IDTypeDef;
+
+typedef struct 
+{
+  u16 Zone;
+  u16 Block;
+  u16 Page;
+} NAND_ADDRESS;
+
+/* Exported constants --------------------------------------------------------*/
+/* NAND Area definition  for STM3210E-EVAL Board RevD */
+#define CMD_AREA                   (u32)(1<<16)  /* A16 = CLE  high */
+#define ADDR_AREA                  (u32)(1<<17)  /* A17 = ALE high */
+
+#define DATA_AREA                  ((u32)0x00000000) 
+
+/* FSMC NAND memory command */
+#define	NAND_CMD_AREA_A            ((u8)0x00)
+#define	NAND_CMD_AREA_B            ((u8)0x01)
+#define NAND_CMD_AREA_C            ((u8)0x50)
+#define NAND_CMD_AREA_TRUE1        ((u8)0x30)
+
+#define NAND_CMD_WRITE0            ((u8)0x80)
+#define NAND_CMD_WRITE_TRUE1       ((u8)0x10)
+	
+#define NAND_CMD_ERASE0            ((u8)0x60)
+#define NAND_CMD_ERASE1            ((u8)0xD0)  
+
+#define NAND_CMD_READID            ((u8)0x90)	
+#define NAND_CMD_STATUS            ((u8)0x70)
+#define NAND_CMD_LOCK_STATUS       ((u8)0x7A)
+#define NAND_CMD_RESET             ((u8)0xFF)
+
+/* NAND memory status */
+#define NAND_VALID_ADDRESS         ((u32)0x00000100)
+#define NAND_INVALID_ADDRESS       ((u32)0x00000200)
+#define NAND_TIMEOUT_ERROR         ((u32)0x00000400)
+#define NAND_BUSY                  ((u32)0x00000000)
+#define NAND_ERROR                 ((u32)0x00000001)
+#define NAND_READY                 ((u32)0x00000040)
+
+/* FSMC NAND memory parameters */
+//#define NAND_PAGE_SIZE             ((u16)0x0200) /* 512 bytes per page w/o Spare Area */
+//#define NAND_BLOCK_SIZE            ((u16)0x0020) /* 32x512 bytes pages per block */
+//#define NAND_ZONE_SIZE             ((u16)0x0400) /* 1024 Block per zone */
+//#define NAND_SPARE_AREA_SIZE       ((u16)0x0010) /* last 16 bytes as spare area */
+//#define NAND_MAX_ZONE              ((u16)0x0004) /* 4 zones of 1024 block */
+
+/* FSMC NAND memory parameters */
+#define NAND_PAGE_SIZE             ((u16)0x0800) /* 2K bytes per page w/o Spare Area */
+#define NAND_BLOCK_SIZE            ((u16)0x0040) /* 64x2K bytes pages per block */
+#define NAND_ZONE_SIZE             ((u16)0x0400) /* 1024 Block per zone */
+#define NAND_SPARE_AREA_SIZE       ((u16)0x0040) /* last 64 bytes as spare area */
+#define NAND_MAX_ZONE              ((u16)0x0002) /* 1 zones of 2048 block */
+
+/* FSMC NAND memory address computation */
+#define ADDR_1st_CYCLE(ADDR)       (u8)((ADDR)& 0xFF)               /* 1st addressing cycle */
+#define ADDR_2nd_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF00) >> 8)      /* 2nd addressing cycle */
+#define ADDR_3rd_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF0000) >> 16)   /* 3rd addressing cycle */
+#define ADDR_4th_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF000000) >> 24) /* 4th addressing cycle */
+#define ADDR_5fh_CYCLE(ADDR)       (u8)(((ADDR)& 0xFF00000000) >> 32) /* 4th addressing cycle */
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+void FSMC_NAND_Init(void);
+void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID);
+u32 FSMC_NAND_WriteSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToWrite);
+u32 FSMC_NAND_ReadSmallPage (u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead);
+u32 FSMC_NAND_WriteSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaTowrite);
+u32 FSMC_NAND_ReadSpareArea(u8 *pBuffer, NAND_ADDRESS Address, u32 NumSpareAreaToRead);
+u32 FSMC_NAND_EraseBlock(NAND_ADDRESS Address);
+u32 FSMC_NAND_Reset(void);
+u32 FSMC_NAND_GetStatus(void);
+u32 FSMC_NAND_ReadStatus(void);
+u32 FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);
+
+#endif /* __FSMC_NAND_H */
+
+/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

+ 116 - 0
bsp/stm32_radio/fsmc_sram.c

@@ -0,0 +1,116 @@
+/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
+* File Name          : fsmc_sram.c
+* Author             : MCD Application Team
+* Version            : V2.0.3
+* Date               : 09/22/2008
+* Description        : This file provides a set of functions needed to drive the
+*                      IS61WV51216BLL SRAM memory mounted on STM3210E-EVAL board.
+********************************************************************************
+* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+#include "stm32f10x_lib.h"
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define Bank1_SRAM3_ADDR    ((u32)0x68000000)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+* Function Name  : FSMC_SRAM_Init
+* Description    : Configures the FSMC and GPIOs to interface with the SRAM memory.
+*                  This function must be called before any write/read operation
+*                  on the SRAM.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void FSMC_SRAM_Init(void)
+{
+  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
+  FSMC_NORSRAMTimingInitTypeDef  p;
+  GPIO_InitTypeDef GPIO_InitStructure;
+
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOE |
+                         RCC_APB2Periph_GPIOF, ENABLE);
+
+/*-- GPIO Configuration ------------------------------------------------------*/
+  /* SRAM Data lines configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
+                                GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+  GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
+                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
+                                GPIO_Pin_15;
+  GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+  /* SRAM Address lines configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
+                                GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
+                                GPIO_Pin_14 | GPIO_Pin_15;
+  GPIO_Init(GPIOF, &GPIO_InitStructure);
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
+                                GPIO_Pin_4 | GPIO_Pin_5;
+  GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
+  GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+  /* NOE and NWE configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
+  GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+  /* NE3 NE4 configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12;
+  GPIO_Init(GPIOG, &GPIO_InitStructure);
+
+  /* NBL0, NBL1 configuration */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
+  GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+/*-- FSMC Configuration ------------------------------------------------------*/
+  p.FSMC_AddressSetupTime = 0;
+  p.FSMC_AddressHoldTime = 0;
+  p.FSMC_DataSetupTime = 2;
+  p.FSMC_BusTurnAroundDuration = 0;
+  p.FSMC_CLKDivision = 0;
+  p.FSMC_DataLatency = 0;
+  p.FSMC_AccessMode = FSMC_AccessMode_A;
+
+  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
+  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
+  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
+  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+
+  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
+
+  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
+  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
+
+  /* Enable FSMC Bank1_SRAM Bank */
+  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);
+  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
+}
+
+/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

+ 2 - 2
bsp/stm32_radio/mp3.c

@@ -285,13 +285,13 @@ int mp3_decoder_run(struct mp3_decoder* decoder)
 		/* no error */
 		MP3GetLastFrameInfo(decoder->decoder, &decoder->frame_info);
 
-// #ifdef MP3_DECODER_TRACE
+#ifdef MP3_DECODER_TRACE
 		rt_kprintf("Bitrate: %i\n", decoder->frame_info.bitrate);
 		rt_kprintf("%i samples\n", decoder->frame_info.outputSamps);
 
 		rt_kprintf("%lu Hz, %i kbps\n", decoder->frame_info.samprate,
             decoder->frame_info.bitrate/1000);
-// #endif
+#endif
 
         /* set sample rate */
 

+ 6 - 3
bsp/stm32_radio/project.Uv2

@@ -21,11 +21,14 @@ File 1,5,<.\stm32f10x_conf.h><stm32f10x_conf.h>
 File 1,5,<.\rtconfig.h><rtconfig.h>
 File 1,1,<.\usart.c><usart.c>
 File 1,1,<.\sdcard.c><sdcard.c>
-File 1,1,<.\enc28j60.c><enc28j60.c>
 File 1,1,<.\rtc.c><rtc.c>
 File 1,1,<.\mp3.c><mp3.c>
 File 1,1,<.\wm8753.c><wm8753.c>
 File 1,1,<.\wav.c><wav.c>
+File 1,1,<.\dm9000.c><dm9000.c>
+File 1,1,<.\fsmc_nand.c><fsmc_nand.c>
+File 1,1,<.\fsmc_sram.c><fsmc_sram.c>
+File 1,1,<.\fmt0371\fmt0371.c><fmt0371.c>
 File 2,1,<.\library\src\stm32f10x_adc.c><stm32f10x_adc.c>
 File 2,1,<.\library\src\stm32f10x_bkp.c><stm32f10x_bkp.c>
 File 2,1,<.\library\src\stm32f10x_can.c><stm32f10x_can.c>
@@ -238,10 +241,10 @@ Options 1,0,0  // Target 'RT-Thread STM32 Radio'
  ADSLDIF ()
  ADSLDDW ()
   OPTDL (SARMCM3.DLL)()(DARMSTM.DLL)(-pSTM32F103ZE)(SARMCM3.DLL)()(TARMSTM.DLL)(-pSTM32F103ZE)
-  OPTDBG 48117,7,()()()()()()()()()() (Segger\JL2CM3.dll)()()()
+  OPTDBG 48118,7,()()()()()()()()()() (Segger\JL2CM3.dll)()()()
  FLASH1 { 1,0,0,0,1,0,0,0,5,16,0,0,0,0,0,0,0,0,0,0 }
  FLASH2 (Segger\JL2CM3.dll)
- FLASH3 ()
+ FLASH3 ("" ())
  FLASH4 ()
 EndOpt
 

+ 2 - 3
bsp/stm32_radio/rtconfig.h

@@ -95,7 +95,7 @@
 
 /* SECTION: lwip, a lighwight TCP/IP protocol stack */
 /* Using lighweight TCP/IP protocol stack */
-/* #define RT_USING_LWIP */
+#define RT_USING_LWIP
 /* #define RT_USING_WEBSERVER */
 
 /* Trace LwIP protocol */
@@ -123,7 +123,7 @@
 /* #define RT_LWIP_SNMP */
 
 /* Using DHCP */
-#define RT_LWIP_DHCP
+/* #define RT_LWIP_DHCP */
 
 /* Using DNS */
 #define RT_LWIP_DNS
@@ -156,6 +156,5 @@
 #define RT_LWIP_ETHTHREAD_MBOX_SIZE		4
 #define RT_LWIP_ETHTHREAD_STACKSIZE		512
 
-#define LWIP_NOASSERT
 
 #endif

+ 27 - 29
bsp/stm32_radio/startup.c

@@ -15,12 +15,14 @@
 #include <rthw.h>
 #include <rtthread.h>
 
-#include "board.h"
+#include "board.h"
 #include "rtc.h"
 
-#ifdef RT_USING_LWIP
-#include <netif/ethernetif.h>
-#include "enc28j60.h"
+#include <stm32f10x.h>
+
+#ifdef RT_USING_LWIP
+#include <netif/ethernetif.h>
+#include "dm9000.h"
 #endif
 
 /**
@@ -28,22 +30,20 @@
  */
 
 /*@{*/
-#ifdef RT_USING_FINSH
-extern void finsh_system_init(void);
-extern void finsh_set_device(char* device);
-#endif
-
-extern int  rt_application_init(void);
-
 #ifdef __CC_ARM
 extern int Image$$RW_IRAM1$$ZI$$Limit;
 #elif __ICCARM__
 #pragma section="HEAP"
 #else
 extern int __bss_end;
-#endif
+#endif
 
-extern rt_err_t wm8753_hw_init(void);
+#ifdef RT_USING_FINSH
+extern void finsh_system_init(void);
+extern void finsh_set_device(const char* device);
+#endif
+extern int rt_application_init(void);
+extern rt_err_t wm8753_hw_init(void);
 
 #ifdef  DEBUG
 /*******************************************************************************
@@ -85,18 +85,18 @@ void rtthread_startup(void)
 	/* init timer system */
 	rt_system_timer_init();
 
-#ifdef RT_USING_HEAP
-#ifdef RT_USING_SRAM
-	rt_system_heap_init((void*)0x68000000, (void*)0x68080000);
-#else
-#ifdef __CC_ARM
-	rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x20010000);
-#elif __ICCARM__
-    rt_system_heap_init(__segment_end("HEAP"), (void*)0x20010000);
+#ifdef RT_USING_HEAP
+#if STM32_EXT_SRAM
+	rt_system_heap_init((void*)STM32_EXT_SRAM_BEGIN, (void*)STM32_EXT_SRAM_END);
 #else
+	#ifdef __CC_ARM
+		rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)STM32_SRAM_END);
+	#elif __ICCARM__
+	    rt_system_heap_init(__segment_end("HEAP"), (void*)STM32_SRAM_END);
+	#else
 	/* init memory system */
-	rt_system_heap_init((void*)&__bss_end, (void*)0x20010000);
-#endif
+		rt_system_heap_init((void*)&__bss_end, (void*)STM32_SRAM_END);
+	#endif
 #endif
 #endif
 
@@ -107,15 +107,15 @@ void rtthread_startup(void)
 	eth_system_device_init();
 
 	/* register ethernetif device */
-	rt_hw_enc28j60_init();
-#endif
+	rt_hw_dm9000_init();
+#endif
 
-	rt_hw_rtc_init();
-	wm8753_hw_init();
+	wm8753_hw_init();
 
 	/* init hardware serial device */
 	rt_hw_usart_init();
 #ifdef RT_USING_DFS
+    GPIO_ResetBits(GPIOC,GPIO_Pin_6);
 	rt_hw_sdcard_init();
 #endif
 
@@ -128,9 +128,7 @@ void rtthread_startup(void)
 #ifdef RT_USING_FINSH
 	/* init finsh */
 	finsh_system_init();
-#ifdef RT_USING_DEVICE
 	finsh_set_device("uart1");
-#endif
 #endif
 
 	/* init idle thread */

+ 15 - 13
bsp/stm32_radio/stm32f10x_it.c

@@ -230,19 +230,6 @@ void RCC_IRQHandler(void)
 *******************************************************************************/
 void EXTI0_IRQHandler(void)
 {
-    extern void enc28j60_isr(void);
-
-    /* enter interrupt */
-    rt_interrupt_enter();
-
-    enc28j60_isr();
-
-    /* Clear the Key Button EXTI line pending bit */
-    EXTI_ClearITPendingBit(EXTI_Line0);
-
-    /* leave interrupt */
-    rt_interrupt_leave();
-    rt_hw_interrupt_thread_switch();
 }
 
 /*******************************************************************************
@@ -484,6 +471,21 @@ void CAN1_SCE_IRQHandler(void)
 *******************************************************************************/
 void EXTI9_5_IRQHandler(void)
 {
+#ifdef RT_USING_LWIP
+	extern void rt_dm9000_isr(void);
+
+	/* enter interrupt */
+	rt_interrupt_enter();
+
+	rt_dm9000_isr();
+
+	/* Clear the Key Button EXTI line pending bit */
+	EXTI_ClearITPendingBit(EXTI_Line7);
+
+	/* leave interrupt */
+	rt_interrupt_leave();
+	rt_hw_interrupt_thread_switch();
+#endif
 }
 
 /*******************************************************************************

+ 2 - 6
bsp/stm32_radio/wav.c

@@ -45,14 +45,10 @@ void wav(char* filename)
 		rt_device_set_tx_complete(device, wav_tx_done);
 		rt_device_open(device, RT_DEVICE_OFLAG_WRONLY);
 
-		// buf = rt_mp_alloc(mp, RT_WAITING_FOREVER);
-		// len = read(fd, (char*)buf, WAV_MP_BUFSZ);
-
-		do {
+		do
+		{
 			buf = rt_mp_alloc(mp, RT_WAITING_FOREVER);
-			rt_kprintf("read file");
 			len = read(fd, (char*)buf, WAV_MP_BUFSZ);
-			rt_kprintf("...done!\n");
 			if (len > 0) rt_device_write(device, 0, buf, len);
 		} while (len != 0);
 

+ 32 - 52
bsp/stm32_radio/wm8753.c

@@ -69,16 +69,16 @@
 #define WM8753_ADCTL2	0x3f
 
 /*
-SCLK  PA3  SPI1_SCK
+SCLK  PA5  SPI1_SCK
 SDIN  PA7  SPI1_MOSI
-CSB   PA2  SPI1_NSS
+CSB   PA4  SPI1_NSS
 */
-#define wm_sclk_0  GPIO_ResetBits(GPIOA,GPIO_Pin_3)
-#define wm_sclk_1  GPIO_SetBits(GPIOA,GPIO_Pin_3)
+#define wm_sclk_0  GPIO_ResetBits(GPIOA,GPIO_Pin_5)
+#define wm_sclk_1  GPIO_SetBits(GPIOA,GPIO_Pin_5)
 #define wm_sdin_0  GPIO_ResetBits(GPIOA,GPIO_Pin_7)
 #define wm_sdin_1  GPIO_SetBits(GPIOA,GPIO_Pin_7)
-#define wm_csb_0   GPIO_ResetBits(GPIOA,GPIO_Pin_2)
-#define wm_csb_1   GPIO_SetBits(GPIOA,GPIO_Pin_2)
+#define wm_csb_0   GPIO_ResetBits(GPIOA,GPIO_Pin_4)
+#define wm_csb_1   GPIO_SetBits(GPIOA,GPIO_Pin_4)
 
 #define DATA_NODE_MAX 5
 /* data node for Tx Mode */
@@ -128,9 +128,10 @@ static void GPIO_Configuration(void)
 
 	/* Disable the JTAG interface and enable the SWJ interface */
 	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 
 	/* Configure GPIOA 2, 3, 7 */
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7;
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
     GPIO_Init(GPIOA,&GPIO_InitStructure);
@@ -140,6 +141,14 @@ static void GPIO_Configuration(void)
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+    /*    MCO    configure */
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_Init(GPIOA,&GPIO_InitStructure);
+
+    RCC_MCOConfig(RCC_MCO_HSE);
 }
 
 #define SPI2_DR_Address  0x4000380C
@@ -182,7 +191,7 @@ static void I2S_Configuration(void)
 
 	/* I2S2 Master Transmitter to I2S3 Slave Receiver communication -----------*/
 	/* I2S2 configuration */
-	I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;//I2S_Mode_MasterTx
+	I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;//I2S_Mode_MasterTx  I2S_Mode_SlaveTx
 	I2S_Init(SPI2, &I2S_InitStructure);
 }
 
@@ -201,34 +210,9 @@ void wm8753_send(rt_uint16_t s_data)
         {
             wm_sdin_0;
         }
-        //wde();
         wm_sclk_1;
-        //wde();
         s_data <<= 1;
         wm_sclk_0;
-        //wde();
-    }
-
-    wm_csb_0;
-    //wde();
-    wm_csb_1;
-}
-
-void wm8753_hw_write(rt_uint16_t reg, rt_uint16_t value)
-{
-	rt_uint32_t index;
-
-	value = (reg << 9) | value;
-
-    wm_sclk_0;
-    for(index = 0; index < 16; index++)
-    {
-        if(value & 0x8000) wm_sdin_1;
-        else wm_sdin_0;
-
-        wm_sclk_1;
-        value <<= 1;
-        wm_sclk_0;
     }
 
     wm_csb_0;
@@ -246,8 +230,8 @@ static rt_err_t wm8753_init (rt_device_t dev)
 	
 	/*  设置时钟及PLL  */
 	#define MCLK1DIV2 0
-	#define pll1_N    11 // 12
-	#define pll1_K    0x1288CE // 0x126E97 //0x126E97
+	#define pll1_N    11
+	#define pll1_K    0x1288CE
 	
 	#if pll1_K > 0x3FFFFF
 	#warning MAX bit(21:0)
@@ -258,12 +242,14 @@ static rt_err_t wm8753_init (rt_device_t dev)
 	wm8753_send(55<<9 | ( (pll1_K>>9)&0x1FF ) );
 	wm8753_send(56<<9 | ( (pll1_K)&0x1FF ) );
 	
-	wm8753_send(52<<9 | 1<<1 | 1 ); // 打开CLK输出 测试用 可以不设置
+	wm8753_send(52<<9 | 1<<4 | 0<<1 | 0 ); // 打开CLK输出 测试用 可以不设置
 	/*  设置时钟及PLL  */
 	
 	/* 设置IIS及DAC */
 	// wm8753_send(6<<9 | 0<<1 | 0 ); // 48K
-	wm8753_send(6<<9 | 1<<5 | 0 ); // 44.1K
+	wm8753_send(7<<9 | 3<<3 ); // BCLK = MCLK / 8	   0:0 1:2 2:4 3:8 4:16
+	wm8753_send(6<<9 | 16<<1 | 0 ); // 44.1K
+	wm8753_send(5<<9 | 0x01<<4 | 0x01<<5 | 0x02<<2 | 0x02<<2 | 0x01<<1 | 1); //
 	wm8753_send(4<<9 | 0<<6 | 2 ); // 6.master IIS
 	wm8753_send(1<<9 | 0 ); // 关闭DAC静音
 	/* 设置IIS及DAC */
@@ -272,11 +258,13 @@ static rt_err_t wm8753_init (rt_device_t dev)
 	wm8753_send(34<<9 | 1<<8 | 1<<7 | 4<<4 );  // DAC LINE
 	wm8753_send(36<<9 | 1<<8 | 1<<7 | 4<<4 );  // DAC LINE
 	
-	wm8753_send(40<<9 | 1<<8 | 1<<7 | 110);    // 耳机音量
-	wm8753_send(41<<9 | 1<<8 | 1<<7 | 110);    // 耳机音量
+	wm8753_send(40<<9 | 0<<8 | 1<<7 | 100);    // 耳机音量
+	wm8753_send(41<<9 | 1<<8 | 1<<7 | 100);    // 耳机音量
 	
 	wm8753_send(45<<9 | 1<<2); // 设置ROUT反向
-	wm8753_send(43<<9 | 1<<8 | 1<<7 | 70 ); //喇叭音量
+	wm8753_send(42<<9 | 1<<8 | 1<<7 | 105 ); //喇叭音量
+	wm8753_send(43<<9 | 1<<8 | 1<<7 | 105 ); //喇叭音量
+	/* 设置IIS及DAC */
 
 	return RT_EOK;
 }
@@ -284,8 +272,11 @@ static rt_err_t wm8753_init (rt_device_t dev)
 #include <finsh.h>
 void vol(int v)
 {
-	wm8753_send(40<<9 | 1<<8 | 1<<7 | v);    // 耳机音量
+	wm8753_send(40<<9 | 0<<8 | 1<<7 | v);    // 耳机音量
 	wm8753_send(41<<9 | 1<<8 | 1<<7 | v);    // 耳机音量
+
+	wm8753_send(42<<9 | 0<<8 | 1<<7 | v);    // 耳机音量
+	wm8753_send(43<<9 | 1<<8 | 1<<7 | v);    // 耳机音量
 }
 FINSH_FUNCTION_EXPORT(vol, set volume)
 
@@ -346,17 +337,6 @@ static rt_size_t wm8753_write (rt_device_t dev, rt_off_t pos, const void* buffer
 	node->data_ptr = (rt_uint16_t*)buffer;
 	node->data_size = size >> 1; /* size is byte unit, convert to half word unit */
 
-#if 0
-	{
-		/* sound patch */
-		rt_uint32_t index;
-		for (index = 0; index < node->data_size; index ++)
-		{
-			((rt_int16_t*)(node->data_ptr))[index] = (rt_int16_t)(node->data_ptr[index] + 0x8000);
-		}
-	}
-#endif
-
 	next_index = device->read_index + 1;
 	if (next_index >= DATA_NODE_MAX) next_index = 0;