?? calibration.c
字號:
adjust_gain (
(int32_t)**punit++,
(int32_t)**pxcal++,
(int32_t)*pcm++)
);
} while (--cnt);
}
// Adjust a CE gain parameter.
// 'unitmax': Either VMAX or IMAX; It's odd that the same adjustment
// routine works for both current and voltage, but it does.
// 'actual': Known quantity. LSB = units * 0.1 (same as VMAX and IMAX).
// 'measured': Same units as 'v0sqsum' or 'i0sqsum'.
static int32_t adjust_gain (int32_t unitmax, int32_t actual, int32_t measured)
{
int32_t gain;
// If noisy, near zero, measured may be negative.
// Returns 4 * sqrt(), rounded to nearest bit;
measured = (int32_t)(4. * sqrt ((float)labsx (measured)) + 0.5);
// Convert actual to RMS units.
#if M6520 || TRACE11
// Note, 162951 / 2 ~= 4 /(SQRT ((6.6952e-13 * 3600))), within 0.00002%.
// The resolution of the gain is +/-(LSB/2) = 1 / (2 * UNITY) ~= 0.003%.
// Rounds to the nearest bit. The 'unitmax' term is the rounding augend.
// This calculation is engineered so even the demo PCB's
// VMAX (600V) and IMAX (208A) will not cause overflow.
actual = (( actual * 162951L ) + unitmax ) / (unitmax * 2L);
#elif TRACE13
// Note, 68745 ~= 4 /(SQRT ((9.4045e-13 * 3600))), within 0.00005%.
// The resolution of the gain is +/-(LSB/2) = 1 / (2 * UNITY) ~= 0.003%.
// Rounds to the nearest bit. The 'unitmax / 2' term is the rounding augend.
// This calculation is engineered so even the demo PCB's..
// VMAX (600V) and IMAX (208A) will not cause overflow.
actual = (( actual * 68745L ) + ( unitmax / 2L )) / unitmax;
#else
#error unknown configuration
#endif
// 16384 = unity; calculation rounds to nearest bit
// "measured/2" is the rounding addend
// The resolution of the gain is +/-(LSB/2) = 1/(16384*2) ~= 0.003%
gain = (( actual * 16384L) + ( measured / 2L )) / measured;
// Keep resolution within possible range, return the revised gain.
return (max (min (gain, 32767L), -32767L));
}
#endif // AUTOCAL
#if NV_SELECT == NV_FLASH
#define MANY 0xFF
void cal_save (void) // Save the calibration.
{
if (CalibrationCount != MANY)
CalibrationCount++;
// Compute & store checksums.
LRC_Calc_NVR ((uint8x_t *) &Totals.Parms, sizeof (struct Parameters_t), TRUE);
chksum_ce ((int32x_t *) CE_PARM_BASE, CE_PARM_SIZE, TRUE);
CE_DISABLE();
memcpy_rx ((uint8r_t *) r_Parms, (uint8x_t*) &Totals.Parms, sizeof (struct Parameters_t) );
memcpy_rce ((uint8r_t *) CeData, (uint8x_t *) CE_PARM_BASE, CE_PARM_SIZE);
CE_ENABLE();
}
#elif NV_SELECT == NV_EEPROM
#define MANY 0xFF
void cal_save (void) // Save the calibration.
{
if (CalibrationCount != MANY)
CalibrationCount++;
// Compute & store checksums.
LRC_Calc_NVR ((uint8x_t *) &Totals.Parms, sizeof (struct Parameters_t), TRUE);
CE_DISABLE();
lrc_ce ((int32x_t *) CE_PARM_BASE, CE_PARM_SIZE, TRUE );
#if EEPROM
eeprom_enable(); // Enable non-volatile store.
memcpy_prce (
EEPROM_CALIBRATION,
(int32x_t *) CE_PARM_BASE,
CE_PARM_SIZE );
memcpy_prx (
EEPROM_CALIBRATION + (CE_PARM_SIZE * 4),
(uint8x_t *) &Totals.Parms,
sizeof (struct Parameters_t) );
eeprom_disable(); // Disable non-volatile store.
#endif
CE_ENABLE();
}
#else
#error unknown NV type
#endif // Validate the restored calibration.
#if NV_SELECT == NV_FLASH
bool cal_restore (void) // Restore the calibration.
{
bool ok = 1;
// get the CE's data
memcpy_cer (
(int32x_t *) CE_PARM_BASE,
&CeData[0],
CE_PARM_SIZE );
// get the MPU's data
memcpy_xr (
(uint8x_t *) &Totals.Parms,
(uint8r_t *) r_Parms,
sizeof (struct Parameters_t) );
#if CONSTANTS_DBG
// Make CE defaults visible to the AMD-51 ICE.
// Note, if this code is enabled, overlap errors occur in the link,
// but they do not cause defective operation.
get_ce_constants ();
#endif
// test the data to see if it's valid
ok &= LRC_Calc_NVR (
(uint8x_t *) &Totals.Parms,
sizeof (struct Parameters_t),
FALSE);
ok &= lrc_ce (
(int32x_t *) CE_PARM_BASE,
CE_PARM_SIZE,
FALSE);
if (!ok)
Status |= CAL_BAD; // dating, etc. is in the main loop
else
Status &= ~CAL_BAD;
CE_ENABLE();
return ok;
}
#elif NV_SELECT == NV_EEPROM && EEPROM
bool cal_restore (void) // Restore the calibration.
{
bool ok = 1;
enum EEPROM_RC data *state;
#if EEPROM
eeprom_enable(); // Enable non-volatile store.
CE_DISABLE();
// get the CE's data
ok &= memcpy_cepr (
(int32x_t *) CE_PARM_BASE,
EEPROM_CALIBRATION,
CE_PARM_SIZE);
// get the MPU's data
state = memcpy_xpr (
(uint8x_t *) &Totals.Parms,
EEPROM_CALIBRATION + (CE_PARM_SIZE * 4),
sizeof (struct Parameters_t)
);
ok &= eeprom_ok (state);
eeprom_disable(); // Disable non-volatile store.
#endif
#if CONSTANTS_DBG
// Make CE defaults visible to the AMD-51 ICE.
// Note, if this code is enabled, overlap errors occur in the link,
// but they do not cause defective operation.
get_ce_constants ();
#endif
// test the data to see if it's valid
ok &= LRC_Calc_NVR (
(uint8x_t *) &Totals.Parms,
sizeof (struct Parameters_t),
FALSE);
ok &= lrc_ce (
(int32x_t *) CE_PARM_BASE,
CE_PARM_SIZE,
FALSE);
memset_ce(&apulsew,0); // do not restore the pulse rates
memset_ce(&apulser,0); // they cause spurious pulses at start-up
if (!ok)
Status |= CAL_BAD; // dating, etc. is in the main loop
else
Status &= ~CAL_BAD;
CE_ENABLE();
return ok;
}
// copy data from EEPROM to the CE's data area
bool memcpy_cepr (int32x_t * pDst, uint16_t pSrc, uint16_t len)
{
int32_t xdata nv_data;
enum EEPROM_RC data *state;
bool ok = 1;
for(; len != 0; --len)
{
state = memcpy_xpr ((uint8x_t *)&nv_data, pSrc, sizeof (int32_t));
ok &= eeprom_ok (state);
memset_ce (pDst++, nv_data);
pSrc += sizeof (int32_t);
}
return ok;
}
// copy data from the CE's data area to EEPROM
void memcpy_prce (uint16_t pDst, int32x_t * pSrc, uint16_t len)
{
int32_t xdata nv_data;
for(; len != 0; --len)
{
nv_data = memget_ce (pSrc++);
memcpy_prx (pDst, (uint8x_t *)&nv_data, sizeof (int32_t));
pDst += sizeof (int32_t);
}
}
#else
#error unknown NV type
#endif
/***************************************************************************
* History:
* $Log: calibration.c,v $
* Revision 1.36 2006/10/13 00:51:09 tvander
* Removed compile options for 6530, 6515;
* renamed 6511 and 6513 to trace11 and trace13;
* Binary verified unchanged from previous version.
*
* Revision 1.35 2006/09/09 01:12:47 gmikef
* *** empty log message ***
*
* Revision 1.34 2006/08/30 02:09:42 gmikef
* *** empty log message ***
*
* Revision 1.33 2006/08/18 23:23:27 tvander
* Added calibration.c back to build in order to cope with differential meter
* equations, which it can calibrate, while caphased.c cannot.
*
* Revision 1.31 2006/04/12 00:26:26 tvander
* Math is right for current and voltage gains. Phase number is right for my test signal, i.e. zero phase. Needs testing on a real meter.
*
* Revision 1.30 2006/03/06 03:36:33 Michael T. Fischer
* More 6530 prep.
*
* Revision 1.29 2006/03/03 11:29:16 Michael T. Fischer
* Prep for 6530 LCD, etc.
*
* Revision 1.28 2006/02/08 22:39:11 gmikef
* *** empty log message ***
*
* Revision 1.27 2006/02/08 03:43:24 tvander
* Made "import" the default power measurement mode, rather than net-metering
*
* Revision 1.26 2006/01/26 01:07:15 tvander
* Debugged calibration. It actually calibrates correctly.
*
* Revision 1.25 2006/01/25 01:04:23 tvander
* Calibration compiles but does not calibrate
*
* Revision 1.24 2006/01/11 00:50:57 gmikef
* *** empty log message ***
*
* Revision 1.22 2006/01/10 04:04:06 gmikef
* Added PDATA support for CE Outputs.
*
* Revision 1.21 2006/01/04 04:47:51 gmikef
* Switched RMS and VA calculations to use floating point. (and Calibration).
*
* Revision 1.19 2005/12/09 20:01:48 tvander
* Clean build
*
* Revision 1.18 2005/12/09 19:42:09 tvander
* Calibration save and restore now work in flash, and save and restore temp_nom
* in the 6520's temp_raw value for the CE variables.
*
* Revision 1.17 2005/12/07 02:30:46 tvander
* Added SO command.
* Fixed uninitialized variable in tempoerature compensation of calibration.
* Added xtal_freq to 6521 options, and alternative brownout baud rate
* to reg652x.h
* Rolled date.
*
* Revision 1.16 2005/12/07 01:43:51 tvander
* tn in temperature compensation was not being initialized.
*
* Revision 1.15 2005/10/31 17:38:03 tvander
* Includes improved EEPROM code with uwire.
* Clean build, all build trees (Thank-you, Mike!)
*
* Revision 1.14 2005/10/15 02:18:08 tvander
* Improved so compensation and extended trim can be separate options.
* Also improved the flash version to save a nominal temperature.
*
* Revision 1.13 2005/10/06 23:36:08 tvander
* Fixed calibration for 6520-- the nominal temperature is shifted left by
* 9 bits.
*
* Revision 1.12 2005/10/06 23:01:36 tvander
* Fixed I-147, default temperature compensation.
*
* Revision 1.11 2005/09/22 23:45:13 tvander
* Clean build all models and unit tests, updated copyright to be fore Teridian
*
* Revision 1.10 2005/08/30 18:14:24 gmikef
* *** empty log message ***
*
* Revision 1.9 2005/08/20 01:32:47 gmikef
* *** empty log message ***
*
* Revision 1.8 2005/08/19 01:04:43 gmikef
* *** empty log message ***
*
* Revision 1.7 2005/08/12 21:54:55 tvander
* Calibration compiles with the EEPROM option.
*
* Revision 1.6 2005/08/12 06:00:27 gmikef
* Added MPU temperature compensation for GAIN_ADJ.
* Added changes to support new CE 6521 code.
*
* Revision 1.5 2005/08/10 02:00:29 gmikef
* *** empty log message ***
*
* Revision 1.4 2005/07/14 20:15:50 tvander
* ce code concentrated in ce.c
* ce interface concentrated in ce652x.c, .h
* Fixed 0-length read or write using flag protocol.
* display.c is out of the build
* kwh_initialize now reads the LRC.
*
* Revision 1.3 2005/06/16 18:58:43 tvander
* Updates the debug values
*
* Revision 1.2 2005/06/10 22:57:07 tvander
* Uses macros to reset watchdog and clear IE and RTC interrupts
* Includes 6515 improvements in register defs.
*
* Revision 1.1 2005/05/13 00:34:46 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.3 2005/04/30 02:12:43 gmikef
* *** empty log message ***
*
*
* Revision 1.2 2005/04/27 23:40:48 gmikef
* Some MATH rountines now use 'idata'.
* Added MATH_FAST flag to 'options.h".
* Changed "6521B.Uv2" to max optimization.
*
* 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. *
***************************************************************************/
#endif /* calibration.c */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -