This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28335: Floating Point Representation

Part Number: TMS320F28335
Other Parts Discussed in Thread: C2000WARE

Hi

I'm implementing a first order low pass filter (fcut = ~0,1Hz / fsample = 30Khz):

-> G(z) = (1.046(...)e-05 z + 1.046(...)e-05) / (z-0.999(...))

-> The coefficients are declared as: 

const float cfmed[4] = {1.04606151580810546875e-5,1.04606151580810546875e-5,1.0,-0.999979078769683837890625};

-> The 30 kHz loop is:

Out_k_1 = Out;
Out = In* cfmed[0] + In_k_1 * cfmed[1] - Out_k_1 * cfmed[3];
In_k_1 = In;

-> The input (In) and output (Out) are declared as float.

The problem is that i'm having unnaceptable static gain error.

For example, if I test the filter with constant input such as: 300.0; 300.5 and 299.2

I get: 299.760712, 299.760712 and 298.302002, respectively.

If i change all the variables and filter coeffs to "long double" I get better results.

But I also get problems with memory and timing (In fact, the complete application has a looot of filters and other things). So i need to work with float.

What intrigues me is that if I pause the execution and inspect cfmed[4], the coefficients "1.04606151580810546875e-5"are encoded as "00000000000000000000000000000000b" / (0x00000000)   and the coefficient "0.999979078769683837890625" is encoded as "00100000000000000000000000000000b"  (0x20000000).

I think that is is not in accordance with IEEE-754. Those numbers should be encoded as "00110111001011111000000000000000b" (0x372f8000) and "10111111011111111111111010100001b" (0xbf7ffea1). 

I think that its the root of my static gain error.

So, I tried to replace the declaration:  const float cfmed[4] = {1.04606151580810546875e-5,1.04606151580810546875e-5,1.0,-0.999979078769683837890625};

For: const float cfmed[4] = {0x372f8000,0x372f8000, 0x3f800000, 0xbf7ffea1};

Now, the filter is giving me only +/- INF output values!

What I'm doing wrong? Why it seems that the compiler is not enconding the floating point values as IEEE-754? 

I'm using F28335, CCS V 8.3.1.00004  and Compiler  V18.1.4.

  • Hello Henrique,

    Are you utilizing any library in C2000Ware as part of your filtering? If you step through your code, can you see which line first gives you an incorrect value? Are any of the values you use initially not stored in memory as expected? In your project properties, is the --fpu_support compiler option set to fpu32?

    Best regards,

    Omer Amir

  • Hello.

    -> "Are you utilizing any library in C2000Ware as part of your filtering?"

    I'm using: "math.h" (Original from TI & Sun 2015), "DSP2833x_Device.h", "DSP2833x_Examples.h", "DSP2833x_Headers_nonBIOS.cmd", "28335_RAM_lnk.cmd"  and "DSP2833x_CodeStartBranch.asm".

    -> "If you step through your code, can you see which line first gives you an incorrect value? Are any of the values you use initially not stored in memory as expected?"

    The error is kind of cumulative.  It seems that there is a small error at every operation. I know that float representation has finite resolution and its ok to have some error.  But things are not as I expected. I'dont need much precision in the cut off frequency and phase angle, but I need a static gain very close to 1.0. To do so, I fine-tuned the filter coefficients (float) so that per IEEE-754 they were perfectly represented in memory.

    For example, the coefficient 0.999979078769683837890625 is been stored as "00100000000000000000000000000000b"  (0x20000000)
    But I think that the correct value for that number should be "10111111011111111111111010100001b" (0xbf7ffea1) per IEEE-754.

    Also, I dont know why I couldnt correctly declare those coeffs as hexadecimal numbers, as: const float cfmed[4] = {0x372f8000,0x372f8000, 0x3f800000, 0xbf7ffea1};

    -> "In your project properties, is the --fpu_support compiler option set to fpu32?"

    Yes, It is

    Thanks 

    
    

  • Hello Henrique,

    Can you show me how you're declaring these floating point values? Are you using the float32_t datatype?

    Also, I dont know why I couldnt correctly declare those coeffs as hexadecimal numbers, as: const float cfmed[4] = {0x372f8000,0x372f8000, 0x3f800000, 0xbf7ffea1};

    Can you show me how these are stored in memory if they're not showing up correctly?

    Also just to let you know, there are FIR/IIR filter libraries available in C2000Ware you can use if you want.

    Best regards,

    Omer Amir