1# Copyright (c) 2025 sensry.io
2# SPDX-License-Identifier: Apache-2.0
3
4'''Runner for Sensry SY1xx Soc Flashing Tool.'''
5
6import importlib.util
7
8from runners.core import RunnerCaps, ZephyrBinaryRunner
9
10
11class Sy1xxBinaryRunner(ZephyrBinaryRunner):
12    '''Runner front-end for Sensry SY1xx Soc'''
13
14    def __init__(self, cfg, dev_id=None):
15        super().__init__(cfg)
16        print(cfg)
17        self.bin_file = cfg.bin_file
18        self.dev_id = dev_id
19
20    @classmethod
21    def name(cls):
22        return 'sy1xx'
23
24    @classmethod
25    def capabilities(cls):
26        return RunnerCaps(commands={'flash'}, dev_id=True)
27
28    @classmethod
29    def do_add_parser(cls, parser):
30        parser.set_defaults(dev_id='/dev/ttyUSB0')
31
32    @classmethod
33    def dev_id_help(cls) -> str:
34        return 'Device identifier such as /dev/ttyUSB0'
35
36    @classmethod
37    def do_create(cls, cfg, args):
38        # make sure the ganymed tools are installed
39        if importlib.util.find_spec('ganymed') is None:
40            raise RuntimeError("ganymed not found; can be installed with 'pip install ganymed'")
41
42        if not hasattr(args, "dev_id") or args.dev_id is None:
43            raise RuntimeError("missing --dev-id argument, such as /dev/ttyUSB0")
44
45        return Sy1xxBinaryRunner(cfg, args.dev_id)
46
47    def do_run(self, command, **kwargs):
48        if command == 'flash':
49            self.flash(**kwargs)
50
51    def flash(self, **kwargs):
52        self.logger.info(f'Flashing file: {self.bin_file} to {self.dev_id}')
53
54        from ganymed.bootloader import Bootloader
55
56        # convert binary to application ganymed-image
57        application_gnm = Bootloader.convert_zephyr_bin(self.bin_file)
58
59        # create the loader
60        flash_loader = Bootloader()
61
62        # connect to serial
63        flash_loader.connect(self.dev_id)
64
65        # set the controller into bootloader mode
66        flash_loader.enter_loading_mode()
67
68        # clear the internal flash
69        flash_loader.clear_mram()
70
71        # write the new binary
72        flash_loader.write_image(application_gnm)
73
74        self.logger.info('Flashing SY1xx finished. You may reset the device.')
75