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

Roman Sowa modular at go2.pl
Fri Mar 10 12:53:09 CET 2017


Ask the guys who designed that PIC.
But it seems more logical to me that writing to STATUS register is not 
alowed, as this is "status" after all, and not "control".

Roman

W dniu 2017-03-10 o 11:32, Tom Wiltshire pisze:
> Aha! Thanks! I'll give it a try.
>
> I didn't know you can't mess with the STATUS register. Why not? Why make the STATUS register available if I can't muck about with it?
>
> Tom
>
> On 10 Mar 2017, at 09:59, Roman Sowa <modular at go2.pl> wrote:
>
>> It struck me this morning when I looked at it again.
>>
>> You cannot xorwf the carry/borrow bit, that will never work.
>> Only clrc or setc can do that.
>>
>> I'm talking about this part:
>> ======================================================
>>
>> 	; 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
>> =======================================================	
>>
>> Roman
>>
>> W dniu 2017-03-09 o 18:14, Tom Wiltshire pisze:
>>> Thanks Roman. That was my first thought too, but I've tried it and it doesn't work. I don't get it.
>>>
>>> The intent of that first "rrf" is deliberately to introduce the borrow flag into the top of the result. This is what the working code does.
>>>
>>> The reasoning behind this is that if you've got two eight bit numbers, the range of the difference between them is -255 to +255, a *nine* bit range. So we need to get an extra bit in from somewhere - the carry/borrow.
>>>
>>> Incidentally, I also tried using "lsrf" for all those high-byte shifts. That works fine for positive numbers, but screws up negative numbers, so the filtering works great on rising edges and slopes, but fails spectacularly on falling edges or slopes!
>>>
>>> Tom
>>>
>>> On 9 Mar 2017, at 14:19, Roman Sowa <modular at go2.pl> wrote:
>>>
>>>> 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