dmr updates

This commit is contained in:
Max 2017-02-09 09:05:34 -05:00
parent b81ad173b1
commit 560f0c5461
3 changed files with 97 additions and 6 deletions

View File

@ -0,0 +1,73 @@
#################################################################################
#
# config file for DMR BS TX
#
#################################################################################
#
# DMR Encoder (C) Copyright 2017 Max H. Parke KA1RBI
#
# This file is part of OP25
#
# This is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#################################################################################
#
# NOTE
#
# Everything in this file is doubled up due to the two slot TDMA.
#
# For example "en1" is for slot 1 and "en2" is for slot 2
#
# Syntax is unforgiving - no whitespace allowed (outside of comments)
#
#
#################################################################################
#
# slot enable [1 bit: 0=disable; 1=enable]
# - transmits voice sync when enabled, idle slot sync when disabled
# - the GR block consumes input samples on both channels (whether or not enabled)
#
en1=1
en2=1
#################################################################################
#
# color code [4 bits]
#
cc1=1
cc2=1
#################################################################################
#
# Activity Update
# - source: spec volume 2 para 7.1.3.2
# - specify the hashed address [8 bits]
# - compressed destination address 1 and destination address 2
# - typically set to zero [?]
#
ts1=0
ts2=0
#################################################################################
#
# Group Voice Channel User LC PDU
# - source: spec volume 2 paragraph 7.1.1.1
# - the so/ga/sa (Service Options/[talk]Group Address/Source Address)
# - values are specified in decimal [so: 8 bits; sa and ga: 24 bits]
# - service options are typically set to zero [?]
#
so1=0
so2=0
ga1=1
ga2=311
sa1=1
sa2=1

View File

@ -76,6 +76,18 @@ def transfer_function_tx():
xfer.append(pf * hf)
return xfer
def transfer_function_dmr():
xfer = [] # frequency domain transfer function
for f in xrange(0, 2881): # specs cover 0 - 2,880 Hz
if f < 1920:
hf = 1.0
else:
hf = 0.5 + 0.5 * cos (2 * pi * float(f) / 1920.0)
xfer.append(hf)
xfer = np.array(xfer, dtype=np.float64)
xfer = np.sqrt(xfer) # root cosine
return xfer
class c4fm_taps(object):
"""Generate filter coefficients as per P25 C4FM spec"""
def __init__(self, filter_gain = 1.0, sample_rate=_def_output_sample_rate, symbol_rate=_def_symbol_rate, span=_def_span, generator=transfer_function_tx):
@ -106,6 +118,7 @@ class p25_mod_bf(gr.hier_block2):
output_sample_rate=_def_output_sample_rate,
reverse=_def_reverse,
verbose=_def_verbose,
generator=transfer_function_tx,
log=_def_log):
"""
Hierarchical block for RRC-filtered P25 FM modulation.
@ -143,7 +156,9 @@ class p25_mod_bf(gr.hier_block2):
else:
self.polarity = blocks.multiply_const_ff( 1)
self.filter = filter.interp_fir_filter_fff(self._interp_factor, c4fm_taps(sample_rate=output_sample_rate).generate())
self.generator = generator
self.filter = filter.interp_fir_filter_fff(self._interp_factor, c4fm_taps(sample_rate=output_sample_rate, generator=self.generator).generate())
if verbose:
self._print_verbage()

View File

@ -119,17 +119,20 @@ static void encode_embedded(const uint8_t lc[72], uint8_t result[32*4]) {
for (int i=0; i<9; i++) {
csum += load_i(&lc[i*8], 8);
}
csum = csum % 31;
for (int i=0; i<7; i++) {
memcpy(&encode[16*i], &lc[s_index], lengths[i]);
s_index += lengths[i];
}
for (int i=0; i<5; i++) {
encode[(i+2)*16+10] = (csum >> (4-i)) & 1;
}
for (int i=0; i<7; i++) {
memcpy(&encode[16*i], &lc[s_index], lengths[i]);
int acc = load_i(&lc[s_index], 11);
int acc = load_i(&encode[16*i], 11);
acc = hamming_16_11[acc];
for (int j=0; j<5; j++){
encode[i*16+j+11] = (acc >> (4-j)) & 1;
}
s_index += lengths[i];
}
for (int i=0; i<16; i++) {
encode[7*16+i] = (encode[0*16+i] + encode[1*16+i] + encode[2*16+i] + \
@ -277,12 +280,12 @@ dmr_bs_tx_bb_impl::config()
}
for (;;) {
cp = fgets(line, sizeof(line) - 2, fp1);
if (!cp) break;
if (line[0] == '#') continue;
// cach: hashed addr ts1(8) and hashed addr ts2(8)
// emb: (one per ch) cc(4)
// group voice channel user PDU: service options (8), group address(24), source address(24)
// (one per ch)
if (!cp) break;
if (memcmp(line, "ts1=", 4) == 0)
sscanf(&line[4], "%d", &d_ts[0]);
else if (memcmp(line, "ts2=", 4) == 0)
@ -416,7 +419,7 @@ dmr_bs_tx_bb_impl::general_work (int noutput_items,
// -1: RC
// 0|1|2|3: segment no. of embedded signalling
{-2, 0, 1, -1, 2, 3},
{-2, 0, 1, 2, 3, -1}
{-1, 2, 3, -2, 0, 1}
};
int nconsumed[2] = {0,0};