Hacking the sBITX

Here is how you can get started with experimenting with the sBitx software. We will see how the sBITX is laid out and how to quickly start changing things. The latest source code can always be found on https://github.com/afarhan/sbitx.

Quick Start

If you received the sBitx as a ready-built system, you will find the source code in /home/pi/sbitx directory. To build the system you execute the batch file build as thus:
cd /home/pi/sbitx (to change to sbitx directory)
To build the radio,
./build sbitx (remember the dot before the slash)
To start the radio,
./sbitx

How it is laid out

The sBitx is all about being able to find your way in the weirdness of software defined radios, hence every attempt is made to keep it simple and quick to understand. We assume a minimum familiarity with the C language and being able to use a text editor. The idea is to make it easy to carry the system from platform to platform. The big idea of sBitx is that it is NOT  a phasing SDR. It is a superhet with the first IF at 40 MHz that is downconverted to a second IF of 24 KHz. The 24 KHz IF is digitized through a high speed, low-noise audio codec. In this specific case, it is the WM8731. In broad strokes:
  1. The core SDR is on sbitx.c and it has no user interface around it. It gets samples from the audio system and writes them back to the audio system. It accepts commands  to change modes, volume, etc., as text strings when the user interface calls sdr_request(). In sbitx.c, the samples from the mic arrive, get processed and sent to the radio (when it is transmitting) or they arrive from the radio, get processed and sent to the speaker (when it is receiving). These two routines are rx_process()  and tx_process().
  2. We use convolution method to do the actual modulation/demodulation. It is much simpler to understand compared to a phasing system. It is best explained by Gerlad Youngblood, K5SDR in his seminal papers called A Software Defined Radio for the Masses. Read them here and here. Better yet, print them out and read and re-read them until you understand the concept. A few tricky details like save-and-overlap convolution or wrap-around with imaginary frequencies are not required knowledge to hack. If you insist, read them on https://www.dspguide.com/.
  3. We do our own GUI. The regular GUIs of Linux/Mac/Windows don’t quite work for radios. Each is pretty complicated as well. We also imagine that in the future someone might want to port the sBitx to an embedded system. Besides, most of us have no time to learn intricacies of GUI programming. Instead, we took the basic ability to draw lines, rectangles and text and built our own simple user interface. All that is in sbitx_gtk.c.
  4. It is written in simple C language in a particular style of using all smalls as the names of functions and variables and it has underscore between the words (do_cmd() instead of doCmd or DoCmd). The lines are formatted such that they can fit into the 7 inch Raspberry Pi screen. We use the opening brace on the same line as the if or while statement to make efficient use of the 7 inch display of the sBitx. Stick to 2 spaces per tab, braces in the same line as the if or while statement. This is not religion but utility. The compact display of the sBitx can’t show too many lines. We follow the Linux coding style.

The Sound System

The details of sound sytem are all hidden in sbitx_sound.c. There are a few things to remember
  1. The sampling rate is fixed at 96,000 samples per second. Each sample read or written to the hardware is a signed 32-bit integer. The audio hardware works in full duplex at all times.
  2. The digital IF is centered on 24 KHz, staritng from 12.5 KHz to 37.5 KHz.
  3. The left channel is dedicated to receive. It gets its samples from the demodulator (Actually, the downconverter that moves the 40 MHz IF to 24 KHz, which is kind of “audio” range, handled by the audio codecs). After processing it writes the samples back to the speaker.
  4. The right channel is dedicated to transmit. It gets its samples from the mic, processes them and writes the transmit signal samples to the right channel.

The GUI

The GUI and other platform specific details are implemented in sbitx_gtk.c. The GUI is build around a single structure called the field. This represents a single element on the screen (like the waterfall or a button)
struct field {
 char *cmd;
 int (*fn)(struct field *f, cairo_t *gfx, int event);
 int x, y, width, height;
 char label[30];
 int label_width;
 char value[MAX_FIELD_LENGTH];
 char value_type; //NUMBER, SELECTION, TEXT, TOGGLE, BUTTON
 int font_index; //refers to font_style table
 char selection[1000];
 int min, max, step;
};
The field cmd holds the text string that is to be sent as the command to the core sbitx. Many functions are not core to the sbitx. For instance, RIT (Receiver incremental tuning) is implemented as user-level feature that changes the core sbitx frequency between receive/transmit. The commands that are not to be passed to the core sdr are prefixed with a ‘#‘. There are a few kinds of controls defined. All of them are in square boxes that can be easily touched by stubby fingers. These are the different kinds of controls
  • Button: These have no ‘value’ just a label (Ex: Close)
  • Selection: These can have one the selection of texts given in the selection field. All values are text strings, separated by forward slash’/’. (Ex: Mode selector)
  • Toggle: Essentially a selection with two values, when you click on it, it changes (like VFO A/B, RIT On/Off, etc.)
  • Number: Like a volume control or gain control. It can take any value between min, max in jumps of step.
  • List: This is takes a long text that is wrapped around or broken with new line characters. The text scrolls past.
  • Text: You can enter text in these fields
While the default drawing and editing of these are handled by draw_field() and edit_field() functions, They can be over-ridden by a user supplied function fn. If fn is NULL, the default behaviour happens. For instance, in the tuning control, the step size is determined by STEP control and the final frequency depends upon RIT, VFO A/B, the current state of radio (transmit/receive). Hence it is handled in the funciton do_tuning(). Every time a control is changed, do_cmd() is called as a clearing house. All the GUI commands are also available as text commands that maybe entered from the softkeyboard or a physical keyboard plugged into the USB port of the sBitx.

Before you make  any changes

Save the current snapshot of the source code using the git like this:
git commit -a -m “Saving the original, just in case, hehe”
This command commits (saves) the current snapshot. The -a means all of it, -m says, a message is to remember what the commit is all about.  To see the history of all the previous commits
git log
This lists all the last few commits, Each commit is listed with the comment as well as a unique checksum. To revert to a previous commit,
git  checkout [checksum] (You can specify just the first few letters of the checksum)
This is the shorest introduction to git, learn more from the Internet.

Debugging

We use the standard linux debugger gdb. You can read all about it in the manual (Run : man gdb). However, here is a quick start for those who don’t read manuals. Start it like this:
gdb sbitx
To run the sbitx, type the command
(gdb) r (Run the program)
To set a break-point
(gdb) b sbitx.c:100 (Sets breakpoint when execution reaches a particular line) (gdb) b rx_process (Sets breakpoin when the execution reaches the function rx_process)
To see a variable
(gdb) p last_mouse_x (Prints the value of the variable) (gdb) p *f  (Prints the structure/variable pointed by f)
To step inside the function on the current line
(gdb) s
To step over the current line to the next
(gdb) n
To resume execution of the sbitx after watching/stepping past a break-point
(gdb) c
To see the stack of called functions (back trace)
(gdb) bt
To get out of the debugger
(gdb) q

Leave a Reply

Your email address will not be published. Required fields are marked *