⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enc28j60.lst

📁 ENC28J60 System HTTP
💻 LST
📖 第 1 页 / 共 5 页
字号:
   1               		.file	"enc28j60.c"
   2               	__SREG__ = 0x3f
   3               	__SP_H__ = 0x3e
   4               	__SP_L__ = 0x3d
   5               	__CCP__  = 0x34
   6               	__tmp_reg__ = 0
   7               	__zero_reg__ = 1
   8               		.global __do_copy_data
   9               		.global __do_clear_bss
  11               		.text
  12               	.Ltext0:
  95               	.global	enc28j60_read_buffer
  97               	enc28j60_read_buffer:
   1:io/enc28j60.c **** /*
   2:io/enc28j60.c **** ,-----------------------------------------------------------------------------------------.
   3:io/enc28j60.c **** | io/enc28j60
   4:io/enc28j60.c **** |-----------------------------------------------------------------------------------------
   5:io/enc28j60.c **** | this file implements the driver for the microchip enc28j60 ethernet controller
   6:io/enc28j60.c **** | - some ideas are based on the enc28j60 driver of the procyon avrlib ;)
   7:io/enc28j60.c **** |
   8:io/enc28j60.c **** | BUGS:
   9:io/enc28j60.c **** | - sometimes enc28j60 is not correctly initialised (not receiving any packets)
  10:io/enc28j60.c **** |
  11:io/enc28j60.c **** | Author   : Simon Schulz / avr{AT}auctionant.de
  12:io/enc28j60.c **** |
  13:io/enc28j60.c **** | 
  14:io/enc28j60.c **** |
  15:io/enc28j60.c **** |-----------------------------------------------------------------------------------------
  16:io/enc28j60.c **** | License:
  17:io/enc28j60.c **** | This program is free software; you can redistribute it and/or modify it under
  18:io/enc28j60.c **** | the terms of the GNU General Public License as published by the Free Software
  19:io/enc28j60.c **** | Foundation; either version 2 of the License, or (at your option) any later
  20:io/enc28j60.c **** | version.
  21:io/enc28j60.c **** | This program is distributed in the hope that it will be useful, but
  22:io/enc28j60.c **** |
  23:io/enc28j60.c **** | WITHOUT ANY WARRANTY;
  24:io/enc28j60.c **** |
  25:io/enc28j60.c **** | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  26:io/enc28j60.c **** | PURPOSE. See the GNU General Public License for more details.
  27:io/enc28j60.c **** |
  28:io/enc28j60.c **** | You should have received a copy of the GNU General Public License along with
  29:io/enc28j60.c **** | this program; if not, write to the Free Software Foundation, Inc., 51
  30:io/enc28j60.c **** | Franklin St, Fifth Floor, Boston, MA 02110, USA
  31:io/enc28j60.c **** |
  32:io/enc28j60.c **** | http://www.gnu.de/gpl-ger.html
  33:io/enc28j60.c **** `-----------------------------------------------------------------------------------------*/
  34:io/enc28j60.c **** #include "enc28j60.h"
  35:io/enc28j60.c **** 
  36:io/enc28j60.c **** //ACTIVATE DEBUG by editing this file:
  37:io/enc28j60.c **** #include "debug.h"
  38:io/enc28j60.c **** 
  39:io/enc28j60.c **** volatile unsigned char enc28j60_current_bank;
  40:io/enc28j60.c **** volatile unsigned int  enc28j60_next_packet_ptr;
  41:io/enc28j60.c **** unsigned char enc28j60_revision;
  42:io/enc28j60.c **** #include <avr/pgmspace.h>
  43:io/enc28j60.c **** 
  44:io/enc28j60.c **** //store enc28j60 config in program memory
  45:io/enc28j60.c **** //syntax: <REGx>, <REGVALx>, <REGy>, <REGVALy>,...
  46:io/enc28j60.c **** unsigned char enc28j60_config[] PROGMEM = {
  47:io/enc28j60.c **** 	//setup bank0 (config stored in progmem, see above)
  48:io/enc28j60.c **** 	//tx buffer:
  49:io/enc28j60.c **** 	ENC28J60_REG_ETXSTL, lo8(ENC28J60_TX_BUFFER_START), //start lo
  50:io/enc28j60.c **** 	ENC28J60_REG_ETXSTH, hi8(ENC28J60_TX_BUFFER_START), //start hi
  51:io/enc28j60.c **** 	ENC28J60_REG_ETXNDL, lo8(ENC28J60_TX_BUFFER_END  ), //end lo
  52:io/enc28j60.c **** 	ENC28J60_REG_ETXNDH, hi8(ENC28J60_TX_BUFFER_END  ), //end hi
  53:io/enc28j60.c **** 	//rx buffer
  54:io/enc28j60.c **** 	ENC28J60_REG_ERXSTL, lo8(ENC28J60_RX_BUFFER_START), //start lo
  55:io/enc28j60.c **** 	ENC28J60_REG_ERXSTH, hi8(ENC28J60_RX_BUFFER_START), //start hi
  56:io/enc28j60.c **** 	ENC28J60_REG_ERXNDL, lo8(ENC28J60_RX_BUFFER_END  ), //end lo
  57:io/enc28j60.c **** 	ENC28J60_REG_ERXNDH, hi8(ENC28J60_RX_BUFFER_END  ), //end hi
  58:io/enc28j60.c **** 	//rx ptr:
  59:io/enc28j60.c **** 	//ENC28J60_REG_ERDPTL, lo8(ENC28J60_RX_BUFFER_START+1),
  60:io/enc28j60.c **** 	//ENC28J60_REG_ERDPTH, hi8(ENC28J60_RX_BUFFER_START+1),
  61:io/enc28j60.c **** 
  62:io/enc28j60.c **** 	//setup bank2: (see microchip datasheet p.36)
  63:io/enc28j60.c **** 	//1.) clear the MARST bit in MACON2.
  64:io/enc28j60.c **** 	ENC28J60_REG_MACON2, 	0x00,
  65:io/enc28j60.c **** 	//2.) mac rx enable, activate pause control frame support
  66:io/enc28j60.c **** 	ENC28J60_REG_MACON1, 	((1<<ENC28J60_BIT_MARXEN)|(1<<ENC28J60_BIT_RXPAUS)|(1<<ENC28J60_BIT_TXPAUS))
  67:io/enc28j60.c **** 	//3.) setup MACON3: auto padding of small packets, add crc, enable frame length check:
  68:io/enc28j60.c **** 	ENC28J60_REG_MACON3, 	((1<<ENC28J60_BIT_PADCFG0)|(1<<ENC28J60_BIT_TXCRCEN)|(1<<ENC28J60_BIT_FRMLNE
  69:io/enc28j60.c **** 	//4.) dont set up MACON4 (use default)
  70:io/enc28j60.c **** 	//5.) setup maximum framelenght to 1518:
  71:io/enc28j60.c **** 	ENC28J60_REG_MAMXFLL, lo8(1518),
  72:io/enc28j60.c **** 	ENC28J60_REG_MAMXFLH, hi8(1518),
  73:io/enc28j60.c **** 	//6.) set up back-to-back gap: 0x15 for full duplex / 0x12 for half duplex
  74:io/enc28j60.c **** 	ENC28J60_REG_MABBIPG, 0x12, //half duplex
  75:io/enc28j60.c **** 	//7.) setup non-back-to-back gap: use 0x12
  76:io/enc28j60.c **** 	ENC28J60_REG_MAIPGL, 	0x12,
  77:io/enc28j60.c **** 	//8.) setup non-back-to-back gap high byte: 0x0C for half duplex:
  78:io/enc28j60.c **** 	ENC28J60_REG_MAIPGH, 	0x0C, //half duplex
  79:io/enc28j60.c **** 	//9.) dont change MACLCON1+2 / MACLCON2 might be changed for networks with long wires !
  80:io/enc28j60.c **** 
  81:io/enc28j60.c **** 	//setup bank3:
  82:io/enc28j60.c **** 	//10.) programm mac address: BYTE BACKWARD !
  83:io/enc28j60.c **** 	ENC28J60_REG_MAADR5, NIC_MAC0,
  84:io/enc28j60.c **** 	ENC28J60_REG_MAADR4, NIC_MAC1,
  85:io/enc28j60.c **** 	ENC28J60_REG_MAADR3, NIC_MAC2,
  86:io/enc28j60.c **** 	ENC28J60_REG_MAADR2, NIC_MAC3,
  87:io/enc28j60.c **** 	ENC28J60_REG_MAADR1, NIC_MAC4,
  88:io/enc28j60.c **** 	ENC28J60_REG_MAADR0, NIC_MAC5
  89:io/enc28j60.c **** 	};
  90:io/enc28j60.c **** 
  91:io/enc28j60.c **** 
  92:io/enc28j60.c **** //initialise spi & enc28j60
  93:io/enc28j60.c **** void enc28j60_init(void){
  94:io/enc28j60.c **** 	unsigned char i;
  95:io/enc28j60.c **** 
  96:io/enc28j60.c **** 	//set bank to invalid value -> bank set will update in any case:
  97:io/enc28j60.c **** 	enc28j60_current_bank = 0xFF;
  98:io/enc28j60.c **** 
  99:io/enc28j60.c **** 	//set up port directions:
 100:io/enc28j60.c **** 	ENC28J60_DDR |= (1<<ENC28J60_PIN_CS)|(1<<ENC28J60_PIN_RESET);
 101:io/enc28j60.c **** 	
 102:io/enc28j60.c **** 	//deselect enc28j60:
 103:io/enc28j60.c **** 	ENC28J60_CS_HI();
 104:io/enc28j60.c **** 
 105:io/enc28j60.c **** 	//SPI init
 106:io/enc28j60.c **** 	// initialize I/O
 107:io/enc28j60.c **** 	PORTB |= (1<<7); //sck = hi
 108:io/enc28j60.c **** 
 109:io/enc28j60.c **** 	//spi = output
 110:io/enc28j60.c **** 	//mega8//DDRB |= (1<<2)|(1<<3)|(1<<5); //SS,MOSI,SCK = OUT
 111:io/enc28j60.c **** 	DDRB |= (1<<4)|(1<<5)|(1<<7); //SS,MOSI,SCK = OUT
 112:io/enc28j60.c **** 	DDRB &= ~(1<<6); //MISO = IN
 113:io/enc28j60.c **** 
 114:io/enc28j60.c **** 	//SPI init:
 115:io/enc28j60.c **** 	// - master mode
 116:io/enc28j60.c **** 	// - positive clock phase
 117:io/enc28j60.c **** 	// - msb first
 118:io/enc28j60.c **** 	// - maximum SPI speed (fosc/2)
 119:io/enc28j60.c **** 	// - enable spi
 120:io/enc28j60.c **** 	SPCR = (0<<CPOL)|(1<<MSTR)|(0<<DORD)|(0<<SPR1)|(0<<SPR0)|(1<<SPE);
 121:io/enc28j60.c **** 	SPSR = (1<<SPI2X);
 122:io/enc28j60.c **** 
 123:io/enc28j60.c **** 	//reset enc28j60:
 124:io/enc28j60.c **** 	ENC28J60_RESET_LO();
 125:io/enc28j60.c **** 	_delay_ms(10);
 126:io/enc28j60.c **** 	ENC28J60_RESET_HI();
 127:io/enc28j60.c **** 
 128:io/enc28j60.c **** 	//after reset we have to wait at least 50us ! 
 129:io/enc28j60.c **** 	_delay_us(60);
 130:io/enc28j60.c **** 	//workaround for bad chip revisions: wait >1ms (wait 10ms...)
 131:io/enc28j60.c **** 	_delay_ms(10);
 132:io/enc28j60.c **** 	
 133:io/enc28j60.c **** 	//wait for ready flag
 134:io/enc28j60.c **** 	while(!(enc28j60_read_address(ENC28J60_REG_ESTAT) & 0x01)){};
 135:io/enc28j60.c **** 
 136:io/enc28j60.c **** 	//set up rx pointer:	
 137:io/enc28j60.c **** 	enc28j60_next_packet_ptr = ENC28J60_RX_BUFFER_START;
 138:io/enc28j60.c **** 	//enc28j60_next_packet_ptr = 0x0602;
 139:io/enc28j60.c **** 
 140:io/enc28j60.c **** 	//copy config from progmem to enc28j60:
 141:io/enc28j60.c **** 	for(i=0; i<2*22; i+=2){
 142:io/enc28j60.c **** 		enc28j60_write_address(pgm_read_byte(&enc28j60_config[i+0]),pgm_read_byte(&enc28j60_config[i+1]))
 143:io/enc28j60.c **** 	}
 144:io/enc28j60.c **** 	
 145:io/enc28j60.c **** 	//setup phy:
 146:io/enc28j60.c **** 	enc28j60_write_phy(ENC28J60_PHY_PHCON2, (1<<ENC28J60_BIT_HDLDIS)); //=no loopback of transmitted f
 147:io/enc28j60.c **** 	
 148:io/enc28j60.c **** 	//enable interrups
 149:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_EIE, (1<<6)|(1<<7));
 150:io/enc28j60.c **** 
 151:io/enc28j60.c **** 	//enable rx
 152:io/enc28j60.c **** 	//enc28j60_write_address(ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_RXEN));
 153:io/enc28j60.c **** 	enc28j60_spi_write_word(ENC28J60_OP_BFS|ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_RXEN));
 154:io/enc28j60.c **** 	
 155:io/enc28j60.c **** 	//set up leds: LEDA: link status, LEDB: RX&TX activity
 156:io/enc28j60.c **** 	enc28j60_write_phy(ENC28J60_PHY_PHLCON, 0x0472);
 157:io/enc28j60.c **** 
 158:io/enc28j60.c **** 	//read silicon revision
 159:io/enc28j60.c **** 	enc28j60_revision = enc28j60_read_address(ENC28J60_REG_EREVID);
 160:io/enc28j60.c **** }
 161:io/enc28j60.c **** 
 162:io/enc28j60.c **** void enc28j60_send_packet(unsigned char *buffer, unsigned int len){
 163:io/enc28j60.c **** 	unsigned int tmp;
 164:io/enc28j60.c **** 	//still sending ?
 165:io/enc28j60.c **** 	//wait max 50*10 = 500ms:
 166:io/enc28j60.c **** 	for(tmp=0; tmp<50; tmp++){
 167:io/enc28j60.c **** 		if (!(enc28j60_read_address(ENC28J60_REG_ECON1) & (1<<ENC28J60_BIT_TXRTS))){
 168:io/enc28j60.c **** 			//send finished -> tx packet
 169:io/enc28j60.c **** 			break;
 170:io/enc28j60.c **** 		}
 171:io/enc28j60.c **** 		//tx not finished yet, wait 10ms
 172:io/enc28j60.c **** 		_delay_ms(10);
 173:io/enc28j60.c **** 	}
 174:io/enc28j60.c **** 	
 175:io/enc28j60.c **** 	//send anyway...
 176:io/enc28j60.c **** 
 177:io/enc28j60.c **** 	//setup write pointer:
 178:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_EWRPTL, (ENC28J60_TX_BUFFER_START&0xFF));
 179:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_EWRPTH, (ENC28J60_TX_BUFFER_START)>>8);
 180:io/enc28j60.c **** 	
 181:io/enc28j60.c **** 	//set tx end pointer to [start+len]:
 182:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_ETXNDL, (ENC28J60_TX_BUFFER_START+len)&0xFF);
 183:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_ETXNDH, (ENC28J60_TX_BUFFER_START+len)>>8);
 184:io/enc28j60.c **** 
 185:io/enc28j60.c **** 	//start buffer write command
 186:io/enc28j60.c **** 	enc28j60_spi_write_word(ENC28J60_OP_WRITE_BUF_MEM, 0x00);
 187:io/enc28j60.c **** 
 188:io/enc28j60.c **** 	//copy buffer to enc28j60:
 189:io/enc28j60.c **** 	enc28j60_write_buffer(buffer, len);
 190:io/enc28j60.c **** 
 191:io/enc28j60.c **** 	//bad silicon workaround:
 192:io/enc28j60.c **** 	//reset tx logic:
 193:io/enc28j60.c **** 	enc28j60_spi_write_word(ENC28J60_OP_BFS | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRST));
 194:io/enc28j60.c **** 	enc28j60_spi_write_word(ENC28J60_OP_BFC | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRST));
 195:io/enc28j60.c **** 
 196:io/enc28j60.c **** 	//activate transmission
 197:io/enc28j60.c **** 	enc28j60_spi_write_word(ENC28J60_OP_BFS | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRTS)|(1<<ENC28J60
 198:io/enc28j60.c **** }
 199:io/enc28j60.c **** 
 200:io/enc28j60.c **** unsigned int enc28j60_receive_packet(unsigned char *buffer, unsigned int maxlen){
 201:io/enc28j60.c **** 	unsigned int rxstat;
 202:io/enc28j60.c **** 	unsigned int len;
 203:io/enc28j60.c **** 
 204:io/enc28j60.c **** 	#if ENC_DEBUG
 205:io/enc28j60.c **** 	unsigned int pktcnt = enc28j60_read_address(ENC28J60_REG_EPKTCNT);
 206:io/enc28j60.c **** 	if (CLOCK_TEST_FLAG(CLOCK_SEC) || pktcnt != 0){
 207:io/enc28j60.c **** 		softuart_puts_progmem("ENC : pktcnt ");
 208:io/enc28j60.c **** 		softuart_put_uint16(pktcnt);
 209:io/enc28j60.c **** 		softuart_puts_progmem(" pktflag ");
 210:io/enc28j60.c **** 		if ((enc28j60_read_address(ENC28J60_REG_EIR) & (1<<ENC28J60_BIT_PKTIF)))
 211:io/enc28j60.c **** 			softuart_putc('1');
 212:io/enc28j60.c **** 		else
 213:io/enc28j60.c **** 			softuart_putc('0');
 214:io/enc28j60.c **** 		softuart_putnewline();
 215:io/enc28j60.c **** 	}
 216:io/enc28j60.c **** 	#endif
 217:io/enc28j60.c **** 
 218:io/enc28j60.c **** 	//packet in buffer ?	
 219:io/enc28j60.c **** 	if ((enc28j60_read_address(ENC28J60_REG_EIR) & (1<<ENC28J60_BIT_PKTIF)) == 0){
 220:io/enc28j60.c **** 		//double check!	
 221:io/enc28j60.c **** 		//errata says that PKTIF does not work as it should 
 222:io/enc28j60.c **** 		//->check packetcount too:
 223:io/enc28j60.c **** 		if (enc28j60_read_address(ENC28J60_REG_EPKTCNT) == 0)
 224:io/enc28j60.c **** 			return 0;
 225:io/enc28j60.c **** 	}
 226:io/enc28j60.c **** 
 227:io/enc28j60.c **** 	//set read pointer to next packet;
 228:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_ERDPTL, (enc28j60_next_packet_ptr));
 229:io/enc28j60.c **** 	enc28j60_write_address(ENC28J60_REG_ERDPTH, (enc28j60_next_packet_ptr)>>8);
 230:io/enc28j60.c **** 	#if ENC_DEBUG
 231:io/enc28j60.c **** 	softuart_puts_progmem("ENC : nptr <= ");
 232:io/enc28j60.c **** 	softuart_put_uint16(enc28j60_next_packet_ptr);
 233:io/enc28j60.c **** 	softuart_putnewline();
 234:io/enc28j60.c **** 	#endif
 235:io/enc28j60.c **** 
 236:io/enc28j60.c **** 	//now read the transmit status vector
 237:io/enc28j60.c **** 	//read next packet ptr
 238:io/enc28j60.c **** 	enc28j60_next_packet_ptr  = enc28j60_spi_read_byte(ENC28J60_OP_READ_BUF_MEM, 0);
 239:io/enc28j60.c **** 	enc28j60_next_packet_ptr |= enc28j60_spi_read_byte(ENC28J60_OP_READ_BUF_MEM, 0)<<8;
 240:io/enc28j60.c ****   #if ENC_DEBUG
 241:io/enc28j60.c **** 	softuart_puts_progmem("ENC : nptr read: ");
 242:io/enc28j60.c **** 	softuart_put_uint16(enc28j60_next_packet_ptr);
 243:io/enc28j60.c **** 	softuart_putnewline();
 244:io/enc28j60.c **** 	#endif
 245:io/enc28j60.c **** 
 246:io/enc28j60.c **** 	//read packet length
 247:io/enc28j60.c **** 	len  = enc28j60_spi_read_byte(ENC28J60_OP_READ_BUF_MEM, 0);
 248:io/enc28j60.c **** 	len |= enc28j60_spi_read_byte(ENC28J60_OP_READ_BUF_MEM, 0)<<8;
 249:io/enc28j60.c **** 	
 250:io/enc28j60.c **** 	//read rx stat
 251:io/enc28j60.c **** 	rxstat  = enc28j60_spi_read_byte(ENC28J60_OP_READ_BUF_MEM, 0);
 252:io/enc28j60.c **** 	rxstat |= enc28j60_spi_read_byte(ENC28J60_OP_READ_BUF_MEM, 0)<<8;
 253:io/enc28j60.c **** 
 254:io/enc28j60.c **** 	//limit read bytecount
 255:io/enc28j60.c **** 	if (len>maxlen)
 256:io/enc28j60.c **** 		len = maxlen;
 257:io/enc28j60.c **** 
 258:io/enc28j60.c **** 	//tranfer packet from enc28j60 to our buffer
 259:io/enc28j60.c **** 	enc28j60_read_buffer(buffer,len);
 260:io/enc28j60.c **** 
 261:io/enc28j60.c **** 	//mark packet as processed (free mem)
 262:io/enc28j60.c **** 
 263:io/enc28j60.c **** 	//ERRATA says we need to check packet pointer:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -