Web 51 - Packet Driver RTL8019AS

Web 51 - Packet Driver RTL8019AS Inicializace driveru - part 1  software.html  Web 51 - Packet Driver RTL8019AS Prijem paketu - part 3

část 2 - vysílání paketů

Vysílání paketů je v tomto driveru řešeno velmi jednoduše. Vzhledem k tomu, že obvod neobsahuje FIFO pro celý vysílaný paket a vysílá paket pomocí DMA kanálu z paměti, je nutno před sestavováním dalšího paketu do paměti čipu RTL počkat na skončení předchozího vysílání. Druhou možností by bylo použít dvou vysílacích bufferů a střídavě z jednoho vysílat a do druhého sestavovat paket. Nicméně ani tak se někdy nevyhneme čekání na dokončení předchozího vysílání. To lze zabezpečit např. pomocí následujícího kódu:
;*************************************************************
;***            S E N D   P A C K E T                       **
;*************************************************************

;*************************************************************
;** wait for end of previous transmit
;**
tx_wait:

Nejprve pro ochranu před zamrznutím nastavíme timeout na dobu danou časem za který je paket buď přenesen, nebo zahozen jako nedoručitelný.

        MOV     DPTR,#-40982    ;max coll time = 1024*7 Ethernet slot units (51.2us)
tx_wait1:

Pak cyklicky čteme hodnotu stavového bitu, udávajícího, zda obvod vysílá. Pokud obvod nevysílá, cyklus ukončíme.

        ISAIN   EN_CMD
        JNB     BIT_TRANS,end_tx_wait
        INC     DPTR
        MOV     A,DPH
        ORL     A,DPL

Cyklus ukončíme rovněž při vypršení timeoutu.

        JNZ     tx_wait1
;;Transmit, with error
;; set errors flag...
end_tx_wait:
        RET

Pokud obvod nevysílá, sestavíme do paměti obvodu RTL paket k vysílání, včetně předepsané ethernetovské hlavičky, udávající MAC adresu příjemce, MAC adresu odesílatele a délku paketu. Sestavený paket vyšleme následující procedurou.

;*************************************************************
;** send packet
;**
;input: R6R7            Transmit Byte Count
send_pkt:

Nejprve pro jistotu počkáme na ukončení předchozího vysílání

; Wait for end of previous transmit
        ACALL   tx_wait

Poté zkontrolujeme, jak skončilo předchozí vysílání. Pokud skončilo s chybou je možno nastavit příslušné bity pro softwarové ošetření chyby při vysílání.

; Check for recent TX completions in the interrupt status register
        ISAIN   EN0_ISR         ; Interrupt status reg
        ANL     A,#ENISR_TX_ERR+ENISR_TX ; Pending Tx interrupts?
        JZ      tx_idle         ; No, Go on new Tx
;       JNB     BITISR_TX_ERR, XmitFrameNoErr
;; Transmit, with error
;; set errors flag...
;XmitFrameNoErr:

Vysílalo-li se přečteme podrobnější informace o ukončeném vysílání a případně je uložíme či jinak zpracujeme.

        ISAIN   EN0_TSR         ; Read Transmit status reg
;; save transmit status...

Na závěr zpracování předchozího vysílání potvrdíme zpracování přerušení od vysílače.

; Acknowledge the TX interrupt
        ISAOUT  EN0_ISR, #ENISR_TX_ERR+ENISR_TX ; Interrupt status reg
                                ; Set Transmitter Interrupt, with/no error

Před zahájením zkontrolujeme povolenou délku paketu. Nejprve zkontrolujeme, zda paket nepřesahuje 1500 bytů dat + 14 bytů hlavičky. Delší pakety zahodíme.

tx_idle:
        MOV     A,R7            ; Is packet too large ?
        ADD     A,#LOW(-GIANT-1)
        MOV     A,R6
        ADD     A,#HIGH(-GIANT-1)
        JNC     XmitNoGiant
;; set errors flag...
        RET

Následuje kontrola zda paket není kratší než 46+14 bytů.

XmitNoGiant:
        MOV     A,R6            ; Is the frame long enought ?
        JNZ     XmitNoRunt
        MOV     A,R7
        ADD     A,#-RUNT
        JC      XmitNoRunt

Je-li kratší, natáhneme jej na minimální povolenou délku. (Paket se automaticky doplní "smetím" z předchozího paketu, není doplňován např. nulami).

;;      MOV     R6,#HIGH(RUNT)  ; Stretch frame to minimum allowed
        MOV     R7,#LOW(RUNT)

Na závěr sdělíme obvodu RTL délku vysílaného paketu a jeho umístění v paměti(*). Poté odstartujeme vysílání.

XmitNoRunt:
        BEGINPORTDATA
        PORTDATA        EN0_TCNTHI+portind,AR6  ; High byte of tx byte count
        PORTDATA        EN0_TCNTLO+portind,AR7  ; Low  byte of tx byte count
        PORTDATA        EN0_TPSR,NE_START_PG    ; Transmit starting page
                                ; First page of TX buffer
        PORTDATA        EN_CMD, EN_PAGE0+EN_NODMA+EN_TRANS+EN_START
                                ; Remote DMA, Transmit a frame,
                                ; Start the chip, clear reset
        ENDPORTDATA
        RET
Dil 2Packet Driver RTL8019AS, část 3

(*) Od verze 1.13 používá Web 51 mírně modifikovanou strukturu paměti, podporující více vysílacích bufferů, adresa vysílacího bufferu není konstantní. Výše uvedený fragment programu je v používané verzi driveru proto pozměněn.





Sponzored by LPhard Ltd. Graphics by GIMP Created by EasyPad

(c)Copyright 2000, 2001, HW server & Radek Benedikt
Web51@HW.cz, Web51.HW.cz

Final applications of the Web51 : www.HWgroup.cz
Web 51 - Packet Driver RTL8019AS Inicializace driveru - part 1  Obsah  Web 51 - Packet Driver RTL8019AS Prijem paketu - part 3