• AVR Freaks

Hot!Fixed Point Q1.15 in XC16

Author
dsprogrammer
New Member
  • Total Posts : 3
  • Reward points : 0
  • Joined: 2020/09/28 07:53:59
  • Location: 0
  • Status: offline
2020/11/16 06:08:51 (permalink)
0

Fixed Point Q1.15 in XC16

The device is dsPic30F4011. The compiler is XC16 v1.50.
I am writing a c main file with an assembly file. I want to use Q1.15 fixed point for mac operation
I have specified the variables as fixed point with the declaration signed _Fract
I have added -menable-fixed to the project properties
I have set CORCON = 0x00F0
I have included <libq.h>
I am getting the following error messages when I build if any negative values are given to a variable as follows :
tmp/cc4nAJuB.0000139b.s: Assembler messages:
/tmp/cc4nAJuB.0000139b.s:53: Warning: bignum truncated to 2 bytes
It still compiles if negative numbers are passed, with the above error messages, but does not work.
It seems to be that the signed fract format Q1.15 is not set up correctly. What am I missing or doing wrong ?
thanks.
 
post edited by dsprogrammer - 2020/11/16 13:17:52
#1

10 Replies Related Threads

    Aussie Susan
    Super Member
    • Total Posts : 3788
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/16 18:26:42 (permalink)
    +3 (3)
    I can't answer your questions a couple of comments:
    - what you have is a 'warning' and not an 'error' . That is why the 'compile' (assemble) completes
    - '...does not work' is not a very useful problem description
    - try showing us the code and describing what you expect to happen and that actually does happen, and how you have determined that
    Susan
    #2
    dsprogrammer
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2020/09/28 07:53:59
    • Location: 0
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/17 14:58:18 (permalink)
    0
    Hi Susan,
    The program is part of a controller for a motor. I have tested it for passing variables, for x and y space being read correctly, and for motor control using  addition equations and only positive variables to give a fixed output value. It works fine in all these tests, i.e. the motor spins, at a speed that would be expected from the predicted output value . The problem is that the program I have requires the use of negative variables, but when I input negative variables,in addition to the compiler warning messages, the motor jumps to a high speed then ramps down over 1  to 2 seconds and repeats the cycle. What I expect to happen is for the motor to start smoothly from rest to a desired speed.
    here is the part of it in c code
     
    // Declare variables and function //
    signed _Fract Gx, Refl; // Variables Gx and Refl
    signed _Fract Zout = 0; // return variable Zout
    signed _Fract __attribute__((space(xmemory), __aligned__(4))) Rijn[3]= {0.111,-0.12,0.001};
    signed _Fract __attribute__((space(ymemory),far,__aligned__(4))) Vs[3];
    extern void ZIJ(void);
     
    here is the assembly code
     
    ;
    ; file: ZIJ.s
    ;
    .text
    .global _ZIJ
    _ZIJ:
    CORCON = 0x00F ; Signed, saturation, fractional computing
    SRbits.OV = 1 ; Overflow for signed arithmetic
    mov #_Rijn, W8; ; W8 pointer
    mov #_Vs, W10; ; W10 pointer
    mov _Gx, W2; ; Move Gx to W2
    mov _Refl, W3; ; Move Refl to W3
    sub W3, W2, [W10]; ; Calculate V = W3 - W2
    movsac A,[W8]+=2,W4,[W10]+=2,W5; ; Move Rijn1
    mac W4*W5,B,[W8]+=2,W4,[W10]+=2,W5; ;Mult W4xW5 store and prefetch
    mac W4*W5,B,[W8]+=2,W4,[W10]+=2,W5;; Mult W4xW5 store and prefetch
    mac W4*W5,B,[W8],W4,[W10]-=2,W5; ; Mult W4xW5, store and point
    sac.r B, #-8, W0; ; Shift acc B 8 bits to left and store in W0
    mov W5, [W10]; ; Copy the content of W5 into W10
    mov [W10 + -#4], W5; ; Copy content of W10-4 to W5
    mov W5, [--W10]; ; Copy W5 to locn pointed to by W10
    mov W0, _Zout; ; Copy W0 to Zout
    return
    .end
     
    thanks,
    dsprogrammer
     
    #3
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 4014
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/18 06:08:13 (permalink)
    0 (2)
    This function is called from C, Registers W8 - W15 must be preserved.
     
    CORCON = 0x00F
     
    Only set the bits that need to be set in CORCON.
    If there was a DO Loop in progress say from C, it could early terminate if that bit was set.
     
    Suggest to make it readable, use tab and useful names instead of registers.
    Other readers won't understand it.  Put time into making code look tidy and separate
    operations by lines.
     
    .include "xc.inc"
     
        bclr     CORCON, #SATA
        bclr     CORCON, #SATB
        bset    CORCON, #ACCSAT
     
    typo:
    mov [W10 + -#4], W5; ; Copy content of W10-4 to W5
     
    Too many semicolons.
     
    As for truncated to 16bit, probably this:
    mov #_Rijn, W8; ; W8 pointer
    mov #_Vs, W10; ; W10 pointer
     
    24bit address, Page needs to be saved, set and restored.
     
        push     TBLPAG
        mov      arg_AddrH, TBLPAG
        tblrdh    [arg_AddrL], x
        pop       TBLPAG
                    
    post edited by Gort2015 - 2020/11/18 06:14:08

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #4
    dsprogrammer
    New Member
    • Total Posts : 3
    • Reward points : 0
    • Joined: 2020/09/28 07:53:59
    • Location: 0
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/19 13:03:59 (permalink)
    0
    Hi Gort,
    Thanks for your suggestions, unfortunately it has not moved the needle. I have edited the code so that it is not a distraction. This new code generates the same warning when a negative number is given to a variable. The question I have is how can I pass a negative number to the signed _Fract variables without getting the warning message from the compiler.
     
    c code
    #include <xc.h>
    #include <stdio.h>
    #include <libpic30.h>
    #include <p30F4011.h>
    #include <libq.h>
        signed _Fract A = 0.2;
        signed _Fract B = -0.1;
        signed _Fract C;
        extern void ABC(void);
     
    assembly code
     
    ;
    ; file: ABC.s
    ;
    .include "xc.inc"
    bclr     CORCON, #SATA
    bclr     CORCON, #SATB
    bset     CORCON, #ACCSAT
    .text
    .global _ABC
    _ABC:
    mov _A, W2           ; Move A to W2
          mov _B, W3           ; Move B to W3
          add W3, W2, W4   ; Calculate C = W3 + W2
          mov W4 , W0        ; Move W4 to W0
          mov W0, _C          ; Move W0 to C
    return
    .end
     
     
    I'm not familiar with pop push so I wasn't able to incorporate it without generating more warnings, but I will look into how to use it further.
    thanks
    post edited by dsprogrammer - 2020/11/20 06:03:42
    #5
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 4014
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/20 17:27:19 (permalink)
    0
    Interacting with C, W8 - W15 must always be preserved:
        push.d  w8
        push.d w10
        ..
        pop.d  w10
        pop.d  w8

     
    The Q1.5 number is a signed integer, it has to be converted.
     
    signed _Fract A = 0.2;                      // won't work, integer type.
    signed FractA    = (1 << 15) * 0.2;   // Q1.5 signed integer.   6,553
     
    Bit15 is the sign bit.
     
    The Q Numbers are fractions of 1.
    If using Q1.5 then to represent 0.5 then:
     
    q15_1 = (1 << 15) * 0.5
    $4000
    16,384
    100 0000 0000 0000
     
    16,384 * (1 / 0.5) = ‭‭32,768
    -----------------------------
    And 0.2:
     
    q15_2 = (1 << 15 ) * 0.2
    $1999
    ‭6,553
    00‭1 1001 1001 10001
     
    6,553 * (1 / 0.2) = ‭‭32,765‬
     
    They are approximations.
     
    To get a fraction in asm, use the divf instruction.
     
    divident = w2
    quote    = w2
    rem      = w3
    divisor  = w4
     
        ; 1 / 2
        mov     #1, divident
        mov     #2, divisor
        repeat  #6 - 1
        divf2   divident, divisor
        mov     quote, w0
        return

     
     
     
    post edited by Gort2015 - 2020/11/20 17:30:29

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #6
    1and0
    Access is Denied
    • Total Posts : 11505
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/20 20:50:18 (permalink)
    +1 (1)
    Gort2015
    The Q1.5 number is a signed integer, it has to be converted.
     
    signed _Fract A = 0.2;                      // won't work, integer type.

    It will work -- the compiler will take care of the conversion. ;)  That is, A = 6553.
     
    #7
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 4014
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/21 09:08:06 (permalink)
    -1 (1)
    I tried that and got zero, the new integer got the integer part of the fraction. 0.2 that you would expect.
     
    "_Fract" gets an error, looks like a C extention.
     
    GC Options: -std=gnu99

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #8
    1and0
    Access is Denied
    • Total Posts : 11505
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/21 11:34:08 (permalink)
    0
    Gort2015
    I tried that and got zero, the new integer got the integer part of the fraction. 0.2 that you would expect.
     
    "_Fract" gets an error, looks like a C extention.

    Did you add -menable-fixed option to the project properties to enable fixed-point types as OP has done?
     
    #9
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 4014
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/21 14:25:41 (permalink)
    +1 (1)
    Off by default.

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #10
    1and0
    Access is Denied
    • Total Posts : 11505
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Fixed Point Q1.15 in XC16 2020/11/21 21:46:33 (permalink)
    +1 (1)
    Gort2015
    Off by default.

    Yeah, I don't understand why one has to enable it to use the fixed-point types. Why can't it be on all the time?!
    #11
    Jump to:
    © 2020 APG vNext Commercial Version 4.5