This article is a follow-up to the previous attempt to implement the DMR land-mobile radio standard with SDR transceivers which can be read here: DMR with a PlutoSDR device. If you haven't already, it is suggested to read the previous article first to have an understanding of the software stack used, while this article will expand on the TDMA features required for a full DMR base station implementation. Further on, a DMR base station will be referred to as BS and the mobile station as the MS.
While the previous implementation described above allowed the operation of a full duplex DMR BS, real TDMA operation was not possible because the GNU radio flowgraph latency is not deterministic leading to unknown sample transmit / receive times, therefore some modifications were made to MMDVM in order to only receive timeslot 2 regardless of the timeslot used by MS transmissions, rendering one inbound channel (timeslot) unusable. The previous implementation also used gr-osmosdr as a wrapper to communicate with SDR devices, which made it compatible with most devices currently on the market. This has now changed, since gr-osmosdr does not support passing GNU radio FPGA timestamps, the LimeSDR hardware is specifically targeted in the implementation below.
This time, we leverage MMDVM-SDR (MMDVM-SDR) operating as designed and receiving both BS inbound timeslots as specified in the ETSI standard. To operate in TDMA mode, we also need to employ SDR hardware which is capable of providing FPGA timestamps of received samples, and also able to transmit sample bursts at specified timestamps. The candidates which were tested were the LimeSDR-mini and LimeNET Micro devices, as they both provide FPGA timestamps. The LimeNET Micro was ultimately chosen for its ability to operate standalone. The LimeRFE device was used as a radio frontend for filtering and power amplification purposes, with the automatic control and band selection being provided by QRadioLink. The implementation can be altered with minimal modifications to support other devices providing this functionality, like the USRP.
The ETSI DMR specification relevant to this work (air interface and burst characterization) can be found at this link: ETSI TS 102 361-1 V1.4.5 (2007-12).
Since our aim is to be relatively ETSI compliant, here is a short summary as some information below will already be familiar:
DMR is a land-mobile voice and data communications radio standard which implements a double timeslot time division multiple access scheme (TDMA). Each DMR base station can carry two radio conversations simultaneously in a single 12.5 kHz channnel, effectively offering double the call capacity compared to a single FM 12.5 kHz repeater channel. More than that, the DMR protocol offers call routing via IP transport between logical channels called talk groups, as well as direct calls between two DMR radios identified by a unique ID. Besides these advantages, the TDMA access scheme requires very strict timing for MS access to the BS, and the mobile station needs to be time synchronized to the BS and transmit within a specific window of time in order to be received in its own timeslot and avoid interfering with the other timeslot where a different radio transmission by a second MS can occur independently.
The structure of the BS-originated TDMA frame transmission is depicted below:
The structure of the MS-originated TDMA frame transmission is depicted below:
The DMR BS needs to be able to receive samples in each timeslot aligned in time with samples transmitted in each timeslot. For the purposes of simplifying the concept, the BS is transmitting both timeslots and CACH bursts continuously. The time base for the MS to align to is set by the BS transmission and does not require an external time reference.
MMDVM implements OSI layers 3, 2 and partly 1, and provides four level FSK symbols at a rate of 24000 samples/second. These symbols are filtered with a root-raised cosine filter.
The GNU radio transmit flowgraph implemented in QRadioLink begins with a MMDVM source block which retrieves these samples sent from MMDVM-SDR via a ZeroMQ socket, handles frequency modulation, filtering and up-sampling. The flowgraph ends with a LimeSDR sink which sends the samples to a LimeSDR device for transmission, with time tags added in the first block and propagated by GNU radio through the flowgraph.
On the receive side, samples received by the LimeSDR devices enter the GNU radio receive flowgraph of QRadioLink through a LimeSDR source, then are downsampled to 24000 samples/second and filtered, and finally frequency demodulated, before being sent via ZeroMQ packets to MMDVM-SDR. The ZeroMQ custom sinks and sources implemented in QRadioLink use IPC (inter-process communication) as a delivery mechanism and are now different to the GNU radio ZeroMQ sinks and sources for the purposes of custom processing.
QRadioLink also serves here as an user interface to handle SDR tuning and setup of RX/TX offsets necessary for a full duplex base station, while also handling automatic control and band operation setup of the LimeRFE radio frontend.
The LimeSDR hardware provides FPGA timstamps for each packet of samples received. The packet size can vary, however these timestamps received by the GNU radio source are converted to rx_time GNU radio tags containing a tuple of:
For the BS application to work, we need to initialize the RX stream before initializing the TX stream. This will allow the GNU radio time tags to configure the burst timing code with a known time base of the SDR device. Since the time tags are not applied to each sample received, we will need to keep a count of the number of received samples downstream, and calculate the exact time of each sample by multiplying the sample counter with the estimated time spent per sample. All time records will be converted and kept internally as nanoseconds.
The burst time allocator for transmitted samples will use this internal time reference to create tx_time GNU radio tags containing the same integer and fractional seconds described above.
MMDVM-SDR provides a buffer of N control elements marking the start of each slot along side the actual sample buffer of N samples. These control elements are sent via ZeroMQ to QRadioLink along with 16 bit samples. Once a control element has been encountered in the incoming buffer, the code will allocate a time in the future for a DMR timeslot, and store this time in an internal queue. In order to be able to transmit the samples, the time has to be far enough in the future so that any latency in the GNU radio flowgraph does not lead to dropped samples. Experimentally the burst delay for the time tags was chosen between 50 - 100 milliseconds in the future, which allows enough time for the non-deterministic nature of GNU radio block calls. The SDR device will store samples in an internal buffer and will wait for the timestamp to be reached, and will then transmit the samples.
The guard time between MS sourced timeslots is 2.5 milliseconds, with 1.25 ms allocated to transmitter ramp-up at the start of the slot and 1.25 ms at the end of the slot allowing for radio propagation delay. This guard time is pretty generous, in the fact it allows us to be off as much as 30 samples at the start and end of the timeslot, and still make the time window for an MS sourced burst to be received in its correct slot.
Received samples continuously increment the internal sample counter used to determine the exact time of a sample, and each sample is then checked against the queue of transmitted time slots. If a sample is deemed to fit inside the next possible timeslot, another counter is started until the timeslot stored in the queue has received all possible samples (a DMR timeslot is 30 milliseconds long, so at the sample rate of 24000, there are 720 samples inside a timeslot).
ZeroMQ messages passed between QRadioLink and MMDVM-SDR contain three data structures: a 32 bit integer reprezenting the number of available samples in the message, a buffer of N 8 bit integers which contain control data (slot start marks) for each sample, and a buffer of N signed 16 bit samples to be modulated / demodulated.
The code for the LimeSDR sinks and sources is basically the same code delivered in the gr-limesdr package, however it has been altered slightly to provide some debug information and also provide time tags for each data packet received, so this code is currently included in the QRadioLink repository.
During implementation and testing, a couple of issues became apparent with the SDR implementation of the DMR BS.
For operation instructions, refer to the previous article on this topic: DMR with a PlutoSDR device as the instructions apply here as well. One special mention for the fact that the RX stream must be initialized before the TX stream in order for the code to function properly. The duplex offset should be configured in QRadioLink to a value in kHz different than zero and matching the frequencies configured in the DMR MS. To enable transmit, the PTT button should be pressed, during which time the frequency cannot be changed. To change the frequency, deactivate PTT.
The TDMA functionality described here can now be found in the mmdvm_tdma branch of the QRadioLink source repository and will be included in a release in the near future. The matching code for MMDVM-SDR can be found in the zmq_double_slot branch here: MMDVM-SDR but it is not currently compatible with regular GNU radio flowgraphs designed with GNU radio companion, due to the custom code required for TDMA operation. Of course, the code is still work in progress, with some bugs still present and issues still left unresolved, but feel free to contribute via the usual channels.
This article was made possible by Jonathan Naylor G4KLX (the author of MMDVM and MMDVMHost), Peter Rakesh (the author of the Linux port of MMDVM, MMDVM-SDR) and Lime Microsystems who supplied the SDR transceiver used for this purpose.
Video of the LimeNET Micro as a SDR DMR BS receiving TDMA trasnmissions from the DMR MS