Вы находитесь на странице: 1из 71

Low Cost Portable

Time Domain Reflectometer


System

Prepared by: Shannon Petty and Paul Bailey


Technical Advice by: John Larkin, Highland Technology

SAN FRANCISCO STATE UNIVERSITY


Fall 2010 to Spring 2011

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Table of Contents
1. Abstract .
.
.
.
.
.
2. Introduction
.
.
.
.
.
3. Background
.
.
.
.
.
4. Design Requirements
.
.
.
.
5. Preferred Implementation
.
.
.
5.1 Operation
.
.
.
.
.
5.2 The TDR Box .
.
.
.
.
5.2.1 The Microcontroller
5.2.2 The Delay Generator
5.2.3 The Fast Sampler and Impulse Generator
5.3 The TDR Application Software
.
.
6. Schedule and Budget
.
.
.
.
7. Results
.
.
.
.
.
.
7.1 Project Implementation (Overview) .
.
7.2 TDR Board Schematic .
.
.
.
7.2.1 Power
7.2.2 Communication
7.2.3 LEDs
7.2.4 Delay Generator
7.2.5 Step Generator
7.2.6 Impulse Generator
7.2.7 Sampler
7.2.8 Sample Conditioning
7.2.9 ADC Buffers
7.3 Circuit Board Layout .
.
.
.
7.4 Microcontroller Programming .
.
.
7.5 Software Programming .
.
.
.
7.6 Test and Verification .
.
.
.
8. Discussion and Conclusion
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

2
3
4
5
6
7
8

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

16
18
19
19
21

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

24
24
24
24
34

Appendix A. Schematic
.
.
.
Appendix B. Board Layout .
.
.
Appendix C. Application Source Code
.
Appendix D. Microcontroller Source Code
Appendix E. References
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

35
43
44
54
70

.
.
.
.
.

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

1. Abstract

For our project, our group designed a low cost portable Time Domain
Reflectometer (TDR) system for use in measuring the impedances of printed
circuit board traces in a test coupon format. This system consists of a Personal
Computer (PC) running a host application and a remote box, connected via a USB
cable or an RS-232 cable. The remote box contains the electronic circuits required
for generating and measuring the TDR signals. The host application software
receives data from the remote TDR box, and then processes and displays the TDR
image with calculated impedance measurements.

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

2. Introduction
As technology has progressed, signal speeds have also increased. Printed Circuit
Board (PCB) designs have had to change in order to deal with these increasing
signal speeds. In many cases, PCB traces have effectively become transmission
lines, requiring controlled impedances to prevent signal loss and distortion. The
burden placed on both PCB manufactures and design engineers is to measure and
verify the impedance of these traces.
Time Domain Reflectometry, or TDR, is the method used to measure the
impedance of a transmission line.TDR is the process of injecting a fast step pulse
into a transmission line and then measuring the reflections that result from the
signal as it travels through the transmission line. Because the PCB traces are
much shorter in length compared to normal cables (millimeters compared to
meters), TDR systems used to measure the impedance of long cables cannot be
used effectively for these traces.
A very fast TDR system, which is usually part of a Vector Network Analyzer or a
Digital Sampling Oscilloscope, must be used in order to perform impedance
measurements of short transmission lines like PCB traces. These types of TDR
systems are very expensive, making them difficult to obtain for the average
design engineer or engineering department, and large and fragile, making them
difficult to transport. Our proposed project is to design a low cost, portable TDR
system for measuring the trace impedance of Printed Circuit Boards. The
proposed system should have specifications that are comparable to the more
expensive systems and sufficient for making the required measurements.
Printed circuit boards are typically manufactured on large panels (18 x 24
typical). Each panel can contain several boards (depending on the board size)
made up of various layers of laminates including copper, epoxy, fiberglass, and
other materials. These materials are heat-pressed together into a tight sandwichlike structure. After further processing, the individual boards are then cut out of
the panel using a router and then inspected, tested, and finally sent to the client.
Impedance controlled boards are boards that contain traces that must meet a
certain impedance specification. Their specifications will be provided by the
client. The board manufacturer will then adjust the process in order to meet these
specifications. In order to verify that the specifications are met, the board
manufacturer will add another small board to the panel of boards which will
contain traces of the same line width and copper weight on the same layer as the
controlled impedances on the customers board. These small boards are known as
Test Coupons. We designed our TDR system to measure these coupons.

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

3. Background
The state of the art is shown in Table 1. The two high-end competitors are
Tektronix and Agilent. Their systems are used for measuring the impedance of
PCB traces, but they are primarily designed for measuring the impedance of small
microwave components as part of their s-parameter specifications, etc. We
intended to compete with them only on price, targeting firms with smaller
engineering department budgets.

Table 1: Possible competitors and their specifications


Manufacturer
Tektronix

Product
Sampling Oscilloscope

Agilent

CSA8200+80E10 TDR
plug-in or P8018 probe
and 80A02 plug-in.
Sampling Oscilloscope

Polar Instruments

86100+N1020A probe
kit.
CITS900 system

Specifications
12ps risetime
incident

Price
$44k+

pulse
15ps risetime
incident pulse

$38k+

200ps risetime
incident pulse

$12k+

The system from Polar Instruments is designed specifically for measuring the
impedance of PCB test coupons. We expected to meet and possibly exceed the
electrical specifications of their system. With a proposed customer price of $2500
(not including a required PC), our target is small engineering firms, engineering
departments, students, hobbyists, and anyone designing high speed controlled
impedance PCBs.

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

4. Requirements and Specifications


Table 2 shows the show the specifications of our proposed TDR systems
hardware, and Table 3 shows the specifications of our proposed TDR systems
software.
Table 2: Electrical characteristics of the external TDR box (hardware)
Characteristic
Excitation Pulse,

Performance Requirement
= 75ps (11.242 mm or 0.443
in)

Supplemental Information
Vp 10 to 90% into precision
short.

Reflected Pulse
(i.e. Incident pulse risetime).
Output Impedance

50(ohm) 1%

After risetime stabilizes into


50(ohm) termination.

Pulse Amplitude
Pulse Width
Pulse Repetition Time
Vertical Resolution

400mV nominal into 50(ohm)


40ns nominal
10us nominal
0.5m(rho)

Horizontal Resolution

1.0ps

Time to Acquire TDR


waveform

0.7s

Based on 12-bit ADC (800mV


max)
Based on 16-bit DAC (Vinear
delay).
Based on 100,000 samples/s.

Table 3: Characteristics of application software for the TDR system


Characteristic
Vertical Scales

Performance Requirement
60m(rho)/div =400 values

Vertical Position

Any waveform point is


moveable to center of display
window.
-150mm to 6000mm
11.2mm or 1% of distance
measured, whichever is greater
0(ohm) to 1k(ohm), 1%
10 seconds (Depending on the
speed of computer used).

Cursor Readout Range


Distance Measurement
Accuracy
Cursor Ohms Readout
Time to Process & Display
TDR waveform

Supplemental Information
Based on 400 vertical pixels
in display window.

Based on Excitation pulse


risetime.
Typically 0 to 200(ohm) used.
Data transfer alone will
require seven seconds at
153.6k baud.

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

5. Preferred Implementation
The proposed TDR system consists of a application software on a PC and an
external TDR box containing the circuitry needed to produce the TDR incident
pulse and measure the reflections returned. The TDR box is connected to the host
computer via USB.

Fig. 1 Proposed TDR System


Figure 2 is a picture of the proposed electronics system inside the remote TDR
box. Three major subsystems to the circuit are shown in colored boxes.

Fig. 2 TDR Remote Box circuit diagram


6

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Each of the major parts of the circuit required additional research to determine
how that part can be implemented (e.g. components, circuits and other various
issues).
5.1 Operation
We intended to design the system so that the PC will do the majority of the work,
allowing a much simpler design for the microcontroller code, whose primary
purpose will be to pass the raw sample or dot data to the PC where it will be
processed.
The system operates by the following steps:
1. The PC sends a request for a TDR image (data).
2. The ramp generator starts producing the TDR step pulse and sample
impulse delays.
3. The TDR step is sent out of the coax connector to the device under
test. The impulse delay is used to generate the required pulse to snap
the SRD (step-recovery diode) and produce the complementary
impulses.
4. The impulses travel to the diode sampler where the pulses forward bias
the two diodes. This momentarily allows the input signal to charge the
two capacitors. This amounts to a very fast sample-and-hold circuit.
5. The voltage from the sample capacitors is conditioned, amplified and
then digitized by the ADC, producing a sample point or dot voltage
value that is stored in the microcontroller memory array.
6. The value is sent to the PC, which receives the data and stores it in an
internal memory array or a file.
7. Steps 2 through 6 are repeated until the array is full or the image is
completed, whichever occurs first.
8. The data is then processed and filtered to remove as much noise as
needed or as possible. This is done with an FIR filter in software. The
FIR filter coefficients are adjusted via inverse convolution algorithm
using an ideal input step as a reference.
9. The post-processed data is normalized and impedance measurements
are made. These measurements are based on a precision impedance
reference that was measured and previously stored in memory during
the initial system calibration. Normally this reference is an air-core
coaxial cable or a precision terminator.

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

5.2 The TDR Box


As shown in Figure 2, the TDR box consists of three main subsystems: the
microcontroller, the delay generator, and the fast sampler and Impulse Generator.
5.2.1 The Microcontroller
For the microcontroller, the principal requirements are that the development tool
set should be cheap (free/open source) and there must be enough internal SRAM
for serial communication buffering and data arrays for sampling. The processor
would need at least one internal UART for communications with the host
computer. Communications to/from the host computer via USB would be
performed using a serial to USB converter IC. Communications would be done by
ASCII serial commands sent from the host computer and acknowledgements
returned to the PC. The microcontroller would perform the functions and return
data to the host computer in binary format. These functions include
starting/stopping the delay generator section and communicating with external
DACs and ADCs via SPI or I2C serial interface. We used the 32-bit LPC (Arm)
microcontroller family from NXP.
The microcontroller would receive serial commands from the Host PC via USB.
The main command is a request form the PC for a TDR image. The
microcontroller initiates this process by starting the ramp generator, sampling the
dot voltage, and finally storing the result in its internal memory array. The
microcontroller then advances the sample delay in time and repeats the process.
Once the TDR image has been acquired (or the memory is full), the data is sent to
the PC. This may take several packet transfers depending on the microcontroller
memory size.
To avoid having to write a USB driver for windows, a USB to Serial chip would
be used. These chips have drivers provided by the manufacturers for windows and
Linux, etc. The chip provides a simple USB to COM port interface on the PC side
and a simple TTL serial I/O interface on the microcontroller side. The only
downside to this is the baud rate is limited to the COM baud rate of the PC
(153.6kbaud normally). This means if 16-bits are used for each dot value, it will
take several seconds to transmit the image data (16 x 65536 = 1,048,576 / 153,600
bits/sec =~6.8s).

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

5.2.2 The Delay Generator


The delay generator is based on a linear ramp that has a rise time of a few
nanoseconds. The ramp voltage is measured by a comparator which produces an
output switch when the ramp voltage reaches the reference input voltage of the
comparator. Different time delays are made by varying the reference voltage of
the comparator via DAC (Digital to Analog Converter). This type of delay is also
known as a Vinear delay.
A constant current source is required to charge a capacitor in order to produce a
linear voltage. The capacitor is discharged by a FET that resets the capacitor
voltage to zero.
This part of the design requires the following: A good current source, very fast
comparators (possibly LVDS receivers), a FET driver circuit (a very fast FET is
needed, such as GaAs FET, which will need a negative voltage to turn off).
The DAC must be moderately fast with a settling time well under 1us (for delay
repetition rates of 100KHz). The bit resolution is not that critical but we prefer
sixteen bits.

Fig 3. Constant Current Source

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

The circuit in Figure 3 is a possible constant current source. The Vref is the set
voltage derived from a stable voltage reference (zener or band gap reference). The
current is set via R1.

R1 should dissipate a bit of power so a Watt resistor may be required


depending on the voltage drop and current. L1 is in the circuit to provide constant
current during the transient of switching the cap back into the circuit (i.e. when
the FET is turned Off).

Fig. 4 Delay Generator


The circuit in Fig.4 is a possible circuit design for the ramp/delay generator. To
start the delay generator, Vgo is driven from the microcontroller to a logic high
state. This pulls the gate of Q1 more negative, turning it OFF and allowing C1 to
start charging. R4 is populated due to the moment Q1 is switched off, C1 appears
as a direct short circuit to ground which causes the ramp to be nonlinear at its
start. (R4 is in the 1 to 15 ohm range). As the cap charges, it produces a linear
voltage ramp. When the ramp voltage reaches the threshold voltage of either of
the two voltage comparators (U2, U3), their outputs will switch, producing both
the TDR step and the Sample pulses. The two delays are adjusted by their
reference voltages Vtdr and Vdac. Vtdr should be a fixed voltage, always
producing the TDR step at the same location in time. Vdac is variable and
allows the Sample pulse to occur before and after the TDR pulse in time.

10

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Fig. 5. Ramp (Voltage vs. Time)

Fig. 6. Ramp (Voltage vs. Delay)

The ramp voltage vs. time can be calculated using:

.
For example:

If a 16-bit DAC is used to set the Sample delay Vdac voltage, very small delay
increments are possible. If the voltage reference input of the DAC is set to the
(delta)V of the ramp (3V in this case), the DAC has 0 to 65535 voltage
increments of

per LSB (Least Significant Bit). Converting this to delay increments,

per LSB. (Referencing the ramp in Figure 4, there would be 65536 possible t
sample dots at a t of 366.2fs). Our required specification is 1ps DAC resolution
so this is a good margin.
The comparators must be very fast. A CML comparator from Analog Devices
ADCMP57x looks to be an ideal part for the TDR pulse comparator/step
generator. This comparator is designed to directly drive 400mV into a 50 ohm
transmission line. Below is a simplified schematic Diagram of its output.
11

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

This comparator has an output rise/fall time of 35ps. Our specification is 75ps.
The TDR step pulse rise time directly affects the resolution of the TDR. If the
TDR rise time is too slow, discontinuities can be missed if their reflection rise
time is faster than the incident step pulse. Two neighboring discontinuities may be
indistinguishable if the distance between them amounts to less half the TDR rise
time. This equation summarizes this concept:

.
In 35ps, light travels approximately 9.6mm. According to the above equation, our
resolution would be approximately 4.8mm.

12

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

5.2.3 The Fast Sampler and Impulse Generator:


Due to the speed of our system, we must use equivalent time sampling to
overcome the bandwidth limitations of real time sampling using ADCs, etc.
Equivalent time sampling requires repetitive input signals. The sampling systems
samples the instantaneous amplitude of the signal during a specific small time
period, digitizes this amplitude, and places the value in a sequential array in
memory. The sample is traditionally known as a dot because these samples
were displayed as dots on old sampling oscilloscopes. The position of the dot
value in the array represents its equivalent horizontal position in time. The sample
time is then incremented slightly (via DAC in our design), and another
instantaneous voltage is sampled (from a different cycle of the input), digitized,
and stored in the array.
Each successive sample is at a slightly later time in relation to a fixed point of
each sampled signal cycle. After many cycles of the input signal, the sampling
system has reconstructed in memory a single facsimile made up of all the samples
in the array, each sample taken in sequence from a different cycle of the input
signal (shown in the blow figures).

Input pulse of a repetitive real-time signal is reconstructed in equivalent-time via


sequential sampling.

13

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Real-time and equivalent-time relationship.

The number of samples and the repetition rate of the system determine the time
required to reconstruct the waveform in memory. After the waveform has been
acquired, the data array is sent to the host computer where it can be
used/displayed.

Fig. 7 Schematic diagram of two diode sampler


The circuit in Figure 7 is a possible two diode sampling circuit. The TDR step
pulse passes from the Delay Generator portion of the circuit through a 50 Ohm,
200ps strip line trace to connector J1. The outgoing and reflected signals are
14

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

sampled by the two diode sampler. The diodes D1 and D2 are low capacitance
Schottky diodes biased off by the two bias voltages Vbias+/-. When the
diodes are momentarily driven into forward conduction by the symmetric strobes
Impulse+/-, the input signal partially charges the hold capacitors C1 and C2. If
the repetition frequency of the input signal is a multiple of the strobe frequency
(and it will be in our design), at each successive strobe interval the sampling
diode will further charge the holding capacitors and cause the output voltage
sampled to asymptotically approach that of the input voltage. These two capacitor
voltages are summed, conditioned and finally digitized by the ADC.

Fig. 8 Schematic diagram of SRD (Step Recovery Diode) Impulse Generator


The sampling delay output Sampdly from Figure 4 is used to produce a fast
pulse that is used to drive the SRD. When the SRD snaps, it produces a very
fast positive and negative impulse that propagates to the diode sampler circuit.
The two shorted transmission lines can be adjusted to change the impulse width.

15

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

5.3 The TDR Application Software:


This software is used to communicate via USB to the TDR remote box. Raw data
is returned to the software after a complete TDR cycle has finished. This can take
several seconds to collect the data and process it for display and measurements.
Since the system is not a real time system this should not be a problem.
A certain amount of unwanted noise is expected as well as other signal
abnormalities. To remove these unwanted signals, an FIR filter can be designed in
software. An FIR filter with impulse response h and input x, where the output is
given by:

Fig. 9: Tapped delay line implementation of an FIR filter.


By definition, the data returned from the TDR remote Box is data from a tapped
delay line so it may be possible to simply multiply each of these discrete data
points by a coefficient in order to adjust the filter (much like a graphic equalizer
for audio).
The filter coefficients are a bit tricky to determine, and using inverse convolution
or deconvolution to find the coefficients can blow up if the noise is amplified
instead of actual signal information. Figure 10 shows an example of
deconvolution being used for our software.

16

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Fig. 10: TDR Application Software Filter


After the data has been processed, an image showing the TDR signal amplitude in
volts or vs. time will be displayed in a window on the display. The window will
have a grid similar to an oscilloscope making it easier to use. A user cursor or a
pair of cursors will be movable along the displayed waveform indicating time,
amplitude, the reflection coefficient () and the impedance () of the current
cursor position.

17

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

6. Schedule and Budget


Highland Technology, Inc. has agreed to provide financing as well as the use of
their production and testing facility. We wanted to design the product to be as
cheap to produce as possible with a target materials cost of around $200. We will
obviously need to spend much more than this for the prototype and rev A PCBs
and for parts. The initial development cost was estimated at approximately $2000.
Our schedule was as follows:
3/22/2011 (week):

Finalize Schematic.

3/29/2011 (week):

Complete PCB layout, send for production by 3/31 (3-day


quick turnaround).

4/8/2011:

Assemble board.

4/9-15/2011:

Debug and test hardware.

4/18/2011:

Integrate hardware and software.

4/25-29/2011:

Debug software.

5/2-6/2011:

Finish up and write spec.

18

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

7. Results

We broadly followed the preferred implementation discussed in section 5, but


with a few changes.
After a brief overview of our project implementation, the results will be explained
in this section in order of the TDR board schematic, its layout, the microcontroller
programming, the software programming, and the TDRs final performance
characteristics. Only channel one will be discussed here.
7.1 Implementing Our Project: Overview
From our original concept and TDR Circuit Diagram from Fig. 2 (which describes
a single channel TDR system), our sponsor (Highland Technology) suggested that
we produce a two-channel TDR system for performing differential TDR
measurements. The understanding was that for this project we only focus on a
single-channel TDR system, adding the other channel to the system later.
We designed each of the three sections in the block diagram (Figure 2) and
produced a schematic (Appendix A). After drawing up the schematic, there were
several design-review sessions where changes were made until both we and our
sponsor were satisfied with the circuit design. We wanted to design the circuit
board entirely with components that Highland currently carried in stock. This
reduced the cost and manufacture time of the prototype. We created a parts list
from the schematic procured our parts from stock.
After completing the schematic, we next had to design the printed circuit board.
Since the design that we had settled on consisted on several unique geometries,
we could not use an off-the-shelf development system for the high-speed analog
portion of the design. This forced us to design a custom printed circuit board that
incorporated all three sections of our block diagram. The dimensions of the PCB
(6.180x 3.465) were determined by an enclosure chosen by Highland. Highland
intends to make a product out of this design in the future, so they wanted it to fit
in their T product line, which is defined by the dimensions of the product
enclosure. Due to the component size and quantity that had to fit in this
predefined area, the board stack-up consists of four electrical layers with
components populated on both the top and bottom of the board. This increased the
board and manufacturing cost slightly, but it was necessary for the prototype.

19

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

The board design took a longer time to design than we expected, mainly because
of the complex geometries that were used in the high-speed step and impulse
generator circuits used to produce the TDR step and the impulse voltage for the
diode sampler. The traces for these circuits are impedance-controlled and two
different techniques were used to produce these traces (Microstrip and Coplanar
Wave Guide with Ground (CPWGG)). Each technique presented its own set of
challenges and every time a change was made to the design such as moving a
component, trace calculations were necessary and the traces were carefully
redrawn. The delays in board layout and design review meetings put the project
behind schedule by a little over one month.
Once the board design was complete, the design files were sent to a quick-turn
board manufacturing house, and we had our boards in four days. Since the boards
were designed with mostly surface-mount components, we were able to use solder
paste to solder our components. A solder paste mask was manufactured at a
different location while the boards were being manufactured and we received both
on the same day. It then took one afternoon to populate the components, solder,
clean, and inspect the boards. This was completed on Friday, April 15, 2011.
Figure 11 is an image of our populated printed circuit board.

Fig. 11 Custom Printed Circuit Board


The next figure (Fig. 12) shows the different areas of the PCB as they correspond
to our concept block diagram and schematic.

20

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Fig. 12 Different Sections of the Board

7.2 TDR Board Schematic


Refer to the schematic in Appendix A for the discussion below, which is broken
down into power, communications, LEDs, delay generator, step generator,
impulse generator, sampler, sample conditioning, and ADC buffers.
7.2.1 Power
The TDR is supplied by power labeled in the schematic as +12V, +5A, +3.3V,
+3.3A, -7.5V, and -5A (sheet 9). The voltages marked A are for analog
circuitry.
7.2.2 Communications
The microcontroller can be programmed as a target via JTAG pins (sheet 3, upper
left corner).
21

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

The microcontrollers signals CPUTX and CPURX exit P0[0] and P0[1],
respectively (sheet 2), and are sent to both the USB connector and RS-232
connector (sheet 3) for serial communications with the personal computer.
7.2.3 LEDs
The microcontroller sends commands to two LEDs (sheet 2). LEDSAMP2,
LEDCOMM, and LEDERR are currently not being used. LEDSAMP1 inverts and
blinks D4 while sampling. The unnamed signal from port zero, pin 23 P0[23]
briefly lights D11 (HEART BEAT) every second when the TDR is powered on.
7.2.4 Delay Generator
Time zero for a single sample begins when the microcontroller sends
commands DDG_D and DDGCLK (sheet 2, left side) to set the vernier flip-flop
U10 (sheet 5). Q bar goes from high to low, turning off Q2. With the current
provided by the current source (U5, Q1, et al.), VERNIER becomes a ramp signal.
CLAMP is 3V, and with 0.3V across D3, the ramp clamps at 3.3V. VERNIER is
also buffered by U11 into the signal BVERNIER.
7.2.5 Step Generator
When the TDR powers on it sends commands STDAC_CS and STDAC_LO
(sheet 2) to the Step DAC U20 (sheet 7). This outputs an analog voltage signal
STEPDAC1 to fast comparator U12. The ramp signal BVERNIER on sheet five
inputs to the fast comparator, and when its voltage matches STEPDAC1, a step
pulse is sent down a 50 Ohm trace and out J3 through the device under test.

7.2.6 Impulse Generator


Before the microcontroller starts each vernier delay ramp, the singals
SAMP_CS/LD and SAMP_CLR (sheet 2, left side) are sent to the impulse
delay/sampling delay DAC (sheet 6, bottom left), controlling the time of the
vernier delay ramp that a sample will be taken. The DAC outputs the analog
signal SAMPDAC, which is sent to the comparator U13 and compared with
VERNIER (from sheet 5). When VERNIER matches SAMPDAC, a step pulse is
generated. The resultant induced (opposite) signals in the twisted pair of wires
will reverse-bias D10, a step recovery diode that will momentarily conduct before
snapping off, creating pulses of opposite polarities on either side. These pulses,
with their extremely short durations, are conducted through the capacitors and
sent down the 50-Ohm traces.

22

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

7.2.7 Sampler
When the impulses reach C59 and C60 (sheet 11) the capacitors act like shorts,
and for a brief duration of time, Schottky diodes D8 and D9 conduct, charging
C24 and C35 with the voltage from the 50-Ohm trace coming from the fast
comparator. These are summed at a node into the signal VSAMP1, which is sent
for conditioning.
7.2.8 Sample Conditioning
Rather than use an open loop sampler, we closed the loop. VSAMP1 is sent to the
charge amplifier U8 (sheet 8), where it is inverted and conditioned before being
sent to an integrator, U3 (MEMORY), but it does not happen just yet. The
charge amps output will be a pulse, and the integrator needs to sum the energy of
only that pulse, or it may add (or subtract) unwanted data.
This is controlled by a switch, U4, which passes the sample voltage to the
integrator only during that pulse. The step pulse generated by the sampling
comparator (sheet 5) is sent to two one-shots that delay the signal GATE and
control its duration. GATE is sent to U4 on sheet 8, to pass the signal to the
integrator. The charge amps U6-A and U6-B receive this data and pass it back to
the loop as VM1 and VP1, into C15 and C34 (sheet 7). Approximately five time
constants of the tracking amps will have passed before the next sample.
7.2.9 ADC Buffers
The output of U3, VOUT1 (sheet 8) is conditioned by an ADC buffer, U1 (sheet
4), where its amplitude and offset are at voltages that can be read by the
microcontrollers ADC. The microcontroller sends the samples index and data to
the personal computer, and then prepares for the next sample.

23

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

7.3 Circuit Board Layout


Appendix B shows the TDR Circuit Board Layout. The TDR was laid out for a
four-layer PCB using PADS software. Implementing it required careful
consideration of trace impedance and lengths (for timing), especially the 50-Ohm
traces at the sampler and at the output jacks. Figure 12 above shows a comparison
of the block diagram from our early concept with our actual layout.
7.4 Microcontroller Programming
We used NXPs LPC1768 microcontroller with an ARM Cortex-M3 processor
core. The microcontroller was programmed in C language using LPCXpresso
software, designed for programming LPC targets. Appendix D contains the source
code. The software included header files with macros for register addresses
specific to LPC1768. (For ease of reading these register macros were written in
bold orange in the code in this report. We commented on these registers in the
source code, but refer to the LPC1768 users manual UM10360 for a more
complete explanation of what these registers do.)
7.5 Software Programming
The application software was programmed with PowerBASIC console compiler.
Appendix C contains the source code. It receives data from the TDR, puts it in an
array and processes it, graphs it, and writes it to a readable text file. Some
deconvolution has been experimented with (using MATLAB for convenience),
but further improvements to the board are necessary first (see section 7.6 for
details).
7.6 Test and Verification
During the weekend after they were populated with parts, the boards were
inspected and hardware debug started. This began with simply powering on the
board and measuring the power supply voltages to make sure they are all within
specification.
Power is supplied to the board via an external +15V AC to DC switching power
supply. This is the kind typically used with most portable electronic equipment
and commonly referred to as a wall wart. The external power supply is capable
of supplying +15V at 1.5A.
At the initial power on, the PCB was found to be drawing more current than
anticipated. The power requirements of the board turn out to be 0.35A and our
fuse was rated at 0.25A, so the fuse opened immediately upon applying power to
the board. The fuse was removed and a piece of wire was used instead. This is a
24

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

temporary fix until a larger fuse can be added. The power LED did not light. It
was discovered that this and all the other LEDs had an error in their PCB
footprint, reversing their anode and cathode. To fix this problem, it was necessary
to rotate the LEDs 90 degrees and tack a small piece of wire across the LEDs to
complete the circuit.
From the +15V external supply, six other internal voltage levels are produced:
+12V, +5V, +3.3V, +3.3V (analog), -7.5V (switching power supply), -5V. The
power supply voltages were measured and all were within specification except for
the +12V supply, which had to be adjusted by changing a resistor value.
The next test was to verify that various other voltages in different circuits were
correct. While measuring voltages in the constant current source (used in the
vernier delay circuit), it was discovered that the voltages were incorrect and that
some of the components were getting very hot. An attempt was made to debug
and fix this circuit but the problem is being caused by something not yet
discovered.
Due to the time constraints of our project, this circuit has temporarily been
disconnected and replaced with a simple resistor to +12V. Clamping at +3.3V
(less than half a time constant), it closely resembles a linear ramp, and it has
allowed us to continue testing and debugging. The constant current source will
still need to be corrected for better performance of our circuit (see section 8).
After checking and verifying the various circuit voltages, the next test was to
make the microcontroller blink an LED. We had chosen a microprocessor based
on a 100MHz ARM Cortex M3 core (the LPC1768) for our project. Initially a
demo program was used that blinks an LED on a LPC1768 development board.
We had populated an LED on the same I/O port for the purpose of debug and to
later act as a heart-beat indicator to let us know our program was alive. It was
discovered that this LED also had a pin-out problem but a jumper formed by a
small piece of wire solved it, and we had our blinking LED. This accomplishment
proved that we had established communication with the microcontroller via JTAG
port, that the microcontroller pin-out was correct, that the controller was
functioning, and that we were able to program its flash-based ROM.
The next series of test involved us writing our own custom embedded source
code. We had to test and verify that the RS-232 and USB communications worked
and that the onboard analog-to-digital converter of the microcontroller worked.
We also checked it for accuracy. We completed these tasks over the next few
days. The source code of the microcontroller continues to evolve, as does the host
program that runs on a PC and communicates with the TDR board via RS-232.
25

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Once the source code had evolved to the point where we could start/stop the
vernier delay and digitize the sample voltage, we needed to move on with testing
and measuring the initial performance of the system. In order to establish the
efficiency of the sampler section of the TDR, we needed to observe and measure
the impulses that turn on the sample diodes.
The way this circuit works is that the diode are normally biased to their off state
by applying a 1V back-bias voltage. When the fast impulses arrive at the diodes, it
momentarily biases the diodes into their on state. At this point, the diodes act as
a switch (or sampling gate), allowing some charge to be transferred from the
voltage being measured to a storage capacitor. From there the charge is amplified,
integrated and sampled by the microcontroller analog to digital converter (Fig.
13).

(a) Idealized sampling gate

(b) General two-diode


sampling circuit

(c) Diode bias and sampling pulse


Fig. 13: General Sampling circuitry

26

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

If we know the time that the diode is in its conducting region or on state (tg), we
can calculate the overall bandwidth of our sampler:

BW (GHz )

350
.
t g ps

When we designed the board, it was inconvenient to add test points for measuring
the impulses being generated. To measure the impulses using the highest
bandwidth sampling oscilloscope that we have available, we soldered a piece of
hard-line coaxial cable directly to the board (Fig. 14).

Fig 14. Step Generator and Diode Sampler with 50-Ohm hard line
After soldering the hard-line coax into the impulse circuit, a Tektronix 11801x
50GHz sampling scope was used to measure the impulse amplitude and gate time
(tg). Images of our impulses are displayed in Fig. 15 and 16. In Fig. 15, the
negative impulse has a tg of 295.5 ps and in Fig 16, the tg is 181.0 ps This give a
bandwidth of:
27

Low Cost Portable TDR System

BW (GHz )

Shannon Petty, Paul Bailey

350
1.184 GHz
295.5 ps

BW (GHz )

350
1.933 GHz
181.0 ps

The bandwidth that we would like to have in order to meet our initial
specifications is somewhere on the order of 4 to 5GHz. This falls short of our
desired specification, but we are able to adjust these pulse widths by adding solder
to the gaps on both sides of each shorted transmission line used to set these pulse
widths. These can be seen in Fig. 14 as the traces labeled 25 ohm The pulse
widths, , are set by:

2L
Vp

60% of C

These adjustments can be done at a later time to increase the performance of the
system.

Fig 15. Negative Impulse

Fig 16. Positive Impulse

The next measurement that we made was the rise time of our incident step pulse.
This rise time is important because it determines the linear resolution of our TDR
system:

28

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

TResolution

2 TRisetime

An image or our incident step pulse can be seen below in Fig. 17. The rise time is
a very disappointing 311.52 ps. The high-speed comparator being used to produce
the step pulse can produce edges of 35 to 38 picoseconds. We are still
investigating the reason for our circuits poor performance. According to the
above formula, our resolution would be approximately 48mm, or about 2 inches.
This falls very short of our desired specification of 11.2mm (.440 inches) or
better.
Notably, the jitter of our system was very high (+/-180ps) at the time these
measurements were made, and averaging was used to capture waveforms. This
implies that our edges are much faster than the displays indicate, but at the time of
this report we were unable to verify the actual speeds. The source of the jitter is
still being investigated. The method of operation of the Tektronix 11801x
sampling scope requires 100ns pre-trigger in order to display a waveform. This
meant we had to use our own board as a trigger source while making these
measurements. We did this by using a large RC time constant as our vernier delay
(220ns). We then used the Q output of the vernier flip flop (Appendix A, sheet 5)
used to start the ramp as a trigger source for the sampling scope. We positioned
the step pulse at 100ns by adjusting the comparator DAC voltage to about half of
the vernier ramp amplitude. The problem with this method is that the vernier ramp
is caused by an RC circuit instead of our preferred constant current source as
mentioned above, so the ramp is not entirely linear. Also, any noise on the resistor
power supply translates directly into the ramp voltage, which causes jitter. Until
we correct our fault with the constant current source, we will not be able to
exclude the vernier ramp from the/a source of our jitter, nor will we be able to
make accurate measurements.

29

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Fig 17. Positive Impulse


Finally, using the host software we plot the digitized dot, or voltages, from our
sampler vs. time. Fig. 18 shows a TDR pulse of an open 50-ohm coaxial cable.
The first step of the waveform represents twice the length of the 50-ohm cable
and has the same amplitude as the incident step pulse. The second pulse is double
the amplitude of the incident step and represents infinite impedance. Impedance is
calculated using the reflection coefficient (), obtained by measuring the voltage
sent and the voltages returned:

Vreflected
Vincident

Z L Z0 *

30

1
1

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Fig 18. TDR Pulse from a Tektronix 11801 sampling oscilloscope using and SD-26 head.

Fig 19. TDR Pulse from our TDR system (open 50 ohm cable, 200ns window)
Using our host software, the image shown in Fig. 19 was produced. This image
shows the TDR of a 50 ohm coaxial cable 6 feet long open at the end. The
incident step and the reflected steps show this to be the case. (Ignore the Z and
31

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

rho cursor calculations, as well as the OPEN and SHORT lines in these
figures. They were based on samples that must remain arbitrary until we have
decided on our exact window.) In Fig. 20 the TDR pulse shows the same 50-ohm
coaxial cable with a 50-ohm termination resistor at the end. The amplitude stays
constant, since Z0 is the same as ZL.

Fig 20. TDR of 50 ohm cable terminated into 50 ohm load (200ns window)
In Fig. 21, a TDR pulse is shown of the same 50-ohm coaxial cable shorted to
ground at the end. The little bump is where a pulse should be. It should have the
same amplitude as the incident pulse shown in Fig. 20. We are still investigating
the reason that it does not. We believe it is related to timing and/or offset voltage
adjustments.

32

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Fig 21. TDR of 50 ohm cable shorted to ground. (200ns window).

We are continuing to adjust the circuits in the TDR system in order to improve the
performance.

33

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

8. Discussion and Conclusion


At the time of this report, we didnt meet the performance specifications of the
system that we intended to design. The test and debug stage of the project is not
yet concluded and increase in performance can come from small adjustments to
the system such as changing a resistor or changing timings in the firmware. These
adjustments take a long time to complete, since each change affects other parts of
the system. All have to be analyzed and possibly modified in order to improve a
particular performance aspect. For example, if we adjust the back bias voltage of
the sampling diodes, we will change the integration voltage of the sampler,
causing its output to change. This requires us to change the gain and offset of our
buffer amplifiers and then we must change the host program to scale the voltages
to the proper display levels.
We have produced a TDR system with limited capabilities. Our incident step
pulse rise time, while not suitable for coupon testing of printed circuit boards, is
good enough to test cable impedance for cables over two inches long, if they are
not terminated with a short. We have produced a potential multi-gigahertz diode
sampler, although its current bandwidth is only around 1.5GHz. The fact that this
works at all is amazing to us.
If we could redesign this prototype, the following circuit modifications would
make performance adjustments much easier: add variable resistors to the diode
back bias voltage circuit, to the charge amplifier/integrator circuit, and to the
ADC buffer amplifier circuit; make the ADC buffer circuit an inverting amplifier
with a gain of 0.5 following, by an inverting amplifier with an adjustable gain and
offset; perhaps use an off-the-shelf balun transformer for the step-recovery-diode
(SRD) circuit instead of fabricating our own. This would take the same
manufacturing time, and perhaps improve the performance of our SRD circuit.

34

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

APPENDIX A
Schematic
Sheet 2 (Sheet 1 is the schematics title page):

35

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 3:

36

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 4:

37

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 5:

38

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 6:

39

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 7:

40

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 8:

41

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

Sheet 9:

42

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

APPENDIX B
Board Layout

43

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

APPENDIX C
Source code for application software (in BASIC)
#COMPILE EXE
#DIM ALL
#RESOURCE "ICONANDVERSION.PBR"
' A resource file to make our icon
'******************************************************************************
'*
*
'*
LOW COST PORTABLE TIME DOMAIN REFLECTOMETER
*
'*
*
'* By:
SP, PB
*
'* Version:
Don't know
*
'* Date:
5/1/2011
*
'* For:
*
'*
*
'* https://sites.google.com/site/lcptdrsystem/
*
'*
*
'******************************************************************************
%TRUE
%FALSE
%SAMPCNT

= -1
= 0
= 1024

'Constants to be found from testing


%OPEN
= 2376 ' corresponds to 3V, seen as "open" on TDR
%SHORT
= 382 ' corresponds to 0V, seen as "short" on TDR
%START50
= 100 ' sample number at start of 50-ohm calibration
%END50
= 200 ' sample number at end of 50-ohm calibration
'Graph constants
%XLEN
= 512
%YLEN
= 300
%XSTART
= 50
%YSTART
= 350
%XEND
= 562
%YEND
= 50
%DIVISION
= 100

'
'
'
'
'
'
'

length of display window


height of display window
x=0 on graph
y=0 on graph
x=512 on graph
y=3 div on graph
100 = number of pixels per division

TYPE SampleData
ypos
AS LONG
n
AS LONG
tdr
AS LONG
rho
AS DOUBLE
z
AS DOUBLE
END TYPE

'
'
'
'
'

In an integer between %YSTART and %YEND


Sample number (0 to %SAMPCNT-1)
ADC voltage, in an integer between 0 and 4096
Reflection coefficient
Impedance at corresponding n

44

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

FUNCTION PBMAIN ()
'==============================================================================
'
Variable declarations
'-----------------------------------------------------------------------------LOCAL hComm
AS LONG
'COMM setting identifier
LOCAL comstring()
AS STRING
'COMM port identifier, ports 1 through 9
LOCAL rawData()
AS STRING
'ASCII characters sent from the TDR
LOCAL rDataPtr
AS BYTE PTR 'Start of rawData string
LOCAL numData()
LOCAL tdrData()
LOCAL fiftymean

AS LONG
AS LONG
AS DOUBLE

'undecoded sample number


'undecoded TDR sample value
'voltage corresponding to fifty ohms

LOCAL tdrfile

AS LONG

'Text file for user to view data

LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL
LOCAL

vpdiv
voffset
tpdiv
toffset
fiftyPos
xPos
yPos
hWin
ylabelPtr
openline
shortline

AS
AS
AS
AS
AS
AS
AS
AS
AS
AS
AS

DOUBLE
DOUBLE
DOUBLE
DOUBLE
LONG
LONG
LONG
LONG
BYTE PTR
LONG
LONG

'volts per division


'scrolling up or down on graph
'time per division
'scrolling left or right on graph
'finds graph y-position of 50-ohm cal.
'graph x position
'graph y position
'graph identifier
'for labeling the y axis
'line marking open value
'line marking short value

LOCAL
LOCAL
LOCAL
LOCAL

myInput
y
x
a

AS
AS
AS
AS

STRING
LONG
LONG
LONG

'for various keyboard inputs


'General purpose variable
'General purpose variable
'General purpose variable

LOCAL tryAgain
DIM
DIM
DIM
DIM
DIM
DIM

comstring$(
rawData$ (
tdr
(
curs
numData
(
tdrData
(

AS LONG

'For starting over

8 )
%SAMPCNT )
0 TO %SAMPCNT-1 ) AS SampleData
AS SampleData
4 )
4 )

'==============================================================================
'
The "main program"
'-----------------------------------------------------------------------------WHILE 1
IF tryAgain = 0 THEN GOSUB welcomeScreen
tryAgain = 0
GOSUB openComms
GOSUB getRawData
GOSUB processRawData
GOSUB writeFile
GOSUB graphData
WEND
'Program continues in a continuous loop.

45

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

'==============================================================================
'
The "modules"
'==============================================================================
' Module that presents a screen to start the program.
'-----------------------------------------------------------------------------welcomeScreen:
COLOR 10,0
' Because it's trendy to go green nowadays
CLS : PRINT
PRINT " ************************************************************
PRINT " *
*
PRINT " *
T
D
R
*
PRINT " *
*
PRINT " *
*
PRINT " * Shannon Petty's and Paul Bailey's
*
PRINT " * enigmatic Senior Design Project
*
PRINT " *
*
PRINT " * (sites.google.com/site/lcptdrsystem)
*
PRINT " ************************************************************
PRINT : SLEEP 500
RETURN

"
"
"
"
"
"
"
"
"
"

'==============================================================================
' Module that opens COM3 for communications with the TDR
'-----------------------------------------------------------------------------openComms:
FOR x = 1 TO 9
comstring$(x) = "COM" + CHR$(x+48)
NEXT x
PRINT "Opening serial comms . . . " : SLEEP 300
hComm = FREEFILE
x = 1
WHILE %TRUE
COMM OPEN comstring(x) AS #hComm
IF ERRCLEAR THEN
x = x+1
IF x = 10 THEN
PRINT "
ERROR! COM1 through COM9 are not available, and I can't"
PRINT "
open COM10 without doing some crazy stuff! Check your"
PRINT "
port settings, then press any key to continue."
INPUT FLUSH : WAITSTAT
x = 1
END IF
ITERATE LOOP
ELSE
EXIT LOOP
END IF
WEND
COMM
COMM
COMM
COMM
COMM
COMM

SET
SET
SET
SET
SET
SET

#hComm,
#hComm,
#hComm,
#hComm,
#hComm,
#hComm,

BAUD
BYTE
PARITY
STOP
TXBUFFER
RXBUFFER

=
=
=
=
=
=

38400
8
%FALSE
0
1024
4194304

'
'
'
'
'
'

9'k6 baud
8 bits
No Parity
1 stop bit
1 Kb transmit buffer
4 Mb receive buffer

PRINT
PRINT , comstring(x)
PRINT , "opened successfully."
PRINT
PRINT "
WARNING! Continuing will overwrite previous tdrdata.txt"
PRINT "
file. If you do not want to overwrite tdrdata.txt, move"
PRINT "
it to a different directory." : PRINT
PRINT "Press any key to continue."
: PRINT
INPUT FLUSH : WAITSTAT
RETURN

46

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

'==============================================================================
' Module that gets "raw data," strings of twelve characters,
' form the TDR and puts them into an array
'-----------------------------------------------------------------------------getRawData:
PRINT
PRINT "
Collecting Data."
PRINT
PRINT "
This takes a wicked long time."
PRINT
PRINT "
Smoke if you got em."
PRINT
y = TIMER
FOR x = 0 TO %SAMPCNT-1
COMM SEND #hComm, "?"
WHILE COMM(#hComm, RXQUE) < 12
IF TIMER-y > 20 THEN
'Timeout error
PRINT "ERROR!!! Not all values were read!"
rawData$(x) = "0000000000"
ITERATE FOR
END IF
WEND
COMM LINE #hComm, rawData$(x)
IF x = INT(%SAMPCNT*1/10) THEN PRINT "
10% complete"
IF x = INT(%SAMPCNT*2/10) THEN PRINT "
20% complete"
IF x = INT(%SAMPCNT*3/10) THEN PRINT "
30% complete"
IF x = INT(%SAMPCNT*4/10) THEN PRINT "
40% complete"
IF x = INT(%SAMPCNT*5/10) THEN PRINT "
50% complete"
IF x = INT(%SAMPCNT*6/10) THEN PRINT "
60% complete"
IF x = INT(%SAMPCNT*7/10) THEN PRINT "
70% complete!"
IF x = INT(%SAMPCNT*8/10) THEN PRINT "
80% complete!!"
IF x = INT(%SAMPCNT*9/10) THEN PRINT "
90% complete!!!!!"
NEXT x
COMM CLOSE #hComm
RETURN

47

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

'==============================================================================
' Module to sort out the TDR's data (sample number and ADC value)
' and put them in their own arrays. Also calculates rho, time, and
' impedance for each sample.
'-----------------------------------------------------------------------------processRawData:
CLS : SLEEP 500 : PRINT : PRINT
PRINT "Processing data."
FOR x = 0 TO %SAMPCNT-1
rDataPtr = STRPTR(rawdata$(x))
' decode the
numData(0) =
numData(1) =
numData(2) =
numData(3) =
tdr(x).n
=

sample number (will be a value between 0 and %SAMPCNT):


ASC(CHR$(@rDataPtr[1]))-48
ASC(CHR$(@rDataPtr[2]))-48
ASC(CHR$(@rDataPtr[3]))-48
ASC(CHR$(@rDataPtr[4]))-48
numData(0)*4096 _
+ numData(1)*256_
+ numData(2)*16_
+ numData(3)
' decode the tdrValue (Will be a value between 0 and 4096):
tdrData(0) = ASC(CHR$(@rDataPtr[6]))-48
tdrData(1) = ASC(CHR$(@rDataPtr[7]))-48
tdrData(2) = ASC(CHR$(@rDataPtr[8]))-48
tdrData(3) = ASC(CHR$(@rDataPtr[9]))-48
tdr(x).tdr = 4096 - (tdrData(0)*4096 _
+ tdrData(1)*256 _
+ tdrData(2)*16 _
+ tdrData(3))
IF tdr(x).n<0 THEN
tdr(x).n
= 0
'Some stray characters,
tdr(x).tdr = 0
'highwaymen and assassins.
END IF
NEXT x
' Now, find the mean 50-Ohm voltage!
fiftymean = 0
' y used as average here
FOR x = %START50 TO %END50
fiftymean = tdr(x).tdr + fiftymean
NEXT x
fiftymean = fiftymean/(%END50-%START50+1)
'Now, find rho and Z for each sample!
FOR x = 0 TO %SAMPCNT-1
'Some linear interpolation is used here in case 50-Ohms does not cor'respond to exactly the mean of Open and Short. Convolution can be used
'when times get lush.
IF tdr(x).tdr > fiftymean THEN
tdr(x).rho = (tdr(x).tdr - fiftymean) / (%OPEN - fiftymean)
ELSE
tdr(X).rho = (tdr(x).tdr - %SHORT) / (fiftymean - %SHORT) - 1
END IF
tdr(x).z
= 50*(1+tdr(x).rho)/(1-tdr(x).rho)
NEXT x
PRINT
PRINT "Done processing data. Hold on a sec."
SLEEP 500
RETURN

48

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

'==============================================================================
' Module to put processed data into a readable text file
'-----------------------------------------------------------------------------writeFile:
tdrfile& = FREEFILE
OPEN "tdrdata.txt" FOR OUTPUT AS #tdrfile&
PRINT #tdrfile&, ,,,"TDR DATA"
PRINT #tdrfile&,
PRINT #tdrfile&, "File Created on: "; DATE$; " at "; TIME$
PRINT #tdrfile&,
PRINT #tdrfile&, "Sample no.",,"ADC Value (V)",,"Rho",,"Z"
PRINT #tdrfile&,
FOR x = 0 TO %SAMPCNT-1
PRINT #tdrfile&, tdr(x).n,, FORMAT$(tdr(x).tdr*3/4096, "0.000"),
PRINT #tdrfile&, , FORMAT$(tdr(x).rho, "0.0000"), ,
IF tdr(x).z > 1000 THEN
PRINT #tdrfile&, FORMAT$(tdr(x).z, "0.3E+###")
ELSE
PRINT #tdrfile&, FORMAT$(tdr(x).z, "##.000")
END IF
NEXT x
CLOSE #tdrfile&
RETURN
'==============================================================================
' A big, long module that plots the data and calculates
' V, rho, and z, based on cursor position.
'-----------------------------------------------------------------------------graphData:
GRAPHIC WINDOW "TDR!!!", 20, 20, %XLEN+100, %YLEN+100 TO hWin
GRAPHIC ATTACH hWin, 0
'the default values
vpdiv = 1
' volts per division
tpdiv = 200
' time (samples) per division
voffset = 0
' voltage offset due to scrolling
toffset = 0
' not yet used
fiftyPos = %YSTART _
' Graph position of fifty-ohm cali- ( %YLEN*fiftymean/4096 _
' bration
+ voffset*%DIVISION
)/vpdiv
curs.ypos = fiftyPos-(fiftyPos MOD 10) ' Cursor starts near 50-Ohms
theMainGraph:
' Updated position values based on scolling, cursor movement, etc.
fiftyPos = %YSTART - (%YLEN*fiftymean/4096 + voffset*%DIVISION)/vpdiv
openline = %YSTART - (%YLEN*%OPEN/4096 + voffset*%DIVISION)/vpdiv
shortline = %YSTART - (%YLEN*%SHORT/4096 + voffset*%DIVISION)/vpdiv
curs.tdr = ((%YSTART-curs.ypos)*vpdiv - voffset*%DIVISION)*4096/%YLEN
' Some linear interpolation to calibrate if 50-Ohms does not
' exactly corespond to the mean(open, short) :
IF curs.tdr > fiftymean THEN
curs.rho = (curs.tdr-fiftymean)/(%OPEN-fiftymean)
ELSE
curs.rho = (curs.tdr-%SHORT)/(fiftymean-%SHORT) - 1
END IF
curs.z = (1+curs.rho)/(1-curs.rho)*50

49

Low Cost Portable TDR System

CLS
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT
PRINT

"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"

GRAPHIC
GRAPHIC
GRAPHIC
GRAPHIC

Shannon Petty, Paul Bailey

=====================================================
| TDR data printed to:
tdrdata.txt
|
| in this program's directory.
|
+---------------------------------------------------+
|
Here are the options:
|
| (You need to be in this window to perform these.) |
+----------------------------+----------------------+
|
W:
|
|
|
Scroll up
|
|
|
A:
S:
|
B: Begin again
|
| Increase
Decrease |
|
|
V/div
Z:
V/div |
ESC: Exit program |
|
Scroll
|
|
|
down
|
|
+----------------------------+----------------------+
|
U: Cursor up
|
|
|
|
N: Cursor down
|
|
|
| (Set your offset and V/div before moving cursor.) |
=====================================================

"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"

CLEAR
BOX (0,0) - (%XLEN+100, %YLEN+100), 0, %BLACK, %BLUE
BOX (7,7) - (%XLEN+93, %YLEN+93 ), 0, %BLACK, RGB(255,255,224)
COLOR %BLACK, RGB(255,255,224)

'axes
GRAPHIC LINE (%XSTART, %YEND) - (%XSTART, %YSTART)
GRAPHIC LINE STEP - (%XEND,%YSTART)
'title
GRAPHIC SET POS (240, 10)
GRAPHIC PRINT "TDR RESULTS"
'v/div and cursor values:
GRAPHIC SET POS (75, 25)
GRAPHIC PRINT "V/div = "
GRAPHIC SET POS (125, 25)
GRAPHIC PRINT STR$(vpdiv,5)
GRAPHIC SET POS (175, 25)
GRAPHIC PRINT "rho = "
GRAPHIC SET POS (225, 25)
GRAPHIC PRINT FORMAT$(curs.rho, "0.000")
GRAPHIC SET POS (295, 25)
GRAPHIC PRINT "Z = "
GRAPHIC SET POS (325, 25)
IF curs.ypos < openline THEN
GRAPHIC PRINT "Inf"
ELSEIF curs.ypos > shortline THEN
GRAPHIC PRINT "0.000"
ELSE
GRAPHIC PRINT STR$( curs.z, 4 )
END IF
GRAPHIC SET POS (395, 25)
GRAPHIC PRINT "V = "
GRAPHIC SET POS (425, 25)
GRAPHIC PRINT STR$( curs.tdr*%YLEN/4096/%DIVISION, 4 )
'x-axis title
GRAPHIC SET POS (100,%YSTART+10)
GRAPHIC PRINT "SAMPLE NUMBER (THIS WILL LATER BE 'TIME')"
'x-axis ticks
FOR x = 1 TO 5
GRAPHIC LINE ( %XSTART+x*%DIVISION, %YSTART )_
- ( %XSTART+x*%DIVISION, %YSTART-10 )
NEXT x

50

Low Cost Portable TDR System

'y-axis
GRAPHIC
GRAPHIC
GRAPHIC

Shannon Petty, Paul Bailey

ticks
LINE ( %XSTART, %YSTART-100 ) - ( %XSTART+10, %YSTART-100 )
LINE ( %XSTART, %YSTART-200 ) - ( %XSTART+10, %YSTART-200 )
LINE ( %XSTART, %YEND
) - ( %XSTART+10, %YEND
)

'x grid
y = %YSTART - 100
WHILE y >= %YEND
x = %XSTART
WHILE x =< %XEND-10
GRAPHIC LINE (x,y)-(x+10,y), %GRAY
x = x + 20
WEND
y = y - 100
WEND
'y grid
x = %XSTART + 100
WHILE x =< %XEND
y = %YSTART
WHILE y >= %YEND+10
GRAPHIC LINE (x,y)-(x,y-10), %GRAY
y = y - 20
WEND
x = x + 100
WEND
'Cursor gridline
x = %XSTART
WHILE x =< %XEND-10
GRAPHIC LINE (x,curs.ypos)-(x+5,curs.ypos), RGB(0,139,139)
x = x + 10
WEND
'OPEN and SHORT markers
GRAPHIC COLOR RGB(255,160,122), RGB(255,255,224)
GRAPHIC LINE (%XSTART, openline)-(%XEND, openline), RGB(255,160,122)
GRAPHIC SET POS (%XEND-50,openline-15)
GRAPHIC PRINT "OPEN"
GRAPHIC LINE (%XSTART, shortline)-(%XEND, shortline), RGB(255,160,122)
GRAPHIC SET POS (%XEND-50,shortline+5)
GRAPHIC PRINT "SHORT"
GRAPHIC COLOR %BLACK, RGB(255,255,224)
'x-axis markers
FOR x = 1 TO 5
GRAPHIC SET POS( %XSTART+5+x*%DIVISION, %YSTART-15 )
GRAPHIC PRINT STR$( tpdiv*(x + toffset) )
NEXT x
'y-axis markers
FOR x = 0 TO 3
GRAPHIC SET POS( %XSTART-25, %YSTART-x/3*%YLEN )
GRAPHIC PRINT FORMAT$( vpdiv*x - voffset, "#.##" )
NEXT x
'y-axis label
myInput
= "ADC VOLTAGE V"
ylabelPtr = STRPTR(myInput)
FOR y = 0 TO LEN(myInput)-1
GRAPHIC SET POS (15,110+15*y)
GRAPHIC PRINT CHR$(@ylabelPtr[y])
NEXT y
' The data points
FOR x = 0 TO %SAMPCNT-1
yPos = %YSTART - (%YLEN*tdr(x).tdr/4096 + voffset*%DIVISION)/vpdiv
xPos = %XSTART + tdr(x).n/(tpdiv/%DIVISION)
GRAPHIC SET PIXEL (xPos, yPos), %RED
NEXT x
GRAPHIC REDRAW

51

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

mainGraphWait:
' Portion that determines user's next step: end program,
INPUT FLUSH
' resend data and plot again, move cursor, scroll, or
WAITSTAT
' change V/div
myInput = INKEY$
SELECT CASE myInput
CASE $ESC : GOTO terminate
CASE "a"
IF vpdiv = 1 THEN
PRINT " Volts per division is at its max."
GOTO mainGraphWait
ELSEIF vpdiv = 0.5 THEN
vpdiv = 1 : GOTO theMainGraph
ELSEIF vpdiv = 0.2 THEN
vpdiv = 0.5 : GOTO theMainGraph
ELSEIF vpdiv = 0.1 THEN
vpdiv = 0.2 : GOTO theMainGraph
ELSEIF vpdiv = 0.05 THEN
vpdiv = 0.1 : GOTO theMainGraph
ELSEIF vpdiv = 0.02 THEN
vpdiv = 0.05 : GOTO theMainGraph
ELSE
' if vpdiv = 0.01
vpdiv = 0.02 : GOTO theMainGraph
END IF
CASE "s"
IF vpdiv = 1 THEN
vpdiv = 0.5 : GOTO theMainGraph
ELSEIF vpdiv = 0.5 THEN
vpdiv = 0.2 : GOTO theMainGraph
ELSEIF vpdiv = 0.2 THEN
vpdiv = 0.1 :GOTO theMainGraph
ELSEIF vpdiv = 0.1 THEN
vpdiv = 0.05 : GOTO theMainGraph
ELSEIF vpdiv = 0.05 THEN
vpdiv = 0.02 : GOTO theMainGraph
ELSEIF vpdiv = 0.02 THEN
vpdiv = 0.01 : GOTO theMainGraph
ELSE
' if vpdiv = 0.01
PRINT " Volts per division is at its min."
GOTO mainGraphWait
END IF
CASE "w"
voffset = voffset - vpdiv
GOTO theMainGraph
CASE "z"
voffset = voffset + vpdiv
GOTO theMainGraph
CASE "b"
CLS : GRAPHIC WINDOW END
tryAgain = 1
RETURN
CASE "u"
IF ABS(curs.ypos-%YEND) < 10 THEN
PRINT " The cursor is at its max."
GOTO mainGraphWait
ELSE
curs.ypos = curs.ypos - 10
GOTO theMainGraph
END IF
CASE "n"
IF ABS(curs.ypos-%YSTART) < 10 THEN
PRINT " The cursor is at its min."
GOTO mainGraphWait
ELSE
curs.ypos = curs.ypos + 10
GOTO theMainGraph
END IF

52

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

CASE ELSE
PRINT
PRINT "
Invalid key pressed "
PRINT
PRINT "
Options are W, A, S, B, U, N, Z, and ESC "
PRINT "
(Hint: don't use caps.)"
PRINT
GOTO mainGraphWait
END SELECT
RETURN
terminate:
END FUNCTION

53

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

APPENDIX D
Source code for LPC1768 microcontroller on TDR board (in C)
(See comments in code regarding register definitions not found in common libraries.)
/*
===============================================================================
File Name
: main.c
Author
: SP and PB
Version
: I'm not a version!
Copyright
: Copyright (C) 04/2011
Description : main definition for the TDR program. See comments at front of
"tdr.c" for explanation of orange- and red-highlighted registers
defined in "LPC17xx.h" and UM10360.
===============================================================================
*/
#include "LPC17xx_hti.h"
#include <NXP/crp.h>
#include "tdr.h"

// Thanks to Rob Gaddi, Highland Technology


// Code read protection macros
// All our bells and whistles

#define SAMPCNT
#define STEPDAC_DATA

// Number of samples sent from TDR


// Sets the threshold for delay gen's step
// (1mv/lsb*850 = 0.850V)

1024
850

extern volatile uint32_t UART3Count, msTicks; // Variables that get modified by


// IRQ handlers in tdr.c
__INLINE static void systick_delay (uint32_t dlyTicks)
{
// An inline function to delay for dlyTicks * 1 ms
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
//==========================MAIN FUNCTION======================================
int main(void) {
volatile uint32_t
adcVal,
// Data from the ADC
sampCount,
// Number of samples
stepDacData;
// Data to send to the Step DAC
volatile uint16_t
dacdata;
// Unsigned 16-bit int
uint32_t
pulse
// Checks for one-second "heart beat".
int i, x;
// Some handy integrators.
Initialize_Clocks();
led_init();
ADCInit();
UARTInit();
vernierInit();
spiInit();

//
//
//
//
//
//

Disable PLL0, setup PLLO, then re-enable PLL0.


Initialize the LEDs.
Initialize the ADC.
Initialize the UART.
Initialize the vernier FF.
Initialize the SPI.

// Setup SysTick Timer for 1 msec interrupts


if (SysTick_Config(SystemCoreClock / 1000)) // <-- DON'T TRY CHANGING THIS
{
//
OR YOU MIGHT HOSE UP THE
ledErr_on();
//
CHIP! (See UM10360 p.612
while (1); // Capture error.
if you DO hose it up.)
}
// Set the step DAC reference.
stepDacData = STEPDAC_DATA;
dacdata = (uint16_t)stepDacData;
send14bits(dacdata);

// Cast to a 16-bit integer.

54

Low Cost Portable TDR System

//
//
//
//
//

Enter an eternal
cation will send
will then have a
samples. Then it
signal.

Shannon Petty, Paul Bailey

loop, waiting for the user. The computer applia signal through the serial interface; UART3Count
nonzero value, triggering the TDR to take its
reset UART3Count to zero and wait for the next

sampCount = 0; // Keep track of sample number


i = 0;
// For blinking LEDSAMP1 during TDR sampling.
pulse = msTicks;
while(1)
{
x = msTicks;
while(UART3Count == 0)
{
// Ensure that we don't do TDR until next command from PC
pulse = check_heartbeat(pulse);
if(msTicks-x>500)
{
ledSamp1_off();// If no longer sampling, turn off LEDSAMP1
sampCount = 0; // and reset sampCount
}
}
U3IER = IER_THRE | IER_RLS;
// disable RBR
pulse = check_heartbeat(pulse);
i++;
sampCount++;
dacdata = (uint16_t) (sampCount*64); // point in time to sample
send16bits(dacdata); // Set SAMP_DAC (add 16 each loop for 5ns)
startVernier();
// Trigger the vernier FF.
mydelay(6);
// Wait 6ms.
stopVernier();
// Stop the vernier FF.
adcVal = ADC0Read(); // Read sample.
systick_delay(5);
// Wait for 5ms. to limit loop frequency.
processSend( sampCount, adcVal );
// Turn data into character string
// and send it out the UART.
if (i == 10)
// Make LEDSAMP1 blink.
{
i = 0;
ledSamp1_invert();
}
if (sampCount == 1024)
{
sampCount = 0;
}
UART3Count = 0;
U3IER = IER_THRE | IER_RLS | IER_RBR;
// Re-enable RBR
}
return 0;
}
/* End of main.c */

55

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/******************************************************************************
* tdr.h
*
These are the definitions for functions used in tdr.c and main.c for the
*
TDR project. Special thanks to the good people at NXP for giving new mean*
ing to the word "abstruse."
*
*
We used the same names for registers (U3IER, etc.) that can be found in
*
the user's manual for the LPC1768, UM10360; these registers are defined
*
in NXP's header file "LPC17xx.h"
******************************************************************************/
#ifndef TDR_H_
#define TDR_H_
#include <NXP/LPC17xx/LPC17xx.h>
//==============================================================================
//
#defines here
//-----------------------------------------------------------------------------// Set ADC clock to 1MHz
#define ADC_CLK

1000000

//
UART3 #defines
// We don't want to brute force our comms or guess timing. UART3's IRQ handler
// was provided by NXP's LPC software, and we gladly used it. Here are #defines
// used in their IRQ handler function.
// Bits to set or clear in UART3 interrupt enable register (U3IER). These en// able or disable interrupts for specific registers
#define IER_RBR
0x01
// for the receiver buffer register
#define IER_THRE
0x02
// for the transmit holding register
#define IER_RLS
0x04
// for the Rx line status
// Bits to set or clear in UART3 interrupt identification register (U3IIR).
// These are used for changing certain volatile variables in the IRQ handler,
// and will be necessary for determining if the PC has sent a command to the
// LPC for TDR sampling.
#define IIR_RLS
0x03
// check for Rx line status
#define IIR_RDA
0x02
// check if Rx data available
#define IIR_CTI
0x06
// check chrctr. time-out ind. (not used by us)
#define IIR_THRE
0x01
// check if transmit holding register empty
// Bits to set or clear in UART3 Line Status Register. These contain flags for
// transmit and receive status.
#define LSR_RDR
0x01
// receiver data ready
#define LSR_OE
0x02
// overrun error
#define LSR_PE
0x04
// prity error (we aren't checking parity)
#define LSR_FE
0x08
// framing error
#define LSR_BI
0x10
// break interrupt
#define LSR_THRE
0x20
// transmit holding register ready
#define LSR_RXFE
0x80
// error in Rx FIFO
// UART buffer can only hold so much:
#define BUFSIZE
0x40
// Useful for defining clock frequencies
#define MHZ
1000000
// An important register, not included in NXP's header
#define SPTSR
(*(volatile unsigned long *)(0x40020014UL))
// Clock functions:
void Initialize_Clocks(void);
// SPI, DAC, and vernier functions:
void spiInit(void);
void send14bits(uint16_t data);
void send16bits(uint32_t data);
void vernierInit(void);
void startVernier(void);
void stopVernier(void);
// ADC functions:
uint32_t ADCInit( void );
uint32_t ADC0Read( void );

56

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

// UART functions:
void UART3_IRQHandler (void);
uint32_t UARTInit( void );
void processSend( uint32_t n, uint32_t adcVal );
// LED functions:
void led_init (void);
void heartbeat_on (void);
void ledSamp1_on (void);
void ledErr_on (void);
void heartbeat_off (void);
void ledSamp1_off (void);
void ledSamp1_invert (void);
// Systick and delay functions:
void SysTick_Handler(void);
void mydelay(uint32_t waits);
uint32_t check_heartbeat(uint32_t curTicks);
#endif
/* End of tdr.h */

57

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/*=============================================================================
Name
: tdr.c
Author
: SP and PB
Version
: lost count
Description : Functions called by main.c for TDR's micro-controller. See comments at front of "tdr.h" for embellishment, wit, and erudition.
FIOnDIR, FIOnSET, PINSELn, et al. registers are as named in the
LPC1768's users manual, UM10360, and as defined in NXP's header
file, "LPC17xx.h" In this report these registers are in bold
orange for easy recognition. Macros that define certain bits in
these registers are in red (not bold).
==============================================================================*/
#include "LPC17xx_hti.h"
// Thanks to Rob Gaddi at Highland Technology.
#include <cr_section_macros.h>
// Some changes made to LCP v. 3.6.
#include <NXP/crp.h>
// Code read protection macros.
#include "type.h"
// Type definition for NXP LPC17xx family uPCs.
#include <NXP/LPC17xx/LPC17xx.h>
// Defines registers used in this function.
#include "tdr.h"
// Our header
#define BAUDRATE

38400

// Baud rate for transmitting TDR data to PC

//=============================================================================
//
Function
void Initialize_Clocks(void)
//
//
See LPC17xx User's Manual UM10360, section 4.5.13 on PLL0 setup (page
//
46) and read it carefully because you could really hose this up.
//=============================================================================
void Initialize_Clocks(void)
{
const PLL_SETTINGS pll =
{
.src
= PLL_SRC_INTERNAL,
// 4 MHz
.f_xtal
= 0,
.pll_m
= 75,
// * 2 * 75
.pll_n
= 2,
// / 2
.cclk_div
= 3
// / 3
};
// = 100 MHz
disable_pll();
// Configure the peripheral clocks. The master bootloader
// doesn't actually use any peripherals. Per the errata
// notes, this has to be done while PLL0 is disabled.
PCLKSEL0 = 0;
PCLKSEL1 = 0;
// This only fails if our PLL settings are wrong.
uint32_t clock_freq = configure_pll(&pll);
assert(clock_freq == 100*MHZ);
}

58

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/******************************************************************************
*
*
SPI Functions here
*
*
void spiInit(void)
*
*
void send14bits(uint32_t data)
*
*
void send16bits(uint32_t data
*
******************************************************************************/
//=============================================================================
//
Function
void spiInit(void)
//
//
Sets up SPI with the peripherals on the TDR.
//=============================================================================
void spiInit(void)
{
// Peripheral power control
PCONP &= ~(1 << 8);
// make sure in default mode (redundant)
PCONP |= (1 << 8);
// power on spi hardware
// Peripheral clock setup
PCLKSEL0 |= (3 << 16); // CCLK = 4 MHz; PCCLK = CCLK/8;
S0SPCCR = 0x08;
// Another divider = PCCLK/8, = ca. 62.5 kHz
// Pin setup
PINSEL0 &=~(3 << 30);
// Reset to defaults
PINSEL1 &= ~((3 << 0)|(3<<2)|(3<<4));
// Setup the SPI pins now
PINSEL0 |= (3 << 30);
// Set P0[15] to SCK
(not yet used)
PINSEL1 |= ((3 << 30)|
// Set P0[16] to SSEL,
(3 << 2) |
//
P0[17] to MISO, (not used)
(3 << 4));
//
P0[18] to MOSI
// Interrupts? We don't need no stinkin' interrupts!
// Control signals
//
For the TDR, these are the DAC control signals:
//
P1[0] = ~STDAC_CS
//
P1[1] = ~STDAC_LD
//
P1[4] = SAMP_~CS/LD
//
P1[8] = SAMP_~CLR
PINSEL2 &= ~(0x0003030F);
// Initialize P1[0], P1[1], P1[4], and P1[8]
PINMODE2 &= ~(0x0003030F);
FIO1DIR |= ( (1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) );
FIO1SET = ( (1 << 0) | (1 << 1) | (1 << 4) | (1 << 8) );
return;
}

59

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

//=============================================================================
//
Function
void send14bits(uint32_t data)
//
//
Sends data to the step DAC to set the fixed threshold for the fast com//
parators -- that is, to set the time at which the TDR's step pulse will
//
be generated.
//=============================================================================
void send14bits(uint16_t data)
{
FIO1SET = (1 << 1);
FIO1CLR = (1 << 0);
S0SPCR = 0x00000E3C; // Sets for 14 bits, & does other cool stuff.
// Send the data packing.
S0SPDR = data; // Put data in SPI data register.
while( (S0SPSR & 0x80) != 0x80 )
{
// Wait for transfer complete flag
}
//Toggle the control signals
FIO1SET = (1 << 0);
// Set the chip select high to stop selecting.
mydelay(1);
// wait for a bit
FIO1CLR = (1 << 1);
// Latch the data internally in the DAC.
mydelay(1);
// wait for a bit
FIO1SET = (1 << 1);
// Set the load back to a high value.
// Before we return, we want to clear and verify clear the SPIF bit
// This is done by reading the dummy byte (8-bits) returned during xmit.
volatile uint8_t dummy1;
while((S0SPSR & 0x80) == 0x80)
{
// After transfer complete set, clear it by reading data reg
dummy1 = S0SPDR;
// Read dummy data
}
// Trap here until the bit is cleared
return;
}
//=============================================================================
//
Function
void send16bits(uint32_t data)
//
//
Sends data to the samp DAC to determine at which time to sample the
//
TDR pulse.
//=============================================================================
void send16bits(uint32_t data)
{
FIO1CLR = (1 << 4);
// Set CS/LD low.
FIO1SET = (1 << 8);
// latch the new data in the DAC register.
S0SPCR = 0x0000003C; // Same as above function, but set to 16 bits.
// Ship off the data.
S0SPDR = data;
// Put data in SPI data register.
while( (S0SPSR & 0x80) != 0x80 )
{
// Wait for transfer complete flag in SPTSR bit 7
}
// Toggle the control signals
FIO1SET = (1 << 4);
// Set chip loading ye internal DAC register.
FIO1SET = (1 << 8);
// Always keep on high.
// Clear SPIF bit and make sure it's clear
volatile uint8_t dummy1;
// dummy var for reading dummy data
while ((S0SPSR & 0x80) == 0x80)
{
// After xfer complete flag set, clear it by reading data reg
dummy1 = S0SPDR;
// Read the dummy data
}
// Trap here until the bit is cleared
return;
}

60

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/******************************************************************************
*
*
Vernier functions here
*
*
*
void vernierInit(void)
*
*
void startVernier(void)
*
*
void stopVernier(void)
*
******************************************************************************/
//=============================================================================
//
Function
void vernierInit(void)
//
//
Initialized the GPIO to the vernier FF and gives Q_not an initial high
//
value.
//=============================================================================
void vernierInit(void)
{
// Set P2[0] (DDG_D) and P2[1] (DDGCLK) to 00 - GPIO
PINSEL4 &= (~((3 << 0) | (3 << 2)));
// Set GPIO - P2[0] and P2[1] - to be output
FIO2DIR |= (1 << 0)|(1 << 1) ;
// Signals to set Qn on vernier FF to high, initially
FIO2CLR = (1 << 1);
// Ck low
FIO2CLR = (1 << 0);
// D low
FIO2SET = (1 << 1);
// Ck high (Qn goes high)
}
//=============================================================================
//
Function
void startVernier(void)
//
//
Starts the Vernier ramp by setting Q_not on Vernier FF to high.
//=============================================================================
void startVernier(void)
{
//toggles vernier FF
FIO2CLR = (1 << 1);
// Ck low
FIO2SET = (1 << 0);
// D high
FIO2SET = (1 << 1);
// Ck high (Qn goes low, starts ramp)
FIO2CLR = (1 << 1);
// Ck low
}
//=============================================================================
//
Function
void stopVernier(void)
//
//
Ends the Vernier ramp by setting Q_not on Vernier FF to low.
//=============================================================================
void stopVernier(void)
{
//toggles vernier FF
FIO2CLR = (1 << 0);
// D low
FIO2SET = (1 << 1);
// Ck high (Q high, ends ramp)
FIO2CLR = (1 << 1);
// Ck low
}

61

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/******************************************************************************
*
*
ADC functions here
*
*
* uint32_t ADCInit( void )
*
* uint32_t ADC0Read( void )
*
******************************************************************************/
//=============================================================================
//
Function
uint32_t ADCInit( void )
//
//
Sets up to read the ADC's samples on ye TDR
//=============================================================================
uint32_t ADCInit( void )
{
uint32_t pclkdiv, pclk;
// Enable CLOCK into ADC controller
PCONP |= (1 << 12);
// all the
PINSEL0 |=
PINSEL1 &=
PINSEL1 |=
PINSEL3 |=

related pins are set to ADC inputs, AD0.0~7


0x0F000000;
// P0[12]~[13], A0[6]~[7], function 11
~0x003FC000;
// P0[23]~[26], A0[0]~[3], function 01
0x00154000;
0xF0000000;
// P1[30]~[31], A0[4]~[5], function 11

// By default, the PCLKSELx value is zero, thus the PCLK for


// all the peripherals is 1/4 of the SystemFrequency.
pclkdiv = (PCLKSEL0 >> 6) & 0x03;
switch ( pclkdiv )
{
case 0x00:
default:
pclk = SystemCoreClock/4;
// <-- It'll be this one
break;
// => 100 MHZ/4 = 25MHz
case 0x01:
pclk = SystemCoreClock;
break;
case 0x02:
pclk = SystemCoreClock/2;
break;
case 0x03:
pclk = SystemCoreClock/8;
break;
}
AD0CR = (
(
(
(
(
(
(

0x01 <<
( pclk
0 << 16
0 << 17
1 << 21
0 << 24
0 << 27

0 ) |
/ ADC_CLK - 1 ) << 8 ) |
) |
) |
) |
) |
);

//
//
//
//
//
//
//
//

SEL=1,select channel 0 on ADC0


CLKDIV = Fpclk / ADC_Clk - 1
BURST = 0, no BURST
CLKS = 0, 11 clocks/10 bits
PDN = 1, normal operation
START = 0 A/D conversion stops
EDGE = 0 (CAP/MAT signal
falling, trigger A/D conv.)

return (TRUE);
}

62

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

//=============================================================================
//
Function
uint32_t ADC0Read( void )
//
//
Reads the ADC. What else?
//=============================================================================
uint32_t ADC0Read( void )
{
uint32_t regVal, ADC_Data;
AD0CR &= 0xFFFFFF00;
AD0CR |= (1 << 24) | (1 << 0);
while(1)
{
regVal = AD0DR0;
if ( regVal & ADC_DONE )
{
break;
}
}

// switch channel,start A/D convert


// wait until end of A/D convert
// read result of A/D conversion

AD0CR &= 0xF8FFFFFF;


//
if ( regVal & ADC_OVERRUN )
//
{
//
return ( 0 );
}
ADC_Data = ( regVal >> 4 ) & 0xFFF;
return ( ADC_Data );
//

stop ADC now


save data when it's not overrun, return
zero otherwise

return A/D conversion value

63

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/******************************************************************************
*
*
UART Functions here
*
*
*
void UART3_IRQHandler( void )
*
* uint32_t UARTInit( void )
*
* void processSend( uint32_t n, uint32_t adcVal )
*
******************************************************************************/
volatile
volatile
volatile
volatile

uint32_t
uint8_t
uint8_t
uint32_t

UART3Status;
UART3TxEmpty=1;
UART3Buffer[BUFSIZE];
UART3Count = 0;

//=============================================================================
//
Function
void UART3_IRQHandler (void)
//
//
Regularly updates the above volatile variables, depending on their
//
status. This function has priority as per "cr_startup_lpc176x.c," which
//
contains the forward declarations for the LPC17xx IRQ handlers.
//=============================================================================
void UART3_IRQHandler (void)
{
uint8_t IIRValue, LSRValue;
uint8_t Dummy = Dummy;
IIRValue = U3IIR;

// Identify which interrupts are pending.

IIRValue >>= 1;
IIRValue &= 0x07;

// Now shift out pending bit in IIR.


// Check bit 1~3, interrupt identification.

if ( IIRValue == IIR_RLS )
// (3 << 0), Receive Line Status
{
LSRValue = U3LSR;
if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
{
// There are errors or break interrupt
// Read LSR will clear the interrupt
UART3Status = LSRValue;
Dummy = U3RBR;
// Dummy read on RX to clear
return;
// interrupt, then bail out
}
if ( LSRValue & LSR_RDR )
// Receive Data Ready
{
// If no error on RLS, normal ready, save into the data buffer.
// Note: read RBR will clear the interrupt
UART3Buffer[UART3Count] = U3RBR;
UART3Count++;
if ( UART3Count == BUFSIZE )
{
UART3Count = 0;
// buffer overflow
}
}
}
else if ( IIRValue == IIR_RDA )
// (1 << 1) Receive Data Available
{
// Receive Data Available
UART3Buffer[UART3Count] = U3RBR;
UART3Count++;
if ( UART3Count == BUFSIZE )
{
UART3Count = 0;
// buffer overflow
}
}
else if ( IIRValue == IIR_CTI )
// (3 << 2) Character timeout indicator
{
UART3Status |= 0x100;
// Bit 9 as the CTI error
}

64

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

else if ( IIRValue == IIR_THRE )


{
LSRValue = U3LSR;
if ( LSRValue & LSR_THRE )
{
UART3TxEmpty = 1;
}
else
{
UART3TxEmpty = 0;
}
}

//(1 << 0) transmit holding register empty


// Check status in the LSR to see if
// valid data in U0THR or not

}
//=============================================================================
//
Function UARTInit( void )
//
//
Initializes the UART for serial comms with the PC
//=============================================================================
uint32_t UARTInit( void )
{
uint32_t Fdiv;
uint32_t pclkdiv, pclk;
// pins specific to port3
PINSEL0 &= ~0x0000000F;
PINSEL0 |= 0x0000000A;
PCONP |= ( 1<<4 ) | ( 1<<25 );

// RxD3 is P0[1] and TxD3 is P0[0]


//Enable PCUART3

// The following is a fancy way of setting the clock dividers based on the
// baud rate. See UM10360, page 312 for a figure of the algorithm, and
// section 14.4.12.1 for baud rate calculation.
//
pclkdiv finds the peripheral clock selection (for UART3 here) and in
// the lookup table will find that it's 0x00, so that pclk will be
// SystemCoreClock/4. The rest is to calculate for different baud rates.
pclkdiv = (PCLKSEL1 >> 18) & 0x03;
switch ( pclkdiv )
{
case 0x00:
default:
pclk = SystemCoreClock/4;
// <-- This one, 100 MHz/4 = 25 MHz
break;
//
(Ignore the others.)
case 0x01:
pclk = SystemCoreClock;
break;
case 0x02:
pclk = SystemCoreClock/2;
break;
case 0x03:
pclk = SystemCoreClock/8;
break;
}
U3LCR = (1 << 7) |
// Enable access to dividers (look up)
(0 << 6) |
// No break transmission
(0 << 3) |
// No parity
(0 << 2) |
// 1 stop bit
(3 << 0);
// 8 bits
Fdiv = ( pclk / 16 ) / BAUDRATE ;
// Fdiv = (int)40.69 = 40
U3DLM = Fdiv / 256;
// Divisor latch MSB is 1
U3DLL = Fdiv % 256;
// Divisor latch LSB is 40, or 0x28
U3LCR = 0x03;
// DLAB = 0
U3FCR = 0x07;
// Enable and reset TX and RX FIFO.
NVIC_EnableIRQ(UART3_IRQn);
U3IER = (1 << 0) |
(1 << 1) |
(1 << 2);
return (TRUE);

// UART3_IRQn = 8, a LCPxx-specific
// interrupt number for UART3
// Enable UART3 receiver buffer register interrupt
// Enable UART3 transmit holding register interrupt
// Enable UART3 RX line status interrupt

65

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

//=============================================================================
//
Function
void processSend( uint32_t n, uint32_t adcVal )
//
//
My favorite. This takes the value read from the ADC, assigns it an
//
index number n, puts them in a twelve-byte array, and sends it out
//
the UART.
//
//
Parameters:
n
Index number
//
adcVal
guess
//=============================================================================
void processSend( uint32_t n, uint32_t adcVal )
{
uint8_t *uartPtr;
char sendVal[12];
int i;
uartPtr = (uint8_t *)&sendVal[0];
// "N"
sendVal[0] = (char)
// Sample Number
sendVal[1] = (char)
sendVal[2] = (char)
sendVal[3] = (char)
sendVal[4] = (char)
// ","
sendVal[5] = (char)
// ADC value
sendVal[6] = (char)
sendVal[7] = (char)
sendVal[8] = (char)
sendVal[9] = (char)
// "CR" and "LF"
sendVal[10] = (char)
sendVal[11] = (char)

0x4E

(
(
(
(

0x30
0x30
0x30
0x30

0x2C

(
(
(
(

0x30
0x30
0x30
0x30

(
(

0x0D
0x0A

);
|
|
|
|

((n
((n
((n
((n

&
&
&
&

0x0000F000) >> 12) );


0x00000F00) >> 8 ) );
0x000000F0) >> 4 ) );
0x0000000F)
) );
);

|
|
|
|

((adcVal
((adcVal
((adcVal
((adcVal

&
&
&
&

0x0000F000) >> 12) );


0x00000F00) >> 8 ) );
0x000000F0) >> 4 ) );
0x0000000F)
) );
);
);

for (i=0; i<12; i=i+1)


{
while ( !(UART3TxEmpty & 0x01) ); // THRE status, contain valid data
U3THR = *uartPtr;
// Put current byte in Xmit holding register.
UART3TxEmpty = 0;
// Not empty in the THR until it shifts out.
// (It will update before end of while loop.)
uartPtr++;
}
return;
}

66

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

/******************************************************************************
*
*
LED functions here
*
*
*
void led_init(void)
*
*
void heartbeat_on(void)
*
void ledSamp1_on(void)
*
void ledErr_on
*
*
void heartbeat_off(void)
*
void ledSamp1_off (void)
*
There isn't a need for ledErr_off. It will go off when resetting
*
(unplugging) the TDR.
*
*
void ledSamp1_invert (void)
*
There isn't a use for inverting the other leds, until we make use of
*
the second channel on the TDR
*
******************************************************************************/
void led_init (void)
{
// HEARTBEAT:
PINSEL1 &= (~(3 << 12));
FIO0DIR |= (1 << 22);
FIO0CLR = (1 << 22);

// Set P0{22] to 00 - GPIO


// Set GPIO - P0[22] - to be output
// Turn it off, initially

// LEDSAMP1:
PINSEL3 &= (~(3 << 16));
FIO1DIR |= (1 << 25);
FIO1SET = (1 << 25);

// Set P1[25] to 00 - GPIO


// Set GPIO - P1[25] - to be output
// Turn it off, initially

// LEDERR:
PINSEL3 &= (~(3 << 22));
FIO1DIR |= (1 << 27);
FIO1SET = (1 << 27);

// Set P1[27] to 00 - GPIO


// Set GPIO - P1[27] - to be output
// Turn it off, initially

}
void heartbeat_on (void)
{
FIO0SET = (1 << 22);
}
void ledSamp1_on (void)
{
FIO1CLR = (1 << 25);
FIO2SET = (1 << 11);
}
void ledErr_on (void)
{
FIO1SET = (1 << 27);
}
void heartbeat_off (void)
{
FIO0CLR = (1 << 22);
}
void ledSamp1_off (void)
{
FIO1SET = (1 << 25);
FIO2CLR = (1 << 11);
}

// P0[22] goes to active high HEARTBEAT

// P1[25] goes to active low LEDSAMP1


// Development board

// P1[27] goes to active low LEDERR

// P0[22] goes to active high HEARTBEAT

// P1[25] goes to active low LEDSAMP1


// Development board

67

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

void ledSamp1_invert (void)


{
int ledstate1, ledstate2;
// Read current state of GPIO P0_0..31, which includes LED2
ledstate1 = FIO1PIN;
// Turn off LED2 if it is on
// (ANDing to ensure we only affect the LED output)
FIO1SET = ~ledstate1 & (1 << 25) ;
// Turn on LED2 if it is off
// (ANDing to ensure we only affect the LED output)
FIO1CLR = ((ledstate1) & (1 << 25));
// Read current state of GPIO P0_0..31, which includes LED2
ledstate2 = FIO2PIN;
// Turn off LED2 if it is on
// (ANDing to ensure we only affect the LED output)
FIO2SET = ~ledstate2 & (1 << 11) ;
// Turn on LED2 if it is off
// (ANDing to ensure we only affect the LED output)
FIO2CLR = ((ledstate2) & (1 << 11));
}
/******************************************************************************
*
*
SysTick Functions
*
*
void SysTick_Handler(void)
*
increment counter necessary in Delay()
*
* uint32_t check_heartbeat(uint32_t curTicks)
*
"Beats" the HEARTBEAT led every second
*
******************************************************************************/
volatile uint32_t msTicks;
void SysTick_Handler(void)
{
msTicks++;
}

// Increments 1ms "clock"

//=============================================================================
//
Function
mydelay(waits*90ns + 70ns)
//
//
With the PLL boosting our 4MHs up to 100MHz, each assembly instruction
//
(if 1 clock/instruction) takes 10ns.
//
//
This is a brute force delay the min. (waits = 0) delay is ca. 160ns.
//
Each nummber of waits adds ca. 90ns.
//=============================================================================
void mydelay(uint32_t waits)
{
if (waits < 1)
{
// gotta be at least one man.
waits = 1;
}
while(waits != 0)
{
// decrement waits
waits--;
}
return;
}

68

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

//=============================================================================
//
Function
uint32_t check_heartbeat(uint32_t curTicks)
//
//
"Beats" the HEARTBEAT led by briefly turning it on every second, give
//
or take.
//
//
Parameter:
curTicks
Value to compare with system's msTicks.
//
Function will return as is or reset to zero,
//
depending whether or not it's time for a
//
"beat."
//=============================================================================
uint32_t check_heartbeat(uint32_t curTicks)
{
if((msTicks - curTicks) >= 960)
{
heartbeat_on();
}
if((msTicks - curTicks) >= 1000)
{
heartbeat_off();
curTicks = msTicks;
}
return curTicks;
}

/* End of tdr.c */

69

Low Cost Portable TDR System

Shannon Petty, Paul Bailey

APPENDIX E
References
Hewlett Packard Application Note 918: Pulse and Wavefore Generation with Step
Recovery Diodes. Palo Alto: Hewlett Packard, 1984.
LCP17xx Users Manual UM10360. NXP Semiconductors, 2010.
Mulvey, John. Sampling Oscilloscope Circuits. Beaverton: Tektronix, 1970.

70

Вам также может понравиться