实例介绍
【实例简介】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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论