enable sig modes only when needed

This commit is contained in:
dj2ls 2022-10-10 09:00:45 +02:00
parent 101903b924
commit b0e3d2286e
2 changed files with 126 additions and 83 deletions

View file

@ -418,8 +418,8 @@ class DATA:
# ack_frame[1:4] = static.DXCALLSIGN_CRC
# ack_frame[4:7] = static.MYCALLSIGN_CRC
ack_frame[1:2] = self.session_id
ack_frame[7:8] = bytes([int(snr)])
ack_frame[8:9] = bytes([int(self.speed_level)])
ack_frame[2:3] = bytes([int(snr)])
ack_frame[3:4] = bytes([int(self.speed_level)])
# Transmit frame
self.enqueue_frame_for_tx(ack_frame)
@ -431,8 +431,8 @@ class DATA:
ack_frame[1:2] = self.session_id
# ack_frame[1:4] = static.DXCALLSIGN_CRC
# ack_frame[4:7] = static.MYCALLSIGN_CRC
ack_frame[7:8] = bytes([int(snr)])
ack_frame[8:9] = bytes([int(self.speed_level)])
# ack_frame[7:8] = bytes([int(snr)])
# ack_frame[8:9] = bytes([int(self.speed_level)])
# Transmit frame
self.enqueue_frame_for_tx(ack_frame, copies=3, repeat_delay=0)
@ -452,14 +452,14 @@ class DATA:
codec2.api.freedv_set_frames_per_burst(freedv, len(missing_frames))
# TODO: Trim `missing_frames` bytesarray to [7:13] (6) frames, if it's larger.
# TODO: Instead of using int we could use a binary flag
# then create a repeat frame
rpt_frame = bytearray(self.length_sig_frame)
rpt_frame[:1] = bytes([FR_TYPE.FR_REPEAT.value])
rpt_frame[1:2] = self.session_id
# rpt_frame[1:4] = static.DXCALLSIGN_CRC
# rpt_frame[4:7] = static.MYCALLSIGN_CRC
rpt_frame[7:13] = missing_frames
# rpt_frame[7:13] = missing_frames
self.log.info("[TNC] ARQ | RX | Requesting", frames=missing_frames)
# Transmit frame
@ -472,8 +472,8 @@ class DATA:
nack_frame[1:2] = self.session_id
# nack_frame[1:4] = static.DXCALLSIGN_CRC
# nack_frame[4:7] = static.MYCALLSIGN_CRC
nack_frame[7:8] = bytes([int(snr)])
nack_frame[8:9] = bytes([int(self.speed_level)])
nack_frame[2:3] = bytes([int(snr)])
nack_frame[3:4] = bytes([int(self.speed_level)])
# TRANSMIT NACK FRAME FOR BURST
self.enqueue_frame_for_tx(nack_frame)
@ -485,8 +485,8 @@ class DATA:
nack_frame[1:2] = self.session_id
# nack_frame[1:4] = static.DXCALLSIGN_CRC
# nack_frame[4:7] = static.MYCALLSIGN_CRC
nack_frame[7:8] = bytes([int(snr)])
nack_frame[8:9] = bytes([int(self.speed_level)])
nack_frame[2:3] = bytes([int(snr)])
nack_frame[3:4] = bytes([int(self.speed_level)])
# TRANSMIT NACK FRAME FOR BURST
self.enqueue_frame_for_tx(nack_frame)
@ -498,7 +498,7 @@ class DATA:
disconnection_frame[1:2] = self.session_id
# disconnection_frame[1:4] = static.DXCALLSIGN_CRC
# disconnection_frame[4:7] = static.MYCALLSIGN_CRC
disconnection_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign)
# TODO: Needed? disconnection_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign)
self.enqueue_frame_for_tx(disconnection_frame, copies=5, repeat_delay=0)
@ -553,7 +553,7 @@ class DATA:
# Append data to rx burst buffer
# [frame_type][n_frames_per_burst][CRC24][CRC24]
#static.RX_BURST_BUFFER[rx_n_frame_of_burst] = data_in[8:] # type: ignore
# static.RX_BURST_BUFFER[rx_n_frame_of_burst] = data_in[8:] # type: ignore
static.RX_BURST_BUFFER[rx_n_frame_of_burst] = data_in[3:] # type: ignore
self.log.debug("[TNC] static.RX_BURST_BUFFER", buffer=static.RX_BURST_BUFFER)
@ -635,7 +635,7 @@ class DATA:
static.ARQ_SPEED_LEVEL = self.speed_level
# Update modes we are listening to
self.set_listening_modes(self.mode_list[self.speed_level])
self.set_listening_modes(False, True, self.mode_list[self.speed_level])
# Create and send ACK frame
self.log.info("[TNC] ARQ | RX | SENDING ACK")
@ -838,6 +838,11 @@ class DATA:
"""
self.arq_file_transfer = True
# set signalling modes we want to listen to
# we are in an ongoing arq transmission, so we don't need sig0 actually
modem.RECEIVE_SIG0 = False
modem.RECEIVE_SIG1 = True
self.tx_n_retry_of_burst = 0 # retries we already sent data
# Maximum number of retries to send before declaring a frame is lost
@ -1143,8 +1148,8 @@ class DATA:
# Update data_channel timestamp
self.data_channel_last_received = int(time.time())
self.burst_ack_snr = int.from_bytes(bytes(data_in[7:8]), "big")
self.speed_level = int.from_bytes(bytes(data_in[8:9]), "big")
self.burst_ack_snr = int.from_bytes(bytes(data_in[2:3]), "big")
self.speed_level = int.from_bytes(bytes(data_in[3:4]), "big")
static.ARQ_SPEED_LEVEL = self.speed_level
self.log.debug(
@ -1747,7 +1752,7 @@ class DATA:
)
# Update modes we are listening to
self.set_listening_modes(self.mode_list[self.speed_level])
self.set_listening_modes(True, True, self.mode_list[self.speed_level])
helpers.add_to_heard_stations(
static.DXCALLSIGN,
@ -2417,6 +2422,8 @@ class DATA:
self.burst_ack_snr = 255
# reset modem receiving state to reduce cpu load
modem.RECEIVE_SIG0 = True
modem.RECEIVE_SIG1 = False
modem.RECEIVE_DATAC1 = False
modem.RECEIVE_DATAC3 = False
# modem.RECEIVE_FSK_LDPC_0 = False
@ -2457,15 +2464,20 @@ class DATA:
self.rpt_request_received = state
self.data_frame_ack_received = state
def set_listening_modes(self, mode: int) -> None:
def set_listening_modes(self, enable_sig0: bool, enable_sig1: bool, mode: int) -> None:
"""
Function for setting the data modes we are listening to for saving cpu power
Args:
enable_sig0:int: Enable/Disable signalling mode 0
enable_sig1:int: Enable/Disable signalling mode 1
mode:int: Codec2 mode to listen for
"""
# set modes we want to listen to
modem.RECEIVE_SIG0 = enable_sig0
modem.RECEIVE_SIG1 = enable_sig1
if mode == FREEDV_MODE.datac1.value:
modem.RECEIVE_DATAC1 = True
self.log.debug("[TNC] Changing listening data mode", mode="datac1")
@ -2530,7 +2542,7 @@ class DATA:
static.ARQ_SPEED_LEVEL = self.speed_level
# Update modes we are listening to
self.set_listening_modes(self.mode_list[self.speed_level])
self.set_listening_modes(True, True, self.mode_list[self.speed_level])
# Why not pass `snr` or `static.SNR`?
self.send_burst_nack_frame_watchdog(0)

View file

@ -32,6 +32,8 @@ TXCHANNEL = ""
static.TRANSMITTING = False
# Receive only specific modes to reduce CPU load
RECEIVE_SIG0 = False
RECEIVE_SIG1 = False
RECEIVE_DATAC1 = False
RECEIVE_DATAC3 = False
RECEIVE_FSK_LDPC_1 = False
@ -83,27 +85,38 @@ class RF:
# Open codec2 instances
# DATAC0
self.datac0_freedv, \
self.datac0_bytes_per_frame, \
self.datac0_bytes_out, \
self.datac0_buffer, \
self.datac0_nin = \
# SIGNALLING MODE 0 - Used for Connecting - Payload 14 Bytes
self.sig0_datac0_freedv, \
self.sig0_datac0_bytes_per_frame, \
self.sig0_datac0_bytes_out, \
self.sig0_datac0_buffer, \
self.sig0_datac0_nin = \
self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC0, None)
# DATAC0
# SIGNALLING MODE 1 - Used for ACK/NACK - Payload 5 Bytes
self.sig1_datac0_freedv, \
self.sig1_datac0_bytes_per_frame, \
self.sig1_datac0_bytes_out, \
self.sig1_datac0_buffer, \
self.sig1_datac0_nin = \
self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC0, None)
# DATAC1
self.datac1_freedv, \
self.datac1_bytes_per_frame, \
self.datac1_bytes_out, \
self.datac1_buffer, \
self.datac1_nin = \
self.dat0_datac1_freedv, \
self.dat0_datac1_bytes_per_frame, \
self.dat0_datac1_bytes_out, \
self.dat0_datac1_buffer, \
self.dat0_datac1_nin = \
self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC1, None)
# DATAC3
self.datac3_freedv, \
self.datac3_bytes_per_frame, \
self.datac3_bytes_out, \
self.datac3_buffer, \
self.datac3_nin = \
self.dat0_datac3_freedv, \
self.dat0_datac3_bytes_per_frame, \
self.dat0_datac3_bytes_out, \
self.dat0_datac3_buffer, \
self.dat0_datac3_nin = \
self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC3, None)
# FSK LDPC - 0
@ -215,20 +228,25 @@ class RF:
)
fft_thread.start()
audio_thread_datac0 = threading.Thread(
target=self.audio_datac0, name="AUDIO_THREAD DATAC0", daemon=True
audio_thread_sig0_datac0 = threading.Thread(
target=self.audio_sig0_datac0, name="AUDIO_THREAD DATAC0 - 0", daemon=True
)
audio_thread_datac0.start()
audio_thread_sig0_datac0.start()
audio_thread_datac1 = threading.Thread(
target=self.audio_datac1, name="AUDIO_THREAD DATAC1", daemon=True
audio_thread_sig1_datac0 = threading.Thread(
target=self.audio_sig1_datac0, name="AUDIO_THREAD DATAC0 - 1", daemon=True
)
audio_thread_datac1.start()
audio_thread_sig1_datac0.start()
audio_thread_datac3 = threading.Thread(
target=self.audio_datac3, name="AUDIO_THREAD DATAC3", daemon=True
audio_thread_dat0_datac1 = threading.Thread(
target=self.audio_dat0_datac1, name="AUDIO_THREAD DATAC1", daemon=True
)
audio_thread_datac3.start()
audio_thread_dat0_datac1.start()
audio_thread_dat0_datac3 = threading.Thread(
target=self.audio_dat0_datac3, name="AUDIO_THREAD DATAC3", daemon=True
)
audio_thread_dat0_datac3.start()
if static.ENABLE_FSK:
audio_thread_fsk_ldpc0 = threading.Thread(
@ -278,9 +296,10 @@ class RF:
length_x = len(x)
for data_buffer, receive in [
(self.datac0_buffer, True),
(self.datac1_buffer, RECEIVE_DATAC1),
(self.datac3_buffer, RECEIVE_DATAC3),
(self.sig0_datac0_buffer, RECEIVE_SIG0),
(self.sig1_datac0_buffer, RECEIVE_SIG1),
(self.dat0_datac1_buffer, RECEIVE_DATAC1),
(self.dat0_datac3_buffer, RECEIVE_DATAC3),
# Not enabled yet.
# (self.fsk_ldpc_buffer_0, static.ENABLE_FSK),
# (self.fsk_ldpc_buffer_1, static.ENABLE_FSK),
@ -334,11 +353,12 @@ class RF:
# Avoid buffer overflow by filling only if buffer for
# selected datachannel mode is not full
for audiobuffer, receive, index in [
(self.datac0_buffer, True, 0),
(self.datac1_buffer, RECEIVE_DATAC1, 1),
(self.datac3_buffer, RECEIVE_DATAC3, 2),
(self.fsk_ldpc_buffer_0, static.ENABLE_FSK, 3),
(self.fsk_ldpc_buffer_1, static.ENABLE_FSK, 4),
(self.sig0_datac0_buffer, True, 0),
(self.sig1_datac0_buffer, True, 1),
(self.dat0_datac1_buffer, RECEIVE_DATAC1, 2),
(self.dat0_datac3_buffer, RECEIVE_DATAC3, 3),
(self.fsk_ldpc_buffer_0, static.ENABLE_FSK, 4),
(self.fsk_ldpc_buffer_1, static.ENABLE_FSK, 5),
]:
if audiobuffer.nbuffer + length_x > audiobuffer.size:
static.BUFFER_OVERFLOW_COUNTER[index] += 1
@ -618,51 +638,62 @@ class RF:
nin = codec2.api.freedv_nin(c2instance)
# Additional Datac0-specific information - these are not referenced anywhere else.
# self.datac0_payload_per_frame = self.datac0_bytes_per_frame - 2
# self.datac0_n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(
# self.datac0_freedv
# self.sig0_datac0_payload_per_frame = self.sig0_datac0_bytes_per_frame - 2
# self.sig0_datac0_n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(
# self.sig0_datac0_freedv
# )
# self.datac0_n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(
# self.datac0_freedv
# self.sig0_datac0_n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(
# self.sig0_datac0_freedv
# )
# self.datac0_n_tx_preamble_modem_samples = (
# self.c_lib.freedv_get_n_tx_preamble_modem_samples(self.datac0_freedv)
# self.sig0_datac0_n_tx_preamble_modem_samples = (
# self.c_lib.freedv_get_n_tx_preamble_modem_samples(self.sig0_datac0_freedv)
# )
# self.datac0_n_tx_postamble_modem_samples = (
# self.c_lib.freedv_get_n_tx_postamble_modem_samples(self.datac0_freedv)
# self.sig0_datac0_n_tx_postamble_modem_samples = (
# self.c_lib.freedv_get_n_tx_postamble_modem_samples(self.sig0_datac0_freedv)
# )
# return values
return c2instance, bytes_per_frame, bytes_out, audio_buffer, nin
def audio_datac0(self) -> None:
"""Receive data encoded with datac0"""
self.datac0_nin = self.demodulate_audio(
self.datac0_buffer,
self.datac0_nin,
self.datac0_freedv,
self.datac0_bytes_out,
self.datac0_bytes_per_frame,
def audio_sig0_datac0(self) -> None:
"""Receive data encoded with datac0 - 0"""
self.sig0_datac0_nin = self.demodulate_audio(
self.sig0_datac0_buffer,
self.sig0_datac0_nin,
self.sig0_datac0_freedv,
self.sig0_datac0_bytes_out,
self.sig0_datac0_bytes_per_frame,
)
def audio_datac1(self) -> None:
def audio_sig1_datac0(self) -> None:
"""Receive data encoded with datac0 - 1"""
self.sig1_datac0_nin = self.demodulate_audio(
self.sig1_datac0_buffer,
self.sig1_datac0_nin,
self.sig1_datac0_freedv,
self.sig1_datac0_bytes_out,
self.sig1_datac0_bytes_per_frame,
)
def audio_dat0_datac1(self) -> None:
"""Receive data encoded with datac1"""
self.datac1_nin = self.demodulate_audio(
self.datac1_buffer,
self.datac1_nin,
self.datac1_freedv,
self.datac1_bytes_out,
self.datac1_bytes_per_frame,
self.dat0_datac1_nin = self.demodulate_audio(
self.dat0_datac1_buffer,
self.dat0_datac1_nin,
self.dat0_datac1_freedv,
self.dat0_datac1_bytes_out,
self.dat0_datac1_bytes_per_frame,
)
def audio_datac3(self) -> None:
def audio_dat0_datac3(self) -> None:
"""Receive data encoded with datac3"""
self.datac3_nin = self.demodulate_audio(
self.datac3_buffer,
self.datac3_nin,
self.datac3_freedv,
self.datac3_bytes_out,
self.datac3_bytes_per_frame,
self.dat0_datac3_nin = self.demodulate_audio(
self.dat0_datac3_buffer,
self.dat0_datac3_nin,
self.dat0_datac3_freedv,
self.dat0_datac3_bytes_out,
self.dat0_datac3_bytes_per_frame,
)
def audio_fsk_ldpc_0(self) -> None:
@ -883,8 +914,8 @@ class RF:
frames_per_burst = min(frames_per_burst, 1)
frames_per_burst = max(frames_per_burst, 5)
codec2.api.freedv_set_frames_per_burst(self.datac1_freedv, frames_per_burst)
codec2.api.freedv_set_frames_per_burst(self.datac3_freedv, frames_per_burst)
codec2.api.freedv_set_frames_per_burst(self.dat0_datac1_freedv, frames_per_burst)
codec2.api.freedv_set_frames_per_burst(self.dat0_datac3_freedv, frames_per_burst)
codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, frames_per_burst)