📄 ax88796.s
字号:
.module ax88796.c
.area text(rom, con, rel)
.dbfile C:\DOCUME~1\yehaoran\桌面\AVRuIP\ax88796.c
.dbfunc e ax88796Write _ax88796Write fV
; data -> R18
; address -> R16
.even
_ax88796Write::
.dbline -1
.dbline 66
; /*****************************************************************************
; * modified by Louis Beaudoin for uIP-AVR port - November 16, 2003
; * www.embedded-creations.com
; *
; * Removed: The debugging calls to the Procyon AVRLIB UART functions and the
; * register dump function was removed
; *
; * Modified:
; * The ax88796Write and Read functions/macros were changed to support
; * three methods of communcating with the NIC
; * Interfacing with the AVR ports changed from sbi/cbi/etc functions
; * to direct port names
; *****************************************************************************/
;
; //*****************************************************************************
; //
; // File Name : 'ax88796.c'
; // Title : ASIX 88796 L Ethernet Interface Driver
; // Author : Pascal Stang
; // Created : 10/22/2002
; // Revised : 10/26/2002
; // Version : 0.1
; // Target MCU : Atmel AVR series
; // Editor Tabs : 4
; //
; // Description : This include file is designed to contain items useful to all
; // code files and projects.
; //
; // Based in part on code by Louis Beaudoin (www.embedded-creations.com)
; //
; // This code is distributed under the GNU Public License
; // which can be found at http://www.gnu.org/licenses/gpl.txt
; //
; //*****************************************************************************
;
; #include "ax88796.h"
;
; // pointers to locations in the ax88796 receive buffer
; static unsigned char nextPage;
; static unsigned int currentRetreiveAddress;
;
; // offsets into ax88796 ethernet packet header
; #define enetpacketstatus 0x00
; #define nextblock_ptr 0x01
; #define enetpacketLenL 0x02
; #define enetpacketLenH 0x03
;
;
;
; #if NIC_CONNECTION == MEMORY_MAPPED_HIGHADDR
; #define ax88796Write(AX88796_REG,AX88796_DATA) do{ *(volatile unsigned char *) \
; (MEMORY_MAPPED_AX88796_OFFSET \
; + (((unsigned char)(AX88796_REG)) << 8)) = \
; (unsigned char)(AX88796_DATA); } while(0)
; #endif
;
; #if NIC_CONNECTION == MEMORY_MAPPED
; #define ax88796Write(AX88796_REG,AX88796_DATA) do{ *(volatile unsigned char *) \
; (MEMORY_MAPPED_AX88796_OFFSET \
; + (unsigned char)(AX88796_REG)) = \
; (unsigned char)(AX88796_DATA); } while(0)
; #endif
;
; #if NIC_CONNECTION == GENERAL_IO
; void ax88796Write(u08 address, u08 data)
; {
.dbline 68
; // assert the address, leaving the non-address pins intact
; address |= (AX88796_ADDRESS_PORT & ~AX88796_ADDRESS_MASK);
in R24,0x15
andi R24,224
or R16,R24
.dbline 69
; AX88796_ADDRESS_PORT = address;
out 0x15,R16
.dbline 72
;
; // set data bus as output and place data on bus
; AX88796_DATA_DDR = 0xFF;
ldi R24,255
out 0x1a,R24
.dbline 73
; AX88796_DATA_PORT = data;
out 0x1b,R18
.dbline 76
;
; // clock write pin
; AX88796_CONTROL_PORT &= ~_BV(AX88796_CONTROL_WRITEPIN);
cbi 0x15,6
.dbline 77
; nop();
nop
.dbline 78
; AX88796_CONTROL_PORT |= _BV(AX88796_CONTROL_WRITEPIN);
sbi 0x15,6
.dbline 81
;
; // set data bus back to input with pullups enabled
; AX88796_DATA_DDR = 0x00;
clr R2
out 0x1a,R2
.dbline 82
; AX88796_DATA_PORT = 0xFF;
out 0x1b,R24
.dbline -2
L7:
.dbline 0 ; func end
ret
.dbsym r data 18 c
.dbsym r address 16 c
.dbend
.dbfunc e ax88796Read _ax88796Read fc
; byte -> R20
; address -> R16
.even
_ax88796Read::
xcall push_gset1
.dbline -1
.dbline 102
; }
; #endif
;
; #if NIC_CONNECTION == MEMORY_MAPPED_HIGHADDR
;
; #define ax88796Read(AX88796_ADDRESS) (*(volatile unsigned char *) \
; (MEMORY_MAPPED_AX88796_OFFSET \
; + (((unsigned char)(AX88796_ADDRESS)) << 8)) )
; #endif
;
; #if NIC_CONNECTION == MEMORY_MAPPED
; #define ax88796Read(AX88796_ADDRESS) (*(volatile unsigned char *) \
; (MEMORY_MAPPED_AX88796_OFFSET \
; + (unsigned char)(AX88796_ADDRESS)) )
; #endif
;
; #if NIC_CONNECTION == GENERAL_IO
;
; u08 ax88796Read(u08 address)
; {
.dbline 106
; u08 byte;
;
; // assert the address, leaving the non-address pins intact
; address |= (AX88796_ADDRESS_PORT & ~AX88796_ADDRESS_MASK);
in R24,0x15
andi R24,224
or R16,R24
.dbline 107
; AX88796_ADDRESS_PORT = address;
out 0x15,R16
.dbline 110
;
; // assert read
; AX88796_CONTROL_PORT &= ~_BV(AX88796_CONTROL_READPIN);
cbi 0x15,5
.dbline 111
; nop();
nop
.dbline 114
;
; // read in the data
; byte = AX88796_DATA_PIN;
in R20,0x19
.dbline 115
; nop();
nop
.dbline 118
;
; // negate read
; AX88796_CONTROL_PORT |= _BV(AX88796_CONTROL_READPIN);
sbi 0x15,5
.dbline 120
;
; return byte;
mov R16,R20
.dbline -2
L8:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r byte 20 c
.dbsym r address 16 c
.dbend
.dbfunc e ax88796Init _ax88796Init fV
; tcrFduFlag -> R20
; delaycount -> R22
.even
_ax88796Init::
xcall push_gset2
sbiw R28,2
.dbline -1
.dbline 126
; }
; #endif
;
;
; void ax88796Init(void)
; {
.dbline 127
; unsigned char delaycount=10;
ldi R22,10
.dbline 129
; unsigned char tcrFduFlag;
; ax88796SetupPorts();
xcall _ax88796SetupPorts
.dbline 132
;
; // do a hard reset
; AX88796_RESET_PORT |= _BV(AX88796_RESET_PIN);
sbi 0x12,2
.dbline 133
; delay_ms(10);
ldi R16,10
xcall _delay_ms
.dbline 134
; AX88796_RESET_PORT &= ~_BV(AX88796_RESET_PIN);
cbi 0x12,2
.dbline 137
;
; // do soft reset
; ax88796Write(ISR, ax88796Read(ISR));
ldi R16,7
xcall _ax88796Read
mov R18,R16
ldi R16,7
xcall _ax88796Write
.dbline 138
; delay_ms(50);
ldi R16,50
xcall _delay_ms
.dbline 141
;
; // wait for PHY to come out of reset
; ax88796Read(RSTPORT);
ldi R16,31
xcall _ax88796Read
L10:
.dbline 142
L11:
.dbline 142
; while(ax88796Read(TR) & RST_B);
ldi R16,21
xcall _ax88796Read
sbrc R16,1
rjmp L10
.dbline 144
;
; ax88796WriteMii(0x10,0x00,0x0800);
ldi R24,2048
ldi R25,8
std y+1,R25
std y+0,R24
clr R18
ldi R16,16
xcall _ax88796WriteMii
xjmp L14
L13:
.dbline 146
ldi R16,255
xcall _delay_ms
L14:
.dbline 145
; while(delaycount--)
mov R2,R22
clr R3
subi R22,1
tst R2
brne L13
.dbline 147
; delay_ms(255);
; ax88796WriteMii(0x10,0x00,0x1200);
ldi R24,4608
ldi R25,18
std y+1,R25
std y+0,R24
clr R18
ldi R16,16
xcall _ax88796WriteMii
.dbline 149
;
; ax88796Write(CR,(RD2|STOP)); // stop the NIC, abort DMA, page 0
ldi R18,33
clr R16
xcall _ax88796Write
.dbline 150
; delay_ms(5); // make sure nothing is coming in or going out
ldi R16,5
xcall _delay_ms
.dbline 151
; ax88796Write(DCR,DCR_INIT);
clr R18
ldi R16,14
xcall _ax88796Write
.dbline 152
; ax88796Write(RBCR0,0x00);
clr R18
ldi R16,10
xcall _ax88796Write
.dbline 153
; ax88796Write(RBCR1,0x00);
clr R18
ldi R16,11
xcall _ax88796Write
.dbline 154
; ax88796Write(IMR,0x00);
clr R18
ldi R16,15
xcall _ax88796Write
.dbline 155
; ax88796Write(ISR,0xFF);
ldi R18,255
ldi R16,7
xcall _ax88796Write
.dbline 156
; ax88796Write(RCR,0x20);
ldi R18,32
ldi R16,12
xcall _ax88796Write
.dbline 157
; ax88796Write(BNRY,RXSTART_INIT);
ldi R18,70
ldi R16,3
xcall _ax88796Write
.dbline 158
; ax88796Write(PSTART,RXSTART_INIT);
ldi R18,70
ldi R16,1
xcall _ax88796Write
.dbline 159
; ax88796Write(PSTOP,RXSTOP_INIT);
ldi R18,96
ldi R16,2
xcall _ax88796Write
.dbline 162
;
; // switch to page 1
; ax88796Write(CR,(PS0|RD2|STOP));
ldi R18,97
clr R16
xcall _ax88796Write
.dbline 164
; // write mac address
; ax88796Write(PAR0+0, MYMAC_0);
ldi R18,48
ldi R16,1
xcall _ax88796Write
.dbline 165
; ax88796Write(PAR0+1, MYMAC_1);
ldi R18,70
ldi R16,2
xcall _ax88796Write
.dbline 166
; ax88796Write(PAR0+2, MYMAC_2);
ldi R18,70
ldi R16,3
xcall _ax88796Write
.dbline 167
; ax88796Write(PAR0+3, MYMAC_3);
ldi R18,73
ldi R16,4
xcall _ax88796Write
.dbline 168
; ax88796Write(PAR0+4, MYMAC_4);
ldi R18,67
ldi R16,5
xcall _ax88796Write
.dbline 169
; ax88796Write(PAR0+5, MYMAC_5);
ldi R18,69
ldi R16,6
xcall _ax88796Write
.dbline 171
; // set start point
; ax88796Write(CURR,RXSTART_INIT+1);
ldi R18,71
ldi R16,7
xcall _ax88796Write
.dbline 173
;
; ax88796Write(CR,(RD2|START));
ldi R18,34
clr R16
xcall _ax88796Write
.dbline 174
; ax88796Write(RCR,RCR_INIT);
ldi R18,68
ldi R16,12
xcall _ax88796Write
.dbline 176
;
; if(ax88796Read(GPI) & I_SPD) // check PHY speed setting
ldi R16,23
xcall _ax88796Read
sbrs R16,2
rjmp L16
.dbline 177
; tcrFduFlag = FDU; // if 100base, do full duplex
ldi R20,128
xjmp L17
L16:
.dbline 179
; else
; tcrFduFlag = 0; // if 10base, do half duplex
clr R20
L17:
.dbline 181
;
; ax88796Write(TCR,(tcrFduFlag|TCR_INIT));
mov R18,R20
ldi R16,13
xcall _ax88796Write
.dbline 183
;
; ax88796Write(GPOC,MPSEL); // select media interface
ldi R18,16
ldi R16,23
xcall _ax88796Write
.dbline 185
;
; ax88796Write(TPSR,TXSTART_INIT);
ldi R18,64
ldi R16,4
xcall _ax88796Write
.dbline 187
;
; ax88796Write(CR,(RD2|STOP));
ldi R18,33
clr R16
xcall _ax88796Write
.dbline 188
; ax88796Write(DCR,DCR_INIT);
clr R18
ldi R16,14
xcall _ax88796Write
.dbline 189
; ax88796Write(CR,(RD2|START));
ldi R18,34
clr R16
xcall _ax88796Write
.dbline 190
; ax88796Write(ISR,0xFF);
ldi R18,255
ldi R16,7
xcall _ax88796Write
.dbline 191
; ax88796Write(IMR,IMR_INIT);
ldi R18,17
ldi R16,15
xcall _ax88796Write
.dbline 192
; ax88796Write(TCR,(tcrFduFlag|TCR_INIT));
mov R18,R20
ldi R16,13
xcall _ax88796Write
.dbline -2
L9:
adiw R28,2
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r tcrFduFlag 20 c
.dbsym r delaycount 22 c
.dbend
.dbfunc e ax88796SetupPorts _ax88796SetupPorts fV
.even
_ax88796SetupPorts::
.dbline -1
.dbline 198
; }
;
;
;
; void ax88796SetupPorts(void)
; {
.dbline 201
; #if NIC_CONNECTION == GENERAL_IO
; // set address port to output
; AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK;
ldi R24,31
out 0x14,R24
.dbline 204
;
; // set data port to input with pull-ups
; AX88796_DATA_DDR = 0x00;
clr R2
out 0x1a,R2
.dbline 205
; AX88796_DATA_PORT = 0xFF;
ldi R24,255
out 0x1b,R24
.dbline 208
;
; // initialize the control port read and write pins to de-asserted
; AX88796_CONTROL_PORT |= _BV(AX88796_CONTROL_READPIN);
sbi 0x15,5
.dbline 209
; AX88796_CONTROL_PORT |= _BV(AX88796_CONTROL_WRITEPIN);
sbi 0x15,6
.dbline 211
; // set the read and write pins to output
; AX88796_CONTROL_DDR |= _BV(AX88796_CONTROL_READPIN);
sbi 0x14,5
.dbline 212
; AX88796_CONTROL_DDR |= _BV(AX88796_CONTROL_WRITEPIN);
sbi 0x14,6
.dbline 219
;
; #else
; // enable external SRAM interface - no wait states
; MCUCR |= _BV(SRE);
; #endif
; // set reset pin to output
; AX88796_RESET_DDR |= _BV(AX88796_RESET_PIN);
sbi 0x11,2
.dbline -2
L18:
.dbline 0 ; func end
ret
.dbend
.dbfunc e ax88796BeginPacketSend _ax88796BeginPacketSend fV
; sendPacketLength -> R20,R21
; packetLength -> R22,R23
.even
_ax88796BeginPacketSend::
xcall push_gset3
movw R22,R16
.dbline -1
.dbline 224
; }
;
;
; void ax88796BeginPacketSend(unsigned int packetLength)
; {
.dbline 226
; unsigned int sendPacketLength;
; sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH) ?
cpi R22,60
ldi R30,0
cpc R23,R30
brlo L20
movw R10,R22
xjmp L21
L20:
ldi R24,60
ldi R25,0
movw R10,R24
L21:
movw R20,R10
.dbline 230
; packetLength : ETHERNET_MIN_PACKET_LENGTH ;
;
; //start the NIC
; ax88796Write(CR,0x22);
ldi R18,34
clr R16
xcall _ax88796Write
L22:
.dbline 233
L23:
.dbline 233
;
; // still transmitting a packet - wait for it to finish
; while( ax88796Read(CR) & 0x04 );
clr R16
xcall _ax88796Read
sbrc R16,2
rjmp L22
.dbline 236
;
; //load beginning page for transmit buffer
; ax88796Write(TPSR,TXSTART_INIT);
ldi R18,64
ldi R16,4
xcall _ax88796Write
.dbline 239
;
; //set start address for remote DMA operation
; ax88796Write(RSAR0,0x00);
clr R18
ldi R16,8
xcall _ax88796Write
.dbline 240
; ax88796Write(RSAR1,0x40);
ldi R18,64
ldi R16,9
xcall _ax88796Write
.dbline 243
;
; //clear the packet stored interrupt
; ax88796Write(ISR, PTX);
ldi R18,2
ldi R16,7
xcall _ax88796Write
.dbline 246
;
; //load data byte count for remote DMA
; ax88796Write(RBCR0, (unsigned char)(packetLength));
mov R18,R22
ldi R16,10
xcall _ax88796Write
.dbline 247
; ax88796Write(RBCR1, (unsigned char)(packetLength>>8));
movw R18,R22
mov R18,R19
clr R19
ldi R16,11
xcall _ax88796Write
.dbline 249
;
; ax88796Write(TBCR0, (unsigned char)(sendPacketLength));
mov R18,R20
ldi R16,5
xcall _ax88796Write
.dbline 250
; ax88796Write(TBCR1, (unsigned char)((sendPacketLength)>>8));
movw R18,R20
mov R18,R19
clr R19
ldi R16,6
xcall _ax88796Write
.dbline 253
;
; //do remote write operation
; ax88796Write(CR,0x12);
ldi R18,18
clr R16
xcall _ax88796Write
.dbline -2
L19:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r sendPacketLength 20 i
.dbsym r packetLength 22 i
.dbend
.dbfunc e ax88796SendPacketData _ax88796SendPacketData fV
; i -> R20,R21
; length -> R22,R23
; localBuffer -> R10,R11
.even
_ax88796SendPacketData::
xcall push_gset3
movw R22,R18
movw R10,R16
.dbline -1
.dbline 257
; }
;
; void ax88796SendPacketData(unsigned char * localBuffer, unsigned int length)
; {
.dbline 260
; unsigned int i;
;
; for(i=0;i<length;i++)
clr R20
clr R21
xjmp L29
L26:
.dbline 261
movw R30,R20
add R30,R10
adc R31,R11
ldd R18,z+0
ldi R16,16
xcall _ax88796Write
L27:
.dbline 260
subi R20,255 ; offset = 1
sbci R21,255
L29:
.dbline 260
cp R20,R22
cpc R21,R23
brlo L26
.dbline -2
L25:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r length 22 i
.dbsym r localBuffer 10 pc
.dbend
.dbfunc e ax88796EndPacketSend _ax88796EndPacketSend fV
.even
_ax88796EndPacketSend::
.dbline -1
.dbline 265
; ax88796Write(RDMAPORT, localBuffer[i]);
; }
;
; void ax88796EndPacketSend(void)
; {
.dbline 267
; //send the contents of the transmit buffer onto the network
; ax88796Write(CR,0x24);
ldi R18,36
clr R16
xcall _ax88796Write
.dbline 270
;
; // clear the remote DMA interrupt
; ax88796Write(ISR, RDC);
ldi R18,64
ldi R16,7
xcall _ax88796Write
.dbline -2
L30:
.dbline 0 ; func end
ret
.dbend
.dbfunc e ax88796BeginPacketRetreive _ax88796BeginPacketRetreive fi
; rxlen -> R20,R21
; writePagePtr -> R10
; bnryPagePtr -> R20
; readPagePtr -> R22
; pageheader -> y+0
; i -> R20
.even
_ax88796BeginPacketRetreive::
xcall push_gset3
sbiw R28,4
.dbline -1
.dbline 275
; }
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -