Thursday, December 15, 2005

New Job

New Job:

I start a new position with the Ohio State University Department of Astronomy in the Imaging Sciences Laboratory on Monday December the 19th. This marks the end of my 5 year stint as a factory automation consultant. I learned a lot in those five years, but I am glad to be moving to something new, interesting, and challenging.

Before going out on my own as a consultant, I worked as an Electrical Engineer with a Department of Defense contractor in the 1980s and early 90s. The company was Piqua Engineering, Inc. - I worked there for 10 years. After PEI a few former employees and I started a company called Technitron Labs, Inc. TL's main product was specialized instrumentation for paper mills, municipal waste and drinking water treatment plants, and industrial water treatment plants. TL was sold after a few years (along with my designs); I moved on to doing Controls Engineering at a company called Zed Industries, Inc. Zed made packaging machinery and thermo-formers. I spent 6 years at Zed bringing their equipment control systems up to modern standards before moving on to a purely software engineering job.

Finally, in 2001 I started vHMI Automation, Inc. The main product when I first started was a Visual Basic based Human Machine Interface (HMI) package that I wrote and various C++ based Programmable Logic Controller communication drivers. I expanded into both hardware and software system consulting in factory automation and control systems. I also did instrumentation, automated test system, and microcontroller based system design. Because I was an independent consultant, it enabled me to live outside of the USA for a while (where I learned a lot about how other countries view the US - which is not as bad as you hear from the news). I also realized how much we take for granted the life we have in the USA. I returned to the US in June of 2004.

I am very happy about leaving the stressful and uncertain side of consulting behind. I am looking forward to working in OSU's Astronomy Department where they design and build extremely interesting instruments for ground-based optical and infrared astronomy.

Friday, December 09, 2005

Update... HPSDR

HPSDR Progress:
I am now able to configure the Spartan 3 FPGA over USB. I switched from slave parallel mode to slave serial configuration loading. This will make the FX2 firmware easy to use with Altera Cyclone FPGAs in addition the the Xilinx Spartan 3.

I am in the process of getting samples of Linear Technology's LTC2208 16 bit, 135 MSPS ADC. I still plan to develop a QSD based RX board using the TI PCM4202 as the ADC - So there will be a high bandwidth path as well as a low bandwidth path in the HPSDR. The LTC2208 board will probably get it's own FPGA to do DDC. The DDC's ouput will then feed the Spartan 3 which will be responsible for performing the second part of the DSP chain.

Verilog Projects for the Xylo Board:
I set up a folder on my server that people can browse . It will contain various verilog projects that can be tried on the Xylo board for educational purposes.

Wednesday, November 16, 2005

Microscope for SMT

Here are a few pictures of an early Birthday present from my wife:

The 10x magnification makes it perfect for soldering and inspecting smt. I was able to hand solder the 208 pin 0.5mm pitch Xilinx Spartan 3 FPGA used on my HPSDR board in under 5 minutes which included inspecting each pin. If you do any serious smt work at all, you may want to consider purchasing a similar microscope. I was amazed at the difference it made in speed and comfort while working with fine pitch parts. (Price is about $214 + shipping).

Monday, November 14, 2005

Some notes on soft real-time under Linux 2,6...

Linux 2.6 Kernel:

With the 2.6 kernel, a large step was taken to improve Linux's real-time capabilities. The improvements are a result of two major changes in the kernel (as well as many minor changes):

1. Kernel preemption. Before 2.6 the scheduler was able to preempt threads running in user mode, but when the thread made a system call that caused a context switch to kernel mode there was no way for the thread to be preempted. This situation could cause a high-priority thread that was ready to run to be blocked by a lower priority thread inside a system call. With 2.6, the kernel can now be preempted.

2. Constant time scheduler. Prior to version 2.6, the time that it took for the scheduler to decide which thread to run depended on how many threads that were currently running on the system. The more threads on the system, the more time it took the scheduler to make a decision. In version 2.6, the scheduler makes the decision in the same amount of time whether there are 1 thread or 100 threads on the system. This makes the system more predictable.

Scheduling Priorities:

Most processes are started with the default scheduler: SCHED_NORMAL. There are two other schedulers that can be used for real time threads:

1. SCHED_FIFO. This is a first-in first-out scheduler. The highest priority SCHED_FIFO thread ready to run will be scheduled. Once the thread starts running it will only be preempted if a higher priority real time thread becomes runnable or if the thread yields the processor.

2. SCHED_RR. This is a round-robbin scheduler. Unlike SCHED_FIFO, the SCHED_RR scheduler does not allow a thread to run indefinitely unless it is preempted by a higher priority thread. If there are multiple threads of the same priority and they are runnable, the scheduler will alow each thread to run for a specific time before it is preempted (quantum).

To start a process with one of the real time schedulers you have to use the system call sched_setscheduler(pid_t pid, int policy, const struct sched_param *p). Once a thread is running under a real time scheduler you can adjust its priority with a call to sched_setparam().

Linux 2.6 Kernel Timers:

nanosleep(): In Linux 2.6 the kernel only checks on timers once every "jiffie" which defaults to 1ms (it was 10ms before 2.6). Even though you can specify times with nanosecond resolution in the call to nanosleep() don't expect that kind of time resolution. nanosleep() is good for a minimum of 2ms - meaning the timer will finish within 2ms of the programmed interval.

If more accurate timing is needed, /dev/rtc can be used. If you do a read() of /dev/rtc it will block until the rtc timer tick is hit. You can program the rtc's tick rate from 2 Hz to 8192 Hz.

Locking memory:

To keep the memory allocated for a process from being swapped out to disk, you can lock all or part of its memory in RAM using the mlock() call. You can unlock the memory by calling munlock(). If you want to lock the entire memory of a process, a call to mlockall(int flags) will lock the entire address space of a process into RAM. The flags are MCL_CURRENT and MCL_FUTURE. MCL_CURRENT will lock the current memory allocated to the process into RAM. MCL_FUTURE will lock any future allocation of memory by the process into physical RAM. You will usually want to or MCL_CURRENT and MCL_FUTURE together.

Tuesday, November 08, 2005

Schematic and PCB software update

Recently I came across the open source Kicad project. I had evaluated DipTrace which is inexpensive but it is not open source. I then worked with the open source gEDA tools which were ok.

Kicad looks very promising:

It is cross platform and uses wxWindows. It is much more polished than the gEDA tools. The file formats are all well documented which make adding symbols very easy using a python script. Kicad's source code build process stinks but fortunately there are binaries available. When I get a chance I will look into creating a Visual Studio project for Kicad so it can be built more easily on Windows.

Friday, October 28, 2005

Modified QSD Circuit

R1 represents the signal source impedance, in this case 200 ohms. If R2 is 4 x 200 ohms = 800 ohms the conversion loss is the same as a single switch with signal integrating capacitor driven by a 25% duty cycle clock. If the clock's duty cycle is increased to 50% the circuit shows some conversion gain. One side of the switch is now effectively grounded (virtual gound of the opamp). The next thing would be to investigate increasing the source impedance that each switch sees.

Below is a two switch model with LT1115 op amps:

Wednesday, October 26, 2005

QSD Simulation

Below is a plot of a model of a two switch QSD circuit. It shows voltage gain in dB vs switch on time. The input frequency is 10.005 MHz. The sampling clock period is 100 nS (10.000 MHz).

Below is a plot of a model of a four switch QSD circuit. It also shows voltage gain in dB vs switch on time. The input frequency is 10.005 MHz. The sampling clock period is 100 nS (10.000 MHz).

The model that I used can be downloaded here. You will need Linear Technology's SWCAD program to run it.

An Excel spreadsheet containing the above data can be downloaded here.

The interesting part about the above data is that the QSD seems to have the most gain when the sampling clock on time is about 20 - 25% of its period. This seems to be true in all the different models (ideal and real switches) and configurations (balanced, sinngle ended) that I have tried. Phil Harmon, VK6APH, I believe has also found this to be true in his modeling. So a 50% duty cycle clock does not seem to be beneficial.

Thursday, October 20, 2005

SharpDSP Mini Console running on Linux

Click on the picture to see a full size version

Wednesday, October 19, 2005

SharpDSP Mini Console with Analog Meter

I have added an analog meter to the SharpDSP Mini Console. I borrowed the image from meterpanel. The scale on the meter is not calibrated. You can substitute your own meter face image in place of the default image. Here are the details of the meter face image:

Size: 220 x 220 pixels
Type: png, gif, jpeg, bmp, tiff
Origin of the image is 0,0 at top - left hand corner of the image

The image file should be placed in the SharpDSPMiniConsole folder.

Here is the important part of the softrock.config.xml file relating to the meter:

  • AnalogMeterImageName is the file name of the meter face image.
  • AnalogMeterCorrection is the correction factor in dBm to apply to the analog meter reading. It defines the zero point - here it is set for -130 dBm.
  • AnalogMeterNeedleLength defines the length in pixels of the needle
  • AnalogMeterMinAngle defines the angle of the end of the needle pointer in relation to vertical (defined as needle pointing straight up - zero degrees) when the meter is at it's minimum scale reading.
  • AnalogMeterMaxAngle defines the angle of the end of the needle pointer in relation to vertical (defined as needle pointing straight up - zero degrees) when the meter is at it's maximum scale reading.
  • AnalogNeedleOrigin defines the x and y coordinates (in pixels) of the meter needle origin.
  • AnalogMeterNeedleColor defines the color of the needle in Argb units.
  • AnalogMeterNeedleWidth defines the width in pixels of the needle.
To create your own meter face you need to keep the image size to 220 x 220 pixels. You will need to note where the needle origin is on your image in pixel units with 0,0 being located at the top - left hand side of the image. You will also have to set the minimum and maximum angles for the needle to define the zero and full scale positions in your image.

The default vu meter face that comes with the SharpDSP Mini Console is not calibrated.

Wednesday, October 12, 2005

Some notes on the SharpDSP Mini Console...

SharpDSP Mini Console for the SoftRock:

It is available on my website at

Center Frequency Calibration Procedure:

The SharpDSP Mini Console allows you to set any desired center frequency. For the standard SoftRock 40 the center frequency is 7.056 Mhz. To get an accurate frequency display you will need to calibrate this setting. Here is how I did it:

I set my HP8640B signal generator to 7040 kHz. I moved the low filter slider to -2000 Hz and the high filter slider to +2000 Hz. I then selected SSB/DSB/CW from the Mode menu. I then moved the frequency tuning slider until I got zero beat on the 7040 kHz signal. This occurred around 7046 kHz on my SoftRock 40. I then clicked on the Setup->Center Freq menu. The text box showed that the software was set for a center frequency of 7056 kHz (7056000). Using the fine tuning slider I adjusted the displayed frequency (at the bottom of the screen above the frequency tuning slider) until it read 7040000 - exactly what the HP8640B was set to. When you move the fine tuning adjustment slider you will also see that it is changing the displayed center frequency in the text box above it by the amount corrected to get the display to show 7040 kHz. I then clicked on the Done button to accept the new center frequency. The calibration is done.

Here is what that screen looks like. You can see my new calibrated center frequency setting.

IQ Balance procedure (Image Rejection):

To calibrate the image rejection setting I left the HP8640B set to 7040 kHz. I then tuned up with the frequency slider until I could hear the image. This occurs at 7072 kHz if your center frequency is 7056 kHz (7056 - 7040 = 16, so 7056 + 16 = 7072). I then clicked on the Levels->Correction menu. I adjusted first the IQ Gain Correction slider for a decrease in the image signal. I then adjusted the IQ Phase Correction slider for a decrease. I went back and forth between the two sliders until I nulled the signal as low as possible. I then clicked Done to exit this screen:

Meter Level Calibration Procedure:

To set the meter level I adjusted the HP8640B to -70 dbm on 7040 kHz. I then clicked on the Levels->Correction menu again. You will see that the s-meter is still visible on this form. This is to aide in calibration. To adjust the s-meter to read -70 dbm I just moved the Signal Level Correction slider until the s-meter read -70 dbm. I then clicked Done.

Hint: You can move the sliders in very small steps by making sure the slider has the focus and then using the left and right arrows on the keyboard. You can also move in slightly larger steps by left clicking to the right or left of the slider.

Thursday, October 06, 2005

Additional info on the HPSDR project...

Hi all,

This is a response to a few questions that someone posted on my blog
page requesting more info about the project. I have copied it here
since it kind of gives a quick outline of where I am going:

I saw your comment on my blog page. Thanks for the link.

I am using libusb-win32 which is a port of the open source libusb
project for Linux. My intention is to use the libusb API since it is
the same on Windows as it is on Linux. On Windows is consists of a
device driver and a interface DLL. They have an inf file generator
that will create an .inf file for your device. I am having very good
luck with libusb.

I have written a C#.NET library to interface to the libusb-win32 DLL.
It works under the Mono framework in both Windows (using the
libusb-win32 driver and DLL) and Linux (using the libusb shared
library). It is pretty cool to be able to write software and have it
work without recompiling on both Win and Linux platforms.

For the compiler I want to use the open source SDCC compiler. It
assumes a standard 8051 type device so it does not directly support
the additional features of the FX2. Basically I have to create custom
interrupt vector and usb descriptor tables in assembly modules and
link them with the main c firmware. Luckily the SDCC linker allows
you to define where in memory particular user defined segments are
based so it turned out to be relatively easy one I pieced together all
the bits of information from various sources on the internet.

The only problem that I am having now is that I cannot get the
SUDPTR's (that you use to send the usb configuration descriptors) to
work. I load them with the correct address but invalid data is
returned. I think that there is a problem with the xdata
initialization in SDCC's startup code because it assumes a standard
8051. I am working on a replacement .startup8051.asm for the FX2 to
correct the deficiencies. The device will not re-enumerate correctly
because of the SUDPTR problem. [Edit: As of 10-05-2005 this problem
has been resolved and the board re-enumerates correctly - N8VB]

Once I get the re-enumeration fixed, I need to complete the firmware
to support uploading the FPGA's configuration data.

I apologize for not responding to your earlier comment on my blog
about having a block diagram for the FPGA_USB board. I just saw your
message today - I guess I missed it. I've been busy in every spare
moment writing support code and firmware for the FPGA_USB board that I
have not released much info on it. Basically the FPGA_USB board is a
high speed I/O system. It has an I2C bus, an SPI bus, and about 64
lines of bit addressable I/O. It has six 40 pin header receptacles on
the board to allow interfacing. The I2C and SPI buses are common to
five of the six headers. The remaining pins on the first five headers
also contain power and GP I/O lines that can be configured either for
CS or ENs for the SPI bus or as general purpose bit addressable I/O.
The first and third headers also have individual I2S sound buses to
allow connection to the audio A/Ds and D/As. If the I2S buses are not
needed those lines can be reconfigured as GP I/O by the FPGA. The
sixth header contains all bit addressable GP I/O that is not common to
the first five headers. The plug in boards will make the project a
SDR, test instrument, etc... For SDR use I plan on having a RX board
(with PCM4202 A/D) in the first slot, a DDS board in the second slot,
a TX board (with A/D - D/A) in the third slot, a BPF board in the
fourth slot, and general purpose I/O interface board in the fifth
slot. I want to use a mini-itx board running Linux that will
interface via USB to the FPGA_USB board and allow you to make a stand
alone radio. The GP I/O will be used for interface to the front panel
encoder knobs, switches, indicators, etc... It will also support
running in PC connected mode like the SDR-1000 with or without the
mini-itx board. I would like to offload some of the DSP to the FPGA
also (like the I/Q correction and NCO for starters). I am very
interested in some of the open cores for the FPGAs that implement your
own custom DSP processor. It would be interesting to see if all the
DSP could be done in the FPGA or in maybe a add on FGPA based
co-processor board.

If I ever get all the above done I would then like to make a high
speed 16 bit A/D board that would replace the TX board and allow you
to scan a large swath of spectrum. Then the narrow bandwidth RX board
(using the QSD and audio A/D) would tune into interesting signals. I
have a sample of a 16 bit 80MSPS A/D from Analog Devices that I will
use. The same board could also be the basis for a high speed DSO or
logic analyzer project.

The inspiration for the FPGA_USB board was to have an expandable high
speed I/O platform to build other projects on. In addition to the FX2
and Spartan 3 FPGA there is a 128 K static ram for the FX2, a 64 K
EEPROM, a Cypress I2C programmable clock generator chip with 6 clock
outputs, and regulators (3.3V, 2.5V, and 1.2V). The board requires 5V
for the logic and +/- 12 VDC for supporting the add on boards. The
+/- 12 V supplies are routed directly to the six headers.

Anyway, it is all a lot of fun!

73 de Phil N8VB

Friday, September 23, 2005


Here is the soldering station that I use (older Weller EC2001):

And the tip:

A Hakko 936 is the backup:

(thanks to Ken N9VV for the link)

Boards and design files:

I do plan on offering boards from bare to fully assembled for this project. All of the design files will be available for those who wish to make their own boards. This is both a open hardware and software project. It will support both Windows 2k/XP and Linux.

Some Test Code for the FX2 using SDCC:

Wednesday, September 21, 2005

It Runs...

I was able to download the initial firmware into the FX2 microcontroller on the FPGA_USB board today and run a test program. I then recompiled the program with the open source SDCC and got it to run (the initial code was compiled with the Keil evaluation package from Cypress' site). After testing the FX2 a little further I will solder the FPGA onto the board and start developing the code for it. So far there have been no major problems...

Tuesday, September 20, 2005


Here is a picture of the FPGA_USB board after soldering most of the components:

Yet to be soldered is the FPGA, USB connector, and connection headers.

I soldered all of the components by hand. Soldering the 128 pin 0.5mm pitch Cypress FX2 microcontroller was much easier than I thought it would be. I need a little more magnification than the Bausch and Lomb 3.5x eye loupe has. I also have a Luxo magnifying fluorescent light that I use when soldering the other components. I am thinking about getting a 7x Bausch and Lomb loupe that clips onto glasses for soldering the 0.5mm pitch stuff. There is a seller on Ebay that sells stereo microscopes on a boom arm for about $260 that would be nice.

Basically I spread a lot of flux on the pads for the FX2 chip, tacked down the pins in the corners to keep the chip in place, and then proceeded to solder the pins using a drag technique with a conical tip on the Weller EC2001 soldering station. I then inspected each pin by lightly pushing sideways with a fine pointed tool to check for any pins that where not soldered down. I found 4 out of 128 and a light touch up with the soldering iron fixed those.

The other components were a piece of cake using the magnified swing-arm fluorescent light. I used 0.015" SN63PB37 Kester solder, SP-44 Kester Paste Flux, and a Weller ETU 0.01" x 0.4mm flat tip on the soldering station.

Next I will solder on the USB connector, apply power, connect to the PC, and see if the FX2 enumerates.

Wednesday, September 14, 2005

The HPSDR FPGA_USB Boards Have Arrived


The HPSDR FPGA_USB boards showed up today. I sent the design files off last week to PCBExpress and UPS delivered them today. They are 4 layer boards with silk screen and solder mask.

You can see some pics here:

Next I get to have fun soldering the 0.5mm pitch ICs...

Last time I reported that there was a long back order for the XILINX FPGA. Instead of 3-4 weeks as quoted I received my order in about 2 weeks. So I do have all of the components in hand.

I have had many emails from people asking me for more details on the FPGA_USB board. I plan to put up much more information on my website soon. Right now I need to concentrate on getting the prototype boards build up and debugged.

Real time Linux:

I decided to build a Linux From Scratch (LFS6.1) distro to patch with the latest from RTAI which is fusion-0.9. RTAI Fusion uses the ADEOS nanokernel. I got it done just before the boards arrived. It was a great learning experience. For LFS6.1 you basically use a host linux system (or the LFS Live CD) to build your system from source. You control exactly what software is installed and where. Next I customized it by adding Direct Framebuffer support
and Mono 1.1.9. This will be the stand-alone DSP processor running on a mini-itx motherboard which will boot from a flash drive. It will run a new version of SharpDSP under the Mono JIT written in, of course, C#.


I received a couple of samples of the Analog Devices AD9958 this week. It will be interesting to test them versus the AD9951/54 parts.

Stay tuned...

Wednesday, August 31, 2005

Short Update


I now have almost 100% of the parts for the board and have verified my PCB layout with the QFP208 pattern used by the Xilinx XC3S400 FPGA. I will immediately send the board design files out to be made. It is a 4 layer board measuring 5"x6" with top side silk screen and top/bottom solder mask. All components are on the top side. The most difficult SMT components are the FPGA (QFP208, 0.5mm pitch) and the Cypress FX2 chip (QFP128, 0.5mm pitch). Resistors are all 0805 size and caps are 0805 and 1210 sizes.

The only part that I do not have is the Xilinx XC3S400 FPGA. It is on backorder for 3-4 weeks (or so they claim). It seems that there are just no Spartan 3 chips available right now. What is the problem Xilinx???


I have been doing a little work with using mono on Windows and Linux. I was able to compile SharpDSP using SharpDevelop targeting the mono runtime and mcs compiler. I compiled SharpDSP into a library (dll) then copied it over to the Linux machine. I compiled a test C# program that uses the Managed.Windows.Forms in mono to test the SharpDSP library. Both the test program and the dll worked perfectly under both Windows and Linux *without* having to recompile either file that was compiled under SharpDevelop on Windows. This means that I should be able to create a dedicated SoftRock 40 console that will run on both Windows and Linux using SharpDevelop for development (or alternately, MonoDevelop under Linux). The Windows version will continue to use PortAudio. The Linux version will use Jack.

Thursday, August 25, 2005

FPGA_USB Board, DipTrace, and Mono

FPGA_USB Board and DipTrace:

I have been using a program called DipTrace to do the schematics and board layout for the FPGA_USB board. After completing my first PCB layout with DipTrace I am very impressed with this program. Questions to the developers are answered very quickly. It has a very intuitive user interface and small learning curve. I had to create a few patterns for smt components that were not in the supplied libraries - the pattern editor is very easy to use. I highly recommend this software if you are looking for a powerful, yet low cost schematic entry/PCB design program. You can download a 30 day evaluation at

The FPGA_USB board design is now complete. I have ordered the parts for the prototype boards and will soon send the design files to the board house to have the PCBs made. I will post more details about the project soon.


I have been doing a little work with Mono ( on both Windows and Linux. It is very impressive to be able to write a C# program with a GTK# GUI and have it run in Windows and Linux without having to recompile. I am considering recompiling SharpDSP to use Mono and then evaluating the performance of SharpDSP running in Linux. I am using Mono with Suse 9.3

Monday, August 08, 2005

Just an update


There is a new build of SharpDevelop available at:

Not a lot of changes - just bugfixes...


Check out this new low cost Schematic Editor/PCB Layout program at:

I have tried Eagle, PCBExpress, and others... DipTrace has then all beat in ease of use. You can dowload a fully functional 30 day trial from the website. Or there is a freeware version also. The developers are very responsive to suggestions for features/improvements. I highly recommend this software.


I received the SoftRock40 with PCM2900 CODEC from Tony Parks this weekend. I will start on modifying the SharpDSP enabled console to make a specific release for the SoftRock40. I will also correct the sample offset bug in the PCM2900 CODEC.


I am in the process of laying out the PCB. I am using DipTrace for the Schematic entry and PCB layout. This will become a open source hardware/firmware SDR project. Stay tuned to my website for more info...

Wednesday, July 27, 2005

SDR mini-itx project update

Here is an update on my mini-itx/SDR project:

I have been working out the details of the A/D – D/A board. I have decided to use the TI PCM4202 (24 bit, 192 kHz, stereo) for the RX A/D. For the TX A/D and RX/TX D/A I am going to use the TI TLV320AIC23B CODEC (24 bits, 8-98 kHz, stereo, with integrated mic amp and headphone driver). The PCM4204 will be dedicated to RX only. The TLV320AIC23B will handle the microphone input for TX as well as the IQ output for TX and the audio output for RX (in the stand alone configuration).

Both chips have digital audio interfaces (I2S, left, right justified, etc…) so I have the problem of getting that data into the PC via USB2.0. I looked at the Cypress EZ-USB FX2 CY7C68013 microcontroller for this but it cannot handle the transfer on its own. I decided to use a Xilinx FPGA in addition to the EZ USB FX2 for the I2S to parallel conversion (inspired by the USRP and SSRP projects of GnuRadio). The EZ USB FX2 will operate in slave FIFO mode to get the data/to from USB2.0. It seems a shame to waste all the I/O available with the FPGA so there will be general purpose parallel I/O, I2C, and SPI bus capability for future expansion*. In addition, since I already have the SPI/Microwire bus, I want to provide the ability to interface two AD9954 DDS chips to the FPGA. The AD9954 has a few dedicated I/O pins for synchronization between multiple chips as well as built in comparators that make it easy to generate a quadrature IQ clock up to 160 Mhz. The AD9954 has a 14 bit D/A so there should be less spurs.

The interface to the PCM4202 requires the digital audio interface lines (LRCK, BCK, DATA) and 3 sample rate select lines. The TLV320AIC23B requires the digital audio interface lines (LRCK, BCK, DIN, DOUT) and 3 wire SPI lines (for control) + /CS. The AD9954 requires 3 wire SPI lines for control and a /CS line. The SPI bus lines will be shared between the TLV320AIC23B and the two AD9954 DDS chips requiring 3 /CS lines, one for each chip.

Part of the parallel I/O will interface to the parallel connector on the SDR-1000 and the rest will be available for user defined I/O.

I will post more on my website as I make progress. Any input, suggestions, and criticisms are welcome.


*future expansion = high speed ( >=50MSPS) 14 bit A/D

Friday, July 22, 2005

Are you a computer simulation?

Someone emailed me about my webpage at: to ask if I really believed we are living in a computer simulation. He was referring to the paper by Bostrom titled "Are You Living In A Computer Simulation? ". No, I do not believe we are living in a computer simulation. It is an interesting paper though.

I think that Ed Fredkin's Digital Philosophy ( is probably closer to what underlies reality.

Tuesday, July 19, 2005

SoftRock 40 & Reorganized website

SoftRock 40

I got Tony Park's SoftRock 40 playing today with Bill KD5TFD's modified PowerSDR console. It is amazing what can be done with such a small board. I want to revive the SharpDSP enabled console for use with the SoftRock 40. I will strip out all of the unneeded controls and functionality in the PowerSDR console to make it specific to the SoftRock 40. This will clear up some screen real estate so I can widen the Panadapter window to show all 48 or 96 kHz of bandwidth at once in the Panadapter.

When the PCM2900 codec boards become available I will modify SDRAudio to correct for the sample offset problem in the PCM2900.


I reorganized my website today. The website notes were archived and links to the various software projects were rearranged to make it easier to find a specific item.

Monday, July 18, 2005

New SDR Project

A few people have mentioned in the past about
wanting to use a small motherboard like mini-itx or micro-atx to run
PowerSDR with the SDR-1000 to make a small self-contained unit
possibly using a small LCD panel display. That was one of the things
on my project list that I wanted to do also. Now that I have started
thinking about it again I decided to try a variant of this idea and
have had encouraging success so far just playing around with it.

I wanted to try to dedicate a mini-itx board to the DSP, CW keyer, and
hardware control of the SDR-1000 using real-time Linux (RTAI I am trying to see how feasible it is to run
the DSP (based on the DttSP code) and hardware control code in hard
real time under RTAI. The RTAI patched linux kernel with DSP and
hardware control code loads from a compact flash card to make it a
diskless system (I have it down to under 16 MB now). I'd also like to
come up with a A/D D/A add on board that will use a chip like the
Wolfson WM8786 24 bit, 192 khz stereo A/D or TI PCM4204 A/D and a
suitable 16 bit D/A instead of using a sound card. There recently has
been a new project released on SourceForge that adds real time USB
support to RTAI (USB4RT) that I am playing with now.

I would then like to use the 100baseT Ethernet on the itx board to
communicate with PowerSDR (minus portaudio, hardware control, DSP
code) so it handles the GUI only. Basically the itx board becomes the
"DSP processor" and the GUI is handled remotely on your home PC.
There are plenty of options for the hardware interfacing since the itx
board has parallel, serial, and USB ports (and I2C) and these ports
can be used in hard real time mode. This also would give the
possibility of running the SDR without the GUI by adding a front panel
with real knobs, switches, leds, etc… if so desired, to make a stand
alone unit without having to have a computer attached for GUI.

I am hoping this approach will eliminate the problems of trying to do
something that is inherently real-time on non-real time operating
systems like Windows and standard Linux. This should eliminate the
burps, braaaps, and buzzes in the DSP as well as give extremely low
latency to hardware interrupt I/O.

I will report on my progress periodically. With the current
improvements in 1.4.1 as well as the improvements to come, there may
be little need for this kind of dedicated hardware but I still would
like to have a stand alone unit that does not have to be connected to
the PC. I am also interested in any comments, suggestions, or
criticisms of this idea.

Sunday, July 17, 2005

vCOM on BerliOS Developer

The vCOM driver project is now hosted at:

Saturday, July 16, 2005

Update on Screen Capture Software

It turns out Microsoft offers a free download called Windows Media Encoder that will do screen recording. I have tried it and so far it looks good. It is not as jerky as CamStudio and creates smaller file sizes.

Monday, July 11, 2005

Screen Capture Software

I have been trying out various screen capture software that I hope can be used for software demonstations and tutorials. The first I looked at is Camtasia ( It is nice for creating software tutorials. Next I looked at Macromedia's Captivate ( It has a lot of avantages and I think I prefer it over Camtasia. Unfortunately it costs about twice what Camtasia costs, but I think it is worth it. I will post a test demo using Captivate to see how it plays with users. It saves files in Shockwave format.

I will probably do the software tutorials inside a VMWare Workstation 5 instance. My screen resolution is 1280x1040 so I need to do the demos within a smaller screen area... probably 1024x768 since this is the smallest common size on laptops as well as most desktops. I can also undo changes easily using VMWare's snapshot and cloning features. VMWare Workstation 5 also has a movie recorder mode where you can capture whatever is going on and save it as an AVI file. Unfortunately, I don't see any option to record audio narration in sync with whatever is happening on the screen. If it worked this way I would probably use it to create the software tutorials.

Saturday, July 09, 2005

vCOM Build 226 released

Build 226 of the vCOM virtual serial port driver is released.

As I said in an earlier note, I had two reports from two different users that the vCOM driver would cause intermittent system freezes. One one system it happened only a few times and on the other system it happened very often. The system that had frequent system hangs was a hyper-threaded box. There can be only a few causes of system freezes and deadlock is the most likely in multiprocessor and hyperthread systems. I had a race condition caused by excessive use of spinlocks resulting in a deadlock. The probablity of the deaklock happening is much higher in a multiprocessor/hyperthreaded system. This is corrected in build 226.

Important: You will need to edit the N8VBvCOM.inf file to match your current inf file before updating the driver. Once you have the inf edited you can run the update.bat file to update the driver.

Thursday, July 07, 2005

vCOM Build 224 released

Build 224 of the vCOM virtual serial port driver is released.

There were two reports by two different people that vCOM build 222 would hand their system. Not BSOD, but just freeze. I have adjusted the thread priorities in build 224 out of the real-time range where they were set in build 222. I think that perodically the threads priority would be boosted above the GUI's thread priority causing a deadlock.

Important: You will need to edit the N8VBvCOM.inf file to match your current inf file before updating the driver. Once you have the inf edited you can run the update.bat file to update the driver.

vSOUND progress - vCOM info

I overcame a major hurdle today in the development of the vSOUND virtual sound card driver. If you are familiar with WDM Audio drivers you know that the portcls.sys driver exposes functions for creating, registering, and managing WDM Audio drivers. Unfortunately for our application the PcXXX functions hide much of the internal workings of the audio driver. For our vSOUND virtual sound card driver we need to be able to send customs IOCTLs to read and write data to the driver's buffers that represent the virtual A/D input and D/A output of the sound card.

In the typical sound driver you will see something like this:

extern "C" NTSTATUS
NTSTATUS ntStatus;

ntStatus =

return ntStatus;


The call to PcInitializeAdapterDriver() causes PortCls.sys to load pointers
to handlers for the certain IRPs like IRP_MJ_CREATE, IRP_MJ_DEVICE_CONTROL, etc… into the driver object. Without access to these handlers we cannot get at the buffers we need for our virtual driver. The question is - how do we intercept these handlers?

It turns out that PortCls provides a function call PcDispatchIrp() that we can use if we can get access to the handlers we need. To get access to the handlers we can override the pointers to the handlers that the call to PcInitializeAdapterDriver() installed:

extern "C" NTSTATUS
NTSTATUS ntStatus;

ntStatus =

if (NT_SUCCESS(ntStatus))
MajorFunction[IRP_MJ_DEVICE_CONTROL] = MSVASDeviceControl;
MajorFunction[IRP_MJ_CREATE] = MSVADCreateDevice;
MajorFunction[IRP_MJ_CLOSE] = MSVADCloseDevice;

return ntStatus;


In the code above we have installed our own handlers for the IOCTLs we are interested in. When our handler is called we can examine the IRP to determine whether the IRP is something we want to handle or pass along to the PortCls driver. We can do this by calling PcDispatchIrp() if we are not interested in the particular IRP.

That is all fine and dandy until you realize that you need to somehow call CreateFile() and DeviceIOControl() on the driver. We need a name that we can call in the CreateFile() function.

The MSVAD's AddDevice() looked like this:
extern "C" NTSTATUS
IN PDEVICE_OBJECT PhysicalDeviceObject
NTSTATUS ntStatus;

ntStatus =

return ntStatus;
The call to PcAddAdapterDevice() creates the device object, initializes the device context, and attaches the device object to the device stack. What we need to do is to create an additional FDO (Functional Device Object). If we create our own FDO we can create a symbolic link to it so Win32 user mode applications can open it and send IOCTLs to it.

Here is the solution:

extern "C" NTSTATUS
IN PDEVICE_OBJECT PhysicalDeviceObject
NTSTATUS ntStatus;
PDEVICE_OBJECT deviceObject;
WCHAR NameBuffer[] = L
WCHAR DOSNameBuffer[] = L
UNICODE_STRING uniNameString, uniDOSString;

ntStatus =

if (!NT_SUCCESS(ntStatus))
return ntStatus;

"Success from PcAddAdapterDevice"));

RtlInitUnicodeString(&uniNameString, NameBuffer);
RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);

ntStatus = IoCreateDevice(DriverObject,

return ntStatus;

"Success from IoCreateDevice"));

pDeviceExtension =
pDeviceExtension-&id = 0x5000;

ntStatus = IoCreateSymbolicLink (&uniDOSString, &uniNameString);

if (!NT_SUCCESS(ntStatus)) //try to delete the symbolic link first
"Failed IoCreateSymbolicLink... trying to delete it..."));
ntStatus = IoCreateSymbolicLink(&uniDOSString, &uniNameString);

if (!NT_SUCCESS(ntStatus))
"Failed IoCreateSymbolicLink"));
return ntStatus;

"Success from IoCreateSymbolicLink"));

deviceObject-&Flags &= ~DO_DEVICE_INITIALIZING;

return ntStatus;

Like in a normal device driver, we create an additional functional device object using IoCreateDevice(). We then create a symbolic link to this FDO using IoCreateSymbolicLink(). If all goes well we can open a handle to the vSOUND driver by calling CreateFile("\\\\.\\vSOUND", ...). And this works... We can now intercept the IOCTLs being sent to the vSOUND driver which means we can define our own custom IOCTL codes to access the buffers we need to get the sound data in and out of the driver!

Unfortunately, because we are trying to do something very out of the ordinary none of this is documented in the DDK so it took a while to figure it out. But it is a major problem that we have overcome on the way to a workable virtual sound card driver for use with PowerSDR. Now someone who has experience in writing device drivers might wonder why I didn't use the WDM prefered method of registering a Device Interface instead of creating a new FDO with a NT sytle name - That is the approach I took initially and it did not work. Upon searching the web and newsgroups it seems that others have tried this approach and were not successful. The answer to why probably lies somewhere in ks.sys or PortCls.sys that we do not have the source code to.


There will be a new build of vCOM available soon. Two users have reported that they have gotten total system freezes while using the driver. They did not get BSODs - just a total system hang up. According to Windows Internals, Forth Edition by Mark E. Russinovich and David A. Solomon there are three things that can cause the system to hang or become unresponsive:

1. A device driver does not return from an ISR.

Since we are not servicing ISRs in the vCOM driver this is not the problem.

2. A high priority realtime thread prempts the windowing system driver's input threads.

3. A deadlock occurs in kernel mode.

I think that #2 is the culprit. In trying to squeeze maximum performance out of the driver I set the thread priorities to the real-time range in the vCOM driver. Obviously this is not a good idea. I will adjust the thread priorities to normal and release a new build. I am 95% sure this is the problem causing the hang on some systems. The threads only rarely run since I implemented the Fast read and Fast write functions in the vCOM driver for build 222. Occasionally these threads will run when data is not immediately available. This would explain the intermittency of the problem.

Tuesday, July 05, 2005

Ken, N9VV reported an error in PowerSDR 1.3.13 where opening a serial port after it had already been opened and then closed would cause an exception. The serial port will remain unavailable until PowerSDR is exited and then restarted.

Using PortMon, I immediately saw the error: I was trying to close the handle to the com port without first cancelling a WaitCommEvent(). The file handle to the com port would only be closed when PowerSDR exited.

The correction to the source code was pretty easy:

In SerialStream.cs line 1383, function FreeHandle needs to be changed to:

protected internal override void FreeHandle(IntPtr handle)
if (_ownsHandle)
//Important! Must cancel all events before closing file!!!
Win32API_Serial.SetCommMask(handle, 0);
//Now we can close the file handle

Calling SetCommMask() with a mask of 0 cancells the current WaitCommEvent() allowing the com port to be closed and correcting the problem.

Monday, July 04, 2005

My new blog

This is the first entry in my blog. I realized that I was basically blogging on my webpage in the Notes section. This caused people to have to search through all the notes for important installation and configuration information about the software. So, now all comments about what I am working on will be posted here and removed from the webpage. Check here for the current status of the vCOM driver, vSound driver, and any other PowerSDR code updates.

Currently I am working on a fix for a problem in the PowerSDR CAT serial code that causes an exception as reported by Ken, N9VV.

Also, I am working on the vSound virtual sound card driver. I will use choice #2 for the implementation as described on my webpage. This will avoid having to use PortAudio in PowerSDR to talk to the virtual sound card.

Thursday, June 30, 2005

vSound Ideas

I started to take a look at creating a virtual sound card driver for use with PowerSDR. Here are two ways that I thought about doing it:


In the above figure we create two virtual sound card instances. They are virtually hooked together as depicted above. The advantage is that they appear to each application as a sound card so MME and DS can be used in both programs.

In the above diagram, the driver creates one virtual sound card device and the third party program talks to it as normal using MME or DS.

PowerSDR talks to the driver using normal file read/write IO and custom IOCTL commands instead of through PortAudio's MME or DS.

Which one is preferred? Comments: Email Me

Wednesday, June 29, 2005

I have a preliminary serial to TCP bridge app. Here are some screenshots:

(click on the image for a full size version)


In the image above PowerSDR's TCP Listener is enabled to listen for connections on port 4444 as in the notes for June 28, 2005 below.

I have two pairs of vCOM ports enabled: The first pair is COM4 and COM5, the second pair is COM6 and COM7.

The Serial To TCP Bridge app connects the virtual com ports to TCP. The app connects to PowerSDR as a client on port 4444.

In the screenshot above HRD is set to connect to COM5. MixW is set to connect to COM7. In the Serial To TCP Bridge app above, COM4 and COM6 are set to bridge to TCP port 4444. Refer to the screenshot below:


The IP Address is the address of the computer where PowerSDR is running. It can be an IP address or a machine name (or "localhost").

The TCP Port Number must be the port that the PowerSDR TCP Server is listening to for connections (here 4444).

COM Port 1 is the virtual com port that you want to bridge to TCP in the first pair of ports you have installed. The Enable check box enables COM Port 1.

COM Port 2 is the virtual com port that you want to also bridge to TCP in the second pair of ports you have installed. If you have only one pair of ports installed then you should not enable the COM Port 2 selection. The Enable check box enables COM Port 2.

The Monitor check boxes determine whether commands can be sent from the virtual com port to the PowerSDR TCP Server or not. If checked, the virtual com port only receives from the TCP Server. Any commands sent to the com port in Monitor mode are not transmitted to the PowerSDR TCP Server. If unchecked the communication is both ways - any commands sent to that virtual port will be sent to the TCP Server. Using Monitor mode another radio can be slaved to PowerSDR.

The Connect button will attempt to connect to the PowerSDR TCP Server with the selected settings. The progress will be reported in the status window. If a successful connect is made the Serial To TCP Bridge form with minimize, otherwise it will report the error.

The Disconnect button will disconnect from the PowerSDR TCP Server. It also closes the Serial To TCP Bridge application.

Here is the source code diffs and the binaries (based on 1.3.12) to play with. You will have to copy the PowerSDR.exe binary over an existing installed PowerSDR 1.3.12.

Note that the N8VB Serial To TCP Bridge application has to be running on the same computer that HRD, MixW, etc... is running. With just the TCP CAT enabled in PowerSDR you do not have to have the virtual com ports installed on the PowerSDR machine (unless you are running all applications on the same computer).

Here is a diagram of how it is set up:

how it works

If you have only one pair of vCOM ports enabled then COM6 and COM7 above would not exist.

We can get more sophisticated in the monitoring setting by possibly filtering commands on the monitored port. It could be set up so that only query commands such as FA; or FB; can be transmitted to the PowerSDR TCP Server from the monitored port. Any set commands would be filtered out and not sent. We will have to explore these possibilites based on what users want to do with all of it.

Also, to use the bridge with a read hardware port we would need to put settings for the com ports on the bridge form. Right now it is hard coded in the software for 9600, 8, n, 1

Tuesday, June 28, 2005

I have added preliminary support for TCP in an experimental version of PowerSDR1.3.12. Here are a few screenshots:

(click on the image for a full size version)


The windows titled "TestClient" is just a fast app I wrote to test the CSocketClient and CSocketServer classes that I wrote. I am using it to send and receive to/from PowerSDR. The four windows represent four different simultaneous connections to PowerSDR.

I added a few items to the setup form:


You can enable either CAT via Serial or TCP or both. For TCP you can set the maximun connections allowed and which port number the TCP server listens to for connections from clients.

I used an umodified PowerSDR 1.3.12 as a base so the new serial port code is not in it. This was just for testing purposes though. As Bill, KD5TFD brought up in an email conversation, we will probably have to serialize access to the PowerSDR CAT and a good place might be in the command parser.

The TCP stuff will probably not be integrated into the console until after 1.4.0 is out.

Here is a view of the two new files (3 classes CSocketClient, CSocketServer, TCPListener) added to make it work:


SocketUtilites.cs contains the asynchronous CSocketServer and CSocketClient classes.

TCPListener basically has the same function as SIOListener.

The next step is to create a TCP Client to Serial bridge what will allow you to connect to a virtual com port and send/rx data to/from the TCP server in PowerSDR.

COMMENT: I must say that Bob, K5KDN and Bill, KD5TFD have made it very easy to extend the CAT support based on their excellent code.

Friday, June 24, 2005

I wanted to add some additional fixed filter buttons to PowerSDR as well as two sliders for setting the filter low and filter high for the variable filters. PowerSDR is running out of room for all these "enhancements" so I added a tabbed control to the filter selection section of the screen to try to get some more room. See below:



When you select either one of the Var buttons on the Fixed Tab it automatically takes you to the Variable tab.

Oh, the above console has not been calibrated with my signal generator yet...

Can we gain some more room by putting some of the other controls on tabs? Comments, suggestions, hate mail: Email Me

Wednesday, June 22, 2005

Build 222 of the vCOM virtual serial port driver is released.

New Features:

Build 222 will now allow you to create up to 10 virtual com port pairs. Each pair acts like a virtual null modem cable.

By default, the inf file that comes with the download will create 1 pair (COM4 and COM5) by default. To change there settings you have to edit the inf file as follows:

Look for the section titled "Localizable Strings"

; *******Localizable Strings*******
Desc_x860= "N8VB vCOM MultiportSerialdrivers"
N8VBvCOMDesc= "N8VB vCOM Virtual Serial Port Driver"

;NOTE: Edit the following to change com port number and amount of paired ports

;Number Of Pairs
;NOTE: MAX is 10 pairs

;Pair 1

;Pair 2

;Pair 3

;Pair 4

;Pair 5

;Pair 6

;Pair 7

;Pair 8

;Pair 9

;Pair 10


To change how many port pairs the driver creates you must uncomment one of the settings in the ";Number Of Pairs" table above. By default it is PAIRS=0x01. To create two pairs you need to comment out PAIRS=0x01 by putting a semicolon in front of that line (;PAIRS=0x01) and then uncomment PAIRS=0x02 by deleting the semicolon in front of that entry.

To change what port numbers are used for each pair you must edit the Pair(n) tables where n is 1 through 10. You must not use com port numbers that are created by a real hardware com port or driver installlation will fail.

Bug Fixes:

It is worthwhile to upgrade to build 222 even if you do not intend to use more than one pair of virtual com ports. I found a few bugs in the DeleteDevice section of the driver that caused problems with creating symbolic links if the driver was previously installed and them removed. The symbolic links were not being deleted correctly. This could either cause BSODs or failure of the driver to reinstall. Since I had to completely rwrite the AddDevice and DeleteDevice functions within the driver I corrected the bugs and now deletion of the symbolic links appears to work correctly.

See the installation procedure below for updating to build 222. Once this installation procedure is done and build 222 is on your system you should be able to uninstall, make changes to the inf file and then reinstall the driver without having to reboot the system. Also, future builds will be able to be installed without rebooting (hopefully ;-)).

Installing Build 222:

To upgrade to build 222 for an earlier build:

1. Go to Control Panel->System->Hardware->Device Manager and uninstall the current vCOM driver. It will be under Multi-port Serial Adapters in Device Manager.

2. Open Start->Run->RegEdit. In RegEdit navigate to HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM. If you see any entries named \Device\vComDrvx where x = 0...n, right click on these entries and select delete. This will delete any symbolic links that were supposed to be deleted when build 114 or earlier was uninstalled.

3. REBOOT your computer. This is important! Do not try to install build 222 until after you have rebooted your computer.

4. Go to Control Panel->System->Hardware->Device Manager and verify that the vCOM driver has not been loaded.

5. Edit the N8VB_vCOM.inf file as described above to select your virtual com ports and number of pairs.

6. Navigate to the N8VB_vCOMBuild222 folder and run install.bat (make sure you have admin privileges!). Some users have reported that just double clicking on install.bat in a Windows Explorer window does not work for them. It appears to be releated to Windows XP Home Edition. They have reported success by first opening a console window and running install.bat from there.


To use PowerSDR with Ham Radio Deluxe you should select TS-50S for the radio type. The current CAT command support in PowerSDR does not implement all of the TS-2000 commands so HRD will update very slowly if you set it for TS-2000. Eventually HRD will support the SDR-1000, but right now selecting TS-50S works ok.


Eventually the vCOM driver will have a proper installation program that will make it easier to configure all of the settings.