📄 picnic.asm
字号:
MOVLW 0x05
CALL assert_wr
MOVLW 0xB4
CALL assert_wr
CALL calc_tcp_sum ;计算TCP的SUM
MOVLW 0x04
MOVWF PORTC
MOVLW PAGE_BEGIN
CALL assert_wr0
MOVLW 0x05
MOVWF PORTC
MOVLW 0x3C
CALL assert_wr0
MOVLW 0x06
MOVWF PORTC
dw 0x100
CALL assert_wr0
CALL transmit
CALL next_seq_no ;seq_no ++
RETURN
;-----------------------------------------------------------------------------------
; 计算Checksum
calc_tcp_sum:
CLRF bytes ;调整2byte对齐
MOVLW this_ip ;计算自己的IP地址
MOVWF FSR
MOVF INDF,W
CALL calc_sum
INCF FSR,F
MOVF INDF,W
CALL calc_sum
INCF FSR,F
MOVF INDF,W
CALL calc_sum
INCF FSR,F
MOVF INDF,W
CALL calc_sum
MOVF ip_src,W ;计算对方的IP地址
CALL calc_sum
MOVF ip_src+1,W
CALL calc_sum
MOVF ip_src+2,W
CALL calc_sum
MOVF ip_src+3,W
CALL calc_sum
dw 0x100 ;计算协议号
CALL calc_sum
MOVLW TCP_PROTO
CALL calc_sum
MOVF remote_len+1,W ;计算byte数量
CALL calc_sum
MOVF remote_len,W
CALL calc_sum
MOVLW 0x32 ;PACKET_SIZE + IP_SIZE + 16
MOVWF remote_adr
MOVLW PAGE_BEGIN
MOVWF remote_adr+1
CALL set_checksum ;设置到RTL8019的Buffer
RETURN
;===================================================================================
; 初始化NIC
;===================================================================================
initialize:
CALL init_nic ;Reset NIC
CALL getmac ;取得MAC地址
CALL setmac ;设置MAC地址
; 初始化RingBuffer
BSF STATUS,RP0
MOVLW fifo_top
MOVWF fifo_buff & 0x7F
MOVWF fifo_poi & 0x7F
MOVWF fifo_bottom & 0x7F
CLRF fifo_cn & 0x7F
CLRF fifo_line_cn & 0x7F
BCF STATUS,RP0
RETURN
;-----------------------------------------------------------------------------------
; RTL8019的Reset
;-----------------------------------------------------------------------------------
reset_nic:
CLRF PORTC
MOVLW 0x21
CALL assert_wr0 ;STOP OPERATION
MOVLW 0x1F
MOVWF PORTC
CALL assert_rd ;读入1Fh
MOVLW 0x1F
MOVWF PORTC
MOVF mdata,W
CALL assert_wr0 ;回写1Fh
reset_nic0:
MOVLW 0x07
MOVWF PORTC
CALL assert_rd ;读入Status
BTFSS mdata,7
GOTO reset_nic0 ;检查Reset是否已经结束
RETURN
;-----------------------------------------------------------------------------------
; 初始化RTL8019
;-----------------------------------------------------------------------------------
init_nic:
CALL reset_nic
MOVLW 0x0E
MOVWF PORTC ;DCR(Data Configuration Register)
MOVLW 0x68
CALL assert_wr0
MOVLW 0x0A
MOVWF PORTC
dw 0x100
CALL assert_wr0 ;for over flow
MOVLW 0x0B
MOVWF PORTC
dw 0x100
CALL assert_wr0 ;for over flow
MOVLW 0x01
MOVWF PORTC
MOVLW PAGE_START ;PAGE START
CALL assert_wr0
MOVLW 0x02
MOVWF PORTC
MOVLW PAGE_STOP ;PAGE STOP
CALL assert_wr0
MOVLW 0x03
MOVWF PORTC
MOVLW PAGE_START ;BDRY
CALL assert_wr0
MOVLW 0x0C
MOVWF PORTC ;RCR
MOVLW 0x00
CALL assert_wr0
MOVLW 0x0D
MOVWF PORTC ;TCR
MOVLW 0x02 ;Loop Back
CALL assert_wr0
MOVLW 0x0F ;IMR
MOVWF PORTC
MOVLW 0x1F
CALL assert_wr0
MOVLW 0x07 ;ISR
MOVWF PORTC
MOVLW 0xFF
CALL assert_wr0
CLRF PORTC ;CR(Command Register)
MOVLW 0x22 ;START OPERATION with L/B
CALL assert_wr0
RETURN
;-----------------------------------------------------------------------------------
; 取得MAC地址
;-----------------------------------------------------------------------------------
getmac:
CLRF PORTC
MOVLW 0x22
CALL assert_wr0
CLRF remote_adr
CLRF remote_adr+1
MOVLW .12 ;读12个bytes
MOVWF remote_len
CLRF remote_len+1
CALL remote_read
MOVLW 0x06
MOVWF gcn1 ;MAC地址是6 bytes
MOVLW mymac ;设置mymac的地址
MOVWF FSR
get_mac0:
MOVLW 0x10
MOVWF PORTC
CALL assert_rd ;开始读
CALL assert_rd
MOVF mdata,W ;将MAC地址读入PIC
MOVWF INDF
INCF FSR,F
DECFSZ gcn1,F
GOTO get_mac0
RETURN
;-----------------------------------------------------------------------------------
; 设置MAC地址
;-----------------------------------------------------------------------------------
setmac:
; PAGE 1
CLRF PORTC
MOVLW b'01100010'
CALL assert_wr0
MOVLW 0x01
MOVWF PORTC
MOVLW mymac
MOVWF FSR
MOVLW 0x06
MOVWF gcn1 ;MAC地址的长度是6
set_mac0:
MOVF INDF,W
CALL assert_wr0 ;设置MAC地址
INCF FSR,F
INCF PORTC,F
DECFSZ gcn1,F
GOTO set_mac0
MOVLW 0x07
MOVWF PORTC
MOVLW PAGE_START+1
CALL assert_wr0
MOVLW 0x08
MOVWF PORTC
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
INCF PORTC,F
dw 0x100
CALL assert_wr0
CLRF PORTC
MOVLW 0x22
CALL assert_wr0
RETURN
;-----------------------------------------------------------------------------------
; 准备Remote DMA写入
;-----------------------------------------------------------------------------------
remote_write:
MOVLW 0x08
MOVWF PORTC
MOVF remote_adr,W
CALL assert_wr0
MOVLW 0x09
MOVWF PORTC
MOVF remote_adr+1,W
CALL assert_wr0
MOVLW 0x0A
MOVWF PORTC
MOVF remote_len,W
CALL assert_wr0
MOVLW 0x0B
MOVWF PORTC
MOVF remote_len+1,W
CALL assert_wr0
CLRF PORTC
MOVLW b'00010010'
CALL assert_wr0 ;可以开始写入了
MOVLW 0x10
MOVWF PORTC
RETURN
;-----------------------------------------------------------------------------------
; 准备Remote DMA读取
;-----------------------------------------------------------------------------------
remote_read:
MOVLW 0x08
MOVWF PORTC
MOVF remote_adr,W
CALL assert_wr0
MOVLW 0x09
MOVWF PORTC
MOVF remote_adr+1,W
CALL assert_wr0
MOVLW 0x0A
MOVWF PORTC
MOVF remote_len,W
CALL assert_wr0
MOVLW 0x0B
MOVWF PORTC
MOVF remote_len+1,W
CALL assert_wr0
CLRF PORTC
MOVLW 0x0A
CALL assert_wr0 ;可以开始读取了
MOVLW 0x10
MOVWF PORTC
RETURN
;-----------------------------------------------------------------------------------
; 计算Checksum
;-----------------------------------------------------------------------------------
calc_sum:
BTFSS bytes,0 ;检查对齐方式
GOTO calc_sum_high
; Low Byte
ADDWF sum,F
MOVLW 0x01
BTFSC STATUS,C
ADDWF sum+1,F
BTFSC STATUS,C
ADDWF sum,F
BTFSC STATUS,C
ADDWF sum+1,F
INCF bytes,F
RETURN
; High Byte
calc_sum_high:
ADDWF sum+1,F
MOVLW 0x01
BTFSC STATUS,C
ADDWF sum,F
BTFSC STATUS,C
ADDWF sum+1,F
INCF bytes,F
RETURN
assert_wr2times:
dw 0x100
CALL assert_wr
dw 0x100
GOTO assert_wr
;-----------------------------------------------------------------------------------
; 送信数据=mdata
assert_wr2x:
MOVLW 0x01
ADDWF remote_len,F
BTFSC STATUS,C
INCF remote_len+1,F
MOVF mdata,W
GOTO assert_wr
; 送信数据=W
assert_wr2
MOVWF mdata
MOVLW 0x01
ADDWF remote_len,F
BTFSC STATUS,C
INCF remote_len+1,F
MOVF mdata,W
;-----------------------------------------------------------------------------------
; 向RTL8019写入(考虑Checksum)
;-----------------------------------------------------------------------------------
assert_wr:
MOVWF PORTD
assert_wr_2
BTFSS bytes,0
GOTO assert_wr_high
ADDWF sum,F
MOVLW 0x01
BTFSC STATUS,C
ADDWF sum+1,F
BTFSC STATUS,C
ADDWF sum,F
BTFSC STATUS,C
ADDWF sum+1,F
INCF bytes,F
GOTO assert_wr0_2
assert_wr_high:
ADDWF sum+1,F
MOVLW 0x01
BTFSC STATUS,C
ADDWF sum,F
BTFSC STATUS,C
ADDWF sum+1,F
INCF bytes,F
GOTO assert_wr0_2
;-----------------------------------------------------------------------------------
; 单纯的向RTL8019写入
;-----------------------------------------------------------------------------------
assert_wr0:
MOVWF PORTD
assert_wr0_2:
BSF STATUS,RP0
CLRF TRISD & 0x7F
BCF STATUS,RP0
BCF WRITE
BTFSS RDY
GOTO $-1
BSF WRITE
BSF STATUS,RP0
MOVLW 0xFF
MOVWF TRISD & 0x7F
BCF STATUS,RP0
RETURN
assert_rd:
BCF READ
BTFSS RDY ;~Wait
GOTO $-1
MOVF PORTD,W
MOVWF mdata
BSF READ
RETURN
;-----------------------------------------------------------------------------------
; Packet送信的相关处理
;-----------------------------------------------------------------------------------
transmit_this_ip:
MOVLW this_ip
MOVWF FSR
MOVLW 0x04
transmit_nbytes:
MOVWF gcn1
MOVLW 0x10
MOVWF PORTC
transmit0:
MOVF INDF,W
CALL assert_wr
INCF FSR,F
DECFSZ gcn1,F
GOTO transmit0
RETURN
transmit_nbytes2:
MOVWF gcn1
MOVLW 0x10
MOVWF PORTC
transmit2_0
MOVF INDF,W
CALL assert_wr2
INCF FSR,F
DECFSZ gcn1,F
GOTO transmit2_0
RETURN
;-----------------------------------------------------------------------------------
; Packet送信
;-----------------------------------------------------------------------------------
transmit:
retry:
CLRF PORTC
CALL assert_rd
BTFSC mdata,2 ;检查送信bit
GOTO transmit ;等待送信
CLRF PORTC
MOVLW b'00100110' ;设立送信bit
CALL assert_wr0 ;送信!
trans100:
MOVLW 0x04
MOVWF PORTC
CALL assert_rd
BTFSC mdata,0
GOTO transmit9 ;送信完了?
BTFSC mdata,3
GOTO retry
GOTO trans100
transmit9:
RETURN
;-----------------------------------------------------------------------------------
; 准备Ethernet Header
;-----------------------------------------------------------------------------------
prepare_ether2:
MOVLW PACKET_SIZE + ARP_SIZE
MOVWF remote_len
GOTO prepare_ether1
prepare_ether:
MOVLW PACKET_SIZE + IP_SIZE
MOVWF remote_len
prepare_ether1:
CLRF remote_len+1
CLRF remote_adr
MOVLW PAGE_BE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -