中级会员
- 积分
- 207
- 金钱
- 207
- 注册时间
- 2017-2-16
- 在线时间
- 67 小时
|
ENC424J600驱动无法ping通,求助
网上找了一份底层配置代码,但是无法ping通
//*****************************************************************************
//enc424j600 driver
//20110822
//hubing
//******************************************************************************
#include "enc424j600.h"
static u8 Enc424j600Bank;
static u16 NextPacketPtr;
extern void delay_mS(u16 time_ms);
//------------------------------------------------------------------------------
// 函数名 : SPI1_ETHERNET_Init
//描述 : 配置 SPI1
//入口参数 : None
//出口参数 : None
//返回 : None
//------------------------------------------------------------------------------
void SPI1_ETH_Init (void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//------ Enable SPI1 GPIOA and GPIOB clocks
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOD, ENABLE);
//------ Configure SPI1 pins: NSS=PA4, SCK=PA5, MISO=PA6 and MOSI=PA7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* //MISO为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure); */
//------ Configure SPI1 pins: NSS=PA4,
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 区别于别的SPI
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure); //GPIOD
SPI1_ENC424J600_CS_HIGH();
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//=0 逻辑低电平出于空闲状态 0,0模式
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//=0
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //=1
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //=0
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
u8 SPI1_ETH_SendByte(u8 byte)
{
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, byte);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
void enc424j600SetBank(unsigned char address)
{
// set the bank (if needed)
if((address & BANK_MASK) != Enc424j600Bank)
{
// set the bank
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(5);
SPI1_ETH_SendByte(((address & BANK_MASK)>>4)|0xC0);
Enc424j600Bank = (address & BANK_MASK);
}
}
unsigned char enc424j600ReadOp(unsigned char op, unsigned char address)
{
unsigned char dat = 0;
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(5);
dat = op | (address & ADDR_MASK);
SPI1_ETH_SendByte(dat);
dat = SPI1_ETH_SendByte(0xFF);
// do dummy read if needed (for mac and mii, see datasheet page 29)
if(address & 0x80)
{
dat = SPI1_ETH_SendByte(0xFF);
}
// release CS
SPI1_ENC424J600_CS_HIGH();
return dat;
}
void enc424j600WriteOp(unsigned char op, unsigned char address, unsigned char data)
{
unsigned char dat = 0;
// unsigned char temp = 0;
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(1);
// issue write command
dat = op | (address & ADDR_MASK);
SPI1_ETH_SendByte(dat);
// write data
dat = data;
SPI1_ETH_SendByte(dat);
// delay_mS(5);
SPI1_ENC424J600_CS_HIGH();
}
unsigned char enc424j600Read(unsigned char address)
{
// set the bank
enc424j600SetBank(address);
// do the read
return enc424j600ReadOp(ENC424j600_READ_CTRL_REG, address);
}
void enc424j600Write(unsigned char address, unsigned char data)
{
// set the bank
enc424j600SetBank(address);
// do the write
enc424j600WriteOp(ENC424j600_WRITE_CTRL_REG, address, data);
}
//读写SRAM的操作指令 op 只能是读写指针指令
unsigned int enc424j600ReadSRAM_op(unsigned char op)
{
unsigned int dat = 0;
unsigned int temp = 0;
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(5);
SPI1_ETH_SendByte(op);
dat = SPI1_ETH_SendByte(0xFF);
temp = SPI1_ETH_SendByte(0xFF);
dat = ((temp<<8)|dat);
// release CS
SPI1_ENC424J600_CS_HIGH();
return dat;
}
void enc424j600WriteSRAM_op(unsigned char op, unsigned int data) //write EGPRDPT etc.... 三字节指令
{
unsigned char dat = 0;
unsigned char temp = 0;
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(5);
dat = data;
temp = (data>>8);
SPI1_ETH_SendByte(op);
SPI1_ETH_SendByte(dat);
SPI1_ETH_SendByte(temp);
// release CS
SPI1_ENC424J600_CS_HIGH();
}
//读写数据
void enc424j600ReadBuffer(u8 op, unsigned int len, unsigned char* data)
{
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(5);
// issue read command
SPI1_ETH_SendByte(op);
while(len)
{
len--;
// read data
*data = (unsigned char)SPI1_ETH_SendByte(0);
data++;
}
SPI1_ENC424J600_CS_HIGH();
}
void enc424j600WriteBuffer(u8 op, unsigned int len, unsigned char* data)
{
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(5);
// issue write command
SPI1_ETH_SendByte(op); //N字节指令 写通用SRAM发送寄存器
while(len)
{
len--;
SPI1_ETH_SendByte(*data);
data++;
}
SPI1_ENC424J600_CS_HIGH();
}
//读写SRAM的操作指令
void enc424j600PhyWrite(unsigned char address, unsigned int data)
{
// set the PHY register address
enc424j600Write(MIREGADRL, address);
enc424j600Write(MIREGADRH, 0x01); //bit8保留位置一,区别去enc28j60
// write the PHY data
enc424j600Write(MIWRL, data);
enc424j600Write(MIWRH, data>>8);
// wait until the PHY write completes
while(enc424j600Read(MISTATL) & MISTAT_BUSY)
{
//Del_10us(1);
//_nop_();
}
}
u16 enc424j600PhyRead(unsigned char address)
{
u16 temp;
// u8 dat ;
// set the PHY register address
enc424j600Write(MIREGADRL, address);
enc424j600Write(MIREGADRH, 0x01); //bit8保留位置一,区别于enc28j60
enc424j600Write(MICMDL,0x01); //读一次MIREGADR<4:0> 指定的PHY 寄存器,并把数据复制到MIRD
// write the PHY data
while(enc424j600Read(MISTATL) & MISTAT_BUSY) //等待busy位变成0
{
//Del_10us(1);
//_nop_();
}
temp = enc424j600Read(MIRDL);
temp |= enc424j600Read(MIRDH)<<8;
// wait until the PHY write completes
return temp;
}
void enc424j600clkout(unsigned char clk)
{
//setup clkout: 2 is 12.5MHz:
enc424j600Write(ECON2H, clk & 0xF);
}
void enc424j600Init(unsigned char* macaddr)
{
// initialize I/O
//enc28j60CSinit();
SPI1_ENC424J600_CS_LOW();
SPI1_FRAM_CS_HIGH();
SPI1_FLASH_CS_HIGH();
// delay_mS(1);
//enc28j60SetSCK();
//enc28j60HWreset();
// perform system reset
SPI1_ETH_SendByte(SETETHRST);
delay_mS(2);
// check CLKRDY bit to see if reset is complete
// The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
//while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
// do bank 0 stuff
// initialize receive buffer
// 16-bit transfers, must write low byte first
// set receive buffer start address
NextPacketPtr = RXSTART_INIT; //接收指针初始化
// Rx FIFO start
enc424j600Write(ERXSTL, RXSTART_INIT&0xFF); //接收缓冲区FIFO起始地址
enc424j600Write(ERXSTH, RXSTART_INIT>>8);
//RX 尾指针
enc424j600Write(ERXTAILL, 0xFE); //
enc424j600Write(ERXTAILH, 0x5F);
enc424j600Write(ECON2L,0x0F);
enc424j600Write(ECON2H,0xDD); //禁止 时钟输出
// do bank 1 stuff, packet filter:
// For broadcast packets we allow only ARP packtets
// All other packets should be unicast only for our mac (MAADR)
//
// The pattern to match on is therefore
// Type ETH.DST
// ARP BROADCAST
// 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
// in binary these poitions are:11 0000 0011 1111
// This is hex 303F->EPMM0=0x3f,EPMM1=0x30
//UCEN接受目标地址与本地MAC 地址匹配的数据包,丢弃具有无效CRC 的数据包
enc424j600Write(ERXFCONL,ERXFCONL_UCEN|ERXFCONL_CRCEN|ERXFCONL_RUNTEN|ERXFCONL_NOTEMEEN|ERXFCONL_MCEN);
enc424j600Write(ERXFCONH, 0x00);//ERXFCONH_PMEN0);
// 接受具有NOTPM 定义的校验和匹配的所有数据包(1)NOTPM 0 = 成功的模式匹配要求模式匹配校验和匹配
// enc28j60Write(EPMM1L, 0x3f);
// enc28j60Write(EPMM1H, 0x30);
// enc28j60Write(EPMCSL, 0xf9);
// enc28j60Write(EPMCSH, 0xf7);
// USART_SendData(USART1,(u8)(enc28j60Read(EPMCSH)));
// DO HERE TO CONTINUE 110929
// do bank 2 stuff
// enable MAC receive
enc424j600Write(MACON1L, 0x0D); //MAC 或MII 寄存器,必须先写低字节再写髙字节 !!!!!不支持位操作
enc424j600Write(MACON1H, 0x00);
// bring MAC out of reset
// enable automatic padding to 60bytes and CRC operations
// enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON2L, MACON2L_PADCFG0|MACON2L_TXCRCEN|MACON2L_FULDPX);
enc424j600Write(MACON2L,0xB3);
//101 = MAC自动检测具有8100h 类型字段的VLAN 协议帧,并自动填充到64 字节长。 如果不是VLAN
//帧,则填充至60 字节长。 填充后还要追加一个有效的CRC。 不管PADCFG位如何,MAC都会在发送帧的末尾追加一个有效的CRC。 如果PADCFG位指定要追加有效的CRC
enc424j600Write(MACON2H,0x00);
// 使能MAC 插入(TXMAC = 1)使能自动填充(PADCFG<2:0> = 101)使能CRC 生成(TXCRCEN = 1)
//MACON2L_FULDPX=1 MAC 工作在全双工模式下。 要确保正确操作, PHY 也必须设置为全双工模式。
// MACON2L_TXCRCEN=1不管PADCFG位如何,MAC都会在发送帧的末尾追加一个有效的CRC。 如果PADCFG位指定要追
//加有效的CRC,则必须将TXCRCEN 置1。
// MACON2L_PADCFG0=1用0 填充所有短帧至60 字节长,并追加一个有效的CRC
// set inter-frame gap (non-back-to-back)
enc424j600Write(MAIPGL, 0x12); // 非背对背包间间隔延时控制位
enc424j600Write(MAIPGH, 0x0C);
// USART_SendData(USART1,(u8)(enc28j60Read(MAIPGH)));
// set inter-frame gap (back-to-back)
enc424j600Write(MABBIPGL, 0x15);
enc424j600Write(MABBIPGH, 0x00);
// 当FULDPX (MACON2<0>) = 1 时:
//在背对背序列中,从前一次发送结束到下一次发送开始之间有半字节时间的延时。 应使用整数倍的半字
//节时间减3 对该寄存器的值进行编程。建议将该值设置为15h,表示IEEE 规定的最小包间间隔(IPG)
//时间为0.96 μs (速度为100 Mb/s 时)或9.6 μs (速度为10 Mb/s 时)。
// Set the maximum packet size which the controller will accept
// Do not send packets longer than MAX_FRAMELEN:
enc424j600Write(MAMXFLL, MAX_FRAMELEN&0xFF);
enc424j600Write(MAMXFLH, MAX_FRAMELEN>>8);
// do bank 3 stuff
// write MAC address
// NOTE: MAC address in ENC28J60 is byte-backward
enc424j600Write(MAADR1L, macaddr[0]);
enc424j600Write(MAADR1H, macaddr[1]);
enc424j600Write(MAADR2L, macaddr[2]);
enc424j600Write(MAADR2H, macaddr[3]);
enc424j600Write(MAADR3L, macaddr[4]);
enc424j600Write(MAADR3H, macaddr[5]);
enc424j600Write(ECON1H,0x06);
enc424j600Write(EIDLEDH,0x67); //设置灯的闪烁方式
// 显示双工模式状态,当有链路且PHY 为全双工模式(即PHYDPX(ESTAT<10> 为1)时,引脚驱动为高电平
//0110 = 显示发送和接收事件;正在发送或接收数据包时,引脚驱动为高电平
enc424j600PhyWrite(PHCON1, PHCON1_PDPXMD|PHCON1_SPD100); // 当MACON3.FULDPX=l和PHCONI.PDPXMD=l时,ENC28J60工作在全双工模式下。
enc424j600PhyWrite(PHANA, 0x05E1); //
// no loopback of transmitted frames
// enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS); //
/* ETHERNET_Rx_Buffer[0] = enc28j60PhyRead(PHCON2);
ETHERNET_Rx_Buffer[1] = (enc28j60PhyRead(PHCON2)>>8);
USART_SendData(USART1,(u8)ETHERNET_Rx_Buffer[0]);
USART_SendData(USART1,(u8)ETHERNET_Rx_Buffer[1]); */
// switch to bank 0
enc424j600SetBank(ECON1L);
// enable interrutps
enc424j600WriteOp(ENC424j600_BIT_FIELD_SET, EIEL, EIEL_PKTIE);
//INT 引脚由INT 状态位(ESTAT<15>)控制
//ESTAT<15> 1 = EIR 的其中一位被置1且由EIE寄存器允许相应中断。 如果INTIE(EIE<15>)被置1,则INT引脚也被驱动为低电平。
enc424j600WriteOp(ENC424j600_BIT_FIELD_SET, EIEH, EIEH_INTIE);
// enable packet reception
enc424j600WriteOp(ENC424j600_BIT_FIELD_SET, ECON1L, ECON1L_RXEN); //1 = 通过当前接收过滤器配置的数据包被写入接收缓冲区
}
unsigned char enc424j600getrev(void)
{
return(enc424j600Read(EIDLEDL));
}
void enc424j600PacketSend(unsigned int len, unsigned char* packet)
{
//////////////////////////////////////
enc424j600WriteSRAM_op(WGPWRPT,TXSTART_INIT);
enc424j600Write(ETXLENL, len&0xFF);
enc424j600Write(ETXLENH, len>>8);
enc424j600WriteBuffer(W_EGPDATA,len, packet);
enc424j600WriteOp(ENC424j600_BIT_FIELD_SET, ECON1L, ECON1L_TXRTS); //使能发送
// USART_SendData(USART1,(u8)enc28j60Read(ETXWIREL)); //统计实际发送的字节数
// USART_SendData(USART1,(u8)enc28j60Read(ETXWIREH));
// Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
if( (enc424j600Read(EIRL) & EIEL_TXABTIE) ) //1 = 因错误而中止数据包发送。 读取ETXSTAT 寄存器来确定原因。 TXRTS(ECON1<1>)已由硬件清0
{
enc424j600WriteOp(ENC424j600_BIT_FIELD_CLR, ECON1L, ECON1L_TXRTS); //终止发送
}
}
// Gets a packet from the network receive buffer, if one is available.
// The packet will by headed by an ethernet header.
// maxlen The maximum acceptable length of a retrieved packet.
// packet Pointer where packet data should be stored.
// Returns: Packet length in bytes if a packet was retrieved, zero otherwise.
unsigned int enc424j600PacketReceive(unsigned int maxlen, unsigned char* packet)
{
unsigned char rxdata[6];
unsigned int len;
u16 newRXTail;
if (!(enc424j600Read(EIRL) & EIRL_PKTIF))
{
return (0);
}
// Set the RX Read Pointer to the beginning of the next unprocessed packet
enc424j600WriteSRAM_op(WRXRDPT,NextPacketPtr);
enc424j600ReadBuffer(R_ERXDATA,2, rxdata);
NextPacketPtr = rxdata[1];
NextPacketPtr = NextPacketPtr<<8;
NextPacketPtr |= rxdata[0]; //下一数据包指针的首地址
enc424j600ReadBuffer(R_ERXDATA,6, rxdata);
len = rxdata[1];
len = len<<8;
len |= rxdata[0]; //数据包长度
len-=4;
if ((rxdata[2] & 0x80)==0)
{
// invalid
len=0;
}
if (len>maxlen-1)
{
len=maxlen-1;
}
enc424j600ReadBuffer(R_ERXDATA,len,packet);
newRXTail = NextPacketPtr - 2;
//Special situation if nextPacketPointer is exactly RXSTART
if (NextPacketPtr == RXSTART_INIT)
newRXTail = 0x5FFE - 2;
//Packet decrement
enc424j600Write(ECON1H, ECON1H_PKTDEC);
//Write new RX tail
enc424j600Write(ERXTAILL, newRXTail); //
enc424j600Write(ERXTAILH, newRXTail>>8);
return len;
}
|
|