Пример #1
0
 def _load_resource(self, name):
     resource = None
     filepath = util.safe_join(util.get_folder('resources'), name + '.json')
     with open(filepath, 'r') as f:
         # Load the JSON file
         resource = json.loads(f.read())
     return resource
Пример #2
0
    def run(self, command, variables=[], board=None, packages=[]):
        """Executes scons for building"""

        # -- Check for the SConstruct file
        if not isfile(util.safe_join(util.get_project_dir(), 'SConstruct')):
            variables += ['-f']
            variables += [
                util.safe_join(util.get_folder('resources'), 'SConstruct')
            ]
        else:
            click.secho('Info: use custom SConstruct file')

        # -- Resolve packages
        if self.profile.check_exe_default():
            # Run on `default` config mode
            if not util.resolve_packages(
                    packages, self.profile.packages,
                    self.resources.distribution.get('packages')):
                # Exit if a package is not installed
                raise Exception
        else:
            click.secho('Info: native config mode')

        # -- Execute scons
        return self._execute_scons(command, variables, board)
Пример #3
0
 def _load_resource(self, name):
     resource = None
     filepath = util.safe_join(util.get_folder('resources'), name + '.json')
     with open(filepath, 'r') as f:
         # Load the JSON file
         resource = json.loads(f.read())
     return resource
Пример #4
0
    def create_sconstruct(self, project_dir='', sayyes=False):
        """Creates a default SConstruct file"""

        project_dir = util.check_dir(project_dir)

        sconstruct_name = 'SConstruct'
        sconstruct_path = util.safe_join(project_dir, sconstruct_name)
        local_sconstruct_path = util.safe_join(
            util.get_folder('resources'), sconstruct_name)

        if isfile(sconstruct_path):
            # -- If sayyes, skip the question
            if sayyes:
                self._copy_sconstruct_file(sconstruct_name, sconstruct_path,
                                           local_sconstruct_path)
            else:
                click.secho(
                    'Warning: {} file already exists'.format(sconstruct_name),
                    fg='yellow')

                if click.confirm('Do you want to replace it?'):
                    self._copy_sconstruct_file(sconstruct_name,
                                               sconstruct_path,
                                               local_sconstruct_path)
                else:
                    click.secho('Abort!', fg='red')

        else:
            self._copy_sconstruct_file(sconstruct_name, sconstruct_path,
                                       local_sconstruct_path)
Пример #5
0
    def run(self, command, variables=[], board=None, packages=[]):
        """Executes scons for building"""

        # -- Check for the SConstruct file
        if not isfile(util.safe_join(util.get_project_dir(), 'SConstruct')):
            variables += ['-f']
            variables += [util.safe_join(
                util.get_folder('resources'), 'SConstruct')]
        else:
            click.secho('Info: use custom SConstruct file')

        # -- Resolve packages
        if self.profile.check_exe_default():
            # Run on `default` config mode
            if not util.resolve_packages(
              packages,
              self.profile.packages,
              self.resources.distribution.get('packages')
             ):
                # Exit if a package is not installed
                raise Exception
        else:
            click.secho('Info: native config mode')

        # -- Execute scons
        return self._execute_scons(command, variables, board)
Пример #6
0
# -*- coding: utf-8 -*-
# -- This file is part of the Apio project
# -- (C) 2016-2019 FPGAwars
# -- Author Jesús Arroyo
# -- Licence GPLv2

import click

from os import listdir
from os.path import isfile
from sys import exit as sys_exit

from apio import util

commands_folder = util.get_folder('commands')


class ApioCLI(click.MultiCommand):
    def list_commands(self, ctx):
        rv = []
        for filename in listdir(commands_folder):
            if filename.startswith('__init__'):
                continue
            if filename.endswith('.py'):
                rv.append(filename[:-3])
        rv.sort()
        return rv

    def get_command(self, ctx, name):
        ns = {}
        fn = util.safe_join(commands_folder, name + '.py')
Пример #7
0
class Drivers(object):  # pragma: no cover

    rules_local_path = util.safe_join(util.get_folder('resources'),
                                      '80-icestick.rules')
    rules_system_path = '/etc/udev/rules.d/80-icestick.rules'

    # Driver to restore: mac os
    driverC = ''

    def enable(self):
        if 'linux' in platform:
            return self._enable_linux()
        elif 'darwin' in platform:
            self.profile = Profile()
            return self._enable_darwin()
        elif 'windows' in platform:
            return self._enable_windows()

    def disable(self):
        if 'linux' in platform:
            return self._disable_linux()
        elif 'darwin' in platform:
            self.profile = Profile()
            return self._disable_darwin()
        elif 'windows' in platform:
            return self._disable_windows()

    def pre_upload(self):
        if 'darwin' in platform:
            self._pre_upload_darwin()

    def post_upload(self):
        if 'darwin' in platform:
            self._post_upload_darwin()

    def _enable_linux(self):
        click.secho('Configure FTDI drivers for FPGA')
        if not isfile(self.rules_system_path):
            subprocess.call(
                ['sudo', 'cp', self.rules_local_path, self.rules_system_path])
            subprocess.call(['sudo', 'service', 'udev', 'restart'])
            # subprocess.call(['sudo', 'udevadm', 'control', '--reload-rules'])
            # subprocess.call(['sudo', 'udevadm', 'trigger'])
            click.secho('FPGA drivers enabled', fg='green')
            click.secho('Unplug and reconnect your board', fg='yellow')
        else:
            click.secho('Already enabled', fg='yellow')

    def _disable_linux(self):
        if isfile(self.rules_system_path):
            click.secho('Revert FTDI drivers\' configuration')
            subprocess.call(['sudo', 'rm', self.rules_system_path])
            subprocess.call(['sudo', 'service', 'udev', 'restart'])
            # subprocess.call(['sudo', 'udevadm', 'control', '--reload-rules'])
            # subprocess.call(['sudo', 'udevadm', 'trigger'])
            click.secho('FPGA drivers disabled', fg='green')
            click.secho('Unplug and reconnect your board', fg='yellow')
        else:
            click.secho('Already disabled', fg='yellow')

    def _enable_darwin(self):
        # Check homebrew
        brew = subprocess.call('which brew > /dev/null', shell=True)
        if brew != 0:
            click.secho('Error: homebrew is required', fg='red')
        else:
            click.secho('Enable FTDI drivers for FPGA')
            subprocess.call(['brew', 'update'])
            subprocess.call(['brew', 'install', '--force', 'libftdi'])
            subprocess.call(['brew', 'unlink', 'libftdi'])
            subprocess.call(['brew', 'link', '--force', 'libftdi'])
            subprocess.call(['brew', 'install', '--force', 'libffi'])
            subprocess.call(['brew', 'unlink', 'libffi'])
            subprocess.call(['brew', 'link', '--force', 'libffi'])
            self.profile.add_setting('macos_drivers', True)
            self.profile.save()
            click.secho('FPGA drivers enabled', fg='green')

    def _disable_darwin(self):
        click.secho('Disable FTDI drivers\' configuration')
        self.profile.add_setting('macos_drivers', False)
        self.profile.save()
        click.secho('FPGA drivers disabled', fg='green')

    def _pre_upload_darwin(self):
        if self.profile.settings.get('macos_drivers', False):
            # Check and unload the drivers
            driverA = 'com.FTDI.driver.FTDIUSBSerialDriver'
            driverB = 'com.apple.driver.AppleUSBFTDI'
            if self._check_driver_darwin(driverA):
                subprocess.call(['sudo', 'kextunload', '-b', driverA])
                self.driverC = driverA
            elif self._check_driver_darwin(driverB):
                subprocess.call(['sudo', 'kextunload', '-b', driverB])
                self.driverC = driverB

    def _post_upload_darwin(self):
        if self.profile.settings.get('macos_drivers', False):
            # Restore previous driver configuration
            if self.driverC:
                subprocess.call(['sudo', 'kextload', '-b', self.driverC])

    def _check_driver_darwin(self, driver):
        return driver in subprocess.check_output(['kextstat'])

    def _enable_windows(self):
        drivers_base_dir = util.get_package_dir('tools-drivers')
        drivers_bin_dir = util.safe_join(drivers_base_dir, 'bin')
        drivers_share_dir = util.safe_join(drivers_base_dir, 'share')
        zadig_ini_path = util.safe_join(drivers_share_dir, 'zadig.ini')
        zadig_ini = 'zadig.ini'

        try:
            if isdir(drivers_bin_dir):
                click.secho('Launch drivers configuration tool')
                click.secho(FTDI_INSTALL_DRIVER_INSTRUCTIONS, fg='yellow')
                # Copy zadig.ini
                with open(zadig_ini, 'w') as ini_file:
                    with open(zadig_ini_path, 'r') as local_ini_file:
                        ini_file.write(local_ini_file.read())

                result = util.exec_command(
                    util.safe_join(drivers_bin_dir, 'zadig.exe'))
                click.secho('FPGA drivers configuration finished', fg='green')
            else:
                util._check_package('drivers')
                result = 1
        except Exception as e:
            click.secho('Error: ' + str(e), fg='red')
            result = 1
        finally:
            # Remove zadig.ini
            if isfile(zadig_ini):
                os.remove(zadig_ini)

        if not isinstance(result, int):
            result = result['returncode']
        return result

    def _disable_windows(self):
        click.secho('Launch device manager')
        click.secho(FTDI_UNINSTALL_DRIVER_INSTRUCTIONS, fg='yellow')

        result = util.exec_command('mmc devmgmt.msc')
        return result['returncode']
Пример #8
0
    def run(self, command, variables=[], board=None, deps=[]):
        """Executes scons for building"""

        # -- Check for the SConstruct file
        if not isfile(util.safe_join(util.get_project_dir(), 'SConstruct')):
            click.secho('Info: default SConstruct file')
            variables += ['-f']
            variables += [
                util.safe_join(util.get_folder('resources'), 'SConstruct')
            ]

        # -- Resolve packages
        if self.profile.check_exe_default():
            # Run on `default` config mode
            if not util.resolve_packages(self.resources.packages, deps):
                # Exit if a package is not installed
                return 1
        else:
            click.secho('Info: native config mode')

        # -- Execute scons
        terminal_width, _ = click.get_terminal_size()
        start_time = time.time()

        if command == 'build' or \
           command == 'upload' or \
           command == 'time':
            if board:
                processing_board = board
            else:
                processing_board = 'custom board'
            click.echo('[%s] Processing %s' %
                       (datetime.datetime.now().strftime('%c'),
                        click.style(processing_board, fg='cyan', bold=True)))
            click.secho('-' * terminal_width, bold=True)

        if self.profile.get_verbose_mode() > 0:
            click.secho('Executing: scons -Q {0} {1}'.format(
                command, ' '.join(variables)))

        result = util.exec_command(util.scons_command + ['-Q', command] +
                                   variables,
                                   stdout=util.AsyncPipe(self._on_run_out),
                                   stderr=util.AsyncPipe(self._on_run_err))

        # -- Print result
        exit_code = result['returncode']
        is_error = exit_code != 0
        summary_text = ' Took %.2f seconds ' % (time.time() - start_time)
        half_line = '=' * int(((terminal_width - len(summary_text) - 10) / 2))
        click.echo('%s [%s]%s%s' %
                   (half_line,
                    (click.style(' ERROR ', fg='red', bold=True) if is_error
                     else click.style('SUCCESS', fg='green', bold=True)),
                    summary_text, half_line),
                   err=is_error)

        if False:
            if is_error:
                print("""
  ______                     _
 |  ____|                   | |
 | |__   _ __ _ __ ___  _ __| |
 |  __| | '__| '__/ _ \| '__| |
 | |____| |  | | | (_) | |  |_|
 |______|_|  |_|  \___/|_|  (_)
""")
            else:
                print("""
   _____                             _
  / ____|                           | |
 | (___  _   _  ___ ___ ___  ___ ___| |
  \___ \| | | |/ __/ __/ _ \/ __/ __| |
  ____) | |_| | (_| (_|  __/\__ \__ \_|
 |_____/ \__,_|\___\___\___||___/___(_)
""")

        return exit_code
Пример #9
0
# -*- coding: utf-8 -*-
# -- This file is part of the Apio project
# -- (C) 2016-2018 FPGAwars
# -- Author Jesús Arroyo
# -- Licence GPLv2

import click

from os import listdir
from os.path import isfile
from sys import exit as sys_exit

from apio import util

commands_folder = util.get_folder('commands')


class ApioCLI(click.MultiCommand):

    def list_commands(self, ctx):
        rv = []
        for filename in listdir(commands_folder):
            if filename.startswith('__init__'):
                continue
            if filename.endswith('.py'):
                rv.append(filename[:-3])
        rv.sort()
        return rv

    def get_command(self, ctx, name):
        ns = {}
Пример #10
0
class Drivers(object):  # pragma: no cover

    # FTDI rules files paths
    ftdi_rules_local_path = util.safe_join(
        util.get_folder('resources'), '80-fpga-ftdi.rules')
    ftdi_rules_system_path = '/etc/udev/rules.d/80-fpga-ftdi.rules'
    old_ftdi_rules_system_path = '/etc/udev/rules.d/80-icestick.rules'

    # Serial rules files paths
    serial_rules_local_path = util.safe_join(
        util.get_folder('resources'), '80-fpga-serial.rules')
    serial_rules_system_path = '/etc/udev/rules.d/80-fpga-serial.rules'

    # Driver to restore: mac os
    driverC = ''

    def ftdi_enable(self):
        if 'linux' in platform:
            return self._ftdi_enable_linux()
        elif 'darwin' in platform:
            self._setup_darwin()
            return self._ftdi_enable_darwin()
        elif 'windows' in platform:
            self._setup_windows()
            return self._ftdi_enable_windows()

    def ftdi_disable(self):
        if 'linux' in platform:
            return self._ftdi_disable_linux()
        elif 'darwin' in platform:
            self._setup_darwin()
            return self._ftdi_disable_darwin()
        elif 'windows' in platform:
            self._setup_windows()
            return self._ftdi_disable_windows()

    def serial_enable(self):
        if 'linux' in platform:
            return self._serial_enable_linux()
        elif 'darwin' in platform:
            self._setup_darwin()
            return self._serial_enable_darwin()
        elif 'windows' in platform:
            self._setup_windows()
            return self._serial_enable_windows()

    def serial_disable(self):
        if 'linux' in platform:
            return self._serial_disable_linux()
        elif 'darwin' in platform:
            self._setup_darwin()
            return self._serial_disable_darwin()
        elif 'windows' in platform:
            self._setup_windows()
            return self._serial_disable_windows()

    def pre_upload(self):
        if 'darwin' in platform:
            self._setup_darwin()
            self._pre_upload_darwin()

    def post_upload(self):
        if 'darwin' in platform:
            self._setup_darwin()
            self._post_upload_darwin()

    def _setup_darwin(self):
        self.profile = Profile()

    def _setup_windows(self):
        profile = Profile()
        resources = Resources()

        self.name = 'drivers'
        self.version = util.get_package_version(self.name, profile)
        self.spec_version = util.get_package_spec_version(self.name, resources)

    def _ftdi_enable_linux(self):
        click.secho('Configure FTDI drivers for FPGA')
        if not isfile(self.ftdi_rules_system_path):
            subprocess.call(['sudo', 'cp',
                             self.ftdi_rules_local_path,
                             self.ftdi_rules_system_path])
            self._reload_rules()
            click.secho('FTDI drivers enabled', fg='green')
            click.secho('Unplug and reconnect your board', fg='yellow')
        else:
            click.secho('Already enabled', fg='yellow')

    def _ftdi_disable_linux(self):
        if isfile(self.old_ftdi_rules_system_path):
            subprocess.call(['sudo', 'rm', self.old_ftdi_rules_system_path])
        if isfile(self.ftdi_rules_system_path):
            click.secho('Revert FTDI drivers configuration')
            subprocess.call(['sudo', 'rm', self.ftdi_rules_system_path])
            self._reload_rules()
            click.secho('FTDI drivers disabled', fg='green')
            click.secho('Unplug and reconnect your board', fg='yellow')
        else:
            click.secho('Already disabled', fg='yellow')

    def _serial_enable_linux(self):
        click.secho('Configure Serial drivers for FPGA')
        if not isfile(self.serial_rules_system_path):
            group_added = self._add_dialout_group()
            subprocess.call(['sudo', 'cp',
                            self.serial_rules_local_path,
                            self.serial_rules_system_path])
            self._reload_rules()
            click.secho('Serial drivers enabled', fg='green')
            click.secho('Unplug and reconnect your board', fg='yellow')
            if group_added:
                click.secho('Restart your machine to enable the dialout group',
                            fg='yellow')
        else:
            click.secho('Already enabled', fg='yellow')

    def _serial_disable_linux(self):
        if isfile(self.serial_rules_system_path):
            click.secho('Revert Serial drivers configuration')
            subprocess.call(['sudo', 'rm', self.serial_rules_system_path])
            self._reload_rules()
            click.secho('Serial drivers disabled', fg='green')
            click.secho('Unplug and reconnect your board', fg='yellow')
        else:
            click.secho('Already disabled', fg='yellow')

    def _reload_rules(self):
        subprocess.call(['sudo', 'udevadm', 'control', '--reload-rules'])
        subprocess.call(['sudo', 'udevadm', 'trigger'])
        subprocess.call(['sudo', 'service', 'udev', 'restart'])

    def _add_dialout_group(self):
        groups = subprocess.check_output('groups')
        if 'dialout' not in groups:
            subprocess.call('sudo usermod -a -G dialout $USER', shell=True)
            return True

    def _ftdi_enable_darwin(self):
        # Check homebrew
        brew = subprocess.call('which brew > /dev/null', shell=True)
        if brew != 0:
            click.secho('Error: homebrew is required', fg='red')
        else:
            click.secho('Enable FTDI drivers for FPGA')
            subprocess.call(['brew', 'update'])
            self._brew_install('libffi')
            self._brew_install('libftdi')
            self.profile.add_setting('macos_ftdi_drivers', True)
            self.profile.save()
            click.secho('FTDI drivers enabled', fg='green')

    def _ftdi_disable_darwin(self):
        click.secho('Disable FTDI drivers configuration')
        self.profile.add_setting('macos_ftdi_drivers', False)
        self.profile.save()
        click.secho('FTDI drivers disabled', fg='green')

    def _serial_enable_darwin(self):
        # Check homebrew
        brew = subprocess.call('which brew > /dev/null', shell=True)
        if brew != 0:
            click.secho('Error: homebrew is required', fg='red')
        else:
            click.secho('Enable Serial drivers for FPGA')
            subprocess.call(['brew', 'update'])
            self._brew_install('libffi')
            self._brew_install('libusb')
            # self._brew_install_serial_drivers()
            click.secho('Serial drivers enabled', fg='green')

    def _serial_disable_darwin(self):
        click.secho('Disable Serial drivers configuration')
        click.secho('Serial drivers disabled', fg='green')

    def _brew_install(self, package):
        subprocess.call(['brew', 'install', '--force', package])
        subprocess.call(['brew', 'unlink', package])
        subprocess.call(['brew', 'link', '--force', package])

    def _brew_install_serial_drivers(self):
        subprocess.call(
            ['brew', 'tap', 'mengbo/ch340g-ch34g-ch34x-mac-os-x-driver',
             'https://github.com/mengbo/ch340g-ch34g-ch34x-mac-os-x-driver'])
        subprocess.call(
            ['brew', 'cask', 'install', 'wch-ch34x-usb-serial-driver'])

    def _pre_upload_darwin(self):
        if self.profile.settings.get('macos_ftdi_drivers', False):
            # Check and unload the drivers
            driverA = 'com.FTDI.driver.FTDIUSBSerialDriver'
            driverB = 'com.apple.driver.AppleUSBFTDI'
            if self._check_ftdi_driver_darwin(driverA):
                subprocess.call(['sudo', 'kextunload', '-b', driverA])
                self.driverC = driverA
            elif self._check_ftdi_driver_darwin(driverB):
                subprocess.call(['sudo', 'kextunload', '-b', driverB])
                self.driverC = driverB

    def _post_upload_darwin(self):
        if self.profile.settings.get('macos_ftdi_drivers', False):
            # Restore previous driver configuration
            if self.driverC:
                subprocess.call(['sudo', 'kextload', '-b', self.driverC])

    def _check_ftdi_driver_darwin(self, driver):
        return driver in str(subprocess.check_output(['kextstat']))

    def _ftdi_enable_windows(self):
        drivers_base_dir = util.get_package_dir('tools-drivers')
        drivers_bin_dir = util.safe_join(drivers_base_dir, 'bin')
        drivers_share_dir = util.safe_join(drivers_base_dir, 'share')
        zadig_ini_path = util.safe_join(drivers_share_dir, 'zadig.ini')
        zadig_ini = 'zadig.ini'

        try:
            if util.check_package(
                self.name,
                self.version,
                self.spec_version,
                drivers_bin_dir
            ):
                click.secho('Launch drivers configuration tool')
                click.secho(FTDI_INSTALL_DRIVER_INSTRUCTIONS, fg='yellow')
                # Copy zadig.ini
                with open(zadig_ini, 'w') as ini_file:
                    with open(zadig_ini_path, 'r') as local_ini_file:
                        ini_file.write(local_ini_file.read())

                result = util.exec_command(
                    util.safe_join(drivers_bin_dir, 'zadig.exe'))
                click.secho('FTDI drivers configuration finished',
                            fg='green')
            else:
                result = 1
        except Exception as e:
            click.secho('Error: ' + str(e), fg='red')
            result = 1
        finally:
            # Remove zadig.ini
            if isfile(zadig_ini):
                os.remove(zadig_ini)

        if not isinstance(result, int):
            result = result.get('returncode')
        return result

    def _ftdi_disable_windows(self):
        click.secho('Launch device manager')
        click.secho(FTDI_UNINSTALL_DRIVER_INSTRUCTIONS, fg='yellow')

        result = util.exec_command('mmc devmgmt.msc')
        return result.get('returncode')

    def _serial_enable_windows(self):
        drivers_base_dir = util.get_package_dir('tools-drivers')
        drivers_bin_dir = util.safe_join(drivers_base_dir, 'bin')

        try:
            if util.check_package(
                self.name,
                self.version,
                self.spec_version,
                drivers_bin_dir
            ):
                click.secho('Launch drivers configuration tool')
                click.secho(SERIAL_INSTALL_DRIVER_INSTRUCTIONS, fg='yellow')
                result = util.exec_command(
                    util.safe_join(drivers_bin_dir, 'serial_install.exe'))
                click.secho('Serial drivers configuration finished',
                            fg='green')
            else:
                result = 1
        except Exception as e:
            click.secho('Error: ' + str(e), fg='red')
            result = 1

        if not isinstance(result, int):
            result = result.get('returncode')
        return result

    def _serial_disable_windows(self):
        click.secho('Launch device manager')
        click.secho(SERIAL_UNINSTALL_DRIVER_INSTRUCTIONS, fg='yellow')

        result = util.exec_command('mmc devmgmt.msc')
        return result.get('returncode')