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:
parent
7f706f6134
commit
91a06406fe
|
@ -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)))
|
||||||
|
|
Loading…
Reference in a new issue