|  | #!/usr/bin/env python3 | 
|  | # Copyright (c) 2020-2021 Project CHIP Authors | 
|  | # | 
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | # you may not use this file except in compliance with the License. | 
|  | # You may obtain a copy of the License at | 
|  | # | 
|  | # http://www.apache.org/licenses/LICENSE-2.0 | 
|  | # | 
|  | # Unless required by applicable law or agreed to in writing, software | 
|  | # distributed under the License is distributed on an "AS IS" BASIS, | 
|  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | # See the License for the specific language governing permissions and | 
|  | # limitations under the License. | 
|  | """Flash a QPG device on a DK board. | 
|  |  | 
|  | Currently only support CMSIS mBed Drag and Drop for public use. | 
|  |  | 
|  | usage: qpg_firmware_utils.py [-h] [--application FILE] [--drive DRIVE] | 
|  |  | 
|  | optional arguments: | 
|  | -h, --help            show this help message and exit | 
|  |  | 
|  | configuration: | 
|  | --verbose             Report more verbosely | 
|  | --drive               Connected mBed USB mount to copy to | 
|  |  | 
|  | operations: | 
|  | --application FILE    Flash an image through drag and drop | 
|  | """ | 
|  |  | 
|  | import os | 
|  | import shutil | 
|  | import sys | 
|  |  | 
|  | import firmware_utils | 
|  |  | 
|  | # Additional options that can be use to configure an `Flasher` | 
|  | # object (as dictionary keys) and/or passed as command line options. | 
|  | QPG_OPTIONS = { | 
|  | # Configuration options define properties used in flashing operations. | 
|  | 'configuration': { | 
|  | # Tool configuration options. | 
|  | 'drive': { | 
|  | 'help': 'Location of the mBed mount', | 
|  | 'default': '/mnt/e', | 
|  | 'alias': ['-d'], | 
|  | 'argparse': { | 
|  | 'metavar': 'FILE' | 
|  | }, | 
|  | }, | 
|  | }, | 
|  | } | 
|  |  | 
|  |  | 
|  | class Flasher(firmware_utils.Flasher): | 
|  | """Manage flashing.""" | 
|  |  | 
|  | def __init__(self, **options): | 
|  | super().__init__(platform='QPG', module=__name__, **options) | 
|  | self.define_options(QPG_OPTIONS) | 
|  |  | 
|  | def erase(self): | 
|  | """Not supported""" | 
|  | self.log(0, "Erase not supported") | 
|  | return self | 
|  |  | 
|  | def verify(self, image): | 
|  | """Not supported""" | 
|  | self.log(0, "Verify not supported") | 
|  | return self | 
|  |  | 
|  | def flash(self, image): | 
|  | """Flash image.""" | 
|  | self.log(1, "Copying to {} drive {}".format( | 
|  | image, self.option.drive or "None")) | 
|  | if not self.option.drive: | 
|  | self.log(0, "--drive or -d required for copy action") | 
|  | self.err = 1 | 
|  | return self | 
|  |  | 
|  | # Check for drive mount | 
|  | if not os.path.exists(self.option.drive): | 
|  | self.log(0, "Drive '{}' does not exist. Is the USB device mounted correctly ?".format( | 
|  | self.option.drive)) | 
|  | self.err = 2 | 
|  | return self | 
|  |  | 
|  | # Check for valid mBed device | 
|  | mbed_marker = os.path.join(self.option.drive, 'MBED.HTM') | 
|  | if not os.path.exists(mbed_marker): | 
|  | self.log(0, "Drive '{}' not a path to an MBED device".format( | 
|  | self.option.drive)) | 
|  | self.err = 3 | 
|  | return self | 
|  |  | 
|  | shutil.copyfile(image, os.path.join( | 
|  | self.option.drive, os.path.basename(image))) | 
|  | return self | 
|  |  | 
|  | def reset(self): | 
|  | """Not supported""" | 
|  | self.log(0, "Reset is triggered automatically after completion of mBed copy.") | 
|  | return self | 
|  |  | 
|  | def actions(self): | 
|  | """Perform actions on the device according to self.option.""" | 
|  | self.log(3, 'Options:', self.option) | 
|  |  | 
|  | if self.option.erase: | 
|  | if self.erase().err: | 
|  | return self | 
|  |  | 
|  | if self.option.application: | 
|  | application = self.option.application | 
|  | if self.flash(application).err: | 
|  | return self | 
|  | if self.option.verify_application: | 
|  | if self.verify(application).err: | 
|  | return self | 
|  | if self.option.reset is None: | 
|  | self.option.reset = True | 
|  |  | 
|  | if self.option.reset: | 
|  | if self.reset().err: | 
|  | return self | 
|  |  | 
|  | return self | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | sys.exit(Flasher().flash_command(sys.argv)) |