;
;**********************************************************************
; capcmd.asm - CAPTURE subroutines for cmd monitor
;**********************************************************************
;
; created 04/03/98 -rlf
; modified 04/13/98 -rlf
;
;*********************************************************************
; Capture module interface functions
;
; The routines included in this file will read the period of a signal
; applied to CAP0 or CAP1. Timer3 is the timer resource required by the
; capture peripherals. Timer3 can be free running or Timer3 can be setup
; to start upon the detection of the first rising edge. For this
; implementation Timer3 starts upon the first rising edge on CAP0 or
; CAP1.
;
cblock
overflow
endc
;
;*********************************************************************
ReadCAP ; This routine uses ReadCAP to measure period on channel n
;*********************************************************************
;
; install this command in the CmdMenu lookup table
CmdPC = $ ; save current inline assembly PC value
org CurCmdMenuAdr ; set assembly PC to addr for new entry
; CmdMenu table entry
data "CAPn\r", CmdPC, "Measure capture channel period\r\n"
CurCmdMenuAdr = $ ; set current CmdMenu addr for next entry
org CmdPC ; begin cmd code gen at inline address
;
; The channel selection is passed in the WREG (it is necessary to
; bring it in from the cmd monitor). It is necessary to pass in the
; channel, then convert the results and wrap the appropriate
; text around the answer to be returned to the user.
; Both the selected Channel and value is returned.
;
call InitCAPn ; init capture module(s)
movlw cmdPrmBuff ; load parameter buffer address
movwf FSR1 ; into FSR1
movfp INDF1, WREG ; else put cmd value in WREG
call ReadCAPn ; read specified capture channel
btfsc ALUSTA,Z ; check return value
goto errout ; display error message
; generate output string
CpyTbl2Out CapnD ; init beginning of output buffer
movlw cmdPrmBuff ; load original parameter buffer address
movwf FSR1 ; into FSR1
movfp INDF1, WREG ; put cmd value in WREG
andlw 0x0F ; mask out upper nibble
call Dec2Buf ; convert channel into output buffer
CpyTbl2Out Eqtx ; add = 0x text
movlr 0 ; select GPR bank
movfp overflow,WREG ; retrieve multiple overflow count
call Hex2Buf ; convert overflow byte
movfp PRODH, WREG ; get MSB of capture
call Hex2Buf ; convert msb of value with no leading 0
movfp PRODL,WREG ; get LSB of capture
call Hex2Buf ; convert lsb of value with no leading 0
CpyTbl2Out CapEm ;
return ; return from Cmd
errout CpyTbl2Out Err ; add trailing text
return
; This is the end of the functions executable code
;
; These data statements store constant ascii output strings in program
; memory. They're accessed using the CpyTbl2Out macro.
;
CapnD ; constant string for capture channel
data "\nCAP", 0
Eqtx ; constant string for =
data " Period = 0x", 0
CapEm ; constant string for capture hex display
data " hex\n\r", 0
Err ; constant for error message
data "Invalid Capture Channel Entered\n\r", 0
;
;
;*********************************************************************
ReadCAPn; Read period for capture channel specified in W
;*********************************************************************
;
; This subroutine selects the capture channel, starts a
; measurement cycle then returns - leaving the result in
; CAPxH and CAPxL registers. It is called while WREG contains
; channel (1 - 4).
;
movlr 0 ; select GPR bank
clrf overflow,1 ; reset overflow register
movlb 1 ; select SFR bank
bcf PIR1,TMR3IF ; reset Timer3 overflow flag
movlb 2 ; select SFR bank
clrf TMR3H ; reset Timer3 MSB
clrf TMR3L ; reset Timer3 LSB
andlw 0x0F ; ensure upper bits are masked out
dcfsnz WREG,0 ; else, is channel 1 ?
goto rdcap1 ; yes, measure capture1 period
dcfsnz WREG,0 ; else channel 2 ?
goto rdcap2 ; yes, measure capture2 period
; dcfsnz WREG,0 ; else channel 3 ?
; goto rdcap3 ; yes, measure capture3 period
; dcfsnz WREG,0 ; else channel 4 ?
; goto rdcap4 ; measure capture4 period
bsf ALUSTA,Z ; no channel match, set error flag
return ; return with error
; ***************************************************************
; ************** READ CAPTURE CHANNEL 1
rdcap1 movlb 2 ; select SFR bank
movfp CA1H,WREG ; dummy read to transfer Master OV state
movfp CA1L,FSR1 ; dummy read to transfer Master OV state
movlb 3 ; select SFR bank
btfss TCON2,CA1OVF ; test for overflow
goto startcap1 ; no overflow so start capture
movlb 2 ; select SFR bank
movfp CA1H,WREG ; dummy read (MSB)
movfp CA1L,FSR1 ; dummy read (LSB)
movlb 1 ; select SFR bank
bcf PIR1,CA1IF ; reset capture event flag from overflow
startcap1
movlb 1 ; select SFR bank
btfss PIR1,CA1IF ; test for capture event
goto $-1 ; loop til capture event occurs
movlb 3 ; select SFR bank
bsf TCON2,TMR3ON ; start timer3
movlb 1 ; select SFR bank
bcf PIR1,CA1IF ; reset capture event flag
movlb 2 ; select SFR bank
movfp CA1H,FSR1 ; save off count (MSB)
movfp CA1L,WREG ; save off count (LSB)
movlb 1 ; select SFR bank
btfss PIR1,TMR3IF ; test for overflow
goto no_ov1 ; no overflow
bcf PIR1,TMR3IF ; reset timer3 overflow flag
movlr 0 ; select GPR bank
incf overflow,1 ; increment overflow
no_ov1 btfss PIR1,CA1IF ; test for capture event
goto $-6 ; loop til capture event occurs
bcf PIR1,CA1IF ; reset capture event flag
movlb 3 ; select SFR bank
bcf TCON2,TMR3ON ; stop timer3
movlb 2 ; select SFR bank
movfp CA1H,PRODH ; read capture MSB
movfp CA1L,PRODL ; read capture LSB
subwf PRODL,1 ; compose LSB
movpf FSR1,WREG ; retrieve MSB first read
subwfb PRODH,1 ; compose MSB
btfss ALUSTA,C ; test for borrow (MSB)
decf overflow,1 ; borrow occurred so decrement overflow
bcf ALUSTA,Z ; clear channel error flag
return ; return with results in PRODH:L
;***************************************************************
; ************** READ CAPTURE CHANNEL 2
rdcap2 movlb 3 ; select SFR bank
movfp CA2H,WREG ; dummy read to transfer Master OV state
movfp CA2L,FSR1 ; dummy read to transfer Master OV state
btfss TCON2,CA2OVF ; test for overflow
goto startcap2 ; no overflow so start capture
movfp CA2H,WREG ; dummy read (MSB)
movfp CA2L,FSR1 ; dummy read (LSB)
movlb 1 ; select SFR bank
bcf PIR1,CA2IF ; reset capture event flag
startcap2
movlb 1 ; select SFR bank
btfss PIR1,CA2IF ; test for capture event
goto $-1 ; loop til capture event occurs
movlb 3 ; select SFR bank
bsf TCON2,TMR3ON ; start timer3
movlb 1 ; select SFR bank
bcf PIR1,CA2IF ; reset capture event flag
movlb 3
movfp CA2H,FSR1 ; save off count (MSB)
movfp CA2L,WREG ; save off count (LSB)
movlb 1 ; select SFR bank
btfss PIR1,TMR3IF ; test for overflow
goto no_ov2 ; there was no Timer3 overflow
bcf PIR1,TMR3IF ; reset Timer3 overflow flag
movlr 0 ; select GPR bank
incf overflow,1 ; increment overflow count
no_ov2 btfss PIR1,CA2IF ; test for capture event
goto $-6 ; loop til capture event occurs
movlb 3 ; select SFR bank
bcf TCON2,TMR3ON ; stop timer3
movlb 1 ; select SFR bank
bcf PIR1,CA2IF ; reset capture event flag
movlb 3
movfp CA2H,PRODH ; read capture MSB
movfp CA2L,PRODL ; read capture LSB
subwf PRODL,1 ; compose LSB
movpf FSR1,WREG ; retrieve MSB first read
subwfb PRODH,1 ; compose MSB
btfss ALUSTA,C ; test for borrow (MSB)
decf overflow,1 ; borrow occurred so decrement overflow
bcf ALUSTA,Z ; clear channel error flag
return ; return with results in PRODH:L
;***************************************************************
; ************** READ CAPTURE CHANNEL 3
rdcap3
; no code available at this time
return ; return with results in ??
;***************************************************************
; ************** READ CAPTURE CHANNEL 4
rdcap4
; no code available at this time
return ; return with results in ??
;
;
;*********************************************************************
InitCAPn; Initialize the capture peripherals
;*********************************************************************
;
; Instructions: Set up CAPTURE module. Timer3 is the timer resource
; used with time-based captures.
;
movlb 7 ; select bank for control register
bsf TCON3,CA3ED0 ; set capture3 on rising edge
bsf TCON3,CA4ED0 ; set capture4 on rising edge
movlb 3 ; select bank for control register
bsf TCON1,CA1ED0 ; set capture1 on rising edge
bsf TCON1,CA2ED0 ; set capture2 on rising edge
bcf TCON1,TMR3CS ; ensure timer3 increments of internal clock
bsf TCON2,PR3 ; enable capture1 vs. period
; bsf TCON2,TMR3ON ; start timer3
return ; return from capture initialized
; end of file capcmd.asm ******************************************************