AnsweredAssumed Answered

Packing data into an 8bit aligned stream on the TWI interface.

Question asked by SteveWiSA on Mar 3, 2014
Latest reply on May 14, 2014 by Jithul_Janardhanan



   Were trying to communicate to an I2C device that uses an 8-bit byte aligned 'stream' to pass data to and from it's uC.


   With other processors we've previously used their compilers allow 'data sizes smaller than the addressable unit size on the processor'.  So in those cases we've taken advantage the pragma pack instruction and typedef a datatype to transmit and receive the message:



   #pragma pack(1)

  typedef struct{

      uint16_t protocol;

      uint16_t checksum;

      uint8_t readWrite;

      uint8_t primaryOpcode;

      uint16_t secondaryOpcode;



  typedef struct{

       uint16_t datalength;

       uint8_t  data[512];



  typedef struct{

   HEADER header;

   PAYLOAD payload;


  #pragma pack()


We then take advantage of casting or memcpy the data into an array that is of type uint8_t.  For example:



MESSAGE my_message;
uint8_t char_arry[SIZEOF_MESSAGE];
unint16_t offset = 0;

my_message.header.protocol = 0x0A0B;
  my_message.header.checksum = 0xFF70;
  my_message.header.readWrite =0x00;
  my_message.header.primaryOpcode = 0xAB;
  my_message.header.secondaryOpcode =0xC1;

memcpy(&[offset ], some_16bit_value, sizeof(uint16_t);
offset +=  sizeof(uint16_t);
memcpy(&[offset ], someother_16bit_value, sizeof(uint16_t);
offset +=  sizeof(uint16_t);
  memcpy(&[offset ], some_8bit_value, sizeof(uint8_t);
offset +=  sizeof(uint8_t);
memcpy(&[offset ], some_32bit_value, sizeof(uint32_t);
  offset +=  sizeof(uint32_t);

my_message.payload.datalength  = offset;

memcpy(char_arry, &my_message,  sizeof(HEADER)+uint16_t+offset);

status = i2cwrite(dev_addr, char_arry, sizeof(HEADER)+uint16_t+offset);

   So on other processor/compilers this that we've used this results in a nice little 8 bit aligned data stream to the device.  A read from the device uses the same data structure type.


   However as the 21479 SHARC's compiler  does not  allow 'data sizes smaller than the addressable unit size on the processor', we're not sure how to go forward.   We've verified that if we simply do a memcpy into a char array and then put each element of the array onto the 8 bit TWI fifo, we don't get the upper bits of those elements.


  For example in the struct above we get 0B 70 00 AB...  When it should be 0A 0B FF 70 00 AB...


It looks like in those elements that have data in the upper bits we'd have to bit shift it into the fifo.


  Is there another way that we can do this without the low level I2C read/write driver having to 'know' about the data is is sending/receiving?