1
0
Fork 0
mirror of https://github.com/hb9fxq/gr-digitalhf synced 2024-12-22 15:10:00 +00:00

prel. support for 12800 baud 110C bursts added

This commit is contained in:
cmayer 2019-05-23 20:34:41 +02:00
parent 7f706f6134
commit 91a06406fe

View file

@ -45,8 +45,18 @@ QAM64=np.array(
range(64)), common.CONST_DTYPE) range(64)), common.CONST_DTYPE)
## for test ## for test
#QAM64 = QAM64[(7,3,24,56,35,39,60,28),] QAM64p = QAM64[(3,24,56,35,39,60,28,7),]
#QAM64['symbols'] = [1, 0, 2, 6, 4, 5, 7, 3] QAM64p['symbols'] = range(8) ## not used
## ---- Walsh-4 codes ----------------------------------------------------------
WALSH4 = np.array([[0,0,0,0], # 0 - 00
[0,1,0,1], # 1 - 01
[0,0,1,1], # 2 - 10
[0,1,1,0]], # 3 - 11
dtype=np.uint8)
FROM_WALSH4 = -np.ones(256, dtype=np.int8)
for i in range(4):
FROM_WALSH4[np.packbits(WALSH4[i][:])[0]] = i
## ---- constellation indices --------------------------------------------------- ## ---- constellation indices ---------------------------------------------------
MODE_BPSK = 0 MODE_BPSK = 0
@ -55,6 +65,7 @@ MODE_8PSK = 2
MODE_16QAM = 3 MODE_16QAM = 3
MODE_32QAM = 4 MODE_32QAM = 4
MODE_64QAM = 5 MODE_64QAM = 5
MODE_64QAMp = 6
## ---- data scrambler ----------------------------------------------------------- ## ---- data scrambler -----------------------------------------------------------
class ScrambleData(object): class ScrambleData(object):
@ -76,6 +87,35 @@ class ScrambleData(object):
self._state = np.concatenate(([self._state.dot(self._taps)&1], self._state = np.concatenate(([self._state.dot(self._taps)&1],
self._state[0:-1])) self._state[0:-1]))
class ScrambleDataP(object):
"""data scrambling sequence generator"""
def __init__(self):
self._i = 0
state = np.array([0,0,0,0,0,0,0,0,0,0,0,1], dtype=np.uint8)
taps = np.array([1,1,0,0,1,0,1,0,0,0,0,0], dtype=np.uint8)
n = 10000
m = len(state)
sequence = np.zeros(n, dtype=np.uint8)
sequence[0:m] = state
for i in range(m,n):
sequence[i] = sequence[i-m:i].dot(taps)&1
idx = np.arange(160, dtype=np.uint32)
self._seq = 4*sequence[3530+idx] + 2*sequence[4042+idx] + sequence[4796+idx]
def reset(self):
self._i = 0
def get_seq(self):
return self._seq
def next(self):
if self._i == 160:
self._i = 0
s = self._seq[self._i]
self._i += 1
return s
## ---- preamble definitions --------------------------------------------------- ## ---- preamble definitions ---------------------------------------------------
## 184 = 8*23 ## 184 = 8*23
PREAMBLE=common.n_psk(8, np.array( PREAMBLE=common.n_psk(8, np.array(
@ -203,7 +243,7 @@ class PhysicalLayer(object):
"""intialization""" """intialization"""
self._sps = sps self._sps = sps
self._frame_counter = -2 self._frame_counter = -2
self._constellations = [BPSK, QPSK, PSK8, QAM16, QAM32, QAM64] self._constellations = [BPSK, QPSK, PSK8, QAM16, QAM32, QAM64, QAM64p]
self._preamble = self.get_preamble() self._preamble = self.get_preamble()
self._scramble = ScrambleData() self._scramble = ScrambleData()
self._viterbi_decoder = viterbi27(0x6d, 0x4f) self._viterbi_decoder = viterbi27(0x6d, 0x4f)
@ -307,7 +347,15 @@ class PhysicalLayer(object):
self._rate_info = rate_info = TO_RATE[self._mode['rate']] self._rate_info = rate_info = TO_RATE[self._mode['rate']]
self._intl_info = intl_info = TO_INTERLEAVER[self._mode['interleaver']] self._intl_info = intl_info = TO_INTERLEAVER[self._mode['interleaver']]
print('======== rate,interleaver:', rate_info, intl_info) self._12800burst_mode = mode['rate']==(1,1,0) and mode['interleaver']==(0,0,1)
print('======== rate,interleaver:', rate_info, intl_info, self._12800burst_mode)
if self._12800burst_mode:
self._scrp = ScrambleDataP()
self._constellation_index = MODE_BPSK# 64QAMp
self._data_scramble = np.ones (256, dtype=np.complex64)
self._data_scramble_xor = np.zeros(256, dtype=np.uint8)
##self._data_scramble = QAM64p['points'][self._scrp.next() for _ in range(256)]
else:
self._interleaver_frames = intl_info['frames'] self._interleaver_frames = intl_info['frames']
baud = rate_info['baud'] baud = rate_info['baud']
intl_id = intl_info['id'] intl_id = intl_info['id']
@ -344,6 +392,9 @@ class PhysicalLayer(object):
def make_data_frame(self, success): def make_data_frame(self, success):
self._preamble_offset = -72 ## all following reinserted preambles start at index -72 self._preamble_offset = -72 ## all following reinserted preambles start at index -72
a = np.zeros(256+31, common.SYMB_SCRAMBLE_DTYPE) a = np.zeros(256+31, common.SYMB_SCRAMBLE_DTYPE)
if self._12800burst_mode:
a['scramble'][:256] = QAM64p['points'][[self._scrp.next() for _ in range(256)]]
else:
a['scramble'][:256] = self._data_scramble a['scramble'][:256] = self._data_scramble
a['scramble_xor'][:256] = self._data_scramble_xor a['scramble_xor'][:256] = self._data_scramble_xor
n = (self._frame_counter-1)%72 n = (self._frame_counter-1)%72
@ -362,6 +413,20 @@ class PhysicalLayer(object):
return a return a
def decode_soft_dec(self, soft_dec): def decode_soft_dec(self, soft_dec):
if self._12800burst_mode:
print('decode_soft_dec', len(soft_dec))
n = len(soft_dec) // 32
soft_bits = np.zeros(2*n, dtype=np.float32)
for i in range(n):
w = np.sum(soft_dec[32*i:32*(i+1)].reshape(8,4),0)
b = FROM_WALSH4[np.packbits(w>0)[0]] ## TODO use 2nd half of WALSH bits
abs_soft_dec = np.mean(np.abs(w))
print('WALSH', i, w, b, abs_soft_dec)
soft_bits[2*i] = abs_soft_dec*(2*(b>>1)-1)
soft_bits[2*i+1] = abs_soft_dec*(2*(b &1)-1)
return soft_bits>0
else:
r = self._deintl_depunct.load(soft_dec) r = self._deintl_depunct.load(soft_dec)
if r.shape[0] == 0: if r.shape[0] == 0:
return [] return []
@ -407,3 +472,6 @@ if __name__ == '__main__':
# print(QAM64['points'][i]) # print(QAM64['points'][i])
print([s.next(6) for _ in range(256)]) print([s.next(6) for _ in range(256)])
s = ScrambleDataP()
assert(np.all(s.get_seq()[0:20]==np.array([0,2,4,3,3,6,4,5,7,6,7,0,5,5,4,3,5,4,3,7], dtype=np.uint8)))