[sdiy] IIR Shift Filter problem - help with bug spotting in PIC ASM

Roman Sowa modular at go2.pl
Thu Mar 9 15:19:05 CET 2017


Hi,
I think you should start the 4x downshift from asrf, not rrf.
That's probably the typo you didn't see "in the trees".

Roman

W dniu 2017-03-09 o 14:23, Tom Wiltshire pisze:
> Hi All,
>
> If you could cast your eyes over this, I'd be grateful. I'm having one of those "can't see the wood for the trees" moments.
>
> The code below is a simple single-pole IIR filter (a digital RC LPF). The INPUT is a 10-bit variable, which is left-aligned, so I have six empty bits below it.
>
> Now, I've actually got this code working (the good version below), but what I don't understand is why the BAD version doesn't do the same thing. I don't see why testing the Borrow flag and sticking the bits in "manually" is really any different from shifting the Borrow flag in. What am I missing, oh wise SynthDIY list? ;)
>
> Thanks for any pointers!
> Tom
>
> ; The Good Version
>
> WaveformSmoothing:
> 	; Subtract FILTER from new INPUT
> 	movf	FILTER_LO, w
> 	subwf	INPUT_LO, f			; INPUT = INPUT - FILTER
> 	movf	FILTER_HI, w
> 	subwfb	INPUT_HI, f
> 	
> 	; Borrow is zero if result required borrow (negative result)
> 	; Is borrow set?
> 	bcf		FLAGS, 3
> 	btfss	BORROW			; Skip if positive
> 	bsf		FLAGS, 3			; Flag set if negative
> 	
> 	; Do the downshifts (x 1/16th effectively)
> 	lsrf		INPUT_HI, f
> 	rrf		INPUT_LO, f
> 	lsrf		INPUT_HI, f
> 	rrf		INPUT_LO, f
> 	lsrf		INPUT_HI, f
> 	rrf		INPUT_LO, f
> 	lsrf		INPUT_HI, f
> 	rrf		INPUT_LO, f			; 4 shifts total
> 	
> 	; Add the extra bits back in if negative
> 	movlw	0xF0
> 	btfsc	FLAGS, 3
> 	addwf	INPUT_HI, f
>
> 	; Add it to FILTER
> 	movf	INPUT_LO, w
> 	addwf	FILTER_LO, f
> 	movf	INPUT_HI, w
> 	addwfc	FILTER_HI, f
> 	; We now have a smoothed copy of our INPUT in FILTER
>
>
> ; The BAD Version
>
> WaveformSmoothing:
> 	; Subtract FILTER from new INPUT
> 	movf	FILTER_LO, w
> 	subwf	INPUT_LO, f			; INPUT = INPUT - FILTER
> 	movf	FILTER_HI, w
> 	subwfb	INPUT_HI, f
>
> 	; Borrow is zero if result required borrow (negative result)
> 	 ; Flip the state of the borrow flag
>  	movlw	0x01
> 	xorwf	STATUS, f				; Borrow set if negative
> 	
> 	; Do the downshifts (x 1/16th effectively)
> 	rrf		INPUT_HI, f			; Rotate the borrow flag in
> 	rrf		INPUT_LO, f
> 	asrf		INPUT_HI, f			; Propagate it down to lower bits
> 	rrf		INPUT_LO, f
> 	asrf		INPUT_HI, f
> 	rrf		INPUT_LO, f
> 	asrf		INPUT_HI, f
> 	rrf		INPUT_LO, f			; 4 shifts total
>
> 	; Add it to FILTER
> 	movf	INPUT_LO, w
> 	addwf	FILTER_LO, f
> 	movf	INPUT_HI, w
> 	addwfc	FILTER_HI, f
> 	; We now have a smoothed copy of our INPUT in FILTER
>
>
>
> If you'd like to know more about this technique, full details are here (I've brought this useful StackExchange post up here before):
>
> http://electronics.stackexchange.com/questions/30370/fast-and-memory-efficient-moving-average-calculation
>
> The crucial part is the filter equation:
> 	FILT <-- FILT + FF(NEW - FILT)
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at synth-diy.org
> http://synth-diy.org/mailman/listinfo/synth-diy
>



More information about the Synth-diy mailing list