PDA

View Full Version : Embedded C - 32 bit math for Atmel


IbarraE
02-02-2011, 06:11 PM
This is a 32bit math library using compiled C code for the ATmega128RFA1 and RF200 platforms. This library can be used to do large number computations efficiently.

jcwoltz
03-12-2011, 03:50 PM
Thank you IbarraE!

Around here, it seems people take, but do not give back. So Thank you for doing this and posting it!

jcwoltz
07-01-2011, 05:04 PM
@IbarraE

could you please email me at jwoltz AT gmail dot com

I have some questions for you.
Thank you,
J.C. Woltz

travisf
02-22-2012, 08:11 AM
This is a 32bit math library using compiled C code for the ATmega128RFA1 and RF200 platforms. This library can be used to do large number computations efficiently.

Would you mind posting your C code as well? I'd like to port this to 8051.

IbarraE
02-22-2012, 08:46 AM
I would post the source file, but it's also full of other functions I wrote for different purposes. There is not really anything special about the functions, and honestly they could probably be made better. You'll notice that a couple things are done differently than you might expect. I remember some things didn't work the way I expected, which probably only requires a simple change of the compiler optimization settings.


//call(Add_32,addStr)
void Add_32(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len;
U32 *Val1;
U32 *Val2;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;

// Load string into longs
Val1 = (U32*)str;
Val2 = (U32*)(str+4);

// Add longs
*Val1 = *Val2 + *Val1;

}

//call(Sub_32,subStr)
void Sub_32(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len;
U32 *Val1;
U32 *Val2;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;

// Load string into longs
Val1 = (U32*)str;
Val2 = (U32*)(str+4);

// Subtract longs
*Val1 = *Val2 - *Val1;

}

//call(Mult_32,multStr)
void Mult_32(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len;
U32 *Val1;
U32 *Val2;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;

// Load string into longs
Val1 = (U32*)(str);
Val2 = (U32*)(str+4);

// Multiply longs
*Val1 = (*Val2 * *Val1)&0xFFFFFFFF;

}

//call(Div_32,divStr)
void Div_32(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len;
U32 *Val1;
U32 *Val2;
long temp;
U32 divCounter = 0;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;

// Load string into longs
Val1 = (U32*)str;
Val2 = (U32*)(str+4);

if (*Val1 == 0)
1;
else {
temp = *Val2;
// Divide longs
while (temp >= *Val1) {
temp -= *Val1;
divCounter++;
}
*Val1 = divCounter;
}

}

//call(Shift_32,shiftStr)
void Shift_32(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len;
U32 *Val1;
U32 *Val2;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;

// Load string into longs
Val1 = (U32*)str;
Val2 = (U32*)(str+4);

// Divide longs
*Val1 = (*Val2 / *Val1)&0xFFFFFFFF;

}

//call(StrToLong,Str)
void StrToLong(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len, i, i2;
U16 *Val1;
U16 temp;
U8 OFFSET = 2;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;
Val1 = (U16*)(str+4);
*Val1 = 0;


for (i = OFFSET; i < len+1; ++i)
{
i2 = 0;
temp = (str[len-i]-48);
if (temp < 10) {
while ((i2 + OFFSET+1) < i){
temp = temp *10;
i2++;
}
*Val1 += temp;
}
}
}

//call(StrToLong,Str)
void StrToLong2(unsigned char nArgs, unsigned char *stack, unsigned char *unused)
{
U8 *str, len, i, i2;
U32 *Val1;
U32 temp;
U8 OFFSET = 4;

// Fetch a pointer to str
str = (U8 *) ((stack[-1] << 8) | stack[-2]);
len = *str++;
Val1 = (U32*)(str+len-4);
*Val1 = 0;


for (i = OFFSET; i < len+1; ++i)
{
i2 = 0;
temp = (str[len-i]-48);
if (temp < 10) {
while ((i2 + OFFSET+1) < i){
temp = temp *10;
i2++;
}
*Val1 += temp;
}
}
}

travisf
02-22-2012, 09:12 AM
Thanks. It looks like your AVR compiler is a lot more efficient than Keils 8051 compiler. Just for the simple addition example, I'm getting over 400 characters in my string.

IbarraE
02-22-2012, 09:37 AM
Yes, the AVR core itself is significantly more efficient than the 8051. If you are trying to do this on the SiLabs processor, I would be very curious to see your results. I was never able to get even the simplest of embedded C functions to work on it.

Jheath
02-22-2012, 10:14 AM
You will probably need to do any 8051 programming in assembly code.

travisf
02-22-2012, 10:17 AM
Could there be an issue of the C code using the same memory space as existing running code?

hagster
03-03-2012, 04:35 AM
Has anyone compiled this for the sm700 (MC13224)?

Jheath
03-04-2012, 04:56 PM
Could there be an issue of the C code using the same memory space as existing running code?

This and attempting to reach out to library functions (math, helper, or other) that are not within the explicitly defined code. Some compiler optimizations might be needed to ensure this doesn't happen.