コード例 #1
0
ファイル: interfaces.py プロジェクト: maxbit89/pyadf435x
class BusPirate:
    """This interface communicates via serial port using the pyBusPirateLite
    module and translate the command in native SPI."""

    def __init__(self, device='/dev/ttyUSB0', baudrate=115200):
        """Initialize the interface for the Bus Pirate using "device"
        with the given "baudrate"."""
        from pyBusPirateLite.SPI import SPI

        self.spi = SPI(device, baudrate)

        # speed = 30kHz
        # polarity = idle low (default)
        # output clock edge = active to idle (default)
        # input sample phase = middle (default)
        # CS = /CS (default)
        # output type = normal

        self.spi.pins = SPI.PIN_POWER | SPI.PIN_CS | SPI.PIN_AUX
        self.spi.config = SPI.CFG_PUSH_PULL | SPI.CFG_CLK_EDGE
        self.spi.speed = '30kHz'

    def write_data(self, data):
        """Write a single integer value (4 bytes) into the SPI bus."""
        data = struct.pack('>I', data)
        logger.debug(['%02x' % d for d in data])
        self.spi.cs = True
        self.spi.transfer(data)
        self.spi.cs = False

    def set_regs(self, regs):
        for reg in regs:
            self.write_data(reg)
コード例 #2
0
    def Connect(self, force):
        self._spiDev = SPI(portname=self._spiDevPath, speed=int(self._uartSpeed),
                           timeout=float(self._timeout), connect=True)
        self._spiDev.pins = SPI.PIN_POWER | SPI.PIN_CS
        self._spiDev.config = SPI.CFG_PUSH_PULL | SPI.CFG_IDLE
        self._spiDev.spiSpeed = self._spiSpeed

        self.Connected = True
        self._probe(force)
コード例 #3
0
ファイル: interfaces.py プロジェクト: maxbit89/pyadf435x
    def __init__(self, device='/dev/ttyUSB0', baudrate=115200):
        """Initialize the interface for the Bus Pirate using "device"
        with the given "baudrate"."""
        from pyBusPirateLite.SPI import SPI

        self.spi = SPI(device, baudrate)

        # speed = 30kHz
        # polarity = idle low (default)
        # output clock edge = active to idle (default)
        # input sample phase = middle (default)
        # CS = /CS (default)
        # output type = normal

        self.spi.pins = SPI.PIN_POWER | SPI.PIN_CS | SPI.PIN_AUX
        self.spi.config = SPI.CFG_PUSH_PULL | SPI.CFG_CLK_EDGE
        self.spi.speed = '30kHz'
コード例 #4
0
class SpiDevice:
    # Public members
    Connected = False
    ManufacturerIdStr = ""
    DeviceIdStr = ""
    FrDevConst = ""
    # Flashrom constants
    _frTestedConst = ""
    _frManuConst = ""
    _frUnlockFunction = ""
    # UART device
    _spiDev = None
    # Connection strings
    _spiDevPath = ""
    _uartSpeed = ""
    _timeout = ""
    _spiSpeed = ""

    def Connect(self, force):
        self._spiDev = SPI(portname=self._spiDevPath, speed=int(self._uartSpeed),
                           timeout=float(self._timeout), connect=True)
        self._spiDev.pins = SPI.PIN_POWER | SPI.PIN_CS
        self._spiDev.config = SPI.CFG_PUSH_PULL | SPI.CFG_IDLE
        self._spiDev.spiSpeed = self._spiSpeed

        self.Connected = True
        self._probe(force)

    def Disconnect(self):
        self._spiDev.disconnect()
        self.Connected = False

    def _getSpiDeviceInfo(self):
        self._spiDev.cs = True
        ret = self._spiDev.transfer([0x9f, 0xFF, 0xFF, 0xFF])
        self._spiDev.cs = False
        return ret

    def _parseFrConstsByIdStr(self, force):
        # Find manufacturer in 'flashchips.h'
        f = open("flashrom/flashchips.h", "r")
        content = f.read()
        f.close()

        # Get manufacturer const
        pattern = re.compile(
            r"#define ([^/\t]*)_ID.*" + self.ManufacturerIdStr + ".*")
        result = pattern.search(content)

        if(result == None):
            if force == True:
                logging.warning("Manufacturer unrecognized by flashrom.")
                return
            else:
                raise Exception("Manufacturer unrecognized by flashrom.")

        self._frManuConst = result.group(1)

        # Get device const
        pattern = re.compile(
            r"#define (" + self._frManuConst + "[^/\t]+).*" + self.DeviceIdStr + ".*")
        result = pattern.search(content)

        if(result == None):
            if force == True:
                logging.warning("Device model unrecognized by flashrom.")
                return
            else:
                raise Exception("Device model unrecognized by flashrom.")

        self.FrDevConst = result.group(1)

        # Find device in 'flashchips.c'
        f = open("flashrom/flashchips.c", "r")
        content = f.read()
        f.close()

        contentLines = content.splitlines()
        foundDevice = False
        foundTested = False

        for idx, line in enumerate(contentLines):
            if foundDevice == False:
                if self.FrDevConst in line:
                    foundDevice = True
            if foundDevice == True:
                # Looking for testing constant x in '.tested = (x),'
                if ".tested" in line:
                    pattern = re.compile(r".*= (.*),")
                    result = pattern.search(line)
                    if(result == None):
                        raise Exception(
                            "Found device, but unexpected syntax encountered in parsing 'tested' member.")
                    else:
                        self._frTestedConst = result.group(1)
                        foundTested = True
                        break

        if foundDevice == False:
            raise Exception(
                "Mismatch between 'flashchips.h' and 'flashchips.c'.")
        if foundDevice == True and foundTested == False:
            raise Exception(
                "Found device, but could not find 'tested' constant.")

        # Get unlock function for device
        foundUnlock = False
        for i in range(idx, len(contentLines)):
            if ".unlock" in contentLines[i]:
                pattern = re.compile(r".*= (.*),")
                result = pattern.search(contentLines[i])
                if(result == None):
                    raise Exception(
                        "Found device, but unexpected syntax encountered in parsing 'unlock' member.")
                else:
                    self._frUnlockFunction = result.group(1)
                    foundUnlock = True
                    break

        if foundUnlock == False:
            raise Exception("No unlock method available for device.")

    def _getStatusReg(self):
        self._spiDev.cs = True
        ret = self._spiDev.transfer([0x05, 0xFF])
        self._spiDev.cs = False
        return list(ret)[1]

    def _bytesToInt(self, x, len):
        return int.from_bytes(x, byteorder='big', signed=False)

    # Get Status Register Protect
    def _getSrp(self):
        return (self._getStatusReg() >> 7 & 1)

    # Get Write Enable Latch
    def _getWel(self):
        return (self._getStatusReg() >> 1 & 1)

    # Change Write Enable
    def _changeWe(self, enableDisable):
        val = 0x06 if enableDisable == True else 0x04
        self._spiDev.cs = True
        self._spiDev.transfer([val])
        self._spiDev.cs = False
        return self._getWel()

    def _getBpStatus(self):
        status = self._getStatusReg()
        return (status >> 2 & 1) + (status >> 3 & 1) + (status >> 4 & 1)

    def _probe(self, force):
        try:
            assert self.Connected == True, "Not connected to SPI device."

            ret = self._bytesToInt(self._getSpiDeviceInfo(), 3)
            if(ret == 0xffffff or ret == 0x000000):
                raise Exception(
                    "Invalid return value. Either the SPI device is not connected or there was a bus collision.")

            retStr = hex(ret)
            self.ManufacturerIdStr = "0x" + retStr[4:6].upper()
            self.DeviceIdStr = "0x" + retStr[6:10].upper()

            self._parseFrConstsByIdStr(force)
            if self._frTestedConst != "TEST_OK_PREW":
                logging.warning(
                    "Enabling block protection for SPI device unsupported (flashrom status: '" + self._frTestedConst + "').")

            # TODO: Add support for additional methods
            if self._frUnlockFunction != "spi_disable_blockprotect":
                logging.warning("Flashrom lists an unknown unlock method (" +
                                self._frUnlockFunction + ") for this device.")

        except Exception as e:
            raise Exception("Cannot connect to SPI device:", e)

    def __init__(self, spiDevPath: str, uartSpeed: str, timeout: str, spiSpeed: str):
        self._spiDevPath = spiDevPath
        self._uartSpeed = uartSpeed
        self._timeout = timeout
        self._spiSpeed = spiSpeed

    def GetDeviceStatus(self):
        wel = self._getWel()
        srp = self._getSrp()
        bp = self._getBpStatus()
        welStr = "Enabled" if wel == 1 else "Disabled"
        srpStr = "Enabled" if srp == 1 else "Disabled"
        bpStr = "Enabled (" + str(bp) + ")" if bp > 0 else "Disabled"

        status = {"Status Register S0": hex(self._getStatusReg()),
                  "Write Enable Latch WEL": welStr,
                  "Status Register Protect SRP0": srpStr,
                  "Block Protection BPx": bpStr}
        return status

    def EnableBlockProtection(self, force):
        assert self.Connected == True, "Not connected to SPI device."

        if self._frUnlockFunction == "" or self._frUnlockFunction != "spi_disable_blockprotect":
            if force == True:
                logging.warning("Unsupported device. This action may fail.")
            else:
                raise Exception(
                    "Unsupported device. Cannot enable block protection.")

        val = self._getBpStatus()
        if val > 1 and val < 3:
            logging.warning("Some block protection has already been enabled.")
        elif val == 3:
            raise Exception("Block protection has already been enabled.")

        # Enable 'Write Enable'
        if self._getSrp() != 0x00:
            logging.warning(
                "WP pin control enabled. Make sure to de-assert WP pin, otherwise this action will fail.")
            logging.warning(
                "If successful, this action will disable WP pin control.")
        if(self._changeWe(True) != 1):
            raise Exception("Device does not allow changing status registers.")

        # Write Status Register to enable block protection
        self._spiDev.cs = True
        self._spiDev.transfer([0x01, 0x1E])
        self._spiDev.cs = False

        if self._getBpStatus() == 0:
            if(self._getSrp() == 1):
                raise Exception(
                    "Device does not allow changing status registers. Disable WP pin control (SRP) first.")
            else:
                raise Exception("Failed to enable block protection.")

        # Disable 'Write Enable'
        if(self._changeWe(False) != 0):
            raise Exception("Failed to disable Write Enable.")

    def DisableBlockProtection(self, force):
        assert self.Connected == True, "Not connected to SPI device."
        if self._frUnlockFunction == "" or self._frUnlockFunction != "spi_disable_blockprotect":
            if force == True:
                logging.warning("Unsupported device. This action may fail.")
            else:
                raise Exception(
                    "Unsupported device. Cannot disable block protection.")

        if self._getBpStatus() == 0:
            raise Exception(
                "Block protection has already been disabled.")

        # Enable 'Write Enable'
        if self._getSrp() != 0x00:
            logging.warning(
                "WP pin control enabled. Make sure to de-assert WP pin, otherwise this action will fail.")
            logging.warning(
                "If successful, this action will disable WP pin control.")
        if(self._changeWe(True) != 1):
            raise Exception("Device does not allow changing status registers.")

        # Write Status Register to disable block protection
        self._spiDev.cs = True
        self._spiDev.transfer([0x01, 0x00])
        self._spiDev.cs = False

        if self._getBpStatus() > 0:
            if(self._getSrp() == 1):
                raise Exception(
                    "Device does not allow changing status registers. Disable WP pin control (SRP) first.")
            else:
                raise Exception("Failed to disable block protection.")

        # Disable 'Write Enable'
        if(self._changeWe(False) != 0):
            raise Exception("Failed to disable Write Enable.")

    def EnableWpControl(self):
        assert self.Connected == True, "Not connected to SPI device."

        if self._getSrp() == 0x01:
            raise Exception(
                "Device already configured to enable WP pin control.")

        # Get current SR value
        sr = self._getStatusReg()

        # Enable 'Write Enable'
        if(self._changeWe(True) != 1):
            raise Exception("Device does not allow changing status registers.")

        # Write to Status Register to enable SRP
        val = sr | 1 << 7
        self._spiDev.cs = True
        self._spiDev.transfer([0x01, val])
        self._spiDev.cs = False

        if self._getSrp() != 0x01:
            if(self._getSrp() == 1):
                raise Exception(
                    "Device does not allow changing status registers. De-assert WP pin first.")
            else:
                raise Exception("Failed to enable WP pin control.")

        # Disable 'Write Enable'
        if(self._changeWe(False) != 0):
            raise Exception("Failed to disable Write Enable.")

    def DisableWpControl(self):
        assert self.Connected == True, "Not connected to SPI device."

        if self._getSrp() == 0x00:
            raise Exception(
                "Device already configured to disable WP pin control.")

        # Get current SR value
        sr = self._getStatusReg()

        # Enable 'Write Enable'
        if(self._changeWe(True) != 1):
            raise Exception(
                "Device does not allow changing status registers.")

        # Write to Status Register to disable SRP
        val = sr & ~(1 << 7)
        self._spiDev.cs = True
        self._spiDev.transfer([0x01, val])
        self._spiDev.cs = False

        if self._getSrp() != 0x00:
            if(self._getSrp() == 1):
                raise Exception(
                    "Device does not allow changing status registers. De-assert WP pin first.")
            else:
                raise Exception("Failed to disable WP pin control.")

        # Disable 'Write Enable'
        if(self._changeWe(False) != 0):
            raise Exception("Failed to disable Write Enable.")
コード例 #5
0
ファイル: test.py プロジェクト: JohnDMcMaster/pyBusPirate
(at your option) any later version.

pyBusPirate is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with pyBusPirate.  If not, see <http://www.gnu.org/licenses/>.
"""
import sys
from pyBusPirateLite.SPI import SPI
""" enter binary mode """
if __name__ is '__main__':
	f=open('/tmp/workfile', 'wb')
	spi = SPI("/dev/tty.usbserial-A7004qlY", 115200)
	print "Entering binmode: ",
	if spi.BBmode():
		print "OK."
	else:
		print "failed."
		sys.exit()

	print "Entering raw SPI mode: ",
	if spi.enter_SPI():
		print "OK."
	else:
		print "failed."
		sys.exit()
		
	print "Configuring SPI."
コード例 #6
0
ファイル: test_spi.py プロジェクト: jaseg/pyBusPirateLite
def test_connect():
    spi = SPI(connect=False)
    spi.connect()
    assert spi.portname != ''
    spi.hw_reset()
コード例 #7
0
ファイル: test_spi.py プロジェクト: jaseg/pyBusPirateLite
def test_init():
    spi = SPI(connect=False)
    assert spi.portname == ''
コード例 #8
0
ファイル: test_spi.py プロジェクト: jaseg/pyBusPirateLite
def test_modestring():
    spi = SPI()
    assert spi.modestring == 'SPI1'
    spi.hw_reset()
コード例 #9
0
ファイル: test_spi.py プロジェクト: jaseg/pyBusPirateLite
def test_connect_on_init():
    spi = SPI()
    assert spi.mode == 'spi'
    spi.hw_reset()
コード例 #10
0
ファイル: test_spi.py プロジェクト: jaseg/pyBusPirateLite
def test_enter():
    spi = SPI(connect=False)
    spi.connect()
    spi.enter()
    assert spi.mode == 'spi'
    spi.hw_reset()