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

Convert FT-8100 for chirp-next #790

Merged
merged 1 commit into from
Oct 21, 2023
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
68 changes: 34 additions & 34 deletions chirp/drivers/ft8100.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,27 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import logging
import time
import os

from chirp import chirp_common, directory, bitwise, errors
from chirp.drivers import yaesu_clone

TONES = chirp_common.OLD_TONES
LOG = logging.getLogger(__name__)

TONES = chirp_common.OLD_TONES
TMODES = ["", "Tone"]

MODES = ['FM', 'AM']

STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0]

DUPLEX = ["", "-", "+", "split"]

# "M" for masked memories, which are invisible until un-masked
SKIPS = ["", "S", "M"]

POWER_LEVELS_VHF = [chirp_common.PowerLevel("Low", watts=5),
chirp_common.PowerLevel("Mid", watts=20),
chirp_common.PowerLevel("High", watts=50)]

POWER_LEVELS_UHF = [chirp_common.PowerLevel("Low", watts=5),
chirp_common.PowerLevel("Mid", watts=20),
chirp_common.PowerLevel("High", watts=35)]

SPECIALS = {'1L': -1,
'1U': -2,
'2L': -3,
Expand Down Expand Up @@ -96,7 +90,7 @@ class FT8100Radio(yaesu_clone.YaesuCloneModeRadio):
@classmethod
def match_model(cls, data, path):
if (len(data) == cls._memsize and
data[1:10] == '\x01\x01\x07\x08\x02\x01\x01\x00\x01'):
data[1:10] == b'\x01\x01\x07\x08\x02\x01\x01\x00\x01'):
return True

return False
Expand All @@ -110,20 +104,31 @@ def get_features(self):
rf.has_bank = False
rf.has_name = False

rf.valid_tones = list(TONES)
rf.valid_modes = list(MODES)
rf.valid_tmodes = list(TMODES)
rf.valid_duplexes = list(DUPLEX)
# This is not actually implemented, so don't expose it
rf.valid_duplexes.remove('split')
rf.valid_power_levels = POWER_LEVELS_VHF
rf.has_sub_devices = self.VARIANT == ''

rf.valid_tuning_steps = list(STEPS)
# This is not implemented properly, so don't expose it
rf.valid_tuning_steps.remove(12.5)
rf.can_odd_split = False

rf.valid_bands = [(110000000, 550000000),
(750000000, 1300000000)]

rf.valid_skips = SKIPS
# This driver doesn't properly support the upper bound of 1300MHz
# so limit us to 999MHz
if self.VARIANT == 'VHF':
rf.valid_bands = [(110000000, 280000000)]
else:
rf.valid_bands = [(280000000, 550000000),
(750000000, 999000000)]

rf.can_odd_split = True
# This is not actually implemented, so don't expose it
# rf.valid_skips = SKIPS
rf.valid_skips = []

# TODO
# rf.valid_special_chans = SPECIALS.keys()
Expand All @@ -134,7 +139,7 @@ def get_features(self):

def sync_in(self):
super(FT8100Radio, self).sync_in()
self.pipe.write(chr(yaesu_clone.CMD_ACK))
self.pipe.write(bytes([yaesu_clone.CMD_ACK]))
self.pipe.read(1)

def sync_out(self):
Expand All @@ -147,8 +152,7 @@ def process_mmap(self):

mem_format = MEM_FORMAT.format(memories=self._memstart,
skips=self._skipstart,
enables=self._enablestart
)
enables=self._enablestart)

self._memobj = bitwise.parse(mem_format, self._mmap)

Expand All @@ -175,21 +179,20 @@ def get_memory(self, number):

if _mem.duplex == DUPLEX.index("split"):
tx_freq = int(_mem.offset) * 1000
print(self.VARIANT, number, tx_freq, mem.freq)
mem.offset = tx_freq - mem.freq
else:
mem.offset = int(_mem.offset) * 1000

if int(mem.freq / 100) == 4:
if mem.freq // 100 == 4:
mem.power = POWER_LEVELS_UHF[_mem.power]
else:
mem.power = POWER_LEVELS_VHF[_mem.power]

# M01 can't be disabled
if not self._memobj.enables[byte] & bit and number != 1:
mem.empty = True

print('R', self.VARIANT, number, _mem.baud9600)
elif number == 1:
mem.immutable = ['empty']

return mem

Expand All @@ -201,18 +204,17 @@ def set_memory(self, mem):

_mem = self._memobj.memory[mem.number - 1]

_mem.freq = int(mem.freq / 1000)
_mem.freq = mem.freq // 1000
_mem.tone = TONES.index(mem.rtone)
_mem.tone_enable = TMODES.index(mem.tmode)
_mem.am = MODES.index(mem.mode)
_mem.duplex = DUPLEX.index(mem.duplex)

if mem.duplex == "split":
tx_freq = mem.freq + mem.offset
_mem.split_high = tx_freq / 10000000
_mem.offset = (tx_freq % 10000000) / 1000
_mem.offset = (tx_freq % 10000000) // 1000
else:
_mem.offset = int(mem.offset / 1000)
_mem.offset = mem.offset // 1000

if mem.power:
_mem.power = POWER_LEVELS_VHF.index(mem.power)
Expand All @@ -226,7 +228,6 @@ def set_memory(self, mem):

# TODO expose these options
_mem.baud9600 = 0
_mem.am = 0

# These need to be cleared, otherwise strange things happen
_mem.unknown4 = 0
Expand All @@ -243,10 +244,10 @@ def _checksums(self):
def _bit_byte(self, number):
if self.VARIANT == 'VHF':
bit = 1 << ((number - 1) % 8)
byte = (number - 1) / 8
byte = (number - 1) // 8
else:
bit = 1 << ((number - 2) % 8)
byte = (number - 2) / 8
byte = (number - 2) // 8

return bit, byte

Expand Down Expand Up @@ -290,25 +291,24 @@ def _status():

pos = 0
for block in radio._block_lengths:
if os.getenv("CHIRP_DEBUG"):
print("\nSending %i-%i" % (pos, pos + block))
LOG.debug("\nSending %i-%i" % (pos, pos + block))
out = radio.get_mmap()[pos:pos + block]

# need to chew byte-by-byte here or else we lose the ACK...not sure why
for b in out:
pipe.write(b)
pipe.write(bytes([b]))
pipe.read(1) # chew the echo

ack = pipe.read(1)

if ack != chr(yaesu_clone.CMD_ACK):
if ack[0] != yaesu_clone.CMD_ACK:
raise Exception("block not ack'ed: %s" % repr(ack))

total_written += len(out)
_status()

pos += block

print("Clone completed in %i seconds" % (time.time() - start))
LOG.debug("Clone completed in %i seconds" % (time.time() - start))

return True
4 changes: 2 additions & 2 deletions tests/Python3_Driver_Testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@
| <a name="Yaesu_FT-70D"></a> Yaesu_FT-70D | [@n8sqt](https://github.com/n8sqt) | 05-Dec-2022 | Yes | 0.27% |
| <a name="Yaesu_FT-7100M"></a> Yaesu_FT-7100M | | | Yes | 0.03% |
| <a name="Yaesu_FT-7800_7900"></a> Yaesu_FT-7800_7900 | [@kk7ds](https://github.com/kk7ds) | 24-Oct-2022 | Yes | 0.14% |
| <a name="Yaesu_FT-8100"></a> Yaesu_FT-8100 | | | Yes | 0.01% |
| <a name="Yaesu_FT-8100"></a> Yaesu_FT-8100 | [Reported working](https://chirp.danplanet.com/issues/10904) | 19-Oct-2023 | Yes | 0.01% |
| <a name="Yaesu_FT-817"></a> Yaesu_FT-817 | [@kk7ds](https://github.com/kk7ds) | 14-Feb-2019 | Yes | 0.04% |
| <a name="Yaesu_FT-817ND"></a> Yaesu_FT-817ND | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.07% |
| <a name="Yaesu_FT-817ND_US"></a> Yaesu_FT-817ND_US | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.02% |
Expand Down Expand Up @@ -425,7 +425,7 @@

**Drivers:** 420

**Tested:** 87% (366/54) (93% of usage stats)
**Tested:** 87% (367/53) (93% of usage stats)

**Byte clean:** 90% (380/40)

Expand Down
Binary file added tests/images/Yaesu_FT-8100.img
Binary file not shown.
1 change: 1 addition & 0 deletions tests/py3_driver_testers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ Yaesu_FT-50,#10824,5-Sep-2023
Yaesu_FT-60,N0EYE,9-Jan-2023
Yaesu_FT-70D,@n8sqt,05-Dec-2022
Yaesu_FT-7800_7900,@kk7ds,24-Oct-2022
Yaesu_FT-8100,#10904,19-Oct-2023
Yaesu_FT-8800,@kk7ds,24-Oct-2022
Yaesu_FT-8900,#10753,30-Jul-2023
Yaesu_FT-817,@kk7ds,14-Feb-2019
Expand Down
Loading