'----------------------------------------------------------- ' Atmega168 and ENC28J60 '----------------------------------------------------------- ' Version 1.0 - june 2007 'fusebits: 'Atmega168 - External clock No div by 8 $regfile = "m168def.dat" $crystal = 6250000 $baud = 9600 'You have to use 19200 in Hyperterminal $hwstack = 128 $swstack = 128 $framesize = 128 $include "enc28j60.inc" Config Portb.1 = Output Config Portb.2 = Output Enc28j60_cs Alias Portb.2 Dim X As Byte Dim A(65) As Byte Dim Bank As Byte Dim Enc28j60_data As Byte Dim Value As Byte Dim Wdata As Word Declare Sub Enc28j60init Declare Sub Enc28j60readcontrolregbyte(byval Register As Byte) Declare Sub Enc28j60writecontrolregbyte(byval Register As Byte , Byval Value As Byte) Declare Sub Enc28j60selectbank(byval Bank As Byte) Declare Sub Enc28j60bitfield_set(byval Register As Byte , Byval Value As Byte) Declare Sub Enc28j60bitfield_clear(byval Register As Byte , Byval Value As Byte) Declare Sub Enc28j60readphyword(byval Phyregister As Byte) Declare Sub Enc28j60writephyword(byval Phyregister As Byte , Byval Wdata As Word) Declare Sub Enc28j60packetsend(byval Pcktlen As Word) ' , Byval Packet As Byte) Declare Sub Enc28j60writebuffer ' (byval Pcktlen As Word , Pcktdata As Byte) Declare Sub Enc28j60regdump '/* The Ethernet address. */ Const Ethaddr0 = &H43 Const Ethaddr1 = &HC6 Const Ethaddr2 = &HB3 Const Ethaddr3 = &HF3 Const Ethaddr4 = &HAB Const Ethaddr5 = &H9E max_framelen = 200 'Configuration of the SPI-bus Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 'init the spi pins Spiinit Enc28j60_cs = 0 'reset ENC28J60 X = Enc28j60_soft_reset Spiout X , 1 Enc28j60_cs = 1 Do Call Enc28j60readcontrolregbyte(estat) X = Enc28j60_data.estat_clkrdy Loop Until X = 1 'clock from default divide/4 (6.25 Mhz) to divide/2 (12.5 Mhz) Call Enc28j60writecontrolregbyte(ecocon , &B00000010) Waitms 250 Print Print "Starting Tux" Call Enc28j60selectbank(3) 'EREVID A(1) = &B000_10010 Enc28j60_cs = 0 Spiout A(1) , 1 Spiin A(1) , 2 Print "Enc28j60-version = " ; A(2) Enc28j60_cs = 1 Call Enc28j60init Value = 0 Value.econ1_txrst = 1 Call Enc28j60bitfield_set(econ1 , Value) Call Enc28j60bitfield_clear(econ1 , Value) Call Enc28j60regdump Call Enc28j60writebuffer Call Enc28j60packetsend(60) Print "End program" End Sub Enc28j60init 'do bank 0 stuff 'initialize receive buffer '16-bit transfers, must write low byte first 'set receive buffer start address Value = Low(rxstart_init) Call Enc28j60writecontrolregbyte(erxstl , Value) Value = High(rxstart_init) Call Enc28j60writecontrolregbyte(erxsth , Value) 'set receive pointer address Value = Low(rxstart_init) Call Enc28j60writecontrolregbyte(erxrdptl , Value) Value = High(rxstart_init) Call Enc28j60writecontrolregbyte(erxrdpth , Value) 'set receive buffer end Value = Low(rxstop_init) Call Enc28j60writecontrolregbyte(erxndl , Value) Value = High(rxstop_init) Call Enc28j60writecontrolregbyte(erxndh , Value) 'set transmit buffer start Value = Low(txstart_init) Call Enc28j60writecontrolregbyte(etxstl , Value) Value = High(txstart_init) Call Enc28j60writecontrolregbyte(etxsth , Value) 'do bank 2 stuff 'enable MAC receive Value = 0 Value.macon1_marxen = 1 Value.macon1_txpaus = 1 Value.macon1_rxpaus = 1 Call Enc28j60writecontrolregbyte(macon1 , Value) 'bring MAC out of reset 'enable automatic padding and CRC operations Value = 0 Value.macon3_padcfg0 = 1 Value.macon3_txcrcen = 1 Value.macon3_frmlnen = 1 Call Enc28j60writecontrolregbyte(macon3 , Value) 'set inter-frame gap (non-back-to-back) Call Enc28j60writecontrolregbyte(maipgl , &H12) Call Enc28j60writecontrolregbyte(maipgh , &H0C) 'set inter-frame gap (back-to-back) Call Enc28j60writecontrolregbyte(mabbipg , &H12) 'set the maximum packet size which the controller will accept Value = Low(max_framelen) Call Enc28j60writecontrolregbyte(mamxfll , Value) Value = High(max_framelen) Call Enc28j60writecontrolregbyte(mamxflh , Value) 'bank 3 stuff Call Enc28j60writecontrolregbyte(maadr5 , Ethaddr0) Call Enc28j60writecontrolregbyte(maadr4 , Ethaddr1) Call Enc28j60writecontrolregbyte(maadr3 , Ethaddr2) Call Enc28j60writecontrolregbyte(maadr2 , Ethaddr3) Call Enc28j60writecontrolregbyte(maadr1 , Ethaddr4) Call Enc28j60writecontrolregbyte(maadr0 , Ethaddr5) 'no loopback of transmitted frames Call Enc28j60writephyword(phcon2 , Phcon2_hdldis) 'switch to bank 0 Call Enc28j60selectbank(0) 'enable interrupts Value = 0 Value.eie_intie = 1 Value.eie_pktie = 1 Call Enc28j60bitfield_set(eie , Value) 'enable packet reception Value = 0 Value.econ1_rxen = 1 Call Enc28j60bitfield_set(econ1 , Value) End Sub Sub Enc28j60selectbank(bank As Byte) 'get ECON1 (BSEL1 en BSEL0) A(1) = &B000_11111 Enc28j60_cs = 0 Spiout A(1) , 1 Spiin A(1) , 2 Enc28j60_cs = 1 A(2) = A(2) And &B1111_1100 'strip bank part A(2) = A(2) Or Bank A(1) = &B010_11111 Enc28j60_cs = 0 Spiout A(1) , 2 Enc28j60_cs = 1 End Sub Sub Enc28j60writecontrolregbyte(register As Byte , Value As Byte) Bank = 0 If Register.7 = 1 Then Bank = 2 If Register.6 = 1 Then Bank = Bank + 1 Register = Register And &B00011111 Call Enc28j60selectbank(bank) Register.6 = 1 'to get a 010_register A(1) = Register A(2) = Value Enc28j60_cs = 0 Spiout A(1) , 2 Enc28j60_cs = 1 End Sub Sub Enc28j60readcontrolregbyte(register As Byte) Local Mcphy As Byte Bank = 0 Mcphy = 0 If Register.7 = 1 Then Bank = 2 If Register.6 = 1 Then Bank = Bank + 1 If Register.5 = 1 Then Mcphy = 1 Register = Register And &B00011111 Call Enc28j60selectbank(bank) A(1) = Register Enc28j60_cs = 0 Spiout A(1) , 1 Spiin A(1) , 3 Enc28j60_cs = 1 'Depending of register (E, MAC, MII) yes or no dummybyte If Mcphy = 1 Then Enc28j60_data = A(2) Else Enc28j60_data = A(3) End If End Sub Sub Enc28j60bitfield_set(register As Byte , Value As Byte) Bank = 0 If Register.7 = 1 Then Bank = 2 If Register.6 = 1 Then Bank = Bank + 1 Register = Register And &B00011111 Call Enc28j60selectbank(bank) Register = Register Or &B100_00000 A(1) = Register A(2) = Value Enc28j60_cs = 0 Spiout A(1) , 2 Enc28j60_cs = 1 End Sub Sub Enc28j60bitfield_clear(register As Byte , Value As Byte) Bank = 0 If Register.7 = 1 Then Bank = 2 If Register.6 = 1 Then Bank = Bank + 1 Register = Register And &B00011111 Call Enc28j60selectbank(bank) Register = Register Or &B101_00000 A(1) = Register A(2) = Value Enc28j60_cs = 0 Spiout A(1) , 2 Enc28j60_cs = 1 End Sub Sub Enc28j60readphyword(phyregister As Byte) 'set the right address and start the register read operation Call Enc28j60writecontrolregbyte(miregadr , Phyregister) Call Enc28j60writecontrolregbyte(micmd , Micmd_miird) 'wait until the PHY read complets Do Call Enc28j60readcontrolregbyte(mistat) Loop Until Enc28j60_data.mistat_busy = 0 'quit reading Call Enc28j60writecontrolregbyte(micmd , 0) 'get data value Call Enc28j60readcontrolregbyte(mirdl) Wdata = Enc28j60_data Shift Wdata , Left , 8 Call Enc28j60readcontrolregbyte(mirdh) Wdata = Wdata + Enc28j60_data End Sub Sub Enc28j60writephyword(phyregister As Byte , Wdata As Word) Call Enc28j60readphyword(phyregister) Local Temp As Byte Local Odata As Word 'set the PHY register address ' ' here still some work to do ' Call Enc28j60writecontrolregbyte(miregadr , Phyregister) Call Enc28j60readcontrolregbyte(miregadr) Temp = Miregadr Value = Low(wdata) Call Enc28j60writecontrolregbyte(miwrl , Value) Value = High(wdata) Call Enc28j60writecontrolregbyte(miwrh , Value) Do Call Enc28j60readcontrolregbyte(mistat) Loop Until Enc28j60_data.mistat_busy = 0 End Sub Sub Enc28j60packetsend(pcktlen As Word) Value = 0 Value.econ1_txrst = 1 Call Enc28j60bitfield_set(econ1 , Value) Value.econ1_txrst = 1 Call Enc28j60bitfield_clear(econ1 , Value) 'set the write pointer to start of transmit buffer area Value = Low(txstart_init) Call Enc28j60writecontrolregbyte(ewrptl , Value) Value = High(txstart_init) Call Enc28j60writecontrolregbyte(ewrpth , Value) 'set the TXND pointer to correspond to the packet size given Value = Low(txstart_init) Value = Value + Low(pcktlen) Call Enc28j60writecontrolregbyte(etxndl , Value) Value = High(txstart_init) Value = Value + High(pcktlen) Call Enc28j60writecontrolregbyte(etxndh , Value) 'send the contents of the transmit buffer onto the network Value = 0 Value.econ1_txrts = 1 Call Enc28j60bitfield_set(econ1 , Value) End Sub Sub Enc28j60writebuffer ' (byval Pcktlen As Word , Pcktdata As Byte) 'tijdelijke test subroutine Print "Write buffer with test packet" A(1) = Enc28j60_write_buf_mem 'control A(2) = &H00 'per packet byte 'ARP A(3) = &HFF 'Broadcast A(4) = &HFF A(5) = &HFF A(6) = &HFF A(7) = &HFF A(8) = &HFF A(9) = Ethaddr0 'MAC-address of TUX-board A(10) = Ethaddr1 A(11) = Ethaddr2 A(12) = Ethaddr3 A(13) = Ethaddr4 A(14) = Ethaddr5 A(15) = &H08 A(16) = &H06 A(17) = &H00 A(18) = &H01 A(19) = &H08 A(20) = &H00 A(21) = &H06 A(22) = &H04 A(23) = &H00 A(24) = &H01 A(25) = &H00 A(26) = &H01 A(27) = &H02 A(28) = &H03 A(29) = &H04 A(30) = &H05 A(31) = &HC0 'eigen IP-nummer A(32) = &HA8 A(33) = &H00 A(34) = &H3D A(35) = &H00 'MAC-address router A(36) = &H0C A(37) = &H41 A(38) = &HAE A(39) = &H7A A(40) = &HDC A(41) = &HC0 'IP-nummer router 192.168.0.254 A(42) = &HA8 A(43) = &H00 A(44) = &HFE A(45) = &H00 'padding A(46) = &H00 A(47) = &H00 A(48) = &H00 A(49) = &H00 A(50) = &H00 A(51) = &H00 A(52) = &H00 A(53) = &H00 A(54) = &H00 A(55) = &H00 A(56) = &H00 A(57) = &H00 A(58) = &H00 A(59) = &H00 A(60) = &H00 A(61) = &H00 A(62) = &H00 Enc28j60_cs = 0 Spiout A(1) , 62 '60 packetlen + writebuffer command + per-packet command Enc28j60_cs = 1 End Sub Sub Enc28j60regdump Print Print "Registerdump ENC28J60" Print Call Enc28j60readcontrolregbyte(erevid) Print "Version: " ; Enc28j60_data Print 'ok Print "Cntrl: ECON1 ECON2 ESTAT EIR EIE" Call Enc28j60readcontrolregbyte(econ1) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(econ2) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(estat) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(eir) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(eie) Print " " ; Hex(enc28j60_data) Print 'ok Print "MAC : MACON1 MACON2 MACON3 MACON4 MAC-Address" Call Enc28j60readcontrolregbyte(macon1) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(macon2) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(macon3) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(macon4) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maadr5) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maadr4) Print "." ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maadr3) Print "." ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maadr2) Print "." ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maadr1) Print "." ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maadr0) Print "." ; Hex(enc28j60_data) Print Print "Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL" Call Enc28j60readcontrolregbyte(erxsth) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxstl) Print Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxndh) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxndl) Print Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxwrpth) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxwrptl) Print Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxrdpth) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxrdptl) Print Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(erxfcon) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(epktcnt) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(mamxflh) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(mamxfll) Print Hex(enc28j60_data) Print Print "Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP" Call Enc28j60readcontrolregbyte(etxsth) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(etxstl) Print Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(etxndh) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(etxndl) Print Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maclcon1) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maclcon2) Print " " ; Hex(enc28j60_data); Call Enc28j60readcontrolregbyte(maphsup) Print " " ; Hex(enc28j60_data) Print End Sub