www.pudn.com > avrepp.zip > avrepp.asm


;**** A P P L I C A T I O N   N O T E   A V R 3 2 5 ************************ 
;* 
;* Title:          High-speed Interface to Host EPP Parallel Port 
;* Version:        1.0 
;* Last updated:   2001.12.20 
;* Target:         All AVR Devices with 12 I/O pins or more 
;* 
;* Support E-mail: avr@atmel.com 
;*  
;* DESCRIPTION 
;* This Application Note describes a method for high-speed bidirectional data 
;* transfer between an AVR microcontroller and an off-the-shelf Intel x86 
;* desktop computer. 
;* 
;* The code contains the EPP library and ISR, along with a sample application 
;* which merely echoes to the host any data sent to it. 
;* 
;*************************************************************************** 
 
.include "8515def.inc" 
 
;   Handy application registers. EPP library registers are below. 
 
.def    tmp     = R17                   ; Ubiquitous temporary 
.def    par0    = R16                   ; First function parameter 
 
;   Point of terminology: 
;   Tx and Rx are used throughout from the host's point of view 
;   (Tx, e.g. goes out from	the host). 
;   The AVR program, however,  has the notion of putting 
;   and getting data to/from a peer, where put corresponds 
;   to a host Rx operation. 
;   The terminology conversion (as it were) takes place in 
;   epp_getc/epp_putc. 
 
;----------------------------------------------------------- 
 
;   Reset and interrupt vectors 
 
.cseg 
.org    0                               ; Reset vector 
    rjmp    start 
 
.org    INT0addr                        ; INT0 vector 
    rjmp    epp_int0 
 
;----------------------------------------------------------- 
; 
;   start() - Come here after reset 
; 
;   This is a sample main program, which just echoes 
;   characters sent from the host with a little bit 
;   of decoration. 
 
.equ    PROMPT = '>'                    ; prompt character 
.equ    CR = 0x0d                       ; Carriage Return 
.equ    LF = 0x0a                       ; Line Feed 
 
start: 
    ldi	    tmp,low(RAMEND)             ; Set up stack pointer 
    out	    SPL,tmp                     ; SP low half 
    ldi	    tmp,high(RAMEND) 
    out	    SPH,tmp                     ; SP high half 
 
;   Initialize the EPP - epp_init assumes interrupts are disabled. 
 
    rcall   epp_init                    ; Initialization 
 
    sei                                 ; Now we can enable interrupts 
 
;   This is a sample application which echoes (forever) 
;   what the host sends it over the EPP. 
 
;   The only modifications it does to the data stream are  
;     (1) a linefeed is inserted following any carriage return and  
;     (2) a prompt at the beginning of each line. 
 
newline:                                ; beginning of new line 
    ldi     par0,PROMPT                 ; prompt 
    rcall   epp_putc                    ; send it 
 
;   Forever: 
;   Get character from host 
 
loop: 
    rcall   epp_getc 
 
;   Echo the character back to the host 
 
echo: 
    rcall   epp_putc                    ; echo 
 
;   To make it pretty, add a linefeed after any CR 
 
    cpi     par0,CR                     ; after a CR, 
    brne    loop 
    ldi     par0,LF                     ; add a linefeed for niceness 
    rcall   epp_putc 
 
    rjmp    newline                     ; back to the top (prompt) 
 
;   End of sample application 
 
;----------------------------------------------------------- 
;   This is the EPP library. 
;   Private definitions are here for data-hiding 
;   (and easy copying). 
 
;   Registers: 
;   The library uses 5 registers. Three provide 
;   the buffering mechanism, and the other two are 
;   dedicated to the ISR for performance/stack. 
 
;   The following dedicated registers (could be in SRAM) 
;   provide a one-element queue in each direction. 
; 
.def    epprxbuf = R25                  ; one-element queue to host 
.def    epptxbuf = R24                  ; one-element queue from host 
.def    eppflag  = R23                  ; control bits (see below) 
 
;   Flags (bit numbers) in "eppflag" 
 
.equ    EPPC_OBUFFULL = 0               ; obuf (epprxbuf) is full 
.equ    EPPC_IBUFFULL = 1               ; ibuf (epptxbuf) is full 
.equ    EPPC_IOVERRUN = 2               ; Tx has overrun 
 
;   These two registers are dedicated to the ISR, and aren't saved. 
;   In an 8MHz AVR, these could probably be pushed/popped and still 
;   meet the deadline. 
 
.def    SAVE_SREG = R1                  ; used to save SREG 
.def    itmp = r22                      ; ISR work register 
 
;	These are the port pins used by the EPP. 
 
;   The four control lines use pins 2 and 4-6 of port D 
 
.equ    eppctlddr = DDRD                ; control lines data direction 
.equ    eppctlin  = PIND                ; input 
.equ    eppctlout = PORTD               ; output 
 
;   The control line assignments in PORTD are mostly conveniences, 
;   in that they sidestep the UART and INT1 lines. 
;   The only assignment we depend on is nDATASTR, assigned to INT0 
 
.equ    nDATASTR = PD2                  ; Data Strobe (from host) [pin 14] 
.equ    nWRITE   = PD4                  ; Read/Write  (from host) [pin  1] 
.equ    nINTR    = PD5                  ; Interrupt   (to host)   [pin 10] 
.equ    nWAIT    = PD6                  ; Device ready (to host)  [pin 11] 
 
;   The eight data lines [pins 2-9] use (all of) port C 
 
.equ    eppdataddr = DDRC               ; Data lines Data Direction 
.equ    eppdatain  = PINC               ; Data lines Input 
.equ    eppdataout = PORTC              ; Data lines Output 
 
;   Use PORTB (LEDs) for debug 
 
.equ    debugddr = DDRB                 ; Data Direction for LEDs 
.equ    debugout = PORTB                ; Port for LEDs 
 
;   If you don't want LED debugging, empty these two macros or remove them and 
;   the references to them 
 
.macro	LEDDEBUGINIT 
    ser     itmp                        ; 0xFF 
    out     debugddr,itmp               ; output 
    out     debugout,itmp               ; off initially 
.endmacro 
 
.macro  LEDDEBUG 
    mov     itmp,@0 
    com     itmp 
    out     debugout,itmp 
.endmacro 
 
;------------------------------------------------------------------ 
; 
;   epp_init() - One-time initialization for the EPP unit. 
;   Input:  none 
;   Output: none 
 
;   Notes:  Assumes interrupts are disabled. 
 
epp_init: 
    ldi     eppflag,(0< EOI 
 
    sbr     itmp,(0<