2020/11/16 06:08:51
dsprogrammer
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.
 
2020/11/16 18:26:42
Aussie Susan
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
2020/11/17 14:58:18
dsprogrammer
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
 
2020/11/18 06:08:13
Gort2015
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
                
2020/11/19 13:03:59
dsprogrammer
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
2020/11/20 17:27:19
Gort2015
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

 
 
 
2020/11/20 20:50:18
1and0
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.
 
2020/11/21 09:08:06
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.
 
GC Options: -std=gnu99
2020/11/21 11:34:08
1and0
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?
 
2020/11/21 14:25:41
Gort2015
Off by default.
12
© 2021 APG vNext Commercial Version 4.5

Use My Existing Forum Account