[04-NOV-24] The Function Generator (A3050) is TCPIP-controlled, Power-over-Ethernet, signal generator for use in test fixtures and quality control systems. We control the A3050 by writing values to its control registers and waveform memory through its network interface. The instrument itself consists of eight-bit resistor DACs, register-configurable low-poss filters, register-configurable attenuators, and fixed-gain amplifiers. The A3050 is an example of a LWDAQ system of Form C. To open a socket to the A3050, we use the LWDAQ Messaging Protocol. This protocol is simple, open-source, and efficient. We provide TclTk code that interacts with the A3050, including an example quality control program with graphical user interface that will configure the A3050 for sine waves, square waves, and sweeps.
To configure the A3050, we open a socket to its IP address and port. We send a start byte (0xA5), a four-byte message type, a four-byte content length, the content of exactly the specified length, and an end byte (0x5A). The message types are things like byte_write, stream_write, and version_read. Although no Python library currently exists to control the A3050, we do not expect Python programmers to have any difficulty operating the A3050.
[04-NOV-24] The following versions of the Function Generator (A3050) exist.
Version | Range (High Z) |
Range (50 Ω) |
Minimum Frequency |
Corner Frequency |
Comment |
---|---|---|---|---|---|
A3050A | ±9.5 V | ±4.8 V | 1 mHz | 2 MHz | Prototype |
A3050B | ±9.5 V | ±4.8 V | 1 mHz | 1 MHz | Discontinued |
A3050C | ±10.0 V | ±5.0 V | 1 mHz | 2 MHz | Active |
For each version, we give the minimum frequency, as dictated by the length of the clock divider in the generator's firmware. We give the corner frequency, which is the frequency at which the sinusoidal output drops by 3 dB.
[04-NOV-24] On the rear side of the instrument is a 100-Base-T, Power over Ethernet, RJ-45 socket. In order to function, the A3050 must be connected with a CAT-5 cable to a PoE switch. On the front are various indicator lamps and two switches, one for hardware reset, and one for configuration. By pressing reset and configuration, then releasing reset while continuing to hold configuration, we restore the Function Generator's IP address to the default 10.0.0.37 and its listening port to 90. We can now connect to and configure the network interace on the function generator using the LWDAQ Configurator Tool with 10.0.0.37:90. We can set its IP address and port to suite our local area network, or we can leave it at 10.0.0.37:90. The two BNC sockets on the front side of the instrument provide access to the Channel One and Channel Two outputs. These are ±10 V range with 50 Ω in series. Once terminated by 50 Ω, their range drops to ±5 V.
The SCT_Check tool in our LWDAQ allows us instruct an A3050 to generate sine waves, square waves, and sinusoidal sweeps. The SCT_Check.tcl source code shows how to use the Long-Wire Function Generator (LWFG) package to control the A3050. The LWFG package is bundled with LWDAQ. Examination of the LWFG code will reveal how we configure the A3050 by writing to its control registers and waveform memory. The LWFG package uses routines in Driver.tcl, also bundled with LWDAQ, to open a socket to the A3050, write addresses and bytes, and close sockets.
[04-NOV-24] The Tcl interface for the Function Generator (A3050) is provided by the LWFG (Long-Wire Function Generator) package, which you will find in the LWDAQ package directory. Load the LWFG package into your LWDAQ process with "package require LWFG". The LWFG package provides routines to configure your function generator to produce sine, square, and triangle waves. The LWDAQ_configure routine takes six parameters.
LWFG_configure ip ch_num waveform frequency v_lo v_hi
Here, ip is the IP address of the function generator's TCPIP server. The LWFG assumes that the A3050 is listening on port 90. We have the channel number, 1 or 2 for the A3050C. The two voltages v_lo and v_hi are the voltages of the minimumm and maximum points in the waveform respectively. For the waveform we can specify "sine", "square", or "triangle". Use the Configurator Tool to set up the function generator's network interface. The SCT_Check tool in the LWDAQ Tools/More menu provides an example graphical user interface to the A3050 function genrator. We can enter sine, square, or triangle for the waveform type, but also "sweep", which will generate a sinusoidal sweep waveform. The tool has us specify peak-to-peak amplitude when terminated by 50 Ω.
[13-JUN-24] The A3050 is a TCPIP server that obtains both power and performs communication over a single RJ-45 socket. We plug the A3050 into a Power over Ethernet (PoE) switch. We use the Configurator Tool to set up the function generator's Network interface. We can resest the A3050's IP address to 10.0.0.37 by pressing the red reset button and the brown configure button at the same time, release the reset button and keep pressing the configure button for a few seconds.
Control Space Address (Hex) | Contents |
---|---|
00 | Hardware identifier |
12 | Hardware version |
13 | Software version |
18 | Data Address, Byte 3 |
19 | Data Address, Byte 2 |
1A | Data Address, Byte 1 |
1B | Data Address, Byte 0 |
3F | Data portal |
We communicate with the A3050 over TCPIP using the LWDAQ Messaging Protocol. These messages allow us to read and write from individual byte locations in control space, and to write blocks of data to locations in date space. The LWDAQ routines that provide LWDAQ messaging are contained in Driver.tcl. All LWDAQ commands are listed and described in the LWDAQ Command Reference. We write to a byte in control space with LWDAQ_byte_write. We read with LWDAQ_byte_read.
Writing to the data space is a two-step process. We first use LWDAQ_set_data_addr to write four bytes to the data address, which resides in the control space. We then use LWDAQ_stream_write to write a block of data to the data portal, which is a single byte in control space. The LWFG package does not use any byte read or write routines, but instead relies upon higher-level routines defined in Driver.tcl that make it easy for us to work in the A3050's data space. The code below, taken from package LWFG V1.4, demonstrates the use of these routines with the A3050.
# Open a socket to the function generator. set sock [LWDAQ_socket_open $ip] # Write the waveform values to the waveform memory. LWDAQ_set_data_addr $sock $LWFG(ch$ch_num\_ram) LWDAQ_stream_write $sock $LWFG(data_portal) [binary format c* $values] # Set the filter configuration register. LWDAQ_set_data_addr $sock $LWFG(ch$ch_num\_rc) LWDAQ_stream_write $sock $LWFG(data_portal) [binary format c [expr $filter]] # Set the attenuator configuration register. LWDAQ_set_data_addr $sock $LWFG(ch$ch_num\_att) LWDAQ_stream_write $sock $LWFG(data_portal) [binary format c [expr $attenuator]] # Set the clock divisor. LWDAQ_set_data_addr $sock $LWFG(ch$ch_num\_div) LWDAQ_stream_write $sock $LWFG(data_portal) [binary format I [expr $divisor - 1]] # Set the waveform length. LWDAQ_set_data_addr $sock $LWFG(ch$ch_num\_len) LWDAQ_stream_write $sock $LWFG(data_portal) [binary format S [expr $num_pts - 1]] # Wait for the controller to be done with configuration. set id [LWDAQ_hardware_id $sock]
The final call to LWDAQ_hardware_id is a way to wait for the A3050 to finish all the writes to the data space before we close the socket. If we close the socket too soon, the A3050 will abandon its work.
All of the registers necessary for controlling the function generator are located in the data space.
Data Address (Hex) | Contents |
---|---|
0000...1FFF | Waveform Memory, Channel 1 |
4000...5FFF | Waveform Memory, Channel 2 |
8000 | Divisor, Channel 1, Byte 3 |
8001 | Divisor, Channel 1, Byte 2 |
8002 | Divisor, Channel 1, Byte 1 |
8003 | Divisor, Channel 1, Byte 0 |
8004 | Waveform Length, Channel 1, Byte 1 |
8005 | Waveform Length, Channel 1, Byte 0 |
8006 | Filter Control Register, Channel 1 |
8007 | Attenuator Control Register, Channel 1 |
8010 | Divisor, Channel 1, Byte 3 |
8011 | Divisor, Channel 1, Byte 2 |
8012 | Divisor, Channel 1, Byte 1 |
8013 | Divisor, Channel 1, Byte 0 |
8014 | Waveform Length, Channel 1, Byte 1 |
8015 | Waveform Length, Channel 1, Byte 0 |
8016 | Filter Control Register, Channel 1 |
8017 | Attenuator Control Register, Channel 1 |
Time constants specified by various binary, hexadecimal, and decimal values written to a filter control register are given below.
Binary | Hex | Decimal | Resistance | Capacitance | Time Constant |
---|---|---|---|---|---|
00000001 | 01 | 01 | 51 Ω | 250 pF (parasitic) | 12.5 ns |
00010001 | 11 | 17 | 51 Ω | 1 nF | 51 ns |
00010010 | 12 | 18 | 110 Ω | 1 nF | 110 ns |
00010100 | 14 | 20 | 270 Ω | 1 nF | 270 ns |
00011000 | 18 | 24 | 560 Ω | 1 nF | 560 ns |
00100001 | 21 | 33 | 51 Ω | 22 nF | 1.12 μs |
00100010 | 22 | 34 | 110 Ω | 22 nF | 2.42 μs |
00100100 | 24 | 36 | 270 Ω | 22 nF | 5.94 μs |
00101000 | 28 | 40 | 560 Ω | 22 nF | 12.3 μs |
01000001 | 41 | 65 | 51 Ω | 500 nF | 25.5 μs |
01000010 | 42 | 66 | 110 Ω | 500 nF | 55 μs |
01000100 | 44 | 68 | 270 Ω | 500 nF | 135 μs |
01001000 | 48 | 72 | 560 Ω | 500 nF | 280 μs |
10000001 | 81 | 129 | 51 Ω | 20 μF | 1.02 ms |
10000010 | 82 | 130 | 110 Ω | 20 μF | 2.2 ms |
10000100 | 84 | 132 | 270 Ω | 20 μF | 5.4 ms |
10001000 | 88 | 136 | 560 Ω | 20 μF | 11.2 ms |
For more info on how LWDAQ messages are used to communicate with the control space, see LWDAQ Specification. For an example of using control space to create a data space through a data portal, see LWDAQ Driver Manual.
Parameter | Reset Value (Dec) |
---|---|
Sample Values | 128 (Output = 0V) |
Clock Divisor, Channel 1, Bytes 0-3 | All 0 |
Waveform Length, Channel 1, Bytes 0-1 | All 0 |
Filter Control Register | 1 |
Attenuation Control Register, both channels | 0 |
The waveform generated has a maximum amplitude of ±10 V when unterminated or ±5 V when terminated with 50 Ω
[04-NOV-24] As an example waveform, consider a 10-Vpp, 1.25-MHz sine wave. We can do this by writing "128, 152, 176, 198, 218, 234, 245, 253, 255, 253, 245, 234, 218, 198, 176, 152, 128, 103, 79, 57, 37, 21, 10, 2, 0, 2, 10, 21, 37, 57, 79, 103" to the waveform memory. We write 31 to the waveform length and 0 to the divisor. We now have a sample clock of 40 MHz ÷ 1 = 40 MHz, and we have 32 samples to step through, so we produce the entire waveform at 1.25 MHz.
The 1.25 MHz sine wave was fast enough that it didn't require a filter to smooth out. We now write 124 to the divisor register and our frequency drops to 10 kHz.
We can see each sample as a step in the sinusoid. We write "34" to the filter control register. The resulting waveform has about 1 dB less amplitude but looks smoother, as a result of the low-pass filter we deploy with our filter register.
The LWFG package picks the filter function automatically to suit the period of sinusoidal and triangle waves. It always disables the filter for square waves.
[21-NOV-24] All our designs are Open Source, protected by the GPL 3.0 license.
S3050C_1: Schematic for A3050C, Page 1.[04-NOV-24] The A3050 runs off an 80-MHz clock. We divide this clock by two, and then by a user-programmable signal divisor to generate the sample clock. We set the divisor by writing the divisor minus one to the thirty-two bit divisor register. We use the sample clock to increment the waveform memory address and so obtain the next sample value in our waveform. We connect the eight-bit memory output directly to an eight-bit resistor digital to analog converter (DAC). The DAC output varies from 0 V to 3.3 V, these being the logic power supplies. The A3050 circuit takes the DAC output and shifts it down by 1.65 V before amplifying until the range is slightly greater than ±10 V. After the final amplifier, we have a 50-Ω, 3 W resistor, which makes the A3050 outputs tolerant of continuous short-circuits.
On the way through the amplifiers, the signal passes through a resistor-capacitor low-pass filter network that we can configure with one of the A3050 registers. The LWFG package sets the RC filters automatically so as to smooth out the sharp edges of our eight-bit steps. The signal also passes through a resistor-resistor attenuator network that we can control with another A3050 register. The LWFG package implements a calibration of these attenuators and selects attenuators automatically so that we can use the largest origin signal before a final attenuation, by which means we reduce quantization noise in the output.
The signal itself will be made up of at least two samle values, and all these values will be written to the waveform memory during waveform configuration. The LWFG package always uses at least half of the 8-KByte memory available for each of the two A3050C channels. It does this by repeating the waveform as many times as necessary, and by allowing itself to repeat the waveform, combined with the clock divisor, we are able to generate frequencies with precision better than ±0.1%. After writing the waveform to memory, we specify the waveform length by writing the length minus one to the sixteen-bit waveform length register.
[21-NOV-24] To create the A3050C out of the A3050B, we load 270 Ω for the attenuator series resistors R86 and R91. We load divider resistors 100 Ω, 27 Ω, 10 Ω, and 3.3 Ω for both channels. We load 2.2 kΩ for R46 and R58 to increase the output amplitude.
[04-NOV-24] For a chronological account of the development and production of the A3050, see its Development page. That page provides an account of our work on discrete-component DC-DC converters, which we may deploy in later versions of the A3050, or in other Form C LWDAQ systems.