CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Make8() function using a variable as the offset !!! SOLVED

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

Make8() function using a variable as the offset !!! SOLVED
PostPosted: Tue Jun 20, 2017 3:00 pm     Reply with quote

Hi
I am using Version PCM 5.52

Are you not allowed to use a variable for the offset?

From Manual
make8( )
Syntax: i8 = MAKE8(var, offset)
Parameters: var is a 16 or 32 bit integer.
offset is a byte offset of 0,1,2 or 3.
Returns: An 8 bit integer
Function: Extracts the byte at offset from var. Same as: i8 = (((var >> (offset*8)) &0xff)
except it is done with a single byte move.
Availability: All devices
Requires: Nothing
Examples: int32 x;
int y;
y = make8(x,3); // Gets MSB of x

Using their example as shown i8 = (((var >> (offset*8)) & 0xff

Code:

int32 var;
int8 i8[4], i;

var = 123456789;

for (i = 0; i < 4; i++)
{
    i8[i] = (((var >> (i*8)) & 0xff;
}

This works.

Code:

for (i = 0; i < 4; i++)
{
    i8[i] = make8(var, i);
}

This is an ERROR: Invalid parameters for built in function.

The above example does nothing, it will just show the error!


I thought make8() function would have saved me some code space?

Any Thoughts?

Thanks
Jerry


Last edited by Jerry I on Wed Jun 21, 2017 10:25 pm; edited 1 time in total
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 3:27 pm     Reply with quote

unroll it and it is faster and takes fewer instructions.

Code:

i8[0] = make8(var,0);
i8[1] = make8(var,1);
i8[2] = make8(var,2);
i8[3] = make8(var,3);
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 12:54 am     Reply with quote

It should make it plain that offset is a constant. However if you think about it a single byte move implicitly must involve a constant, since otherwise there will need to be calculations to find the byte. As Gaugeguy says 'unroll it'.
The same applied to lots of things where variables are allowed. So (for instance):
Code:

bit_set(var,n);

Where 'n' is a constant, codes as a single instruction. However using a variable, one single call codes to perhaps 20 instructions.... Sad

This is an area where 'tidy code', may not result in efficient code.
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Wed Jun 21, 2017 9:34 am     Reply with quote

In embedded systems when coding in C the prettiest or most "standard" routines are not always the most efficient. This is where understanding the assembler code can make for a more efficient routine in C. CCS does a lot of special functions like make8 that allows C code to be written as efficiently as assembler.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Jun 21, 2017 11:23 am     Reply with quote

If this was facebook- the above would merit a very smiley faced 'like'
Jerry I



Joined: 14 Sep 2003
Posts: 96
Location: Toronto, Ontario, Canada

View user's profile Send private message

Make8() function using a variable as the offset !!! SOLVED
PostPosted: Wed Jun 21, 2017 10:24 pm     Reply with quote

Hi All,

Thanks for the replies.

My problem is that I am transmitting a 32 bit integer via the i2c bus within the #int_ssp interrupt.

I transmit 1 byte at a time and the index = i2c state & 7 would have been the offset for the make8() function to send 4 bytes of 32 bit integer.

I will try something like this, possibly save me some code.

Code:


////  NEW IDEA  ////

if (state >= 0x80)

index = state & 7
switch (index)
{
case:0
    i2c_write(make8(32BitNumber, 0));
    break;
case:1
    i2c_write(make8(32BitNumber, 1));
    break;
case:2
    i2c_write(make8(32BitNumber, 2));
    break;
case:3
    i2c_write(make8(32BitNumber, 3));
    break;
}


/// This is the original code  ////

if (state >= 0x80)

index = state & 7
i2c_write((int8)32BitNumber) >> 8 * index;


I just did a check.

The original code took about 35 lines of code, but these 35 lines execute 4 times.

The above code idea using the switch/case statement overall took more code about 8 extra lines. But each case within the switch was about 11 line which made the execution time much faster.

Very Happy Exclamation Idea

Thanks again for all the great help.

-Jerry
temtronic



Joined: 01 Jul 2010
Posts: 9226
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jun 22, 2017 7:13 pm     Reply with quote

I appreciate the time and effort 'Mr. T' took to cut and compile code to show HOW and WHY it's important to understand how a PIC works. While most don't know 'dreaded' machine code, aka Assembler aka the 'Instruction Set for PICs' this one example shows how a programmer can truly benefit from reading a few chapters and experimenting.

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group