Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

question about using memcpy function to load data into CE0

Hello:

 

    I adopted technican Sivaraj K's suggestion that I need to utilize memcpy function to load a frame of data from the wav file to the CE0 external ram.

    But I have tried and this method seem did not work at all.  Here are the snapshot of my code:

 

  

I want to load a wav file containing a sequence of data 0.1 into the CE0 of my C6713 DSK.  I want to store from the 0x80000000

 

But when I checked the memory, it seemed that I failed to load in my data properly.

 

 

I defined a pointer variable used in memcpy.

 

 

In my ISR, I used memcpy to load data one by one from the McBSP to the temp and finally to where pointer was pointing to (it points to consecutive address of the CE0).

 

 

Could you please tell me whether there were some invisible problems or are there any alternative approach to import this stream of data into the external memory of my C6713 DSK?  Is memcpy the only feasible approach?

 

Are there any method without utilizing McBSP and interrupt service, such as I past the data from my Matlab and copy into the external memory (I have never heard of this method)?

 

Thank you very much!

 

Yu
 


  • A couple things:

    1.  You'll want to make sure that the sender of the data is sending it formatted in a way that your program knows how to understand.  It looks like your sender is sending one value at a time, as a four byte value.  Are these four bytes an IEEE-754 single precision floating value*?  Is the endianess (byte order) correct?

    2.  You are doing an assignment to your floating array

    buffer[0] = temp;

    Here temp is a Uint32.  Assuming you have issue number 1 correct, then Uint32 is just a holder for four bytes that are really expressing an IEEE-754 single precision float.  By doing the assignment directly, you are saying, takes those four bytes, treat them as an unsigned integer, and set the float to that value (or at least as close as we can given the constraints of an IEEE-754 single precision float).  For example, if you are working with 0.1, then those four bytes might be 0x3dcccccd.  That is the unsigned int 1036831949.  When you assign that to a float, you'll get a float value of approximately 1036831949, not 0.1.

    What you'll want to do treat those four bytes as a float:

    buffer[0] = *reinterpret_cast<float *>(&temp);

    3.  Additionally you'll want to make sure you don't have anything else in your program that might be using 0x80000000.  You can check your linker command file if you are unsure.

    * Assuming your architecture is using IEEE-754, which it probably is.  You can use <limits>'s std::numeric_limits<float>::is_iec559() to verify this.

  • Hello:

     

    thank you for your guidance.

     

    I am not very clear about some of your suggestions:

     

     

    first, do you think I need to modify the endianness?

     

    I checked my C6713 dsk and it literally supports both single and double prcecision floating point values of IEEE754.

     

     

    But what's really beyond my comprehension is that why the "0.1" in matlab will become 1036831949, the startlingly large number?

     

    Another thing is that I typed in buffer[0]=*reinterpret_cast<float *>(&temp) in my CCS and it showed "syntax error".

     

    In summation, I need to do both format-casting and the endianness modifications? Is that right?

     

    Thank you

     

  • Hi,
     
    Thanks for your update.

    Yes, you need to do appropriate format casting and endianness modification.

    In general, the packed-data processing extensions that the C64x provides will operate in either big- or little-endian mode, and will perform identically on values stored in the register file. However, accesses to memory behave differently in big-endian mode.

    In type casting method, you can cast a pointer of a narrow type to a pointer of a wider datatype. For more understanding on this, please refer examples 2-9, 2-10, 2-11 from the C6000 programmer's guide as below:

    http://www.ti.com/lit/ug/spru198k/spru198k.pdf
     
    Thanks & regards,
    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question

    -------------------------------------------------------------------------------------------------------

  • Yu Zhang39 said:

    first, do you think I need to modify the endianness?

    I would suggest not changing the endianness of the program for now.

    What we need to know is what format the sender (Matlab) is sending the data in.  I am not familiar enough with Matlab to know this.  If Matlab sends in little endian, then the byte order should be correct already.  If Matlab sends in big endian, then your program will need to swap the bytes read before it interprets them:

        temp = (temp & 0x000000ff<<24) | (temp & 0x0000ff00<<8) | (temp & 0x00ff0000>>8) | (temp & 0xff000000>>24);

     

    Yu Zhang39 said:

    But what's really beyond my comprehension is that why the "0.1" in matlab will become 1036831949, the startlingly large number?

    It is an issue of interpreting the bits sent over the wire.  Computer data is just 1s and 0s, but how those bits are interpreted gives them different values.  We have a similar problem in written language.  Say I see the letters 't' 'o' 'd' 'o'.  In English, this is the phrase "todo", which is some thing that should be accomplished.  In Spanish, this is the word "todo", which translates to English as "all".

    As you read data off the serial, it looks like your read function returns four bytes at a time.  Say those four bytes are 0x3dcccccd.

    If I treat those as the four bytes as a unsigned integer, we get (hexidecimal -> decimal) 1,036,831,949.

    If I treat those four bytes as a float (per the float specification that described which bits are sign, mantissa, exponent) 0.1.

    To see this in action you can play around with code:

    #include <stdio.h>
    
    int main(void)
    {
        unsigned int temp;
        float buffer[1] = {0.0};
        
        temp = 0x3dcccccd;
        
        printf("The bytes as an unsigned int: %d\n", temp);
        
        buffer[0] = temp;
        printf("The bytes as an unsigned int, then copied into a float %f\n", buffer[0]);
        
        buffer[0] = *((float *) &temp);
        printf("The bytes as a float %f\n", buffer[0]);
        
        return 0;
    }
    

     

    Yu Zhang39 said:

    Another thing is that I typed in buffer[0]=*reinterpret_cast<float *>(&temp) in my CCS and it showed "syntax error".

    reinterpret_cast is C++ code.  Perhaps you are using C.  If so, then the corresponding code would be:

    buffer[0] = *((float *) &temp);

     

    Yu Zhang39 said:

    In summation, I need to do both format-casting and the endianness modifications? Is that right?

    You definitely need format-casting.  You may or may not need endianness modification.