Gr4-packet-modem receiver
This page describes the operation of the gr4-packet-modem receiver.
The packet receiver is implemented as a class that adds and connects multiple blocks to an existing gr::Graph
. This is done like so because at the moment hierarchical flowgraphs are not supported in GNU Radio 4.0.
Flowgraph
The flowgraph of the packet receiver is shown here. Blocks in grey are not present, but could be added to the flowgraph. The functionality of the flowgraph is described below. This assumes some familiarity with the packet structure defined in gr4-packet-modem waveform design.
The Syncword Detection block receives IQ samples at an integer number of samples/symbol (typically 4 samples/symbol). It uses FFTs to compute correlations with the synchronization words and detect the presence of a packet in the time-frequency domain. The mathematical details are described below. When a packet is detected, the block inserts tags that mark the sample in which the syncword begins, a fine time offset, indicating fractional sample delay, a carrier frequency estimate, a phase estimate, an amplitude estimate, and a CN0 estimate. The output of this block is the same stream of IQ samples as the input, with these tags inserted.
The Coarse Frequency Correction block is similar to a Rotator that can update its frequency using a tag. When this block sees a tag indicating the carrier frequency estimate at the beginning of a packet, it sets its rotator frequency to correct that frequency error, and resets its internal rotator phase to zero so that the phase estimate produced by Syncword Detection is still applicable to the output of this block. In this way, most of the frequency error of the packet is corrected. The Coarse Frequency Correction block maintains a constant frequency shift throughout all the packet, and it does not take into account any frequency drift or error in the frequency estimate produced by the Syncword Detection.
The output of Coarse Frequency Correction is sent to the Symbol Filter block. This block implements RRC matched filtering and decimation to one sample/symbol. This is performed by a polyphase FIR filter, similar to how Symbol Sync operates. However this block is open-loop. It does not try to measure and correct the symbol timing offset. It only uses the tags generated by Syncword Detection that indicate the start of the packet and its fractional sample delay to initialize the symbol timing at the beginning of the packet. This symbol timing is propagated at the nominal symbol rate throughout the packet, so this block does not handle any sampling frequency offset. This is fine for packet of a reasonable length. For instance, for a packet of 10000 symbols (which can carry around 2500 bytes with uncoded QPSK data) and a sampling frequency offset of 10 ppm, the accumulated symbol timing error at the end of the packet is only 0.1 symbols. This open-loop approach is simpler than the closed loop implemented by Symbol Sync, and it can be more robust under low SNR or fading conditions, as it only relies on the accuracy of the timing estimate done on the synchronization word. The Symbol Filter block also uses the amplitude estimate tags produced by Syncword Detection to normalize its output to unit amplitude (the constellation symbols are normalized to the amplitude of the reference constellation).
The Syncword Wipe-off block receives the one sample/symbol output of Symbol Filter and wipe off the known 64-bit pattern of the synchronization word at the beginning of each packet, so that all the IQ symbols of the synchronization word at the output are +1 (which acts as a pilot signal). This blocks knows where the synchronization word occurs in the sample stream because of the tags inserted by Syncword Detection, which have been propagated appropriately by Symbol Filter. Note that up to this point the stream of samples throwing to the blocks corresponds to all the samples in the input signal. The gaps between packets have not been discarded yet, and the lengths of the packets are not known until the header is decoded and parsed.
Payload Metadata Insert is critical for the operation of the rest of the flowgraph. It works in the following way. It first drops input samples until it sees a tag marking the beginning of a packet. Then it passes the first 64 + 128 symbols of the packet to the output. These 64 + 128 symbols correspond to the synchronization word and header. The downstream blocks will use these symbols to decode and parse the header, in order to find the packet length and potentially other properties such as its payload MODCOD (in this implementation the only MODCOD possible is uncoded QPSK, but the system is designed to allow other MODCODs). The Payload Metadata Insert now blocks waiting for a gr::Message
that contains the "metadata" (packet length, packet type, etc.) decoded from the header. In this state, the block does not consume any input and does not produce any output. When the message eventually arrives, the block starts passing the payload of the packet to the output. It inserts tags at the beginning of the payload indicating what is the payload length and what is the constellation (and potentially what is the FEC type, if different FECs were supported for the payload). The block only passes to the output as many samples as there are symbols in the payload (which it knows because of the payload length in the metadata message). Once the end of the payload is reached according to this count, the block goes back to its initial state in which it drops input until it sees a tag indicating that a packet begins. In this way, the output of Payload Metadata Insert is a stream of back-to-back packets, appropriately cut from the continuous symbol stream to their correct payload length, and with some metadata tags inserted at the beginning of the payload. In order to produce this output, the block needs to first pass the header to the output, and then wait for the header to be decoded before passing the payload to the output.
The Costas Loop block is used for closed loop recovery of phase and frequency error.