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.

double var y=double var x missing high word

I have written some code which is not behaving as expected.

    double y,ymag,yval;
    y=2.0/(double) fftpoints;
    ymag=0.0;
    for(x=0; x <= fftpoints; x++){    //mag=sqrt(Real^2+Imag^2)*(2/fftpoints)
        yval= sqrtdp(powdp(fftbuf[x*2],2)+powdp(fftbuf[x*2+1],2))*y;
        bin[x]=yval;
        if (yval > ymag){
            ymag=yval;}
    }

This routine is calculating magnitudes as the post processing for my FFT and trying to extract the bin with the largest magnitude.  The bold statement is not processing as I would expect.  When emulating, I see that the yval variable contains the proper 64bit word (number), but after the assignment to ymag, ymag only has the lower word, and the upper word is all 0s.  Is this not the proper method to do this type of double to double assignment?  Is there an alternate method or trick to making this work?

  • Dan,

    I think you've run into a CCS bug.  It affects both the watch window and the register window.  It's fixed in CCS 4.0 (or so I'm told) and I see is planned to be fixed in CCS 3.3 SR13.

    If you want to look at the register view you can open the older register window which did not contain this bug by invoking GEL_OpenLegacyRegisterWindow(“Core Registers”) from the GEL toolbar (View -> GEL toolbar, I think).

    Brad

  • Dan,

    Actually, I went back and looked further at the CCS bug and it mainly impacts the register window.  I did a quick test with a watch window in both CCS 3.3 and CCS 4.0 and variables appear ok.

    Nothing jumps out at me from your code.  Perhaps you should right-click on your source window and select "mixed mode" and post the corresponding assembly.

    FYI, you can significantly optimize your code by removing the square root.  Looking for the bin with largest squared magnitude will yield the same result as looking for the bin with the largest magnitude.

    Brad

  • Sorry, this reply goes a little bit off topic, but...

    The problem is occurring in the watch window as I look at the specific variable ymag. 

    The program however is operating correctly beyond this problem.  What prompted the question is that my display showed a number from a different bin than expected, so I started to debug and found the issue.  However, when looking through the memory I found that the highest magnitude was actually in a different bin, I think in the negative frequency realm.

    The post processing shown involves the scaling of the complex output:  mag=sqrt(Real^2+Imag^2)*(2/fftpoints) as well as finding the largest magnitude.  Later, down the road, I will be looking at a specific bin of interest.  Do you feel I can remove the sqrt() and process a different way, would it be better to use powdp(x,0.5) in place of the sqrt()?.

    This does lead me to another question.  I had imported 16 consecutive raw data streams from the ADC and imported them into Excel, processed them with the Excel FFT and found that the magnitude at the frequency bin of interest varied only about 10 counts out of about 29000.  I mentioned that I started using the Single Percision FFT and found variance of about 100+ counts in 29000, so I converted the program to Double Percision, but find that the extended percision did not improve the accuracy, I am still getting that 100+ variance between points.  Any ideas why Excel is giving me better results than the TI FFT routines?

  • dan kantorski said:

    However, when looking through the memory I found that the highest magnitude was actually in a different bin, I think in the negative frequency realm.

    Do you not have even symmetry of your FFT magnitude?  It should be if you had a real-valued input!!!!  (Is it just a rounding error where they are just barely different?)

    dan kantorski said:

    The post processing shown involves the scaling of the complex output:  mag=sqrt(Real^2+Imag^2)*(2/fftpoints) as well as finding the largest magnitude.  Later, down the road, I will be looking at a specific bin of interest.  Do you feel I can remove the sqrt() and process a different way, would it be better to use powdp(x,0.5) in place of the sqrt()?.

    No, that's not what I was suggesting.  I was questioning the use of a square root at all.  If you're looking for a maximum you will arrive at the same conclusion whether you perform a square root on everything or not.  Maybe later if there's a specific bin of interest you could do it a square root if it's really necessary.  Normally it's not though.  For example, if you wanted to look for magnitude greater than some threshold, THRESH, then you would not want to take the square root of every sample and compare to THRESH.  A much better way would be to square THRESH and compare it to the magnitude squared (no square root).

    dan kantorski said:

    This does lead me to another question.  I had imported 16 consecutive raw data streams from the ADC and imported them into Excel, processed them with the Excel FFT and found that the magnitude at the frequency bin of interest varied only about 10 counts out of about 29000.  I mentioned that I started using the Single Percision FFT and found variance of about 100+ counts in 29000, so I converted the program to Double Percision, but find that the extended percision did not improve the accuracy, I am still getting that 100+ variance between points.  Any ideas why Excel is giving me better results than the TI FFT routines?

    Don't know -- are you sure you're getting correct results?  I recommend stepping back and trying something like a ramp sequence or some other known input to see how much variation you have in the numbers from Excel and from the DSP.  You might also compare the DSP's C model with the output you get from the library.