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