;
		;**********************************************************************
		; 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 ******************************************************