The purpose of this group is to foster exchange of information on the Texas Instruments MSP430 family of microcontrollers and related tools. Everyone welcome, all levels of familiarity/expertise.
union and struct to speed up data handling - timokirschke - Jul 24 8:37:54 2008
Hello,
filling a 38-byte long buffer for the serial data output, I used
following construction:
------------------------
union INTSPLITTER1
{
struct
{
char lobyte1;
char hibyte1;
} character1;
unsigned int both_bytes1;
}SendBuf1Int1;
union INTSPLITTER2
{
struct
{
char lobyte2;
char hibyte2;
} character2;
unsigned int both_bytes2;
}SendBuf1Int2;
...
{
SendBuf1Int1.both_bytes1 = SumRHist; // save O2 sensor heater
resistance
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.hibyte1]; //look up table
SendBuf1[34] = SendBuf1Int2.character2.hibyte2; // split hibyte
SendBuf1[33] = SendBuf1Int2.character2.lobyte2; // split lobyte
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.lobyte1]; //look up table
SendBuf1[32] = SendBuf1Int2.character2.hibyte2; // split hibyte
SendBuf1[31] = SendBuf1Int2.character2.lobyte2; // split lobyte
...
}
------------------------
I tried this to prevent the excessive bit shifts for data alignments
in the code before:
------------------------
{
shift_help = SumRHist; // save O2 sensor heater
resistance
result = 0x0F & shift_help;
SendBuf1[31] = ASCII_HEX_vector_byte[result]; //look up table
shift_help >>= 4;
result = 0x0F & shift_help;
SendBuf1[32] = ASCII_HEX_vector_byte[result];
result = 0x0F & (SumRHist >> 8);
SendBuf1[33] = ASCII_HEX_vector_byte[result];
result = 0x0F & (shift_help >> 8);
SendBuf1[34] = ASCII_HEX_vector_byte[result];
}
------------------------
The result were 15us saved for the related 32 bytes. It takes 51us
now.
Does anybody have an idea to save some time additionally?
Thank you in advance!
Regards, Timo
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - bb_stefan - Jul 24 10:09:03 2008
Hi Timo,
the explanation of your problem is somewhat confusing to me...
... but I think I guess what you want to realize..?!
On the one hand you want a byte-buffer for simplified transfer over
UART or something. On the other hand you want to access this buffer
with some "meaningful" names instead of buffer[17] = xyz.
So why not using unions in that way?
#pragma pack(1) // maybe necessary in some cases for correct data
alignment
struct SEND_DATA
{
BYTE len; // e.g. some header stuff
BYTE adr;
struct DATA_1 // different structs for different
{ // data values...
BYTE err;
WORD meas_value;
} data1;
struct DATA_2
{
BYTE err;
BYTE meas_value_hi;
BYTE meas_value_lo;
} data2;
BYTE data[MAX_RECEIVEBUF-8]; // fill the rest that is left over
};
#pragma pack() // back to standard alignment
union PROTOCOL_SEND_DATA
{
SEND_DATA SendData;
BYTE SendBuffer[MAX_SENDBUF];
} m_SendBuf;
// Fill Buffer with Values
m_SendBuf.SendData.len = 38;
m_SendBuf.SendData.adr = 1;
...
m_SendBuf.SendData.data1.meas_value = 0xFFFF;
...
// Send Buffer
SendBufferFunction(m_SendBuf.SendBuffer,...);
With this union you only have one physical buffer, which is accesed in
two (ore more) different ways, one with meaningful names and one
strict byte oriented. In addition you save the time to copy data from
one buffer to another because there is only one!
Hope this helps ?
--- In m...@yahoogroups.com, "timokirschke"
wrote:
>
> Hello,
>
> filling a 38-byte long buffer for the serial data output, I used
> following construction:
>
> ------------------------
> union INTSPLITTER1
> {
> struct
> {
> char lobyte1;
> char hibyte1;
> } character1;
> unsigned int both_bytes1;
> }SendBuf1Int1;
> union INTSPLITTER2
> {
> struct
> {
> char lobyte2;
> char hibyte2;
> } character2;
> unsigned int both_bytes2;
> }SendBuf1Int2;
> ...
> {
> SendBuf1Int1.both_bytes1 = SumRHist; // save O2 sensor heater
> resistance
> SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> [SendBuf1Int1.character1.hibyte1]; //look up table
> SendBuf1[34] = SendBuf1Int2.character2.hibyte2; // split hibyte
> SendBuf1[33] = SendBuf1Int2.character2.lobyte2; // split lobyte
> SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> [SendBuf1Int1.character1.lobyte1]; //look up table
> SendBuf1[32] = SendBuf1Int2.character2.hibyte2; // split hibyte
> SendBuf1[31] = SendBuf1Int2.character2.lobyte2; // split lobyte
> ...
> }
> ------------------------
> I tried this to prevent the excessive bit shifts for data alignments
> in the code before:
> ------------------------
> {
> shift_help = SumRHist; // save O2 sensor heater
> resistance
> result = 0x0F & shift_help;
> SendBuf1[31] = ASCII_HEX_vector_byte[result]; //look up table
> shift_help >>= 4;
> result = 0x0F & shift_help;
> SendBuf1[32] = ASCII_HEX_vector_byte[result];
> result = 0x0F & (SumRHist >> 8);
> SendBuf1[33] = ASCII_HEX_vector_byte[result];
> result = 0x0F & (shift_help >> 8);
> SendBuf1[34] = ASCII_HEX_vector_byte[result];
> }
> ------------------------
> The result were 15us saved for the related 32 bytes. It takes 51us
> now.
> Does anybody have an idea to save some time additionally?
>
> Thank you in advance!
> Regards, Timo
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling - old_cow_yellow - Jul 24 10:16:30 2008
I thought Timo wants to unpack the 4 nibbles of SumRHist, encode them
with ASCII_HEX table, and put them in SendBuf1[31..34].
--- In m...@yahoogroups.com, "bb_stefan"
wrote:
>
> Hi Timo,
>
> the explanation of your problem is somewhat confusing to me...
> ... but I think I guess what you want to realize..?!
>
> On the one hand you want a byte-buffer for simplified transfer over
> UART or something. On the other hand you want to access this buffer
> with some "meaningful" names instead of buffer[17] = xyz.
>
> So why not using unions in that way?
>
> #pragma pack(1) // maybe necessary in some cases for correct data
> alignment
>
> struct SEND_DATA
> {
> BYTE len; // e.g. some header stuff
> BYTE adr;
>
> struct DATA_1 // different structs for different
> { // data values...
> BYTE err;
> WORD meas_value;
> } data1;
>
> struct DATA_2
> {
> BYTE err;
> BYTE meas_value_hi;
> BYTE meas_value_lo;
> } data2;
>
> BYTE data[MAX_RECEIVEBUF-8]; // fill the rest that is left over
> };
>
> #pragma pack() // back to standard alignment
> union PROTOCOL_SEND_DATA
> {
> SEND_DATA SendData;
> BYTE SendBuffer[MAX_SENDBUF];
> } m_SendBuf;
>
> // Fill Buffer with Values
> m_SendBuf.SendData.len = 38;
> m_SendBuf.SendData.adr = 1;
> ...
> m_SendBuf.SendData.data1.meas_value = 0xFFFF;
> ...
>
> // Send Buffer
> SendBufferFunction(m_SendBuf.SendBuffer,...);
>
> With this union you only have one physical buffer, which is accesed in
> two (ore more) different ways, one with meaningful names and one
> strict byte oriented. In addition you save the time to copy data from
> one buffer to another because there is only one!
>
> Hope this helps ?
> --- In m...@yahoogroups.com, "timokirschke" wrote:
> >
> > Hello,
> >
> > filling a 38-byte long buffer for the serial data output, I used
> > following construction:
> >
> > ------------------------
> > union INTSPLITTER1
> > {
> > struct
> > {
> > char lobyte1;
> > char hibyte1;
> > } character1;
> > unsigned int both_bytes1;
> > }SendBuf1Int1;
> > union INTSPLITTER2
> > {
> > struct
> > {
> > char lobyte2;
> > char hibyte2;
> > } character2;
> > unsigned int both_bytes2;
> > }SendBuf1Int2;
> > ...
> > {
> > SendBuf1Int1.both_bytes1 = SumRHist; // save O2 sensor heater
> > resistance
> > SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> > [SendBuf1Int1.character1.hibyte1]; //look up table
> > SendBuf1[34] = SendBuf1Int2.character2.hibyte2; // split hibyte
> > SendBuf1[33] = SendBuf1Int2.character2.lobyte2; // split lobyte
> > SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> > [SendBuf1Int1.character1.lobyte1]; //look up table
> > SendBuf1[32] = SendBuf1Int2.character2.hibyte2; // split hibyte
> > SendBuf1[31] = SendBuf1Int2.character2.lobyte2; // split lobyte
> > ...
> > }
> > ------------------------
> > I tried this to prevent the excessive bit shifts for data alignments
> > in the code before:
> > ------------------------
> > {
> > shift_help = SumRHist; // save O2 sensor heater
> > resistance
> > result = 0x0F & shift_help;
> > SendBuf1[31] = ASCII_HEX_vector_byte[result]; //look up table
> > shift_help >>= 4;
> > result = 0x0F & shift_help;
> > SendBuf1[32] = ASCII_HEX_vector_byte[result];
> > result = 0x0F & (SumRHist >> 8);
> > SendBuf1[33] = ASCII_HEX_vector_byte[result];
> > result = 0x0F & (shift_help >> 8);
> > SendBuf1[34] = ASCII_HEX_vector_byte[result];
> > }
> > ------------------------
> > The result were 15us saved for the related 32 bytes. It takes 51us
> > now.
> > Does anybody have an idea to save some time additionally?
> >
> > Thank you in advance!
> > Regards, Timo
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling - Hugh Molesworth - Jul 24 13:00:59 2008
You might get a small improvement doing something like this:
Declare SumRHist as type BlahBlahType where
typedef union
{
struct
{
char lobyte;
char hibyte;
} character;
unsigned int both_bytes;
}BlahBlahType;
BlahBlahType SumRHist; // Allocate storage
SumRHist.both_bytes = 0x1234; // example set
SendBuf1[32] = ASCII_HEX_vector_int[SumRHist.character.hibyte];
SendBuf1[31] = ASCII_HEX_vector_int[SumRHist.character.lobyte];
You can get a bigger improvement using something like this:
*(unsigned int *)&SendBuf1[Index] = ASCII_HEX_vector_int[Reading];
Index MUST be even, ASCII_HEX_vector_int[] now has to be bigger
(perhaps 8192 bytes).
You can get an even bigger improvement using something like this:
*(unsigned int *)&SendBuf1[Index] = [Reading];
Index MUST be even, table lookup conversion is done back at the host
Hugh
At 05:37 AM 7/24/2008, you wrote:
Hello,
filling a 38-byte long buffer for the serial data output, I used
following construction:
------------------------
union INTSPLITTER1
{
struct
{
char lobyte1;
char hibyte1;
} character1;
unsigned int both_bytes1;
}SendBuf1Int1;
union INTSPLITTER2
{
struct
{
char lobyte2;
char hibyte2;
} character2;
unsigned int both_bytes2;
}SendBuf1Int2;
....
{
SendBuf1Int1.both_bytes1 = SumRHist; // save O2 sensor heater resistance
SendBuf1Int2.both_bytes2 =
ASCII_HEX_vector_int[SendBuf1Int1.character1.hibyte1]; //look up table
SendBuf1[34] = SendBuf1Int2.character2.hibyte2; // split hibyte
SendBuf1[33] = SendBuf1Int2.character2.lobyte2; // split lobyte
SendBuf1Int2.both_bytes2 =
ASCII_HEX_vector_int[SendBuf1Int1.character1.lobyte1]; //look up table
SendBuf1[32] = SendBuf1Int2.character2.hibyte2; // split hibyte
SendBuf1[31] = SendBuf1Int2.character2.lobyte2; // split lobyte
....
}
------------------------
I tried this to prevent the excessive bit shifts for data alignments
in the code before:
------------------------
{
shift_help = SumRHist; // save O2 sensor heater
resistance
result = 0x0F & shift_help;
SendBuf1[31] = ASCII_HEX_vector_byte[result]; //look up table
shift_help >>= 4;
result = 0x0F & shift_help;
SendBuf1[32] = ASCII_HEX_vector_byte[result];
result = 0x0F & (SumRHist >> 8);
SendBuf1[33] = ASCII_HEX_vector_byte[result];
result = 0x0F & (shift_help >> 8);
SendBuf1[34] = ASCII_HEX_vector_byte[result];
}
------------------------
The result were 15us saved for the related 32 bytes. It takes 51us
now.
Does anybody have an idea to save some time additionally?
Thank you in advance!
Regards, Timo
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - timokirschke - Jul 24 13:17:35 2008
Thank you,
you both know, what I want. ;)
The vector looks like that (I forgot to show it before):
-------------------
const unsigned int ASCII_HEX_vector_int[256] = {
0x3030,0x3031,...,0x3045,0x3046,
0x3130,0x3131,...,0x3145,0x3146,
...
0x4630,0x4631,...,0x4645,0x4646}; // Look up table
-------------------
It helps to convert the two nibbles of a byte simultaneously into
ASCII:
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.hibyte1];
I will try the hints from Stefan during the next days, when I
understood it fully. Unfortunately I'm a lousy programmer.
Thank you again,
Timo
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - bb_stefan - Jul 24 14:23:58 2008
Hmm, ... feeling like having a deja-vu...
Are you still trying to reduce instruction cycles
(mikrocontroller.net)? ;-)
The idea behind my proposed "union mechanism" is that you have one
physical buffer of 38 bytes (in your case). Using a union is like
using different masks laid over this one and only buffer.
One mask simply interprets the buffer as it is: an array of bytes that
can be accessed by union.buffer[i] (0<=i<=37).
Another mask uses a more understandable way to deal with the buffer by
using structs that e.g. rely on the protocol used for the serial
communication or whatever is useful and can be accessed e.g. by
union.struct.identifier
So the benefit is, that you can use the same buffer either as array of
bytes or as a structured container with meaningful identifiers without
calculating the correct indices inside the underlying byte-array. And
you don't have to copy one buffer into another!
I hope, this makes things a bit clearer, but maybe you should look
around the internet a little bit for using unions.
It's not magic ;-)
--- In m...@yahoogroups.com, "timokirschke"
wrote:
>
> Thank you,
>
> you both know, what I want. ;)
> The vector looks like that (I forgot to show it before):
> -------------------
> const unsigned int ASCII_HEX_vector_int[256] = {
> 0x3030,0x3031,...,0x3045,0x3046,
> 0x3130,0x3131,...,0x3145,0x3146,
> ...
> 0x4630,0x4631,...,0x4645,0x4646}; // Look up table
> -------------------
> It helps to convert the two nibbles of a byte simultaneously into
> ASCII:
> SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> [SendBuf1Int1.character1.hibyte1];
>
> I will try the hints from Stefan during the next days, when I
> understood it fully. Unfortunately I'm a lousy programmer.
>
> Thank you again,
> Timo
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling - old_cow_yellow - Jul 24 14:42:24 2008
Since you are using c, I think you should let the c-compiler do the
dirty work.
I would just call a procedure to do it. Like this:
Foo(SumRHist, &SendBuf1[31]);
Where the procedure Foo() is something like:
void Foo(unsigned int src, char dst[])
{
dst[0] = Table[src & 0x0F];
dst[1] = Table[(src >> 4) & 0x0F];
dst[2] = Table[(src >> 8) & 0x0F];
dst[3] = Table[(src >> 12) & 0x0F];
}
I think an efficient (in speed) c-compiler should be able to generate
decent code to do the above in 8 microseconds with MCLK=8MHz. Where
the shifting and table-look up actually only take about 5
microseconds. The other 3 are spent to load the parameters, calling,
returning, and cleaning up.
You counted microseconds but did not say what MCLK is.
--- In m...@yahoogroups.com, "timokirschke"
wrote:
>
> Thank you,
>
> you both know, what I want. ;)
> The vector looks like that (I forgot to show it before):
> -------------------
> const unsigned int ASCII_HEX_vector_int[256] = {
> 0x3030,0x3031,...,0x3045,0x3046,
> 0x3130,0x3131,...,0x3145,0x3146,
> ...
> 0x4630,0x4631,...,0x4645,0x4646}; // Look up table
> -------------------
> It helps to convert the two nibbles of a byte simultaneously into
> ASCII:
> SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> [SendBuf1Int1.character1.hibyte1];
>
> I will try the hints from Stefan during the next days, when I
> understood it fully. Unfortunately I'm a lousy programmer.
>
> Thank you again,
> Timo
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling - Hugh Molesworth - Jul 24 16:45:59 2008
oops, fixed a couple of typos in my post
==
You might get a small improvement doing something like this:
Declare SumRHist as type BlahBlahType where
typedef union
{
struct
{
char lobyte;
char hibyte;
} character;
unsigned int both_bytes;
}BlahBlahType;
BlahBlahType SumRHist; // Allocate storage
SumRHist.both_bytes = 0x1234; // example set
SendBuf1[32] = ASCII_HEX_vector_int[SumRHist.character.hibyte];
SendBuf1[31] = ASCII_HEX_vector_int[SumRHist.character.lobyte];
You can get a bigger improvement using something like this:
*(unsigned int *)&SendBuf1[Index] = ASCII_HEX_vector_int[Reading];
SendBuf1[Index] MUST be on even address, ASCII_HEX_vector_int[] now
has to be bigger (perhaps 8192 bytes).
You can get an even bigger improvement using something like this:
*(unsigned int *)&SendBuf1[Index] = Reading;
SendBuf1[Index] MUST be on even address, table lookup conversion is
done back at the host
Hugh
At 05:37 AM 7/24/2008, you wrote:
Hello,
filling a 38-byte long buffer for the serial data output, I used
following construction:
------------------------
union INTSPLITTER1
{
struct
{
char lobyte1;
char hibyte1;
} character1;
unsigned int both_bytes1;
}SendBuf1Int1;
union INTSPLITTER2
{
struct
{
char lobyte2;
char hibyte2;
} character2;
unsigned int both_bytes2;
}SendBuf1Int2;
....
{
SendBuf1Int1.both_bytes1 = SumRHist; // save O2 sensor heater resistance
SendBuf1Int2.both_bytes2 =
ASCII_HEX_vector_int[SendBuf1Int1.character1.hibyte1]; //look up table
SendBuf1[34] = SendBuf1Int2.character2.hibyte2; // split hibyte
SendBuf1[33] = SendBuf1Int2.character2.lobyte2; // split lobyte
SendBuf1Int2.both_bytes2 =
ASCII_HEX_vector_int[SendBuf1Int1.character1.lobyte1]; //look up table
SendBuf1[32] = SendBuf1Int2.character2.hibyte2; // split hibyte
SendBuf1[31] = SendBuf1Int2.character2.lobyte2; // split lobyte
....
}
------------------------
I tried this to prevent the excessive bit shifts for data alignments
in the code before:
------------------------
{
shift_help = SumRHist; // save O2 sensor heater
resistance
result = 0x0F & shift_help;
SendBuf1[31] = ASCII_HEX_vector_byte[result]; //look up table
shift_help >>= 4;
result = 0x0F & shift_help;
SendBuf1[32] = ASCII_HEX_vector_byte[result];
result = 0x0F & (SumRHist >> 8);
SendBuf1[33] = ASCII_HEX_vector_byte[result];
result = 0x0F & (shift_help >> 8);
SendBuf1[34] = ASCII_HEX_vector_byte[result];
}
------------------------
The result were 15us saved for the related 32 bytes. It takes 51us
now.
Does anybody have an idea to save some time additionally?
Thank you in advance!
Regards, Timo
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - timokirschke - Jul 24 19:01:25 2008
Hello,
so many replies, that's nice! Thank you again. Do I have to arrange a
shootout between the possibilities? :)
Stefan,
Deja-vu? I do not post there until now. May be one of our students
wrote something concerning this topic. Hehe, a good test, if they are
doing something.
I found a little bit here:
http://de.wikibooks.org/wiki/C-Programmierung:_Komplexe_Datentypen
Yes, it seems to be easy.
The data to be transferred are int variables, but the sequence of the
variables may change during the program run due to parameterising by
the PC via RS232 (different sensors require different data handling/
reading). So the first "buffer", int variables containing the
measurement values as hex data, is not aligned, the send buffer is.
They cannot be the same. Maybe, I did not understand you correctly.
old_cow_yellow,
hmm, your code looks better than my constructs, easier to read. You
actually combined two lines into one.
I use Pauls great compiler, it does the 4 bit shifts honestly, the 8
bit shifts are done by byteswaps. Maybe, the one-line-thing is easier
to optimise, I'll try it.
Of course I forgot to tell the clock, you are right, it is 8MHz,
excuse me.
Hugh,
I have to learn something about pointers, they are still a bit
mystical to me. One of the students suggested a similar construct.
Thank you!
Regards, Timo
If interested, the PCB:
http://ibtk.de/project/rss/PRO1.6_top_02_400x375.jpg
explanation of the project:
http://ibtk.de/project/rss/PRO3-FR-Exec-Sum_17102006.pdf
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - timokirschke - Jul 24 19:03:42 2008
Hello,
so many replies, that's nice! Thank you again. Do I have to arrange a
shootout between the possibilities? :)
Stefan,
Deja-vu? I do not post there until now. May be one of our students
wrote something concerning this topic. Hehe, a good test, if they are
doing something.
I found a little bit here:
http://de.wikibooks.org/wiki/C-Programmierung:_Komplexe_Datentypen
Yes, it seems to be easy.
The data to be transferred are int variables, but the sequence of the
variables may change during the program run due to parameterising by
the PC via RS232 (different sensors require different data handling/
reading). So the first "buffer", int variables containing the
measurement values as hex data, is not aligned, the send buffer is.
They cannot be the same. Maybe, I did not understand you correctly.
old_cow_yellow,
hmm, your code looks better than my constructs, easier to read. You
actually combined two lines into one.
I use Pauls great compiler, it does the 4 bit shifts honestly, the 8
bit shifts are done by byteswaps. Maybe, the one-line-thing is easier
to optimise, I'll try it.
Of course I forgot to tell the clock, you are right, it is 8MHz,
excuse me.
Hugh,
I have to learn something about pointers, they are still a bit
mystical to me. One of the students suggested a similar construct.
Thank you!
Regards, Timo
If interested, the PCB:
http://ibtk.de/project/rss/PRO1.6_top_02_400x375.jpg
explanation of the project:
http://ibtk.de/project/rss/PRO3-FR-Exec-Sum_17102006.pdf
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - bb_stefan - Jul 25 2:11:51 2008
> The data to be transferred are int variables, but the sequence of the
> variables may change during the program run due to parameterising by
> the PC via RS232 (different sensors require different data handling/
> reading). So the first "buffer", int variables containing the
> measurement values as hex data, is not aligned, the send buffer is.
> They cannot be the same. Maybe, I did not understand you correctly.
If you are only using int variables (supposing them to be 16 bit on
MSP) then there is no alignment problem. Every int starts at an even
address without the need of padding bytes.
Problems occur if you define a struct like this:
struct
{
char c_dummy;
int n_dummy;
}
c_dummy starts at an even address, consuming one byte. n_dummy must
also start at an even address, so a padding byte has to be inserted
after c_dummy.
In other words: the struct is consuming 4 bytes instead of 3 bytes as
might be supposed!
But in such a case you could force the compile/linker not to add
padding bytes by using the #pragma pack(1)... (also see e.g. the user
guide of the IAR compiler "pragma directives" with examples about
alignment)
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling - timokirschke - Jul 25 5:43:00 2008
Hello,
yes, that's clear.
What I meant was that the measured values, e.g. voltages,
resistances, currents, which have to be sent out, differ depending on
the application, which can be modified during runtime.
So in the first case voltage1, voltage2, current1 will be sent, in
the second case current2, voltage2, resistance1 etc. The types remain
unsigned int and the number of variables to be sent (==> length of
the buffer) remain the same.
So the sequence inside of the first buffer would change and it cannot
be handled as a normal data buffer with consistent measurement value
places - as I think, may be wrong.
A way out could be, to put all these variables into a union and to
switch between the send modes, using different FillSendBuf codes
(using case or if).
Regards, Timo
The code I posted first, needs 49 cycles (Crossworks core simulator)
on the F149 for putting 4 bytes into the buffer:
------------------------
SendBuf1Int1.both_bytes1 = SumRHist;
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.hibyte1];
SendBuf1[34] = SendBuf1Int2.character2.hibyte2;
SendBuf1[33] = SendBuf1Int2.character2.lobyte2;
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.lobyte1];
SendBuf1[32] = SendBuf1Int2.character2.hibyte2;
SendBuf1[31] = SendBuf1Int2.character2.lobyte2;
------------------------
--- In m...@yahoogroups.com, "bb_stefan"
wrote:
>
> If you are only using int variables (supposing them to be 16 bit on
> MSP) then there is no alignment problem. Every int starts at an even
> address without the need of padding bytes.
> Problems occur if you define a struct like this:
>
> struct
> {
> char c_dummy;
> int n_dummy;
> }
>
> c_dummy starts at an even address, consuming one byte. n_dummy must
> also start at an even address, so a padding byte has to be inserted
> after c_dummy.
> In other words: the struct is consuming 4 bytes instead of 3 bytes
as
> might be supposed!
> But in such a case you could force the compile/linker not to add
> padding bytes by using the #pragma pack(1)... (also see e.g. the
user
> guide of the IAR compiler "pragma directives" with examples about
> alignment)
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling: shootout - timokirschke - Jul 25 10:06:32 2008
Hello,
yes, that's clear.
What I meant was that the measured values, e.g. voltages,
resistances, currents, which have to be sent out, differ depending on
the application, which can be modified during runtime.
So in the first case voltage1, voltage2, current1 will be sent, in
the second case current2, voltage2, resistance1 etc. The types remain
unsigned int and the number of variables to be sent (==> length of
the buffer) remain the same.
So the sequence inside of the first buffer would change and it cannot
be handled as a normal data buffer with consistent measurement value
places - as I think, may be wrong.
A way out could be, to put all these variables into a union and to
switch between the send modes, using different FillSendBuf codes
(using case or if).
Regards, Timo
------------------------
This line does not work (does not fill four bytes of the buffer as I
thought first), I have no idea to correct it (e.g. the value SumRHist
is unsigned int and would need a 65k ASCII_HEX_vector):
*(unsigned int *)&SendBuf1[31] = ASCII_HEX_vector_int[SumRHist];
------------------------
The needed number of cycles (Crossworks core simulator)
on the F149 for putting 4 bytes into the buffer:
------------------------
// 52 cycles, the "old" code
shift_help = SumRHist;
result = 0x0F & shift_help;
SendBuf1[31] = ASCII_HEX_vector_byte[result];
shift_help >>= 4;
result = 0x0F & shift_help;
SendBuf1[32] = ASCII_HEX_vector_byte[result];
result = 0x0F & (SumRHist >> 8);
SendBuf1[33] = ASCII_HEX_vector_byte[result];
result = 0x0F & (shift_help >> 8);
SendBuf1[34] = ASCII_HEX_vector_byte[result];
------------------------
// 56 cycles, the lines saving variant
SendBuf1[31] = ASCII_HEX_vector_byte[SumRHist & 0x0F];
SendBuf1[32] = ASCII_HEX_vector_byte[(SumRHist >> 4) & 0x0F];
SendBuf1[33] = ASCII_HEX_vector_byte[(SumRHist >> 8) & 0x0F];
SendBuf1[34] = ASCII_HEX_vector_byte[(SumRHist >> 12) & 0x0F];
------------------------
// 49 cycles, the first union/struct variant
SendBuf1Int1.both_bytes1 = SumRHist;
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.hibyte1];
SendBuf1[34] = SendBuf1Int2.character2.hibyte2;
SendBuf1[33] = SendBuf1Int2.character2.lobyte2;
SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
[SendBuf1Int1.character1.lobyte1];
SendBuf1[32] = SendBuf1Int2.character2.hibyte2;
SendBuf1[31] = SendBuf1Int2.character2.lobyte2;
Hmm, it seems to remain the best version.
--- In m...@yahoogroups.com, "bb_stefan"
wrote:
>
> If you are only using int variables (supposing them to be 16 bit on
> MSP) then there is no alignment problem. Every int starts at an even
> address without the need of padding bytes.
> Problems occur if you define a struct like this:
>
> struct
> {
> char c_dummy;
> int n_dummy;
> }
>
> c_dummy starts at an even address, consuming one byte. n_dummy must
> also start at an even address, so a padding byte has to be inserted
> after c_dummy.
> In other words: the struct is consuming 4 bytes instead of 3 bytes
as
> might be supposed!
> But in such a case you could force the compile/linker not to add
> padding bytes by using the #pragma pack(1)... (also see e.g. the
user
> guide of the IAR compiler "pragma directives" with examples about
> alignment)
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling: shootout - old_cow_yellow - Jul 25 10:37:45 2008
If the value of SumRHist and the addrss of SendBuf1 are already in two
of the Rn registers, and there are at least two other Rn for scratch,
it should take only 41 MCLK to do:
SendBuf1[31] = ASCII_HEX_vector_byte[SumRHist & 0x0F];
SendBuf1[32] = ASCII_HEX_vector_byte[(SumRHist >> 4) & 0x0F];
SendBuf1[33] = ASCII_HEX_vector_byte[(SumRHist >> 8) & 0x0F];
SendBuf1[34] = ASCII_HEX_vector_byte[(SumRHist >> 12) & 0x0F];
Loading SumRHist and &SendBuf1 into registers take 6 extra cycles, but
if the code was working with them, they should be in registers already.
--- In m...@yahoogroups.com, "timokirschke"
wrote:
>
> Hello,
>
> yes, that's clear.
> What I meant was that the measured values, e.g. voltages,
> resistances, currents, which have to be sent out, differ depending on
> the application, which can be modified during runtime.
> So in the first case voltage1, voltage2, current1 will be sent, in
> the second case current2, voltage2, resistance1 etc. The types remain
> unsigned int and the number of variables to be sent (==> length of
> the buffer) remain the same.
> So the sequence inside of the first buffer would change and it cannot
> be handled as a normal data buffer with consistent measurement value
> places - as I think, may be wrong.
> A way out could be, to put all these variables into a union and to
> switch between the send modes, using different FillSendBuf codes
> (using case or if).
>
> Regards, Timo
>
> ------------------------
> This line does not work (does not fill four bytes of the buffer as I
> thought first), I have no idea to correct it (e.g. the value SumRHist
> is unsigned int and would need a 65k ASCII_HEX_vector):
> *(unsigned int *)&SendBuf1[31] = ASCII_HEX_vector_int[SumRHist];
>
> ------------------------
> The needed number of cycles (Crossworks core simulator)
> on the F149 for putting 4 bytes into the buffer:
>
> ------------------------
> // 52 cycles, the "old" code
>
> shift_help = SumRHist;
> result = 0x0F & shift_help;
> SendBuf1[31] = ASCII_HEX_vector_byte[result];
> shift_help >>= 4;
> result = 0x0F & shift_help;
> SendBuf1[32] = ASCII_HEX_vector_byte[result];
> result = 0x0F & (SumRHist >> 8);
> SendBuf1[33] = ASCII_HEX_vector_byte[result];
> result = 0x0F & (shift_help >> 8);
> SendBuf1[34] = ASCII_HEX_vector_byte[result];
>
> ------------------------
> // 56 cycles, the lines saving variant
>
> SendBuf1[31] = ASCII_HEX_vector_byte[SumRHist & 0x0F];
> SendBuf1[32] = ASCII_HEX_vector_byte[(SumRHist >> 4) & 0x0F];
> SendBuf1[33] = ASCII_HEX_vector_byte[(SumRHist >> 8) & 0x0F];
> SendBuf1[34] = ASCII_HEX_vector_byte[(SumRHist >> 12) & 0x0F];
>
> ------------------------
> // 49 cycles, the first union/struct variant
>
> SendBuf1Int1.both_bytes1 = SumRHist;
> SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> [SendBuf1Int1.character1.hibyte1];
> SendBuf1[34] = SendBuf1Int2.character2.hibyte2;
> SendBuf1[33] = SendBuf1Int2.character2.lobyte2;
> SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> [SendBuf1Int1.character1.lobyte1];
> SendBuf1[32] = SendBuf1Int2.character2.hibyte2;
> SendBuf1[31] = SendBuf1Int2.character2.lobyte2;
>
> Hmm, it seems to remain the best version.
>
> --- In m...@yahoogroups.com, "bb_stefan" wrote:
> >
> > If you are only using int variables (supposing them to be 16 bit on
> > MSP) then there is no alignment problem. Every int starts at an even
> > address without the need of padding bytes.
> > Problems occur if you define a struct like this:
> >
> > struct
> > {
> > char c_dummy;
> > int n_dummy;
> > }
> >
> > c_dummy starts at an even address, consuming one byte. n_dummy must
> > also start at an even address, so a padding byte has to be inserted
> > after c_dummy.
> > In other words: the struct is consuming 4 bytes instead of 3 bytes
> as
> > might be supposed!
> > But in such a case you could force the compile/linker not to add
> > padding bytes by using the #pragma pack(1)... (also see e.g. the
> user
> > guide of the IAR compiler "pragma directives" with examples about
> > alignment)
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling: shootout - old_cow_yellow - Jul 25 11:19:56 2008
By the way, I was assuming a table of 16 bytes.
If you are willing to have a 256 words (512 bytes) table, you can
speed up a lot! Stay tuned.
--- In m...@yahoogroups.com, "old_cow_yellow"
wrote:
>
> If the value of SumRHist and the addrss of SendBuf1 are already in two
> of the Rn registers, and there are at least two other Rn for scratch,
> it should take only 41 MCLK to do:
>
> SendBuf1[31] = ASCII_HEX_vector_byte[SumRHist & 0x0F];
> SendBuf1[32] = ASCII_HEX_vector_byte[(SumRHist >> 4) & 0x0F];
> SendBuf1[33] = ASCII_HEX_vector_byte[(SumRHist >> 8) & 0x0F];
> SendBuf1[34] = ASCII_HEX_vector_byte[(SumRHist >> 12) & 0x0F];
>
> Loading SumRHist and &SendBuf1 into registers take 6 extra cycles, but
> if the code was working with them, they should be in registers already.
>
> --- In m...@yahoogroups.com, "timokirschke" wrote:
> >
> > Hello,
> >
> > yes, that's clear.
> > What I meant was that the measured values, e.g. voltages,
> > resistances, currents, which have to be sent out, differ depending on
> > the application, which can be modified during runtime.
> > So in the first case voltage1, voltage2, current1 will be sent, in
> > the second case current2, voltage2, resistance1 etc. The types remain
> > unsigned int and the number of variables to be sent (==> length of
> > the buffer) remain the same.
> > So the sequence inside of the first buffer would change and it cannot
> > be handled as a normal data buffer with consistent measurement value
> > places - as I think, may be wrong.
> > A way out could be, to put all these variables into a union and to
> > switch between the send modes, using different FillSendBuf codes
> > (using case or if).
> >
> > Regards, Timo
> >
> > ------------------------
> > This line does not work (does not fill four bytes of the buffer as I
> > thought first), I have no idea to correct it (e.g. the value SumRHist
> > is unsigned int and would need a 65k ASCII_HEX_vector):
> > *(unsigned int *)&SendBuf1[31] = ASCII_HEX_vector_int[SumRHist];
> >
> > ------------------------
> > The needed number of cycles (Crossworks core simulator)
> > on the F149 for putting 4 bytes into the buffer:
> >
> > ------------------------
> > // 52 cycles, the "old" code
> >
> > shift_help = SumRHist;
> > result = 0x0F & shift_help;
> > SendBuf1[31] = ASCII_HEX_vector_byte[result];
> > shift_help >>= 4;
> > result = 0x0F & shift_help;
> > SendBuf1[32] = ASCII_HEX_vector_byte[result];
> > result = 0x0F & (SumRHist >> 8);
> > SendBuf1[33] = ASCII_HEX_vector_byte[result];
> > result = 0x0F & (shift_help >> 8);
> > SendBuf1[34] = ASCII_HEX_vector_byte[result];
> >
> > ------------------------
> > // 56 cycles, the lines saving variant
> >
> > SendBuf1[31] = ASCII_HEX_vector_byte[SumRHist & 0x0F];
> > SendBuf1[32] = ASCII_HEX_vector_byte[(SumRHist >> 4) & 0x0F];
> > SendBuf1[33] = ASCII_HEX_vector_byte[(SumRHist >> 8) & 0x0F];
> > SendBuf1[34] = ASCII_HEX_vector_byte[(SumRHist >> 12) & 0x0F];
> >
> > ------------------------
> > // 49 cycles, the first union/struct variant
> >
> > SendBuf1Int1.both_bytes1 = SumRHist;
> > SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> > [SendBuf1Int1.character1.hibyte1];
> > SendBuf1[34] = SendBuf1Int2.character2.hibyte2;
> > SendBuf1[33] = SendBuf1Int2.character2.lobyte2;
> > SendBuf1Int2.both_bytes2 = ASCII_HEX_vector_int
> > [SendBuf1Int1.character1.lobyte1];
> > SendBuf1[32] = SendBuf1Int2.character2.hibyte2;
> > SendBuf1[31] = SendBuf1Int2.character2.lobyte2;
> >
> > Hmm, it seems to remain the best version.
> >
> > --- In m...@yahoogroups.com, "bb_stefan" wrote:
> > >
> > > If you are only using int variables (supposing them to be 16 bit on
> > > MSP) then there is no alignment problem. Every int starts at an even
> > > address without the need of padding bytes.
> > > Problems occur if you define a struct like this:
> > >
> > > struct
> > > {
> > > char c_dummy;
> > > int n_dummy;
> > > }
> > >
> > > c_dummy starts at an even address, consuming one byte. n_dummy must
> > > also start at an even address, so a padding byte has to be inserted
> > > after c_dummy.
> > > In other words: the struct is consuming 4 bytes instead of 3 bytes
> > as
> > > might be supposed!
> > > But in such a case you could force the compile/linker not to add
> > > padding bytes by using the #pragma pack(1)... (also see e.g. the
> > user
> > > guide of the IAR compiler "pragma directives" with examples about
> > > alignment)
> > >
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling: shootout - timokirschke - Jul 25 13:44:12 2008
Hello,
>
> By the way, I was assuming a table of 16 bytes.
> If you are willing to have a 256 words (512 bytes) table, you can
> speed up a lot! Stay tuned.
>
yes, I'm curious, because I already use a 256 byte vector, as written
before:
const unsigned int ASCII_HEX_vector_int[256] = {
0x3030,0x3031,...,0x3045,0x3046,
0x3130,0x3131,...,0x3145,0x3146,
...
0x4630,0x4631,...,0x4645,0x4646};
---------------------------
Next question. Using this construct:
union PROTOCOL_SEND_DATA
{
char SendBuf_char[40];
unsigned int SendBuf_int[20];
} m_SendBuf;
m_SendBuf.SendBuf_int[16] = ASCII_HEX_vector_int[SumRHist & 0xFF];
m_SendBuf.SendBuf_int[17] = ASCII_HEX_vector_int[(SumRHist >> 8) &
0xFF];
the data will not be aligned correctly. Example:
The value of SumRHist is 0xABCD.
m_SendBuf.SendBuf_int[17] will contain 0x0042 (ASCII B)
m_SendBuf.SendBuf_int[16] will contain 0x4344 (ASCII CD)
m_SendBuf.SendBuf_int[15] will contain 0xCD00
but only after accessing the buffer, e.g.
SendBuf1[34] = m_SendBuf.SendBuf_char[34];
I am confused. :(
It is a pity, because the two lines need only 22 cycles.
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling: shootout - bb_stefan - Jul 25 14:17:31 2008
>
> The value of SumRHist is 0xABCD.
> m_SendBuf.SendBuf_int[17] will contain 0x0042 (ASCII B)
> m_SendBuf.SendBuf_int[16] will contain 0x4344 (ASCII CD)
> m_SendBuf.SendBuf_int[15] will contain 0xCD00
>
> but only after accessing the buffer, e.g.
> SendBuf1[34] = m_SendBuf.SendBuf_char[34];
>
> I am confused. :(
I'm too ;-)
1.) Why do you use an additional 40 bytes buffer "SendBuf1[]" ?
With m_SendBuf.SendBuf_char[] you already have one !
2.) I suppose that you have "overloaded" your RAM with lots of
different buffers, resulting in a stack overflow by writing
to SendBuf1[]. Check your available RAM against all buffers
and variables you are using (of course there will be some other
stuff saved onto the stack also)
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: union and struct to speed up data handling: shootout - old_cow_yellow - Jul 25 14:38:31 2008
The code I wrote only needed a table of 16 bytes.
I did not pay attention to your second e-mail with the 512-byte table.
I did not study how your code uses it either. But I think you may need
a different 512-byte table depending on whether the buffer is aligned
with even address or not.
I want to keep my code simple to write, simple to understand, and
accomplish the task at hand correctly.
If I use c, I want the c-compiler to do the dirty work for me. I do
not want to do the dirty work for the compiler.
If my goal is not simple to achieve in c, I will use assembly instead.
And if that is not simple to achieve in assembly either, I will use
machine code.
--- In m...@yahoogroups.com, "timokirschke"
wrote:
>
> Hello,
>
> >
> > By the way, I was assuming a table of 16 bytes.
> > If you are willing to have a 256 words (512 bytes) table, you can
> > speed up a lot! Stay tuned.
> > yes, I'm curious, because I already use a 256 byte vector, as written
> before:
>
> const unsigned int ASCII_HEX_vector_int[256] = {
> 0x3030,0x3031,...,0x3045,0x3046,
> 0x3130,0x3131,...,0x3145,0x3146,
> ...
> 0x4630,0x4631,...,0x4645,0x4646};
> ---------------------------
>
> Next question. Using this construct:
>
> union PROTOCOL_SEND_DATA
> {
> char SendBuf_char[40];
> unsigned int SendBuf_int[20];
> } m_SendBuf;
>
> m_SendBuf.SendBuf_int[16] = ASCII_HEX_vector_int[SumRHist & 0xFF];
> m_SendBuf.SendBuf_int[17] = ASCII_HEX_vector_int[(SumRHist >> 8) &
> 0xFF];
>
> the data will not be aligned correctly. Example:
>
> The value of SumRHist is 0xABCD.
> m_SendBuf.SendBuf_int[17] will contain 0x0042 (ASCII B)
> m_SendBuf.SendBuf_int[16] will contain 0x4344 (ASCII CD)
> m_SendBuf.SendBuf_int[15] will contain 0xCD00
>
> but only after accessing the buffer, e.g.
> SendBuf1[34] = m_SendBuf.SendBuf_char[34];
>
> I am confused. :(
> It is a pity, because the two lines need only 22 cycles.
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling: shootout - timokirschke - Jul 25 15:22:30 2008
Hello,
--- In m...@yahoogroups.com, "bb_stefan"
wrote:
>
> I'm too ;-)
>
> 1.) Why do you use an additional 40 bytes buffer "SendBuf1[]" ?
> With m_SendBuf.SendBuf_char[] you already have one !
>
> 2.) I suppose that you have "overloaded" your RAM with lots of
> different buffers, resulting in a stack overflow by writing
> to SendBuf1[]. Check your available RAM against all buffers
> and variables you are using (of course there will be some other
> stuff saved onto the stack also)
>
Okay, that's possible, did not check this.
> I want to keep my code simple to write, simple to understand, and
> accomplish the task at hand correctly.
Of course, simple because my C-knowledge is not the best, as you
noticed. But I have to save every microsecond for the control tasks.
Assembler - I did it for approx. 2 years in my first MSP project,
don't want anymore.
------------------------------
I declared the union inside the FillSendBuf function for testing.
All other global variables are declared in a separate *.h file:
extern char SendBuf1[40];
extern const unsigned int ASCII_HEX_vector_int[256];
Definitions are in a separate *.c file:
char SendBuf1[40];
const unsigned int ASCII_HEX_vector_int[256] = {0x3030,...,0x4646};
If I try to do the union declaration and definition as global in the
both files I fail (says the compiler or linker alternating ;). If I
knew the way to do this, I could try the one-SendBuf1[40]-version.
Otherwise I will be satisfied with the working 49-cycle variant.
Thank you again for your help,
Regards, Timo
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: union and struct to speed up data handling: shootout - bb_stefan - Jul 25 16:53:32 2008
>
> If I try to do the union declaration and definition as global in the
> both files I fail (says the compiler or linker alternating ;). If I
> knew the way to do this, I could try the one-SendBuf1[40]-version.
> Otherwise I will be satisfied with the working 49-cycle variant.
>
Try this:
:
--------------------------------------------------------
union PROTOCOL_SEND_DATA
{
char SendBuf_char[40];
unsigned int SendBuf_int[20];
};
extern char SendBuf1[40];
...
extern union PROTOCOL_SEND_DATA m_SendBuf;
--------------------------------------------------------
:
--------------------------------------------------------
#include "globals.h"
char SendBuf1[40];
...
union PROTOCOL_SEND_DATA m_SendBuf;
--------------------------------------------------------
This should work... happy weekend ;-)
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )union and struct to speed up data handling: final version - timokirschke - Jul 28 12:46:30 2008
Hello,
Ende gut, alles gut...
After some marginal modifications this version seems to work=20
perfectly. The overall CPU time for the routine FillSendBuf()=20
including call melted down from 200=B5s to <60=B5s (8MHz F149).=20
Additionally it saves some RAM bytes.
Many thanks for your extensive help!
Best regards,
Timo
------------------------------------
PRO_1_6_decla.c=20
...
union SEND_DATA u_SendBuf;
...
PRO_1_6_decla.h=20
...
union SEND_DATA
{ =
=20
char SendBuf1[40];
unsigned int SendBuf1_int[20];
}; // xx_int[y] contains xx_char[2*y] and xx_char[2*y+1]
extern union SEND_DATA u_SendBuf;
...
PRO_1_6_interrupts.c
...
usart1_tx(void) __interrupt[UART1TX_VECTOR]
{
if (SendBufCnt1 > 0)
{
SendBufCnt1--; // decrement counter for bytes to be sent
TXBUF1 =3D u_SendBuf.SendBuf1[SendBufCnt1]; // fill TX buffer
}
else
LED7_OFF; // switch LED 7 off, signals data transmission end
IFG2 &=3D~ UTXIFG1; // reset interrupt flag
_EINT(); // Enable interrupts
}
...
PRO_1_6_Init.c=20
...
void FillSendBuf(unsigned int UARTx)
{
_EINT(); // Enable interrupts
if (UARTx =3D=3D 1)
// uplink format: STX 0D0A xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=20
CRC ETB ETX
// STX =3D 02hex, xxxx =3D measurement value (4 number bytes 0...9 =3D=20
30hex...39hex),
// 0D0A =3D CRLF, CRC =3D 2 byte hex CRC converted into ASCII, ETB =3D=20
17hex, ETX =3D 03hex
{
u_SendBuf.SendBuf1[38] =3D 0x02; // STX Start of text
u_SendBuf.SendBuf1[37] =3D 0x0D; // ASCII Carriage Return
u_SendBuf.SendBuf1[36] =3D 0x0A; // ASCII Line Feed
if ((Flags & RSS) =3D=3D RSS)
{ =
=20
u_SendBuf.SendBuf1_int[16] =3D ASCII_HEX_vector_int[SumRHist &=20
0xFF];
u_SendBuf.SendBuf1_int[17] =3D ASCII_HEX_vector_int[(SumRHist=20
>> 8) & 0xFF];
// needs 22 CPU cycles
...
u_SendBuf.SendBuf1_int[2] =3D ASCII_HEX_vector_int[SumUCO2 &=20
0xFF];
u_SendBuf.SendBuf1_int[3] =3D ASCII_HEX_vector_int[(SumUCO2 >>=20
8) & 0xFF];
}
SendCRC =3D 0;
SendCRC ^=3D u_SendBuf.SendBuf1[37]; // bytewise EXOR
SendCRC ^=3D u_SendBuf.SendBuf1[36];
...
SendCRC ^=3D u_SendBuf.SendBuf1[4];
u_SendBuf.SendBuf1_int[1] =3D ASCII_HEX_vector_int[SendCRC];
u_SendBuf.SendBuf1[1] =3D 0x17; // End of transmission block
u_SendBuf.SendBuf1[0] =3D 0x03; // ETX
SendBufCnt1 =3D 38; // counter for bytes to be sent
TXBUF1 =3D u_SendBuf.SendBuf1[SendBufCnt1]; // load first value=20
into send buffer
}
}=20
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )