Jump to content

Recommended Posts

I wish to parse a data packet from a GPS module. The packet when receive has 10 bytes, comprising a float, 4 bytes MSB first; a short 2 bytes, MSB first and a float 4 bytes MSB first.

 

The data is received into a buffer.

 

I tried this to swap the 'short' bytes - MAKESHORT( WeekNum, ucData[5], ucData[4] ); //MAKESHORT( dst, lobyte, hibyte )

 

and got the following error:

failure

C:\Documents and Settings\Ted\My Documents\PIC\working\Mynovo\tflib\TsipParser.c(315): error: error in built-in assembly

To swap the 4 bytes needed for the floats I tried the following code which is based on sample code given in the GPS documentation. I have to admit I don't understand the return line so I can't deal with the error message for the return line.

 

Error message : internal error: can't assign operand to temp var.

 

sample code

FLT CTsipParser::GetSingle (U8 *pucBuf)
{
U8 ucBuf[4];

ucBuf[0] = pucBuf[3];
ucBuf[1] = pucBuf[2];
ucBuf[2] = pucBuf[1];
ucBuf[3] = pucBuf[0];

return (*((FLT *)ucBuf));
}


my rewrite

float MakeFloat (char *inBuf)
{
char buf[4];

buf[0] = inBuf[3];
buf[1] = inBuf[2];
buf[2] = inBuf[1];
buf[3] = inBuf[0];
return (*((float *)buf));

}

Any advice would be welcomed.

 

Error message : internal error: can't assign operand to temp var

Link to post
Share on other sites
You could try using a union.

 

float myfloatfunc(char *inbuf)
{
union {
	float myfloat;
	char buf[4];
} floaty;
//....
return floaty.myfloat;
}

 

Cheers

 

Reynard

 

Not sure I follow your thinking here. I can see this will divide up the buffer into 'bite size chunks'

 

My struggle is with the byte swapping needed to get the 2 or 4 bytes into the correct order.

 

Using the built in MAKESHORT macro gave this error: error: error in built-in assembly - which is a worry as it is defined in boostc.h

 

However on a brighter note I have since found this code snippet at bytes.com although its not loading tonight!

 

UInt16 swap16(UInt16 input) {

return ((UInt16)(

((0xFF00 & input) >8) |

((0x00FF & input) << 8)));

}

 

UInt32 swap32(UInt32 input) {

return ((UInt32)(

((0xFF000000 & input) >24) |

((0x00FF0000 & input) >8) |

((0x0000FF00 & input) << 8) |

((0x000000FF & input) << 24)));

}

Link to post
Share on other sites

I didn't put in the obvious byte swaping part as you knew that bit.

 

float myfloatfunc(char *inbuf)
{
union {
	float myfloat;
	char buf[4];
} floaty;
//....
floaty.buf[0] = inBuf[3];
floaty.buf[1] = inBuf[2];
floaty.buf[2] = inBuf[1];
floaty.buf[3] = inBuf[0];

return floaty.myfloat;
}

 

unsigned char buf[4] would have read better.

An unsigned long would have done just as well instead of the float. If you are using the BoostC float library then keep it as a float.

 

Cheers

 

Reynard

Link to post
Share on other sites
...I tried this to swap the 'short' bytes - MAKESHORT( WeekNum, ucData[5], ucData[4] ); //MAKESHORT( dst, lobyte, hibyte )...

 

The MAKESHORT macro uses built-in assembly under the hood. This maker it very efficient but the down side to this efficiency is that it can deal with plain variables only. The macro pretty much puts the macro arguments into the the assembly operators and since assembly doesn't understand arrays (i.e. movf _ucData[5], W) you see these errors.

 

Regards,

Pavel

 

PS: From other hand it doesn't look to difficult to add support for array operation that uses const offset into built-in assembly. We'll investigate if this feature can be added to compiler.

Link to post
Share on other sites
...I tried this to swap the 'short' bytes - MAKESHORT( WeekNum, ucData[5], ucData[4] ); //MAKESHORT( dst, lobyte, hibyte )...

 

The MAKESHORT macro uses built-in assembly under the hood. This maker it very efficient but the down side to this efficiency is that it can deal with plain variables only. The macro pretty much puts the macro arguments into the the assembly operators and since assembly doesn't understand arrays (i.e. movf _ucData[5], W) you see these errors.

 

Regards,

Pavel

 

PS: From other hand it doesn't look to difficult to add support for array operation that uses const offset into built-in assembly. We'll investigate if this feature can be added to compiler.

 

Thanks for the 2 replies. It does clarify what is happening. I will give it a try.

 

Thanks again.

 

Ted

Link to post
Share on other sites
  • 2 weeks later...
I didn't put in the obvious byte swaping part as you knew that bit.

 

float myfloatfunc(char *inbuf)
{
union {
	float myfloat;
	char buf[4];
} floaty;
//....
floaty.buf[0] = inBuf[3];
floaty.buf[1] = inBuf[2];
floaty.buf[2] = inBuf[1];
floaty.buf[3] = inBuf[0];

return floaty.myfloat;
}

 

unsigned char buf[4] would have read better.

An unsigned long would have done just as well instead of the float. If you are using the BoostC float library then keep it as a float.

 

Cheers

 

Reynard

 

I have used this function and a similar one to swap bytes in a short - thanks.

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...