Searching \ for 'Bug in posted MOMA code??' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/index.htm?key=bug+posted+moma
Search entire site for: 'Bug in posted MOMA code??'.

Truncated match.
PICList Thread
'Bug in posted MOMA code??'
1998\11\09@172243 by Morgan Olsson

picon face
Or what is it:

I just added new routines in the project from where i pulled out the code
for MOMA filter i posted here recently.

The i noticed that the output after the average routine "flickers" for
certaion input values!

I exchanged the summing routine Sum16 (in the posting) to a straight adding
routine, and the problem was gone.  !?

I just can't see what is wrong with Sum16 ??

On the LCD i have connected for field-test, i see that the most significant
hex nibble flickers occasionally for values close to where least
significant byte shifts between 00 and FF.  And this is after the following
divide by 8 (shift left 3 steps.)

Theese are the problem values afted the average routines (Sum16, and the
shift right 3 steps) It is the average of the values feeding the filter.

Should read:            Reads:   (#= flicker)
00FF/0100               #0FF/#1FF
01FF/0200               #1FF/#2FF
02FF/0300               #2FF/#3FF
03FF/0400               #3FF/#4FF
04FF/0500               #4FF/#5FF
etc                     etc

By the notation 02FF/0300 i mean it is weighing between theese tvo values
because of noise.  That should no way give overflow to MSB.  Still MSB
flickers occasionally for a reason i can not understand!
I cant see exactly what the digit # is as i have sample rate about 300Hz.

Please can anybody see what i made wrong?
Thanks in advance
/Morgan

Sum16:  ;commented in english
;Summs a interval of 2-byte variables to 3-byte T4:T3:T2
;MSB at adress of LSB +1.
;Before call, state in W the total number of 2byte variables to sum.
;And set FSR to point to the low byte of first variabe to sum.
;(FSR may point in bank 0 or 1 regardless of back select :) )
;FSR get incremented by two for each variable summed

       movwf T1        ;store number of variables to temp reg T1
        movlw  4          ;Preload destination with 000004h
       movwf T2           ;(New; for correct rounding in this application
       clrf T3    ;where we sum 8 variables;
       clrf T4    ;For normal SUM use we clear all T4:T3:T2)
Sum16loop:
       movf INDF,W     ;Get low byte,
       addwf T2,F      ;and add to low byte result
       ifcs            ;If carry,
         incf T3,F     ; inc middle byte result
       ifzs            ;If wrapped to Zero,
         incf T4,F     ; inc high byte result

       incf FSR,F      ;Point to MSB in,
       movf INDF,W     ;get it,
       addwf T3,F      ;and add to middle byte result
       ifcs            ;If carry,
         incf T4,F     ; inc high byte result

       incf FSR,F      ;Point to next variable low byte
       decfsz T1,F     ;Decrease counter for variables to add,
         goto Sum16loop;if not done add next variable
       return      ;the sum +4 is now in T4:T3:T2

;and after this routine:
;Divide by 8 = shift logical left 3 steps
       STL 3, T1
FilAdiv8loop:
       cc              ;clear carry
       rrf T4, F
       rrf T3, F
       rrf T2, F
       decfsz T1, F
         goto FilAdiv8loop

       ;And the averaged result is in T3:T2

;... But sometimes the highest bits of T3 flickers!  WHY???

       Morgan Olsson                   ph  +46(0)414 70741
       MORGANS REGLERTEKNIK            fax +46(0)414 70331
       H€LLEKS           (in A-Z letters: "HALLEKAS")
       SE-277 35 KIVIK, SWEDEN               spam_OUTmrtTakeThisOuTspaminame.com
___________________________________________________________

1998\11\09@181135 by Scott Dattalo

face
flavicon
face
Morgan Olsson wrote:
{Quote hidden}

Suppose the addwf T2,F sets C and Z. Then, T4 will be incremented and
the shift right 3 done below will cause the upper nibble of T3 to
'flicker'.

It might be better to do something like this:

       movf    INDF,W
       addwf   T2,F
       rlf     known_zero,W
       addwf   T3,F
       rlf     known_zero,W
       addwf   T4,F


>
>         incf FSR,F      ;Point to MSB in,
>         movf INDF,W     ;get it,
>         addwf T3,F      ;and add to middle byte result
>         ifcs            ;If carry,
>           incf T4,F     ; inc high byte result
>

However, since you're doing something like:
       sum = sum + sample[i]

where sum is 24 bits, and sample[i] is 16 bits, it might be better to do
this:

       movf    INDF,W     ;Get low byte,
       incf    FSR,F

       addwf   T2,F
       movf    INDF,W

       skpnc
        incfsz INDF,W
         addwf T3,F

       skpnc
        incf   T4,F

       incf    FSR,F      ;Point to next variable low byte
       ...

This way you only have to deal with the carry once. (I think this is
right, but it's not tested.)
Should I add comments?


{Quote hidden}

for the shift right 3, you might want to just unroll the loop:

   rrf   T4,F
   rrf   T3,F
   rrf   T2,F

   rrf   T4,W
   andlw 00011111b
   movwf T4
   rrf   T3,F
   rrf   T2,F

   rrf   T4,F
   rrf   T3,F
   rrf   T2,F

It's 3 instructions longer, but twice as fast (11 cycles vs 23 cycles)

Scott

1998\11\09@195312 by Mike Keitz

picon face
On Mon, 9 Nov 1998 23:21:03 +0100 Morgan Olsson <.....mrtKILLspamspam@spam@INAME.COM> writes:

>The i noticed that the output after the average routine "flickers" for
>certaion input values!
[...]

>Sum16loop:
>        movf INDF,W     ;Get low byte,
>        addwf T2,F      ;and add to low byte result
>        ifcs            ;If carry,
>          incf T3,F     ; inc middle byte result
>        ifzs            ;If wrapped to Zero,
>          incf T4,F     ; inc high byte result

This part is just plain wrong.  I think the author intended to skip the
last increment if the middle byte was *not* zero after incrementing.  But
even fixing this won't work because the zero flag may have come from the
original add, or it may have come from the increment.

Do something like this:
       addwf   T2,f
       skpc            ;If carry, need to increment higher bytes
       goto    addok
       incf    T3,f
       skpnz
       incf    T4,f
addok

If you need constant execution time, or no GOTO:

       addwf   T2,f
       skpnz           ;Compensate for possible bad inc later?
       decf    T4,f    ;If C=0 and Z=1 (low bytes 0+0), need
this.
       skpnc           ;No carry - don't inc. high bytes.
       incf    T3,f
       skpnz           ;T3 not 0?
       incf    T4,f



___________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]

1998\11\10@064400 by Stefan Sczekalla-Waldschmidt

flavicon
face
Scott Dattalo wrote:
>
> where sum is 24 bits, and sample[i] is 16 bits, it might be better to do
> this:
>
>         movf    INDF,W     ;Get low byte,
>         incf    FSR,F
>
>         addwf   T2,F
>         movf    INDF,W
>
>         skpnc
>          incfsz INDF,W
>           addwf T3,F
>
>         skpnc
>          incf   T4,F
>
>         incf    FSR,F      ;Point to next variable low byte
>         ...

My Idea for the lines above:

       addwf   T2, F   ; add actual low byte to Temp T2 ( sdtter Z och
C )
       ifcc            ; om ej Carry
       goto    $+4     ; goto handling the high byte

       incf    T3, F   ; se vka mellanbyte ut
       ifzs            ; if result is ZERO, ( caution, incf sets Z, not
C !!)
       incf    T4,F


and back to bussines as usal ...

I put some coments at certain lines but I4m not sure about the
possibility
I4m wrong ...

{Quote hidden}

you meant

{Quote hidden}

dont you ?

Kind regards

       Stefan Sczekalla-Waldschmidt
       sswspamKILLspamoikossw.de

1998\11\10@071741 by Morgan Olsson

picon face
>Suppose the addwf T2,F sets C and Z. Then, T4 will be incremented and
>the shift right 3 done below will cause the upper nibble of T3 to
>'flicker'.

Right on target, i realized it when i woke up this morning, thanks.

>It might be better to do something like this:
>
>        movf    INDF,W
>        addwf   T2,F
>        rlf     known_zero,W
>        addwf   T3,F
>        rlf     known_zero,W
>        addwf   T4,F

Seen before, but now i understand too...
That is a smart way to get the carry bit alone in a byte and add to the
higher byte and get both flags always correct. :)  
Just need a register that is guaranteed zero.

Learned, must practise.
..will probably work for subtraction too.


{Quote hidden}

Should work. I learned that movf-skpnc-incfsz-addwf -trick last week, so i
have not updated this routine yet.

>Should I add comments?

If anyone is interested, I posted "Re: 32 Bit Addition (commented)" three
days ago, and then Dimitry replied to that.

{Quote hidden}

I think the andlw trick is a nice way to not need to use clear carry before
each shift sequence. :)
Thinking about it i do not need to clear incoming carry to T4 at all
anyway, since it is trasched, and the whole result is only in T3:T2

It then becomes a childs play:

   rrf   T4,F
   rrf   T3,F
   rrf   T2,F

   rrf   T4,F
   rrf   T3,F
   rrf   T2,F

   rrf   T4,F
   rrf   T3,F
   rrf   T2,F

...almost ridiculous. 9 instr, 9 cyc.

And i think i will unroll the add to straight inline using the
known-zero-trick.  I still have lot of code space and this filter is one of
the most often run routines.

And if time I'll see what i can do to boost the
findinjectposition-shift-inject in MOMA.  Any ideas?


>Scott

Thanks, Scott

Thank you also, Mike, for your corrections

Stefan, have you got the filter working now?

/Morgan
       Morgan Olsson                   ph  +46(0)414 70741
       MORGANS REGLERTEKNIK            fax +46(0)414 70331
       H€LLEKS           (in A-Z letters: "HALLEKAS")
       SE-277 35 KIVIK, SWEDEN               .....mrtKILLspamspam.....iname.com
___________________________________________________________

More... (looser matching)
- Last day of these posts
- In 1998 , 1999 only
- Today
- New search...