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

Steve Lenham steve at bendentech.co.uk
Fri Mar 10 16:26:51 CET 2017


You are right. The datasheet description of the STATUS register is a bit 
misleading. It says:

"If the STATUS register is the destination for an instruction that 
affects the Z, DC or C bits, then the write to these three bits is
disabled."

Because XORWF only affects the Z bit, a natural assumption is that the C 
and CD bits should still be accessible (helped by the Instruction Set 
Summary labelling the relevant column as "Status Affected", implying 
that those not listed are not affected).

However, it would appear that what they should have said is:

"If the STATUS register is the destination for an instruction that 
affects ANY OF the Z, DC or C bits, then the write to ALL THREE bits is 
disabled."

i.e. because the XORWF is affecting Z, writes to Z, DC and C are all 
blocked.

The more I read it now, the more obvious it is, but it wasn't obvious 
before!

Yey! I can stop thinking about this now :-)

Steve L.



On 10/03/2017 15:01, Roman Sowa wrote:
> They are writable by bsf, bcf, swapf and mowvf, when there's no ALU
> operation involved. What I think happens is the result of your XORWF is
> indeed stored in STATUS, but at the end of the cycle, Z, DC and C are
> overwritten by the results provided by ALU.
> So only when ALU is not doing anything (like in BCF) the bit can be
> written and stays there.
>
> Roman
>
> W dniu 2017-03-10 o 15:32, Tom Wiltshire pisze:
>> Writing the STATUS register seems to vary on a bit-by-bit basis. I
>> checked the datasheet for the device I'm using (16F1825) and the Time
>> Out and Power Down bits are readable but not writable, but the Zero
>> bit, Digit Carry and Carry bits are all read and writable. So it
>> should work, at least that part.
>> That suggests there's something else going on.
>>
>> And yeah, Richie, you're right…I suppose I have to use the simulator
>> and see what it can tell me. It's a drag but sometimes an unavoidable
>> necessity!
>>
>> I'll report back once I've had a chance to try it.
>>
>> Tom
>>
>>
>> On 10 Mar 2017, at 11:53, Roman Sowa <modular at go2.pl> wrote:
>>
>>> 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
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
> _______________________________________________
> 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