实例介绍
【实例简介】RTL8306e是一款网络交换机芯片,可进行10M/100M网口、光口通信,驱动简单,可用作网络交换设备。该程序可进行网口、光口数据传送,实现10M/100M网功能,并附有全部代码
【实例截图】
【核心代码】
/****************************************Copyright (c)****************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2010-02-04
** Last Version: V1.0
** Descriptions: The main() function example template
**
**--------------------------------------------------------------------------------------------------------
** Created by: Lanwuqiang
** Created date: 2010-02-05
** Version: V1.0
** Descriptions: 添加用户应用程序
**
**--------------------------------------------------------------------------------------------------------
** Modified by: ZhangNingbo
** Modified date: 2010-02-25
** Version: V1.0
** Descriptions: 串口查询方式示例程序
**
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
** Rechecked by:
*********************************************************************************************************/
#include <string.h>
#include "..\config.h"
#include "x_ClnkDefs.h"
#include "main.h"
#include ".\RTL8306E_API\mdcmdio.h"
#include ".\RTL8306E_API\rtk_api_ext.h"
#define SwitchType 3
/*********************************************************************************************************
宏定义
*********************************************************************************************************/
#define Eeprom_LoAdd 0x3f000
#define Eeprom_HiAdd 0x7f000
unsigned char Eeprom_buf[256];
#define frist_block_start 0x00000
#define host_begin 0x7000
//*********************************************************************************************************/
#define Version " YT_CPE 2013-09-18 Clink 1.66.3 Ver 3.1.4 \r\n\r\n"
#define UART_BPS 9600 /* 串口通信波特率 */
//*********************************************************************************************************/
#define TP_PAUSE 'p'
#define TP_HANDSHAKE 'h'
#define TP_CONFIGURE 'c'
#define TP_UPDATE 'u'
#define TP_INDIRECT 'i'
#define TP_FILE 'f'
#define TP_COMPRESSED 'z'
#define TP_END 'e'
/*************************************************************************************/
#define READ 0x03
#define READ_STATUS_REGISTER 0x05
#define WREN 0x06
#define PROGRAM 0x02
#define SECTOR_ERASE 0x20
#define BLOCK_ERASE 0xd8
/*************************************************************************************/
unsigned long mdio[4];
#define MDIO1_PORT GPIO0DATA
#define MDIO1_DIR GPIO0DIR
#define MDC1 (1ul << 2) //p0.2
#define MDIO1 (1ul << 3) //p0.3
#define MDC1_OUT_E() MDIO1_DIR |= MDC1 //设置为输出
#define MDIO1_OUT_E() MDIO1_DIR |= MDIO1
#define MDIO1_IN_E() MDIO1_DIR &= ~MDIO1 //设置为输入
#define MDIO2_PORT GPIO1DATA
#define MDIO2_DIR GPIO1DIR
#define MDC2 (1ul << 1) //p1.1
#define MDIO2 (1ul << 0) //p1.0
#define MDC2_OUT_E() MDIO2_DIR |= MDC2 //设置为输出
#define MDIO2_OUT_E() MDIO2_DIR |= MDIO2
#define MDIO2_IN_E() MDIO2_DIR &= ~MDIO2 //设置为输入
#define ZIP_Reset (1ul << 4) //p3.4
#define PLL_Reset (1ul << 5) //p3.5
#define ZIP_OUT_E() GPIO3DIR |= ZIP_Reset //设置为输出
#define PLL_OUT_E() GPIO3DIR |= PLL_Reset
#define ZIP_Reset_1() GPIO3DATA |= ZIP_Reset
#define ZIP_Reset_0() GPIO3DATA &= ~ZIP_Reset
#define PLL_Reset_1() GPIO3DATA |= PLL_Reset
#define PLL_Reset_0() GPIO3DATA &= ~PLL_Reset
#define SPI_CS (1ul << 7) //p0.7
#define CE_Low() GPIO0DATA &= ~SPI_CS;
#define CE_High() GPIO0DATA |= SPI_CS;
#define LED_OUT (1ul << 0) //p2.0
#define LED_OUT_E() GPIO2DIR |= LED_OUT //设置为输出
#define LED_ON() GPIO2DATA &= ~LED_OUT;
#define LED_OFF() GPIO2DATA |= LED_OUT;
#define RESET_IN (1ul << 2) //p3.2
#define RESET_IN_E() GPIO3DIR &= ~RESET_IN //设置为输入
#define SW_R_IN (1ul << 4) //p0.4
#define SW_OUT_E() GPIO0DIR |= SW_R_IN //设置为输出
#define SW_OUT_1() GPIO0DATA |= SW_R_IN
#define SW_OUT_0() GPIO0DATA &= ~SW_R_IN
/*************************************************************************************/
unsigned char UartReceiveBuf[30];
unsigned char UartReceiveLen;
/*************************************************************************************/
unsigned char link_stat;
unsigned char update_flash_flag=0; //正在升级标记
unsigned long lst_update_sig; //Last update signature - or address in the fhash where to write
unsigned char lof_read_req; //Set when we should read LOF
unsigned char last_link_status; //What the link status was last time we checked
unsigned int SoC_watchdog; //Count down timer to determine if SoC is hung or not
unsigned long update_ln_buf;
unsigned long update_ln_end;
unsigned long Currently_LOF=0;
#define SOC_BOOT_TIMEOUT 60000 // 35s
/*************************************************************************************/
#define CRC32_POLY 0x04c11db7 /* AUTODIN II, Ethernet, & FDDI */
unsigned long int crc_mini_tab[2] = { 0, CRC32_POLY};
/*************************************************************************************/
// update
#define NumOfMapTx 0x0c007ae4
#define NumOfMapTxErr 0x0c007afc
#define NumOfRsrvRx 0x0c007b18
#define NumOfRsrvRxErr 0x0c007b30
#define NumOfRsrvRxDropped 0x0c007b48
SwitchGetStruct SwitchGetData[5];
unsigned long systemtime=0;
/*************************************************************************************/
void console(void);
void bootup(void);
void eeprom_write(void);
void eeprom_read(void);
void uart_hex32(long int val);
void uart_puts(char *s);
void uart_puts_hex32(char *s,unsigned long val);
int32 function(uint32 enabled);
void Switch_Data_Init(void);
void Switch_Init(void);
void Switch_Set(INT8U PortIndex);
void get_switch_info(void);
void set_LOF(void);
void vlan_entry_clean(void);
/*********************************************************************************************************
** Function name: myDelay
** Descriptions: 软件延时
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void myDelay (INT32U ulTime)
{
INT32U i;
i = 0;
while (ulTime--) {
for (i = 0; i < 5000; i );
}
}
void my_Delay (INT32U ulTime)
{
INT32U i;
for (i = 0; i < ulTime; i );
}
void IO_Init(void)
{
SYSAHBCLKCTRL |= (1ul << 16); /* 使能GPIO模块时钟 */
// IOCON_PIO0_2 &= ~0x07;
// IOCON_PIO0_3 &= ~0x07;
// IOCON_PIO1_0 = ~0x07;
// IOCON_PIO1_1 = ~0x07;
MDC1_OUT_E();
MDIO1_OUT_E();
MDC2_OUT_E();
MDIO2_OUT_E();
ZIP_OUT_E() ;
PLL_OUT_E();
ZIP_Reset_1();
PLL_Reset_1();
LED_OUT_E();
RESET_IN_E();
SW_OUT_E();
}
/*********************************************************************************************************
** Function name: uartInit
** Descriptions: 串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为9600
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
__asm void UART_IRQHandler(void)
{
/* Re-direct interrupt, get handler address from application vector table */
ldr r0, =0x1094
ldr r0, [r0]
BX r0
NOP
}
/*********************************************************************************************************
** Function name: uartInit
** Descriptions: 串口初始化,设置为8位数据位,1位停止位,无奇偶校验,波特率为115200
** input parameters: 无
** output parameters: 无
** Returned value: 无
*********************************************************************************************************/
void uartInit (void)
{
INT16U usFdiv;
SYSAHBCLKCTRL |= (1 << 16); /* 使能IOCON时钟 */
IOCON_PIO1_6 |= 0x01; /* 将P1.6 1.7配置为RXD和TXD */
IOCON_PIO1_7 |= 0x01;
SYSAHBCLKCTRL |= (1<<12); /* 打开UART功能部件时钟 */
UARTCLKDIV = 0x01; /* UART时钟分频 */
U0LCR = 0x83; /* 允许设置波特率 */
usFdiv = (FAHBCLK / UARTCLKDIV /16)/UART_BPS; /* 设置波特率 */
U0DLM = usFdiv / 256;
U0DLL = usFdiv % 256;
U0LCR = 0x03; /* 锁定波特率 */
U0FCR = 0x87; /* 使能FIFO,设置8个字节触发点 */
}
//part 1 -------------uart read/write
// ########################################################################
// ## 初始化
// ########################################################################
void uart_send(const char c)
{
U0THR = c; /* 写入数据 */
while ((U0LSR & 0x40) == 0) { /* 等待数据发送完毕 */
}
}
void uart_puts(char *s)
{
while (*s)
{
uart_send(*s );
}
}
void uart_puts_hex32_no_nl(char *s, unsigned long val)
{
uart_puts(s);
uart_hex32(val);
}
void uart_puts_hex32(char *s,unsigned long val)
{
uart_puts_hex32_no_nl(s,val);
uart_puts("\r\n");
}
void uart_nibble(int val)
{
val &= 0xf;
if (val > 9)
uart_send('A' val-10);
else
uart_send(val '0');
}
void uart_hex(int val)
{
uart_nibble(val >> 4);
uart_nibble(val);
}
void uart_hex32(long val)
{
int i;
for (i=24;i>=0;i-=8)
{
uart_hex(val >> i);
}
}
void TIMER16_0_IRQHandler (void)
{
TMR16B0IR = 0x01; /* 清除中断标志 */
systemtime ;
}
void Timer16B0Init (void)
{
SYSAHBCLKCTRL |= (1 << 7); /* 打开定时器模块 */
TMR16B0IR = 1;
TMR16B0PR = 1000; /* 设置分频系数 */
TMR16B0MCR = 3; /* 设置MR0匹配后复位TC并产生中断*/
TMR16B0MR0 = FAHBCLK/1000; /* 设置中断时间0.1S */
/* 16位定时器计数最大值65535 */
TMR16B0TCR = 0x01; /* 启动定时器 */
zyIsrSet(NVIC_TIMER16B0, (unsigned long)TIMER16_0_IRQHandler, 3); /* 设置中断并使能 */
}
//part 2 -------------serial flash read/write
// ########################################################################
// ## 初始化
// ########################################################################
void SF_Init(void)
{
SYSAHBCLKCTRL |= (1 << 16); /* 配置IOCON模块时钟 */
IOCON_PIO0_7 &= ~0x07; /* 初始化SPI0引脚 */
GPIO0DIR |= SPI_CS;
IOCON_PIO0_6 |= 0x02;
IOCON_PIO0_8 |= 0x01;
IOCON_PIO0_9 |= 0x01;
PRESETCTRL |= 0x01; /* 禁止SPI0复位 */
IOCON_SCKLOC = 0x02; /* P0.6配置为SCK */
SYSAHBCLKCTRL |= (1 << 11); /* 打开SPI0外设 */
SSP0CLKDIV = 0x01; /* SSP时钟分频 */
SSP0CR0 = (0x01 << 8) | /* SCR 设置SPI时钟分频 */
(0x00 << 7) | /* CPHA 时钟输出相位, */
/* 仅SPI模式有效 */
(0x00 << 6) | /* CPOL 时钟输出极性, */
/* 仅SPI模式有效 */
(0x00 << 4) | /* FRF 帧格式 00=SPI,01=SSI, */
/* 10=Microwire,11=保留 */
(0x07 << 0); /* DSS 数据长度,0000-0010=保留,*/
/* 0011=4位,0111=8位,1111=16位 */
SSP0CR1 = (0x00 << 3) | /* SOD 从机输出禁能,1=禁止 */
(0x00 << 2) | /* MS 主从选择,0=主机,1=从机 */
(0x01 << 1) | /* SSE SSP使能 */
(0x00 << 0); /* LBM 回写模式 */
SSP0CPSR = 2; /* PCLK分频值 */
SSP0ICR = 0x03; /* 中断清除寄存器 */
}
// ########################################################################
// ## 允许芯片读写串行flash
// ########################################################################
void SF_CS_ENABLE(void)
{
CE_Low();
}
// ########################################################################
// ## 禁止芯片读写flash
// ########################################################################
void SF_CS_DISABLE(void)
{
CE_High();
}
/*********************************************************************************************************
** 函数名称: Send_Byte
** 函数功能:通过硬件SPI发送一个字节到MX25L1602
** 输入参数: data
** 输出参数: 无
** 返 回 值:无
*********************************************************************************************************/
void Send_Byte (INT8U data)
{
SSP0DR = data;
while( (SSP0SR & 0x10) == 0x10); /* 等待TFE置位,即发送FIFO空 */
data = SSP0DR;
}
/*********************************************************************************************************
** 函数名称:Get_Byte
** 函数功能:通过硬件SPI接口接收一个字节到处理器
** 输入参数:无
** 输出参数:无
*********************************************************************************************************/
INT8U Get_Byte (void)
{
SSP0DR = 0xFF; /* 发送该数据用以产生时钟 */
while ( 0 == (SSP0SR & 0x01)); /* 等待数据发送完毕 */
/*
* 判断当前是否空闲(是否处于TX Or RX)
*/
while( SSP0SR & (1 << 4));
/*
* 判断是否已接收到数据,必须判断是否接收完成,否则
* 新的TX发送再次写入LPC_SSP0->DR寄存器
*/
while( SSP0SR & (1 << 2) == 0x00);
return (INT8U)(SSP0DR); /* 返回接收到的数据 */
}
// ########################################################################
// ## 从串行flash 中发送或接收一个字符
// ########################################################################
unsigned char SF_SpiTransfer(unsigned char data,unsigned char flag)
{
if(flag==1) //读
{
SSP0DR = 0xFF; /* 发送该数据用以产生时钟 */
while ( 0 == (SSP0SR & 0x01)); /* 等待数据发送完毕 */
/*
* 判断当前是否空闲(是否处于TX Or RX)
*/
while( SSP0SR & (1 << 4));
/*
* 判断是否已接收到数据,必须判断是否接收完成,否则
* 新的TX发送再次写入LPC_SSP0->DR寄存器
*/
while( SSP0SR & (1 << 2) == 0x00);
return (INT8U)(SSP0DR); /* 返回接收到的数据 */
}
else //写
{
SSP0DR = data;
while( (SSP0SR & 0x10) == 0x10); /* 等待TFE置位,即发送FIFO空 */
return (INT8U)(SSP0DR);
}
}
// ########################################################################
// ## 等待串行flash 可读
// ########################################################################
void SF_WaitSpiReady(void)
{
char sr; // SPI memory status register
for (;;)
{
SF_CS_ENABLE(); // Pull down the chip select line of the SPI serial memory
SF_SpiTransfer(READ_STATUS_REGISTER,0);
//--------------------------------------------------------------
// get the status register value, send the value 0xFF to avoid
// toggle on the MOSI line
//--------------------------------------------------------------
sr = SF_SpiTransfer(0xFF,1);
SF_CS_DISABLE(); // Pull high the chip select line of the SPI serial memory
if (!(sr & 1))
return;
}
}
// ########################################################################
// ## 发送一个32位地址到串行flash (有效19位 寻址512K)
// ########################################################################
void SF_SendAddr(unsigned long addr)
{
SF_SpiTransfer((char)(addr>>16),0); // transmit the most significant address byte
SF_SpiTransfer((char)(addr>>8),0); // transmit the middle address byte
SF_SpiTransfer((char)(addr),0); // transmit the less significant address byte
}
// ########################################################################
// ## 从flash中读取一个块指令(读开始)
// ########################################################################
void SF_ReadFlashBegin(unsigned long addr)
{
SF_WaitSpiReady();
SF_CS_ENABLE(); // Pull down the chip select line of the SPI serial memory
SF_SpiTransfer(READ,0); //transmitt the op_code READ
SF_SendAddr(addr);
}
// ########################################################################
// ## 写数据命令
// ########################################################################
void SF_WriteCommand(void)
{
SF_WaitSpiReady();
SF_CS_ENABLE(); // Pull down the chip select line of the SPI serial memory
SF_SpiTransfer(WREN,0); // transmitt the op_code
SF_CS_DISABLE(); // Pull high the chip select line of the SPI serial memory
}
// ########################################################################
// ## 擦除flash的64K字节
// ########################################################################
void SF_EraseSector(unsigned long addr)
{
SF_WriteCommand(); // always perform a WREN command before any write operation
SF_WaitSpiReady();
SF_CS_ENABLE(); // Pull down the chip select line of the SPI serial memory
SF_SpiTransfer(SECTOR_ERASE,0); // transmit the SECTOR_ERASE op_code
SF_SendAddr(addr);
SF_CS_DISABLE(); // Pull high the chip select line of the SPI serial memory
}
// ########################################################################
// ## 写flash
// ## 入口:
// ## addr = 要写入的flash起始地址 ##
// ## count = 写入的字节数 ##
// ## ptr = 写入的数据(指针) ##
// ## dir = 指针的操作方向, -1 或 1 ##
// ########################################################################
void SF_PutChars(unsigned long addr, unsigned int count, unsigned char *ptr, char dir, char auto_erase)
{
int pg;
pg=256;
while (count--)
{
if ( pg >= 256)
{
SF_CS_DISABLE();
if (auto_erase && ((addr & 0xfff)==0))
{ SF_EraseSector(addr);
// uart_puts_hex32(" addr1=",addr);
}
SF_WriteCommand(); // always perform a WREN command before any write operation
SF_WaitSpiReady();
SF_CS_ENABLE(); // Pull down the chip select line of the SPI serial memory
SF_SpiTransfer(PROGRAM,0);// transmitt the op_code WRITE
SF_SendAddr(addr);
pg=addr & 0xff; // Compute the number of bytes left in this page.
}
SF_SpiTransfer(*ptr,0);
ptr =dir;
addr ;
}
SF_CS_DISABLE(); // Pull high the chip select line of the SPI serial memory
}
// ########################################################################
// ## 从flash 中读取32位数据
// ########################################################################
unsigned long flash_long(void)
{
signed char j;
unsigned long data;
data=0;
for (j=24;j>=0;j-=8)
{
data |= (unsigned long) SF_SpiTransfer(0xff,1) << j;
}
return(data);
}
//part 3 ------------ MII
// ########################################################################
// ## 初始化
// ########################################################################
void setup_MDIO1ClockOut16Bit(void)
{
mdio[0]=MDIO1_PORT & ~(MDIO1|MDC1);
mdio[1]=mdio[0] | MDC1;
mdio[2]=mdio[0] | MDIO1;
mdio[3]=mdio[1] | mdio[2];
}
void setup_MDIO2ClockOut16Bit(void)
{
mdio[0]=MDIO2_PORT & ~(MDIO2|MDC2);
mdio[1]=mdio[0] | MDC2;
mdio[2]=mdio[0] | MDIO2;
mdio[3]=mdio[1] | mdio[2];
}
// ########################################################################
// ## MDIO1ClockOut8Bit - send 8 bits to MDIO bus ##
// ## 发送一个8位的数据到MDIO总线上
// ########################################################################
void MDIO1ClockOut8Bit(unsigned char val)
{
unsigned char i;
for(i=0;i<8;i )
{
if(val&0x80)
{
MDIO1_PORT=mdio[2];
MDIO1_PORT=mdio[3];
}
else
{
MDIO1_PORT=mdio[0];
MDIO1_PORT=mdio[1];
}
val<<=1;
}
}
void MDIO2ClockOut8Bit(unsigned char val)
{
unsigned char i;
for(i=0;i<8;i )
{
if(val&0x80)
{
MDIO2_PORT=mdio[2];
MDIO2_PORT=mdio[3];
}
else
{
MDIO2_PORT=mdio[0];
MDIO2_PORT=mdio[1];
}
val<<=1;
}
}
// ########################################################################
// ## MDIOClockOut16Bit - Write 16 bits to the MDIO bus ##
// ## 发送16位数据到MDIO总线上
// ########################################################################
void MDIO1ClockOut16Bit(unsigned int info)
{
MDIO1ClockOut8Bit(info >> 8);
MDIO1ClockOut8Bit(info);
}
void MDIO2ClockOut16Bit(unsigned int info)
{
MDIO2ClockOut8Bit(info >> 8);
MDIO2ClockOut8Bit(info);
}
// ########################################################################
// ## MDIOClockOutPreamble - send the 32 bit preamble to the MDIO bus ##
// ## 发送32位前导码到MDIO总线上
// ########################################################################
void MDIO1ClockOutPreamble(void)
{
unsigned long m2, m3;
unsigned char ct;
m2 = mdio[2];
m3 = mdio[3];
for (ct=0;ct<8/*32/4*/;ct )
{
MDIO1_PORT=m2;
MDIO1_PORT=m3;
MDIO1_PORT=m2;
MDIO1_PORT=m3;
MDIO1_PORT=m2;
MDIO1_PORT=m3;
MDIO1_PORT=m2;
MDIO1_PORT=m3;
}
}
void MDIO2ClockOutPreamble(void)
{
unsigned long m2, m3;
unsigned char ct;
m2 = mdio[2];
m3 = mdio[3];
for (ct=0;ct<8/*32/4*/;ct )
{
MDIO2_PORT=m2;
MDIO2_PORT=m3;
MDIO2_PORT=m2;
MDIO2_PORT=m3;
MDIO2_PORT=m2;
MDIO2_PORT=m3;
MDIO2_PORT=m2;
MDIO2_PORT=m3;
}
}
// ########################################################################
// ## MDIO1ClockIn16Bit - read 16 bits from the mdio bus ##
// ## 从MDIO总线上读取16位字节
// ########################################################################
unsigned int MDIO1ClockIn16Bit(void)
{
int mdio_val;
int bit;
int rc;
mdio_val=MDIO1_PORT & ~(MDIO1| MDC1);
rc=0;
MDIO1_IN_E();
for (bit=15;bit>=0;--bit)
{
MDIO1_PORT=mdio_val | MDIO1;
if (MDIO1_PORT & MDIO1)
rc=(rc << 1) | 1;
else
rc=(rc << 1) | 0;
MDIO1_PORT=mdio_val | MDIO1| MDC1;
}
MDIO1_OUT_E();
MDIO1_PORT=mdio_val | MDIO1 | MDC1;
MDIO1_PORT=mdio_val | MDIO1 | MDC1;
MDIO1_PORT=mdio_val | MDIO1 | MDC1;
MDIO1_PORT=mdio_val | MDIO1 | MDC1;
return(rc);
}
unsigned int MDIO2ClockIn16Bit(void)
{
int mdio_val;
int bit;
int rc;
mdio_val=MDIO2_PORT & ~(MDIO2| MDC2);
rc=0;
MDIO2_IN_E();
for (bit=15;bit>=0;--bit)
{
MDIO2_PORT=mdio_val | MDIO2;
if (MDIO2_PORT & MDIO2)
rc=(rc << 1) | 1;
else
rc=(rc << 1) | 0;
MDIO2_PORT=mdio_val | MDIO2| MDC2;
}
MDIO2_OUT_E();
MDIO2_PORT=mdio_val | MDIO2 | MDC2;
MDIO2_PORT=mdio_val | MDIO2 | MDC2;
MDIO2_PORT=mdio_val | MDIO2 | MDC2;
MDIO2_PORT=mdio_val | MDIO2 | MDC2;
return(rc);
}
// ########################################################################
// ## ClinkReadMDIOData - read one of the PHY registers on EN2210 ##
// ## 读取EN2210的一个寄存器数据
// ## EN2210所有的信息全部是通过MDIO 总线访问最后的5个PHY寄存器。
// ## 为了访问这5个寄存器,这个程序按照常规发送"read"请求,
// ## 并发送访问的寄存器地址,然后从EN2210中读取16位数据。
// ## 这样允许访问EN2210中的任何寄存器。
// ## 入口:reg_addr 。这个重要的寄存器地址是 : 0x1b ~0x1f
// ########################################################################
unsigned int ClinkReadMDIOData(int reg_addr)
{
setup_MDIO1ClockOut16Bit();
MDIO1ClockOutPreamble();
MDIO1ClockOut16Bit((MDIO_READ_MASK_HI << 8) | MDIO_READ_MASK_LO(reg_addr));
return(MDIO1ClockIn16Bit());
}
// ########################################################################
// ## ClinkWriteMDIOData - write value to the EN2210 MDIO interface ##
// ## 把16位数据写入EN2210的MDIO接口,下面是5个寄存器的映射
// ## Register Meaning
// ## ---------- --------------------------------------------- ##
// ## 0x1b Write control / status register ##
// ## 0x1c 1/2 of 32 bit address latch (high) ##
// ## 0x1d 1/2 of 32 bit address latch (low) ##
// ## 0x1e 1/2 of 32 bit data latch (high) ##
// ## 0x1f 1/2 of 32 bit data latch (low) ##
// ########################################################################
void ClinkWriteMDIOData(int reg_addr,unsigned val)
{
setup_MDIO1ClockOut16Bit();
MDIO1ClockOutPreamble();
MDIO1ClockOut16Bit((MDIO_WRITE_MASK_HI << 8) | MDIO_WRITE_MASK_LO(reg_addr));
MDIO1ClockOut16Bit(val);
}
// ########################################################################
// ## PHY_operation - Raw MDIO bus read or write ##
// ## 这是一个通用的MDIO总线读写程序,
// ## 允许我们读写任何器件的任何寄存器。
// ## 入口:
// ## operation: PHY_READ | PHY_WRITE
// ## phy: EN2210设置为1,其他为2
// ## addr: 寄存器地址
// ## val: 数值
// ########################################################################
unsigned int PHY_operation(int operation,int phy, int addr,unsigned int val)
{
setup_MDIO2ClockOut16Bit();
MDIO2ClockOutPreamble();
MDIO2ClockOut16Bit(operation | (MDIO_START_BITS << 8) | (phy << 7) | (addr << 2));
if (operation == PHY_READ)
return(MDIO2ClockIn16Bit());
else
MDIO2ClockOut16Bit(val);
return(val);
}
// ########################################################################
// ## ClinkWaitMDIOReady - wait for SoC bus to say idle ##
// ## 检测EN2210是否空闲,
// ########################################################################
void ClinkWaitMDIOReady(void)
{
unsigned int rc;
for (;;)
{ // If there is problem in SoC, Watchdog interrupt will reset me !!!
rc=ClinkReadMDIOData(ADDRESS_MODE);
if ((rc & 0xff) == 0)
return;
if (rc & CLINK_BUSY)
{
uart_puts("CLINK_BUSY\r\n");
bootup();
}
if (rc & CLINK_ERROR)
{
uart_puts("CLINK_ERROR\r\n");
bootup();
}
return;
}
}
unsigned long ClinkReadFrom(unsigned long addr)
{
unsigned long data;
ClinkWaitMDIOReady();
ClinkWriteMDIOData(ADDRESS_HIGH, addr >> 16);
ClinkWriteMDIOData(ADDRESS_LOW, addr);
ClinkWriteMDIOData(ADDRESS_MODE, CLINK_START_READ);
ClinkWaitMDIOReady();
data=ClinkReadMDIOData(DATA_HIGH);
data = data << 16;
data |= ClinkReadMDIOData(DATA_LOW);
return data;
}
void ClinkWriteTo(unsigned long addr, unsigned long data)
{
ClinkWaitMDIOReady();
ClinkWriteMDIOData(ADDRESS_HIGH, addr >> 16);
ClinkWriteMDIOData(ADDRESS_LOW, addr);
ClinkWriteMDIOData(DATA_HIGH, data >> 16);
ClinkWriteMDIOData(DATA_LOW, data);
ClinkWriteMDIOData(ADDRESS_MODE, CLINK_START_WRITE);
}
// ########################################################################
// ## Turbo_open - Setup the system for turbo download ##
// ## 这个函数用于Turbo模式的开始,用于下载image,那时地址自动增加。
// ## 低地址发送两次是为了兼容之前的版本中出现的bug
// ########################################################################
void Turbo_open(unsigned long addr)
{
ClinkWaitMDIOReady();
ClinkWriteMDIOData(ADDRESS_HIGH, addr >> 16);
ClinkWriteMDIOData(ADDRESS_LOW, addr);
ClinkWriteMDIOData(ADDRESS_LOW, addr);
}
void Turbo_write(unsigned long data)
{
ClinkWriteMDIOData(DATA_HIGH, data >> 16);
ClinkWriteMDIOData(DATA_LOW, data);
ClinkWriteMDIOData(ADDRESS_MODE, CLINK_START_WRITE | CLINK_AUTO_INC);
}
void Turbo_close(void)
{
ClinkWriteMDIOData(ADDRESS_MODE, 0);
}
// ########################################################################
//zxf
unsigned long crctab32[128] =
{
0x0,
0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6,
0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC,
0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F,
0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A,
0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58,
0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033,
0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE,
0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4,
0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5,
0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07,
0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C,
0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1,
0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B,
0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698,
0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D,
0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F,
0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
0xDC3ABDED, 0xD8FBA05A
};
unsigned long compute_crc(unsigned char *databuf,unsigned long len,unsigned char flag)
{
unsigned char val;
unsigned long i;
unsigned long crc=0;
unsigned char ix;
for (i=0;i<len;i )
{
if(flag==0)
val=databuf[i];
else
val=SF_SpiTransfer(0xFF,1);
ix=(unsigned int) (crc >> 24) ^ val;
if ((ix & 0xc0) == 0x80)
{
crc = (crc << 8) ^ ((crctab32[ix>>1]) << 1) ^ (crctab32[ix & 1]);
}
else if ((ix & 0xc0) == 0xc0)
{
crc = (crc << 8) ^ ((crctab32[ix>>1]) << 1) ^ (crctab32[~ix & 1]);
}
else
crc = (crc << 8) ^ (crctab32[ix]);
}
return(crc);
}
unsigned char crc_check (unsigned char *databuf,unsigned long len,unsigned long *crc,unsigned char flag)
{
unsigned long crc1;
*crc=compute_crc(databuf,len-4,flag);
if(flag==0)
{
crc1=databuf[len-4];crc1<<=8;
crc1 =databuf[len-3];crc1<<=8;
crc1 =databuf[len-2];crc1<<=8;
crc1 =databuf[len-1];
}
else
{
crc1=SF_SpiTransfer(0xFF,1);crc1<<=8;
crc1 =SF_SpiTransfer(0xFF,1);crc1<<=8;
crc1 =SF_SpiTransfer(0xFF,1);crc1<<=8;
crc1 =SF_SpiTransfer(0xFF,1);
}
// uart_puts_hex32("crc_c=",*crc);
// uart_puts_hex32("crc_r=",crc1);
if(crc1==0)
return 0;
if(crc1==*crc)
return 1;
else
return 0;
}
// ########################################################################
void fetch_data_and_override(unsigned long info[])
{
char i;
char *info_fill;
info_fill=(char *)(&info[3]);
for(i=0;i<4;i ,info_fill )
*info_fill=SF_SpiTransfer(0xff,1);
}
void locate(char *name,unsigned long *info,unsigned char LocateFile_flag)
{
unsigned char temp,i;
unsigned char *info_fill;
info[2]=SF_SpiTransfer(0xff,1); //读取类型
temp=SF_SpiTransfer(0xff,1);
i=0;
if(LocateFile_flag==1)
info[2]=1; //
while((temp!=0x00)&&(i<50)) //判断是否为0,如果为0,取文件名
{
if(LocateFile_flag==1)
{
if(name[i]!=temp)info[2]=0;
}
else
{
name[i]=temp;
name[i 1]='\0';
}
i ;
temp=SF_SpiTransfer(0xff,1);
}
//取数据,地址低字节
info_fill=(unsigned char *)(&info[1]);
for(i=0;i<4;i ,info_fill )
*info_fill=SF_SpiTransfer(0xff,1);
//取长度,地址低字节
info_fill=(unsigned char *)(&info[0]);
for(i=0;i<4;i ,info_fill )
*info_fill=SF_SpiTransfer(0xff,1);
}
void ClinkDownloadFirmware(unsigned long clinkAddr, unsigned long len)
{
unsigned long data;
Turbo_open(clinkAddr);
while (len)
{
data=flash_long();
Turbo_write(data);
len-=4;
}
Turbo_close();
}
//下载配置文件和image
unsigned char ClinkProcessRecord(void)
{
char name[30];
unsigned long i;
unsigned long info[4];
locate(name,info,0);
info[3]=0;
switch (info[2])
{
case TP_FILE:
if (info[1])
ClinkDownloadFirmware(info[1],info[0]);
else
{
for (i=0;i<info[0];i )
SF_SpiTransfer(0xff,1);
}
break;
case TP_CONFIGURE:
fetch_data_and_override(info);
if(strcmp(name,"CSC_CLK_CTL0")==0)
// uart_puts_hex32_no_nl(" CSC_CLK_CTL0= ",info[3]);
info[3]=0x0B000000;
if(strcmp(name,"GPHY_ENH_CTRL")==0)
// uart_puts_hex32_no_nl(" GPHY_ENH_CTRL= ",info[3]);
info[3]=0x0201;
ClinkWriteTo(info[1],info[3]);
break;
case TP_UPDATE:
fetch_data_and_override(info);
ClinkWriteTo(info[1],info[3]=ClinkReadFrom(info[1]) |info[3]);
break;
case TP_INDIRECT:
fetch_data_and_override(info);
info[3]=ClinkReadFrom( info[3]);
ClinkWriteTo(info[1], info[3]);
break;
case TP_END:
case TP_PAUSE:
break;
default:
uart_puts("ERROR\r\n");
return('e');
}
/*
uart_puts(name);
uart_puts_hex32_no_nl(" = ",info[3]);
uart_puts("\r\n");
*/
return((unsigned char)info[2]);
}
#define ANY_NODE_ID 0x99
void retrieve_reply(void)
{
unsigned long data;
SoC_watchdog=0x4242;
data=ClinkReadFrom(HOST_MAILBOX_INCOMMING);
if((data&0xff)==0x85)
{
if((data&0xff00)!=0)
bootup();
}
else if((data&0xff)==ANY_NODE_ID)
{
data=ClinkReadFrom(0x0c00b8dc);
if((Currently_LOF!=data)&&(data!=0))
{
uart_puts_hex32("Lof = ",data);
Currently_LOF=data;
Eeprom_buf[7]=((data>>24)&0xff);
Eeprom_buf[8]=((data>>16)&0xff);
Eeprom_buf[9]=((data>>8)&0xff);
Eeprom_buf[10]=((data)&0xff);
eeprom_write();
}
}
ClinkWriteTo(READ_CSR_REG,ClinkReadFrom(READ_CSR_REG) & 0x7fffffff);
return;
}
void send_request(void)
{
ClinkReadFrom(WRITE_CSR_REG);
if((ClinkReadFrom(WRITE_CSR_REG) & 0x80000000)==0)
{
if(lof_read_req!=0)
{
lof_read_req=0;
ClinkWriteTo(HOST_MAILBOX_OUTGOING,((unsigned long ) ANY_NODE_ID << 8) | CLNK_MBX_ETH_DATA_BUF_CMD);
ClinkWriteTo(HOST_MAILBOX_OUTGOING 4,DATA_BUF_MY_NODE_INFO_CMD_TYPE);
}
else
{
ClinkWriteTo(HOST_MAILBOX_OUTGOING,((unsigned long ) ANY_NODE_ID << 8) | CLNK_MBX_ETH_GET_STATUS_CMD);
}
}
ClinkWriteTo(WRITE_CSR_REG,ClinkReadFrom(WRITE_CSR_REG) | 0x80000000);
}
void update_scan(void)
{
unsigned long data,i;
unsigned long clinkadd;
unsigned long position;
unsigned char update_info[272];
SwitchSetStruct *SwitchSetbuf;
SwitchGetStruct *SwitchGetbuf;
clinkadd=update_ln_buf;
while(clinkadd<update_ln_end)
{
data=ClinkReadFrom(clinkadd);
if((data&0xffffff00)==0x476f6f00) //=Goo
{
clinkadd =(data&0xff)*4;
position=ClinkReadFrom(clinkadd); //position
update_info[0]=(unsigned char)((position>>24)&0xff);
update_info[1]=(unsigned char)((position>>16)&0xff);
update_info[2]=(unsigned char)((position>>8)&0xff);
update_info[3]=(unsigned char)((position)&0xff);
if(position!=lst_update_sig)
{
lst_update_sig=position;
for(i=0;i<67;i )
{
clinkadd =4;
data=ClinkReadFrom(clinkadd); //info
update_info[i*4 4]=(unsigned char)((data>>24)&0xff);
update_info[i*4 5]=(unsigned char)((data>>16)&0xff);
update_info[i*4 6]=(unsigned char)((data>>8)&0xff);
update_info[i*4 7]=(unsigned char)((data)&0xff);
}
clinkadd =4;
i=ClinkReadFrom(clinkadd); //block_checksum
if((position&0xff)>0)
data=compute_crc(update_info,272,0);
else
data=i;
if(i==data)
{
if(((update_info[264]==Eeprom_buf[1])&&(update_info[265]==Eeprom_buf[2])&&(update_info[266]==Eeprom_buf[3])
&&(update_info[267]==Eeprom_buf[4])&&(update_info[268]==Eeprom_buf[5])&&(update_info[269]==Eeprom_buf[6]))||
((update_info[264]==0xff)&&(update_info[265]==0xff)&&(update_info[266]==0xff)
&&(update_info[267]==0xff)&&(update_info[268]==0xff)&&(update_info[269]==0xff)))
{
switch(position&0xff)
{
case 0: //update
clinkadd=(position&0x0000ff00) (unsigned char)(position>>16)-0x0400;
if(clinkadd==0)
update_flash_flag=1;
if(update_flash_flag==1)
{
SF_PutChars(clinkadd*256,256,update_info 8,1,1);
uart_puts_hex32("add=",clinkadd);
if(clinkadd==0x3ef)
{
SF_ReadFlashBegin(0x0);
if(crc_check(update_info,0x3f000,&data,1)==1)
{
SF_ReadFlashBegin(0x40000 0x3effc);
clinkadd=SF_SpiTransfer(0xFF,1);clinkadd<<=8;
clinkadd =SF_SpiTransfer(0xFF,1);clinkadd<<=8;
clinkadd =SF_SpiTransfer(0xFF,1);clinkadd<<=8;
clinkadd =SF_SpiTransfer(0xFF,1);
if(data==clinkadd)
uart_puts("update seccess,same!\r\n");
else
{
uart_puts("update seccess,reboot!\r\n");
bootup();
}
}
else
update_flash_flag=0;
}
}
break;
case 1: //EEPROM
// uart_puts_hex32(" EEPROM=",position);
break;
case 2: //reset
bootup();
break;
case 3: //交换机控制
switch(update_info[8])
{
// set
case 0xf1:
case 0xf2:
case 0xf3:
case 0xf4:
i=update_info[8]-0xf1;
if(Eeprom_buf[12]==2)i =2;
memcpy(Eeprom_buf 32 i*32,update_info 10,32);
vlan_entry_clean();
Switch_Set(0);
Switch_Set(1);
Switch_Set(2);
Switch_Set(3);
eeprom_write();
break;
// get
case 0x01:
SwitchGetbuf=&SwitchGetData[0];
data=update_info[8];data<<=8;
data =Eeprom_buf[12];data<<=8;
data =SwitchType;data<<=8;
ClinkWriteTo(NumOfRsrvRx,data);
ClinkWriteTo(NumOfMapTx,SwitchGetbuf->rxTraffic); // 下行流量
ClinkWriteTo(NumOfRsrvRxErr,SwitchGetbuf->txTraffic); // 上行流量
ClinkWriteTo(NumOfMapTxErr,SwitchGetbuf->rxDropPacketCount); //下行丢包
ClinkWriteTo(NumOfRsrvRxDropped,SwitchGetbuf->rxErrorPacketCount); //下行错包
break;
case 0x02:
case 0x04:
case 0x06:
case 0x08:
i=(update_info[8]-0x02)/2;
if(Eeprom_buf[12]==2)i =2;
SwitchSetbuf=(SwitchSetStruct*)(&Eeprom_buf[32 i*32]);
data=update_info[8];data<<=8;
data =SwitchSetbuf->portModelControl;data<<=8;
data =SwitchSetbuf->broadcastProtectionEnable;data<<=8;
data =SwitchSetbuf->flowControlEnable;
ClinkWriteTo(NumOfRsrvRx,data);
data=SwitchSetbuf->vlanID[0];data<<=8;
data =SwitchSetbuf->vlanID[1];
data<<=8;
data =SwitchSetbuf->priorityGrade;data<<=8;
data =SwitchSetbuf->portEnable;
ClinkWriteTo(NumOfMapTx,data);
data=SwitchSetbuf->downstreamRateControl[0];data<<=8;
data =SwitchSetbuf->downstreamRateControl[1];data<<=8;
data =SwitchSetbuf->downstreamRateControl[2];data<<=8;
data =SwitchSetbuf->downstreamRateControl[3];
ClinkWriteTo(NumOfRsrvRxErr,data);
data=SwitchSetbuf->upstreamRateControl[0];data<<=8;
data =SwitchSetbuf->upstreamRateControl[1];data<<=8;
data =SwitchSetbuf->upstreamRateControl[2];data<<=8;
data =SwitchSetbuf->upstreamRateControl[3];
ClinkWriteTo(NumOfMapTxErr,data);
data=SwitchSetbuf->autoConfigStatus;data<<=8;
data =SwitchSetbuf->portMACLimit;data<<=8;
data<<=8;
ClinkWriteTo(NumOfRsrvRxDropped,data);
break;
case 0x03:
case 0x05:
case 0x07:
case 0x09:
i=(update_info[8]-0x03)/2;
if(Eeprom_buf[12]==2)i =2;
SwitchGetbuf=&SwitchGetData[i];
data=update_info[8];data<<=8;
data =(SwitchGetbuf->portLinkStatus)&0xff;data<<=8;
data =(SwitchGetbuf->portModelStatus)&0xff;data<<=8;
ClinkWriteTo(NumOfRsrvRx,data);
ClinkWriteTo(NumOfMapTx,SwitchGetbuf->txTraffic); // 下行流量
ClinkWriteTo(NumOfRsrvRxErr,SwitchGetbuf->rxTraffic); // 上行流量
ClinkWriteTo(NumOfMapTxErr,SwitchGetbuf->rxDropPacketCount); //上行丢包
ClinkWriteTo(NumOfRsrvRxDropped,SwitchGetbuf->rxErrorPacketCount); //上行错包
break;
default:
break;
}
break;
default:
break;
}
}
}
return;
}
}
else
clinkadd =1016;
}
}
INT8U hex_nibble(INT8U val)
{
if ('A' <= val && val <='F')
return(val - 'A' 10);
if ('a' <= val && val <='f')
return(val - 'a' 10);
if ('0' <= val && val <='9')
return(val - '0');
return 0;
}
//00 12 d6 22 02 29
//30 30 31 32 44 36 32 32 30 32 32 39 0D
INT8U resetflag=0;
INT32U resettime=0;
void console(void)
{
INT8U ch,i;
INT32U maxresettime;
if (GPIO3DATA & RESET_IN)
{
if((resettime>40)&&(resettime<=400)) //10s
{
ClinkWriteTo(CLNK_REG_CPU_RESET,1);
bootup();
}
else
resettime=0;
}
else
{
resettime ;
if(link_stat==0)
maxresettime=2000;
else
maxresettime=15000;
if(resettime>maxresettime)
{
uart_puts("Reset sw\r\n");
Switch_Data_Init();
Eeprom_buf[7]=0x3b;Eeprom_buf[8]=0x9a;
Eeprom_buf[9]=0xca;Eeprom_buf[10]=0x00;
eeprom_write();
SW_OUT_0(); //复位交换机和clink
myDelay(50);
SW_OUT_1();
ClinkWriteTo(CLNK_REG_CPU_RESET,1);
bootup();
}
}
if((U0LSR & 0x01)==0) /* 等待接收标志置位 */
return;
else
{
ch=U0RBR;
UartReceiveBuf[UartReceiveLen]=ch;
if((UartReceiveLen==0)||(UartReceiveLen==1))
{
if(ch==0x30)
UartReceiveLen ;
else
UartReceiveLen=0;
}
else if(UartReceiveLen==2)
{
if(ch==0x31)
UartReceiveLen ;
else
UartReceiveLen=0;
}
else if(UartReceiveLen==3)
{
if(ch==0x32)
UartReceiveLen ;
else
UartReceiveLen=0;
}
else
UartReceiveLen ;
if(UartReceiveLen==13)
{
UartReceiveLen=0;
if(((UartReceiveBuf[4]==0x44)||(UartReceiveBuf[4]==0x64))&&(UartReceiveBuf[5]==0x36))
{
Eeprom_buf[4]=(hex_nibble(UartReceiveBuf[6])<<4) hex_nibble(UartReceiveBuf[7]);
Eeprom_buf[5]=(hex_nibble(UartReceiveBuf[8])<<4) hex_nibble(UartReceiveBuf[9]);
Eeprom_buf[6]=(hex_nibble(UartReceiveBuf[10])<<4) hex_nibble(UartReceiveBuf[11]);
if((Eeprom_buf[4]>0x20)&&((Eeprom_buf[4]-0x20)%2==0))
Eeprom_buf[12]=4;
else
Eeprom_buf[12]=2;
uart_puts(" -------MAC------- P\r\n");
for (i=1;i<7;i )
{
uart_hex(Eeprom_buf[i]);
uart_puts(" ");
}
uart_hex(Eeprom_buf[12]);
uart_puts("\r\n");
eeprom_write();
bootup();
}
}
//00 00 12 D6 21 11 22 3B 9A CA 00 00 02
}
}
int main(void )
{
INT8S i;
INT32U j;
INT32U data,oldsystemtime=0;
INT8U last_record_type;
targetInit(); /* 初始化目标板,切勿删除 */
pinInit(); /* 引脚初始化 */
SYSAHBCLKCTRL |= (1 << 6);
uartInit ();
IO_Init();
SF_Init();
Timer16B0Init();
eeprom_read();
Switch_Init();
PLL_Reset_0();
ZIP_Reset_0();
uart_puts(Version);
PLL_Reset_1();
myDelay(1);
ZIP_Reset_1();
// uart_puts_hex32("0x0014 = ",SwRegisterRead(0x0014));
uart_puts("I -----MAC--------- ----LOF---- N\r\n");
for (i=0;i<13;i )
{
uart_hex(Eeprom_buf[i]);
uart_puts(" ");
}
uart_puts("\r\n");
if((Eeprom_buf[4]==0x22)&&(Eeprom_buf[5]==0x00)&&(Eeprom_buf[6]==0x01)) //MAC地址还未烧写
{
uart_puts("Input Address:\r\n");
LED_ON();
oldsystemtime=0;
while(oldsystemtime<2500000)
{
oldsystemtime ;
console();
}
}
else
{
LED_OFF();
}
UartReceiveLen=0;
if (ClinkReadMDIOData(0) == 0xffff)
{
uart_puts("PHY\r\n");
}
lst_update_sig=0xffffffff;
lof_read_req=0;
last_link_status=0;
SoC_watchdog=0x2a2a; // RESET_SOC_WATCHDOG();
//复位3230
ClinkWriteTo(EHI_SYS_RESET_SET,0xffffffff);
myDelay(50);
ClinkWriteTo(EHI_SYS_RESET_SET,0);
//######################################################################
// ## Hold and release the DIC so it can startup
//######################################################################
ClinkWriteTo(DIC_MISC_CTL_0,0);
ClinkReadFrom(DIC_MISC_CTL_0);
ClinkWriteTo(DIC_TC_CTL_0,0);
ClinkWriteTo(DIC_MISC_CTL_0,0x1f);
//----------------------------------------------------------------------
// Put the CPU into a hold state - hold reset
//----------------------------------------------------------------------
ClinkWriteTo(CLNK_REG_CPU_RESET,1);
//######################################################################
//## Download a the firmware code into the EN3230 now
//######################################################################
ClinkWaitMDIOReady(); // Is this really necessary? - should it be done earlier?
SF_ReadFlashBegin(frist_block_start host_begin);
uart_puts("Loading image...\r\n");
last_record_type=0;
while (last_record_type != TP_PAUSE && last_record_type != TP_END)
{
console();
last_record_type=ClinkProcessRecord();
}
data=0L;
for (i=1;i<5;i )
data=(data << 8) | Eeprom_buf[i];
ClinkWriteTo(MAC_ADDR_HI,data);
data=0L;
for (i=5;i<7;i )
data=(data << 8) | ((unsigned long ) Eeprom_buf[i] << 16);
ClinkWriteTo(MAC_ADDR_LO,data);
Currently_LOF=0L;
for (i=7;i<11;i )
Currently_LOF=(Currently_LOF << 8) |Eeprom_buf[i];
ClinkWriteTo(FS_CFG_LOF,Currently_LOF);
// ################################################################
//##Setup the FLOW control MAC address in the GPHY
//################################################################
data=0L;
for (i=1;i<5;i )
data=(data >>8) | ((unsigned long )Eeprom_buf[i]<<24);
ClinkWriteTo(GPHY_FLOW_MAC_HI,data);
data=0L;
for (i=5;i<7;i )
data=(data >>8) | ((unsigned long ) Eeprom_buf[i]<< 24);
ClinkWriteTo(GPHY_FLOW_MAC_LO,data);
last_record_type=0;
while (last_record_type != TP_PAUSE && last_record_type != TP_END)
{
console();
last_record_type=ClinkProcessRecord();
}
//######################################################################
//## Wait for CPU to come alive and respond to the "startup" request
//######################################################################
uart_puts("Waiting for link...\r\n");
j=0;
while (1)
{
console();
data=ClinkReadFrom(DEBUG_REG_0);
if(((data!=0x00)&&(data!=0x12))||(j > SOC_BOOT_TIMEOUT))
{
bootup();
}
if(ClinkReadFrom(MAILBOX_RET_UNSOL_MSGBUF)!=0)
break;
}
data=ClinkReadFrom(MAILBOX_RET_PD_ENTRIES) * 8;
ClinkWriteTo(DIC_D_PD_SIZE_0,data);
ClinkWriteTo(DIC_D_PD_SIZE_1,data);
ClinkWriteTo(DIC_D_PD_SIZE_2,data);
update_ln_buf=ClinkReadFrom(MAILBOX_RET_RX_DID);
update_ln_end=update_ln_buf 0x700;
for(j=0;j<256;j )
ClinkWriteTo(update_ln_end-(1 j)*4,0);
last_record_type=0;
while (last_record_type != TP_PAUSE && last_record_type != TP_END)
{
console();
last_record_type=ClinkProcessRecord();
}
SF_CS_DISABLE();
while(1)
{
console();
data=ClinkReadFrom(DIC_D_STATUS);
if((data&0xff)!=0)
{
ClinkWriteTo(DIC_D_STATUS,3);
break;
}
}
ClinkWriteTo(MAILBOX_RET_UNSOL_MSGBUF,0);
link_stat=1;
while (1)
{
if((oldsystemtime!=systemtime)&&((systemtime%5)==0))
{
get_switch_info();
oldsystemtime=systemtime;
}
data=ClinkReadFrom(READ_CSR_REG);
if(last_link_status!=(data & 0xff))
{
last_link_status=data & 0xff;
lof_read_req=last_link_status;
}
if (data & 0xff)
{
if (link_stat)
{
uart_puts("Link is up!\r\n");
set_LOF();
link_stat=0;
}
}
else
{
if(link_stat==0)
{
bootup();
}
}
if(SoC_watchdog==1)
bootup();
else
SoC_watchdog--;
if(data&0x80000000)
retrieve_reply();
send_request();
update_scan();
data=ClinkReadFrom(DEBUG_REG_0);
if(data!=0x12)
{
if(data==0x21)
uart_puts("Check bond opt!\r\n\r\n");
bootup();
}
console();
}
}
void set_LOF(void)
{
unsigned long lof;
lof=ClinkReadFrom(0x0c00ad9c);
if(lof!=Currently_LOF)
{
Eeprom_buf[7]=(lof>>24)&0xff;Eeprom_buf[8]=(lof>>16)&0xff;
Eeprom_buf[9]=(lof>>8)&0xff;Eeprom_buf[10]=lof&0xff;
eeprom_write();
}
}
void bootup(void)
{
AITCR = (0x05fa << 16) 4;
}
void eeprom_write(void)
{
unsigned long crc;
crc=compute_crc(Eeprom_buf,252,0);
Eeprom_buf[252]=((crc>>24)&0xff);
Eeprom_buf[253]=((crc>>16)&0xff);
Eeprom_buf[254]=((crc>>8)&0xff);
Eeprom_buf[255]=((crc)&0xff);
SF_PutChars(Eeprom_LoAdd,256,Eeprom_buf,1,1);
SF_PutChars(Eeprom_HiAdd,256,Eeprom_buf,1,1);
}
void eeprom_read(void)
{
unsigned char flag=0;
unsigned int i;
unsigned long crc1,crc2;
// 判断第二块flash是否有问题
SF_ReadFlashBegin(Eeprom_HiAdd);
for (i=0;i<256;i )
Eeprom_buf[i]=SF_SpiTransfer(0xff,1);
if(crc_check(Eeprom_buf,256,&crc2,0)==0)
flag=1;
// 判断第一块flash是否有问题
SF_ReadFlashBegin(Eeprom_LoAdd);
for (i=0;i<256;i )
Eeprom_buf[i]=SF_SpiTransfer(0xff,1);
if(crc_check(Eeprom_buf,256,&crc1,0)==1) //没有问题
{
if(flag==1)
SF_PutChars(Eeprom_HiAdd,256,Eeprom_buf,1,1);
return;
}
else // 有问题
{
if(flag==0)
{
SF_ReadFlashBegin(Eeprom_HiAdd);
for (i=0;i<256;i )
Eeprom_buf[i]=SF_SpiTransfer(0xff,1);
SF_PutChars(Eeprom_LoAdd,256,Eeprom_buf,1,1);
return;
}
}
uart_puts("Initializtion!\r\n");
// 初始化数据
Eeprom_buf[0]=0x00;
Eeprom_buf[1]=0x00;Eeprom_buf[2]=0x12;
Eeprom_buf[3]=0xd6;Eeprom_buf[4]=0x22;
Eeprom_buf[5]=0x00;Eeprom_buf[6]=0x01;
Eeprom_buf[7]=0x3b;Eeprom_buf[8]=0x9a;
Eeprom_buf[9]=0xca;Eeprom_buf[10]=0x00;
Eeprom_buf[11]=0;
Eeprom_buf[12]=4;
Switch_Data_Init();
crc1=compute_crc(Eeprom_buf,252,0);
Eeprom_buf[252]=((crc1>>24)&0xff);
Eeprom_buf[253]=((crc1>>16)&0xff);
Eeprom_buf[254]=((crc1>>8)&0xff);
Eeprom_buf[255]=((crc1)&0xff);
SF_PutChars(Eeprom_LoAdd,256,Eeprom_buf,1,1);
SF_PutChars(Eeprom_HiAdd,256,Eeprom_buf,1,1);
}
void Switch_Data_Init(void)
{
unsigned char i;
SwitchSetStruct *SwitchSetbuf;
// 交换机初始化
for(i=0;i<4;i )
{
SwitchSetbuf=(SwitchSetStruct*)(&Eeprom_buf[32 i*32]);
SwitchSetbuf->autoConfigStatus=1;
SwitchSetbuf->portModelControl=0;
SwitchSetbuf->vlanID[0]=0;
SwitchSetbuf->vlanID[1]=1;
SwitchSetbuf->priorityGrade=0;
SwitchSetbuf->portEnable=1;
SwitchSetbuf->broadcastProtectionEnable=1;
SwitchSetbuf->flowControlEnable=1;
SwitchSetbuf->downstreamRateControl[0]=0x00;
SwitchSetbuf->downstreamRateControl[1]=0x01;
SwitchSetbuf->downstreamRateControl[2]=0x86;
SwitchSetbuf->downstreamRateControl[3]=0xa0;
SwitchSetbuf->upstreamRateControl[0]=0x00;
SwitchSetbuf->upstreamRateControl[1]=0x01;
SwitchSetbuf->upstreamRateControl[2]=0x86;
SwitchSetbuf->upstreamRateControl[3]=0xa0;
SwitchSetbuf->portMACLimit=0;
SwitchSetbuf->resetMib=0;
}
}
void Switch_Init(void)
{
INT8U port;
uint32 regval;
rtk_priority_select_t priDec;
rtl8306e_qosSchPara_t sch_para;
SW_OUT_0();
myDelay(50);
SW_OUT_1();
myDelay(100);
rtk_switch_init();
/*****************************************************/
//VLAN
rtk_vlan_init();
/*set tag insert for port 4*/
rtl8306e_regbit_set(0, 29, 12, 0, 1);
rtl8306e_regbit_get(0, 16, 10, 0, ®val);
rtl8306e_regbit_set(0, 16, 10, 0, 0);
for(port=0;port<4;port )
{
rtl8306e_regbit_set (port, 22, 1, 0, 0);
rtl8306e_regbit_set (port, 22, 1, 1, 0);
rtl8306e_regbit_set (port, 22, 0, 0, 1);
rtl8306e_regbit_set (port, 22, 0, 1, 1);
}
/*****************************************************/
//QOS
// Init qos and set two queue
/*
rtk_qos_init(4);
// Set priority weight
priDec.dot1q_pri=5;
priDec.port_pri=4;
priDec.dscp_pri=3;
priDec.acl_pri=2;
priDec.vid_pri=1;
rtk_qos_priSel_set(&priDec);
rtl8306e_qos_1pPriRemap_set(0,0);
rtl8306e_qos_1pPriRemap_set(1,0);
rtl8306e_qos_1pPriRemap_set(2,1);
rtl8306e_qos_1pPriRemap_set(3,1);
rtl8306e_qos_1pPriRemap_set(4,2);
rtl8306e_qos_1pPriRemap_set(5,2);
rtl8306e_qos_1pPriRemap_set(6,3);
rtl8306e_qos_1pPriRemap_set(7,3);
*/
rtl8306e_qos_queueNum_set(4) ;
// Set priority weight
priDec.dot1q_pri=5;
priDec.port_pri=4;
priDec.dscp_pri=3;
priDec.acl_pri=2;
priDec.vid_pri=1;
rtk_qos_priSel_set(&priDec);
// 做好队列映射
for(port = 0 ; port< 4; port )
{
rtl8306e_qos_priToQueMap_set(port,port);
}
// 1Qmapping:
rtl8306e_qos_1pPriRemap_set(0,0);
rtl8306e_qos_1pPriRemap_set(1,0);
rtl8306e_qos_1pPriRemap_set(2,1);
rtl8306e_qos_1pPriRemap_set(3,1);
rtl8306e_qos_1pPriRemap_set(4,2);
rtl8306e_qos_1pPriRemap_set(5,2);
rtl8306e_qos_1pPriRemap_set(6,3);
rtl8306e_qos_1pPriRemap_set(7,3);
// 设置好set0
sch_para.q0_wt = 0x01;
sch_para.q1_wt = 0x01;
sch_para.q2_wt = 0x7F ;
//或者设定 sch_para.q2_wt = 0x00;
sch_para.q3_wt = 0x7F;
//或者设定 sch_para.q3_wt = 0x00;
sch_para.q2_n64Kbps = 0x00;
sch_para.q3_n64Kbps = 0x00 ;
rtl8306e_qos_schedulingPara_set(RTL8306_QOS_SET0, sch_para);
for(port = 0 ; port < 5; port )
{
//基于802.1q的优先级
rtl8306e_qos_priSrcEnable_set (port, RTL8306_1QBP_PRIO, 1) ;
//所有端口启用set0,Q2和Q3开启strict priority(q2.wt=q3.wt=0x00)或者127wight, 且不开启q2、q3的出限速控制, lbmask = 0;
rtl8306e_qos_portSchedulingMode_set (port, RTL8306_QOS_SET0, 0) ;
}
/*****************************************************/
// 端口隔离
rtl8306e_port_isolation_set(0x0267);
/*****************************************************/
//端口控制
for(port=0;port<4;port )
Switch_Set(port);
/*****************************************************/
for(port=0;port<5;port )
{
// 设置字节统计
rtl8306e_mibUnit_set(port,RTL8306_MIB_CNT1,RTL8306_MIB_BYTE);
rtl8306e_mibUnit_set(port,RTL8306_MIB_CNT2,RTL8306_MIB_BYTE);
// 统计清除
rtl8306e_mib_reset(port);
}
}
void vlan_entry_clean(void)
{
INT8U i;
for(i=1;i<5;i ) //判断设置的VLAN已经存在,
{
rtl8306e_vlan_entry_set(i,0 , 0, 0);
}
}
void Switch_Set(INT8U PortIndex)
{
INT8U i,trigNum,filTime;
INT32U VLANID,pIgPortMsk,val;
uint32 pVid, pMbrmsk, pUntagmsk;
rtk_port_phy_ability_t pAbility;
SwitchSetStruct *SwitchSetbuf;
SwitchSetbuf=(SwitchSetStruct*)(&Eeprom_buf[32 PortIndex*32]);
/*****************************************************/
VLANID=SwitchSetbuf->vlanID[0];VLANID<<=8;VLANID =SwitchSetbuf->vlanID[1];
//VLAN
rtl8306e_vlan_tagInsert_get(4,&pIgPortMsk);
if(VLANID>1)
{
rtl8306e_vlan_tagInsert_set(4, pIgPortMsk|(0x01<<PortIndex));
val=0;
for(i=1;i<5;i ) //判断设置的VLAN已经存在,
{
rtl8306e_vlan_entry_get(i,&pVid,&pMbrmsk,&pUntagmsk);
if((pVid&0xffff)==VLANID)
{
rtl8306e_vlan_entry_set(i,pVid , pMbrmsk|(0x01<<PortIndex), pUntagmsk|(0x01<<PortIndex));
val=1;
break;
}
}
if(val==0) //不存在,则直接设置
rtl8306e_vlan_entry_set(PortIndex 1,VLANID , 0x10 (0x01<<PortIndex), 0x01<<PortIndex);
/*set PVid for every port*/
rtk_vlan_portPvid_set(PortIndex, VLANID, 0);
/*****************************************************/
//QOS
rtk_qos_1pRemark_set(SwitchSetbuf->priorityGrade/2,SwitchSetbuf->priorityGrade);
rtk_vlan_vlanBasedPriority_set(VLANID,SwitchSetbuf->priorityGrade/2);
}
else
{
rtl8306e_vlan_tagInsert_set(4, (pIgPortMsk&(~(0x01<<PortIndex)))&0x0f);
}
/*****************************************************/
// 端口MAC地址数量限制
if(SwitchSetbuf->portMACLimit==0)
rtk_l2_limitLearningCnt_set(PortIndex, 0xff);
else
rtk_l2_limitLearningCnt_set(PortIndex, SwitchSetbuf->portMACLimit);
/*****************************************************/
// 端口限速
val=SwitchSetbuf->downstreamRateControl[0];val<<=8;
val =SwitchSetbuf->downstreamRateControl[1];val<<=8;
val =SwitchSetbuf->downstreamRateControl[2];val<<=8;
val =SwitchSetbuf->downstreamRateControl[3];
/*
if((SwitchSetbuf->flowControlEnable==0)&&(val<0x1996))
val*=2;
if((SwitchSetbuf->flowControlEnable==0)&&(PortIndex!=1))
rtk_rate_igrBandwidthCtrlRate_set(PortIndex,val/8,DISABLED); //下行
*/
rtk_rate_egrBandwidthCtrlRate_set(PortIndex,val/64,DISABLED); // x
val=SwitchSetbuf->upstreamRateControl[0];val<<=8;
val =SwitchSetbuf->upstreamRateControl[1];val<<=8;
val =SwitchSetbuf->upstreamRateControl[2];val<<=8;
val =SwitchSetbuf->upstreamRateControl[3];
rtk_rate_igrBandwidthCtrlRate_set(PortIndex,val/64,DISABLED); // s
/*****************************************************/
// 端口使能
rtl8306e_reg_get(PortIndex, 0, 0, &val);
if(SwitchSetbuf->portEnable==0)
{
val=val|(0x01<<11);
rtl8306e_reg_set(PortIndex, 0, 0, val);
}
else
{
val=val&(~(0x01<<11));
rtl8306e_reg_set(PortIndex, 0, 0, val);
}
/*****************************************************/
// 端口环路检测使能
rtl8306e_reg_get(0, 16, 0, &val);
val=val|(0x01<<2);
rtl8306e_reg_set(0, 16, 0, val);
/*****************************************************/
// 端口状态控制
pAbility.AutoNegotiation=0;
pAbility.Half_10=0;
pAbility.Full_10=0;
pAbility.Half_100=0;
pAbility.Full_100=0;
pAbility.FC=0;
pAbility.AsyFC=0;
switch(SwitchSetbuf->portModelControl)
{
case 0:pAbility.AutoNegotiation=1;break;
case 1:pAbility.Full_100=1;break;
case 2:pAbility.Half_100=1;break;
case 3:pAbility.Full_10=1;break;
case 4:pAbility.Half_10=1;break;
default:pAbility.AutoNegotiation=1;break;
}
// 流控
if(SwitchSetbuf->flowControlEnable)
pAbility.FC=1;
rtk_port_phyForceModeAbility_set(PortIndex,&pAbility);
/*****************************************************/
/*****************************************************/
if(PortIndex==0)
{
// 广播风暴抑制
if(SwitchSetbuf->broadcastProtectionEnable==0)
{
rtl8306e_storm_filterEnable_set(RTL8306_BROADCASTPKT,DISABLE);
rtl8306e_storm_filterEnable_set(RTL8306_MULTICASTPKT,DISABLE);
rtl8306e_storm_filterEnable_set(RTL8306_UDAPKT,DISABLE);
}
else
{
rtl8306e_storm_filterEnable_set(RTL8306_BROADCASTPKT,ENABLE);
rtl8306e_storm_filterEnable_set(RTL8306_MULTICASTPKT,ENABLE);
rtl8306e_storm_filterEnable_set(RTL8306_UDAPKT,ENABLE);
switch(SwitchSetbuf->broadcastProtectionEnable)
{
case 1:trigNum=RTL8306_STM_FILNUM8;filTime=RTL8306_STM_FIL800MS;break;
case 2:trigNum=RTL8306_STM_FILNUM16;filTime=RTL8306_STM_FIL800MS;break;
case 3:trigNum=RTL8306_STM_FILNUM32;filTime=RTL8306_STM_FIL800MS;break;
case 4:trigNum=RTL8306_STM_FILNUM64;filTime=RTL8306_STM_FIL800MS;break;
case 5:trigNum=RTL8306_STM_FILNUM128;filTime=RTL8306_STM_FIL800MS;break;
case 6:trigNum=RTL8306_STM_FILNUM256;filTime=RTL8306_STM_FIL800MS;break;
case 7:trigNum=RTL8306_STM_FILNUM64;filTime=RTL8306_STM_FIL100MS;break;
case 8:trigNum=RTL8306_STM_FILNUM128;filTime=RTL8306_STM_FIL100MS;break;
case 9:trigNum=RTL8306_STM_FILNUM256;filTime=RTL8306_STM_FIL100MS;break;
default: trigNum=RTL8306_STM_FILNUM8;filTime=RTL8306_STM_FIL100MS;break;
}
rtl8306e_storm_filter_set(trigNum,filTime,DISABLE);
}
// 统计信息清除
if(SwitchSetbuf->resetMib)
{
SwitchSetbuf->resetMib=0;
for(i=0;i<5;i )
rtl8306e_mib_reset(i);
}
}
}
void get_switch_info(void)
{
INT8U i;
INT32U mibinfo;
rtk_port_linkStatus_t pLinkStatus;
rtk_port_speed_t pSpeed;
rtk_port_duplex_t pDuplex;
SwitchGetStruct *SwitchGetbuf;
for(i=0;i<5;i )
{
SwitchGetbuf=&SwitchGetData[i];
// 端口状态
rtk_port_phyStatus_get(i,&pLinkStatus,&pSpeed,&pDuplex);
SwitchGetbuf->portLinkStatus=pLinkStatus;
if((pSpeed==PORT_SPEED_100M)&&(pDuplex==PORT_FULL_DUPLEX))
SwitchGetbuf->portModelStatus=1;
else if((pSpeed==PORT_SPEED_100M)&&(pDuplex==PORT_HALF_DUPLEX))
SwitchGetbuf->portModelStatus=2;
else if((pSpeed==PORT_SPEED_10M)&&(pDuplex==PORT_FULL_DUPLEX))
SwitchGetbuf->portModelStatus=3;
else
SwitchGetbuf->portModelStatus=4;
//环路检测
rtl8306e_reg_get(i, 24, 0, &mibinfo);
SwitchGetbuf->portLoopStatus=(mibinfo>>8)&0x01;
// uart_puts("port:");uart_hex(i);uart_puts_hex32_no_nl(" loop status",SwitchGetbuf->portLoopStatus);uart_puts("\r\n");
//统计信息
rtl8306e_mib_get(i,RTL8306_MIB_CNT1,&mibinfo); //TX byte count
if(mibinfo>=SwitchGetbuf->txByteCount)
{
SwitchGetbuf->txTraffic=(mibinfo-SwitchGetbuf->txByteCount)/5;
}
SwitchGetbuf->txByteCount=mibinfo;
rtl8306e_mib_get(i,RTL8306_MIB_CNT2,&mibinfo); //RX byte count
if(mibinfo>=SwitchGetbuf->rxByteCount)
{
SwitchGetbuf->rxTraffic=(mibinfo-SwitchGetbuf->rxByteCount)/5;
}
SwitchGetbuf->rxByteCount=mibinfo;
rtl8306e_mib_get(i,RTL8306_MIB_CNT3,&mibinfo); //RX drop packet count
SwitchGetbuf->rxDropPacketCount=mibinfo;
rtl8306e_mib_get(i,RTL8306_MIB_CNT4,&mibinfo); //RX CRC error packet count
SwitchGetbuf->rxErrorPacketCount=mibinfo;
rtl8306e_mib_get(i,RTL8306_MIB_CNT5,&mibinfo); //RX fragment packet count
SwitchGetbuf->rxFragmentPacketCount=mibinfo;
}
// uart_puts("\r\n");
}
/*
PHY REG: 00000500
PHY REG: 00007940
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00003000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000081
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
PHY REG: 00000000
0x0100:0000007D
MAC模式:
GPHY_ENH_CTRL = 0xc081
CSC_CLK_CTL0 = 0
PHY模式:
GPHY_ENH_CTRL = 00000201
CSC_CLK_CTL0 = 0B000000
arp -s 192.168.100.162 00-1d-7d-7d-6e-75
*/
// pc3 reset pd6 pll reset
/*********************************************************************************************************
End Of File
*********************************************************************************************************/
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论