51 |
51 |
bbcd dtcs_tx[2];
|
52 |
52 |
char name[9];
|
53 |
53 |
"""
|
|
54 |
|
|
55 |
MEM_IC7100_FORMAT = """
|
|
56 |
u8 bank; // 1 bank number
|
|
57 |
bbcd number[2]; // 2,3
|
|
58 |
u8 splitSelect; // 4 split and select memory settings
|
|
59 |
lbcd freq[5]; // 5-9 operating freq
|
|
60 |
u8 mode; // 10 operating mode
|
|
61 |
u8 filter; // 11 filter
|
|
62 |
u8 dataMode; // 12 data mode setting (on or off)
|
|
63 |
u8 duplex:4, // 13 duplex on/-/+
|
|
64 |
tmode:4; // 13 tone
|
|
65 |
u8 dsql:4, // 14 digital squelch
|
|
66 |
unknown1:4; // 14 zero
|
|
67 |
bbcd rtone[3]; // 15-17 repeater tone freq
|
|
68 |
bbcd ctone[3]; // 18-20 tone squelch setting
|
|
69 |
u8 dtcsPolarity; // 21 DTCS polarity
|
|
70 |
u8 unknown2:4, // 22 zero
|
|
71 |
firstDtcs:4; // 22 first digit of DTCS code
|
|
72 |
u8 secondDtcs:4, // 23 second digit DTCS
|
|
73 |
thirdDtcs:4; // 23 third digit DTCS
|
|
74 |
u8 digitalSquelch; // 24 Digital code squelch setting
|
|
75 |
u8 duplexOffset[3]; // 25-27 duplex offset freq
|
|
76 |
char destCall[8]; // 28-35 destination call sign
|
|
77 |
char accessRepeaterCall[8];// 36-43 access repeater call sign
|
|
78 |
char linkRepeaterCall[8]; // 44-51 gateway/link repeater call sign
|
|
79 |
bbcd duplexSettings[47]; // repeat of 5-51 for duplex
|
|
80 |
char name[16]; // 52-60 Name of station
|
|
81 |
"""
|
|
82 |
|
54 |
83 |
mem_duptone_format = """
|
55 |
84 |
bbcd number[2];
|
56 |
85 |
u8 unknown1;
|
... | ... | |
169 |
198 |
|
170 |
199 |
class BankMemFrame(MemFrame):
|
171 |
200 |
"""A memory frame for radios with multiple banks"""
|
|
201 |
FORMAT = MEM_IC7000_FORMAT
|
172 |
202 |
_bnk = 0
|
173 |
203 |
|
174 |
204 |
def set_location(self, loc, bank=1):
|
... | ... | |
185 |
215 |
|
186 |
216 |
def get_obj(self):
|
187 |
217 |
self._data = MemoryMap(str(self._data)) # Make sure we're assignable
|
188 |
|
return bitwise.parse(MEM_IC7000_FORMAT, self._data)
|
|
218 |
return bitwise.parse(self.FORMAT, self._data)
|
|
219 |
|
|
220 |
|
|
221 |
class IC7100MemFrame(BankMemFrame):
|
|
222 |
FORMAT = MEM_IC7100_FORMAT
|
189 |
223 |
|
190 |
224 |
|
191 |
225 |
class DupToneMemFrame(MemFrame):
|
... | ... | |
204 |
238 |
# complete list of modes from CI-V documentation
|
205 |
239 |
# each radio supports a subset
|
206 |
240 |
# WARNING: "S-AM" and "PSK" are not valid (yet) for chirp
|
207 |
|
_MODES = ["LSB", "USB", "AM", "CW", "RTTY",
|
208 |
|
"FM", "WFM", "CWR", "RTTYR", "S-AM", "PSK"]
|
|
241 |
_MODES = [
|
|
242 |
"LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CWR"
|
|
243 |
"RTTYR", "S-AM", "PSK", None, None, None, None, None,
|
|
244 |
None, None, None, None, None, None, None, None,
|
|
245 |
"DV",
|
|
246 |
]
|
209 |
247 |
|
210 |
248 |
def mem_to_ch_bnk(self, mem):
|
211 |
249 |
l, h = self._bank_index_bounds
|
... | ... | |
332 |
370 |
pass
|
333 |
371 |
|
334 |
372 |
mem.freq = int(memobj.freq)
|
335 |
|
mem.mode = self._MODES[memobj.mode]
|
|
373 |
try:
|
|
374 |
mem.mode = self._MODES[memobj.mode]
|
|
375 |
|
|
376 |
# We do not know what a variety of the positions between
|
|
377 |
# PSK and DV mean, so let's behave as if those values
|
|
378 |
# are not set to maintain consistency between known-unknown
|
|
379 |
# values and unknown-unknown ones.
|
|
380 |
if mem.mode is None:
|
|
381 |
raise IndexError(memobj.mode)
|
|
382 |
except IndexError:
|
|
383 |
LOG.error(
|
|
384 |
"Bank %s location %s is set for mode %s, but no known "
|
|
385 |
"mode matches that value.",
|
|
386 |
int(memobj.bank),
|
|
387 |
int(memobj.number),
|
|
388 |
repr(memobj.mode),
|
|
389 |
)
|
|
390 |
raise
|
336 |
391 |
|
337 |
392 |
if self._rf.has_name:
|
338 |
393 |
mem.name = str(memobj.name).rstrip()
|
... | ... | |
435 |
490 |
memobj.freq = int(mem.freq)
|
436 |
491 |
memobj.mode = self._MODES.index(mem.mode)
|
437 |
492 |
if self._rf.has_name:
|
438 |
|
memobj.name = mem.name.ljust(9)[:9]
|
|
493 |
name_length = len(memobj.name.get_value())
|
|
494 |
memobj.name = mem.name.ljust(name_length)[:name_length]
|
439 |
495 |
|
440 |
496 |
if self._rf.valid_tmodes:
|
441 |
497 |
memobj.tmode = self._rf.valid_tmodes.index(mem.tmode)
|
... | ... | |
541 |
597 |
|
542 |
598 |
|
543 |
599 |
@directory.register
|
|
600 |
class Icom7100Radio(IcomCIVRadio):
|
|
601 |
"""Icom IC-7100"""
|
|
602 |
MODEL = "IC-7100"
|
|
603 |
_model = "\x88"
|
|
604 |
_template = 102
|
|
605 |
|
|
606 |
_num_banks = 5
|
|
607 |
_bank_index_bounds = (1, 99)
|
|
608 |
_bank_class = icf.IcomBank
|
|
609 |
|
|
610 |
def _initialize(self):
|
|
611 |
self._classes["mem"] = IC7100MemFrame
|
|
612 |
self._rf.has_bank = True
|
|
613 |
self._rf.has_bank_index = False
|
|
614 |
self._rf.has_bank_names = False
|
|
615 |
self._rf.has_dtcs_polarity = False
|
|
616 |
self._rf.has_dtcs = False
|
|
617 |
self._rf.has_ctone = True
|
|
618 |
self._rf.has_offset = False
|
|
619 |
self._rf.has_name = True
|
|
620 |
self._rf.has_tuning_step = False
|
|
621 |
self._rf.valid_modes = [
|
|
622 |
"LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CWR", "RTTYR", "DV"
|
|
623 |
]
|
|
624 |
self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
|
|
625 |
self._rf.valid_duplexes = ["", "-", "+"]
|
|
626 |
self._rf.valid_bands = [(30000, 199999999), (400000000, 470000000)]
|
|
627 |
self._rf.valid_tuning_steps = []
|
|
628 |
self._rf.valid_skips = []
|
|
629 |
self._rf.valid_name_length = 16
|
|
630 |
self._rf.valid_characters = chirp_common.CHARSET_ASCII
|
|
631 |
self._rf.memory_bounds = (0, 99 * self._num_banks - 1)
|
|
632 |
|
|
633 |
|
|
634 |
@directory.register
|
544 |
635 |
class Icom746Radio(IcomCIVRadio):
|
545 |
636 |
"""Icom IC-746"""
|
546 |
637 |
MODEL = "746"
|
... | ... | |
571 |
662 |
|
572 |
663 |
CIV_MODELS = {
|
573 |
664 |
(0x76, 0xE0): Icom7200Radio,
|
|
665 |
(0x88, 0xE0): Icom7100Radio,
|
574 |
666 |
(0x70, 0xE0): Icom7000Radio,
|
575 |
667 |
(0x46, 0xE0): Icom746Radio,
|
576 |
668 |
}
|