;*************************************************************************** ; ; File Name :"dm9000a.asm" ; Title :Davicom DM9000A Driver ; Date :2007.04.02. ; Version :1.0.0 ; Support telephone :+36-70-333-4034, old: +36-30-9541-658 VFX ; Support fax : ; Support Email :info@vfx.hu ; Target MCU :AVR ; ;*************************************************************************** ; D E S C R I P T I O N ; ; Davicom DM9000 ISA NIC fast Ethernet driver for AVR ; Based on "A Davicom DM9000A/DM9010 ISA NIC fast Ethernet driver for Linux" ; .equ ADR_LANS = 0x3FEF ;LAN command .equ ADR_LANI = 0x3FF0 ;DM9000A Index .equ ADR_LAND = 0x3FFF ;DM9000A Data ; ;*************************************************************************** ; M O D I F I C A T I O N H I S T O R Y ; ; ; rev. date who why ; ---- ---------- --- ------------------------------------ ; 0.01 2007.04.02 VFX Creation ; 0.02 2009.10.17 VFX Modify to DM9000B ; ;************************************************************************** ;* Hardware Def. ; DM9000A Ethernet .equ DM9000_ID = 0x90000A46 .equ DM9000_PKT_MAX = 1536 ;Received packet max size .equ DM9000_PKT_RDY = 0x01 ;Packet ready to receive ; although the registers are 16 bit, they are 32-bit aligned. .equ DM9000_NCR = 0x00 .equ DM9000_NSR = 0x01 .equ DM9000_TCR = 0x02 .equ DM9000_TSR1 = 0x03 .equ DM9000_TSR2 = 0x04 .equ DM9000_RCR = 0x05 .equ DM9000_RSR = 0x06 .equ DM9000_ROCR = 0x07 .equ DM9000_BPTR = 0x08 .equ DM9000_FCTR = 0x09 .equ DM9000_FCR = 0x0A .equ DM9000_EPCR = 0x0B .equ DM9000_EPAR = 0x0C .equ DM9000_EPDRL = 0x0D .equ DM9000_EPDRH = 0x0E .equ DM9000_WCR = 0x0F .equ DM9000_PAR = 0x10 .equ DM9000_MAR = 0x16 .equ DM9000_GPCR = 0x1e .equ DM9000_GPR = 0x1f .equ DM9000_TRPAL = 0x22 .equ DM9000_TRPAH = 0x23 .equ DM9000_RWPAL = 0x24 .equ DM9000_RWPAH = 0x25 .equ DM9000_VIDL = 0x28 .equ DM9000_VIDH = 0x29 .equ DM9000_PIDL = 0x2A .equ DM9000_PIDH = 0x2B .equ DM9000_CHIPR = 0x2C .equ DM9000_SMCR = 0x2F .equ DM9000_PHY = 0x40 ;PHY address 0x01 .equ DM9000_MRCMDX = 0xF0 .equ DM9000_MRCMDX1 = 0xF1 ;see DM9000B datasheet .equ DM9000_MRCMD = 0xF2 .equ DM9000_MRRL = 0xF4 .equ DM9000_MRRH = 0xF5 .equ DM9000_MWCMDX = 0xF6 .equ DM9000_MWCMD = 0xF8 .equ DM9000_MWRL = 0xFA .equ DM9000_MWRH = 0xFB .equ DM9000_TXPLL = 0xFC .equ DM9000_TXPLH = 0xFD .equ DM9000_ISR = 0xFE .equ DM9000_IMR = 0xFF .equ NCR_EXT_PHY = (1<<7) .equ NCR_WAKEEN = (1<<6) .equ NCR_FCOL = (1<<4) .equ NCR_FDX = (1<<3) .equ NCR_LBK = (3<<1) .equ NCR_RST = (1<<0) .equ NSR_SPEED = (1<<7) .equ NSR_LINKST = (1<<6) .equ NSR_WAKEST = (1<<5) .equ NSR_TX2END = (1<<3) .equ NSR_TX1END = (1<<2) .equ NSR_RXOV = (1<<1) .equ TCR_TJDIS = (1<<6) .equ TCR_EXCECM = (1<<5) .equ TCR_PAD_DIS2 = (1<<4) .equ TCR_CRC_DIS2 = (1<<3) .equ TCR_PAD_DIS1 = (1<<2) .equ TCR_CRC_DIS1 = (1<<1) .equ TCR_TXREQ = (1<<0) .equ TSR_TJTO = (1<<7) .equ TSR_LC = (1<<6) .equ TSR_NC = (1<<5) .equ TSR_LCOL = (1<<4) .equ TSR_COL = (1<<3) .equ TSR_EC = (1<<2) .equ RCR_WTDIS = (1<<6) .equ RCR_DIS_LONG = (1<<5) .equ RCR_DIS_CRC = (1<<4) .equ RCR_ALL = (1<<3) .equ RCR_RUNT = (1<<2) .equ RCR_PRMSC = (1<<1) .equ RCR_RXEN = (1<<0) .equ RSR_RF = (1<<7) .equ RSR_MF = (1<<6) .equ RSR_LCS = (1<<5) .equ RSR_RWTO = (1<<4) .equ RSR_PLE = (1<<3) .equ RSR_AE = (1<<2) .equ RSR_CE = (1<<1) .equ RSR_FOE = (1<<0) .equ IMR_PAR = (1<<7) .equ IMR_LNKCHGI = (1<<5) .equ IMR_UDRUNI = (1<<4) .equ IMR_ROOI = (1<<3) .equ IMR_ROI = (1<<2) .equ IMR_PTI = (1<<1) .equ IMR_PRI = (1<<0) .equ ISR_LNKCHG = (1<<5) .equ ISR_UDRUN = (1<<4) .equ ISR_ROOS = (1<<3) .equ ISR_ROS = (1<<2) .equ ISR_PTS = (1<<1) .equ ISR_PRS = (1<<0) .equ ISR_CLR_STATUS = (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS) .equ EPCR_REEP = (1<<5) .equ EPCR_WEP = (1<<4) .equ EPCR_EPOS = (1<<3) .equ EPCR_ERPRR = (1<<2) .equ EPCR_ERPRW = (1<<1) .equ EPCR_ERRE = (1<<0) .equ GPCR_GEP_CNTL = (1<<0) ; Board/System/Debug information/definition .equ DM9801_NOISE_FLOOR = 0x08 .equ DM9802_NOISE_FLOOR = 0x05 ;DM9000_PHY_mode .equ DM9000_10MHD = 0x00 .equ DM9000_100MHD = 0x01 .equ DM9000_10MFD = 0x04 .equ DM9000_100MFD = 0x05 .equ DM9000_AUTO = 0x08 .equ DM9000_1M_HPNA = 0x10 ; Generic MII registers. #define MII_BMCR 0x00 ; Basic mode control register #define MII_BMSR 0x01 ; Basic mode status register #define MII_PHYSID1 0x02 ; PHYS ID 1 #define MII_PHYSID2 0x03 ; PHYS ID 2 #define MII_ADVERTISE 0x04 ; Advertisement control reg #define MII_LPA 0x05 ; Link partner ability reg #define MII_EXPANSION 0x06 ; Expansion register #define MII_CTRL1000 0x09 ; 1000BASE-T control #define MII_STAT1000 0x0a ; 1000BASE-T status #define MII_ESTATUS 0x0f ; Extended Status #define MII_DCOUNTER 0x12 ; Disconnect counter #define MII_FCSCOUNTER 0x13 ; False carrier counter #define MII_NWAYTEST 0x14 ; N-way auto-neg test reg #define MII_RERRCOUNTER 0x15 ; Receive error counter #define MII_SREVISION 0x16 ; Silicon revision #define MII_RESV1 0x17 ; Reserved... #define MII_LBRERROR 0x18 ; Lpback, rx, bypass error #define MII_PHYADDR 0x19 ; PHY address #define MII_RESV2 0x1a ; Reserved... #define MII_TPISTATUS 0x1b ; TPI status for 10mbps #define MII_NCONFIG 0x1c ; Network interface config ; Basic mode control register. #define BMCR_RESV 0x003f ; Unused... #define BMCR_SPEED1000 0x0040 ; MSB of Speed (1000) #define BMCR_CTST 0x0080 ; Collision test #define BMCR_FULLDPLX 0x0100 ; Full duplex #define BMCR_ANRESTART 0x0200 ; Auto negotiation restart #define BMCR_ISOLATE 0x0400 ; Disconnect DP83840 from MII #define BMCR_PDOWN 0x0800 ; Powerdown the DP83840 #define BMCR_ANENABLE 0x1000 ; Enable auto negotiation #define BMCR_SPEED100 0x2000 ; Select 100Mbps #define BMCR_LOOPBACK 0x4000 ; TXD loopback bits #define BMCR_RESET 0x8000 ; Reset the DP83840 ; Basic mode status register. */ #define BMSR_ERCAP 0x0001 ; Ext-reg capability #define BMSR_JCD 0x0002 ; Jabber detected #define BMSR_LSTATUS 0x0004 ; Link status #define BMSR_ANEGCAPABLE 0x0008 ; Able to do auto-negotiation #define BMSR_RFAULT 0x0010 ; Remote fault detected #define BMSR_ANEGCOMPLETE 0x0020 ; Auto-negotiation complete #define BMSR_RESV 0x00c0 ; Unused... #define BMSR_ESTATEN 0x0100 ; Extended Status in R15 #define BMSR_100HALF2 0x0200 ; Can do 100BASE-T2 HDX #define BMSR_100FULL2 0x0400 ; Can do 100BASE-T2 FDX #define BMSR_10HALF 0x0800 ; Can do 10mbps, half-duplex #define BMSR_10FULL 0x1000 ; Can do 10mbps, full-duplex #define BMSR_100HALF 0x2000 ; Can do 100mbps, half-duplex #define BMSR_100FULL 0x4000 ; Can do 100mbps, full-duplex #define BMSR_100BASE4 0x8000 ; Can do 100mbps, 4k packets ;***************************************************************************** ; ; Ethernet constants ; ;**************************************************************************** .equ ETHERNET_MIN_PACKET_LENGTH = 0x3C .equ ETHERNET_HEADER_LENGTH = 0x0E .equ IP_TCP_HEADER_LENGTH = 40 .equ TOTAL_HEADER_LENGTH = IP_TCP_HEADER_LENGTH+ETHERNET_HEADER_LENGTH ; LANBUFSIZE: The size of the buffer that holds incoming and outgoing packets. .equ LANBUFSIZE = 1564 ;*************************************************************************** .ESEG ; ETHADDR: The Ethernet address ; 48 bit IEEE OUI (Organizationally Unique Identifier) EETHADDR: .db 0xDE,0xD0,0x80,0x00,0x00,0x06 ; ;*************************************************************************** ;**** VARIABLES .DSEG ETHADDR: .byte 6 FifoError: .byte 4 CRCError: .byte 4 LenError: .byte 4 RecPack: .byte 4 ;*************************************************************************** ;**** CODE SEG ;*************************************************************************** .CSEG ;************************************************************* ; Read DM9000A register ; ; In: R16 - register index ; ; Out: R16 - read data ; DM9k_ior: sts ADR_LANI,R16 nop lds R16,ADR_LAND ret ;************************************************************* ; Read9k Register ; ; In: register index ; ; Out: R16 - read data ; .macro Read9k ldi R16,@0 rcall DM9k_ior .endmacro ;************************************************************* ; Write DM9000A register ; ; In: R16 - register index ; R17 - data ; ; Out: - ; DM9k_iow: sts ADR_LANI,R16 nop sts ADR_LAND,R17 ret ;************************************************************* ; Write9k Register, Value ; ; In: register index , Value ; ; Out: - ; .macro Write9k ldi R16,@0 ldi R17,@1 rcall DM9k_iow .endmacro ;************************************************************* ; HW Reset DM9000A ; ; In: - ; ; Out: - ; DM9k_HW_Reset: ldi R16,0 sts ADR_LANS,R16 ;LAN reset active ldi R16,1 call Wait1ms ldi R16,255 sts ADR_LANS,R16 ;LAN reset inactive ldi R16,1 call Wait1ms ret ;************************************************************* ; General Purpose dm9000 reset routine ; ; In: - ; ; Out: - ; dm9k_reset: ldi R16,DM9000_NCR ;writeb(DM9000_NCR, db->io_addr) sts ADR_LANI,R16 ldi R16,1 call Wait1ms ;udelay(200) ldi R16,NCR_RST ;writeb(NCR_RST, db->io_data); sts ADR_LAND,R16 ldi R16,1 call Wait1ms ;udelay(200) ret ;************************************************************* ; Search DM9000A ; ; In: - ; ; Out: c = 1 DM9000A/B notfound ; ; Search and HW reset DM9000A ; DM9k_Probe: Read9k DM9000_VIDL cpi R16,low(DM9000_ID) ;0x46 brne NoNetBoard Read9k DM9000_VIDH cpi R16,byte2(DM9000_ID) ;0x0a brne NoNetBoard Read9k DM9000_PIDL cpi R16,byte3(DM9000_ID) brne NoNetBoard Read9k DM9000_PIDH cpi R16,byte4(DM9000_ID) brne NoNetBoard clc ret NoNetBoard: sec ret ;************************************************************* ; Read a word from phyxcer ; ; In: R16 - PHY register ; ; Out: R19:R18 - read word ; phy_read: ;Fill the phyxcer register into REG_0C ldi R17,DM9000_PHY or R17,R16 ldi R16,DM9000_EPAR rcall DM9k_iow ;Issue phyxcer read command Write9k DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS ldi R16,1 call Wait1ms ;Wait read complete 1ms ;Clear phyxcer read command Write9k DM9000_EPCR, 0x0 ;Read PHY value Read9k DM9000_EPDRH mov R19,R16 ;hi-byte Read9k DM9000_EPDRL mov R18,R16 ;low byte ret ;************************************************************* ; Write a word to phyxcer ; ; In: R16 - PHY register ; R19:R18 - PHY data ; ; Out: - ; phy_write: ;Fill the phyxcer register into REG_0C ldi R17,DM9000_PHY or R17,R16 ldi R16,DM9000_EPAR rcall DM9k_iow ;Fill the written data into REG_0D & REG_0E ldi R16,DM9000_EPDRL mov R17,R18 rcall DM9k_iow ldi R16,DM9000_EPDRH mov R17,R19 rcall DM9k_iow ;Issue phyxcer write command Write9k DM9000_EPCR,EPCR_EPOS | EPCR_ERPRW ldi R16,1 ;Wait write complete 1ms call Wait1ms ; Clear phyxcer write command Write9k DM9000_EPCR, 0x00 ret ;************************************************************* ; Initilize dm9000 board ; ; In: - ; ; Out: c = 1 error, board not valid, active ect. ; DM9k_Init: clr R0 sts FifoError+0,R0 sts FifoError+1,R0 sts FifoError+2,R0 sts FifoError+3,R0 sts CRCError+0,R0 sts CRCError+1,R0 sts CRCError+2,R0 sts CRCError+3,R0 sts LenError+0,R0 sts LenError+1,R0 sts LenError+2,R0 sts LenError+3,R0 sts RecPack+0,R0 sts RecPack+1,R0 sts RecPack+2,R0 sts RecPack+3,R0 rcall DM9k_HW_Reset ldi R20,4 ;Try 4x Try9k: rcall DM9k_Probe brcc NIC_Found ldi R16,1 call Wait1ms ;delay 1ms dec R20 brne Try9k sec ret ;No valid DM900A NIC_Found: rcall dm9k_reset ;GPIO0 on pre-activate PHY Write9k DM9000_GPR,0 ;REG_1F bit0 activate phyxcer ldi R16,1 call Wait1ms ;delay 1ms Write9k DM9000_GPCR, GPCR_GEP_CNTL ;GPIO0 output Write9k DM9000_GPR, 0 ;Enable PHY ldi R16,2 call Wait1ms ;wait 2ms for PHY power-on ready rcall PhyMode_Auto ;Set PHY, a Linuxban ez nincs itt ;Program operating register ;only internal phy supported by now Write9k DM9000_TCR, 0 ;TX Polling clear Write9k DM9000_BPTR, 0x3f ;Less 3Kb, 200us Write9k DM9000_FCR, 0xff ;Flow Control Write9k DM9000_SMCR, 0 ;Special Mode ;clear TX status Write9k DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END ;Clear interrupt status Write9k DM9000_ISR, ISR_CLR_STATUS ;Set Node address ldi ZL,low(EETHADDR) ;MAC address from EEPROM ldi ZH,high(EETHADDR) call EERead sts ETHADDR+0,R0 mov R17,R0 ldi R16,DM9000_PAR+0 ;Setup our MAC Address rcall DM9k_iow adiw ZL,1 call EERead sts ETHADDR+1,R0 mov R17,R0 ldi R16,DM9000_PAR+1 rcall DM9k_iow adiw ZL,1 call EERead sts ETHADDR+2,R0 mov R17,R0 ldi R16,DM9000_PAR+2 rcall DM9k_iow adiw ZL,1 call EERead sts ETHADDR+3,R0 mov R17,R0 ldi R16,DM9000_PAR+3 rcall DM9k_iow adiw ZL,1 call EERead sts ETHADDR+4,R0 mov R17,R0 ldi R16,DM9000_PAR+4 rcall DM9k_iow adiw ZL,1 call EERead sts ETHADDR+5,R0 mov R17,R0 ldi R16,DM9000_PAR+5 rcall DM9k_iow ;set multicast/broadcast address ldi R16,DM9000_MAR ;multicast register ldi R17,0xff ldi R18,8 FillM: rcall DM9k_iow inc R16 dec R18 brne FillM ;Set address filter table ;dm9000_hash_table(dev) ;;RX enable Write9k DM9000_RCR,RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN ;Enable TX/RX interrupt mask Write9k DM9000_IMR, IMR_PAR | IMR_PTI | IMR_PRI clc ret ;************************************************************* ; Set PHY operationg mode ; ; In: - ; ; Out: - ; PhyMode_10MHD: ldi R18,low(0x21) ;phy_reg4 ldi R19,high(0x21) ldi R20,low(0x0000) ;phy_reg0 ldi R21,high(0x0000) rjmp SetPhy PhyMode_10MFD: ldi R18,low(0x41) ;phy_reg4 ldi R19,high(0x41) ldi R20,low(0x1100) ;phy_reg0 ldi R21,high(0x1100) rjmp SetPhy PhyMode_100MHD: ldi R18,low(0x81) ;phy_reg4 ldi R19,high(0x81) ldi R20,low(0x2000) ;phy_reg0 ldi R21,high(0x2000) rjmp SetPhy PhyMode_100MFD: ldi R18,low(0x101) ;phy_reg4 ldi R19,high(0x101) ldi R20,low(0x3100) ;phy_reg0 ldi R21,high(0x3100) rjmp SetPhy PhyMode_Auto: ldi R18,low(0x01e1) ;phy_reg4 ldi R19,high(0x01e1) ldi R20,low(0x1000) ;phy_reg0 ldi R21,high(0x1000) SetPhy: ldi R16,4 rcall phy_write ;Set PHY media mode ldi R16,0 movw R18,R20 rcall phy_write ;Tmp Write9k DM9000_GPR,0x00 ;Enable PHY ret ;************************************************************* ; Stop the interface ; ; In: - ; ; Out: ; ; The interface is stopped when it is brought. ; dm9k_shutdown: ldi R16,MII_BMCR ldi R18,low(BMCR_RESET) ldi R19,high(BMCR_RESET) rcall phy_write ;PHY RESET Write9k DM9000_GPR, 0x01 ;Power-Down PHY Write9k DM9000_IMR, IMR_PAR ;Disable all interrupt Write9k DM9000_RCR, 0x00 ;Disable RX ret ;************************************************************* ; Hardware start transmission. ; ; In: Y - Packet address ; X - Packet length ; ; Out: ; ;Send a packet to media from the upper layer. ; dm9k_send: ;wait for end of previous transmission ;ide kell majd egy time out kilepes! ldi R16,DM9000_TCR rcall DM9k_ior andi R16,TCR_TXREQ brne dm9k_send ;ide meg varakozas kellhet ;Set TX length to DM9000 ldi R16,DM9000_TXPLL mov R17,XL rcall DM9k_iow ldi R16,DM9000_TXPLH mov R17,XH rcall DM9k_iow ;Move data to DM9000 TX RAM ldi R16,DM9000_MWCMD sts ADR_LANI,R16 movw R0,XL ;save length movw R2,YL ;Byte mode SendBytes: ld R16,Y+ sts ADR_LAND,R16 sbiw XL,1 brne SendBytes movw XL,R0 movw YL,R2 ;Set TX length to DM9000 ldi R16,DM9000_TXPLL mov R17,XL rcall DM9k_iow ldi R16,DM9000_TXPLH mov R17,XH rcall DM9k_iow ;Issue TX polling command ldi R16,DM9000_TCR ldi R17,TCR_TXREQ rcall DM9k_iow ;Cleared after TX complete ret ;************************************************************* ; Received a packet and pass to upper layer ; ; In: Y - Packet address ; ; ; Out: Y - Packet address ; X - Packet length ; c - 0 valid packet ; dm9k_recv: Read9k DM9000_ISR ;Got DM9000 interrupt status andi R16,ISR_PRS breq Exit_Rec ;Received the coming packet ;Check packet ready or not Read9k DM9000_MRCMDX ;Dummy read ;Get most updated data lds R16,ADR_LAND ;rxbyte = readb(db->io_data) cpi R16,DM9000_PKT_RDY+1 ;Status check: this byte must be 0 or 1 brcs StatusOk ;Invalid status ;SEND Warning - Ethernet stoped!!!! ;dev_warn(db->dev, "status check fail: %d\n", rxbyte); Write9k DM9000_RCR,0x00 ;Stop Device Write9k DM9000_ISR, IMR_PAR ;Stop INT request Exit_Rec: Write9k DM9000_ISR,ISR_PRS ;Clear Rx ISR status clr XL clr XH sec ret StatusOk: cpi R16,DM9000_PKT_RDY ;if (rxbyte != DM9000_PKT_RDY) return brne Exit_Rec ;A packet ready now & Get status/length ldi R16,DM9000_MRCMD sts ADR_LANI,R16 ;RxStatus [16 bit] lds R18,ADR_LAND lds R19,ADR_LAND lds XL,ADR_LAND ;RxLen [16 bit] lds XH,ADR_LAND ;Packet Status check clr R0 ;R0 = 0 Good Packet cpi XL,0x40 cpc XH,R0 brcc Good1 inc R0 ;(RxLen < 0x40) Bad Packet received ;dev_dbg(db->dev, "RX: Bad Packet (runt)\n") Good1: ldi R16,high(DM9000_PKT_MAX+1) ;(RxLen > DM9000_PKT_MAX) - nalam ez is hiba cpi XL,low(DM9000_PKT_MAX+1) cpc XH,R16 brcs Good2 inc R0 ;dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen) Good2: ldi R22,1 clr R7 ;rxhdr.RxStatus is identical to RSR register. ldi R20,RSR_FOE | RSR_CE | RSR_AE | RSR_PLE | RSR_RWTO | RSR_LCS | RSR_RF and R20,R19 brne ErrorVan rjmp NoLenErr ErrorVan: inc R0 ldi R20,RSR_FOE ;if (rxhdr.RxStatus & RSR_FOE) -> and R20,R19 ;FIFO Error breq NofifoErr ;dev_dbg(db->dev, "fifo error\n") lds R8,FifoError+0 ;dev->stats.rx_fifo_errors++ lds R9,FifoError+1 lds R10,FifoError+2 lds R11,FifoError+3 add R8,R22 adc R9,R7 adc R10,R7 adc R11,R7 sts FifoError+0,R8 sts FifoError+1,R9 sts FifoError+2,R10 sts FifoError+3,R11 NofifoErr: ldi R20,RSR_CE and R20,R19 breq NoCRCErr ;dev_dbg(db->dev, "crc error\n" lds R8,CRCError+0 ;dev->stats.rx_crc_errors++ lds R9,CRCError+1 lds R10,CRCError+2 lds R11,CRCError+3 add R8,R22 adc R9,R7 adc R10,R7 adc R11,R7 sts CRCError+0,R8 sts CRCError+1,R9 sts CRCError+2,R10 sts CRCError+3,R11 NoCRCErr: ldi R20,RSR_RF and R20,R19 breq NoLenErr ;dev_dbg(db->dev, "length error\n") lds R8,LenError+0 ;dev->stats.rx_length_errors++ lds R9,LenError+1 lds R10,LenError+2 lds R11,LenError+3 add R8,R22 adc R9,R7 adc R10,R7 adc R11,R7 sts LenError+0,R8 sts LenError+1,R9 sts LenError+2,R10 sts LenError+3,R11 NoLenErr: tst R0 ;if packet is good -> Move data from DM9000 brne BadPacket ;Move data from DM9000 movw R0,XL movw R2,YL st Y+,R18 st Y+,R19 st Y+,XL st Y+,XH RecCycle: ;Read received packet from RX SRAM lds R16,ADR_LAND st Y+,R16 sbiw XL,1 brne RecCycle movw YL,R2 movw XL,R0 ;dev->stats.rx_bytes += RxLen lds R8,RecPack+0 ;dev->stats.rx_packets++ lds R9,RecPack+1 lds R10,RecPack+2 lds R11,RecPack+3 clr R0 ldi R16,1 add R8,R16 adc R9,R0 adc R10,R0 adc R11,R0 sts RecPack+0,R8 sts RecPack+1,R9 sts RecPack+2,R10 sts RecPack+3,R11 ; Write9k DM9000_ISR,ISR_PRS ;Clear Rx ISR status ;ez nem kell, majd a k”vetkez‹ bel‚p‚s t”rli clc ret BadPacket: ;need to dump the packet's data lds R16,ADR_LAND push XL push XH ; call SendChrW pop XH pop XL sbiw XL,1 brne BadPacket rjmp Exit_Rec