📄 mmath.h
字号:
/***************************************************************************
* This code and information is provided "as is" without warranty of any *
* kind, either expressed or implied, including but not limited to the *
* implied warranties of merchantability and/or fitness for a particular *
* purpose. *
* *
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
***************************************************************************/
//**************************************************************************
// DESCRIPTION: 71M652x Meter MATH library.
//
// AUTHOR: MTF
//
// HISTORY: See end of file.
//**************************************************************************
// File: MMATH.H
//
#ifndef MATH_H
#define MATH_H 1
//===========================================================================//
// 'add', 'add_1', 'add_2', 'add8_8', 'add8_4', 'abs_x'..
// 'sub', 'sub_1', 'sub8_8', 'sub8_4' work w/ 2s-complement integers.
//
// All other functions work with non-negative values.
// All non-void routines return 'carry' or 'borrow'.
//===========================================================================//
// Binary addition of 8n-bit 'x'; Also works w/ 2s-complement numbers.
// to 8n-bit 'y'.
// *x += *y; returns carry.
int8_t add (uint8x_t *x, uint8p_t *y, uint8_t n);
// Binary addition of 8-bit 'y_',
// to 8n-bit 'x'.
// *x += y_; returns carry.
int8_t add_1 (uint8x_t *x, uint8_t n, int8_t y_);
#if PULSE_CNT
// Binary addition of 16-bit 'y_',
// to 8n-bit 'x'.
// *x += y_; returns carry.
int8_t add_2 (uint8x_t *x, uint8_t n, int16_t y_) small reentrant;
#endif
// Binary addition of 64-bit 'y'; Also works w/ 2s-complement numbers.
// to 64-bit 'x'.
// *x += *y;
void add8_8 (uint8x_t *x, uint8x_t *y);
// Binary addition of 32-bit 'y'; Also works w/ 2s-complement numbers.
// to 64-bit 'x'.
// *x += *y;
void add8_4 (uint8x_t *x, uint8p_t *y);
//===========================================================================//
// Binary subtraction of 8n-bit 'y'; Also works w/ 2s-complement numbers.
// from 8n-bit 'x'.
// *x -= *y; returns borrow.
int8_t sub (uint8x_t *x, uint8p_t *y, uint8_t n);
// Binary subtraction of 8-bit 'y_',
// from 8n-bit 'x'.
// *x -= y_; returns the borrow.
int8_t sub_1 (uint8x_t *x, uint8_t n, int8_t y_);
// Binary subtraction of 16-bit 'y_',
// from 8n-bit 'x'.
// *x -= y_; returns the borrow.
int8_t sub_2 (uint8x_t *x, uint8_t n, int16_t y_);
// Binary subtraction 64-bit 'y'; Also works w/ 2s-complement numbers.
// from 64-bit 'x'.
// *x -= *y;
void sub8_8 (uint8x_t *x, uint8p_t *y);
// Binary subtraction 32-bit 'y'; Also works w/ 2s-complement numbers.
// from 64-bit 'x'.
// x -= y;
void sub8_4 (uint8x_t *x, uint8p_t *y);
//===========================================================================//
// Binary multiplication of 8m-bit 'y',
// and 8n-bit 'x',
// leaving result in 8(n+m)-bit 'w'; 't' is a scratchpad for partial products.
// *w = *x * *y;
void multiply (uint8x_t *w, uint8x_t *x, uint8_t m, uint8p_t *y, uint8_t n, uint8p_t *t);
// Multiply and accumulate positive 8n-bit partial product into 'w'.
// Multiplication of 8n-bit 'x',
// and 8-bit 'y_', accumulated positive into 'w'.
// *w += *x * y_; 't' is a scratchpad for partial products.
uint8_t macp (uint8x_t *w, uint8x_t *x, uint8_t n, uint8_t y_, uint8p_t *t);
// Binary multiplicaton of 8n-bit 'x',
// by 8-bit 'y_',
// leaving result in 8n-bit 'w' with a returned carry.
// w = x * y_; 't' is a scratchpad for partial products.
uint8_t multiply_1 (uint8p_t *w, uint8x_t *x, uint8_t n, uint8_t y_);
//---------------------------------------------------------------------------//
// Binary multiplicaton of 64-bit 'x',
// by 32-bit 'y'.
// leaving result in 96-bit 'w'.
// *w = *x * *y;
void multiply_8_4 (uint8x_t *w, uint8x_t *x, uint8p_t *y);
// Multiply and accumulate positive 64-bit partial product into 'w'.
// *w += *x * y_; 't' is a scratchpad for partial product.
uint8_t macp8 (uint8x_t *w, uint8x_t *x, uint8_t y_, uint8p_t *t);
// Binary multiplicaton of 64-bit 'x',
// by 8-bit 'y_',
// leaving result in 64-bit 'w' with a returned carry.
// *w = *x * y_;
uint8_t multiply_8_1 (uint8p_t *w, uint8x_t *x, uint8_t y_);
//---------------------------------------------------------------------------//
// Binary multiplicaton of 32-bit 'x',
// by 32-bit 'y',
// leaving result in 64-bit 'w'.
// *w = *x * *y;
void multiply_4_4 (uint8x_t *w, uint8x_t *x, uint8p_t *y);
// Multiply and accumulate positive 32-bit partial product into 'w'.
// *w += *x * y_; 't' is a scratchpad for partial product.
uint8_t macp4 (uint8x_t *w, uint8x_t *x, uint8_t y_, uint8p_t *t) ;
// Binary multiplicaton of 32-bit 'x',
// by 8-bit 'y_',
// leaving result in 32-bit 'w' with a returned carry.
// *w = *x * y_;
uint8_t multiply_4_1 (uint8p_t *w, uint8x_t *x, uint8_t y_);
//---------------------------------------------------------------------------//
// About twice as fast as general multiply.
// Binary squaring of 8n-bit 'x',
// leaving result in 16n-bit 'w'.
// *w = *x ** 2; Square n-byte 'x' into a 2n-byte 'w'.
void square (uint8x_t *w, uint8p_t *x, uint8_t n);
//===========================================================================//
// Binary divide of unnormalized 8m-bit 'u',
// by unnormalized 8n-bit 'v',
// leaving quotient & remainder back in 'u'.
// *u /= *v; 't' = temporary storage, allocate at least 'm' bytes.
// The dividend 'u' becomes the quotient and remainder;
// Remainder is in the low order part of 'u'.
// divide() returns how many bytes are in the quotient.
uint8_t divide (uint8x_t *u, uint8_t m, uint8x_t *v, uint8_t n, uint8p_t *t);
// Normalize 8m-bit dividend 'u' and 8n-bit divisor 'v' so division is possible.
// It makes the divisor 'v' such that the first digit is..
// ..greater than half the first digit of the dividend 'u'.
// 't' = temporary storage, allocate at least 'm' bytes.
uint8_t normalize (uint8x_t *u, uint8_t m, uint8x_t *v, uint8_t n, uint8p_t *t);
// Takes a 64-bit 'w',
// Returns a 32-bit number containing the least significant 6 decimal digits.
uint32_t Mod10_6 (uint8x_t *w);
// Binary divide of normalized 8m-bit 'u',
// by normalized 8n-bit 'v',
// leaving quotient & remainder back in 'u'.
// *u /= *v; like divide, except it assumes everything is already normalized.
void divide_ (uint8x_t *u, uint8_t m, uint8p_t *v, uint8_t n, uint8p_t *t);
// Multiply and accumulate negative, a 32-bit partial product 'u'.
// (uint32x_t) u += (uint32i_t) v * (uint8_t) q_; 't' is a scratchpad for partial product.
// *u -= *v * *q_; 'q_' is the intermediate quotient, a single byte,
uint8_t macn (uint8x_t *u, uint8p_t *v, uint8_t n, uint8_t q_, uint8p_t *t);
// *u /= v;
void divide_1 (uint8x_t *u, uint8_t n, uint8_t v);
//---------------------------------------------------------------------------//
// Shift (in-place) n-byte 'x' to the right by 's' bits.
void shift_right (uint8x_t *x, uint8_t n, uint8_t s);
// Calculates the absolute (positive) value of 'x'.
void abs_x (uint8x_t *x, uint8x_t *x0, uint8_t n);
// Calculates the twos complement value of 'x'.
void complement_x (uint8x_t *x, uint8x_t *x0, uint8_t n);
// Returns the log base 2 of 'k'.
uint8_t log2 (uint16_t k) small reentrant;
// returns the maximum of a and b
uint32_t lmax (uint32_t a, uint32_t b) small reentrant;
// returns the minimum of a and b
uint32_t lmin (uint32_t a, uint32_t b) small reentrant;
// returns the absolute (positive) value of a
int32_t labsx (int32_t a) small reentrant;
//---------------------------------------------------------------------------//
// Domain of following equation is |tan(theta)| <= 1.
//
// atan(tan(theta)) = -3/10 + 62 * tan(theta) - 100/6 * tan(theta)^2 degrees.
// accurate to less than one degree (about 0.1 degree)
//
// atan(y/x) = -3/10 + 62 * (y/x) - 100/6 * (y/x)^2 degrees.
// = -3/10 + (y/x) * [62 - 100/6 * (y/x)] degrees.
// = -3/10 + (y/x) * [62 - 50/3 * (y/x)] degrees.
//
// atan(y/x) * 1000 = [62000 - ((y * 1000 / x) * 50 / 3)] * y / x - 300 mDegrees.
// = [62000 - ((y * 50000 / x) / 3)] * y / x - 300 mDegrees.
// = [62000 - (y * 16667 / x)] * y / x - 300 mDegrees.
//
// Scale y and x so that y < x < 2^16.
//
uint32_t latan2 (int32_t sy, int32_t sx);
//---------------------------------------------------------------------------//
// Takes the square root of 64-bit 'x' and produces 32-bit result.
uint32_t sqrt8_4 (uint8p_t *x);
// Returns the 32-bit square root of the 32-bit argument 'x'.
// The most significant two bytes of result are the integer part,
// the least significant two bytes of result are the fractional part.
uint32_t sqrt4_4 (int32_t x); // Sqrt (y << 16).
// Returns the 16-bit square root of the 32-bit argument 'x'.
uint16_t sqrt4_2 (int32_t x);
// Shift 64-bit 'x' right 1 bit.
void shift_right8_1 (uint8x_t *x);
// Shift 64-bit 'x' right 2 bits.
void shift_right8_2 (uint8x_t *x);
// converts 64-bit number to float. Has up to 40 bits of underflow!!
float s2f (uint8x_t *s);
// standard C99 library function not provided by Keil
// converts a float to the nearest long integer.
// Keil's float->long conversion has some defects at boundaries.
// e.g. INT32_MIN (0x8000000) doesn't convert correctly to float.
long lroundf (float f);
#endif
/***************************************************************************
* History
* $Log: mmath.h,v $
* Revision 1.6 2006/09/09 01:15:34 gmikef
* *** empty log message ***
*
* Revision 1.5 2006/08/30 02:09:59 gmikef
* *** empty log message ***
*
* Revision 1.4 2006/04/12 00:30:41 tvander
* Added code for phased calibration, 6513 compiled with equations 3 and 4.
*
* Revision 1.3 2006/03/06 03:42:47 Michael T. Fischer
* More 6530 prep.
*
* Revision 1.2 2006/01/10 04:13:01 gmikef
* Added PDATA support for CE Outputs.
*
* Revision 1.1 2006/01/04 04:47:57 gmikef
* Switched RMS and VA calculations to use floating point. (and Calibration).
*
* Revision 1.14 2005/09/22 23:45:27 tvander
* Clean build all models and unit tests, updated copyright to be fore Teridian
*
* Revision 1.13 2005/08/10 02:06:11 gmikef
* *** empty log message ***
*
* Revision 1.12 2005/06/25 02:04:45 tvander
* Integrated pulse counting
*
* Revision 1.11 2005/06/17 22:54:46 tvander
* Separated imports and exports.
* Some imports and exports were not being updated.
*
* Revision 1.10 2005/05/13 00:34:48 tvander
* 6511/32k works
* Integrated and debugged self-calibration.
* The build has one unused segment, and no other errors or warnings.
* default LCD and pulse displays appear OK.
* EEPROM, software timers and hardware timers are all integrated.
*
* Revision 1.9 2005/05/04 01:00:53 gmikef
* *** empty log message ***
*
* Revision 1.10 2005/05/03 22:29:41 gmikef
* *** empty log message ***
*
* Revision 1.9 2005/05/03 02:18:56 gmikef
* *** empty log message ***
*
* Revision 1.8 2005/05/02 18:03:20 gmikef
* *** empty log message ***
*
* Revision 1.8 2005/04/30 02:19:22 gmikef
* *** empty log message ***
*
* Revision 1.7 2005/04/28 19:12:27 tvander
* Comments only! Restored history comments.
*
* Revision 1.6 2005/04/27 23:47:43 gmikef
* Some MATH rountines now use 'idata'.
* Added MATH_FAST flag to 'options.h".
* Changed "6521B.Uv2" to max optimization.
*
* Revision 1.5 2005/04/21 02:07:51 gmikef
* *** empty log message ***
*
* Revision 1.4 2005/04/20 00:10:41 tvander
* Revised the comments. Hopefully they're more readable.
*
* Revision 1.3 2005/04/19 18:08:15 tvander
* First working flag interface.
*
* Revision 1.2 2005/04/13 16:36:28 tvander
* Removed spurious text
*
* Revision 1.1 2005/04/12 21:53:35 tvander
* Library and math, compiles ok, added some comments (needs more)
*
* Copyright (C) 2005 Teridian Semiconductor Corp. All Rights Reserved. *
* this program is fully protected by the United States copyright *
* laws and is the property of Teridian Semiconductor Corporation. *
***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -