|
|
【驱动程序】ENC28J60网卡芯片驱动程序(不含lwIP协议栈) |
一派護法 十九級 |
【ENC28J60.h】 #define EIE 0x1b #define EIR 0x1c #define ESTAT 0x1d #define ECON2 0x1e #define ECON1 0x1f
// Bank 0 registers #define ERDPTL 0x00 #define ERDPTH 0x01 #define EWRPTL 0x02 #define EWRPTH 0x03 #define ETXSTL 0x04 #define ETXSTH 0x05 #define ETXNDL 0x06 #define ETXNDH 0x07 #define ERXSTL 0x08 #define ERXSTH 0x09 #define ERXNDL 0x0a #define ERXNDH 0x0b #define ERXRDPTL 0x0c #define ERXRDPTH 0x0d #define ERXWRPTL 0x0e #define ERXWRPTH 0x0f #define EDMASTL 0x10 #define EDMASTH 0x11 #define EDMANDL 0x12 #define EDMANDH 0x13 #define EDMADSTL 0x14 #define EDMADSTH 0x15 #define EDMACSL 0x16 #define EDMACSH 0x17
// Bank 1 registers #define EHT0 0x20 #define EHT1 0x21 #define EHT2 0x22 #define EHT3 0x23 #define EHT4 0x24 #define EHT5 0x25 #define EHT6 0x26 #define EHT7 0x27 #define EPMM0 0x28 #define EPMM1 0x29 #define EPMM2 0x2a #define EPMM3 0x2b #define EPMM4 0x2c #define EPMM5 0x2d #define EPMM6 0x2e #define EPMM7 0x2f #define EPMCSL 0x30 #define EPMCSH 0x31 #define EPMOL 0x34 #define EPMOH 0x35 #define EWOLIE 0x36 #define EWOLIR 0x37 #define ERXFCON 0x38 #define EPKTCNT 0x39
// Bank 2 registers #define MACON1 0xc0 #define MACON2 0xc1 #define MACON3 0xc2 #define MACON4 0xc3 #define MABBIPG 0xc4 #define MAIPGL 0xc6 #define MAIPGH 0xc7 #define MACLCON1 0xc8 #define MACLCON2 0xc9 #define MAMXFLL 0xca #define MAMXFLH 0xcb #define MAPHSUP 0xcd #define MICON 0xd1 #define MICMD 0xd2 #define MIREGADR 0xd4 #define MIWRL 0xd6 #define MIWRH 0xd7 #define MIRDL 0xd8 #define MIRDH 0xd9
// Bank 3 registers #define MAADR1 0xe0 #define MAADR0 0xe1 #define MAADR3 0xe2 #define MAADR2 0xe3 #define MAADR5 0xe4 #define MAADR4 0xe5 #define EBSTSD 0x66 #define EBSTCON 0x67 #define EBSTCSL 0x68 #define EBSTCSH 0x69 #define MISTAT 0xea #define EREVID 0x72 #define ECOCON 0x75 #define EFLOCON 0x77 #define EPAUSL 0x78 #define EPAUSH 0x79
// PHY registers #define PHCON1 0x00 #define PHSTAT1 0x01 #define PHHID1 0x02 #define PHHID2 0x03 #define PHCON2 0x10 #define PHSTAT2 0x11 #define PHIE 0x12 #define PHIR 0x13 #define PHLCON 0x14
// ENC28J60 ERXFCON Register Bit Definitions #define ERXFCON_UCEN 0x80 #define ERXFCON_ANDOR 0x40 #define ERXFCON_CRCEN 0x20 #define ERXFCON_PMEN 0x10 #define ERXFCON_MPEN 0x08 #define ERXFCON_HTEN 0x04 #define ERXFCON_MCEN 0x02 #define ERXFCON_BCEN 0x01
// ENC28J60 EIE Register Bit Definitions #define EIE_INTIE 0x80 #define EIE_PKTIE 0x40 #define EIE_DMAIE 0x20 #define EIE_LINKIE 0x10 #define EIE_TXIE 0x08 #define EIE_WOLIE 0x04 #define EIE_TXERIE 0x02 #define EIE_RXERIE 0x01
// ENC28J60 EIR Register Bit Definitions #define EIR_PKTIF 0x40 #define EIR_DMAIF 0x20 #define EIR_LINKIF 0x10 #define EIR_TXIF 0x08 #define EIR_WOLIF 0x04 #define EIR_TXERIF 0x02 #define EIR_RXERIF 0x01
// ENC28J60 ESTAT Register Bit Definitions #define ESTAT_INT 0x80 #define ESTAT_LATECOL 0x10 #define ESTAT_RXBUSY 0x04 #define ESTAT_TXABRT 0x02 #define ESTAT_CLKRDY 0x01
// ENC28J60 ECON2 Register Bit Definitions #define ECON2_AUTOINC 0x80 #define ECON2_PKTDEC 0x40 #define ECON2_PWRSV 0x20 #define ECON2_VRPS 0x08
// ENC28J60 ECON1 Register Bit Definitions #define ECON1_TXRST 0x80 #define ECON1_RXRST 0x40 #define ECON1_DMAST 0x20 #define ECON1_CSUMEN 0x10 #define ECON1_TXRTS 0x08 #define ECON1_RXEN 0x04 #define ECON1_BSEL1 0x02 #define ECON1_BSEL0 0x01
// ENC28J60 MACON1 Register Bit Definitions #define MACON1_LOOPBK 0x10 #define MACON1_TXPAUS 0x08 #define MACON1_RXPAUS 0x04 #define MACON1_PASSALL 0x02 #define MACON1_MARXEN 0x01
// ENC28J60 MACON2 Register Bit Definitions #define MACON2_MARST 0x80 #define MACON2_RNDRST 0x40 #define MACON2_MARXRST 0x08 #define MACON2_RFUNRST 0x04 #define MACON2_MATXRST 0x02 #define MACON2_TFUNRST 0x01
// ENC28J60 MACON3 Register Bit Definitions #define MACON3_PADCFG2 0x80 #define MACON3_PADCFG1 0x40 #define MACON3_PADCFG0 0x20 #define MACON3_TXCRCEN 0x10 #define MACON3_PHDRLEN 0x08 #define MACON3_HFRMLEN 0x04 #define MACON3_FRMLNEN 0x02 #define MACON3_FULDPX 0x01
// ENC28J60 MICMD Register Bit Definitions #define MICMD_MIISCAN 0x02 #define MICMD_MIIRD 0x01
// ENC28J60 MISTAT Register Bit Definitions #define MISTAT_NVALID 0x04 #define MISTAT_SCAN 0x02 #define MISTAT_BUSY 0x01
// ENC28J60 PHY PHCON1 Register Bit Definitions #define PHCON1_PRST 0x8000 #define PHCON1_PLOOPBK 0x4000 #define PHCON1_PPWRSV 0x0800 #define PHCON1_PDPXMD 0x0100
// ENC28J60 PHY PHSTAT1 Register Bit Definitions #define PHSTAT1_PFDPX 0x1000 #define PHSTAT1_PHDPX 0x0800 #define PHSTAT1_LLSTAT 0x0004 #define PHSTAT1_JBSTAT 0x0002
// ENC28J60 PHY PHCON2 Register Bit Definitions #define PHCON2_FRCLINK 0x4000 #define PHCON2_TXDIS 0x2000 #define PHCON2_JABBER 0x0400 #define PHCON2_HDLDIS 0x0100
// ENC28J60 Packet Control Byte Bit Definitions #define PKTCTRL_PHUGEEN 0x08 #define PKTCTRL_PPADEN 0x04 #define PKTCTRL_PCRCEN 0x02 #define PKTCTRL_POVERRIDE 0x01
/* 指令集, 详见数据手册26页 */ #define ENC28J60_READ_CTRL_REG 0x00 // 读控制寄存器 #define ENC28J60_READ_BUF_MEM 0x3a // 读缓冲区 #define ENC28J60_WRITE_CTRL_REG 0x40 // 写控制寄存器 #define ENC28J60_WRITE_BUF_MEM 0x7a // 写缓冲区 #define ENC28J60_BIT_FIELD_SET 0x80 // 位域置位 #define ENC28J60_BIT_FIELD_CLR 0xa0 // 位域清零 #define ENC28J60_SOFT_RESET 0xff // 系统复位
#define RXSTART_INIT 0 // 接收缓冲区起始地址 #define RXSTOP_INIT (0x1fff - 0x0600 - 1) // 接收缓冲区停止地址 #define TXSTART_INIT (0x1fff - 0x0600) // 发送缓冲区起始地址, 大小约1500字节 #define TXSTOP_INIT 0x1fff // 发送缓冲区停止地址 #define MAX_FRAMELEN 1500 // 以太网报文最大长度
void ENC28J60_BeginSend(void); void ENC28J60_EndReceive(void); uint16_t ENC28J60_GetPacketLength(void); uint8_t ENC28J60_GetPacketNum(void); void ENC28J60_Init(uint8_t *mac_addr); void ENC28J60_InitSend(uint16_t len); uint8_t ENC28J60_Read(uint8_t addr); void ENC28J60_ReadBuf(uint8_t *p, uint16_t len); uint8_t ENC28J60_ReadOP(uint8_t op, uint8_t addr); void ENC28J60_SetBank(uint8_t addr); void ENC28J60_Write(uint8_t addr, uint8_t data); void ENC28J60_WriteBuf(uint8_t *p, uint16_t len); void ENC28J60_WriteOP(uint8_t op, uint8_t addr, uint8_t data); void ENC28J60_WritePhy(uint8_t addr, uint16_t data);
|
一派護法 十九級 |
【ENC28J60.c】 #include <stm32f10x.h> #include "ENC28J60.h"
static uint8_t enc28j60_bank; // 存储区Bank编号, ENC28J60具有Bank0~3共4个存储区, 需要通过ECON1寄存器选择 static uint16_t enc28j60_next_pkt; // 下一个数据包指针, 详见数据手册P43图7-3
// 开始发送 void ENC28J60_BeginSend(void) { ENC28J60_WriteOP(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); if (ENC28J60_Read(EIR) & EIR_TXERIF) { ENC28J60_SetBank(ECON1); ENC28J60_WriteOP(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS); } }
// 结束读取接收缓冲区过程, 移动接收缓冲区指针 void ENC28J60_EndReceive(void) { // 移动接收缓冲区读指针 ENC28J60_Write(ERXRDPTL, enc28j60_next_pkt); ENC28J60_Write(ERXRDPTH, enc28j60_next_pkt >> 8); // 数据包递减 ENC28J60_WriteOP(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); }
// 获得数据包长度 uint16_t ENC28J60_GetPacketLength(void) { uint16_t len = 0; uint16_t rxstat; // 设置接收缓冲器读指针 ENC28J60_Write(ERDPTL, enc28j60_next_pkt); ENC28J60_Write(ERDPTH, enc28j60_next_pkt >> 8); // 读下一个包的指针 enc28j60_next_pkt = ENC28J60_ReadOP(ENC28J60_READ_BUF_MEM, 0); enc28j60_next_pkt |= ENC28J60_ReadOP(ENC28J60_READ_BUF_MEM, 0) << 8; // 读包的长度 len = ENC28J60_ReadOP(ENC28J60_READ_BUF_MEM, 0); len |= ENC28J60_ReadOP(ENC28J60_READ_BUF_MEM, 0) << 8; len -= 4; // 删除CRC计数 // 读取接收状态 rxstat = ENC28J60_ReadOP(ENC28J60_READ_BUF_MEM, 0); rxstat |= ENC28J60_ReadOP(ENC28J60_READ_BUF_MEM, 0) << 8; return len; }
// 获取数据包个数 uint8_t ENC28J60_GetPacketNum(void) { return ENC28J60_Read(EPKTCNT); }
// 初始化 void ENC28J60_Init(uint8_t *mac_addr) { ENC28J60_WriteOP(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); // ENC28J60软件复位 while ((ENC28J60_Read(ESTAT) & ESTAT_CLKRDY) == 0); enc28j60_next_pkt = RXSTART_INIT; // 设置接收缓冲区起始地址, 该变量用于每次读取缓冲区时保留下一个包的首地址 // 设置接收缓冲区起始指针 ENC28J60_Write(ERXSTL, RXSTART_INIT & 0xff); ENC28J60_Write(ERXSTH, RXSTART_INIT >> 8); // 设置接收缓冲区读指针 ENC28J60_Write(ERXRDPTL, RXSTART_INIT & 0xff); ENC28J60_Write(ERXRDPTH, RXSTART_INIT >> 8); // 设置接收缓冲区结束指针 ENC28J60_Write(ERXNDL, RXSTOP_INIT & 0xff); ENC28J60_Write(ERXNDH, RXSTOP_INIT >> 8); // 设置发送缓冲区起始指针 ENC28J60_Write(ETXSTL, TXSTART_INIT & 0xff); ENC28J60_Write(ETXSTH, TXSTART_INIT >> 8); // 设置发送缓冲区结束指针 ENC28J60_Write(ETXNDL, TXSTOP_INIT & 0xff); ENC28J60_Write(ETXNDH, TXSTOP_INIT >> 8); // 使能单播过滤, CRC校验, 格式匹配自动过滤 ENC28J60_Write(ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_PMEN); ENC28J60_Write(EPMM0, 0x3f); ENC28J60_Write(EPMM1, 0x30); ENC28J60_Write(EPMCSL, 0xf9); ENC28J60_Write(EPMCSH, 0xf7); ENC28J60_Write(MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS); // 使能MAC接收, 允许MAC发送暂停控制帧, 当接收到暂停控制帧时停止发送 ENC28J60_Write(MACON2, 0x00); // 退出复位状态 // 用0填充所有短帧至60字节长, 并追加一个CRC, 发送CRC使能, 帧长度校验使能, MAC全双工使能 // 由于ENC28J60不支持802.3的自动协商机制, 所以对端的网络卡需要强制设置为全双工 ENC28J60_WriteOP(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX); ENC28J60_Write(MAIPGL, 0x12); ENC28J60_Write(MAIPGH, 0x0c); ENC28J60_Write(MABBIPG, 0x15); // 最大帧长度 ENC28J60_Write(MAMXFLL, MAX_FRAMELEN & 0xff); ENC28J60_Write(MAMXFLH, MAX_FRAMELEN >> 8); // 写入MAC地址 ENC28J60_Write(MAADR5, mac_addr[0]); ENC28J60_Write(MAADR4, mac_addr[1]); ENC28J60_Write(MAADR3, mac_addr[2]); ENC28J60_Write(MAADR2, mac_addr[3]); ENC28J60_Write(MAADR1, mac_addr[4]); ENC28J60_Write(MAADR0, mac_addr[5]); ENC28J60_WritePhy(PHCON1, PHCON1_PDPXMD); // 配置PHY为全双工, LEDB为拉电流 ENC28J60_WritePhy(PHLCON, 0x0476); // LED状态 ENC28J60_WritePhy(PHCON2, PHCON2_HDLDIS); // 半双工回环禁止 ENC28J60_SetBank(ECON1); // 返回BANK0 ENC28J60_WriteOP(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE | EIE_PKTIE | EIE_RXERIE); // 使能中断: 全局中断, 接收中断, 接收错误中断 ENC28J60_WriteOP(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); // 允许接收 }
void ENC28J60_InitSend(uint16_t len) { while ((ENC28J60_Read(ECON1) & ECON1_TXRTS) != 0); // 查询发送逻辑复位位 // 设置发送缓冲区起始地址 ENC28J60_Write(EWRPTL, TXSTART_INIT & 0xff); ENC28J60_Write(EWRPTH, TXSTART_INIT >> 8); // 设置发送缓冲区结束地址 该值对应发送数据包长度 ENC28J60_Write(ETXNDL, (TXSTART_INIT + len) & 0xff); ENC28J60_Write(ETXNDH, (TXSTART_INIT + len) >> 8); // 发送控制字节: 控制字节为0x00, 表示使用macon3设置 ENC28J60_WriteOP(ENC28J60_WRITE_BUF_MEM, 0, 0x00); }
// 读取寄存器值 uint8_t ENC28J60_Read(uint8_t addr) { ENC28J60_SetBank(addr); return ENC28J60_ReadOP(ENC28J60_READ_CTRL_REG, addr); }
// 读缓冲区 void ENC28J60_ReadBuf(uint8_t *p, uint16_t len) { uint8_t data; uint8_t first = 1; if (len == 0) return; SPI1->CR1 |= SPI_CR1_SPE; SPI1->DR = ENC28J60_READ_BUF_MEM; // 通过SPI发送读取缓冲区命令 while ((SPI1->SR & SPI_SR_TXE) == 0); // 循环读取 while (len--) { SPI1->DR = 0xff; // 送入下一次要发送的数据 while ((SPI1->SR & SPI_SR_RXNE) == 0); // 等待本次数据发送完毕 data = SPI1->DR; // 接收本次数据 if (first) first = 0; // 忽略第一次数据 else *p++ = data; while ((SPI1->SR & SPI_SR_TXE) == 0); } while ((SPI1->SR & SPI_SR_RXNE) == 0); *p = SPI1->DR; // 接收最后一次数据 while (SPI1->SR & SPI_SR_BSY); SPI1->CR1 &= ~SPI_CR1_SPE; }
uint8_t ENC28J60_ReadOP(uint8_t op, uint8_t addr) { uint8_t data; SPI1->CR1 |= SPI_CR1_SPE; // 启动SPI总线, 同时自动拉低片选信号CS SPI1->DR = op | (addr & 0x1f); // 操作码和地址 (1) while ((SPI1->SR & SPI_SR_TXE) == 0); // TXE置位时数据(1)刚好发完1位, 可以向DR中放入下次要发送的数据 SPI1->DR = 0xff; // 送入数据 (2) while ((SPI1->SR & SPI_SR_RXNE) == 0); // 等待数据(1)发送完毕 data = SPI1->DR; // 接收 (1) while ((SPI1->SR & SPI_SR_TXE) == 0); // TXE置位时数据(2)刚好发完1位 if (addr & 0x80) // 如果是MAC和MII寄存器, 第一个读取的字节无效, 该信息包含在地址的最高位 SPI1->DR = 0xff; // 送入数据 (3), 再次通过SPI读取数据 while ((SPI1->SR & SPI_SR_RXNE) == 0); // 等待数据(2)发送完毕 data = SPI1->DR; // 接收 (2) if (addr & 0x80) { while ((SPI1->SR & SPI_SR_RXNE) == 0); // 等待数据(3)发送完毕 data = SPI1->DR; // 接收 (3) } while (SPI1->SR & SPI_SR_BSY); SPI1->CR1 &= ~SPI_CR1_SPE; // 关闭SPI总线, 同时自动拉高片选信号CS return data; }
// 设定寄存器存储区域 void ENC28J60_SetBank(uint8_t addr) { addr &= 0x60; if (addr != enc28j60_bank) { ENC28J60_WriteOP(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_BSEL1 | ECON1_BSEL0); ENC28J60_WriteOP(ENC28J60_BIT_FIELD_SET, ECON1, addr >> 5); enc28j60_bank = addr; } }
// 写寄存器 void ENC28J60_Write(uint8_t addr, uint8_t data) { ENC28J60_SetBank(addr); ENC28J60_WriteOP(ENC28J60_WRITE_CTRL_REG, addr, data); }
// 写缓冲区 void ENC28J60_WriteBuf(uint8_t *p, uint16_t len) { SPI1->CR1 |= SPI_CR1_SPE; SPI1->DR = ENC28J60_WRITE_BUF_MEM; // 发送写取缓冲区命令 while ((SPI1->SR & SPI_SR_TXE) == 0); // 循环发送 while (len--) { SPI1->DR = *p++; while ((SPI1->SR & SPI_SR_TXE) == 0); } while (SPI1->SR & SPI_SR_BSY); SPI1->CR1 &= ~SPI_CR1_SPE; }
void ENC28J60_WriteOP(uint8_t op, uint8_t addr, uint8_t data) { SPI1->CR1 |= SPI_CR1_SPE; SPI1->DR = op | (addr & 0x1f); // 发送操作码和寄存器地址 while ((SPI1->SR & SPI_SR_TXE) == 0); SPI1->DR = data; // 发送数据 while ((SPI1->SR & SPI_SR_TXE) == 0); while (SPI1->SR & SPI_SR_BSY); data = SPI1->DR; // 清RxNE SPI1->CR1 &= ~SPI_CR1_SPE; }
// 写物理寄存器 void ENC28J60_WritePhy(uint8_t addr, uint16_t data) { ENC28J60_Write(MIREGADR, addr); ENC28J60_Write(MIWRL, data); ENC28J60_Write(MIWRH, data >> 8); while (ENC28J60_Read(MISTAT) & MISTAT_BUSY); }
|
一派護法 十九級 |
【网卡端口配置:以STM32F103单片机为例】 // 配置SPI1 RCC->APB2ENR = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_SPI1EN; GPIOA->CRL = 0xb4bb0080; GPIOA->BSRR = GPIO_BSRR_BS1; // PA1为网卡中断输出 SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_1; // 主机模式, 时钟至少需要8分频(BR=010), 也就是72MHz/8=9MHz SPI1->CR2 = SPI_CR2_SSOE; // 开CS片选输出
|
一派護法 十九級 |
【端口连线】 PA1连接外中断端口INT,带上拉电阻输入(CRL=8, 且ODR=1) PA4连接片选端口CS,复用推挽50MHz输出(CRL=b) PA5连接时钟端口SCK,复用推挽50MHz输出(CRL=b) PA6连接端口SO,浮空输入(CRL=4) PA7连接端口SI,复用推挽50MHz输出(CRL=b)
当SPE=1时SPI总线启动,CS=0;当SPE=0时SPI总线关闭,CS=1。(SSOE=1) SPI总线的Baud Rate必须至少为8分频(=f_PCLK/8),也就是将BR位设为010。
|
一派護法 十九級 |
【头文件中未引用的宏定义】 ERXWRPTL, ERXWRPTH, EDMASTL, EDMASTH, EDMANDL, EDMANDH, EDMADSTL, EDMADSTH, EDMACSL, EDMACSH, EHT0, EHT1, EHT2, EHT3, EHT4, EHT5, EHT6, EHT7, EPMM2, EPMM3, EPMM4, EPMM5, EPMM6, EPMM7, EPMOL, EPMOH, EWOLIE, EWOLIR, PHSTAT1, PHHID1, PHHID2, PHSTAT2, PHIE, PHIR, ERXFCON_ANDOR, ERXFCON_MPEN, ERXFCON_HTEN, ERXFCON_MCEN, ERXFCON_BCEN, EIE_DMAIE, EIE_LINKIE, EIE_TXIE, EIE_WOLIE, EIE_TXERIE, EIR_PKTIF, EIR_DMAIF, EIR_LINKIF, EIR_TXIF, EIR_WOLIF, EIR_RXERIF, ESTAT_INT, ESTAT_LATECOL, ESTAT_RXBUSY, ESTAT_TXABRT, ECON2_AUTOINC, ECON2_PWRSV, ECON2_VRPS, ECON1_TXRST, ECON1_RXRST, ECON1_DMAST, ECON1_CSUMEN, MACON1_LOOPBK, MACON1_PASSALL, MACON2_MARST, MACON2_RNDRST, MACON2_MARXRST, MACON2_RFUNRST, MACON2_MATXRST, MACON2_TFUNRST, MACON3_PADCFG2, MACON3_PADCFG1, MACON3_PHDRLEN, MACON3_HFRMLEN, MICMD_MIISCAN, MICMD_MIIRD, MISTAT_NVALID, MISTAT_SCAN, PHCON1_PRST, PHCON1_PLOOPBK, PHCON1_PPWRSV, PHSTAT1_PFDPX, PHSTAT1_PHDPX, PHSTAT1_LLSTAT, PHSTAT1_JBSTAT, PHCON2_FRCLINK, PHCON2_TXDIS, PHCON2_JABBER, PKTCTRL_PHUGEEN, PKTCTRL_PPADEN, PKTCTRL_PCRCEN, PKTCTRL_POVERRIDE
|
一派護法 十九級 |
【精简后的ENC28J60.h头文件】 #define EIE 0x1b #define EIR 0x1c #define ESTAT 0x1d #define ECON2 0x1e #define ECON1 0x1f
// Bank 0 registers #define ERDPTL 0x00 #define ERDPTH 0x01 #define EWRPTL 0x02 #define EWRPTH 0x03 #define ETXSTL 0x04 #define ETXSTH 0x05 #define ETXNDL 0x06 #define ETXNDH 0x07 #define ERXSTL 0x08 #define ERXSTH 0x09 #define ERXNDL 0x0a #define ERXNDH 0x0b #define ERXRDPTL 0x0c #define ERXRDPTH 0x0d
// Bank 1 registers #define EPMM0 0x28 #define EPMM1 0x29 #define EPMCSL 0x30 #define EPMCSH 0x31 #define ERXFCON 0x38 #define EPKTCNT 0x39
// Bank 2 registers #define MACON1 0xc0 #define MACON2 0xc1 #define MACON3 0xc2 #define MABBIPG 0xc4 #define MAIPGL 0xc6 #define MAIPGH 0xc7 #define MAMXFLL 0xca #define MAMXFLH 0xcb #define MIREGADR 0xd4 #define MIWRL 0xd6 #define MIWRH 0xd7
// Bank 3 registers #define MAADR1 0xe0 #define MAADR0 0xe1 #define MAADR3 0xe2 #define MAADR2 0xe3 #define MAADR5 0xe4 #define MAADR4 0xe5 #define MISTAT 0xea
// PHY registers #define PHCON1 0x00 #define PHCON2 0x10 #define PHLCON 0x14
#define ERXFCON_UCEN 0x80 #define ERXFCON_CRCEN 0x20 #define ERXFCON_PMEN 0x10 #define EIE_INTIE 0x80 #define EIE_PKTIE 0x40 #define EIE_RXERIE 0x01 #define EIR_TXERIF 0x02 #define ESTAT_CLKRDY 0x01 #define ECON2_PKTDEC 0x40 #define ECON1_TXRTS 0x08 #define ECON1_RXEN 0x04 #define ECON1_BSEL1 0x02 #define ECON1_BSEL0 0x01 #define MACON1_TXPAUS 0x08 #define MACON1_RXPAUS 0x04 #define MACON1_MARXEN 0x01 #define MACON3_PADCFG0 0x20 #define MACON3_TXCRCEN 0x10 #define MACON3_FRMLNEN 0x02 #define MACON3_FULDPX 0x01 #define MISTAT_BUSY 0x01 #define PHCON1_PDPXMD 0x0100 #define PHCON2_HDLDIS 0x0100
/* 指令集, 详见数据手册26页 */ #define ENC28J60_READ_CTRL_REG 0x00 // 读控制寄存器 #define ENC28J60_READ_BUF_MEM 0x3a // 读缓冲区 #define ENC28J60_WRITE_CTRL_REG 0x40 // 写控制寄存器 #define ENC28J60_WRITE_BUF_MEM 0x7a // 写缓冲区 #define ENC28J60_BIT_FIELD_SET 0x80 // 位域置位 #define ENC28J60_BIT_FIELD_CLR 0xa0 // 位域清零 #define ENC28J60_SOFT_RESET 0xff // 系统复位
#define RXSTART_INIT 0 // 接收缓冲区起始地址 #define RXSTOP_INIT (0x1fff - 0x0600 - 1) // 接收缓冲区停止地址 #define TXSTART_INIT (0x1fff - 0x0600) // 发送缓冲区起始地址, 大小约1500字节 #define TXSTOP_INIT 0x1fff // 发送缓冲区停止地址 #define MAX_FRAMELEN 1500 // 以太网报文最大长度
void ENC28J60_BeginSend(void); void ENC28J60_EndReceive(void); uint16_t ENC28J60_GetPacketLength(void); uint8_t ENC28J60_GetPacketNum(void); void ENC28J60_Init(uint8_t *mac_addr); void ENC28J60_InitSend(uint16_t len); uint8_t ENC28J60_Read(uint8_t addr); void ENC28J60_ReadBuf(uint8_t *p, uint16_t len); uint8_t ENC28J60_ReadOP(uint8_t op, uint8_t addr); void ENC28J60_SetBank(uint8_t addr); void ENC28J60_Write(uint8_t addr, uint8_t data); void ENC28J60_WriteBuf(uint8_t *p, uint16_t len); void ENC28J60_WriteOP(uint8_t op, uint8_t addr, uint8_t data); void ENC28J60_WritePhy(uint8_t addr, uint16_t data);
|
|
|
|