I am trying to find an efficient way to calculate LOG10(), POW() (only POW(10,?)) and SQRT(). Or, use tables... my program is far too slow on an embedded controller that has no floating point core.

I need to step a log value by a linear one, or in other words, step RF levels in dBm by volts.

The formula to convert volts to dBm is:

dBm = 10 * log(((V^2)/50ohm)/1mW)

Or simplified: dBm = 10 * log10(20 * V * V)

and dBm to volts:

volts = 0.223607 * sqrt(pow(10, dBm / 10))

Where 0.223.. = Volts at 1mW

Now dBm I have multiplied by 10,000 to use integer math rather than double-precision floats which speeds up text conversions considerably for display. For these routines I have to convert back to double for the built-in C routines, which is where my time gets chewed up, almost 100mS to step once!

I have found some good, fast sqrt() integer routines at http://www.azillionmonkeys.com which I have used in other programs before like DFTs and FFTs, but was pointless here until I figured out how to get all results into integer form with decent precision.

Currently this is the long-hand version of code (just a portion of a much larger multiple units conversion routine):

- Code: Select all
`result = dBm10ktoVolts(level->dBm10k); //Convert to volts`

result += levelStepV; //Step by volts

level->dBm10k = VoltstodBm10k(result); //Convert back to dBm10k

- Code: Select all
`/************ Level conversion routines, common base of dBm*1000 *****************/`

/******* dB are in the format of -000.0000dB, so a fixed dP at place 4 **/

/******* uV are in the format of 0uV, so no dP or 000.000000V**/

/******* uW are in the format of 000,000,000uW, so no dP, or 000.000000W ****/

double dBm10ktoVolts(INT32 dBm10k){

return(0.22360679774997896964 * sqrt(pow(10.0, dBm10k / 100000.0)));

}

INT32 VoltstodBm10k(double Volts){

return(100000.0 * log10(20.0 * Volts * Volts)); //Convert to dBm * 1000 (10 * 1000 for the 10000)

}

Anyone have any linkage for integer-based log10 or pow routines? I could go from there. Otherwise, any clever ideas I can get started on?

Log10 can be easy in integer math since the value repeats between powers of 10, and you just need a table lookup and some interpolation to get close... but Exp(10,?) seems to have my poor brain befuddled.

Thanks for some ideas...

See what old PC programmers had to deal with in SX/DX days? Poor guys...

-LS