I decided to try and make the assembler less ugly first by using indirect addressing to access the Period[8] array but it is no faster than my laborious method and this one will only run on an 18F4550 due to the use of the helpful POSTINC0 operator representing INDF(0) with a post Increment:
Code:
_xPULSIN MOVLW 0xFF
MOVWF _pCount
MOVLW 0x0F
MOVWF _pCount + 1 ;pCount = $FFF = 4095
MOVLW _Mask
MOVWF _k ;k = Mask
CLRF _sample ;clear sample flag
cycleX MOVF _mPort, W ;Sample the Port
ANDWF _k, W
MOVWF _j ;j = Port AND Mask
MOVLW High(_Period) ;Set up FSR to point to Period[0]
MOVWF FSR0H
MOVLW Low(_Period)
MOVWF FSR0L
MOVLW 1
MOVWF _i ;Bit Marker = 00000001
CheckJ RRCF _j
BTFSS STATUS,C ;Bit i Set
GOTO BCLR
INCFSZ POSTINC0 ;Yes - Period[i] = Period[i]+1
GOTO NoRoll
INFSNZ POSTINC0 ;=Inc and always skip - Period.Hi never Zero
NoRoll MOVF POSTINC0,F ;=NOP except inc FSR
MOVF _i,W
IORWF _sample,F ;Now sampling bit i
Nexti RLCF _i ;i = i<<1
BTFSS STATUS,C ;Carry set = 8 rotations?
GOTO CheckJ ;No - Loop round
MOVF _k,F ;Is Mask = 0?
BTFSC STATUS,Z
RETURN ;Yes - Finished all samples
DecCount DECFSZ _pCount ;No - Update counter
GOTO cycleX
DECFSZ _pCount + 1
GOTO cycleX
RETURN ;Countdown = 0 - Timeout?
BCLR MOVF POSTINC0,F ;=NOP except inc FSR
MOVF POSTINC0,F ;=NOP except inc FSR
MOVF _i,W
ANDWF _sample,W ;Pulse low - already sampling?
BTFSC STATUS,Z
GOTO Nexti ;No - do nothing
MOVF _i,W
XORWF _k,F ;Yes - Clear Bit in Mask
GOTO Nexti
;-----------------------------------------------------------------------------
_PeriodZ MOVLW High(_Period) ;Set Period[0 to 7] = 0
MOVWF FSR0H
MOVLW Low(_Period)
MOVWF FSR0L
CLRF _i ; i = 0 (counter)
clr CLRF POSTINC0 ;CLRF INDF0 then inc FSR0
INCF _i
BTFSS _i,4 ; i.4 set = 16
GOTO clr
RETURN
Bookmarks