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.

Unit8 and Uint16 not playing nice

I was looking at the following code while using a F28069. I said to myself, how could this work. The values for sdata[1] and sdata[2] would be 0!

myWrite(0x1234, 0, 0);

void myWrite( Uint16 u16Address, Uint8 u8DataLength, Uint8* pDataBuffer)
{

   Uint8 sdata[3];
   Uint8 temp;

   sdata[0] = (WRITE_OPCODE << 8);
   sdata[1] = (u16Address & 0xFF00);
   sdata[2] = (u16Address << 8) & 0xFF00;

But to my surprise, in this example, sdata[1] was 0x1200 and sdata[2] was 0x3400. I was expecting that assigning a 16 bit to an 8 bit would cause the value to be truncated. But it wasn't. I did some digging and discovered that the processor was word addressable. OK. Got it. But when I tried to cast it to a Uint8, it still acted like 16 bit.

sdata[1] = (Uint8)0x1234;
temp = (Uint8)sdata[1];


 if(temp == 0x12)
    sdata[0] = 0;
 else if(temp == 0x34)
    sdata[0] = 1;
 else if(temp == 0x1234)
    sdata[0] = 3;
 else
    sdata[0] = 10;

Here, the else for 0x1234 evaluated to true. So the caste did nothing. Same when passing a 8 bit value as a parameter to a function. Got all 16 bits.

 So what's the rule when using 16 bit and 8 bit values?

  • Hi Charles,

    I believe there are no true 8-bit values, Uint8 is merely a typedef of unsigned int, exactly like Uint16 (and char is 16 bits aswell).

    If you want the value to be truncated to 8 bits there are two ways:

    1. Use a structure with an 8-bit bitfield e.g struct 
    2. Use the __byte() intrinsic to have the compiler generate MOVB instructions (but beware when using pointers, it can get tricky when using optimization because of pointer aliasing). See the compiler user guide (Literature Number: SPRU514H).

    Regards,

    Pierre

  • Hi I just noticed I forgot the end of my first proposed solution. I meant something along the lines of:

    typedef union {
    	Uint16 all;
    	struct {
    		Uint16 low: 8;
    		Uint16 high: 8;
    	} byte;
    } buffer_t;
    
    ...
    
    buffer_t Buffer;
    
    Buffer.byte.low = 0x1234; // truncated to 34
    Buffer.byte.high = 0x5678 // truncated to 78
    
    /* At this point accessing Buffer.all will read 0x7834 */

    Regards,

    Pierre