8 serial interrupt, 3 background tasks, 1 meter_run() – Maxim Integrated 71M6534 Energy Meter IC Family Software User Manual
Page 57: Serial interrupt, Background tasks, Meter_run()

71M653X Software User’s Guide
The RTC interrupt performs any resynchronization of the real-time clock. In the 6530, this loads the latest timing
adjustment, and transfers pulse counts.
The near overflow interrupt is a diagnostic tool to find code that causes a watchdog interrupt.
5.4.2.8
SERIAL Interrupt
es0_isr()
(IO\ser0.c, CLI\serial0.c) is the ISR servicing UART 0. This isr is just the hardware layer. It calls an input
macro (SER0_RCV_INT), and an output macro (SER0_XMIT_INT) that buffer the data. The macros are defined in the
options.h include file. They map to cli0_in() and cli0_out() (in CLI\ser0cli.c). An AMR routine can be spliced in
just by writing the input and output code, and changing the options.h file.
In this ISR, the UART data is sent and received using XON/XOFF flow control. Parity and other serial controls are
managed in this ISR. The guts of the code are in ser0cli.c.
cli0_in()
takes a character in, and decides if it is XON or XOFF. If not, it puts it into a circular buffer and counts it.
The circular buffer’s index is made to restart by masking (logical anding) it. If the count of data in the buffer is too big, it
sends an XOFF. The XON is sent later, by the code that takes data out of the buffer: see the code that calls
flow_on().
cli0_out()
first sees if it has to write a flow character. If not, then if there’s no more characters to send, it disables
the transmit interrupt. If there’s more to send, and the flow is enabled, it gets a character out of the circular transmit
buffer and sends it. If the flow is turned off, it disables the transmit interrupt.
The output code is designed to switch a driving pin, as well. There’s a flag “has_run”, which is polled by a software
timer routine, ser0_free_timer(). If has_run is not set, the timer switches off the external pin or driver. In the
demo code, this switches DIO2 between OPT_TX from serial output 1, and WPULSE. The timer is used so that the
output switches well after the last character is sent. The serial interrupt overhead is low, because the timer routine is
only allocated once, at the start of transmission. Pulse outputs change so slowly that they are invisible to most UARTs.
The alternative serial port, UART 1 uses an ISR with identical code structure and function (es1_isr in IO\ser1.c and
CLI\ser1cli.c). The code can be identical because it uses a different .h file to define different serial IO macros that have
the same names. The buffer-level code was written once, and then ported instantly by copying the code and just
testing it.
Both serial ports are enabled at all times.
5.4.3 Background Tasks
5.4.3.1
meter_run()
This does all the metering calculations. It’s in Meter\meter.c, called from the main loop main_background() in
Main\main.c Putting the calculations in the background makes the code faster because the local variables don’t have
to be on Keil’s reentrant stack. They can be statically allocated overlays, instead.
First, it checks to see if there’s more meter data. That is, whether an accumulation interval finished and caused a
xfer_busy interrupt. It checks the flag, xfer_update set by the xfer_busy() interrupt in meter\ce.c.
If the flag is clear, then there’s no new meter data, so it returns to the main loop. If there’s new data, it processes it.
In the processing, first it checks to see if there was a request to clear the metering registers (“)1=2” clears the metering
registers). The clearing has to be synchronized with the meter calculation.
Next it counts accumulation intervals (variable cai). This count is useful to find the exact number of accumulation
intervals for calibration or meter tests. In a real meter, this number is useful in a demand calculation, because the
average demand in a demand interval is the total VAh in a demand interval, divided by the number of accumulation
intervals. Util\math.c has a routine s2f() to convert a power register into a floating point number. Accumulating
demand in a power register, and then dividing avoids any possibility of floating point underflow in the demand
calculation. The demo code does not include a demand calculation because most customers have preferred
algorithms.
The while loop synchronizes the meter calculation with the CE’s accumulation interval.
RescalePhaseB()
is used only in the single-phase demo code. Some customers use a shunt on one element, and a
current transformer on the other. These elements have different Wh/count, and rescaling adjusts PhaseB, usually the
lower-accuracy, in terms of PhaseA, usually the higher accuracy current sensor.
v1.1v1.1
TERIDIAN Proprietary
57 of 116
© Copyright 2005-2008 TERIDIAN Semiconductor Corporation