Commit 57c49c47 authored by Juergen Hasch's avatar Juergen Hasch Committed by GitHub

Merge pull request #5 from juhasch/feature/update

Fix autodetect and tests
parents 57dcc05b ad9c0a1b
# pyBusPirateLite # pyBusPirateLite
Python library for BusPirate based on code from Garrett Berg. It tries to be more Pythonic than the original code. Python library for BusPirate based on code from Garrett Berg.
It tries to be more Pythonic than the original code.
This library allows using the following modes: This library allows using the following modes:
* SPI * SPI
...@@ -31,8 +32,24 @@ Based on code from Garrett Berg <cloudform511@gmail.com> ...@@ -31,8 +32,24 @@ Based on code from Garrett Berg <cloudform511@gmail.com>
data = spi.transfer( [0x82, 0x00]) data = spi.transfer( [0x82, 0x00])
spi.cs = False spi.cs = False
### I2C ![SPI example](spi-example.png)
### Bitbang
from pyBusPirateLite.BitBang import BitBang
bb = BitBang()
bb.outputs = PIN_AUX
bb.pins = 0 # set aux pin = 0
bb.pins = PIN_AUX # set aux pin = 1
### Automatically detect port
from pyBusPirateLite.BitBang import BitBang
bb = BitBang(connect=False)
port = bb.get_port()
print(port)
### I2C
from pyBusPirateLite.SPI import * from pyBusPirateLite.SPI import *
i2c = I2C() i2c = I2C()
......
...@@ -55,7 +55,7 @@ class BBIO_base: ...@@ -55,7 +55,7 @@ class BBIO_base:
_attempts_ = 0 # global stored for use in enter _attempts_ = 0 # global stored for use in enter
def enter(self): def enter_bb(self):
"""Enter bitbang mode """Enter bitbang mode
This is the be-all-end-all restart function. It will keep trying This is the be-all-end-all restart function. It will keep trying
...@@ -78,13 +78,10 @@ class BBIO_base: ...@@ -78,13 +78,10 @@ class BBIO_base:
IOError IOError
If device is not connected If device is not connected
""" """
if self.mode == 'bb':
return
if self.connected is not True: if self.connected is not True:
raise IOError('Device not connected') raise IOError('Device not connected')
self.timeout(self.minDelay * 10) self.timeout(self.minDelay * 10)
self.port.flushInput() self.port.flushInput()
for i in range(10): for i in range(10):
self.write(0x00) self.write(0x00)
r = self.response(1, True) r = self.response(1, True)
...@@ -99,7 +96,6 @@ class BBIO_base: ...@@ -99,7 +96,6 @@ class BBIO_base:
resp = self.response(200) resp = self.response(200)
self.write(0x00) self.write(0x00)
resp = self.response(5) resp = self.response(5)
# print('RESP:', resp)
if resp == "BBIO1": if resp == "BBIO1":
self.mode = 'bb' self.mode = 'bb'
self.bp_config = 0x00 # configuration bits determine action of power sources and pullups self.bp_config = 0x00 # configuration bits determine action of power sources and pullups
...@@ -109,6 +105,13 @@ class BBIO_base: ...@@ -109,6 +105,13 @@ class BBIO_base:
return True return True
raise BPError('Could not enter bitbang mode') raise BPError('Could not enter bitbang mode')
def enter(self):
"""Enter bitbang mode
Will be overriden by other classes
"""
if self.mode == 'bb':
return
return self.enter_bb()
def hw_reset(self): def hw_reset(self):
"""Reset Bus Pirate """Reset Bus Pirate
...@@ -117,11 +120,41 @@ class BBIO_base: ...@@ -117,11 +120,41 @@ class BBIO_base:
The hardware and firmware version is printed (same as the 'i' command in the terminal), The hardware and firmware version is printed (same as the 'i' command in the terminal),
and the Bus Pirate returns to the user terminal interface. Send 0x00 20 times to enter binary mode again. and the Bus Pirate returns to the user terminal interface. Send 0x00 20 times to enter binary mode again.
""" """
if self.mode != 'bb':
self.enter_bb()
self.write(0x0f) self.write(0x0f)
self.port.flushInput() self.port.flushInput()
self.timeout(.1) self.timeout(.1)
self.mode = None self.mode = None
def get_port(self):
"""Detect Buspirate and return first detected port
Returns
-------
str
First valid portname
"""
try:
import serial.tools.list_ports as list_ports
except ImportError:
raise ImportError('Pyserial version with serial.tools.list_port required')
import serial
# the API in version 2 and 3 is different
if serial.VERSION[0] == '2':
ports = list_ports.comports()
for port in ports:
if len(port) == 3 and '0403:6001' in port[2]:
return port[0]
else:
ports = list_ports.comports()
for port in ports:
if hasattr(port, 'pid') and hasattr(port, 'vid'):
if port.vid == 1027 and port.pid == 24577:
return port.name
def connect(self, portname='', speed=115200, timeout=0.1): def connect(self, portname='', speed=115200, timeout=0.1):
""" will try to automatically find a port regardless of os """ will try to automatically find a port regardless of os
...@@ -142,18 +175,9 @@ class BBIO_base: ...@@ -142,18 +175,9 @@ class BBIO_base:
If device could not be opened If device could not be opened
""" """
try:
import serial.tools.list_ports as list_ports
except ImportError:
raise ImportError('Pyserial version with serial.tools.list_port required (> 3.0')
if portname == '': if portname == '':
ports = list_ports.comports() portname = self.get_port()
for port in ports:
if hasattr(port, 'pid') and hasattr(port, 'vid'):
if port.vid == 1027 and port.pid == 24577:
portname = port.device
break
self.portname = portname self.portname = portname
try: try:
self.port = serial.Serial(portname, speed, timeout=timeout) self.port = serial.Serial(portname, speed, timeout=timeout)
...@@ -171,7 +195,6 @@ class BBIO_base: ...@@ -171,7 +195,6 @@ class BBIO_base:
sleep(timeout) sleep(timeout)
def write(self, value): def write(self, value):
# print('val %s' % value.to_bytes(1, 'big'))
self.port.write(value.to_bytes(1, 'big')) self.port.write(value.to_bytes(1, 'big'))
def response(self, byte_count=1, binary=False): def response(self, byte_count=1, binary=False):
......
...@@ -26,7 +26,7 @@ import serial ...@@ -26,7 +26,7 @@ import serial
from .BBIO_base import BBIO_base, BPError, ProtocolError from .BBIO_base import BBIO_base, BPError, ProtocolError
class BitBang(BBIO_base): class BitBang(BBIO_base):
def __init__(self, portname='', speed=115200, timeout=1, connect=True): def __init__(self, portname='', speed=115200, timeout=0.1, connect=True):
""" Provide access to the Bus Pirate bitbang mode """ Provide access to the Bus Pirate bitbang mode
Parameters Parameters
...@@ -37,6 +37,8 @@ class BitBang(BBIO_base): ...@@ -37,6 +37,8 @@ class BitBang(BBIO_base):
Communication speed, use default of 115200 Communication speed, use default of 115200
timeout : int timeout : int
Timeout in s to wait for reply Timeout in s to wait for reply
connect : bool
Automatically connect to BusPirate (default)
Example Example
------- -------
......
...@@ -35,7 +35,7 @@ pin_mapping = {'AUX': 0b10, ...@@ -35,7 +35,7 @@ pin_mapping = {'AUX': 0b10,
class I2C(BBIO_base): class I2C(BBIO_base):
def __init__(self, portname='', speed=115200, timeout=1, connect=True): def __init__(self, portname='', speed=115200, timeout=0.1, connect=True):
""" Provide access to the Bus Pirate I2C interface """ Provide access to the Bus Pirate I2C interface
Parameters Parameters
...@@ -71,6 +71,8 @@ class I2C(BBIO_base): ...@@ -71,6 +71,8 @@ class I2C(BBIO_base):
""" """
if self.mode == 'i2c': if self.mode == 'i2c':
return return
if self.mode != 'bb':
super(I2C, self).enter()
self.write(0x02) self.write(0x02)
self.timeout(self.minDelay * 10) self.timeout(self.minDelay * 10)
if self.response(4) == "I2C1": if self.response(4) == "I2C1":
......
...@@ -60,6 +60,8 @@ class SPI(BBIO_base): ...@@ -60,6 +60,8 @@ class SPI(BBIO_base):
Communication speed, use default of 115200 Communication speed, use default of 115200
timeout : int timeout : int
Timeout in s to wait for reply Timeout in s to wait for reply
connect : bool
Automatically connect to BusPirate (default)
Example Example
------- -------
......
...@@ -49,7 +49,7 @@ class UARTSpeed: ...@@ -49,7 +49,7 @@ class UARTSpeed:
class UART(BBIO_base): class UART(BBIO_base):
def __init__(self, portname='', speed=115200, timeout=1): def __init__(self, portname='', speed=115200, timeout=0.1, connect=True):
""" Provide the Bus Pirate UART interface """ Provide the Bus Pirate UART interface
Parameters Parameters
...@@ -60,14 +60,17 @@ class UART(BBIO_base): ...@@ -60,14 +60,17 @@ class UART(BBIO_base):
Communication speed, use default of 115200 Communication speed, use default of 115200
timeout : int timeout : int
Timeout in s to wait for reply Timeout in s to wait for reply
connect : bool
Automatically connect to BusPirate (default)
Example Example
------- -------
>>> spi = UART() >>> spi = UART()
""" """
super().__init__() super().__init__()
self.connect(portname, speed, timeout) if connect is True:
self.enter() self.connect(portname, speed, timeout)
self.enter()
self._config = None self._config = None
self._echo = False self._echo = False
...@@ -81,6 +84,8 @@ class UART(BBIO_base): ...@@ -81,6 +84,8 @@ class UART(BBIO_base):
""" """
if self.mode == 'uart': if self.mode == 'uart':
return return
if self.mode != 'bb':
super(UART, self).enter()
self.write(0x03) self.write(0x03)
self.timeout(self.minDelay * 10) self.timeout(self.minDelay * 10)
if self.response(4) == "ART1": if self.response(4) == "ART1":
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Example of SPI data transfer
from pyBusPirateLite.SPI import *
spi = SPI()
spi.pins = PIN_POWER | PIN_CS
spi.config = CFG_PUSH_PULL
spi.speed = '1MHz'
# send two bytes and receive answer
spi.cs = True
data = spi.transfer( [0x82, 0x55])
spi.cs = False
spi.pins = PIN_CS
...@@ -11,6 +11,7 @@ def test_outputs(): ...@@ -11,6 +11,7 @@ def test_outputs():
bb = BitBang() bb = BitBang()
bb.outputs bb.outputs
bb.disconnect() bb.disconnect()
bb.hw_reset()
def test_pins_CS(): def test_pins_CS():
...@@ -25,6 +26,7 @@ def test_pins_CS(): ...@@ -25,6 +26,7 @@ def test_pins_CS():
sleep(0.2) sleep(0.2)
assert bb.outputs == PIN_CS assert bb.outputs == PIN_CS
assert bb.pins == PIN_CS assert bb.pins == PIN_CS
bb.hw_reset()
def test_pins_MISO(): def test_pins_MISO():
...@@ -39,6 +41,7 @@ def test_pins_MISO(): ...@@ -39,6 +41,7 @@ def test_pins_MISO():
sleep(0.2) sleep(0.2)
assert bb.outputs == PIN_MISO assert bb.outputs == PIN_MISO
assert bb.pins == PIN_MISO assert bb.pins == PIN_MISO
bb.hw_reset()
def test_pins_MOSI(): def test_pins_MOSI():
...@@ -53,6 +56,7 @@ def test_pins_MOSI(): ...@@ -53,6 +56,7 @@ def test_pins_MOSI():
sleep(0.2) sleep(0.2)
assert bb.outputs == PIN_MOSI assert bb.outputs == PIN_MOSI
assert bb.pins == PIN_MOSI assert bb.pins == PIN_MOSI
bb.hw_reset()
def test_pins_CLK(): def test_pins_CLK():
...@@ -67,6 +71,7 @@ def test_pins_CLK(): ...@@ -67,6 +71,7 @@ def test_pins_CLK():
sleep(0.2) sleep(0.2)
assert bb.outputs == PIN_CLK assert bb.outputs == PIN_CLK
assert bb.pins == PIN_CLK assert bb.pins == PIN_CLK
bb.hw_reset()
def test_pins_AUX(): def test_pins_AUX():
...@@ -81,3 +86,4 @@ def test_pins_AUX(): ...@@ -81,3 +86,4 @@ def test_pins_AUX():
bb.pins = PIN_AUX bb.pins = PIN_AUX
assert bb.outputs == PIN_AUX assert bb.outputs == PIN_AUX
assert bb.pins == PIN_AUX assert bb.pins == PIN_AUX
bb.hw_reset()
...@@ -10,6 +10,7 @@ def test_connect(): ...@@ -10,6 +10,7 @@ def test_connect():
i2c = I2C(connect=False) i2c = I2C(connect=False)
i2c.connect() i2c.connect()
assert i2c.portname != '' assert i2c.portname != ''
i2c.hw_reset()
def test_enter(): def test_enter():
...@@ -24,11 +25,6 @@ def test_connect_on_init(): ...@@ -24,11 +25,6 @@ def test_connect_on_init():
assert i2c.mode == 'i2c' assert i2c.mode == 'i2c'
def test_modestring():
i2c = I2C()
assert i2c.modestring == 'I2C1'
def test_echo(): def test_echo():
pass pass
......
from pyBusPirateLite.SPI import SPI, CFG_PUSH_PULL, CFG_IDLE from pyBusPirateLite.SPI import SPI, CFG_PUSH_PULL, CFG_IDLE
from pyBusPirateLite.BBIO_base import PIN_POWER, PIN_CS
def test_init(): def test_init():
...@@ -10,7 +9,8 @@ def test_init(): ...@@ -10,7 +9,8 @@ def test_init():
def test_connect(): def test_connect():
spi = SPI(connect=False) spi = SPI(connect=False)
spi.connect() spi.connect()
assert bb.portname != '' assert spi.portname != ''
spi.hw_reset()
def test_enter(): def test_enter():
...@@ -18,13 +18,16 @@ def test_enter(): ...@@ -18,13 +18,16 @@ def test_enter():
spi.connect() spi.connect()
spi.enter() spi.enter()
assert spi.mode == 'spi' assert spi.mode == 'spi'
spi.hw_reset()
def test_connect_on_init(): def test_connect_on_init():
spi = SPI() spi = SPI()
assert spi.mode == 'spi' assert spi.mode == 'spi'
spi.hw_reset()
def test_modestring(): def test_modestring():
spi = SPI() spi = SPI()
assert spi.modestring == 'SPI1' assert spi.modestring == 'SPI1'
spi.hw_reset()
...@@ -9,7 +9,8 @@ def test_init(): ...@@ -9,7 +9,8 @@ def test_init():
def test_connect(): def test_connect():
uart = UART(connect=False) uart = UART(connect=False)
uart.connect() uart.connect()
assert bb.portname != '' assert uart.portname != ''
uart.hw_reset()
def test_enter(): def test_enter():
...@@ -17,16 +18,19 @@ def test_enter(): ...@@ -17,16 +18,19 @@ def test_enter():
uart.connect() uart.connect()
uart.enter() uart.enter()
assert uart.mode == 'uart' assert uart.mode == 'uart'
uart.hw_reset()
def test_connect_on_init(): def test_connect_on_init():
uart = UART() uart = UART()
assert UART.mode == 'uart' assert uart.mode == 'uart'
uart.hw_reset()
def test_modestring(): def test_modestring():
uart = UART() uart = UART()
assert uart.modestring == 'ART1' assert uart.modestring == 'ART1'
uart.hw_reset()
def test_echo(): def test_echo():
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment