📄 enc28j60.c
字号:
#include "config.h"
static u8_t ENC28J60Bank=0;
static WORD_BYTES next_packet_ptr;
static u8_t mac[6]={'a','r','m','m','a','c'};
/*******************************************************************************
*名称: ENC28J60ReadOp()
*功能: ENC28J60的SPI命令,读寄存器
*******************************************************************************/
u8_t ENC28J60ReadOp(u8_t op, u8_t address)
{
u8_t data=0;
OS_ENTER_CRITICAL();
ENC28J60_SPI_CS_OFF();
ENC28J60_WriteSPI(op | (address & ADDR_MASK));//写命令
data = ENC28J60_ReadSPI(); //读数据
if(address & 0x80) //如果地址指向了一个MAC 或MII 寄存器
{
data = ENC28J60_ReadSPI(); //读数据
}
ENC28J60_SPI_CS_ON();
OS_EXIT_CRITICAL();
return(data);
}
/*******************************************************************************
*名称: ENC28J60WriteOp()
*功能: ENC28J60的SPI命令,写寄存器,位域操作只能操作ETH的寄存器
*******************************************************************************/
void ENC28J60WriteOp(u8_t op, u8_t address,u8_t data)
{
OS_ENTER_CRITICAL();
ENC28J60_SPI_CS_OFF();
ENC28J60_WriteSPI(op | (address & ADDR_MASK));//写命令
ENC28J60_WriteSPI(data); //写数据
ENC28J60_SPI_CS_ON();
OS_EXIT_CRITICAL();
}
/*******************************************************************************
*名称: ENC28J60SetBank()
*功能: ENC28J60设置命令所在的存储区
*******************************************************************************/
void ENC28J60SetBank(u8_t address)
{
OS_ENTER_CRITICAL();
if((address & BANK_MASK) != ENC28J60Bank) // set the bank (if needed)
{
// set the bank
ENC28J60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));
ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);
ENC28J60Bank = (address & BANK_MASK);
}
OS_EXIT_CRITICAL();
}
/*******************************************************************************
*名称: ENC28J60ReadBuf()
*功能: ENC28J60的SPI命令,读缓冲
*******************************************************************************/
void ENC28J60ReadBuf(u8_t *buf,u16_t length)
{
OS_ENTER_CRITICAL();
ENC28J60_SPI_CS_OFF();
//read command
ENC28J60_WriteSPI(ENC28J60_READ_BUF_MEM);
while(length)
{
length--;
// write data
*buf++ = ENC28J60_ReadSPI();
}
ENC28J60_SPI_CS_ON();
OS_EXIT_CRITICAL();
}
/*******************************************************************************
*名称: ENC28J60WriteBuf()
*功能: ENC28J60的SPI命令,写缓冲
*******************************************************************************/
void ENC28J60WriteBuf(u8_t *buf,u16_t length)
{
OS_ENTER_CRITICAL();
ENC28J60_SPI_CS_OFF();
//write command
ENC28J60_WriteSPI(ENC28J60_WRITE_BUF_MEM);
while(length)
{
length--;
// write data
ENC28J60_WriteSPI(*buf++);
}
ENC28J60_SPI_CS_ON();
OS_EXIT_CRITICAL();
}
/*******************************************************************************
*名称: ENC28J60Read()
*功能: ENC28J60的SPI命令,读控制寄存器
*******************************************************************************/
u8_t ENC28J60Read(u8_t address)
{
ENC28J60SetBank(address); // select bank to read
// do the read
return ENC28J60ReadOp(ENC28J60_READ_CTRL_REG, address);
}
/*******************************************************************************
*名称: ENC28J60Write()
*功能: ENC28J60的SPI命令,写控制寄存器
*******************************************************************************/
void ENC28J60Write(u8_t address, u8_t data)
{
ENC28J60SetBank(address); // select bank to write
// do the write
ENC28J60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);
}
/*******************************************************************************
*名称: ENC28J60SC()
*功能: ENC28J60的SPI命令,写复位命令
*******************************************************************************/
void ENC28J60SC(void)
{
OS_ENTER_CRITICAL();
ENC28J60_SPI_CS_OFF();
ENC28J60_WriteSPI(ENC28J60_SOFT_RESET);//写复位命令
ENC28J60_SPI_CS_ON();
OS_EXIT_CRITICAL();
}
/*******************************************************************************
*名称: ENC28J60ReadPHY()
*功能: ENC28J60的SPI命令,读PHY
*******************************************************************************/
uint16 ENC28J60ReadPhy(uint8 address)
{
uint16 data=0;
// set the PHY register address
ENC28J60Write(MIREGADR, address);
ENC28J60Write(MICMD, MICMD_MIIRD);
// Loop to wait until the PHY register has been read through the MII
// This requires 10.24us
while( (ENC28J60Read(MISTAT) & MISTAT_BUSY) );
// Stop reading
ENC28J60Write(MICMD, MICMD_MIIRD);
// Obtain results and return
data = ENC28J60Read ( MIRDL );
data |= ENC28J60Read ( MIRDH );
return data;
}
/*******************************************************************************
*名称: ENC28J60WritePhy()
*功能: ENC28J60的SPI命令,写Phy
*******************************************************************************/
void ENC28J60WritePhy(u8_t address, WORD_BYTES data)
{
// set the PHY register address
ENC28J60Write(MIREGADR, address);
// write the PHY data
ENC28J60Write(MIWRL, data.byte.low);
ENC28J60Write(MIWRH, data.byte.high);
// wait until the PHY write completes
while( ENC28J60Read(MISTAT) & MISTAT_BUSY );
}
/*******************************************************************************
*名称: ENC28J60Init()
*功能: ENC28J60的初始化
*******************************************************************************/
void _ENC28J60Init( void )
{
int i=0;
PINSEL0 |= 0x0000c000; // 设置P0.7 INT
IO0DIR |= (1 << 15); // P0.15 RESET
IO1DIR |= (1 << 23); // P1.23 RST输出
RST_ENC28J60();
RST_MCP2515();
for(i=0;i<100000;i++);
RLS_ENC28J60();
RLS_MCP2515();
}
void ENC28J60Init( void )
{
WORD_BYTES temp;
u8_t i=0;
OS_ENTER_CRITICAL(); // initialize I/O
//PINSEL0 = (PINSEL0 & 0x303fffff); // 设置P0.7 INT P0.15 RESET
PINSEL0 |= 0x0000c000; // 设置P0.7 INT
PINSEL0 = (PINSEL0 | 0x0000c000);
PINSEL1 = (PINSEL1 & 0xffff3cc0); // 设置P0.18 WOL
IO0DIR |= (1 << 15); // reset as output
IO0SET |= (1 << 15);
IO0DIR = (IO0DIR & 0xfffbffff); // WOL输入
OS_EXIT_CRITICAL(); // set output to gnd, reset the ethernet chip
do
{
i = ENC28J60Read(ESTAT);
}while((~i & ESTAT_CLKRDY) | (i & ESTAT_INT));
// check CLKRDY bit to see if reset is complete
//当OST 超时后, ESTAT 寄存器中的CLKRDY 位将置1,应用程序软件可通过查询此位来确定何时开始正常的器件操作。
ENC28J60SC();
OSTimeDlyHMSM(0, 0, 0,100); //软件复位
// do bank 0 stuff
// initialize receive buffer
// 16-bit transfers, must write low byte first
// set receive buffer start address
next_packet_ptr.word = RXSTART_INIT;
// Rx start
ENC28J60Write(ERXSTL, LOW(RXSTART_INIT));
ENC28J60Write(ERXSTH, HIGH(RXSTART_INIT));
// set receive pointer address
ENC28J60Write(ERXRDPTL, LOW(RXSTART_INIT));
ENC28J60Write(ERXRDPTH, HIGH(RXSTART_INIT));
// RX end
ENC28J60Write(ERXNDL, LOW(RXSTOP_INIT));
ENC28J60Write(ERXNDH, HIGH(RXSTOP_INIT));
// TX start
ENC28J60Write(ETXSTL, LOW(TXSTART_INIT));
ENC28J60Write(ETXSTH, HIGH(TXSTART_INIT));
// TX end
ENC28J60Write(ETXNDL, LOW(TXSTOP_INIT));
ENC28J60Write(ETXNDH, HIGH(TXSTOP_INIT));
ENC28J60Write(ERXFCON, 0x00); //接收所有的数据包
// bring MAC out of reset
ENC28J60Write(MACON2, 0x00);
// do bank 2 stuff
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -