786 Zeilen
16 KiB
NASM
786 Zeilen
16 KiB
NASM
TITLE "Source for CAN-USB4 interface for CBUS"
|
|
; filename CAN_USB4.asm 15/09/14
|
|
;
|
|
; Uses 4 MHz resonator and PLL for 16 MHz clock
|
|
; This interface does not have a Node Number
|
|
|
|
|
|
|
|
; The setup timer is TMR3. This should not be used for anything else
|
|
; CAN bit rate of 125 Kbits/sec
|
|
; Standard frame only
|
|
; Uses 'Gridconnect' protocol for USB
|
|
; Works with FTDI 245AM for now.
|
|
|
|
;
|
|
|
|
; added RUN LED switch on.
|
|
; no full diagnostics yet.
|
|
|
|
|
|
; Doesn't use interrupts - for speed.
|
|
; Working at full speed with minimum CAN frames (no data bytes)
|
|
; 390 uSec per frame
|
|
; PC gets all frames 08/05/08
|
|
; Mod so it sends response to RTR (FLiM compatibility)
|
|
; Fixed CAN_ID at 7E to avoid conflict with CAN_RS
|
|
; RTR response removed. Avoids possibility of buffer overflow
|
|
; Allows true sniffer capability for checking self enum. of other modules.
|
|
; FLiM should never have a CAN_ID of 7E
|
|
|
|
; This version is based on the CAN_USBm code but changed for the 25K80 and
|
|
; for use with the 14K50 as an altenative to Andrew's C code vrsion
|
|
; Incorporates ECAN overflow and busy mechanism as in the CAN_CAN
|
|
; Working with the 14K50 OK. 17/09/14
|
|
|
|
;
|
|
; Assembly options
|
|
LIST P=18F25K80,r=hex,N=75,C=120,T=ON
|
|
|
|
include "p18f25K80.inc"
|
|
|
|
;definitions Change these to suit hardware.
|
|
|
|
#DEFINE CDAV 5
|
|
#DEFINE UREQ 4
|
|
#DEFINE CREQ 1
|
|
#DEFINE UDAV 0
|
|
|
|
;set config registers
|
|
|
|
;config for 18F25K80
|
|
|
|
CONFIG FCMEN = OFF, FOSC = HS1, IESO = OFF, PLLCFG = ON
|
|
CONFIG PWRTEN = ON, BOREN = SBORDIS, BORV=0, SOSCSEL = DIG
|
|
CONFIG WDTEN = OFF, WDTPS = 128 ;watchdog 512 mSec
|
|
CONFIG MCLRE = ON, CANMX = PORTB
|
|
CONFIG BBSIZ = BB1K
|
|
|
|
CONFIG XINST = OFF,STVREN = ON,CP0 = OFF
|
|
CONFIG CP1 = OFF, CPB = OFF, CPD = OFF,WRT0 = OFF,WRT1 = OFF, WRTB = OFF
|
|
CONFIG WRTC = OFF,WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTRB = OFF
|
|
|
|
|
|
|
|
; processor uses 4 MHz. Resonator
|
|
|
|
|
|
|
|
|
|
;****************************************************************
|
|
; define RAM storage
|
|
|
|
CBLOCK 0 ;file registers - access bank
|
|
;interrupt stack for low priority
|
|
;hpint uses fast stack
|
|
W_tempL
|
|
St_tempL
|
|
Bsr_tempL
|
|
PCH_tempH ;save PCH in hpint
|
|
PCH_tempL ;save PCH in lpint (if used)
|
|
Fsr_temp0L
|
|
Fsr_temp0H
|
|
Fsr_temp1L
|
|
Fsr_temp1H
|
|
Fsr_temp2L
|
|
Fsr_hold
|
|
Fsr_holx
|
|
TempCANCON
|
|
TempCANSTAT
|
|
CanID_tmp ;temp for CAN Node ID
|
|
IDtemph ;used in ID shuffle
|
|
IDtempl
|
|
|
|
|
|
|
|
Datmode ;flag for data waiting
|
|
Count ;counter for loading
|
|
Count1
|
|
Latcount ;latency counter
|
|
|
|
Temp ;temps
|
|
Temp1
|
|
;the above variables must be in access space (00 to 5F)
|
|
|
|
Buffer ;temp buffer in access bank for data
|
|
RXbuf ;:0x1C USB serial receive packet buffer
|
|
RXbuf1
|
|
RXbuf2
|
|
RXbuf3
|
|
RXbuf4
|
|
RXbuf5
|
|
RXbuf6
|
|
RXbuf7
|
|
RXbuf8
|
|
RXbuf9
|
|
RXbufA
|
|
RXbufB
|
|
RXbufC
|
|
RXbufD
|
|
RXbufE
|
|
RxbufF
|
|
RXbuf10
|
|
RXbuf11
|
|
RXbuf12
|
|
RXbuf13
|
|
RXbuf14
|
|
RXbuf15
|
|
RXbuf16
|
|
RXbuf17
|
|
RXbuf18
|
|
RXbuf19
|
|
|
|
|
|
|
|
ENDC ;ends at 5F
|
|
|
|
|
|
|
|
CBLOCK h'60' ;rest of bank 0
|
|
|
|
Rx0con ;start of receive packet 0
|
|
Rx0sidh
|
|
Rx0sidl
|
|
Rx0eidh
|
|
Rx0eidl
|
|
Rx0dlc
|
|
Rx0d0
|
|
Rx0d1
|
|
Rx0d2
|
|
Rx0d3
|
|
Rx0d4
|
|
Rx0d5
|
|
Rx0d6
|
|
Rx0d7
|
|
|
|
|
|
|
|
Tx0con ;start of transmit frame 0
|
|
Tx0sidh
|
|
Tx0sidl
|
|
Tx0eidh
|
|
Tx0eidl
|
|
Tx0dlc
|
|
Tx0d0
|
|
Tx0d1
|
|
Tx0d2
|
|
Tx0d3
|
|
Tx0d4
|
|
Tx0d5
|
|
Tx0d6
|
|
Tx0d7
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;add variables to suit
|
|
|
|
;****************************************************************
|
|
; used in ASCII to HEX and HEX to ASCII and decimal conversions
|
|
Abyte1 ;first ascii char of a hex byte for ascii input
|
|
Abyte2 ;second ascii char of a hex byte
|
|
Hbyte1 ;first ascii char of a hex byte for ascii output
|
|
Hbyte2
|
|
Atemp ;temp store
|
|
Htemp
|
|
Hexcon ;answer to ascii to hex conversion
|
|
;*************************************************************
|
|
; used in USB transmit and receive
|
|
Srbyte_n ;number of serial bytes received in packet
|
|
Stbyte_n ;number of serial bytes to send
|
|
TXmode ;state during serial send
|
|
RXmode ;state during serial receive
|
|
RXtemp ;temp store for received byte
|
|
RXnum ;number of chars in receive string
|
|
Datnum ;no. of data bytes in a received frame
|
|
|
|
;**************************************************************
|
|
|
|
|
|
|
|
ENDC
|
|
|
|
CBLOCK 0x100
|
|
|
|
TXbuf ;USB transmit packet buffer to PC
|
|
TXbuf1
|
|
TXbuf2
|
|
TXbuf3
|
|
TXbuf4
|
|
TXbuf5
|
|
TXbuf6
|
|
TXbuf7
|
|
TXbuf8
|
|
TXbuf9
|
|
TXbuf10
|
|
TXbuf11
|
|
TXbuf12
|
|
TXbuf13
|
|
TXbuf14
|
|
TXbuf15
|
|
TXbuf16
|
|
TXbuf17
|
|
Txbuf18
|
|
TXbuf19
|
|
TXbuf20
|
|
TXbuf21
|
|
TXbuf22
|
|
TXbuf23
|
|
TXbuf24
|
|
TXbuf25
|
|
|
|
ENDC
|
|
|
|
;****************************************************************
|
|
;
|
|
; start of program code
|
|
|
|
ORG 0000h
|
|
nop ;for debug
|
|
goto setup
|
|
|
|
ORG 0008h
|
|
goto hpint ;high priority interrupt
|
|
|
|
ORG 0018h
|
|
goto lpint ;low priority interrupt
|
|
|
|
|
|
;*******************************************************************
|
|
|
|
ORG 0840h ;start of program
|
|
;
|
|
;
|
|
; high priority interrupt.
|
|
|
|
hpint nop
|
|
btfsc PIR5,IRXIF ;a bus error?
|
|
bra err
|
|
btfsc PIR5,ERRIF
|
|
bra err
|
|
bra no_err
|
|
err
|
|
bsf CANCON,ABAT ;abort transmission
|
|
bcf PIR5,ERRIF ;clear interrupts
|
|
bcf PIR5,IRXIF
|
|
bcf PIE5,ERRIF
|
|
|
|
bcf PIR5,IRXIF
|
|
|
|
|
|
|
|
retfie 1
|
|
|
|
no_err
|
|
movlb .15
|
|
btfss PIR5,FIFOWMIF,0
|
|
bra no_fifo
|
|
bcf PIR5,FIFOWMIF,0 ;clear FIFO flag
|
|
bcf PIR5,4,0 ;clear busy frame flag
|
|
bsf TXB1CON,TXREQ ;send busy frame
|
|
bcf PIE5,FIFOWMIE,0 ;disable FIFO interrupt
|
|
movlb .14
|
|
bsf TXBIE,TXB1IE ;enable IRQ for busy frame sent
|
|
bsf PIE5,4,0 ;enable IRQ for busy frame sent
|
|
movlb 0
|
|
retfie 1
|
|
|
|
no_fifo bcf PIR5,4,0 ;clear busy frame flag
|
|
movlb .14
|
|
bcf TXBIE,TXB1IE ;no busy frame IRQ
|
|
movlb 0
|
|
bsf PIE5,FIFOWMIE ;wait for next FIFO IRQ
|
|
|
|
retfie 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;**************************************************************
|
|
;
|
|
;
|
|
; low priority interrupt. (if used)
|
|
;
|
|
|
|
lpint retfie
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;*********************************************************************
|
|
|
|
|
|
|
|
|
|
main btfsc COMSTAT,7 ;fast loop for CAN detection
|
|
bra incan
|
|
btfsc PORTB,UDAV
|
|
bra inusb
|
|
bra main
|
|
|
|
; move incoming CAN frame to serial output buffer
|
|
|
|
incan movf CANCON,W ;sort out ECAN buffer
|
|
andlw B'00001111'
|
|
movwf TempCANCON
|
|
movf ECANCON,W
|
|
andlw B'11110000'
|
|
iorwf TempCANCON,W
|
|
movwf ECANCON
|
|
movlw .13
|
|
movwf Count
|
|
lfsr FSR0,RXB0SIDH ; ;start of CAN frame in RB0
|
|
lfsr FSR1,Rx0sidh
|
|
incan1 movff POSTINC0,POSTINC1 ;save ECAN buffer
|
|
decfsz Count
|
|
bra incan1
|
|
bcf RXB0CON,RXFUL
|
|
lfsr FSR0,Rx0sidh
|
|
lfsr FSR1,TXbuf ;start of serial string for PC
|
|
movlw ":" ;serial start
|
|
movwf POSTINC1
|
|
btfsc Rx0sidl,3 ;is it extended
|
|
bra exide
|
|
movlw "S" ;standard frames only
|
|
movwf POSTINC1
|
|
bra serload
|
|
exide movlw "X"
|
|
movwf POSTINC1
|
|
|
|
serload movf POSTINC0,W ;get byte
|
|
call hexasc ;convert to acsii
|
|
movff Hbyte1,POSTINC1
|
|
movff Hbyte2,POSTINC1
|
|
movf POSTINC0,W ;get byte
|
|
call hexasc ;convert to acsii
|
|
movff Hbyte1,POSTINC1
|
|
movff Hbyte2,POSTINC1
|
|
btfsc Rx0sidl,3 ;is it extended
|
|
bra exload
|
|
incf FSR0L ;skip the extended ID bytes
|
|
incf FSR0L
|
|
bra serlo1
|
|
exload movf POSTINC0,W ;get byte
|
|
call hexasc ;convert to acsii
|
|
movff Hbyte1,POSTINC1
|
|
movff Hbyte2,POSTINC1
|
|
movf POSTINC0,W ;get byte
|
|
call hexasc ;convert to acsii
|
|
movff Hbyte1,POSTINC1
|
|
movff Hbyte2,POSTINC1
|
|
serlo1 movff POSTINC0,Datnum ;get dlc byte
|
|
btfsc Datnum,6 ;is it an RTR
|
|
bra rtrset
|
|
movlw "N"
|
|
movwf POSTINC1
|
|
bra datbyte
|
|
rtrset movlw "R"
|
|
movwf POSTINC1
|
|
bcf Datnum,6 ;Datnum now has just the number
|
|
datbyte tstfsz Datnum
|
|
bra datload
|
|
bra back2
|
|
datload movf POSTINC0,W ;get byte
|
|
call hexasc ;convert to acsii
|
|
movff Hbyte1,POSTINC1
|
|
movff Hbyte2,POSTINC1
|
|
decfsz Datnum
|
|
bra datload
|
|
back2 movlw ";"
|
|
movwf POSTINC1
|
|
movf FSR1L,W ;get last
|
|
movwf Count1 ;number of bytes to send
|
|
|
|
|
|
lfsr FSR1,TXbuf
|
|
|
|
|
|
;set to output
|
|
|
|
|
|
usbwr movlw B'00000000'
|
|
movwf TRISC
|
|
|
|
|
|
notwr1 btfsc PORTB,CREQ ;CREQ must be lo to write to USB initially
|
|
bra notwr1
|
|
|
|
|
|
notwr bsf PORTB,CDAV
|
|
btfss PORTB,CREQ ;CREQ must be hi to write to USB
|
|
bra notwr
|
|
movff POSTINC1,PORTC ;output byte
|
|
nop ;settling time
|
|
nop
|
|
|
|
bcf PORTB,CDAV ;flag to USB
|
|
nop
|
|
nop
|
|
|
|
decfsz Count1
|
|
bra notwr1
|
|
movlw B'11111111'
|
|
movwf TRISC ;back to inputs
|
|
|
|
|
|
|
|
endwr bra main
|
|
|
|
inusb clrf RXmode ;clear receive mode flags
|
|
movlw B'11111111'
|
|
movwf TRISC ;set to input
|
|
btfss PORTB,UDAV ;any USB data?
|
|
bra notin ;loop
|
|
|
|
bsf PORTB,UREQ ;can take
|
|
inusb1 btfsc PORTB,UDAV ;is data
|
|
bra inusb1
|
|
nop
|
|
bcf PORTB,UREQ
|
|
|
|
movlw ":"
|
|
subwf PORTC,W
|
|
bnz notin ;not start of frame
|
|
|
|
inusb2 btfss PORTB,UDAV ;is data
|
|
bra inusb2
|
|
bsf PORTB,UREQ
|
|
inusb3 btfsc PORTB,UDAV
|
|
bra inusb3
|
|
nop
|
|
bcf PORTB,UREQ
|
|
|
|
movlw "S" ;is it S (standard) or X (extended)
|
|
subwf PORTC,W
|
|
bz instd
|
|
movlw "X"
|
|
subwf PORTC,W
|
|
bz inext
|
|
bra notin ;neither so abort
|
|
instd bcf RXmode,3 ;flag standard
|
|
bra instart
|
|
inext bsf RXmode,3 ;flag extended
|
|
instart clrf RXnum ;byte counter
|
|
lfsr FSR2,RXbuf ;set to start
|
|
|
|
|
|
inloop btfss PORTB,UDAV ;read all USB till end
|
|
bra inloop
|
|
bsf PORTB,UREQ ;can take
|
|
inloop1 btfsc PORTB,UDAV ;data?
|
|
bra inloop1
|
|
nop
|
|
bcf PORTB,UREQ
|
|
|
|
|
|
movlw ";" ;end?
|
|
subwf PORTC,W
|
|
bz lastin
|
|
movff PORTC,POSTINC2 ;bug fix
|
|
bra inloop
|
|
|
|
lastin movff PORTC,POSTINC2
|
|
|
|
|
|
lfsr FSR2,RXbuf ;point to serial receive buffer
|
|
lfsr FSR1,Tx0sidh ;point to CAN TX buffer 1 - lowest priority
|
|
txload movff POSTINC2,Abyte1
|
|
movff POSTINC2,Abyte2
|
|
call aschex
|
|
movwf POSTINC1 ;put in CAN TX buffer
|
|
movlw "N"
|
|
subwf INDF2,W
|
|
bz txload1
|
|
movlw "R"
|
|
subwf INDF2,W
|
|
bz txload5
|
|
bra txload
|
|
txload5 bsf RXmode,2 ;flag R
|
|
txload1 incf FSR2L ;miss N or R
|
|
incf FSR1L ;miss dlc
|
|
btfsc RXmode,3 ;is it ext
|
|
bra txload2
|
|
incf FSR1L ;miss out EIDH and EIDL if not extended
|
|
incf FSR1L
|
|
|
|
txload2 movlw ";"
|
|
subwf INDF2,W
|
|
bz txdone
|
|
|
|
|
|
|
|
txload4 movff POSTINC2,Abyte1
|
|
movff POSTINC2,Abyte2
|
|
call aschex
|
|
movwf POSTINC1 ;put in CAN TX buffer
|
|
incf RXnum,F
|
|
bra txload2
|
|
txdone movf RXnum,W ;get number of data bytes
|
|
btfsc RXmode,2 ;is it a RTR
|
|
iorlw B'01000000' ;set RTR bit
|
|
movwf Tx0dlc
|
|
movlw B'00001000'
|
|
btfsc RXmode,3 ;extended?
|
|
iorwf Tx0sidl,F ;add extended bit
|
|
clrf RXmode ;ready for next
|
|
movlw .10
|
|
movwf Latcount ;ten tries at low priority
|
|
call sendTX0
|
|
|
|
notin bcf PORTB,UREQ ;clear
|
|
|
|
goto main
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;***************************************************************************
|
|
; main setup routine
|
|
;*************************************************************************
|
|
|
|
setup bcf WDTCON,SWDTEN ;WDT off during reset
|
|
movlb 0
|
|
clrf INTCON ;no interrupts yet
|
|
|
|
movlb .15
|
|
|
|
clrf ANCON0 ;disable A/D
|
|
clrf ANCON1
|
|
clrf CM1CON
|
|
clrf CM2CON
|
|
setf WPUB ;pullups set
|
|
movlb 0
|
|
|
|
|
|
;port settings will be hardware dependent. RB2 and RB3 are for CAN.
|
|
;set S_PORT and S_BIT to correspond to port used for setup.
|
|
;rest are hardware options
|
|
|
|
|
|
movlw B'00100000' ;Port A outputs except reset pin
|
|
movwf TRISA ;
|
|
movlw B'00001011' ;RB0 is UDAV, RB1 is CREQ, RB2 = CANTX, RB3 = CANRX, RB4 = UREQ, RB5 = CDAV
|
|
;RB6,7 for debug and ICSP and diagnostic LEDs
|
|
movwf TRISB
|
|
clrf PORTB
|
|
bsf PORTB,2 ;CAN recessive
|
|
bcf PORTB,4 ;USB write strobe
|
|
bcf PORTB,5 ;USB read strobe
|
|
movlw B'11111111' ;Port C USB interface
|
|
movwf TRISC
|
|
|
|
; next segment is essential.
|
|
|
|
clrf BSR ;set to bank 0
|
|
clrf EECON1 ;no accesses to program memory
|
|
bsf CANCON,7 ;CAN to config mode
|
|
movlw B'10110000'
|
|
movwf ECANCON ;CAN mode 2
|
|
bsf ECANCON,5
|
|
|
|
movlb .15
|
|
|
|
clrf RXB0CON
|
|
clrf RXB1CON
|
|
bsf TXB0CON,TXABT ;abort any pending messages
|
|
bsf TXB1CON,TXABT
|
|
|
|
|
|
movlb .14
|
|
|
|
clrf BSEL0 ;8 frame FIFO
|
|
clrf B0CON
|
|
clrf B1CON
|
|
clrf B2CON
|
|
clrf B3CON
|
|
clrf B4CON
|
|
clrf B5CON
|
|
bcf TXBIE,TXB1IE ;no interrupt on busy
|
|
|
|
|
|
|
|
movlw B'00000011' ;set CAN bit rate at 125000 for now. 4 MHz
|
|
movwf BRGCON1
|
|
movlw B'10011110' ;set phase 1 etc
|
|
movwf BRGCON2
|
|
movlw B'00000011' ;set phase 2 etc
|
|
movwf BRGCON3
|
|
movlb 0
|
|
|
|
movlw B'00100000'
|
|
movwf CIOCON ;CAN to high when off
|
|
|
|
|
|
mskload lfsr FSR0,RXM0SIDH ;Clear masks, point to start
|
|
mskloop clrf POSTINC0
|
|
cpfseq FSR0L
|
|
bra mskloop
|
|
|
|
bcf COMSTAT,RXB0OVFL ;clear overflow flags if set
|
|
bcf COMSTAT,RXB1OVFL
|
|
clrf PIR5 ;clear all flags
|
|
clrf CANCON ;out of CAN setup mode
|
|
clrf CCP1CON
|
|
|
|
clrf IPR1 ;all peripheral interrupts are low priority
|
|
clrf IPR2
|
|
clrf PIE2
|
|
clrf PIR5 ;can FLAGS
|
|
clrf EEADRH ;clear EEPROM Hi byte
|
|
|
|
|
|
|
|
movlw B'10001000' ;Config TX1 buffer for busy frame
|
|
movwf CANCON
|
|
movlb .15 ;buffer in bank 15
|
|
movlw B'00000011'
|
|
movwf TXB0CON ;no send yet
|
|
movwf TXB1CON
|
|
clrf TXB1SIDH
|
|
clrf TXB1SIDL
|
|
clrf TXB1DLC
|
|
movlb 0 ;back to bank 0
|
|
clrf CANCON ;out of CAN setup mode
|
|
|
|
movlw 3
|
|
movwf Tx0con ;set transmit priority
|
|
|
|
movlw B'00100011'
|
|
movwf IPR3 ;high priority CAN RX and Tx error interrupts(for now)
|
|
clrf IPR1 ;all peripheral interrupts are low priority
|
|
clrf IPR2
|
|
clrf PIE2
|
|
|
|
clrf INTCON2 ;
|
|
clrf INTCON3 ;
|
|
|
|
clrf PIR1
|
|
clrf PIR2
|
|
|
|
clrf PIR5
|
|
movlw B'10110001'
|
|
movwf IPR5 ;FIFOHWM and TXB are high priority
|
|
movlw B'10110001'
|
|
movwf PIE5 ;FIFOHWM IRQ, error interrupts and TX complete only
|
|
|
|
bcf PORTB,6
|
|
bsf PORTB,7 ;put run LED on.
|
|
goto main
|
|
|
|
|
|
|
|
;****************************************************************************
|
|
; start of subroutines
|
|
|
|
;*****************************************************************************
|
|
; send a busy frame - already preloaded in TX0.
|
|
|
|
sendTX1 movlb .15 ;set to bank 1
|
|
bsf TXB1CON,TXREQ ;send immediately
|
|
movlb 0 ;back to bank 0
|
|
return
|
|
;******************************************************************
|
|
|
|
; Send contents of Tx1 buffer via CAN TXB1
|
|
|
|
sendTX0 movlb .15 ;check for buffer access
|
|
tx_loop btfsc TXB0CON,TXREQ
|
|
bra tx_loop
|
|
movlb 0
|
|
|
|
lfsr FSR0,Tx0con
|
|
lfsr FSR1,TXB0CON
|
|
ldTX0 movf POSTINC0,W
|
|
movwf POSTINC1 ;load TXB1
|
|
movlw Tx0d7+1
|
|
cpfseq FSR0L
|
|
bra ldTX0
|
|
|
|
|
|
movlb .15 ;bank 15
|
|
tx0test btfsc TXB0CON,TXREQ ;test if clear to send
|
|
bra tx0test
|
|
bsf TXB0CON,TXREQ ;OK so send
|
|
|
|
tx1done movlb 0 ;bank 0
|
|
return ;successful send
|
|
|
|
|
|
|
|
;************************************************************************
|
|
|
|
|
|
; converts one hex byte to two ascii bytes
|
|
|
|
hexasc movwf Htemp ;save hex. comes in W
|
|
swapf Htemp,W
|
|
andlw B'00001111' ;mask
|
|
addlw 30h
|
|
movwf Hbyte1
|
|
movlw 39h
|
|
cpfsgt Hbyte1
|
|
bra nxtnib
|
|
movlw 7
|
|
addwf Hbyte1,F
|
|
nxtnib movlw B'00001111'
|
|
andwf Htemp,W
|
|
addlw 30h
|
|
movwf Hbyte2
|
|
movlw 39h
|
|
cpfsgt Hbyte2
|
|
bra ascend
|
|
movlw 7
|
|
addwf Hbyte2,F
|
|
ascend return ;Hbyte1 has high nibble, Hbyte2 has low nibble
|
|
|
|
|
|
;****************************************************************************
|
|
; converts two ascii bytes to one hex byte.
|
|
; for consistency, ascii hi byte in Abyte1, ascii low byte in Abyte2
|
|
; answer in Hexcon
|
|
|
|
aschex movlw 30h
|
|
subwf Abyte1,F
|
|
movlw 9
|
|
cpfsgt Abyte1
|
|
bra hinib
|
|
movlw 7
|
|
subwf Abyte1,F
|
|
hinib movf Abyte1,W
|
|
movwf Hexcon
|
|
swapf Hexcon,F
|
|
movlw 30h
|
|
subwf Abyte2,F
|
|
movlw 9
|
|
cpfsgt Abyte2
|
|
bra hexend
|
|
movlw 7
|
|
subwf Abyte2,F
|
|
hexend movf Abyte2,W
|
|
iorwf Hexcon,W
|
|
return
|
|
|
|
;
|
|
|
|
|
|
;************************************************************************
|
|
|
|
end
|