diff --git a/bsp/stm32_radio/application.c b/bsp/stm32_radio/application.c index 97bfc81f9c..49124666a6 100644 --- a/bsp/stm32_radio/application.c +++ b/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 #include +#include + #ifdef RT_USING_DFS /* dfs init */ #include @@ -29,19 +31,115 @@ #include /* dfs Filesystem APIs */ #include -#endif +#endif -#ifdef RT_USING_LWIP -#include -#include -#endif +#ifdef RT_USING_LWIP +#include +#include +#endif -/* thread phase init */ -void rt_init_thread_entry(void *parameter) -{ -/* Filesystem Initialization */ -#ifdef RT_USING_DFS - { +/* +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, - 1024, 8, 20); - rt_thread_startup(init_thread); + 2048, 8, 20); +#else + init_thread = rt_thread_create("init", + rt_init_thread_entry, RT_NULL, + 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; } diff --git a/bsp/stm32_radio/board.c b/bsp/stm32_radio/board.c index 8ffc1cf193..0d031604c2 100644 --- a/bsp/stm32_radio/board.c +++ b/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 #include -#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; + 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 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); + /* 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) diff --git a/bsp/stm32_radio/board.h b/bsp/stm32_radio/board.h index 32350bac62..9b724a4736 100644 --- a/bsp/stm32_radio/board.h +++ b/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 */ +// SDCard Driver <1=>SDIO sdcard <0=>SPI MMC card +// Default: 1 +#define STM32_USE_SDIO 1 + +/* whether use board external SRAM memory */ +// Use external SRAM memory on the board +// Enable External SRAM memory +#define STM32_EXT_SRAM 0 +// Begin Address of External SRAM +// Default: 0x68000000 +#define STM32_EXT_SRAM_BEGIN 0x68000000 /* the begining address of external SRAM */ +// End Address of External SRAM +// Default: 0x68080000 +#define STM32_EXT_SRAM_END 0x68080000 /* the end address of external SRAM */ +// + +// Internal SRAM memory size[Kbytes] <8-64> +// 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 >>> diff --git a/bsp/stm32_radio/dac.c b/bsp/stm32_radio/dac.c deleted file mode 100644 index fd30ac7bcd..0000000000 --- a/bsp/stm32_radio/dac.c +++ /dev/null @@ -1,56 +0,0 @@ -#include - -#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(); -} diff --git a/bsp/stm32_radio/dac.h b/bsp/stm32_radio/dac.h deleted file mode 100644 index 8a34a31587..0000000000 --- a/bsp/stm32_radio/dac.h +++ /dev/null @@ -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_ */ diff --git a/bsp/stm32_radio/dm9000.c b/bsp/stm32_radio/dm9000.c index 29701c2f42..af3910ec1a 100644 --- a/bsp/stm32_radio/dm9000.c +++ b/bsp/stm32_radio/dm9000.c @@ -3,13 +3,16 @@ #include #include "lwipopts.h" +#include /* * 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 diff --git a/bsp/stm32_radio/dm9000.h b/bsp/stm32_radio/dm9000.h index 2edb19fa4a..ec4b2d14bb 100644 --- a/bsp/stm32_radio/dm9000.h +++ b/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) diff --git a/bsp/stm32_radio/enc28j60.c b/bsp/stm32_radio/enc28j60.c deleted file mode 100644 index 841b740e9b..0000000000 --- a/bsp/stm32_radio/enc28j60.c +++ /dev/null @@ -1,727 +0,0 @@ -#include "enc28j60.h" - -#include -#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 -/* - * 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; -} diff --git a/bsp/stm32_radio/enc28j60.h b/bsp/stm32_radio/enc28j60.h deleted file mode 100644 index c8d27c2a5c..0000000000 --- a/bsp/stm32_radio/enc28j60.h +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef __ENC28J60_H__ -#define __ENC28J60_H__ - -#include - -// 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 diff --git a/bsp/stm32_radio/fmt0371/fmt0371.c b/bsp/stm32_radio/fmt0371/fmt0371.c new file mode 100644 index 0000000000..cc5cfdc041 --- /dev/null +++ b/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>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 diff --git a/bsp/stm32_radio/fsmc_nand.c b/bsp/stm32_radio/fsmc_nand.c new file mode 100644 index 0000000000..823219fa70 --- /dev/null +++ b/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****/ diff --git a/bsp/stm32_radio/fsmc_nand.h b/bsp/stm32_radio/fsmc_nand.h new file mode 100644 index 0000000000..2587ce070f --- /dev/null +++ b/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****/ diff --git a/bsp/stm32_radio/fsmc_sram.c b/bsp/stm32_radio/fsmc_sram.c new file mode 100644 index 0000000000..734863521a --- /dev/null +++ b/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****/ diff --git a/bsp/stm32_radio/mp3.c b/bsp/stm32_radio/mp3.c index b1e4eed77b..5182550460 100644 --- a/bsp/stm32_radio/mp3.c +++ b/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 */ diff --git a/bsp/stm32_radio/project.Uv2 b/bsp/stm32_radio/project.Uv2 index 3a5fcc687b..7f0afa70e9 100644 --- a/bsp/stm32_radio/project.Uv2 +++ b/bsp/stm32_radio/project.Uv2 @@ -21,11 +21,14 @@ File 1,5,<.\stm32f10x_conf.h> File 1,5,<.\rtconfig.h> File 1,1,<.\usart.c> File 1,1,<.\sdcard.c> -File 1,1,<.\enc28j60.c> File 1,1,<.\rtc.c> File 1,1,<.\mp3.c> File 1,1,<.\wm8753.c> File 1,1,<.\wav.c> +File 1,1,<.\dm9000.c> +File 1,1,<.\fsmc_nand.c> +File 1,1,<.\fsmc_sram.c> +File 1,1,<.\fmt0371\fmt0371.c> File 2,1,<.\library\src\stm32f10x_adc.c> File 2,1,<.\library\src\stm32f10x_bkp.c> File 2,1,<.\library\src\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 diff --git a/bsp/stm32_radio/rtconfig.h b/bsp/stm32_radio/rtconfig.h index 38cbc8ada2..706c443756 100644 --- a/bsp/stm32_radio/rtconfig.h +++ b/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 diff --git a/bsp/stm32_radio/startup.c b/bsp/stm32_radio/startup.c index 916c3d17bf..34e4666288 100644 --- a/bsp/stm32_radio/startup.c +++ b/bsp/stm32_radio/startup.c @@ -15,12 +15,14 @@ #include #include -#include "board.h" +#include "board.h" #include "rtc.h" -#ifdef RT_USING_LWIP -#include -#include "enc28j60.h" +#include + +#ifdef RT_USING_LWIP +#include +#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 */ diff --git a/bsp/stm32_radio/stm32f10x_it.c b/bsp/stm32_radio/stm32f10x_it.c index c2da35f7da..ac42f4ef59 100644 --- a/bsp/stm32_radio/stm32f10x_it.c +++ b/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 } /******************************************************************************* diff --git a/bsp/stm32_radio/wav.c b/bsp/stm32_radio/wav.c index ceaf152ec5..85b3d69e12 100644 --- a/bsp/stm32_radio/wav.c +++ b/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); diff --git a/bsp/stm32_radio/wm8753.c b/bsp/stm32_radio/wm8753.c index 17ba39c48c..56518f6ca0 100644 --- a/bsp/stm32_radio/wm8753.c +++ b/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 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;