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

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@73 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong 2009-10-08 13:47:58 +00:00
parent f3b6d80e58
commit 18fd853790
21 changed files with 1477 additions and 1449 deletions

View File

@ -1,11 +1,11 @@
/*
* File : app.c
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
@ -20,6 +20,8 @@
#include <rtthread.h>
#include <finsh.h>
#include <stm32f10x.h>
#ifdef RT_USING_DFS
/* dfs init */
#include <dfs_init.h>
@ -36,6 +38,102 @@
#include <lwip/api.h>
#endif
/*
key_enter PA0
key_down PA1
key_up PA2
key_right PC2
key_left PC3
*/
#define key_enter_GETVALUE() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define key_down_GETVALUE() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)
#define key_up_GETVALUE() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)
#define key_right_GETVALUE() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
#define key_left_GETVALUE() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
void rt_key_entry(void *parameter)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_Init(GPIOC,&GPIO_InitStructure);
while (1)
{
if ( key_enter_GETVALUE() == 0 )rt_kprintf("key_enter\r\n");
if ( key_down_GETVALUE() == 0 )rt_kprintf("key_down\r\n");
if ( key_up_GETVALUE() == 0 )rt_kprintf("key_up\r\n");
if ( key_right_GETVALUE() == 0 )rt_kprintf("key_right\r\n");
if ( key_left_GETVALUE() == 0 )rt_kprintf("key_left\r\n");
rt_thread_delay(20);
}
}
#include "fmt0371\fmt0371.h"
// lcd test routine
void fmt0371_test(void)
{
unsigned int color[]={0xf800,0x07e0,0x001f,0xffe0,0x0000,0xffff,0x07ff,0xf81f};
unsigned int num;
unsigned int n,c;
for (c=0;c<8;c++)
{
LCD_ADDR = 0x02;
LCD_DATA = 0x00;
LCD_ADDR = 0x03;
LCD_DATA16(0x0000);
LCD_ADDR = 0x0E;
for (n=0;n<240;n++)
{
for (num=0;num<320;num++)
{
LCD_DATA16(color[c]);
}
}
rt_thread_delay(100);
}
}
void rt_lcd_entry(void *parameter)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF,&GPIO_InitStructure);
GPIO_SetBits(GPIOF,GPIO_Pin_9);
ftm0371_port_init();
ftm0371_init();
rt_kprintf("Now test the LCD......\r\n");
while (1)
{
fmt0371_test();
}
}
void lcd_test()
{
rt_thread_t lcd_tid;
lcd_tid = rt_thread_create("lcd",
rt_lcd_entry, RT_NULL,
512, 30, 5);
if (lcd_tid != RT_NULL) rt_thread_startup(lcd_tid);
}
FINSH_FUNCTION_EXPORT(lcd_test, test lcd)
/* thread phase init */
void rt_init_thread_entry(void *parameter)
{
@ -71,11 +169,25 @@ int rt_application_init()
{
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;
}

View File

@ -5,7 +5,7 @@
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
@ -15,7 +15,8 @@
#include <rthw.h>
#include <rtthread.h>
#include "stm32f10x_lib.h"
#include "stm32f10x.h"
#include "board.h"
static void rt_hw_console_init(void);
@ -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) ;
}
}
@ -131,179 +132,60 @@ void rt_hw_timer_handler(void)
/* 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();
/* Configure the SysTick */
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 */
{

View File

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

View File

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

View File

@ -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_ */

View File

@ -3,6 +3,7 @@
#include <netif/ethernetif.h>
#include "lwipopts.h"
#include <stm32f10x_lib.h>
/*
* DM9000 interrupt line is connected to PF7
@ -10,6 +11,8 @@
//--------------------------------------------------------
#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,13 +468,82 @@ 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;
@ -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

View File

@ -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)

View File

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

View File

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

View File

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

View File

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

498
bsp/stm32_radio/fsmc_nand.c Normal file
View File

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

106
bsp/stm32_radio/fsmc_nand.h Normal file
View File

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

116
bsp/stm32_radio/fsmc_sram.c Normal file
View File

@ -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****/

View File

@ -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 */

View File

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

View File

@ -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

View File

@ -18,9 +18,11 @@
#include "board.h"
#include "rtc.h"
#include <stm32f10x.h>
#ifdef RT_USING_LWIP
#include <netif/ethernetif.h>
#include "enc28j60.h"
#include "dm9000.h"
#endif
/**
@ -28,13 +30,6 @@
*/
/*@{*/
#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__
@ -43,6 +38,11 @@ extern int Image$$RW_IRAM1$$ZI$$Limit;
extern int __bss_end;
#endif
#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
@ -86,17 +86,17 @@ void rtthread_startup(void)
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);
#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();
rt_hw_dm9000_init();
#endif
rt_hw_rtc_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 */

View File

@ -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
}
/*******************************************************************************

View File

@ -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);

View File

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