mirror of
https://github.com/wagiminator/ATtiny814-USB-PD-Adapter.git
synced 2025-08-08 12:50:58 +03:00
131 lines
5.2 KiB
Python
131 lines
5.2 KiB
Python
"""
|
|
NVM layer protocols
|
|
"""
|
|
# Python 3 compatibility for Python 2
|
|
from __future__ import print_function
|
|
from logging import getLogger
|
|
|
|
from .deviceinfo.deviceinfokeys import DeviceInfoKeys
|
|
|
|
def get_nvm_access_provider(transport, device_info, interface="", packpath=None, frequency=None, options=""):
|
|
"""
|
|
Returns an NVM provider with the requested properties
|
|
|
|
:param transport: transport layer object
|
|
:param device_info: device info dict
|
|
:param interface: physical interface for NVM
|
|
:param packpath: path to pack
|
|
:param frequency: interface clock
|
|
:param options: special options
|
|
:return: NVM access object
|
|
"""
|
|
# Although it is considered best practice to have imports at top level, in this case it makes sense to have the
|
|
# imports on the function level as in most cases only one import will be used. Having all imports at the top
|
|
# level will then be a waste of resources.
|
|
#pylint: disable=import-outside-toplevel
|
|
# There will be cyclic imports since the modules imported below containing NVM Access providers will import
|
|
# from the current module since all NVM Access providers inherits from the NVM Access provider base classes
|
|
# defined in the current module, but this should be ok since the imports below are late.
|
|
#pylint: disable=cyclic-import
|
|
accessprovider = None
|
|
architecture = device_info[DeviceInfoKeys.ARCHITECTURE].lower()
|
|
if DeviceInfoKeys.INTERFACE in device_info:
|
|
interface = device_info[DeviceInfoKeys.INTERFACE].lower()
|
|
|
|
if architecture in ['pic16', 'pic18', 'pic24']:
|
|
from .nvmpic import NvmAccessProviderCmsisDapPic
|
|
accessprovider = NvmAccessProviderCmsisDapPic(transport, device_info, packpath, options=options)
|
|
elif architecture == 'avr8x':
|
|
if isinstance(transport, str):
|
|
if interface == 'updi':
|
|
from .nvmserialupdi import NvmAccessProviderSerial
|
|
accessprovider = NvmAccessProviderSerial(transport, device_info, baud=frequency)
|
|
elif interface == 'updi':
|
|
from .nvmupdi import NvmAccessProviderCmsisDapUpdi
|
|
accessprovider = NvmAccessProviderCmsisDapUpdi(transport, device_info=device_info,
|
|
frequency=frequency, options=options)
|
|
elif architecture == 'avr8':
|
|
if interface == 'isp':
|
|
if interface == "debugwire":
|
|
from .nvmdebugwire import NvmAccessProviderCmsisDapDebugwire
|
|
accessprovider = NvmAccessProviderCmsisDapDebugwire(transport, device_info)
|
|
else:
|
|
from .nvmspi import NvmAccessProviderCmsisDapSpi
|
|
accessprovider = NvmAccessProviderCmsisDapSpi(transport, device_info)
|
|
elif architecture == 'cortex-m0plus':
|
|
from .nvmmzeroplus import NvmAccessProviderCmsisDapMZeroPlus
|
|
accessprovider = NvmAccessProviderCmsisDapMZeroPlus(transport, device_info, frequency)
|
|
elif architecture == 'avr32':
|
|
from .nvmavr32 import NvmAccessProviderCmsisDapAvr32
|
|
accessprovider = NvmAccessProviderCmsisDapAvr32(transport, device_info)
|
|
|
|
return accessprovider
|
|
|
|
class NvmAccessProvider:
|
|
"""
|
|
Wrapper for device info
|
|
"""
|
|
|
|
def __init__(self, device_info):
|
|
self.device_info = device_info
|
|
self.logger = getLogger(__name__)
|
|
|
|
def _log_incomplete_stack(self, device_stack):
|
|
"""
|
|
Used to tell the user this device stack is not completed yet
|
|
|
|
:param device_stack: User friendly name of target stack
|
|
"""
|
|
self.logger.warning("")
|
|
self.logger.warning("%s stack is in Alpha state", device_stack)
|
|
self.logger.warning("Expect some features to be missing")
|
|
self.logger.warning("")
|
|
|
|
def start(self, user_interaction_callback=None):
|
|
"""
|
|
Start (activate) session
|
|
|
|
:param user_interaction_callback: Callback to be called when user interaction is required,
|
|
for example when doing UPDI high-voltage activation with user target power toggle.
|
|
This function could ask the user to toggle power and halt execution waiting for the user
|
|
to respond (this is default behavior if the callback is None), or if the user is another
|
|
script it could toggle power automatically and then return.
|
|
"""
|
|
#pylint: disable=unused-argument
|
|
self.logger.info("No specific initializer for this provider")
|
|
|
|
def stop(self):
|
|
"""
|
|
Stop (deactivate) session
|
|
"""
|
|
self.logger.info("No specific de-initializer for this provider")
|
|
|
|
def hold_in_reset(self):
|
|
"""
|
|
Hold target in reset
|
|
"""
|
|
self.logger.info("hold_in_reset not implemented for this provider")
|
|
|
|
def release_from_reset(self):
|
|
"""
|
|
Release target from reset
|
|
"""
|
|
self.logger.info("release_from_reset not implemented for this provider")
|
|
|
|
class NvmAccessProviderCmsisDapTool(NvmAccessProvider):
|
|
"""
|
|
General CMSIS-DAP Tool
|
|
"""
|
|
|
|
def __init__(self, device_info):
|
|
NvmAccessProvider.__init__(self, device_info)
|
|
|
|
|
|
class NvmAccessProviderCmsisDapAvr(NvmAccessProviderCmsisDapTool):
|
|
"""
|
|
AVR CMSIS DAP Tool
|
|
"""
|
|
|
|
def __init__(self, device_info):
|
|
NvmAccessProviderCmsisDapTool.__init__(self, device_info)
|