Language selection

Search

Patent 2527068 Summary

Third-party information liability

Some of the information on this Web page has been provided by external sources. The Government of Canada is not responsible for the accuracy, reliability or currency of the information supplied by external sources. Users wishing to rely upon this information should consult directly with the source of the information. Content provided by external sources is not subject to official languages, privacy and accessibility requirements.

Claims and Abstract availability

Any discrepancies in the text and image of the Claims and Abstract are due to differing posting times. Text of the Claims and Abstract are posted:

  • At the time the application is open to public inspection;
  • At the time of issue of the patent (grant).
(12) Patent: (11) CA 2527068
(54) English Title: APPARATUS AND METHODS FOR MULTI-CHANNEL METERING
(54) French Title: APPAREILLAGE ET METHODES DE COMPTAGE MULTIVOIE
Status: Expired and beyond the Period of Reversal
Bibliographic Data
(51) International Patent Classification (IPC):
  • G01R 22/00 (2006.01)
  • G01R 11/00 (2006.01)
  • G01R 11/24 (2006.01)
  • H02J 13/00 (2006.01)
  • H04B 3/54 (2006.01)
(72) Inventors :
  • SWARZTRAUBER, SAYRE A. (United States of America)
  • SHAFRIR, DORON (United States of America)
  • MALIK, SIDDHARTH (United States of America)
  • HAYWARD, ROBERT (Canada)
(73) Owners :
  • QUADLOGIC CONTROLS CORPORATION
(71) Applicants :
  • QUADLOGIC CONTROLS CORPORATION (United States of America)
(74) Agent: OSLER, HOSKIN & HARCOURT LLP
(74) Associate agent:
(45) Issued: 2013-08-20
(22) Filed Date: 2005-11-15
(41) Open to Public Inspection: 2007-05-15
Examination requested: 2006-11-14
Availability of licence: N/A
Dedicated to the Public: N/A
(25) Language of filing: English

Patent Cooperation Treaty (PCT): No

(30) Application Priority Data: None

Abstracts

English Abstract

In one aspect, the invention comprises a device for measuring electricity usage of several circuits in an integrated environment, comprising: means for remote disconnection via power line communication; means for detection of electricity theft; means for tamper detection; and means for reverse voltage detection. In another aspect, the invention comprises an apparatus for multi-channel metering of electricity, comprising: (a) a meter head operable to measure electricity usage for a plurality of electricity consumer lines; (b) a transponder operable to transmit data received from the meter head via power line communication to a remotely located computer, and to transmit data received via power line communication from the remotely located computer to the meter head; and (c) a load control module operable to actuate connection and disconnection of each of a plurality of relays, each relay of the plurality of relays corresponding to one of the plurality of electricity consumer lines.


French Abstract

Selon un aspect, l'invention concerne un dispositif qui permet de mesurer la consommation d'électricité de plusieurs circuits dans un environnement intégré et qui comprend : un moyen de déconnexion à distance par une communication via le réseau électrique; un moyen de détection de détournement de ligne électrique; un moyen de détection de modification; et un moyen de détection de tension inverse. Selon un autre aspect, l'invention concerne un appareil permettant d'effectuer une mesure multivoie de la consommation électrique comprenant : (a) un compteur servant à mesurer la consommation d'électricité pour une pluralité de lignes électriques; (b) un transpondeur servant à transmettre des données reçues du compteur par une communication via le réseau électrique à un ordinateur distant et à transmettre au compteur les données reçues de l'ordinateur distant par une communication via le réseau électrique; et (c) un module de commande de charge servant à activer la connexion et la déconnexion d'une pluralité de relais, chacun de ces relais correspondant à une des lignes électriques.

Claims

Note: Claims are shown in the official language in which they were submitted.


The embodiments of the present invention for which an exclusive property or
privilege is claimed are defined as follows:
1. An apparatus for remote multi-channel metering of electricity using
power line
communication, comprising:
a plurality of metering points located on a secondary side of a distribution
transformer and operable to separately measure electricity usage for each of a
plurality of electricity consumer lines;
said apparatus in communication with a transponder located on a primary side
of said distribution transformer and operable to transmit data to and receive
data from
said transponder via power line communication, said transponder operable to
transmit
data to and receive data from a remotely located computer;
said apparatus operable to control one or more load control modules operable
to actuate connection and disconnection of each of a plurality of relays, each
relay of
said plurality of relays corresponding to one of said plurality of electricity
consumer
lines; and
a box containing said plurality of metering points, said load control module,
and said relays,
wherein said distribution transformer converts medium tension distribution
voltages to low tension voltages appropriate for supplying power to customers,
and
wherein said apparatus is operable to inject signals onto and receive signals
from low voltage power lines that supply customers with electric power; said
signals
providing two-way communication between a meter head and said transponder and
traversing said distribution transformer.
2. An apparatus as in claim 1, further comprising a tamper detector in
communication with said meter head.
3. An apparatus as in claim 2, wherein said tamper detector comprises a
light and
a reflective surface, and wherein said meter head is operable to instruct said
load control
module to disconnect all of said customer lines if said tamper detector
provides notification
that said light is not detected reflecting from said reflective surface.
-67-

4. An apparatus as in claim 2, wherein said tamper detector comprises a
detector
of ambient light entering said box.
5. An apparatus as in claim 1, wherein said box is installed on a utility
pole.
6. An apparatus as in claim 1, further comprising means for comparing
transformer energy to total energy used by said consumer lines.
7. An apparatus as in claim 1, further comprising means for detecting
reverse
voltage flow through said consumer lines.
8. An apparatus as in claim 1, further comprising a computer readable
memory in
communication with said meter head and a counter in communication with said
meter head,
said counter corresponding to a customer line and operable to count down an
amount of
energy stored in said memory, and said meter head operable to send a
disconnect signal to
said load control module to disconnect said customer line when said counter
reaches zero.
9. An apparatus as in claim 1, further comprising a computer readable
memory in
communication with said meter head, said memory operable to store a load limit
for a
customer line, and said meter head operable to send a disconnect signal to
said load control
module to disconnect said customer line when said load limit is exceeded.
10. An apparatus as in claim 1, further comprising a computer readable
memory in
communication with said meter head, said memory operable to store a usage
limit for a
customer line, and said meter head operable to send a disconnect signal to
said load control
module to disconnect said customer line when said usage limit is exceeded.
11. An apparatus as in claim 1, wherein said transponder is operable to
communicate with said remotely located computer over medium tension power
lines.
12. An apparatus as in claim 1, further comprising a display unit in
communication with said meter head and operable to display data received from
said meter
head.
-68-

13. An apparatus as in claim 12, wherein said display unit is operable to
display
information regarding a customer's energy consumption.
14. An apparatus as in claim 12, wherein said display unit is operable to
display
warnings regarding a customer's energy usage or suspected theft of energy.
15. An apparatus as in claim 12, wherein said display unit is operable to
transmit
to said meter head information entered by a customer.
16. An apparatus as in claim 1, wherein said transponder is operable to
communicate with said remotely located computer via at least one of: radio
communications,
fiber optics, and telephone lines.
17. An apparatus as in claim 1, wherein said apparatus is operable to
transmit data
directly to said transponder at frequencies within the range 10-25 kHz.
18. An apparatus as in claim 1, wherein said apparatus is operable to
transmit data
directly to said transponder at frequencies corresponding to half-odd
harmonics of 60 Hz.
19. An apparatus as in claim 1, wherein said box is located in a secure
area.
20. An apparatus for multi-channel metering of electricity, comprising:
a control module in communication with a secondary circuit of a distribution
transformer, wherein said distribution transformer converts medium tension
distribution voltages to low tension voltages appropriate for supplying power
to
customers;
said control module in direct communication with a transponder in
communication with a primary circuit of said transformer and operable to
transmit
data to and receive data from said transponder via direct power line
communication,
through said distribution transformer, said transponder operable to transmit
data to
and receive data from a remotely located computer;
-69-

a plurality of meter modules in communication with said control module, each
meter module operable to measure electricity usage on one of a plurality of
electricity
consumer lines fed from the secondary circuit of said distribution
transformer;
one or more relays in communication with said control module and operable to
actuate connection and disconnection of electricity to said electricity
consumer lines;
and
a box containing said control module, said meter modules and said relays,
wherein said apparatus is operable to inject signals onto and receive signals
from low voltage power lines that supply customers with electric power;
said signals providing two-way communication between said meter head and
said transponder and traversing said distribution transformer to communicate
at least
partially over medium tension power lines to said remotely located computer.
21. An apparatus as in claim 20, wherein said one or more relays are
operable to
control each phase of said electricity consumer lines.
22. An apparatus for multi-channel metering of electricity, comprising:
a meter head located on a secondary side of a transformer and operable to
separately measure electricity usage for each of a plurality of electricity
consumer
lines;
said meter head in direct communication with a transponder located on a
primary side of said transformer operable to transmit data to and receive data
from
said transponder via direct power line communication, said transponder
operable to
transmit data to and receive data from a remotely located computer;
a load control module in communication with said meter head and operable to
actuate connection and disconnection of each of a plurality of relays, each
relay of
said plurality of relays corresponding to one of said plurality of electricity
consumer
lines; and
a box containing said meter head, said load control module, and said relays.
23. An apparatus as in claim 22, further comprising a tamper detector in
communication with said meter head.
-70-

24. An apparatus as in claim 23, wherein said tamper detector comprises a
light
and a reflective surface, and wherein said meter head is operable to instruct
said load control
module to disconnect all of said customer lines if said tamper detector
provides notification
that said light is not detected reflecting from said reflective surface.
25. An apparatus as in claim 23, wherein said tamper detector comprises a
detector of ambient light entering said box.
26. An apparatus as in claim 22, wherein said box is installed on a utility
pole.
27. An apparatus as in claim 22, further comprising means for comparing
transformer energy to total energy used by said consumer lines.
28. An apparatus as in claim 22, further comprising means for detecting
reverse
voltage flow through said consumer lines.
29. An apparatus for multi-channel metering of electricity, comprising:
a control module in communication with a secondary circuit of a distribution
transformer;
said control module in direct communication with a transponder in
communication with a primary circuit of said transformer and operable to
transmit
data to and receive data from said transponder via direct power line
communication,
through said distribution transformer, said transponder operable to transmit
data to
and receive data from a remotely located computer;
a plurality of meter modules in communication with said control module, each
meter module operable to measure electricity usage on one of a plurality of
electricity
consumer lines fed from the secondary circuit of said distribution
transformer;
one or more relays in communication with said control module and operable to
actuate connection and disconnection of electricity to said electricity
consumer lines;
and
a box containing said control module, said meter modules and said relays.
-71-

30. An apparatus as in claim 29, wherein said one or more relays are
operable to
control each phase of said electricity consumer lines.
-72-

Description

Note: Descriptions are shown in the official language in which they were submitted.


CA 02527068 2009-05-27
APPARATUS AND METHODS FOR MULTI-CHANNEL METERING
Background and Summary
One embodiment of the present invention comprises a metering device that is
related to the Quadlogic ASIC-based family of meters (see U.S. Pat. No.
6,947,854, and
U.S. Pat. App. Pub. No. 2006/0036388). Specifically, this embodiment (referred
to herein
for convenience as "Energy Guard") is a multi-channel meter that preferably is
capable of
providing much of the functionality of the above-mentioned family of meters,
and further
provides the improvements, features, and components listed below.
Used in at least one embodiment, a MiniCloset is a 24-channel metering device
that can measure electric usage for up to 24 single-phase customers, 12 two-
phase
customer, or 8 three-phase customers. Preferably connected to the MiniCloset
are one or
more Load Control Modules (LCMs), discussed below.
Energy Guard preferably comprises a MiniCloset meter head module and two
LCMs mounted into a steel box. Relays that allow for an electricity customer
to be
remotely disconnected and reconnected, along with current transformers, also
are mounted
into the box.
Upon installation, an electricity customer's electricity supply line is tapped
off the
main electric feeder, passed through the Energy Guard apparatus, and run
directly to the
customer's home. The construction and usage of the Energy Guard will be
apparent to
those skilled in the art upon review of the description below and related
figures. Source
it
code is supplied in the attached Appendix.
Energy Guard meters preferably are operable to provide:
(A) Remote Disconnect/Reconnect: The meter supports full duplex (bi-
directional)
communication via power line communication ("PLC") and may be equipped

1
CA 02527068 2006-11-14
with remotely operated relays (60 amp, 100 amp, or 200 amp) that allow for
disconnect
and reconnect of electricity users remotely.
(B) Theft Prevention: The system is designed with three specific features to
prevent theft. First, an Energy Guard apparatus preferably is installed on a
utility pole
above the medium-tension lines, making it difficult for customers to reach and
tamper
with. Second, because there are no additional signal wires with the system
(i.e., all
communication is via the power line), any severed communication wires are
immediately
detectable. That is, if a communication wire is cut, service is cut, which is
readily
apparent. A third theft prevention feature is that the meter may be used to
measure the
transformer energy in order to validate the measured totals of individual
clients.
Discrepancies can indicate theft of power.
(C) Tamper Detection: The Energy Guard preferably provides two modes of
optical tamper detection. Each unit contains a light that reflects against a
small mirror-
like adhesive sticker. The absence of this reflective light indicates that the
box has been
opened. This detection will automatically disconnect all clients measured by
that Energy
Guard unit. In addition, if the Energy Guard enclosure is opened and ambient
light
enters, this will also automatically disconnect all clients measured by that
Energy Guard
unit. These two modes of tamper detection are continuously engaged and
alternate
multiple times per second for maximum security.
(D) Reverse Voltage Detection: In some cases, a utility company can disconnect
power to an individual client and that client is able to obtain power via an
alternative
feed. If the utility were to reconnect power under these conditions, damage
could occur
to the metering equipment and/or the distribution system. Energy Guard
preferably is
able to detect this fault condition. The Energy Guard can detect any voltage
that feeds
back into the open disconnect through the lines that connect to the customers'
premises.
If voltage is detected, the firmware of the Energy Guard will automatically
prevent the
reconnection.
(E) Pre-Payment: Pre-payment for energy can be done via phone, electronic
transaction, or in person. The amount of kWh purchased is transmitted to the
meter and
stored in its memory. The meter will count down, showing how much energy is
still
- 2 -

CA 02527068 2006-11-14
available before reaching zero and disconnecting. As long as the customer
continues to
purchase energy, there will be no interruption in service, and the utility
company will
have a daily activity report.
(F) Load Limiting: As an alternative to disconnection for nonpayment or part
of a
pre-payment system, Energy Guard meters can allow the utility to remotely
limit the
power delivered to a set level, disconnecting when that load is exceeded. If
the customer
exceeds that load and is disconnected, the customer can reset a button on the
optional
remote display unit to restore load as long as the connected load is less than
the pre-set
limit. Alternatively, clients can call an electric utility service line by
telephone to have
the service restored. This feature allows electric utilities to provide
electricity for critical
systems even, for example, in the case of a non-paying customer.
(G) Monthly Consumption Limiting: Some customers benefit from subsidized
rates and are given a maximum total consumption per month. The Energy Guard
firmware is capable of shutting down power when a certain consumption level is
reached.
However, this type of program is best implemented when advanced notification
to
customers is provided. This can be achieved either with a display in the home
whereby a
message or series of messages notifies customers that their rate of
consumption is
approaching the projected consumption for the month. Alternatively (or in
conjunction)
timed service interruptions can be programmed so that as the limit is
approaching, power
is disconnected for periods of time with longer and longer increments to
notify the
residents. These planned interruptions in service act as a warning to
customers that their
limit is nearing so that they have time to alter their consumption patterns.
(H) Meter Validation: The integrated module of the system preferably is
removable. This permits easy laboratory re-validation of meter accuracy in the
event of
client billing disputes.
(I) Operational Benefits for Utility: The Energy Guard has extensive onboard
event logs and diagnostic functions, providing field technicians with a wealth
of data for
commissioning and trouble shooting the electrical and communication systems.
Non
billing parameters include: amps, volts, temperature, total harmonic
distortion,
- 3 -

CA 02527068 2006-11-14
frequency, instantaneous values of watts, vars and volt-amperes, V2 hrs, 12
hrs, power
factor, and phase angle.
These features and others will be apparent to those skilled in the art after
reviewing the attached descriptions, software code, and schematics.
In one aspect, the invention comprises a device for measuring electricity
usage,
comprising: means for remote disconnection via power line communication; means
for
detection of electricity theft; means for tamper detection; and means for
reverse voltage
detection.
In another aspect, the invention comprises an apparatus for multi-channel
metering of electricity, comprising: (a) a meter head operable to measure
electricity
usage for a plurality of electricity consumer lines; (b) a transponder in
communication
with the meter head and operable to transmit data received from the meter head
via power
line communication to a remotely located computer, and to transmit data
received via
power line communication from the remotely located computer to the meter head;
and (c)
a load control module in communication with the meter head and operable to
actuate
connection and disconnection of each of a plurality of relays, each relay of
the plurality
of relays corresponding to one of the plurality of electricity consumer lines.
In various embodiments: (1) the apparatus further comprises a tamper detector
in
communication with the meter head; (2) the tamper detector comprises a light
and a
reflective surface, and wherein the meter head is operable to instruct the
load control
module to disconnect all of the customer lines if the tamper detector provides
notification
that the light is not detected reflecting from the reflective surface; (3) the
apparatus
further comprises a box containing the meter head, the load control module,
and the
relays, and wherein the tamper detector comprises a detector of ambient light
entering the
box; (4) the apparatus further comprises a box containing the meter head, the
load control
module, and the relays, and wherein the box is installed on a utility pole;
(5) the
apparatus further comprises means for comparing transformer energy to total
energy used
by the consumer lines; (6) the apparatus further comprises mans for detecting
reverse
voltage flow through the consumer lines; (7) the apparatus further comprises a
computer
readable memory in communication with the meter head and a counter in
communication
- 4 -

CA 02527068 2006-11-14
with the meter head, the counter corresponding to a customer line and operable
to count
down an amount of energy stored in the memory, and the meter head operable to
send a
disconnect signal to the load control module to disconnect the customer line
when the
counter reaches zero; (8) the apparatus further comprises a computer readable
memory in
communication with the meter head, the memory operable to store a load limit
for a
customer line, and the meter head operable to send a disconnect signal to the
load control
module to disconnect the customer line when the load limit is exceeded; (9)
the apparatus
further comprises a computer readable memory in communication with the meter
head,
the memory operable to store a usage limit for a customer line, and the meter
head
operable to send a disconnect signal to the load control module to disconnect
the
customer line when the usage limit is exceeded; and (10) the transponder is
operable to
communicate with the remotely located computer over medium tension power
lines.
Brief Description of the Drawings
FIG. 1 is a block/wiring diagram showing connection of preferred embodiments.
FIG. 2 is a block diagram showing physical configuration of preferred
embodiments.
FIGS. 3A-3B are schematic diagrams of a preferred CPU board of a Scan
Transponder and MiniCloset.
FIG. 4 is a schematic diagram of a preferred Scan Transponder power supply.
FIG. 5 is a schematic diagram of a preferred MiniCloset power supply.
FIG. 6 is a schematic diagram of a preferred circuit board for returning
current
transformer information to a MiniCloset meter head.
FIGS. 7A-7C are schematic diagrams of a preferred Load Control Module circuit
board.
FIGS. 8A-8D are schematic diagrams of a preferred power supply board that
provides for optical tamper detection.
FIGS. 9A-9C are schematic diagrams of a preferred Energy Guard connection
board.
- 5 -

CA 02527068 2006-11-14
FIG. 10 is a schematic diagram for a control circuitry board operable to
provide
relay control.
Detailed Description of Preferred Embodiments
In one embodiment, an Energy Guard metering apparatus comprises a MiniCloset
The MiniCloset and Scan Transponder referred to herein are largely the same as
described in U.S. Pat. No. 6,947,854. That is, although each has been improved
over the
One aspect of the invention comprises taking existing multichannel metering
functionality found in the MiniCloset and adding remote connect and disconnect
via
PLC. Providing such additional functionality required adding new hardware and
20 FIG. 1 is a block diagram of connections of a preferred embodiment.
Medium
voltage power lines A, B, C, and N (neutral) feed into Distribution
Transformer 110.
Low voltage lines connect (via current transformers 120) Distribution
Transformer 110 to
Energy Guard unit 140. Energy Guard unit 140 monitors current transformers
120, and
feeds single phase customer lines 1-24.
25 FIG. 2 is a block diagram of preferred structure of an Energy -Guard
unit 140.
Scan Transponder 210 is the preferred data collector for the unit 140, may be
located external to or inside the MiniCloset, and may be the main data
collector for more
than one MiniCloset at a time. The Scan Transponder 210 preferably: (a)
verifies data
(each communication preferably begins with clock and meter identity
verification to
- 6 -

CA 02527068 2006-11-14
ensure data integrity); (b) collects data (periodically it collects a data
block from each
meter unit, with each block containing previously collected meter readings,
interval
readings, and event logs); (c) stores data (preferably the data is stored in
non-volatile
memory for a specified period (e.g., 40 days)); and (d) reports data (either
via PLC,
telephone modem, RS-232 connection, or other means).
The slide plate 280 comprises a Minicloset meter head and a load control
module
240 that provides the control signals to activate the relays. All of the
electronics
preferably is powered up by power supply 250. The back plate assembly 270
comprises
multiple (e.g., 24) Current Transformers and relays - grouped, in this
example, as three
sets of 8 CTs and relays. Customer cables are wired through the CTs and
connect to the
circuit on customer premises 290. The remotely located Scan Transponder 210
accesses
the Energy Guard meter head and bi-directionally communicates using power line
carrier
communication.
The signal flow shown in FIGS. 1 and 2 preferably is accomplished by
implementing different software code modules operating concurrently to enable
remote
connect/disconnect ability in the Minicloset. These software modules, provided
in the
Appendix below, are:
Code Module Location Function
lcm.def and Load Control Actuate connect and
pic.def Module disconnect of relays.
pulse.c and Meter Head Establish communication with
pulse.h LCM.
picend.def and Meter Head Provide control signals to
picvars.def LCM.
pulselink.def and Meter Head Provides LCM with pulses to
pulseoutm.c be used for connecting and
disconnecting relays.
FIGS. 3-10 are schematics of preferred components, as described below. The
preferred connect/disconnect relays are series K850 KG relays, but those
skilled in the art
- 7 -

CA 02527068 2006-11-14
will recognize that other relays may be used without departing from the scope
of the
invention.
Figure Schematic Detail
3 PCB 107D CPU board of the Scan Transponder and MiniCloset.
4 PCB 135C Power Supply for Scan Transponder.
PCB 144C Power Supply for MiniCloset.
6 PCB 146C This board brings back the Current Transformer
information back to MiniCloset meter head.
7 PCB 160A Board for Load Control Module.
8 PCB 170 EG power supply board that adds capability for
optical
tamper detection.
9 PCB 171 EG Connection board. A board with traces to route the
signal.
PCB 172 Control circuitry board for Relay control.
5 While certain specific embodiments of the invention have been
described herein
for illustrative purposes, the invention is not limited to the specific
details, representative
devices, and illustrative examples shown and described herein. Various
modifications
may be made without departing from the spirit or scope of the invention
defined by the
appended claims and their equivalents.
- 8 -

CA 02527068 2006-11-14
APPENDIX
- 9 -

CA 02527068 2006-11-14
LCM.DEF
; QLC LCM (Load Control Module) program for PIC 16C63A;
;
include 'CApictools\16c63a.inc'
=
include 'CApictools\16c63.inc' =
; Configuration bits
FUSES _BODEN_OFF ; Brown-out reset disabled
FUSES _CP_OFF ; No code protect
FUSES _PWRTE_OFF ; Disable power-up timer
FUSES _WDT_ON ; Watchdog Timer Enabled
FUSES _ RC _OSC ; Oscillator = RC
; Program Parameter Equates
Software_type equ 7 ; Which PIC program is this?
; 7 = LCM program
Software_version equ 2 ; Version #
LCM_base_addr equ 16 ; Address of first LCM
Ram_start equ 020h ; Beginning of available RAM
RESET_VECTOR equ 0 ; Location of reset vector
ROM_start equ 008h ; first available program location
Num_start_bits equ 12 ; Number of start bits
; Port definitions
comm_port equ PORTA
data_out equ 3
data_in equ 4
clock_in equ 5
ctl_port equ PORTA
driver_enable equ 0 ; output bit to turn on the drivers
Driver_enable_mask equ 1 driver_enable
Initialization values for I/O ports
- 10 -

1
CA 02527068 2006-11-14
init_TRISA equ 00110000b ; Data direction for port A
init_TRISB equ 000h ; B port data direction - all ports output
init_TRISC equ 000h ; C port data direction - all out
read_TRISC equ Olfh ; C port data direction for jumper read - 0-
4 in
Init_comm_port_value equ 1 data_out + Driver_enable_mask
= bit 7 = 1: Port B pullups disabled
,
= bit 6 = 0: Int on falling edge
,
, bit 5 = 0: Timer 0 uses inst clock
; bit 4 =0: Timer 0 counts on rising edge
bit 3 = 1: Prescaler used by WDT
,
= bit 2,1,0 = 111:Prescaler divide by 128
,
; NOTE - interrupts and timer 0 are not used by this program
ms_preset equ 700 ; Time set for millisecond delay
=
,
; RAM locations
ORG Ram_start
Status_reg ds 4 ; status register
ORG Status_reg
Status_MSB ds 1
Clk_timeout_flag equ 7 ; Timeout waiting for comm clock edge
bad_reset_flag equ 6 ; Non-POR, non-WDT reset encountered
POR_flag equ 5 ; Power-on reset detected
WDT_reset_flag equ 4 ; WDT reset, not from sleep
Status_LSB ds 1
CPU_reset_flag equ 7
Need_param_refresh_flag equ 6
Parity_err_flag equ 5
Global_cmd_timer ds 1
Jumper_state ds 1 ; current state of input jumpers
Parameter_reg ds 4 ; Communication parameters
org Parameter_reg
ds 1 ,
-11-

CA 02527068 2006-11-14
=
ds 2
=
ds 1
; Fast communication variables
;
Comm_state ds 1 ; Stored state of fast comm uart
Wstate ds 1 ; Stored state of fast comm word handler
Comm_bit_count ds 1 ; Bit counter for fast comm
Comm_buffer ds 1 ; fast comm word buffer
Work_addr ds 1 ; Address read from jumpers
Temp ds I ; temporary register
Tpar ds 1 ; Transverse parity
Word_count ds 1 ; Counter for sending and receiving 5-bit words
Command ds 1 ; Command received over comm link
Register_ID ds 1 ; Register specified in comm command
PIC_addr ds 1 ; Address of this PIC chip
Comm_buf ds 5 ; Communication buffer
Input_hold ds I ; Hold register for comm rcv value
Output_bit_reg ds 4 ; Hold register for output bit mask
Flags ds 1 ; Program control flags
Clk_wait_flag equ 7 ; indicates which clock edge we are waiting
for
Global_cmd_flag equ 6 ; Processing global command
scratch ds 1 ; Work register
Timeout_ctr ds 2 ; Counter for pulse duration
Millisecs ds 1 ; Counter for pulse duration milliseconds
Clk_timeout_ctr ds 2 ; counter for clock timeout
NPR timer ds 2 ; counter for need parameter refresh
=
ORG 0a0h
; Bank 1 RAM locations
IF $ - 1 & 0100h
error - RAM overflow
ENDIF
=
ORG RESET_VECTOR
jmp start ; Jump to first program location
- 12 -

CA 02527068 2006-11-14
= Start of program space
=
ORG ROM_start
=
= Initialization
=
Start
setb RPO ; point to upper register bank
jnb NOT_POR,got_POR ; Power on reset, set flags
clrb RPO ; point to RAM bank 0
jnb NOT_TO,WDT_reset ; Watchdog reset
setb status_MSB.bad_reset_flag ; Indicate unknown reset
condition
jmp Do_initialize
WDT_reset
setb Status_MSB.WDT_reset_flag
jmp do_initialize
got_POR
clrb RPO ; point to RAM bank 0
mov Status_MSB,#1 POR_flag ; Set POR flag
clr Status_LSB
Do_initialize
mov FSR,#Ram_start+2 ; Point past status flags
:c1r_loop
clr INDF ; Clear RAM location
inc FSR ; Increment pointer
jz Init_state ; If zero, done
mov W,FSR ; get pointer
and W,#7fH ; look at 7 LSB's
jnz :c1r_loop ; Not end of segment, continue
add FSR,#20h ; Point to next segment
jmp :c1r_loop ; Not last segment, continue
Init_state
setb Status_LSB.CPU_reset_flag ; Indicate CPU reset
setb Status_LSB.Need_param_refresh_flag ; Indicate parameter
refresh needed
mov comm_port,#Init_comm_port_value ;
initialize comm port state
mov Comm_state,#Edge_wait
mov Comm_bit_count,#Num_start_bits ; Initialize fast
comm state
machine
clr PORTB
clr PORTC
jmp Main_loop ; start running main program
=
=
; Comm Receive routines
Edge_wait
; Initialize Watchdog timer
- 13 -

CA 02527068 2006-11-14
mov !OPTION,#option_reg_val ; Set option reg
setb comm_port.data_out ; send a 1
dec Comm_bit_count ; decrement bit count
jz See_edge_one ; if zero, looking for a 1
jb Input_hold.data_in,Set_edge_wait ; Looking for 0, reset bit count if
1
imp Comm_ret ; done
See_edge_one
jnb Input_hold.data_in,Set_edge_wait ; looking for 1, reset if 0
mov Wstate,#Rcv_addr ; First word is address
mov Tpar,#01fh ; Init parity
imp Rcv_next_word
Rcv_stop
mov Comm_state,#Edge_wait
mov Comm_bit_count,#Num_start_bits ; Preset state to wait for edge
jnb Input_hold.data_in,Parity_error ; stop bit must be 1
jmp Cmd_exec ; Done, process received buffer
Rcv_bits
dc ; copy ...
snb Input_hold.data_in ; ... input bit ...
setc ... to carry
rl Comm_buffer ; shift buffer
imp Rcv_word_handler ; Check for complete word
;
; Comm Transmit routines
Send_edge
dec Comm_bit_count ; decrement bit count
jz :One ; if zero, send a 1
clrb comm_port.data_out ; send a 0
imp Comm_ret
:One
setb comm_port.data_out ; send a 1
imp Do_xmit_word
Send_bits
rl Comm_buffer ; put xmit bit into carry
jc :one
clrb comm_port.data_out ; send a '0'
imp :check
:one
setb comm_port.data_out ; send a '1'
:check
imp Xmit_word_handler
=
= Comm receive word handler routines
;
- 14 -

CA 02527068 2006-11-14
Rcv_word_handler
djnz Comm_bit_count,Comm_ret ; If word not complete, continue
and Comm_buffer,#031h ; only 6 bits
dc
mov W, Comm_buffer ; get 5 MSBs of received word
call parity_lookup
xor W,Comm_buffer ; compare with received word
jnz Parity_error
rr Comm_buffer
and Comm_buffer,#01fh ; extract 5-bit value
xor Tpar,Comm_buffer ; calculate total parity
mov PCLATH,#Rcv_addr<
mov W,Wstate
jmp W ; Execute word handler routine
Rcv_addr
clrb Flags.Global_cmd_flag ; Clear global command flag
mov W,Comm_buffer ; Get received address
mov PIC_addr,W ; save it
xor W,#1fh ; is it global command
jnz See_if us ; No, check for address match
setb Flags.Global_cmd_flag ; Set global command flag
jmp Its_us ; process rest of command
See if us
mov !PORTC,#read_TRISC ; Switch C port bit 0-4 to input
clrb ctl_port.driver_enable ; Disable output drivers, enable jumper
read
mov temp,#9
:loop
djnz temp,:loop ; Wait at least 20 uSec
mov W,/PORTC ; Get inverse of jumpers in W
mov Work_addr,W ; Save jumper value
setb ctl_port.driver_enable ; Enable output drivers
mov !PORTC,#init_TRISC ; Restore C port status
mov Jumper_state,Work_addr ; Save jumper state
and Work_addr,#03h ; Ignore all but 2 LSBs
add Work_addr,#LCM_base_addr ; Add base offset
cjne Work_addr,PIC_addr,Set_edge_wait
Its_us
mov Wstate,#Rcv_cmd ; point to next routine
jmp Rcv_next_word
Rcv_cmd
mov Command,Comm_buffer ; save command
jnb Command.4,Comm_get_fast ; Fast read command, skip Reg ID
mov Wstate,#Rcv_reg_ID ; point to next routine
jmp Rcv_next_word
Comm_get_fast
mov Wstate,#Rcv_tpar ; point to next routine
jmp Rcv_next_word
Rcv_reg_ID
- 15 -

CA 02527068 2006-11-14
mov register_ID,Comm_buffer ; save register number
mov Wstate,#Rcv_tpar ; point to next routine
jnb Command.3,Rcv_next_word ; If no value, done
mov word_count,#7 ; Init word count
mov Wstate,#Rcv_value ; point to next routine
jmp Rcv_next_word
Rcv_value
rl Comm_buffer
rl Comm_buffer
rl Comm_buffer ; Shift rcvd bits to MSBs
mov Comm_bit_count,#5 ; shift 5 bits
:shift_loop
rl Comm_buffer
rl Comm_buf+4
rl Comm_buf+3
rl Comm_buf+2
rl Comm_buf+1
rl Comm_buf ; Shift a bit from Comm_buf to comm_buf
djnz Comm_bit_count,:shift_loop
djnz word_count,Rcv_next_word ; any more words?
mov Wstate,#Rcv_tpar ; point to next routine
jmp Rcv_next_word
Rcv_tpar
mov W,Tpar ; Get result of parity calculations
jnz Parity_error ; If not 0, parity error
jmp Set_rcv_stop ; set up to receive stop bit
;
Comm transmit word handler routines
=
Xmit_word_handler
djnz Comm_bit_count,Comm_ret ; If word not complete, continue
Do_xmit_word
mov PCLATH,#$<
mov W,Wstate
jmp W ; Execute word handler routine
Send_addr
mov Wstate,#Send_cmd> ; point to next word routine
mov W,PIC_addr ; get address
jmp Send_next_word
Send_cmd
mov Wstate,#Send_value> ; point to send value
jnb Command.4,Value_is_next ; Is it fast read command?
mov Wstate,#Send_reg_ID> ; point to next word routine
Value_is_next
- 16 -

CA 02527068 2006-11-14
mov W,Command ; get command
jmp Send_next_word
Send_reg_ID
mov Wstate,#Send_value> ; point to next word routine
mov W,Register_ID ; get Register ID
jmp Send_next_word
Send_value
mov Wstate,#Next_value> ; point to next word routine
mov Word_count,#7 ; value is 7 words long
Next_value
mov Comm_bit_count,#5
:loop
rl comm_buf+4
rl comm_buf+3
rl Comm_buf+2
rl Comm_buf+1
rl Comm_buf
rl Comm_buffer
djnz Comm_bit_count,:loop
mov W,Comm_buffer ; Get 5-bit word
djnz word_count,Send_next_word ; if not last word, all set
mov Wstate,#Send_Tpar> ; send parity next
mov W,Comm_buffer
jmp Send_next_word
Send_Tpar
mov Wstate,#Send_stop ; point to next word routine
mov W,Tpar ; get transverse parity
jmp Send_next_word
Send_stop
jmp Set_edge_wait ; Go back to receive mode
=
=
; Process received buffer
org 100h
Cmd_exec
Process_cmd
cjbe Command,#7h,Fast_register_read ; is it fast read?
cje Command,#10h,read_register ; is it read register command?
cje Command,#18h,write_register ; is it write register?
cje Command,#19h,reset_status_bits ; is it reset status?
jmp Cmd_process_done
Fast_register_read
- 17

CA 02527068 2006-11-14
mov register_ID,command ; Register number is same as command code
Read_register
mov W,#27
mov W,register_ID-W ; Get index of register to read
jnc Cmd_process_done ; if negative, not a valid register
mov Temp,W ; save index
mov PCLATH,#$< ; set up High-order PC bits
mov W,Temp ; get index
jmp PC+W
jmp cpy_output_reg
jmp cpy_reg_28
jmp cpy_reg_29
jmp cpy_reg_30
Cpy_reg_31 ; Reg 31 = Status register
mov Comm_buf,Status_reg
mov Comm_buf+1,Status_reg+1
mov Comm_buf+2,Status_reg+2
mov Comm_buf+3,Status_reg+3
jmp Setup_reply
Cpy_reg_30 ; Reg 30 = Serial number
call semo
mov comm_buf+3,W
call semo+1
mov comm_buf+2,W
call serno+2
mov comm_buf+1,W
call serno+3
mov comm_buf,W
jmp Setup_reply
Cpy_reg_29 ; Reg 29 = Software type and version
mov Comm_buf,#Software_type
mov Comm_buf+1,#Software_version
mov Comm_buf+2,#0
mov Comm_buf+3,#0 ; Send Software type and version
jmp Setup_reply
Cpy_reg_28 ; Reg 28 = Parameter reg
mov Comm_buf,Parameter_reg
mov Comm_buf+1,Parameter_reg+1
mov Comm_buf+2,Parameter_reg+2
mov Comm_buf+3,Parameter_reg+3
jmp Setup_reply
Cpy_output_reg ; Reg 27 = Output state
mov Comm_buf,Output_bit_reg
mov Comm_buf+1,Output_bit_reg+1
mov Comm_buf+2,Output_bit_reg+2
mov Comm_buf+3,Output_bit_reg+3
jmp Setup_reply
- 18-

CA 02527068 2006-11-14
Write_register
mov Comm_bit_count,#5 ; need to shift buffer by 5
bits
:loop
rl comm buf+4
rl comm_buf+3
rl comm_buf+2
rl comm_buf+1
rl comm_buf
djnz Comm_bit_count,:loop
cjne Register_ID,#28,See_write_output_reg ; Not reg 28, see if
output reg
mov Parameter_reg,Comm_buf
mov Parameter_reg+1,Comm_buf+1
mov Parameter_reg+2,Comm_buf+2
mov Parameter_reg+3,Comm_buf+3 ; Copy received data to reg
clrb Status_LSB.Need_param_refresh_flag ; Reset need parameter
refresh flag
jmp Cpy_reg_28 ; send contents back in reply
See_write_output_reg
cjne Register_ID,#27,Cmd_process_done ; if not output reg,
ignore
mov Output_bit_reg,Comm_buf
mov Output_bit_reg+1,Comm_buf+1
mov Output_bit_reg+2,Comm_buf+2
mov Output_bit_reg+3,Comm_buf+3 ; Copy received data to reg
call Update_outputs
jmp Cpy_output_reg ; send contents back in reply
Reset_status_bits
mov Comm_bit_count,#5 ; need to shift buffer by 5
bits
:loop
rl comm_buf+4
rl comm_buf+3
rl comm_buf+2
rl comm_buf+1
rl comm_buf
djnz Comm_bit_count,:loop
mov W,/Comm_buf+1 ; get byte
and Status_reg+1,W ; Clear bits
mov W,/Comm_buf ; get MSB
and Status_reg,W ; Clear bits
mov Register_ID,#31 ; indicate status reg in reply
jmp Cpy_reg_31
Setup_reply
jb Flags.Global_cmd_flag,Set_edge_wait ; If it was global, don't
reply
mov W,Status_LSB ; Get status LSB
mov Comm_buf+4,W ; preset stored flags
and W,#01fh ; Turn off 3 MSBs
or W,Status_MSB ; Combine 5 LSbs with Status_MSB
sz
setb Comm_buf+4.7 ; If any other flag bits set, indicate in
MSB
- 19 -

,
CA 02527068 2006-11-14
mov Tpar,#1fh ; Initialize parity word
mov Comm_state,#Send_edge ; Go to send_edge state
mov Wstate,#Send_addr ; Point to next routine
mov Comm_bit_count,#Num_start_bits ; Init number of bits
jmp Comm_ret
Cmd_process_done
jmp Set_edge_wait ; No reply needed, done
;
; Exit routines for comm
,
Parity_error
setb status_LSB.Parity_err_flag ; Indicate parity error
Set_edge_wait
mov Comm_state,#Edge_wait ; Go to edge wait state
mov Comm_bit_count,#Num_start_bits ; Init number of bits
jmp Comm_ret
Set_send_reply
mov Comm_state,#Send_edge ; Go to send edge state
mov Comm_bit_count,#Num_start_bits
jmp Comm_ret
Rcv_next_word
mov Comm_state,#Rcv_bits ; set up to receive 6-bit word
mov Comm_bit_count,#6
jmp Comm_ret
Send_next_word
and W,#01fh ; only 5 bits
xor Tpar,W ; update parity calculation
call parity_lookup
mov Comm_buffer,W ; Save word with parity (6 bits)
rl Comm_buffer
rl Comm_buffer ; move to MSbs
mov Comm_state,#Send_bits ; set up to send 6-bit word
mov Comm_bit_count,#6
jmp Comm_ret
Set_rcv_stop
mov Comm_state,#Rcv_stop ; point to next routine
jmp Comm_ret
ORG 200h
Serno
retw 05ah,092h,05fh,000h
,
= retw Offh,Offh,Offh,Offh
,
ds 4
ret
- 20 -

CA 02527068 2006-11-14
=
=
= Returns 6-bit value corresponding to passed 5-bit value with odd parity
;
parity_loolwp
mov Temp,W ; Save index
mov PCLATH,#:table< ; Set up high-order bits
mov W,Temp ; get index
imP Pc w
:table
retw
1,2,4,7,8,11,13,14,16,19,21,22,25,26,28,31,32,35,37,38,41,42,44,47,49,50,52,55,
56,59,61
,62
Sets output bits according to received data
= Comm_buf = Pulse duration in milliseconds
; 0: Continuous output (infinite duration)
1-255: Set output state for specified duration
= After duration is over, turn all outputs off
=
= Comm_buf+1[3] = Bit map of output states - MSB first
; bits 23-18: Unused
bits 17-0: Outputs 18-1
=
Update_outputs
mov W,Comm_buf+3 ; get lsbs
and W,#03h ; only need 2 bits
mov Temp,W
add Temp,W ; Shift into bits 1 and 2 (X1 and X2)
mov W,PORTA ; Get present status of port A pins
and W,#0f9h ; clear output control bits
or W,Temp ; Set desired output state
mov PORTA,W ; output new value
rr comm_buf+1
rr comm_buf+2
rr comm buf+3
ff COMM_bUf-F 1
ff comm_buf+2
rr comm_buf+3 ; shift buffer left 2 bits
mov PORTB,comm_buf+2
mov PORTC,comm_buf+3
mov !PORTA,#init_TRISA
mov !PORTB,#init_TRISB
mov !PORTC,#init_TRISC
mov Millisecs,Comm_buf ; first byte is pulse duration
jz done_output_set
ms_loop
- 21

CA 02527068 2006-11-14
mov Timeout_ctr,#ms_preset<
mov Timeout_ctr+1,#ms_preset>
:loop
djnz Timeout_ctr+1,:loop
djnz Timeout_ctr,:loop
djnz Millisecs,ms_loop ; delay for pulse duration
and PORTA,#0f9h ; turn off X1 and X2
clr PORTB
clr PORTC ; turn off other outputs
done_output_set
ret
;
Main Program start
=
Main_loop
mov !PORTA,#Init_TRISA ; Initialize port A direction
mov !PORTB,#Init_TRISB ; Initialize port B direction
mov !PORTC,#Init_TRISC ; Init port C direction
mov Clk_timeout_ctr,#12 ; preset ...
clr Clk_timeout_ctr+1 ; ... clock timeout counter
clrb Flags.Clk_wait_flag ; Indicate waiting for clock low
Clkwait_loop
djnz scratch,Clk_cont
clr WDT ; Reset watchdog
djnz Clk_timeout_ctr+1,Clk_cont
djnz Clk_timeout_ctr,Clk_cont
jb Status_MSB.POR_flag,got_POR ; Ignore clock timeout until
POR flag
cleared
setb Status_MSB.Clk_timeout_flag ; Indicate timeout on comm clock
jmp
Clk_cont
jb Comm_port.clock_in,:high ; clock high
:low
jb Flags.Clk_wait_flag,Clkwait_loop
mov Input_hold,Comm_port ; Save Data port value
setb Flags.Clk_wait_flag ; Indicate waiting for clock high
jmp Clkwait_loop
:high
jnb Flags.Clk_wait_flag,Clkwait_loop
djnz NPR_timer+1,:cont ; Dec LSB of need parm timer
djnz NPR_timer,:cont ; Dec MSB
setb Status_LSB.Need_param_refresh_flag ; set flag every 64k clocks
:cont
mov PCLATH,#0 ; Set up high-order bits for routines
in page 0
mov W,Comm_state ; get vector
jmp W ; Execute comm state machine
Comm_ret
- 22 -

CA 02527068 2006-11-14
jmp Main_loop
- 23 -

CA 02527068 2006-11-14
PIC.DEF
/*
include file for serial communication with PIC chips
*1
#pragma switch(ALL,FREQ)
switch (PIC_serial_status)
case sending_bits:
case sending_st5_bits:
#ifdef VATEST
out_bit_value = (PICxmitBuf. bits.bufLong[0] & 0x80000000) != 0; /* out bit
value =
MSB */
PICxmitButbits.bufLong[0] = PICxmitBuf. bits.bufLong[0] 1;
if (PICxmitBuf. bits.bufLong[1] & 0x80000000)
PICxmitBufbits.bufLong[0]++;
PICxmitBufbits.bufLong[1] = PICxmitBuf. bits.bufLong[1] 1;
if (PICxmitBuf. bits.bufLong[2] & 0x80000000)
PICxmitBuf.bits.bufLong[1]++;
PICxmitButbits.bufLong[2] = PICxmitBuf. bits.bufLong[2] 1; /* Shift 96-bit
buffer */
#else
out_bit_value = 0;
shift_LSB_ptr = &PICxmitBuf. bits.bufByte[12]; /* point past least significant
word of 96-
bit register */
asm(" MOVE.L _shift_LSB_ptr,A0", /* Get pointer to buffer, clear
carry */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* 96 bits have been shifted, MSB is in carry */
" ROXL.W _out_bit_value" /* Put MSB in out_bit_value */
);
#endif
break;
case do_send_cmd:
bit _count = NUM_START_BITS-1;
PIC_serial_status = sending_start;
out_bit_value = 0;
break;
case do_PIC_start :
bit_count = 3 * BITS_PER_SEC;
out_bit_value = 1;
PIC_serial_status = sending_PIC_start;
break;
case sending_start:
- 24 -

CA 02527068 2006-11-14
out_bit_value = 0;
break;
case sending_stop:
case sending_start_l:
out_bit_value = 1;
break;
default:
out_bit_value = 1;
if (out_bit_value)
fs1004.io.pulseOut2Off = 1;
else
fs1004.io.pulseOut2Off = 0; /* Send bit out */
in_bit_value = fs1004.io.pulseIn1State; /* Get rcvd bit value */
fs1004.io.pulseOut1Off = 1; /* Send clock rising edge */
switch (PIC_serial_status)
case waiting_for_start:
if (in_bit_value == 0)
zero_count++;
else
if (zero_count == (NUM_START_BITS-1))
PIC_serial_status = rcving_bits;
bit_count = PICrcyBufbitCount + 1;
else
zero_count = 0;
break;
case rcving_bits:
#i fdef VATEST
PICrcyButbits.bufLong[0] = PICrcyBufbits.bufLong[0] 1;
if (PICrcyBufbits.bufLong[1] & 0x80000000)
PICrcyBufbits.bufLong[0]++;
PICrcyBufbits.bufLong[1] = PICrcyBufbits.bufLong[1] 1;
if (PICrcyButbits.bufLong[2] & 0x80000000)
PICrcyBuf. bits.bufLong[1]++;
PICrcyBufbits.bufLong[2] = (PICrcyBuf. bits.bufLong[2] << 1) +
in_bit_value;
#else
shift_LSB_pft = &PICrcyBufbits.bufByte(12]; /*
point past least significant word of
96-bit register */
asm(" MOVE.L _shift_LSB_pft,A0", /* Get pointer
to buffer, clear carry */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
- 25 -

,
CA 02527068 2006-11-14
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)", /* rotate left and decrement pointer */
" ROXL.W -(A0)" /* 96 bits have been shifted, LSb is unknown */
);
PICrcyBuf.bits.bufByte[111 =
(PICrcyBufbits.bufByte[11] & Oxfe) I in_bit_value; /* add in received bit
*/
#endif
break;
default:
{
1
1
if (--bit_count <= 0)
{
switch (PIC_serial_status)
{
case rcving_bits:
PIC_serial_status = rcving_stop;
bit_count = 1;
break;
case sending_bits:
PIC_serial_status = sending_stop;
bit_count = 1;
break;
case sending_stop:
if (PICxmitBuf.PIC_addr == GLOBAL_PIC_ADDR)
PIC_serial_status = idle;
else
{
PIC_serial_status = waitingfor_start;
bit_count = PIC_wait_limit;
zero_count = 0;
}
break;
case sending_PIC_start:
PIC_serial_status = idle;
break;
case sending_start:
PIC_serial_status = sending_start_1;
bit_count = 1;
break;
case sending_start_l:
PIC_serial_status = sending_bits;
bit_count = PICxmitBuf.bitCount;
break;
case waiting_for_start:
- 26 -

CA 02527068 2006-11-14
PICrcvfiufflags 1= rcv_timeout_flagIrcv_data_ready_flag;
PIC_serial_status = idle;
break;
case rcving_stop:
if (in_bit_value == 0)
PICrorBuf.flags1= rcv_bad_length_flag;
PIC_serial_status = idle;
PICrcvfiutflags1= rcv_data_ready_flag;
bit_count = 1;
break;
default:
PIC_serial_status = idle;
#pragma switch(ALL,NOFREQ)
- 27 -

CA 02527068 2006-11-14
PULSE.0
#include "mtrlink.der
/* #include "flash.def' */
#define PSTRU_DEFINED
#include "pulselink.der
#include "pulse.h"
#include "ufloat.h"
#include "log.h"
#include "alarm.h"
#include "copymem.h"
#include "plcctrl.h"
#include <stdio.h>
#ifdef fakeMC5
#undef NUMPH
#define NUMPH 24
#endif
/* define WDT flags for the PIC communication routine */
#pragma region ("ram=WDTFlags")
short int WDTpulseSec ;
#pragma region ("ram=ram")
#pragma region ("data=secondBack")
void (*pulseSecondp)(void)=pulseSecond;
#pragma region ("data=data")
#ifndef IS_MC5
#pragma region ("data=everySubsecond")
#ifdef IS_RSM
void (*pulseSubsecp)(void)=pulseSubsecond ;
#else
void (*pulseSubsecp)(void)=pulseService;
#endif
#pragma region ("data=data")
#endif
#pragma region ("data=powerUp")
void (*pulseStartupp)(void)=pulseStartup ;
#pragma region ("data=data")
#pragma region ("data=dayBack")
- 28

1
CA 02527068 2006-11-14
,
void (*pulseDayp)(void)=pulseDay ;
#pragma region ("data=data")
/* clear out PIC */
void pulseColdstart()
1
int i ;
for (i=0; i<num_PICs; i-H-)
if (PIC_statuslitsoftware_type == 3)
{
PIC_statuslitclear_pulse_regs = TRUE;
PIC_statuslitget_status = TRUE;
1
clear state = SEND_GLOBAL_CLR;
1
void pulseStartup(void)
1
int i;
#ifndef IS_RSM
int work_PIC_addr;
#endif
#ifdef IS_MC5
int work_num_pulses;
#endif
#ifdef VATEST
/* test !!!!! */
temp_command = SYSTEM_CONTROL;
temp_reg_ID = 0;
temp_command_data = READ_ENCODER_ID;
temp_flags = rcv_data_ready_flag;
#endif
for (i=0;(!dont_clear_PIC_stats) && (i<(2*NUMPH));i++)
1
pulseDatanerror_cnt = 0;
pulseData[i].ID_field[0]=0;
pulseData[i]seading = 0;
)
for (i=0; i<MAX_PICS; i++)
PIC_status[i].PIC_addr = 0;
hold_num_pulse_ctrs = releaseCodep->option.numPulseCounters;
if (hold_num_pulse_ctrs > NUMPH)
num_pulse_ctrs = NUMPH;
- 29 -

CA 02527068 2006-11-14
else
num_pulse_ctrs = hold_num_pulse_ctrs;
num_PICs = 1;
#ifdef IS_MC5
PIC_status[0].PIC_addr = MC5_MUX_PIC_ADDR; /* If MC5, add PDM PIC(s) to PIC
table
*/
if (int_configltmessg.configLTM[PULSE1].accum)
work_num_pulses = num_pulse_ctrs;
work_PIC_addr =0;
while (work_num_pulses > 0)
PIC_status[num_PICs++].PIC_addr = work_PIC_addr++; /* Pulse counters for Q13
*/
work_num_pulses -= 4;
if (int_configltmessg.configLTM[PULSEnaccum)
work_num_pulses = num_pulse_ctrs;
work_PIC_addr = 6;
while (work_num_pulses > 0)
{
PIC_status[num_PICs++1.PIC_addr = work_PIC_addr++; /* Pulse counters for Q14
*/
work_num_pulses -=4;
num_LCMs = releaseCodep->option.LCM_flags & 0x03;
work_PIC_addr = LCM_BASE_ADDR;
for (i=0;i<num_LCMs;i+-F)
PIC_status[num_PICs++1.PIC_addr = work_PIC_addr++; /* LCM's */
1
#else
#ifdef IS_ST5
PIC_status[0].PIC_addr = ST5_MUX_PIC_ADDR; /* If ST5, add mux to PIC table */
ATM_work = releaseCodep->option.couplers_mask;
work_PIC_addr = ATM_BASE_ADDR;
for (i=0;i<4;i++)
{
if ((ATM_work & 0x08) != 0)
/* Bit is set in mask, add ATM PIC to table */
PIC_status[num_PICs++1.PIC_addr = work_PIC_addr;
1
work_PIC_addr++;
ATM_work = ATM_work 1;
#else
if (num_pulse_ctrs == 0)
- 30 -

CA 02527068 2006-11-14
num_PICs =0;
#endif
#endif
for (i=0; i<MAX_PICS; i++)
/* Build PIC table */
PIC_statusgget_serno = TRUE;
PIC_status[i].get_version = TRUE;
PIC_status[aget_status = FALSE;
PIC_statusnreset_status = FALSE;
PIC_statusnupdate_parameter = FALSE;
if (!dont_clear_PIC_stats)
PIC_statusfil.PIC_reset_count = 0;
PIC_status[i].comm_error_count = 0;
PIC_status[i].PIC_data_err_count = 0;
PIC_status[i].software_type =0;
PIC_statusnsoftware_version =0;
PIC_status[i].serial_number = 0;
PIC_status[i].curr_pulse_reg = 0;
#ifdef IS_MC5
if (PIC_status[i].PIC_addr >= ST5_MUX_PIC_ADDR)
PIC_status[i] .reply_wait_limit = DIRECT_PIC_WAIT_LIMIT;
else
PIC_statuslitreply_wait_limit = BUFEL.RED_PIC_WAIT_LIMIT;
#else
PIC_status[i].reply_wait_limit = DIRECT_PIC_WAIT_LIMIT;
#endif
if (P1C_status[i].PIC_addr <= MAX_PULSE_PIC_ADDR)
PIC_status[i].num_pulse_regs = PULSES_PER_PIC;
else
PIC_status[il.num_pulse_regs = 0;
current_PIC_index =0;
rcv_PIC_index =0;
if (dont_clear_PIC_stats)
dont_clear_PIC_stats = FALSE; /* Clear flag */
else
PIC_bad_addr_count = 0;
PICrcyBufflags =0;
PIC_serial_status = do_PIC_start;
PIC_clk_state = clk_low; /* Initialize
serial comm variables */
-31-

i
CA 02527068 2006-11-14
..
}
clear_state = NO_GLOBAL_SEND;
pulseOutMode = releaseCode.option.picMode ; /* for compatibility with old code
*/
if (startup.coldStart)
{
pulseColdstart() ;
)
1
const unsigned char parity6[32] =
{1,2,4,7,8,11,13,14,16,19,21,22,25,26,28,31,32,35,37,38,41,42,44,47,49,50,52,55
,56,59,61,62);
void pulseDay()
(
dont_clear_PIC_stats = TRUE; /* Tell pulseStartup not to clear error counts */
rebuild_timer = REBUILD_DELAY; /* Set up for delayed table rebuild */
1
void pulseSecond()
{
#ifndef IS_ST5
pulseService();
#endif
if (Comm_background_flags.do_rebuild)
1
pulseStartup();
Comm_background_flags.do_rebuild = FALSE;
1
if (Comm_background_flags.do_alarm)
{
putAlarm(&PIC_alarm,4);
Comm_background_flags.do_alann = FALSE;
1
1
/* set_PLC_relays function *1
/* Called from PLC routines to request update of */
/* PLC port multiplexer PIC chip on 5T5 power board */
#ifdef IS_ST5
void set_PLC_relays(int xmitRelay,int rcvRelay)
1
while (MUX_control.active_flaglIMUX_control.request_flag)
1
ccwait();
- 32 -

CA 02527068 2006-11-14
MUX_control.xmit_mask = xmitRelay;
MUX_controlscv_mask = rcvRelay;
MUX_control.done_flag = FALSE;
MUX_controlsequest_flag = TRUE;
if ((MUX_control.xmit_mask != MUX_controllast_xmit_mask) II
(MUX_control.rcv_mask != MUX_control.last_rcv_mask))
while OMUX_control.done_flag &&
!(MUX_control.active_flag && (PIC_serial_status == rcving_bits)) )
ccwait();
I
#endif
void pulseService(void)
{
BOOLEAN need_pulse_read,
copy_rcvd_data,
rev_buf err;
#ifdef IS_MC5
BOOLEAN
got_ver_3,
got_ver_3_3;
int I;
unsigned char *work_char_ptr;
unsigned long work_bit_mask;
#endif
int work_pulse_index;
phaccum accumXfer;
int i ;
if (num_PICs == 0)
PIC_serial_status = idle;
if (PIC_serial_status == idle)
if (!WDTpulseSec)
WDTpulseSec=1; /*Tell WDT controller that we are OK*/
if (hold_num_pulse_ctrs != releaseCodep->option.numPulseCounters)
- 33 -

CA 02527068 2006-11-14
/* hdwr -n has changed */
dont_clear_PIC_stats = FALSE;
rebuild_timer = 1; /* Force immediate table rebuild */
if ((PIC_serial_status = idle) &&
(rebuild_timer != 0) &&
(--rebuild_timer == 0))
Comm_background_flags.do_rebuild = TRUE;
1
else if ((PIC_serial_status == idle) &&
(num_PICs != 0) &&
(pulseOutMode != PIC_MC_SERIAL) &&
(!Comm_background_flags.do_rebuild)) /* Serial processing enabled? */
if (PICrcyBuf.flags & rcv_data_ready_flag)
/* Process received message */
PICro/Buf. flags &= -rcv_data_ready_flag;
rcv_buf err = !decode_rcv_buffer();
if ((PIC_comm_mon.control_flags & RCV_DATA_RDY) =0)
PIC_comm_monscv_buf = PICrcyBuf;
PIC_comm_mon.control_flags1= RCV_DATA_RDY;
if ((ext_comm.control_flags & CPY_RCV_DATA) != 0)
ext_commscv_buf = PICrcyBuf;
ext_comm.control_flags &= -CPY_RCV_DATA;
ext_comm.control_flags 1= RCV_DATA_RDY;
#ifdefIS_ST5
if (ATM_control.active_flag)
ATM_controlsesult_flags = PICrcyBufflags;
if (rcv_buf err)
if (ATM_control.state != WAIT_ALIGN)
{
ATM_controkerror_flag = TRUE;
ATM_control.active_flag = FALSE;
ATM_control.done_flag = TRUE;
else
switch (ATM_control.state)
-34-

CA 02527068 2006-11-14
case DO_PRESET:
ATM_control.xmit_level = PICrcyBulcommand_data 24;
ATM_control.coupler_level = (PICrcyBuf.command_data 16) & OxOff;
ATM_control.active_flag = FALSE;
1
break;
case SET ALIGN:
ATM_control.state = WAIT_ALIGN;
break;
case WAIT_ALIGN:
ATM_control.optimum_cap_code = PICrevriutcommand_data &
ATM_RC_CAP_MASK;
ATM_control.optimum_reading = PICro/Buf.command_data >> 16;
ATM_control.result_flags 1= (PICrcv13uf.command_data & Oxe000);
/* Copy flags from reply */
if ((ATM_controlsesult_flags & Oxc000) != 0)
/* Analog levels out of range */
ATM_control.error_flag = TRUE;
1
if (ATM_control.optimum_reading < ATM_MIN_READING)
ATM_controlsesult_flags 1= Ox1000; /* Indicate reading too low */
ATM_control.error_flag = TRUE;
1
ATM_control.active_flag = FALSE;
break;
case DO_PLC_SET:
case DO_ATM_DISCONNECT:
ATM_control.active_flag = FALSE;
break;
default:
ATM_control.active_flag = FALSE;
ATM_control.error_flag = TRUE;
break;
if (!ATM_control.active_flag)
ATM_control.done_flag = TRUE;
if (MUX_control.active_flag)
- 35 -

CA 02527068 2006-11-14
MUX_control.result_flags = PICrcyBuf. flags;
if (rcv_buf err)
MUX_control.error_flag = TRUE;
MUX_control.last_xmit_mask =0;
MUX_control.last_rcv_mask =0;
1
else
MUX_control.last_xmit_mask = PICro/Buf.command_data & Oxff;
MUX_control.last_rcv_mask = (PICro/Buf.command_data >> 8) & Oxff;
1
MUX_control.active_flag = FALSE;
MUX_control.done_flag = TRUE;
1
#endif
if (rcv_buf err)
#ifdef IS_ST5
if (!ATM_control.active_flag (ATM_control.state != WAIT_ALIGN))
#endif
last_comm_err_flag = PICrcyBuf. flags;
copymem(sizeof (PICbitBuf), (char *) (&HoldrcyBuf), (char *) (&PICro/Buf));
if ((PICrcyBuf. flags & rcv_bad_addr_flag) != 0)
{ /* past end of valid PICs, address error */
PIC_bad_addr_count++;
set_PIC_alarm(PIC_adderr_O,PICro/Buf.PIC_addr,
(PICxmitBuf.PIC_addr 8)+PICxmitBuf.command);
1
else
( /* PIC address was valid, but comm failed */
PIC_status[rcv_PIC_index].comm_error_count++;
if (PIC_status[rcv_PIC_indextcomm_error_count > 2)
set_PIC_alarm(PIC_comerr_O,PIC_status[rcv_PIC_indexl.PIC_addr,
PICrcyBufflags);
1
/* Lost contact with PIC, read serial number and software version */
PIC_status[rcv_PIC_index] .get_serno = TRUE;
PIC_status[rcv_PIC_index] .get_version = TRUE;
1
else
/* Valid message received */
if ((PICrcyBuf.command == READ_REGISTER) && (PICro/Bufseg_ID ==
STATUS_REG))
- 36

,
CA 02527068 2006-11-14
process_status_bits();
}
else if (PICrcyBuf.command == SYSTEM_CONTROL)
{
if (PICrcyBufreg_ID == STATUS_REG)
{ /* Response frome reset status bits cmd */
PIC_status[rcv_PIC_index] .reset_status = FALSE;
process_status_bits();
I
else if ( (PIC_status[rcv_PIC_index].software_type == 4) &&
((PIC_status[rcv_PIC_index].last_cmd_data & Oxffff0000) ==
READ_ENCODER_ID) )
{ /* response from encoder read ID comd */
work_pulse_index = (PICrcyBuf.PIC_addr * PULSES_PER_PIC) +
PICrcyBuf.reg_ID;
i = (PIC_status[rcv_PIC_index] .last_cmd_data 8z Ox0000ff00) 8;
work_char_ptr = (unsigned char *) &PICrcyBuf.command_data;
for (j=0; j<4 ; j++)
{
if ((*work_char_ptr == 0)11(i >= ID_F1ELD_LENGTH))
{
j = 10; /* indicate end of message found */
I
else
{
pulseData[work_pulse_index].[D_buffer[i] = *work_char_ptr;
i++;
work_char_ptr-i-+;
I
}
if (j>5)
( /* found end of ID field from remote encoder */
for (i=0; i<ID_FIELD_LENGTH; i++)
{
pulseData[work_pulse_index].ID_field[i] =
pulseData[work_pulse :index].ID_buffer[i];
pulseData[work_pulse_indexLID_buffer[i] = 0;
I
I
}
I
else if ((PICrcyBuf.command == READ_REGISTER) && (PICrcliBuf.reg_ID ==
ERROR_REG))
{
if (PIC_status[rcv_PIC_indexlsoftware_type == 4)
{ /* Remote encoder interface module */
work_pulse_index = (PICro/Buf.PIC_addr * PULSES_PER_PIC) +
(PICrcyBuf.command_data 24);
if (work_pulse_index < (2 * NUMPH))
(
- 37 -

CA 02527068 2006-11-14
pulseData[work_pulse_index].error_cnt++;
for (i=0; i<ID_FIELD_LENGTH;
pulseData[work_pulse jndex1.1D_buffer[i++] = 0);
ttendif
else if ((PICrcyBuf.command == WRITE_REGISTER) && (PICrcvfiutreg_ID ==
PARM_REG))
PIC_status[rcv_PIC_indextupdate_parameter = FALSE;
else if ((PICrcvfiuf.command == READ_REGISTER) && (PICrcv13ufreg_ID ==
VERS_REG))
PIC_status[rcv_PIC_index]. get_version = FALSE;
PIC_status[rcv_PIC_index].software_type =
(PICrcyBuf.command_data & Oxff000000) >> 24;
PIC_status[rcv_PIC_index].software_version =
(PICreviiuf.command_data & Ox0Off0000) 16;
PIC_status[rcv_PIC_index].loop_rate =
(PICrcyButcommand_data & Ox0000ftD0) >> 8;
else if ((PICro/Butcommand --= READ_REGISTER) && (PICrcvfiuf.reg_ID ==
SERNO_REG))
PIC_status[rcv_PIC_index] .get_semo = FALSE;
PIC_status[rcv_PIC_indextserial_number = PICro/Buf.command_data;
else if (OPICrcv13utcommand == READ_REGISTER) II (PICreviiutcommand <=
MAX_FAST_READ))
&& (PICrcvl3utreg_ID <= MAX_PULSE_REG))
/* Pulse reading */
work_pulse_index = (PICrcyBuf.PIC_addr * PULSES_PER_PIC) +
PICrcyBufreg_ID;
if (work_pulse_index < (NUMPH * 2))
pulseData[work_pulse_index] .reading = PICrcyBuf.command_data;
copy_rcvd_data = FALSE;
if (PIC_status[rcv_PIC_index].get_version)
else if (PIC_status[rcv_PIC_index]. software_type == 4)
/* Remote encoder interface module */
copy_rcvd_data = TRUE;
accumXfer.low = pulseData[work_pulse_index].reading;
else if (PIC_status[rcv_PIC_index].software_type == 3)
/* Remote pulse counter module */
copy_rcvd_data = TRUE;
- 38 -

CA 02527068 2006-11-14
if (!PIC_status[rcv_PIC_indexl.get_semo)
sprintf((char *) pulseData[work_pulse indext1D_field,"S%081dP%d",
PIC_status[rcv PIC_index].seriallnumber,
PICrcvflutreglID);
if (releaseCode.option.countEveryEdge)
accumXfer.low = pulseData[work_pulse_index] .reading;
1
else
accumXfer.low = pulseData[work_pulse_index].reading 1;
1
1
accumXfer.high = OL;
#ifndef VATEST
if (copy_rcvd_data)
#ifndef IS MC5
¨/* It is an RSM or ST5, so mapping for pulse 1 thru 4 is M1Q13, M1Q14, M2Q13,
M2Q14 */
ph[0][work_pulse_index/2][(work_pulse_index&Ox01)?PULSE2:PULSEl] .accum =
ph [1] [work_pulse_index/2] [(work_pulse_index&Ox01)?PULSE2:PULSE1] .accum =
accumXfer ;
#else
/* It is an MC5, so mapping for pulse 1 thru 48 is M1Q13..M24Q13,
M1Q14..M24Q14 */
ph[0][work_pulse_index%NUMPH]Rwork_pulse_index/NUMPH)?PULSE2:PULSE1].accum =
ph[l][work_pulse_index%NUMPH]Rwork_pulse_index/NUMPH)?PULSE2:PULSEllaccum =
accumXfer ;
#endif
#endif
1
1
if ((PICrcvfluf. flags & (PIC_error_flag I PIC invalid_data_flag)) != 0)
PIC status[rcv_PIC indextget_status = TRUE;
if ((PIC¨rcvBuf.flags &¨PIC_need refresh_flag) != 0)
PIC status[rcv_PIC indextup¨date_parameter = TRUE;
/* check status flags */
- 39 -

CA 02527068 2006-11-14
/* Decide what command to send */
PICxmitBuf.flags = 0;
#ifndef IS_ST5
/* MC5 or RSM, check for cold-start processing to clear pulse registers */
if (clear_state == SEND_GLOBAL CLR)
/* Cold start, send global clr */
PICxmitBuf.PIC_addr = GLOBAL PIC ADDR;
PICxmitBuf.command = CLEAR_PULS¨E_REGISTERS;
format_xmit buffer();
clear_state = SENDING_GLOBAL_CLR;
PIC_serial_status = do_send_cmd; /* Start UART */
else if (clear_state == SENDING_GLOBAL_CLR)
clear_state = GLOBAL_CLR_SENT;
1
#else
/* ST5, check for ATM (Automatic Tuning Module) operations */
if (ATM_controlsequest_flag)
ATM_controlsequest flag = FALSE;
fl
ATM_control.error_¨ag = FALSE;
ATM_control.active_flag = TRUE;
ATM_control.state = ATM DONE;
PICxmitBuf.PIC_addr = AT¨M_control.ATM_number + ATM_BASE_ADDR;
switch (ATM_control.operation)
case SET PRE_ALIGN:
PICxmi¨tBuf.command = WRITE REGISTER;
PICxmitBufseg_ID = OUTPUT ¨REG;
PICxmitBuf.command_data = A¨TM_control.start_cap_code &
ATM_RC CAP_MASK;
PICxmitBuf.command data1= ATM_PRESET_CODE;
ATM_control.state = D¨O_PRESET;
break;
case DO_ALIGN:
PICxmitBuf.command = WRITE REGISTER;
PICxmitBufseg_ID = CONTROL¨ REG;
if (ATM_control.start_cap_code > ATM_control.end_cap_code)
= - 40 -

CA 02527068 2006-11-14
ATM control.end_cap_code = ATM_control.start_cap_code;
PICxmi¨tBuf.command_data = ATM_control.start_cap_code &
ATM_RC_CAP_MASK;
PICxmitBuf.command_data = (PICxmitBuf.command_data 12)
(ATM_control.end cap_code & ATM_RC_CAP_MASK)
(ATM MEAS_TI¨ME 24);
ATM_control.state = SET_ALIGN;
ATM_control.align_timer = ATM_control.end_cap_code -
ATM_control.start_cap_code;
ATM_control.align_timer *= ((ATM_DISC_TIME + ATM_MEAS_TIME +4) *
(1.25 /62.5));
ATM_control.align_timer += 13; /* Time in 1/64 sec to wait before checking
result */
/* Number of steps * time per step + 25% + .2 second */
break;
case SET NORMAL_PLC:
PICxmitBuf.command = WRITE_REGISTER;
PICxmitBuf. reg_ID = OUTPUT_REG;
PICxmitBuf.command_data = ATM_control.optimum_cap_code &
ATM_RC_CAP_MASK;
PICxmitBuf.command_data1= ATM PLC_CODE;
ATM_control.state = DO_PLC_SET
break;
case DISCONNECT_COUPLER:
PICxmitBuf.command = WRITE_REGISTER;
PICxmitBufreg_ID = OUTPUT REG;
PICxmitBuf.command_data = A¨TM_control.optimum_cap_code &
ATM_RC_CAP_MASK;
PICxmitBuf.command data1= ATM DISC CODE;
ATM control.state = DO_ATM_DISCONNE¨ CT;
break
default:
case READ_XMIT_LEVEL:
ATM_control.error_flag = TRUE;
ATM_control.done_flag = TRUE;
ATM_control.active_flag = FALSE;
break;
if (ATM_control.active_flag)
f
format_xmit_buffer();
PIC_wait limit = DIRECT PIC_WAIT_LIMIT;
PIC_seria¨l_status = do_send_cmd; /* Start UART */
1
-41 -

CA 02527068 2006-11-14
else if (ATM_control.active_flag)
if ((ATM_control.state != WAIT_ALIGN) II
(--ATM_control.align_timer <= 0))
ATM_control.error_flag = TRUE;
ATM_control.done_flag = TRUE;
ATM_control.active_flag = FALSE;
}
else
/* poll ATM for auto-tune end */
PICxmitBuf.command = 0;
format_xmit_buffer();
= DIRECT_PIC_WAIT_LIMIT;
PIC_serial_status = do_send_cmd; /* Start UART */
1
else if (MUX_controlsequest_flag)
MUX_controlsequest_flag = FALSE;
MUX_control.error_flag = FALSE;
if ((pulseOutMode == PIC_ST_SERIAL))
PICxmitBuf. bits.bufByte[0] = ((MUX_controlscv_mask & 0x03) 5) I
((MUX_control.xmit_mask & Ox7f) >> 2);
PICxmitBuf. bits.bufByte[1] = ((MUX_control.xmit_mask & 0x03) 6);
bit_count = 11;
PIC_serial_status = sending_st5_bits; /* Start UART */
MUX_control.last_xmit_mask = MUX_control.xmit_mask;
MUX_control.last_rcv_mask = MUX_control.rcv_mask;
MUX_control.done_flag = TRUE;
1
else
MUX_control.active_flag = TRUE;
PICxmitBuf.PIC_addr = ST5_MUX_PIC_ADDR;
PICxmitBuf.command = WRITE_REGISTER;
PICxmitBufreg_ID = OUTPUT_REG;
PICxmitBuf.command_data = (MUX_controlscv_mask 8) +
MUX_control.xmit_mask;
format_xmit_buffer();
PIC_wait_limit = DIRECT_PIC_WAIT_LIMIT;
PIC_serial_status = do_send_cmd; /* Start UART */
1
1
*tendif
-42 -

CA 02527068 2006-11-14
else if ((ext_comm.control_flags & (XMIT DATA_RDY I XMIT_REQUEST)) =
(XMIT_DATA_RDY I XMIT_REQUEST))
1 /* Send command for external routine */
PICxmitBuf = ext_comm.xmit buf;
ext_comm.control_flags &= ¨XMIT_REQUEST;
ext_comm.control_flags 1= CPY_RCV_DATA;
/* Look up correct PIC status
index for reuested PIC */
for (i=0; ((i<MAX_PICS¨) && (PIC_status[i].PIC_addr != PICxmitBuf.PIC_addr));
i++);
if (i < num_PICs)
PIC_status[i]last_cmd_data = PICxmitBuf.command data;
PIC_status[i].last_command = PICxmitBuf.command7
#ifdef IS_MC5
if (ext comm.xmit_buf.PIC addr < ST5 MUX PIC ADDR)
= ______________ L
AI¨LIMIT;
else
#endif
PIC_wait_limit = DIRECT_PIC_WAIT_LIMIT;
format_xmit_buffer();
PIC_serial_status = do_send_cmd; /* Start UART */
1
else if ( ((ext_comm.control_flags & SUPPRESS_NORMAL_COMM) == 0)
&& (--ST5_PIC_delay_ctr <= 0))
ST5_PIC_delay_ctr = ST5_PIC_DELAY; /* Slow down routine communications in the
ST5 */
#else
#endif
PICxmitBuf.PIC addr = PIC_status[current PIC_index].PIC_addr;
need_pulse_readl TRUE; /* Set defaults */
#ifdef IS_ST5
if ((pulseOutMode == PIC_ST SERIAL) &&
(PICxmitBuf.PIC_addr == ST5_MUX_PIC_ADDR))
1
else
#endif
-43 -

CA 02527068 2006-11-14
if (PIC_status[current_PIC_index] .force_pulse_read &&
OPIC_status[current_PIC_indexl.get_version) &&
(PIC_status[current_PIC_index].PIC_addr < ST5_MUX_PIC_ADDR) )
PIC_status[current_PIC_index].force_pulse_read = FALSE;
else
PIC_status[current_PIC_index].force_pulse_read = TRUE;
#ifndef IS_ST5
if (PIC_status[current_PIC_indextclear_pulse_regs &&
(clear_state == GLOBAL_CLR_SENT) )
/* Global clear sent, get status */
need_pulse_read = FALSE;
PICxmitBuf.command = READ_REGISTER;
PICxmitBufseg_ID = STATUS_REG;
format_xmit_buffer();
else
#endif
if (PIC_status[current_PIC_index].get_version)
need_pulse_read = FALSE;
PICxmitBuf.command = READ_REGISTER;
PICxmitBuf. reg_ID = VERS_REG;
format_xmit_buffer();
else if (PIC_status[current_PIC_index] .get_serno)
need_pulse_read = FALSE;
PICxmitBuf.command = READ_REGISTER;
PICxmitBuf. reg_ID = SERNO_REG;
format_xmit_buffer();
else if (PIC_status[current_PIC jndex] .update_parameter)
1
PICxmitBuf.command = WRITE_REGISTER;
if (PIC_status[current_PIC_index]. software_type == 3)
/* Pulse ctr */
/* Pulse ctr parameters: *1
/* Power-On sample rate: 42/sec */
/* Power-off sample rate: 1/sec */
/* Days to count if rcving pulses: */
/* RSM: 5 days *1
/* PDM: 35 days */
/* Days to count if no pulses rcvd: */
/* RSM: 1 day */
/* PDM: 3 days */
-44 -

CA 02527068 2006-11-14
/* on RSM, the 2 lsbs of */
/* load_shed_mask[0] are sent to */
/* the PIC output bits *1
#ifdef IS_RSM
PICxmitButcommand_data = Ox01150507 &
(load_shed_state[0] I Oxfffffffc);
#else
PICxmitButcommand_data = 0x0115230d;
#endif
#ifdef IS_MC5
else if (PIC_status[current_PIC_index] software_type == 4)
/* Remote encoder reader */
PICxmitBuf.command_data = READ_ENCODER_PARM;
if ((releaseCodep->option.couplers_mask & Ox01) == 0)
/* If mask bit 0 is 0, no touch-pad compatibility */
PICxmitBuf.command_data &= Oxff0Offff;
1
else if (PIC_status[current_PIC_index].software_type == 5)
/* MC5 mux */
got_ver_3 = got_ver_3_3 = FALSE;
for (i=0; i<num_PICs; i-H-)
if (PIC_status[i].get_version)
got_ver_3 = TRUE;
got_ver_3_3 = TRUE;
1
else if (PIC_statusnsoftware_type == 3)
got_ver_3 = TRUE;
if (PIC_status[i].software_version == 3)
got_ver_3_3 = TRUE;
}
if (got_ver_3)
if (got_ver_3_3 &&
((releaseCodep->option.couplers_mask & 0x02) != 0))
PICxmitBuf.command_data = Ox0c007000; /* 32 bps, periodic wake-up */
1
else
PICxmitBuf.command_data = 0x0c007080; /* 32 bps, no wake-up */
}
1
else
-45 -
,

CA 02527068 2006-11-14
PICxmitBuf.command_data = 0x02030080; /* 205 bps, no wake-up */
#endif
#ifdef IS_ST5
else if (PIC_status[current_PIC_indextsoftware_type == 8)
/* Auto tune module */
PICxmitBuf.command_data = 0x02030000 I (ATM_DISC_TIME << 8) I
(ATM_RC_XMIT_ON 8)1ATM_NUM_CAP_BITS;
/* xmit offset = 2, cplr offset = 3, */
/* relay delay = ATM_DISC_TIME, Xmit mask = ATM_RC_XMIT_ON, */
/* number of capacitor relays = ATM_NUM_CAP_BITS
else if (PIC_status[current_PIC_index] .software_type == 6)
/* ST5 mux */
PICxmitBuf.command_data = Ox00000000;
1
#endif
else if (PIC_status[current_PIC_index] software_type == 7)
/* Load Control Module */
PICxmitBuf.command_data = Ox00000000;
1
else
PIC_status[current_PIC_index] .update_parameter = FALSE;
/* unknown software type, cancel command */
if (PIC_status[current_PIC_index].update_parameter)
need_pulse_read = FALSE;
PICxmitBuf. reg_ID = PARM_REG;
format_xmit_buffer();
1
else if (PIC_status[current_PIC_index].reset_status)
need_pulse_read = FALSE;
PICxmitBuf.command = SYSTEM_CONTROL;
PICxmitBuf.command_data =
(PIC_status[current_PIC_index]. status_reg_value & Oxffbf);
PICxmitBuf.command_data = PICxmitBuf.command_data << 16; /* Move status
bits to MSb's */
PICxmitBuf.reg_ID = STATUS_REG;
format_xmit_buffer();
else if (PIC_status[current_PIC_index].get_status)
need_pulse_read = FALSE;
PICxmitBuf.command = READ_REGISTER;
PICxmitBufseg_ID = STATUS_REG;
-46 -

i
CA 02527068 2006-11-14
format_xmit_buffer();
}
#ifdef IS_MC5
if (need_pulse_read && (PIC_status[current_PIC_index]. software_type == 4))
1
need_pulse_read = FALSE;
PICxmitBucommand = SYSTEM_CONTROL;
if (++PIC_status[current PIC indexl.curriD_reg >= PULSES_PER_PIC)
PIC_status[current_PICtind¨exlcurr_ID_reg = 0;
if ( (((PIC_status[current PIC_index].PIC addr * PULSES_PER_PIC) +
PIC_statuslcurrent_PIC_indexlcurr ID reg) % 24) >= num_pulse_ctrs)
PIC_status[current_PIC-lin¨clex] .curr_ID_reg = 0;
PICxmitBufseg_ID = PIC_status[current PIC_indexlcurr_ID reg;
work_pulse index = (PIC_status[current:PIC_index].PIC_adcir *
PULSES_PER_PIC) + ¨PICxmitBufreg_ID;
for (i=0; i<ID_FIELD_LENGTH; i-H-)
1
if (pulseData[work_pulse_indexl.ID_buffer[i] == 0)
{
j=i-1;
i = ID_FIELD_LENGTH;
1
1
if (j<0)
{
j = 0;
)
else if (j > (ID_FIELD_LENGTH-4))
1
j = ID_F1ELD_LENGTH-4;
1
PICxmitBuf.command_data = READ_ENCODER_ID I (j 8);;
format_xmit_buffer();
1
#endif
)
if (need_pulse_read)
{
#ifdef IS_MC5
if (PIC_statuslcurrent_PIC_index]. software_type == 7)
{
i = PIC_status[current_PIC_index].PIC_addr - LCM_BASE_ADDR; 1* get LCM #
*1
-47 -

CA 02527068 2006-11-14
work_bit_mask = (load_shed_state[0] (9 * i)) & Ox000001ff;
PICxmitButcommand_data =0;
for (i=0;i<9;i++)
if ((work_bit_mask & Ox100) != 0)
PICxmitBuf.command_data = (PICxmitBuf.command_data << 2) + 1; /* lsb turns
relay on */
else
PICxmitBuf.command_data = (PICxmitBuf.command_data << 2) + 2; /* msb
turns relay on */
work_bit_mask = work_bit_mask << 1;
PICxmitBuf.command_data1= 0x32000000; /* Set pulse time = 50 mS */
PICxmitBuf.command = WRITE_REGISTER;
PICxmitBufreg_ID = OUTPUT_REG;
format_xmit_buffer();
need_pulse_read = FALSE;
1
else
#endif
if (PIC_statusicurrent_PIC_indexl.num_pulse_regs == 0)
#ifndef IS_5T5
PICxmitBuf.command = READ_REGISTER;
PICxmitBuf. reg_ID = VERS_REG;
format_xmit_buffer();
need_pulse_read = FALSE;
#endif
1
else
#ifdef IS_MC5
if ( (((PIC_status[current_PIC_indexl.PIC_addr * PULSES_PER_PIC) +
PIC_status[current_PIC_indexlcurr_pulse_reg) % 24) >= num_pulse_ctrs)
PIC_status[current_PIC_indextcurr_pulse_reg = 0;
#endif
if (PIC_status[current_PIC_indexlcurr_pulse_reg <= MAX_FAST_READ)
PICxmitBuf.command = PIC_status[current_PIC_index].curr_pulse_reg;
else
PICxmitBuf.command = READ_REGISTER;
PICxmitBufreg_ID = PIC_status[current_PIC_index] .curr_pulse_reg;
format_xmit_buffer();
need_pulse_read = FALSE;
if (++PIC_status[current_PIC_index].curr_pulse_reg >=-
PIC_status[current_PIC_index].num_pulse_regs)
PIC_status[current_PIC_index].curr_pulse_reg = 0;
#ifdef IS_RSM
PIC_status[current_PIC_index].update_parameter = TRUE;
#endif
-48 -

1
CA 02527068 2006-11-14
_
)
}
}
PIC_status[current_PIC_index].last_cmd_data = PICxmitBuf.command_data;
PIC_status[current_PIC_index].last_command = PICxmitBuf.command;
PIC_wait_limit = PIC_status[current_PIC_index] .reply_wait_limit;
rcv_PIC_index = current_PIC_index;
if (++current_PIC_index == num_PICs)
current_PIC_index =0;
if (!need_pulse_read)
PIC_serial_status = do_send_cmd; /* Start UART */
1
1
}
#ifdef IS_RSM /* In RSM, generate serial stream from subseconds */
void pulseSubsecond(void)
(
if (num_PICs != 0)
1
if (PIC_clk_state == clk_high)
1
/* Falling edge, just set clock low */
fs1004.io.pulseOut1Off = 0;
PIC_clk_state = clk_low;
1
else
1
PIC_clk_state = clk_high;
#include "pic.def' /* Do PIC serial comm on clock rising edge */
1
1
}
#endif
void process_status_bits(void)
1
unsigned int work_pulse_index, work_status_bits;
-49 -

CA 02527068 2006-11-14
PIC_status[rcv_PIC_indextget_status = FALSE;
PIC_status[rcv_PIC_index] .status_reg_value = PICrcyButcommand_data >> 16;
PIC_status[rcv_PIC_index].time_since_global = (PICrcyBuf.command_data 8) &
Oxff;
if (PIC_status[rcv_PIC_indextstatus_reg_value != 0)
PIC_status[rcv_PIC_index].reset_status = TRUE;
if ((PIC_status[rcv_PIC jndexbstatus_reg_value & Ox8f10) != 0)
1
PIC_statusircv_PIC_indexl.PIC_data_err_count++; /* PIC detected bad data */
set_PIC_alarm(PIC_flags_O,PIC_status[rcv_PIC_indexl.PIC_addr,
PIC_status[rcv_PIC_index].status_reg_value);
work_status_bits = (PIC_status[rcv_PIC_index]. status_reg_value >> 8) & Ox0f;
work_pulse_index = PIC_status[rcv_PIC_index].PIC_addr * PULSES_PER_PIC;
while (work_status_bits > 0)
1
if (work_status_bits & Ox01)
pulseData[work_pulse_indexl.error_cnt++;
work_status_bits = work_status_bits >> 1;
work_pulse_index++;
1
if (((PIC_status[rcv_PIC_index].status_reg_value & 0x20) != 0) &&
!PIC_status[rcv_PIC_index].clear_pulse_regs)
PIC_status[rcv_PIC_index].comm_error_count++; /* PIC detected comm parity err
*/
if (PIC_status[rcv_PIC_index].comm_error_count > 2)
set_PIC_alarm(PIC_comerr_O,PIC_status[rcv_PIC_index].PIC_addr,
PICrcvl3uf.flags I 0x0800);
if ((PIC_statusircv_PIC_indextstatus_reg_value & 0x3080) != 0)
PIC_status[rcv_PIC_indexl.PIC_reset_count++; /* PIC was reset */
if (PIC_statuslrcv_PIC_index].PIC_reset_count > 1)
set_PIC_alarm(PIC_reset_O,PIC_status[rcv_PIC_index].PIC_addr,
PIC_status[rcv_PIC_index].status_reg_value);
1
1
1
if (PIC_status[rcv_PIC_index] .clear_pulse_regs &&
(clear_state == GLOBAL_CLR_SENT) )
PIC_statusircv_PIC_indextclear_pulse_regs = FALSE;
if ( ((PIC_status[rcv_PIC_index].status_reg_value & Ox0f) != Ox0f) &&
(PIC_status[rcv_PIC_index]. software_type == 3) )
- 50 -

i
. CA 02527068 2006-11-14
{
PIC_status[rcv_PIC_index] .PIC_data_err_count++; /* Clear cmd failed */
set_PIC_alarm(PIC_flags_O,PIC_status[rcv_PIC_index].PIC_addr,
PIC_status[rcv_PIC_index].status_reg_value);
}
1
else if ( ((PIC_status[rcv_PIC_index].status_reg_value & OxOf) != 0) &&
OPIC_status[rcv_PIC_index].status_reg_value & Oxf10) == 0) )
I
PIC_status[rcv_PIC_index].PIC_data_err_count += 1000; /* Spurious clr cmd */
set_PIC_alarm(PIC_flags_O,PIC_status[rcv_PIC_index].PIC_addr,
PIC_status[rcv_PIC_index].status_reg_value);
I
1
void set_PIC_alarm(alarmcodes pass_alarm_codes,
int pass_PIC_addr,
unsigned int pass_alarm_data)
I
if (!Comm_background_flags.do_alarm)
I
PIC_alann.alarm_codes = pass_alarm_codes + pass_PIC_addr;
PIC_alarm.ack = pass_alarm_data;
Comm_background_flags.do_alarm = TRUE;
)
I
unsigned char workTpar;
BOOLEAN decode_rcv_buffenvoid)
I
int i;
unsigned int workInt;
workTpar = Ox if;
if (PICrcyBuf.flags == 0)
I
work_PIC_addr = Get5();
if (PICrcyButflags == 0)
PICrcyBuf.PIC_addr = work_PIC_addr; /* Valid address received */
PICrcyBuf.command = Get5();
if (PICrcyBuf.command > OxOf)
PICro/Bufseg_ID = Get5();
else
PICro/Buf. reg_ID = PICrcyBuf.command;
PICrcyBuf.command_data = 0;
for (i=0; i<6; i++)
PICro/Buf.command_data = (PICrcyBuf.command_data 5) + Get5();
workInt = Get5();
PICrcyBuf.command_data = (PICrcyButcommand_data 2) + (workInt 3);
-51 -

CA 02527068 2006-11-14
PICrcyBuf. flags1= workInt & 0x07;
workInt = Get5();
if (workTpar 1=0)
PICrcyBuf. flags1= rcv_tpar_error_flag;
/* Look up correct PIC_status index for data in rcv buffer */
for (i=0; ((i<MAX_PICS) && (PIC_status[i].PIC_addr != PICrcyBuf.PIC_addr));
i++);
if (i >= num_PICs)
PICrcyBuf. flags1= rcv_bad_addr_flag; /* past end of valid PICs, address error
*/
if (i == MAX_PICS)
rcv_PIC jndex = 0;
else
rcv_PIC_index =
#ifdef VATEST
#if VATEST==1
PICrcyBuf.command = temp_command;
PICrcyBuf.reg_ID = temp_reg_ID;
PICrcyBuf.command_data = temp_command_data;
PICrcyBuf.flags = temp_flags;
ftendif
#endif
return((PICrcyBut flags &
¨(PIC_error_flagIPIC_need_refresh_flagIPIC_invalid_data_flag)) == 0);
1
void format_xmit_buffer(void)
int i,j,ShiftCount;
unsigned int WorkInt;
unsigned long WorkData;
PICxmitBuf.bitCount =0;
PICxmitBuf.bits.bufLong[0] = 0;
PICxmitBuf. bits.bufLong[1] = 0;
PICxmitBuf. bits.bufLong[2] = 0; /* Clear xmit bit buffer */
workTpar = Ox If; /* Initializa Tpar */
Stuff6(PICxmitBuf.PIC_addr);
Stuff6(PICxmitBuf.command);
if (PICxmitBuf.command > Ox0f)
Stuff6(PICxmitBuf.reg_ID);
if (PICxmitBuf.command > Ox17)
- 52 -

i
CA 02527068 2006-11-14
_
WorkData = PICxmitBuf.command_data;
ShiftCount = 32;
for (i = 0;i<7;i++)
1
WorkInt = 0;
for (j=0;j<5;j++)
1
WorkInt = WorkInt 1;
if (WorkData & 0x80000000)
WorkInt += 1;
WorkData = WorkData 1;
if (--ShiftCount == 0)
1
WorkInt = (WorkInt 3) + (PICxmitBuf.flags & 0x07);
.l = 5;
1
1
Stuff6(WorkInt);
1
1
1
Stuff6(workTpar);
/* Buffer set, set up UART control */
PICrcyBuf.bitCount = 66;
if ((PIC_comm_mon.control_flags & XMIT_DATA_RDY) == 0)
1
PIC_comm_mon.xmit_buf = PICxmitBuf;
PIC_comm_mon.controlflags 1= XMIT_DATA_RDY;
1
PICrcyBuf.flags =0;
PICrcyBuf.PIC_addr = PICxmitBuf.PIC_addr; /* preset address of remote PIC */
1
unsigned int Get5(void)
1
int byte_index, bit_index;
unsigned int work_result;
work_result = 0;
if ((PICrcvBuf. flags &
-(PIC_error_flagIPIC_need_refresh_flagIPIC_invalid_data_flag)) == 0)
1
byte_index = 96 - PICrcyBufbitCount;
bit_index = byte_index & 0x07;
byte_index = byte_index 3;
work_result = (PICrcyBuf. bits.bufByte[byte_index] 8) +
PICrcyBufbits.bufByte[byte_index+1];
- 53 -

CA 02527068 2006-11-14
work_result = work_result >> (10 - bit_index);
work_result &= Ox3f;
if (parity6[work_result >> 1] != work_result)
work_result =0;
PICrcvBufflags 1= rcv_parity_err_flag;
else
work_result = work_result >> 1;
workTpar A= work_result;
PICrcl/BufbitCount -= 6;
if (PICrcyBufbitCount < 0)
PICro/But flags1= rcv_bad_length_flag;
return(work_result);
void Stuff6(int pass_data)
int byte_index, bit_index;
workTpar A= pass_data;
byte_index = PICxmitBuf.bitCount >> 3;
bit_index = PICxmitBuf.bitCount & 0x07;
pass_data = parity6[pass_data] (10 - bit_index);
PICxmitBuf.bits.bufByte[byte_index] 1= pass_data >> 8;
PICxmitBuf. bits.bufByte[byte_index+1] 1= pass_data & Oxff;
PICxmitBuf.bitCount += 6;
- 54 -

CA 02527068 2006-11-14
PULSE.H
*1
#ifndef BOOLEAN_DEFINED
#define BOOLEAN_DEFINED
typedef int BOOLEAN;
#endif
/* subsecond processing for pulse counters */
void pulseSubsecond(void);
/* Daily PIC table rebuild */
void pulseDay(void);
/* Main PIC communication routine */
void pulseService(void);
/* PIC comm routine - once-per-second code */
void pulseSecond(void);
/* Subroutines for PIC communication */
void Stuff6(int pass_data);
void format_xmit_buffer(void);
BOOLEAN decode_rcv_buffer(void);
void process_status_bits(void);
unsigned int Get5(void);
void set_PIC_alarm(alarmcodes pass_alarm_type,
int pass_PIC_addr,
unsigned int pass_alarm_data);
/* Startup code for PIC communication */
void pulseStartup (void);
/* Routine to clear pulse registers after cold start */
void pulseColdstart(void);
/* defined in pt.c */
#define RELAY_A 0
#define RELAY_B 1
void pulseOut(int picNbr,int relayNbr,int ONoff);
void ptEveryMinute(void) ;
void ptEverySecond(void) ;
void set_PLC_relays(int xmitRelay,int rcvRelay) ;
- 55 -

1
CA 02527068 2006-11-14
PICEND.DEF
/*
include file at end of mtrsamp to control MC and ST pic chips from mtrsamp
interrupt
*/
#ifdef IS_MC5
if (pulseOutMode==PIC_MC_SERIAL)
{
asm (" MOVE.L #0x80400E,A0");
asm (" AND.W #0xFCFF,(A0)"); /* Clear clock and data ports */
1
#endif
#ifdef IS_5T5
asm (" MOVE.L #0x80400E,A0");
asm (" AND.W #0xFEFF,(A0)"); /* Insert clock falling edge */
if (PIC_serial_status == sending_st5_bits)
{
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" NOP");
asm (" MOVE.L #0x80400E,A0");
asm (" OR.W #0x0100,(A0)"); /* If sending bits, activate clock*/
1
#endif
- 56 -

CA 02527068 2006-11-14
PlCVARS.DEF
/*
local variables to control MC and ST pic chips from mtrsamp interrupt
meter/c/lib/picvars.def
*/
unsigned long bitOneFlag;
- 57 -

i
CA 02527068 2006-11-14
PULSELINK.DEF
/* determine if variables are external or defined here */
#undef ref
#ifdef PSTRU_DEFINED
#define ref
#else
#define ref extern
#endif
#if (NUMPH >6)
#define IS_MC5
#else
#ifdef MAX SCAN_METERS
#define IS_S¨T5
#else
#define IS_RSM
#endif
#endif
/* Values for hdwr -p (pulseOutMode) */
#define STANDARD_PIC_COMM 0
#if 0 /* remove these equates from mtrlink.def */
#define PIC_PULSE SERIAL 1
#define PIC_MC SERIAL 2
#define PIC_ST_SERIAL 3
#endif /* then uncomment them here */
/* #define VATEST 1 */
#ifdef VATEST
#undef IS_MC5
#undef IS_RSM
#undef IS_ST5
#define IS_RSM
#undef NUMPH
#define NUMPH 3
#undef MAX_SCAN_METERS
#endif
/* Uncomment for water meters (Oakville Hydro) */
#define READ_ENCODER_ID Ox49ff0000
#define READ_ENCODER_PARM 0x0312500c
- 58 -

CA 02527068 2006-11-14
1* Uncomment for gas meters (Sonix)
#define READ_ENCODER ID 0x49fe0389
#define READ_ENCODERIPARM 0x0300500c
*/
#define ID_FIELD_LENGTH 13
#define PULSES_PER_PIC 4
#ifdef IS MC5
#define B¨ITS PER SEC 822
#define MAX1PICS¨ 16
#else
#ifdef IS ST5
#define B¨ITS PER SEC 942
#define MAX1PICS¨ 5
#else
#define BITS PER SEC 32
#define MAX¨_PICS¨ 1
#endif
#endif
#define DIRECT_PIC_WAIT_LIMIT 24
#define BUFFERED_PIC_WAIT_LIMIT 10* BITS_PER_SEC
#define NUM_START_BITS 12
#ifdef IS ST5
#define ¨REBUILD_DELAY 30000
#else
#define REBUILD_DELAY 1000
#endif
typedef
struct
unsigned long serial_number;
unsigned long last_cmd data;
unsigned char PICiaddr;
unsigned char software_type;
unsigned char software version;
unsigned char 1¨oop_rate;
unsigned int status_reg_value;
unsigned char time_since_global;
unsigned char num_pulse_regs;
unsigned char curr_pulse_reg;
unsigned char curr_ID_reg;
unsigned char last_command;
unsigned int reply_wait_limit;
- 59

,
CA 02527068 2006-11-14
unsigned int PIC_data_err_count;
unsigned int PIC_reset_count;
unsigned int comm_error_count;
unsigned force_pulse_read: 1;
unsigned get_serno : 1;
unsigned get_version : 1;
unsigned get_status : 1;
unsigned reset_status : 1;
unsigned update_parameter: 1;
unsigned clear_pulse_regs: 1;
}
PIC_status_t;
typedef
enum {
sending_bits,
sending_st5_bits,
rcving_bits,
do_PIC_start,
sending_PIC_start,
do_send_cmd,
sending_start,
sending_start_l,
sending_stop,
waiting_for_start,
rcving_stop,
idle
}
PIC_s_stat_t;
typedef
enum {
SET_PRE_ALIGN,
DO_ALIGN,
SET_NORMAL_PLC,
DISCONNECT_COUPLER,
READ_XMIT_LEVEL
}
ATM_op_t;
typedef
enum {
DO_PRESET,
DO_PLC_SET,
SET_ALIGN,
WAIT_ALIGN,
DO_ATM_DISCONNECT,
ATM_DONE
}
ATM_state_t;
- 60 -
,

CA 02527068 2006-11-14
typedef
struct
unsigned char PIC_addr;
unsigned char command;
unsigned char reg_ID;
unsigned long command_data;
unsigned int flags;
int bitCount;
union{
unsigned long bufLong13];
unsigned char bufByte[12];
1 bits;
}
PICbitBuf;
#ifndef BOOLEAN DEFINED
#define BOOLEAN DEFINED
typedef int BOOLEAN;
#endif
/* Definition of bits in Flags field of PIC comm buffers */
/* NOTE- Top 4 bits (Oxf000) reserved for use by ATM code */
#define rcv_bad_addr_flag Ox0100
#define rcv_tpar_error_flag 0x0080
#define rcv_data_ready_flag 0x0040
#define rcv_bad_length_flag 0x0020
#define rcv_timeout_flag Ox0010
#define rcv_parity_err_flag 0x0008
#define PIC_error_flag 0x0004
#define PIC_need_refresh_flag 0x0002
#define PIC_invalid_data_flag Ox0001
/* Command codes for PIC communication */
#define MAX_FAST_READ 0x07
#define CLEAR PULSE REGISTERS 0x08
E
#define READ_R¨ GISTE¨R Ox10
#define WRITE REGISTER Ox18
#define SYSTEM¨ _CONTROL 0x19
/* Register ID codes for PIC communication */
#define MAX PULSE REG 15
#define CONT¨ROL_REG 16
#define ERROR_REG 26
#define OUTPUT REG 27
#define PARM_RE¨G 28
#define VERS_REG 29
-61-

,
CA 02527068 2006-11-14
#define SERNO_REG 30
#define STATUS_REG 31
/* Special-purpose PIC addresses */
#define GLOBAL_PIC ADDR 31
#define MC5 MUX_PI¨C ADDR 30
#define ST5=MUX_PIC_ADDR 29
#define LCM BASE ADDR 161* First LCM is at address 16 */
#define ATM¨BASE_ADDR 20/* First ATM is at address 20 */
#define MAX¨_PULSE_PIC_ADDR 15 /* pulse couters are from 0 to 15 */
/* Bit usage in the ATM relay control word */
#define ATM RC_XMIT ON 0x00008000
#define ATM_RC_MEAS_XMIT 0x00004000
#define ATM_RC MEAS CPLR 0x00002000
#define ATM_RCIRES_S¨HORTED Ox00001000
#define ATM_RC CAP MASK Ox000003ff
#define ATM_NU¨M_CA¨P_BITS 10
#define ATM_PRESET_CODE ATM_RC_XMIT_ON I ATM_RC_MEAS_XMIT I
ATM_RC_MEAS_CPLR
#define ATM_PLC CODE ATM_RC_XMIT_ON I ATM_RC_RES_SHORTED
#define ATM_DISC_CODE 0
/* Other ATM control equates */
#define ATM_MEAS_TIME 20L /* mSec to wait between cap change and ADC reading
*/
#define ATM_DISC TIME 20L /* mSec to wait before switching cap relays */
#define ATM_MIN_READING 0x0038 /* If reading at end of autotune less than
this, fail */
/* Equates for ST5 comm */
#define STS_PIC_DELAY 66
#pragma region ('ram=ram")
ref unsigned short current_PIC index, rcv_PIC_index;
ref PIC_status_t PIC_status[MAX=PICS];
struct (
unsigned long reading;
int error cnt;
unsigned char ¨113_field[ID_FIELD LENGTH);
unsigned char ID_buffer[ID FIELD LENGTH];
) ref pulseData[2*NUM¨PH];
-62-

CA 02527068 2006-11-14
struct
PICbitBuf xmit_buf;
PICbitBuf rcv_buf;
int control_flags;
} ref ext_comm, PIC_comm_mon;
struct
ATM_op_t operation;
unsigned int ATM_number;
ATM_state_t state;
unsigned request_flag : 1;
unsigned done_flag 1;
unsigned error_flag : 1;
unsigned active_flag : 1;
unsigned int start_cap code;
unsigned int end_cap_code;
unsigned int optimum_cap_code;
unsigned int optimum_reading;
unsigned int xmit_level;
unsigned int coupler_level;
unsigned int result_flags;
long int align_timer;
) ref ATM_control;
struct
unsigned request_flag : 1;
unsigned done_flag : 1;
unsigned error_flag : 1;
unsigned active_flag : 1;
unsigned int xmit_mask;
unsigned int rcv_mask;
unsigned int result_flags;
unsigned int last_xmit_mask;
unsigned int last_rcv_mask;
} ref MUX_control;
struct
unsigned do_rebuild : 1;
unsigned do_alarm 1;
} ref Comm_background_flags;
/* Bit definitions in ext_buf.control_flags */
#define SUPPRESS_NORMAL_COMM Ox0001
#define XMIT_REQUEST 0x0002 /* External routine requests send of xmit_buf
*/
#define CPY_RCV_DATA 0x0004 /* External cmd was sent, copy rcvd
buffer to
rcv_buf */
#define RCV_DATA_RDY 0x0008 /* Got reply from external cmd, reply is
in rcv_buf
*1
#define XMIT_DATA_RDY Ox0010 /* xmit_buf has copy of last cmd sent */
- 63 -

CA 02527068 2006-11-14
ref PICbitBuf PICxmitBuf, PICro/Buf, HoldrcyBuf;
ref PIC_s_stat_t PIC_serial_status;
ref unsigned int num_PICs;
ref unsigned int num_LCMs;
ref unsigned int rebuild_timer;
ref unsigned int ATM_work;
ref unsigned int work_PIC_addr;
ref unsigned int num_pulse_ctrs;
ref unsigned int hold_num_pulse_ctrs;
ref unsigned int bit_count;
ref unsigned int out_bit_value;
ref unsigned char *shift_LSB_ptr;
ref unsigned char in_bit_value;
ref unsigned int PIC_wait_limit;
ref unsigned int zero_count;
ref unsigned int last_comm_err_flag;
ref BOOLEAN dont_clear_PIC_stats;
ref int ST5_PIC_delay_ctr;
ref unsigned int PIC_bad_addr_count;
ref alarmstru PIC_alarm;
#ifdef VATEST
/* test !!!! */
ref int temp_command;
ref int temp_reg_ID;
ref long temp_command_data;
ref int temp_flags;
/* test !!!! */
#endif
ref enum {
clk_high,
clk_low
) PIC_clk_state;
ref enum {
NO_GLOBAL_SEND,
SEND_GLOBAL_CLR,
SENDING_GLOBAL_CLR,
GLOBAL_CLR_SENT
i clear_state;
/* Old equates maintained for compatibility */
#if 0
#define RELAY_A_BIT 1
#define RELAY_B_BIT 2
#define IDLE 0
#define TX 1
#define RX 2
#define DATA_READY 3
#define WAKE 4
- 64 -

CA 02527068 2006-11-14
#define PIC_RESET 5
#define WAKE COUNT RELOAD (64*4) /* Four Seconds */
#define RESET¨COUNT:RELOAD 10 /* 1/4 Seconds */
#define RELAY¨_A_OFF_CMD 5 /*active low trigger*/
#define RELAY A ON CMD 4
#define RELAY:B1OFF_CMD 7
#define RELAY B ON CMD 6
#define CLEAR¨ACC C¨MD 8
#define SUBAC¨C CMD¨ 12
#define ECHO CMD¨ 14
#define SLEEP¨SMD 15
#define PULSE SERIAL_COM_MAX 15
#define WAKE¨CMD 16
fi
#dene RESET:CMD 17
#define PULSE COM NUM 18
#define NO_PUISE_B¨IT_DATA Ox1-1-1-1.14-1-F
#define RELAY_CMD_MIN 4
#define RELAY_CMD_MAX 7
#endif
-65 -

CA 02527068 2006-11-14
PULSEOUTM.DEF
#include "clklinlc.der
#include "mtrlink.def'
#include "plc.def'
#include "serlink.der
#include "pulselink.def'
#ifndef NO_FULSES
#include "scan.h"
#include "pulse.h"
#include "log.h"
void pulseout_second_back(void);
void pulseout_ram_initl(void);
ADDRFN pulseoutaddrfn ;
#pragma region ("data=ramlnitl")
void (*pulseout_ram_initlp)(void)=pulseout_ram_initl;
#pragma region ("data=data")
#pragma region ("data=secondBack")
void (*pulseout_second_backp)(void)=pulseout_second_back ;
#pragma region ("data=data")
ADDRFN_RET pulseoutaddrfn(reg8stru reg8)
/* write the load shed event to flash */
putEvent(LOAD_SHED_EVENT,1,&reg8.ulong);
return(0);
void pulseout_ram_init10
addrfn_tblfGET_FROM_SLAVEIIPULSEOUT_STATE1= pulseoutaddrfn ; 1
void pulseout_second_back()
1
#endif
-66 -
,

Representative Drawing

Sorry, the representative drawing for patent document number 2527068 was not found.

Administrative Status

2024-08-01:As part of the Next Generation Patents (NGP) transition, the Canadian Patents Database (CPD) now contains a more detailed Event History, which replicates the Event Log of our new back-office solution.

Please note that "Inactive:" events refers to events no longer in use in our new back-office solution.

For a clearer understanding of the status of the application/patent presented on this page, the site Disclaimer , as well as the definitions for Patent , Event History , Maintenance Fee  and Payment History  should be consulted.

Event History

Description Date
Time Limit for Reversal Expired 2021-08-31
Inactive: COVID 19 Update DDT19/20 Reinstatement Period End Date 2021-03-13
Letter Sent 2020-11-16
Letter Sent 2020-08-31
Inactive: COVID 19 - Deadline extended 2020-08-19
Inactive: COVID 19 - Deadline extended 2020-08-06
Inactive: COVID 19 - Deadline extended 2020-07-16
Inactive: COVID 19 - Deadline extended 2020-07-02
Inactive: COVID 19 - Deadline extended 2020-06-10
Inactive: COVID 19 - Deadline extended 2020-05-28
Inactive: COVID 19 - Deadline extended 2020-05-14
Inactive: COVID 19 - Deadline extended 2020-04-28
Letter Sent 2019-11-15
Common Representative Appointed 2019-10-30
Common Representative Appointed 2019-10-30
Inactive: Late MF processed 2018-11-26
Letter Sent 2018-11-15
Inactive: Late MF processed 2017-11-20
Letter Sent 2017-11-15
Grant by Issuance 2013-08-20
Inactive: Cover page published 2013-08-19
Pre-grant 2013-06-11
Inactive: Final fee received 2013-06-11
Notice of Allowance is Issued 2012-12-11
Letter Sent 2012-12-11
Notice of Allowance is Issued 2012-12-11
Inactive: Approved for allowance (AFA) 2012-11-29
Letter Sent 2012-02-20
Reinstatement Request Received 2012-02-01
Reinstatement Requirements Deemed Compliant for All Abandonment Reasons 2012-02-01
Amendment Received - Voluntary Amendment 2012-02-01
Inactive: Abandoned - No reply to s.30(2) Rules requisition 2011-02-02
Inactive: S.30(2) Rules - Examiner requisition 2010-08-02
Amendment Received - Voluntary Amendment 2009-05-27
Amendment Received - Voluntary Amendment 2009-05-27
Inactive: S.30(2) Rules - Examiner requisition 2008-11-27
Inactive: S.29 Rules - Examiner requisition 2008-11-27
Letter Sent 2008-09-25
Inactive: Inventor deleted 2008-09-19
Inactive: Office letter 2008-09-19
Inactive: Inventor deleted 2008-09-19
Inactive: Inventor deleted 2008-09-19
Correct Applicant Request Received 2008-05-01
Inactive: Correspondence - Formalities 2008-05-01
Inactive: Single transfer 2008-05-01
Application Published (Open to Public Inspection) 2007-05-15
Inactive: Cover page published 2007-05-14
Letter Sent 2006-12-07
Letter Sent 2006-12-06
Amendment Received - Voluntary Amendment 2006-11-14
Request for Examination Requirements Determined Compliant 2006-11-14
All Requirements for Examination Determined Compliant 2006-11-14
Request for Examination Received 2006-11-14
Inactive: Single transfer 2006-10-31
Inactive: IPC assigned 2006-02-20
Inactive: First IPC assigned 2006-02-16
Inactive: IPC assigned 2006-02-16
Inactive: IPC assigned 2006-02-16
Inactive: IPC assigned 2006-02-16
Inactive: IPC assigned 2006-02-13
Inactive: Courtesy letter - Evidence 2006-01-10
Inactive: Filing certificate - No RFE (English) 2006-01-04
Filing Requirements Determined Compliant 2006-01-04
Application Received - Regular National 2006-01-04

Abandonment History

Abandonment Date Reason Reinstatement Date
2012-02-01

Maintenance Fee

The last payment was received on 2012-11-05

Note : If the full payment has not been received on or before the date indicated, a further fee may be required which may be one of the following

  • the reinstatement fee;
  • the late payment fee; or
  • additional fee to reverse deemed expiry.

Please refer to the CIPO Patent Fees web page to see all current fee amounts.

Owners on Record

Note: Records showing the ownership history in alphabetical order.

Current Owners on Record
QUADLOGIC CONTROLS CORPORATION
Past Owners on Record
DORON SHAFRIR
ROBERT HAYWARD
SAYRE A. SWARZTRAUBER
SIDDHARTH MALIK
Past Owners that do not appear in the "Owners on Record" listing will appear in other documentation within the application.
Documents

To view selected files, please enter reCAPTCHA code :



To view images, click a link in the Document Description column. To download the documents, select one or more checkboxes in the first column and then click the "Download Selected in PDF format (Zip Archive)" or the "Download Selected as Single PDF" button.

List of published and non-published patent-specific documents on the CPD .

If you have any difficulty accessing content, you can call the Client Service Centre at 1-866-997-1936 or send them an e-mail at CIPO Client Service Centre.


Document
Description 
Date
(yyyy-mm-dd) 
Number of pages   Size of Image (KB) 
Abstract 2005-11-15 1 17
Description 2005-11-15 126 3,202
Drawings 2005-11-15 6 112
Claims 2005-11-15 2 50
Drawings 2006-11-14 18 625
Description 2006-11-14 66 1,730
Claims 2006-11-14 2 70
Abstract 2006-11-14 1 23
Cover Page 2007-05-07 1 36
Description 2009-05-27 66 1,726
Claims 2009-05-27 4 138
Claims 2009-05-27 4 138
Claims 2012-02-01 6 222
Cover Page 2013-07-24 1 37
Filing Certificate (English) 2006-01-04 1 157
Acknowledgement of Request for Examination 2006-12-06 1 178
Request for evidence or missing transfer 2006-11-16 1 101
Courtesy - Certificate of registration (related document(s)) 2006-12-07 1 106
Reminder of maintenance fee due 2007-07-17 1 112
Courtesy - Certificate of registration (related document(s)) 2008-09-25 1 105
Courtesy - Abandonment Letter (R30(2)) 2011-04-27 1 165
Notice of Reinstatement 2012-02-20 1 169
Commissioner's Notice - Application Found Allowable 2012-12-11 1 163
Maintenance Fee Notice 2018-11-26 1 180
Late Payment Acknowledgement 2018-11-26 1 165
Late Payment Acknowledgement 2018-11-26 1 165
Maintenance Fee Notice 2017-11-20 1 177
Late Payment Acknowledgement 2017-11-20 1 162
Late Payment Acknowledgement 2017-11-20 1 162
Commissioner's Notice - Maintenance Fee for a Patent Not Paid 2019-12-27 1 544
Courtesy - Patent Term Deemed Expired 2020-09-21 1 552
Commissioner's Notice - Maintenance Fee for a Patent Not Paid 2021-01-04 1 544
Correspondence 2006-01-04 1 26
Fees 2007-11-06 1 43
Correspondence 2008-05-01 6 206
Correspondence 2008-09-19 1 16
Fees 2009-11-16 1 43
Fees 2010-11-12 1 42
Correspondence 2013-06-11 1 42