w6iwi.org | rtty | DSP TU2


This is a continuation of the DSP Terminal Unit project. The project is a digital signal processing based RTTY terminal unit. Part one covers initial experimentation using a Microchip development board. In this part, the project is moved to a custom printed circuit board. In addition, the firmware development will continue to support additional features.

Software Design

The software is a work in progress. The latest version is available here

Hardware Design

The schematic capture and board design were done with KiCad. This is my first project using this software, and I am very impressed! The KiCad files for the design are here. The preliminary Bill of Materials is here. The part list is also available as a Digikey List. The full set of Kicad files is here.

Schematic Review

The schematic is based on the original DSP TU project. The details of the new design are discussed here.

Power Supply - The system is powered by a 5 volt USB power supply (VBUS on J3). The 5 volts is passed through the front panel power switch (S8) to a 3.3 volt linear regulator (U6). The enable pin is driven by one section of U5, a 74HCT series inverter. U5 is powered by 5 volts, but since it is an HCT part, the inputs use TTL thresholds and can be driven by 3.3 volt logic. The USB-UART bridge (U3) has an active low open drain power enable output. This pin is pulled low once the USB interface has negotiated with the USB host to provide 500 mA. Once PWRENn goes low, U5 inverts the enable signal, making it active high, and enabling U6 to provide 3.3 volts to the remainder of the circuitry. If J3 is connected to a "USB charger" instead of a USB port, U3 should also enable power.

USB Client - U3 bridges the PIC32MZ UART number 1 to the USB port. Though the PIC32MZ has a USB port, use of an external USB to UART bridge simplifies boot loading code. The boot code will not need any USB client code. Instead, it will merely parse incoming Intel Hex code and program application flash. The system will enter boot mode, waiting for Intel hex code, if a couple front panel buttons are pressed during power up. If they are not detected as down, the application runs, and the USB port is available for use by the application.

AFSK Input - The AFSK input is the same as in the original DSP TU project. Balanced or unbalanced receive audio is passed through T1 to the PIC32MZ analog input number 2. R2, R3, and C8 bias the transformer secondary to half supply, the middle of the ADC range.

AFSK Output - The AFSK output is similar to that of the original DSP TU project. The PIC32MZ generates an 80 kHz PWM signal that is updated 8,000 times per second. The PWM is passed through a 4 kHz low pass filter formed by U2 and related components. U2 has a shutdown pin. When U2 is shutdown, its output is floated. During receive, U2 is shut down allowing the transmit and receive audio lines to be tied to a single "tristate" audio bus. The filtered audio is passed through T2 to drive the transmitter audio input or a tristate audio bus.

PTT - K2 drives the PTT output. K2 is wired to switch AC so its output is independent of polarity and is floating to allow for maximum flexibility when connecting to the transmitter.

Loop Key - As in the original DSP TU project, the 60 mA high voltage Teletype loop is keyed by a solid state relay, K1. It is protected from transient voltages (especially selector magnet flyback voltages) by CR1. K1 is wired in the "AC configuration" with the two FETs in series to make the loop independent of polarity.

Loop Sense - As in the original DSP TU project, high voltage 60 mA loop current is detected by an AC optocoupler, U4. The use of an AC opto-coupler allows the circuit to work with either loop polarity. R11 carries some of the 60 mA loop current leaving the LED current at 30 mA.

Display - As in the original DSP TU project, a small color graphic display is included. In normal operation, this is a "tuning scope." In addition, the display can be used in configuring the system through a text menu with the use of the quadrature encoder S7. The display is driven by a dedicated SPI port.

SPI Flash - U8 is an SPI driven flash memory chip to hold system configuration.

WiFi Module - U7 is an SPI driven WiFi module. It can provide Internet access to ITTY and other potential uses.

Front Panel Switches - Front panel backlit pushbutton switches are provided for various commonly used functions. Pressing a switch toggles the mode. For example, pressing the shift switch toggles between 170 Hz and 850 Hz shift with the current state being indicated by the LED.

PCB Bringup

This project has many firsts for me. These firsts include:

  • First DSP project
  • First MPLAB X project
  • First KiCAD project
  • First SMT project
Today, July 26, 2023, a prototype board was powered up for the first time. The video at the right shows the board receiving ITTY.

SMT soldering is a challenge, but I AM getting better. I'm using a YIHUA 959D hot air rework station with Essmetuim ZB628 solder paste. The air temperature was set to 300 C. The process works very well, though it was a challenge to solder down the 64 pin microcontroller. On the first try, the chip was tilted a bit so the pins on one side were between the pads instead of on them. I finally removed the chip, placed it again, and soldered it down. It is amazing that the chip still worked after being heated for so long. The soldering was viewed under a microscope to ensure there were no shorts. Any shorts were removed by wiping a hot soldering iron on the leads moving away from the chip body.

The only problem found with the board so far is the orientation of the display connector. The display board was supposed to plug onto the right angle header and then extend above and perpindicular to the board. However, the pins are reversed so that when plugged in, the display extends below the board instead of above. For now, the display is wired to the display connector using individual lead wires.

A fair amount of code remains to be done, especially dealing with the front panel switches, display, etc.

The video at the right shows the board receiving ITTY.

Construction Notes

I assembled the board using the YIHUA 959D hot air rework station with Essmetuim ZB628 solder paste. The air temperature was set to 300 C. I first mounted all the resistors capacitors, and the ferrite bead. These small surface mount parts were soldered using the smallest tip on the hot air gun. Then solder down the USB connector, J3, S8 (the power switch) and the FT232 chip, U3. At this point, it should be possible to plug the board into the USB port of a computer and see the USB Serial port on the Device Manager.

Install FT_PROG to program the EEPROM in the USB interface. In the DSP TU, CBUS3 is used to enable the 3.3 V regulator for the system. Using FT_PROG, program U3 as below:

Solder down U5 and U6. Ensure that +3.3 V is available on U6-5.

Now the fun part! Solder down the PIC32MZ, U1. I put a narrow stream of solder paste on all the pads. The chip was set in place, then shoved around a bit while looking at it under a microscope. Once the leads were centered on the pads, the chip was soldered using the large rectangular tip for the YIHUA 959D. This tip heats all four sides of the chip at the same time. On the first try, I had the leads between the pads on one side. I had to remove the chip and try again. Once the chip is soldered down, inspect the soldering under a microscope and ensure there are no shorts. A short between pins can be removed by sliding a hot soldering iron tip over the short wiping from the body of the chip outwards.

Install J2, the program/debug header. Note that a PIC Kit 3 only uses 6 pins. The last two pins (7 and 8) can be trimmed to allow the PIC Kit 3 to plug all the way on to J2.

At this point, it should be possible to plug the PIC Kit 3 onto J2, power the board up, and find the target processor using MPLAB X.

Solder down the rest of the components. Note that I used sockets on K1 and K2 since these are the most likely parts to fail. I have not yet soldered down U7, the WiFi module. That will be done later.

I intended to be able to put a female connector on the display board and plug it directly onto J1. The display would then stand above the board. However, on revision A of the board, the connections to J1 are reversed. The display comes with individual wires that can be plugged onto J1. Starting at pin 1 (the right end of J1), the wire colors should be red, black, blue, yellow, orange, green, white.

Preliminary Tests

Some preliminary tests were run by setting AudioOut to DISCRIM and watching the signal on the audio output, U2-1. Note that U2 is disabled unless the TU is in transmit, so it was put in transmit by pressing the TX button. The eye diagrams show minimal jitter in the zero crossing and full amplitude at the middle of the bit position. While full amplitude is not required for proper demodulation, the mark and space amplitudes are used to set the dynamic threshold control level, so full amplitude for each bit is desired.

The 170 Hz eye diagram was generated with this audio. The 850 Hz eye diagram was generated with this audio. Both use random data with each bit being 22 ms. The audio was generated using LTSPICE RandomAfskGenerator170.asc and RandomAfskGenerator850.asc.

The following filter settings are in UserConfig.c.

  const UserConfig_t UserConfigDefault={
    .NarrowShiftCenterFreq=2210.0,    // Center frequency for 170 Hz shift
    .WideShiftCenterFreq=2000.0,      // Center freq for 850 Hz shift
    .BaudRate=45.45,                  // Used to determine filter bandwidth and in software uart
    .ToneFilterBwBrMult=2.0,          // Tone filter bandwidth is the baud rate
                                      // times this number.
                                      // Make wide enough for minimal attenuation
                                      // of BR/2 sideband
    .AutostartShutdownSeconds=30.0,   // Keep motor running this may seconds after signal drop
    .KosDropSeconds=5.0,              // Drop transmitter 5 seconds after last character
    .AgcTargetLevel=0.5,              // AGC adjusts to this level
    .AgcLpfF=0.1,                   // Cutoff frequency of the LPF in the AGC gain control 

Eye diagram with 170 Hz shift

Eye diagram with 850 Hz shift


The DSP TU does not have any high voltage on the PCB. It provides a 5V logic output to drive an external autostart motor control relay. The relay box at the right was constructed by adding a solid state relay to a Home Depot 1007 546 208 four outlet "power block." The "power block" sells for less than $15. It includes four outlets, a circuit breaker, and a heavy duty line cord. It was a tight fit, but a TE SSRMP-240D10R solid state relay was stuffed into the box and screwed down with a couple 6-32 screws. The black wire with the heat shrink on it originally went to the center connection on the circuit breaker. It was moved to one of the SSR AC connections. The added red wire connects between the circuit breaker center connection and the other SSR AC connection. An incoming two conductor cable was connected to the DC control terminals on the SSR. When the DSP TU puts 5V on the autostart output (either by autorstart or hitting the motor button), the SSR runs the printer motor.

Tone Filter Bandwidth

25 November 2023

The menu system allows continuous adjustment of various parameters. In addition, the menu allows the audio output (PWM through LPF) to reflect various points in the DSP "circuit." The images at the right show the discriminator output (mark LPF - space LPF) with different tone filter bandwidths (multiples of the baud rate). The eye diagrams were generated with this audio. The audio uses random data with each bit being 22 ms long. The audio was generated with LTSPICE RandomAfskGenerator170.asc. An eye diagram is difficult to generate with real RRTY data, including from punched tape, since the stop bit is 31 ms long. This causes a transition between bit times in the eye diagram.

As discussed some previously, it is interesting to think of each tone of the FSK signal as being an on-off keyed signal. A 45.45 baud signal (22 ms per bit) consists of a square wave at 22.72 Hz and subharmonics of this frequency (when there are successive mark or space bits).

Each tone is 100% modulated with a square wave with a maximum frequency of 22.72 Hz. This places sidebands at the tone frequency ±22.7 Hz. If the tone filters pass these sidebands without attenuation, we would get a sine wave with an amplitude that is 1.274 times the amplitude of the square wave with the peak at the middle of the bit time (half way between the mark-space transition). A filter that passes these two sidebands would have a bandwidth equal to the baud rate since the square wave frequency is 1/2 the baud rate, and there are two sidebands: one above, and one below the tone frequency. However, the filter bandwidth is where the gain is 3 dB down from the maximum, so the tone is only modulated about 71% after going through a bandpass filter where the bandwidth is equal to the baud rate. As noted above, the fundamental frequency component is 1.274 times the amplitude of the final square wave, but 0.71 * 1.274 = 0.90454, so the sine wave does not reach the full amplitude of the square wave if the tone filter bandwidth is equal to the baud rate. A somewhat higher bandwidth is required.

What is the harm in not having the sine wave amplitude reach the full square wave amplitude? Since our random data includes square waves at BaudRate/2 PLUS its subharmonics (when there are successive mark or space bits instead of alternating mark and space), these subarmonics WILL reach the full square wave amplitude (or even 1.274 times that amplitude), while the peaks of alternate mark and space bits would not. Note in the first image, where the bandwidth is 70% of the baud rate, that some bits reach a fairly high amplitude while others do not. If there are , for example, successive mark bits followed by a space bit, the space bit has to start at full amplitude and does not have time to reach the full space amplitude. This introduces bias distortion, though it is variable bias distortion instead of a fixed shift of the mark-space threshold. Note also that the peak to peak amplitude of the signal is about 1.4 volts.

The second image shows the eye pattern with the tone filter bandwidth set to 100% of the baud rate. As discussed above, this results in 3 dB attenuation of the fundamental of the BaudRate/2 square wave. It can be seen that bits are not reaching the full amplitude. The peak to peak amplitude has increased to about 2 volts.

The third image shows the eye pattern with the tone filter bandwidth set to 150% of the baud rate. The sine wave peaks are still a little short of maximim amplitude. The peak to peak amplitude is about 2.8 volts.

The final eye pattern is with the tone filter bandwidth set to 170% of the baud rate. All the bit peaks appear to be reaching full amplitude. The peak to peak amplitude is still about 2.8 volts.

Filters for RTTY suggests use of third order filters with the tone filters being 1.2 times the baud rate. The DSP TU uses fourth order filters (two biquads), so attenuation outside the passband is a bit more than that of a third order filter. Wider filters will have output due to off-frequency signals, such as noise, so filters should be as narrow as possible. Based on these experiments, it appears we should use tone filters that are 170% of the baud rate.

Eye pattern with tone filter bandwidth = 70% of baud rate

Eye pattern with tone filter bandwidth = 100% of baud rate

Eye pattern with tone filter bandwidth = 150% of baud rate

Eye pattern with tone filter bandwidth = 170% of baud rate

Display and Menu Operation

30 November 2023
Video at right shows the operation of the display and menu system.

Wide Shift

2 December 2023

850 Hz shift was tried on the DSP TU. The center frequency is 2 kHz with mark 425 Hz below that, and space 425 Hz above. It was found that there is considerable amplitude skew with wide shift. The table below demonstrates the observed transmitter output power and TU output (on the primary of the output transformer) at various frequencies.

FrequencyTU Output
(Transformer Primary)
TU Output
(Transformer Secondary 680 ohm load)
Transmitter Output
(Shift, M/S)VoltsRMSdBVoltsRMSdBWattsdB
1 kHz 1.05 0960 mV0.0 105 0
1.575 kHz
850 Mark
1.05 V0.0900 mV-0.695-0.4
2.125 kHz
170 Mark
950 mV-0.9810 mV-1.565-2.1
2.295 kHz
170 Space
900 mV-1.3780 mV-1.860-2.4
2.425 kHz
850 Space
850 mV-1.8750 mV-2.150-3.2
3 kHz 720 mV-3.3630 mV-3.7

The first image at the right shows the transmit frequency response of the SEA245. As noted, each peak is 100 Hz from the next peak. The first peak is at 300 Hz and down about 6 dB from the mid-band level. On the right, a peak at 2.7 kHz is down about 1 dB. The peak at 2.8 kHz is down about 12 dB.

The second image at the right shows the predicted frequency response of the 4 kHz low pass filter on the DSP TU AFSK audio output. This filter smooths the 80 kHz PWM which has a sample rate of 8 kHz (the duty cycle is changed 8,000 times per second).

Based on these two graphs, there should be minimal attenuation of the 850 Hz shift space frequency (2.425 kHz), though the RF power drops 3.2 dB from the power with 1 kHz input. Further, the audio level out of the LPF also drops 1.8 dB.

Measurements of the SEA245 frequency response are shown here. The frequency response varies quite a bit with audio input level. At full power (0 dBm audio input), the power drops about 2.7 dB between 1.5 kHz and 2.5 kHz (a bit wider than 850 Hz shift centered at 2 kHz). That, along with the 1.5 dB level shift noted above on the transformer secondary between mark and space for 850 Hz shift yields about 4.2 dB change between mark and space TPO for 850 Hz shift. The table above shows a 2.8 dB difference between the 850 Hz mark and space TPO. In any case, it appears some high tone boost is required. Since the AFSK PWM is already going between 0% and 100% duty cycle, we cannot increase the high frequency tone level. Instead, we'll decrease the low frequency tone level.

SEA245 transmit frequency response from FCC test dataz. Horizontal divisions are 500 Hz. Peaks are every 100 Hz. Vertical scale is 10 dB per division.

Frequency response of 4 kHz LPF on DSP TU audio output.

To deal with the high frequency rolloff in the transceiver and the terminal unit, code for "high frequency boost" was added (see code where a MarkGain and a SpaceGain are set based on user input and whether wide or narrow shift is being used). By default, gains are set to 1.0 resulting in full scale output of the PWM generator (0% to 100% duty cycle). If the "HF Boost" is set to a positive number of dB, the high tone has a gain of 1.0, and the low tone has a lower gain resulting in the high tone being the specified number of dB above the high tone. Similarly, if the "HF Boost" is set to a negative dB value, the gain for the low tone is set to 1.0, and the gain of the high tone set to a lower value. The image at the right shows the Shift menu with the HF Boost can be adjusted.

Shift menu with HF Boost selected.

Command Interpreter

Systen configuration is done through a command interpreter driven by a virtual UART on the USB port. The UART is configured for 921.6 kbps, 8N1, with software (XON/XOFF) handshake. Typing a question mark results in help text being sent. Configuration can be saved to SPI flash memory. It is saved as a series of text commands using the same synatx as used through the USB virtual UART. When the system is powered up, the text in the flash memory is sent trough the command interpter, restoring the configuration of the system. The image at the right shows the results of the command "PrintSavedConfig".


For more details, see Adventures in Bootloading.

The video at the right shows the bootloader operation. When the leftmost button (Mark High) is held down when the DSP TU is powered up, the DSP TU enters the bootload mode. All the button LEDs are lit to indicate the unit is in bootload mode. The button can be released once all the LEDs are lit. A terminal program, sucn as Tera Term is used to send new firmware to the DSP TU. If using Windows, the COM port can be identified using the Device Manager. On my computer, the DSP TU, which uses the FT231XS USB/UART bridge, shows up as COM5. Configure the serial port for 921,600 bits per second, 8 data bits, no parity, 1 stop bit, and XON/XOFF handshake. The terminal should be configured for local echo and CR for both transmit and receive newline.

When all the button LEDs are lit, the DSP TU is waiting for an Intel hex file to load into the program flash. On Tera Term, use the File -> Send File, then select the Intel hex file with the application code. Upon receiving the first valid line of hex (the checksum indicates the line is valid), the program flash is erased. The program flash is not erased until the first valid line of Intel hex is received to ensure the program flash is not erased accidentally. (If the system accidentally gets into bootload mode (all LEDs lit), turn the power off and back on again. The program flash has not yet been erased.) As each valid line of hex containing program data is received, the program flash is programmed 32 bit word by 32 bit word as the hex lines are received. A typical line contains 16 bytes, so four 32 bit words are programmed for each line. Since it takes time to erase flash and to program each word, the DSP TU bootloader sends XOFF to the host computer after each line with a valid checksum is received. It sends XON when it has finished processing the line, which typically has programmed several flash words. The host computer then sends the next line of the hex file. As each line of the hex file is programmed into program flash, the binary code shown on the button LEDs is incremented from the initial -1 (all on). This results in the LEDs flickering indicating that the hex file is being programmed into flash. If there is an overrun error (typically caused by XOn/XOFF handshake not being selected) or a bad checksum, an error message is sent to the terminal.

Sample Rate Adjust


The DSP TU is using the internal Fast RC clock. This drives timer 2 which is set to reset at 80 kHz based on Period Register 2. The timer 2 interrupt then drives a counter that causes the DSP functions to run at 8 kHz. It was discovered that the tones out of the DSP TU were 0.7% high. This indicates that the sample rate was also 0.7% high. While there is a tuning register on the FRC clock, it's easier to slightly modify the PR2 register to adjust the 80 kHz PWM and 8 kHz sample rate. A command was added to the command interpeter. This command is also used on power up when the saved configuration is run through the command interpreter. An adjustment was added to the display Debug menu. Both of these adjustments are limited to ±5%.

Power Line Noise Measurement


Added code to measure power line noise in received audio. Details here.

Added WiFi


w6iwi.org | rtty | DSP TU2