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.

LAUNCHXL-F280025C: UNION : unint8_t or unsigned char with 16 bit

Part Number: LAUNCHXL-F280025C
Other Parts Discussed in Thread: C2000WARE

Hi,

after researching T.I. forum I understand uint8_t or char is 16 bits not 8 bits, therefore below union does not work as expected.  

typedef union {
   uint32_t longValue;
   uint8_t charValue[4];
} unLong;

unLong   unLongTemp ;

if ...

unLongTemp.charValue[0] = 135
unLongTemp.charValue[0] = 214
unLongTemp.charValue[0] = 18
unLongTemp.charValue[0] = 0

the unLongTemp.longvalue = 14024839 not expected 1234567 because each charValue is 16 bit wide

  

now I use below codes instead...

uint8_t   i;
uint32_t  longValue[4];

for (i=0; i<=charGetIndex; i++)
{
   longValue[i] = charBuffer[charGetIndex];

   longValue[i] = charBuffer[charGetIndex + i];
   longValue[i] = charBuffer[charGetIndex + i];
   longValue[i] = charBuffer[charGetIndex + i];
}
return ((longValue[0]<<24&0xFF000000) | (longValue[1]<<16&0x00FF0000) | (longValue[2]<<8&0x0000FF00) | (longValue[3]&0x000000FF))&0xFFFFFFFF;


My question is, how can I use UNION with char / uint8_t is actually 16 bits wide ? 

Thanks,

Danny

  • Hi Danny,

    If you have installed C2000Ware SDK, please take a look at this header file.

    C:/ti/c2000/C2000Ware_4_02_00_00/device_support/f28002x/headers/include/f28002x_sysctrl.h

    This file defines the unions and structures for system control.

    Hope it helps.

    Regards, Santosh 

  • Hi Santosh,

    thanks for your information, its worked, can you help if I want to use array inside structure

    below codes OK

    struct CHAR_IN_LONG {
    uint16_t charValue1:8;
    uint16_t charValue2:8;
    uint16_t charValue3:8;
    uint16_t charValue4:8;
    };

    typedef union UNLONG {
       uint32_t all;
       struct CHAR_IN_LONG bit;
    } UNLong;


    UNLong unLongTemp;

    unLongTemp.bit.charValue1 = a_buffer[0]&0xFF;
    unLongTemp.bit.charValue2 = a_buffer[1]&0xFF;
    unLongTemp.bit.charValue3 = a_buffer[2]&0xFF;
    unLongTemp.bit.charValue4 = a_buffer[3]&0xFF;

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

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

    below codes NOT OK

    struct CHAR_IN_LONG {
       uint16_t charValue[4]:8;
    };

    typedef union UNLONG {
       uint32_t all;
       struct CHAR_IN_LONG bit;
    } UNLong;


    UNLong unLongTemp;

    unLongTemp.bit.charValue[0] = a_buffer[0]&0xFF;
    unLongTemp.bit.charValue[1] = a_buffer[1]&0xFF;
    unLongTemp.bit.charValue[2] = a_buffer[2]&0xFF;
    unLongTemp.bit.charValue[3] = a_buffer[3]&0xFF;

    regards,

    Danny

  • Danny,

    What is the symptom in No-Good condition?

    Regards, Santosh

  • What is the symptom in No-Good condition?

    when declare array inside struct with bit field, I have got error

    error #xxx: invalid type for a bit field

    struct CHAR_IN_LONG {
       uint16_t charValue[4]:8;  // this got error ....
    };

    typedef union UNLONG {
       uint32_t all;
       struct CHAR_IN_LONG bit;
    } UNLong;


    UNLong unLongTemp;

    unLongTemp.bit.charValue[0] = a_buffer[0]&0xFF;
    unLongTemp.bit.charValue[1] = a_buffer[1]&0xFF;
    unLongTemp.bit.charValue[2] = a_buffer[2]&0xFF;
    unLongTemp.bit.charValue[3] = a_buffer[3]&0xFF;

  • Danny,

    Requesting compiler expert to take a look at this. We should hear sometime later day/tomorrow.

    Regards, Santosh

  • I think this example is very close to what you need to write.

    #include <stdint.h>
    
    typedef union UNLong_tag {
        uint32_t all;
        struct inner_union_tag  {
            uint16_t val : 8;
        } charArray[4];
    } UNLong;
    
    int a_buffer[4];
    UNLong unLongTemp;
    
    void fxn()
    {
        unLongTemp.charArray[0].val = a_buffer[0]&0xFF;
        unLongTemp.charArray[1].val = a_buffer[1]&0xFF;
        unLongTemp.charArray[2].val = a_buffer[2]&0xFF;
        unLongTemp.charArray[3].val = a_buffer[3]&0xFF;
    }

    Thanks and regards,

    -George

  • Hi George,

    if assign 0x0111 111 (127 decimal) to each val array member, the uint32 all is :

    8323199 not excepted 2139062143

    typedef union UNLong_tag {
      uint32_t all;
        struct inner_union_tag {
        uint16_t val : 8;
      } charArray[4];
    } UNLong;

    int a_buffer[4];
    UNLong unLongTemp;

    void fxn()
    {
      a_buffer[0] = 127;
      a_buffer[1] = 127;
      a_buffer[2] = 127;
      a_buffer[3] = 127;

      unLongTemp.charArray[0].val = a_buffer[0]&0xFF;
      unLongTemp.charArray[1].val = a_buffer[1]&0xFF;
      unLongTemp.charArray[2].val = a_buffer[2]&0xFF;
      unLongTemp.charArray[3].val = a_buffer[3]&0xFF;
    }

    if assign 0xFF (255 decimal) to charArray, the uint32 all is : 

    16711935 not expected 4294967295

    void fxn()
    {
      a_buffer[0] = 255;
      a_buffer[1] = 255;
      a_buffer[2] = 255;
      a_buffer[3] = 255;

      unLongTemp.charArray[0].val = a_buffer[0]&0xFF;
      unLongTemp.charArray[1].val = a_buffer[1]&0xFF;
      unLongTemp.charArray[2].val = a_buffer[2]&0xFF;
      unLongTemp.charArray[3].val = a_buffer[3]&0xFF;
    }

    Thanks

    Danny

  • My previous post is in error.  I apologize.

    can you help if I want to use array inside structure

    It is not possible to have an array of anything that is smaller than 16-bits.  Thus, the best you can do is something similar to ...

    #include <stdint.h>
    
    typedef union UNLong_tag {
        uint32_t all;
        struct inner_union_tag  {
            uint16_t hi : 8;
            uint16_t lo : 8;
        } charArray[2];
    } UNLong;
    
    int a_buffer[4];
    UNLong unLongTemp;
    
    void fxn()
    {
        unLongTemp.charArray[0].hi = a_buffer[0]&0xFF;
        unLongTemp.charArray[0].lo = a_buffer[1]&0xFF;
        unLongTemp.charArray[1].hi = a_buffer[2]&0xFF;
        unLongTemp.charArray[1].lo = a_buffer[3]&0xFF;
    }

    I suspect you want to avoid names for the 8-bit wide fields, such as hi and lo in this example.  Unfortunately, that is not possible.

    Thanks and regards,

    -George

  • Hi George,

    I suspect you want to avoid names for the 8-bit wide fields, such as hi and lo in this example.  Unfortunately, that is not possible.

    I am OK with it.

    Now I have a question, if I assign 0xFF to each hi and lo, i got signed value. 

    e.g. if hi lo assigned with 0x7F, the unLongTemp.all is 2139062143 011111111 011111111 011111111 011111111

    a_buffer[0] = 0x7F;
    a_buffer[1] = 0x7F;
    a_buffer[2] = 0x7F;
    a_buffer[3] = 0x7F;

    however if hi lo assigned with 0xFF, the unLongTemp.all is -1 

    a_buffer[0] = 0xFF;
    a_buffer[1] = 0xFF;
    a_buffer[2] = 0xFF;
    a_buffer[3] = 0xFF;

    Danny

  • Hi Danny,

    What exact version of CCS are you using?

    Thanks

    ki

  • Code Composer Studio

    Version: 11.2.0.00007

    OS X Version

  • When I use George's example code and set a_buffer all to 0xFF, this is what I see in the expressions view:

    The Expressions view in your screenshot is not showing the type, which is odd to me.

    I only tried on my Windows PC. I'll try on my Mac when I have a chance.

    What OS X version are you using?

    Thanks

    ki