123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- ;*** PrScale ROUTINE CALLED AT END OF AttnSig AND Srq SIGNALS
-
-
- PreScale8
- banksel OPTION_REG
- movlw b'00000010' ; BINARY - set to prescale RTCC
- movwf OPTION_REG ; Clear 4th bit from right to select RTCC
- banksel TMR0
- clrf TMR0 ; last 3 bits set prescale value as 1:4
- retlw 00h ; this gives a good ratio to monitor the
- ; timing for Reset and Attention signals and
- ; the 2nd Application Task
-
- ;*** NoPrScl ROUTINE CALLED AT BEGINNING OF SyncSig AND END OF Srq SIGNALS
- PreScale2
- banksel OPTION_REG
- movlw b'00000000' ; BINARY - set to prescale RTCC
- movwf OPTION_REG ; Clear 4th bit from right to select RTCC
- banksel TMR0
- clrf TMR0 ; last 3 bits set prescale value as 1:4
- retlw 00h ; this gives a good ratio to monitor the
- ; timing for Reset and Attention signals and
- ; the 2nd Application Task
-
-
- ;***************************************************************************
-
- ;*** GET INCOMING BIT & INTERPRET WHETHER IT'S A '1' OR A '0' *** (Get_Bit) ***
- ;*** Get_Bit CALLED BY COMMAND AND LISTEN ROUTINES
- ; Get the bit, find out whether it's less than or greater than 50 usecs,
- ; if < than 50 usecs, it's a '1' bit
- ; if > than 50 usecs, it's a '0' bit
- ; if it's a '1' bit, set LSB in the reg. pointed to by the FSR (Command Byte)
- ; if it's a '0' bit, do nothing to the LSB
- ; then look for the end of the Bit Cell (104 usecs max.)
- ; if the maximum Bit time of (72 usecs) or maximum Bit Cell time is exceeded,
- ; abort to the Attn Signal
-
- Get_Bit banksel TMR0
- movf TMR0,w ; Check the time, then check if the line went high:
- subwf TimeVar,w ; See if more than BIT_TST usecs have passed
- btfss STATUS,C ; if not, check whether the line went high
- goto AttnSig ; if so, abort to the Attn Signal
- btfss PORTA,ADBPin ; Check whether the line went high
- goto Get_Bit ; if line is still low, loop again
- movlw BIT_TST ; if line went high, see if it's a '1' or a '0'
- movwf TimeVar ; as the bit has not yet been determined yet,
- bcf INDF,0 ; ensure the LSB in the indirect address is '0'
- movf TMR0,W ; Get the time
- subwf TimeVar,W ; if time < 50 usecs, it's a '1' bit
- btfsc STATUS,C ; if time > 50 usecs and < 72, it's a '0' bit
- bsf INDF,0 ; if it's a 1, set LSB in the address FSR points to
- movlw BITCELL ; Check whether the Max. Bit Cell time of 104 usecs
- movwf TimeVar ; has been exceeded
- CellChk movf TMR0,W ; Check the time, then check the line
- subwf TimeVar,W ; See if more than Max. Bit Cell usecs have passed
- btfss STATUS,C ; if not, look for the line to go low again
- goto AttnSig ; if so, abort to the Attn Signal or Reset
- btfsc PORTA,ADBPin ; Check the line for the start of another bit
- goto CellChk ; if the line is still high, loop CelChk1 again
- clrf TMR0 ; if the line went low, clear the RTCC & return
- retlw 00h ; for another bit or to interpret the Command
-
-
-
- ;***************************************************************************
-
-
-
-
- ;*** MASK OUT COMMAND NIBBLE AND REG.# BITS FROM THE COMMAND *** (MaskCmd) ***
- ; NOTE: This routine should only be called once during any single ADB
- ; transaction, from either AddrChk or CmmdChk
-
- ; Command Byte:
- ; | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- ; | A3 | A2 | A1 | A0 | Cmd Code | Register |
-
- DecodeCmd
- assume bank0
-
- movf CmdByte, w
- andlw 0xF0
- movwf ReqAddress
- swapf ReqAddress, f
-
- movf CmdByte, w
- andlw 0x03
- movwf ReqReg
- addwf ReqReg, w ; multiply reg by 2 to get 16 bit register offset
- addlw Reg0a ; add base address of register memory area
- movwf RAMaddr ; store pointer
-
-
- call SetCmdFlags ; use a jump table to translate the 16
- movwf ReqCommand ; possible combinations of commands into a
-
-
- ; turn ReqReg into bit field so we can use btfss elsewhere
-
- btfsc ReqReg, 1
- goto $+5
- movlw 0x01 ; 00
- btfsc ReqReg, 0
- movlw 0x02 ; 01
- goto storVal
- movlw 0x04 ; 10
- btfsc ReqReg, 0
- movlw 0x08 ; 11
- storVal movwf ReqReg
-
- return
-
- SetCmdFlags
-
- movf CmdByte, w
- andlw 0x0F
- addlw SetCmdFlagsJump
-
- SetCmdFlagsJump
-
- retlw 1<<cmdReset ; 0
- retlw 1<<cmdFlush ; 1
- retlw 1<<cmdReserved ; 2
- retlw 1<<cmdReserved ; 3
- retlw 1<<cmdReserved ; 4
- retlw 1<<cmdReserved ; 5
- retlw 1<<cmdReserved ; 6
- retlw 1<<cmdReserved ; 7
- retlw 1<<cmdListen ; 8
- retlw 1<<cmdListen ; 9
- retlw 1<<cmdListen ; A
- retlw 1<<cmdListen ; B
- retlw 1<<cmdTalk ; C
- retlw 1<<cmdTalk ; D
- retlw 1<<cmdTalk ; E
- retlw 1<<cmdTalk ; F
-
-
-
-
-
-
-
-
- ;***************************************************************************
-
- ;*** ISSUE A SERVICE REQUEST IF NECESSARY *** (Srq; may call LineLow) ***
- ;*** CALLED BY AddrChk
- ; see if the Srq Flag is set, if not, return, otherwise:
- ; change the prescaler to RTCC since this takes longer than 255 usecs,
- ; load the SRQTIME of 300 usecs into the TimeVariable,
- ; call LineLow to:
- ; keep checking the time to see if 300 usecs have passed,
- ; let the line go high again,
- ; and see if the line is high, and if not, abort, if it is,
- ; change the prescaler back to WDT, and return
-
- SendSrq
- call PreScale8 ; switch the prscaler to RTCC
- banksel TRISA
- bcf TRISA, ADBPin ; tri-state PORTA to make the ADB an output
- movlw SRQ_MAX
- call LineLow
- call PreScale2 ; change the prescaler back to WDT
- return
-
- ;***************************************************************************
-
- ;*** Tlt - TIME FROM STOP BIT TO START BIT *** (Tlt) ***
- ;*** CALLED BY EITHER Talk OR Listen ROUTINES
- ; Loop checking the time, then checking the line to see if it went low
- ; if at any time the line goes low,
- ; see if this is a Talk Command,
- ; if it is a Talk Commmand, go to the Collision routine
- ; if the line goes low before the minimum Tlt time, abort to Attn Signal
- ; if the line is high longer than TLT_Min usecs,
- ; see if this is a Talk Command, and if it is, wait for the mid-point,
- ; and return to Send the Start Bit, Data Bytes, & the Stop Bit
- ; if it's not a Talk Command, see if it's a Listen Command, and if so,
- ; load Tlt_Max for TimeVariable, and look for the line to go
- ; low as the beginning of the Start Bit,
- ; if more than Tlt_Max usecs pass, abort to Attn Signal
- ; if the line goes low and this is a Listen Command,
- ; clear the RTCC & return to get the rest of the Start Bit
-
- Tlt movlw TLT_MIN ; Look for Stop-to-Start-Time, Tlt
- banksel TimeVar
- movwf TimeVar ; Check the time, then check the line
- TltChk1 movf TMR0,W ; See if more than TLT_MIN usecs have passed
- xorwf Random,F ; (ensure the Talk R3 address is Random with XOR)
- subwf TimeVar,W ; by checking whether Carry bit is set
- btfss STATUS,C ; after subtraction
- goto ChkFlag ; if TLT_MIN usecs passed, see what Command this is
- btfsc PORTA, ADBPin ; if not, check whether the line went low
- goto TltChk1 ; if the line is still high, keep looping
- btfsc Flags1,F1Talk ; if line went low, see if this is a Talk Command
- goto Collisn ; if it is, there was a Collision, abort
- movf TMR0,W ; otherwise, check the time
- subwf TimeVar,W ; see if TLT_MIN usecs passed,
- btfss STATUS,C ; if not, abort to Attn Signal, too little
- goto AttnSig ; time passed when the line went low
- clrf TMR0 ; if it's not a Talk Command, clear the RTCC and
- retlw 00h ; return for the rest of the Start Bit
-
- ChkFlag banksel Flags1
- btfsc Flags1,F1Talk ; Check whether to Talk or Listen
- goto TltTalk ; if Talk, wait for mid-point of Tlt time
- btfss Flags1,F1Lstn ; if Listen, continue to look for Start Bit
- retlw 00h ; if neither flag is set, abort, something's wrong
- movlw TLT_MAX ; Load TimeVariable to check for upper limit
- movwf TimeVar ; of Tlt time
- TltChk2 movf TMR0,W ; See if TLT_MAX usecs have been exceeded
- subwf TimeVar,W ; by checking whether Carry bit is set
- btfss STATUS,C ; after subtraction
- goto AttnSig ; if so, abort to Attn Signal
- btfsc PORTA,ADBPin ; if not, check whether the line went low
- goto TltChk2 ; if line is still high, check the time again
- btfsc Flags1,F1Talk ; if line went low, see if this is a Talk Command
- goto Collisn ; if so, there was a Collision
- clrf TMR0 ; if it's not a Talk Command, return to get
- retlw 00h ; the rest of the Start Bit from Host
-
- TltTalk movlw TLT_MID ; Load TimeVariable so Talk will send Start Bit at
- banksel TimeVar
- movwf TimeVar ; about the mid-point of the Tlt
- TltChk3 movf TMR0,W ; See if TLT_MID usecs have been exceeded
- subwf TimeVar,W ; by checking whether Carry bit is set
- btfss STATUS,C ; after subtraction
- retlw 00h ; if time was exceeded, return to send Start Bit
- btfsc PORTA, ADBPin ; if not, check whether the line went low
- goto TltChk3 ; if line is still high, check the time again
- goto Collisn ; if the line went low, abort to Collision
-
-
- Collisn banksel bank1
- btfsc ReqReg, 3 ; if there was a collision during a Talk Reg. 3
- bsf Flags1, F1Cllsn ; Command, then set the Collision Flag,
- goto AttnSig ; otherwise, just abort to Attn Signal
-
- ;***************************************************************************
-
-
- SendLow
- movlw LOW0BIT ; Send a '0' bit
- call LineLow ; hold the line low for 2/3rd of a Bit Cell
- movlw HI_0BIT
- call LineHi ; let the line high for the rest of the Bit Cell
- return
-
- SendHigh
- movlw LOW1BIT ; Send a '1' bit
- call LineLow ; hold the line low for 1/3rd of a Bit Cell
- movlw HI_1BIT
- call LineHi ; let the line high for the rest of the Bit Cell
- return
-
-
-
-
-
- ;*** MAKE LINE GO LOW TIME IN TimeVar AS A '1' OR '0' BIT *** (LineLow) ***
- ;*** CALLED BY Talk OR Srq
-
- LineLow movwf TimeVar
- Low_Tmp movf TMR0,W ; Check the clock,
- subwf TimeVar,W ; loop until TimeVar usecs have passed
- skpnc
- goto Low_Tmp
- banksel bank1 ; Tri-state PORTA to make ADB line an input again
- bsf TRISA, ADBPin ; and let the line go high
- banksel bank0
- clrf TMR0 ; and clear RTCC
- goto $+1 ; Allow the ADB Port line to stabilize
- goto $+1 ; Allow the ADB Port line to stabilize
- btfss PORTA, ADBPin ; check if the line is still low, if so, a
- goto Collisn ; Collision occurred
- retlw 00h ; if not, return to load high time for rest of bit
-
- ;*** MAKE LINE GO HIGH FOR REST OF BIT CELL TIME IN TimeVar *** (LineHi) ***
- ;*** CALLED BY Talk
-
- LineHi movwf TimeVar ; Let the line go high for a pre-designated time
- Hi_Tmp movf TMR0,W ; Check the clock,
- subwf TimeVar,W ; loop until TimeVar usecs have passed
- skpnc
- goto Hi_Tmp
- btfss PORTA, ADBPin ; check if the line is still high,
- goto Collisn ; if not, a Collision occurred, Abort
- btfsc Flags1,F1Stop ; if this is the end of the Data Stop Bit, don't
- retlw 00h ; let the line go low again, just return
- banksel bank1 ; if still high, start sending a bit to the Host
- bcf TRISA, ADBPin ; tri-state PORTA to make the ADB an output and
- banksel bank0
- clrf TMR0
- retlw 00h
|