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:
parent
f3b6d80e58
commit
18fd853790
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
{
|
||||
|
|
|
@ -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 >>>
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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_ */
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue