Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More TK280 work #1230

Merged
merged 7 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 82 additions & 44 deletions chirp/drivers/tk280.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,10 @@
char name[10]; // Channel name, 10 chars
lbcd rxfreq[4]; // rx freq
lbcd txfreq[4]; // tx freq
u8 rx_unkw; // unknown yet
u8 tx_unkw; // unknown yet
u8 unknown_rx:4,
rx_step:4; // rx tuning step
u8 unknown_tx:4,
tx_step:4;
ul16 rx_tone; // rx tone
ul16 tx_tone; // tx tone
u8 unknown23[5]; // unknown yet
Expand Down Expand Up @@ -666,8 +668,9 @@ def _open_radio(radio, status):
# after that we are ready to receive the radio image or to write to it
radio.pipe.write(b'O')

radio.metadata = {'tkx80_ver': ver.strip(b'\xFF'),
'tkx80_rid': rid.strip(b'\xFF')}
radio.metadata = {'tkx80_ver': ver.strip(b'\xFF').decode('ascii',
errors='ignore'),
'tkx80_rid': list(rid.strip(b'\xFF'))}


def exchange_ack(pipe):
Expand Down Expand Up @@ -808,7 +811,7 @@ def get_features(self):
rf.has_ctone = True
rf.has_cross = True
rf.valid_modes = MODES
rf.valid_duplexes = ["", "-", "+", "off"]
rf.valid_duplexes = ["", "-", "+", "off", "split"]
rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross']
rf.valid_cross_modes = [
"Tone->Tone",
Expand All @@ -829,6 +832,7 @@ def get_features(self):
rf.memory_bounds = (1, self._upper)
rf.has_sub_devices = True
rf.has_bank = False
rf.can_odd_split = True
return rf

def get_sub_devices(self):
Expand Down Expand Up @@ -868,6 +872,7 @@ def sync_out(self):

def process_mmap(self):
self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
self._compact_mappings()

def _decode_tone(self, val):
"""Parse the tone data to decode from mem, it returns:
Expand Down Expand Up @@ -927,15 +932,24 @@ def _get_memory_mapping(self, group, number, allocate=False):

Raise IndexError if not mapped.
"""
try:
return self._map_cache[(group, number)]
except KeyError:
if not allocate:
raise IndexError('Memory %i-%i not mapped' % (group, number))

LOG.debug('Cache miss for allocating %i,%i' % (group, number))
empty = None
free_memories = set(range(250))
this_group_index = None
# Count to 150 and...
# Count to 250 and...
for i in range(250):
# Look for an existing mapping for this group,number
mapping = self._memobj.group_mapping[i]
if mapping.group == group and mapping.number == number:
# Direct hit, return
# Direct hit, return it. But, we should have found this in the
# cache
LOG.warning('Found mapping for %i-%i but was not in cache?',
group, number)
return mapping
elif empty is None and mapping.group == 0xFF:
# Record the earliest-available mapping
Expand All @@ -950,30 +964,28 @@ def _get_memory_mapping(self, group, number, allocate=False):
if self._memobj.groups[i].number == group:
this_group_index = i

if allocate:
if this_group_index is None:
raise errors.RadioError(
'Allocate for group %i did not find a record' % group)
# Use the first available memory location
memory = list(sorted(free_memories))[0]
self._memobj.group_mapping[empty].group = group
self._memobj.group_mapping[empty].number = number
self._memobj.group_mapping[empty].group_index = this_group_index
self._memobj.group_mapping[empty].index = memory
self._memobj.groups[this_group_index].channels += 1
LOG.info(('Allocating slot %i memory %i for %i-%i '
'grp index %i channels %i') % (
empty, memory, group, number, this_group_index,
self._memobj.groups[this_group_index].channels))
self._compact_mappings()
# The above may have rearranged things so re-search for our
# new slot
return self._get_memory_mapping(group, number)
else:
raise IndexError('Memory %i-%i not mapped' % (group, number))
if this_group_index is None:
raise errors.RadioError(
'Allocate for group %i did not find a record' % group)
# Use the first available memory location
memory = list(sorted(free_memories))[0]
mapping = self._memobj.group_mapping[empty]
mapping.group = group
mapping.number = number
mapping.group_index = this_group_index
mapping.index = memory
self._memobj.groups[this_group_index].channels += 1
LOG.info(('Allocating slot %i memory %i for %i-%i '
'grp index %i channels %i') % (
empty, memory, group, number, this_group_index,
self._memobj.groups[this_group_index].channels))
self._compact_mappings()
# The above may have rearranged things so re-search for our
# new slot
return self._get_memory_mapping(group, number)

def _delete_memory_mapping(self, group, number):
mapping = self._get_memory_mapping(group, number)
mapping = self._parent._get_memory_mapping(group, number)
mem = self._memobj.memory[mapping.index]
group_rec = self._memobj.groups[mapping.group_index]
group_rec.channels -= 1
Expand Down Expand Up @@ -1004,6 +1016,7 @@ def _compact_mappings(self):

memories = 0
groups = set()
self._map_cache = {}
# Count to 250 again and...
for i in range(250):
# Update all the mappings with the new sorted survey results
Expand All @@ -1013,10 +1026,14 @@ def _compact_mappings(self):
groups.add(group)
except IndexError:
group = number = group_index = index = 0xFF
self._memobj.group_mapping[i].group = group
self._memobj.group_mapping[i].number = number
self._memobj.group_mapping[i].group_index = group_index
self._memobj.group_mapping[i].index = index
mapping = self._memobj.group_mapping[i]
mapping.group = group
mapping.number = number
mapping.group_index = group_index
mapping.index = index

# Rebuild our cache
self._map_cache[int(mapping.group), int(mapping.number)] = mapping

# Also update the groups with correct memory counts
group = int(self._memobj.groups[i].number)
Expand Down Expand Up @@ -1595,7 +1612,7 @@ def set_settings(self, settings):
class TKx80Group(KenwoodTKx80):
def __init__(self, parent, group, name):
self._parent = parent
self._group = group
self._group = int(group)
self.VARIANT = name
self.TYPE = parent.TYPE

Expand All @@ -1610,6 +1627,9 @@ def _memobj(self):
def load_mmap(self, filename):
self._parent.load_mmap(filename)

def _compact_mappings(self):
self._parent._compact_mappings()

def get_sub_devices(self):
return []

Expand All @@ -1623,7 +1643,7 @@ def get_raw_memory(self, number):
"""Return a raw representation of the memory object, which
is very helpful for development"""
try:
mapping = self._get_memory_mapping(self.group, number)
mapping = self._parent._get_memory_mapping(self.group, number)
except IndexError:
return 'Memory not set'
return repr(self._memobj.memory[mapping.index])
Expand All @@ -1632,7 +1652,7 @@ def get_memory(self, number):
mem = chirp_common.Memory()
mem.number = number
try:
mapping = self._get_memory_mapping(self.group, number)
mapping = self._parent._get_memory_mapping(self.group, number)
except IndexError:
mem.empty = True
return mem
Expand Down Expand Up @@ -1688,8 +1708,8 @@ def get_memory(self, number):

def set_memory(self, mem):
try:
mapping = self._get_memory_mapping(self.group, mem.number,
allocate=True)
mapping = self._parent._get_memory_mapping(self.group, mem.number,
allocate=True)
except IndexError as e:
# Out of memory
raise errors.RadioError(str(e))
Expand All @@ -1702,21 +1722,39 @@ def set_memory(self, mem):

_mem.rxfreq = mem.freq // 10

# this are a mistery yet, but so falr there is no impact
# whit this default values for new channels
if int(_mem.rx_unkw) == 0xff:
_mem.rx_unkw = 0x35
_mem.tx_unkw = 0x32
_mem.unknown_rx = 0x3
_mem.unknown_tx = 0x3

if mem.duplex == "+":
_mem.txfreq = (mem.freq + mem.offset) // 10
elif mem.duplex == "-":
_mem.txfreq = (mem.freq - mem.offset) // 10
elif mem.duplex == "off":
_mem.txfreq.fill_raw(b'\xFF')
elif mem.duplex == 'split':
_mem.txfreq = mem.offset // 10
else:
_mem.txfreq = mem.freq // 10

step_lookup = {
2.5: 0x0,
6.25: 0x2,
12.5: 0x5,
5.0: 0x1,
}
try:
_mem.rx_step = step_lookup[chirp_common.required_step(
int(_mem.rxfreq) * 10)]
except errors.InvalidDataError:
LOG.warning('Unknown step for rx freq, defaulting to 5kHz')
_mem.rx_step = 0x1
try:
_mem.tx_step = step_lookup[chirp_common.required_step(
int(_mem.txfreq) * 10)]
except errors.InvalidDataError:
LOG.warning('Unknown step for tx freq, defaulting to 5kHz')
_mem.tx_step = 0x1

((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \
chirp_common.split_tone_encode(mem)
self._encode_tone(_mem.tx_tone, txmode, txtone, txpol)
Expand Down
28 changes: 25 additions & 3 deletions chirp/drivers/tk8180.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@
u8 number;
lbcd rx_freq[4];
lbcd tx_freq[4];
u8 unknown1[2];
u8 unknown11:4,
rx_step:4;
u8 unknown12:4,
tx_step:4;
ul16 rx_tone;
ul16 tx_tone;
char name[12];
Expand Down Expand Up @@ -744,8 +747,8 @@ def set_memory(self, mem):
'memory allocation')

# Default values for unknown things
_mem.unknown1[0] = 0x36
_mem.unknown1[1] = 0x36
_mem.unknown11 = 0x3
_mem.unknown12 = 0x3
_mem.unknown2 = [0xFF for i in range(0, 19)]
_mem.unknown3_1 = 0xF
_mem.unknown3_2 = 0x1
Expand Down Expand Up @@ -787,6 +790,25 @@ def set_memory(self, mem):
else:
raise errors.RadioError('Unsupported duplex mode %r' % mem.duplex)

try:
tx_step = chirp_common.required_step(int(_mem.tx_freq) * 10)
except errors.InvalidDataError:
tx_step = 5
try:
rx_step = chirp_common.required_step(int(_mem.rx_freq) * 10)
except errors.InvalidDataError:
rx_step = 5

step_lookup = {
2.5: 0x1,
6.25: 0x3,
12.5: 0x3,
5: 0x2,
}
# Default to 5kHz if we don't know any better
_mem.rx_step = step_lookup.get(rx_step, 0x2)
_mem.tx_step = step_lookup.get(tx_step, 0x2)

skipbyte = self._memobj.skipflags[(mem.number - 1) // 8]
if mem.skip == 'S':
skipbyte |= (1 << (mem.number - 1) % 8)
Expand Down
Loading