Lately, I have been experimenting with using a CC1101 chip together with a Beaglebone black single board ARM computer to transmit IP traffic over the 70cm Amateur band. There has been a similar project from OEVSV, but I’ve never seen this project reach a final form. Edouard F4EXB has some code that uses the Raspberry Pi instead. Presumably, this will suffer from problems when using the higher data rates supported by the CC1101, as his software is not real-time.
The goal of my project is to build an affordable 70cm IP transceiver with a power of a few Watts. This can be used in the Hamnet Amateur Radio IP network. The modulation should not use more than a couple of hundreds of kHz’s of spectrum, as it doesn’t seem very sensible to take up much more spectrum in the 70cm band. Although the usual maximum bandwidth in the 70cm band is 20kHz, the IARU R1 bandplan allows for wideband experiments around 434.000MHz. A data rate of 128kbps with MSK modulation seems about right, as it uses roughly 200kHz of spectrum. Further on-the-air tests will perhaps change these parameters a bit.
The CC1101 is a transceiver chip from Texas Instrument that is able to do up to 600kbps using different digital modulations (FSK, GFSK, 4-FSK and MSK). It supports packet-based transmissions using RX and TX FIFOs and can be programmed through a SPI interface. It is quite inexpensive and popular, and there are several modules in the market that include the CC1101 and an RF amplifier in a small board (the CC1101 by itself goes only up to 10dBm). For instance, the RFC-1100H I’m using includes a 2W PA. One has to be a bit careful with these amplifiers, as they lack filtering after the amplifier and will probably need a low-pass filter to comply with the regulations. Also, they may suffer from thermal issues during long transmissions.
The hamnet-cc1101 code I’ve programmed uses one of the Beaglebone black PRU’s (Programmable Realtime Units). These are two 200MHz 32bit special purpose processors that are embedded in the TI ARM chip that the Beaglebone uses. They are intended for real-time applications and can be programmed using an assembler code that runs at one instruction per clock cycle. Initially, I wanted to make my code a regular user-space program. However, I found out soon that the 64byte buffer of the CC1101 empties quite fast (in 4ms at 128kbps), so the code should run often enough to refill the buffer. The problem is that a Linux user-space program can be forbidden to run for several milliseconds while the kernel is busy serving interrupts. Therefore, I have ended up using the PRU to interface with the CC1101.
The PRU runs some assembler code that controls the CC1101 through SPI by bit-banging some PRU I/O pins. The communication between the PRU code and the user-space Linux code is through the PRU RAM. Each PRU has 8kB of dedicated RAM that can be
mmap()ed by a user-space program. The user-space code just writes and reads to some buffers on the PRU RAM. This hides away all the complexity in the PRU code and makes it possibly to implement easily different FEC codes and checksums in the user-space code.
So far, I’m using a CRC-32 checksum and no FEC, but perhaps I’ll do some tests with some low-overhead FEC in the future. The packet format I’m using is as follows:
- 2 bytes. Big-endian 16bit unsigned integer. Length of the whole frame.
- n bytes. Ethernet frame.
- 4 bytes. CRC-32 of the whole frame (big-endian).
By maintaining a simple packet format, this system can be interfaced with others, as the CC1101 supports a wide range of digital modulations and rates. However, nothing stops one of using a really complex FEC, beacause the Beaglebone has enough CPU power to handle this at the (relatively) low data rates used.
The user-space code creates a TAP device to allow access to the CC1101. This can be treated as a regular ethernet device, so IPv4, IPv6 and/or BPQ AX.25 can be used over this interface.
While programming this project, I’ve found that the documentation on the web about how to start programming the PRU in assembler is not so good. The book Exploring BeagleBone has been very useful to understand how the PRU works and get this up and running.
I am testing the stability of my code by running two of these CC1101 modules at home, each on its own Beaglebone black. One of them is connected to my Hamnet network, using a bridge between the TAP interface and the ethernet interface. I use the other one connected to my laptop by USB and bridging the TAP interface and the ethernet over USB interface. This allows me to access Hamnet from my laptop. There are 3 floors in vertical between both devices and I’m using a power of 10dBm (I keep the PA off). So far, it seems to work well. The data rate doesn’t allow for video streaming, but mumble and echolink work without problems.