📄 ce.c
字号:
// Interrupt priorities are set in main.
EX_XFER_RTC = TRUE; // Enable external interrupt 6
CE2 |= EX_XFER; // enable the xfer interrupt
#ifdef WD_RTC
wd_create (WD_RTC); // if wd.h says, watch this interrupt
#endif
#ifdef WD_XFER_BUSYZ
wd_create (WD_XFER_BUSYZ); // if wd.h says, watch this interrupt
#endif
// clear both flags at once, forcing an edge to cause interrupt 6
// If this is not done, the unit can deadlock at reset.
IFLAGS &= ~(IE_XFER_ | IE_RTC_);
// CE is enabled in main.c after CE constants
// are read from nonvolatile memory
#ifdef OSCOPE_H
OSCOPE_INIT;
#endif
irq_enable (); // end of a critical section
}
// Copy data from CODE space to the CE.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_cer (int32x_t *pDst, int32r_t *pSrc, uint8_t len)
{ // Never any overlapped data.
do {
memset_ce (pDst++, *pSrc++);
} while (--len);
}
#if EXTRAS
// Copy data from the IDATA to the CE.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_cei (int32x_t *pDst, int32i_t *pSrc, uint8_t len)
{ // Never any overlapped data.
do {
memset_ce (pDst++, *pSrc++);
} while (--len);
}
#endif
#if EXTRAS
// Copy data from the CE to IDATA.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_ice (int32i_t *pDst, int32x_t *pSrc, uint8_t len)
{ // Never any overlapped data.
do {
*pDst++ = memget_ce (pSrc++);
} while (--len);
}
#endif
#if EXTRAS
// Copy data from the PDATA to the CE.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_cep (int32x_t *pDst, int32p_t *pSrc, uint8_t len)
{ // Never any overlapped data.
do {
memset_ce (pDst++, *pSrc++);
} while (--len);
}
#endif
#if EXTRAS
// Copy data from the CE to PDATA.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_pce (int32p_t *pDst, int32x_t *pSrc, uint8_t len)
{ // Never any overlapped data.
do {
*pDst++ = memget_ce (pSrc++);
} while (--len);
}
#endif
#pragma save
#pragma NOAREGS
// Set CE to value.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memset_ce (int32x_t *pDst, int32_t src) small reentrant
{ // Never any overlapped data.
uint8_16_32_t Src;
// variables to save interrupt state for a CE transfer
CE_XFER_DEFINES;
// save a snapshot of the state
CE_XFER_SAVE;
Src.l = (uint32_t)src;
BEGIN_CE_CRITICAL_SECTION; // Disable CE interrupts.
*((uint8x_t *) pDst) = Src.c[ HI_HI ]; ((uint8x_t *) pDst)++;
*((uint8x_t *) pDst) = Src.c[ HI_LO ]; ((uint8x_t *) pDst)++;
*((uint8x_t *) pDst) = Src.c[ LO_HI ]; ((uint8x_t *) pDst)++;
CLK_STRETCH; // Change stretch to '6' equivalent.
*((uint8x_t *) pDst) = Src.c[ LO_LO ];
CLK_RELAX; // Back to default value.
END_CE_CRITICAL_SECTION; // Reenable CE interrupts.
}
#pragma restore
#if FLAG || PULSE_SOURCE || FREQUENCY || MAIN_EDGE_COUNT || VOLTAGE_PHASES || SHUNTS || PULSE_SOFT || (CAL_SAVE && NV_SELECT == NV_EEPROM) || BATTERY_TEST
#pragma save
#pragma NOAREGS
// Get value from the CE.
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
int32_t memget_ce (int32x_t *pSrc) small reentrant
{ // Never any overlapped data.
uint8_16_32_t Dst;
// variables to save interrupt state for a CE transfer
CE_XFER_DEFINES;
// save a snapshot of the state
CE_XFER_SAVE;
BEGIN_CE_CRITICAL_SECTION; // Disable CE interrupts.
CLK_STRETCH; // Change stretch to '6' equivalent.
Dst.c[ HI_HI ] = *(uint8x_t *) pSrc;
CLK_RELAX; // Back to default value.
((uint8x_t *) pSrc)++;
Dst.c[ HI_LO ] = *((uint8x_t *) pSrc); ((uint8x_t *) pSrc)++;
Dst.c[ LO_HI ] = *((uint8x_t *) pSrc); ((uint8x_t *) pSrc)++;
Dst.c[ LO_LO ] = *((uint8x_t *) pSrc);
END_CE_CRITICAL_SECTION; // Reenable CE interrupts.
return ((int32_t)Dst.l);
}
#pragma restore
#endif
//---------------------------------------------------------------------------//
#if CONSTANTS_DBG || FLAG || CAL_LDR
// Copy data from the CE to xdata.
#pragma save
#pragma NOAREGS
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_xce (int32x_t *pDst, int32x_t *pSrc, uint8_t len) small reentrant
{ // Never any overlapped data.
do {
*pDst++ = memget_ce (pSrc++);
} while (--len);
}
#pragma restore
#endif // constants_debug or flag
// Copy data from the xdata to the CE
#if CAL_LDR
#pragma save
#pragma NOAREGS
// Access to the CE RAM is multiplexed, and this logic synchronizes with
// the multiplexer.
void memcpy_cex (int32x_t *pDst, int32x_t *pSrc, uint8_t len) small reentrant
{ // Never any overlapped data.
do {
memset_ce (pDst++, *pSrc++);
} while (--len);
}
#pragma restore
#endif // calibration loader
#if CONSTANTS_DBG
/*** Public variables declared within this module ***/
struct Constants_t xdata Constants; // configures the meter
volatile struct Constants_t xdata CE_Constants _at_ (CE_DATA_BASE + (0x08 << 2));
//---------------------------------------------------------------------------//
void get_ce_constants (void) // reads the meter configuration
{
memcpy_xce ((int32x_t *) &Constants, (int32x_t *) &CE_Constants, sizeof (Constants) / sizeof (int32_t));
}
#endif // parms_debug
#if EXTRAS
void set_ce_constants (void) // configures the meter
{
memcpy_cex ((int32x_t *) &CE_Constants, (int32x_t *) &Constants, sizeof (Constants) / sizeof (int32_t));
}
#endif // EXTRAS.
#if CAL_SAVE
// longitudinal redundancy checks do not lose precision, as checksums do
// However, they can also fail to detect all-zeros, or all-ones.
// So, initialize to half ones, half zeros.
bool lrc_ce (int32x_t *src, uint16_t len, bool set)
{
uint32_t lrc = 0x55555555L;
if (set)
--len;
for (; len != 0; --len)
lrc ^= memget_ce (src++);
if (set)
{
memset_ce (src, lrc);
lrc = 0;
}
return (0L == lrc);
}
#endif
/***************************************************************************
* History:
* $Log: ce.c,v $
* Revision 1.61 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.60 2006/09/29 08:55:11 tvander
* Moved the xfer_busy flag to the end of the xfer_busy ISR.
* Theoretically, this might improve margin on the alt_mux bit
* with the ce_busy, if ce_busy is sometimes
* invoked after xfer_busy is started.
*
* Revision 1.59 2006/09/27 01:35:17 tvander
* MUX_ALT bit setting moved to ce_busy, so xfer_busy can be lower priority than serial ports.
*
* Revision 1.58 2006/09/20 23:50:51 tvander
* Set interrupt priorities only once, during start-up.
*
* Revision 1.57 2006/09/18 19:29:40 tvander
* Centralized interrupt priorities
*
* Revision 1.56 2006/09/09 01:13:01 gmikef
* *** empty log message ***
*
* Revision 1.55 2006/08/16 20:57:21 tvander
* Added comments about clock speed change changing the UART speed.
*
* Revision 1.54 2006/07/22 01:10:54 tvander
* Fixed so a zero-length CE data area is possible.
*
* Revision 1.53 2006/06/29 00:58:08 tvander
* Added NOAREGs to reeentrant code.
*
* Revision 1.52 2006/06/15 20:03:30 tvander
* Made the register save go at maximum speed- reached 21ms.
*
* Revision 1.51 2006/06/15 16:54:49 tvander
* Removed reset of meter_had_power from meter.c, and moved to ce.c
* Moved readying of eeprom into eeprom driver, from meter.c
*
* Revision 1.50 2006/06/14 02:43:42 tvander
* Backed out battery test code that's synchronized to the measurement cycle.
*
* Revision 1.49 2006/06/08 20:53:58 tvander
* Fixed save-on-sag so it doesn't reset.
* Also regularized calls of watchdog functions.
*
* Revision 1.48 2006/06/06 05:14:40 tvander
* clean build
*
* Revision 1.47 2006/06/06 03:59:00 tvander
* Updated battery test logic so it can use hardware timers as well as software timers.
*
* Revision 1.46 2006/05/25 03:29:30 tvander
* Renamed net-metering variables, so switch of nonvolatile has no conflicts.
* Calibration loader integrated.
*
* Revision 1.45 2006/05/18 23:18:51 tvander
* 16K and 32K
* First cut at new requirements.
* 32K 6521 is grossly tested.
* All others have a clean compile with C51 8.02
*
* Revision 1.44 2006/03/08 00:08:01 tvander
* Multiplexed interrupts are in io65xx.c
* Added stubbed interrupt to io65xx.c
* Clean build
*
* Revision 1.43 2006/03/06 03:36:57 Michael T. Fischer
* More 6530 prep.
*
* Revision 1.42 2006/03/03 11:29:32 Michael T. Fischer
* Prep for 6530 LCD, etc.
*
* Revision 1.41 2006/02/08 03:43:24 tvander
* Made "import" the default power measurement mode, rather than net-metering
*
* Revision 1.40 2006/01/20 21:27:39 gmikef
* Moved "CE_Constants" to "ce.c" to get around linker bug.
*
* Revision 1.39 2006/01/16 20:11:26 tvander
* Clean Keil build, all versions
*
* Revision 1.38 2006/01/10 04:04:40 gmikef
* Added PDATA support for CE Outputs.
*
* Revision 1.37 2005/12/23 01:27:45 tvander
* Meter.c would not compile for 6513 because a table was wrong.
* A few style issues.
*
* Revision 1.35 2005/12/09 20:01:48 tvander
* Clean build
*
* Revision 1.34 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.33 2005/12/07 01:44:40 tvander
* Disabled scope loop code.
*
* Revision 1.32 2005/11/29 01:24:17 tvander
* Automatic software watchdogs; includes code in RTC interrupt to reset watchdog
* once/sec even in brownout mode, even when the software watchdog management is disabled.
*
* Revision 1.31 2005/10/31 17:38:03 tvander
* Includes improved EEPROM code with uwire.
* Clean build, all build trees (Thank-you, Mike!)
*
* Revision 1.30 2005/10/08 04:41:24 tvander
* Fixed priority inversion.
* Rewrote watchdog to work in brownout, but of course it doesn't work.
* Watchdog can now be defeated by clearing watchdog option to 0.
* Reorganized watt hour modules (at last!).
* Disabled reading of STATUS in 6521_cli because the CE's status is always SAG.
* Tested with 6521_CLI; measurements seem to work.
* Fixed other builds.
*
* Revision 1.29 2005/09/28 20:54:02 tvander
* V/I phase displays for all phases,
* main edge count displays for both types,
* rewrote setup from defaults to group related functions.
*
* Revision 1.28 2005/09/26 23:20:07 tvander
* Fixed warning for meters without PULSE_SOURCE
*
* Revision 1.27 2005/09/22 23:45:14 tvander
* Clean build all models and unit tests, updated copyright to be fore Teridian
*
*
* 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. *
***************************************************************************/
/* ce.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -