Commit 913ac51e authored by Juergen Hasch's avatar Juergen Hasch

Update code, works for SPI

parent c023d06d
......@@ -2,6 +2,7 @@
Python library for BusPirate
Based on code from Garrett Berg <cloudform511@gmail.com>
http://dangerousprototypes.com/2011/03/14/new-version-of-pybuspiratelite-python-library/
-------------------------
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Example of SPI data transfer
from pyBusPirateLite.SPI import *
from pyBusPirateLite.BBIO_base import PinCfg
spi = SPI()
spi.connect('COM3')
spi.enter_bb()
spi.enter_spi()
spi = SPI('COM3', 115200)
spi.BBmode()
spi.enter_SPI()
spi.cfg_pins(PinCfg.POWER | PinCfg.CS )
spi.cfg_spi( 0x0c )
spi.set_speed(SPISpeed._1MHZ)
register = 0
spi.CS_Low()
spi.port.write(bytes([0x11]))
spi.port.write(bytes([0x80]))
spi.port.write(bytes([0x00]))
spi.CS_High()
data = spi.response(2, True)
# send two bytes and receive answer
spi.cs_low()
data = spi.transfer( [0x82, 0x00])
spi.cs_high()
print(data[1])
print(ord(data[2]))
spi.reset()
spi.port.close()
This diff is collapsed.
This diff is collapsed.
......@@ -22,36 +22,35 @@ 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/>.
"""
try:
from .BitBang import BBIO
except ValueError:
from BitBang import BBIO
from .BitBang import BBIO
class I2CSpeed:
_400KHZ = 0x03
_100KHZ = 0x02
_50KHZ = 0x01
_5KHZ = 0x00
_400KHZ = 0x03
_100KHZ = 0x02
_50KHZ = 0x01
_5KHZ = 0x00
class I2CPins:
POWER = 0x8
PULLUPS = 0x4
AUX = 0x2
CS = 0x1
POWER = 0x8
PULLUPS = 0x4
AUX = 0x2
CS = 0x1
pin_mapping = {'AUX': 0b10,
'CS': 0b01 }
'CS': 0b01 }
class I2C(BBIO):
def send_ack(self):
self.check_mode('i2c')
self.port.write("\x06")
#self.timeout(0.1)
return self.response()
def send_nack(self):
self.check_mode('i2c')
self.port.write("\x07")
#self.timeout(0.1)
return self.response()
def send_ack(self):
self.check_mode('i2c')
self.port.write(bytes([0x06]))
return self.response(1, True)
def send_nack(self):
self.check_mode('i2c')
self.port.write(bytes([0x07]))
return self.response(1, True)
......@@ -19,71 +19,71 @@ 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/>.
"""
try:
from .BitBang import BBIO
except ValueError:
from BitBang import BBIO
from .BitBang import BBIO
from .I2C import *
""" enter binary mode """
class I2Chigh(I2C):
"""High level I2C transactions, not included in uc class"""
def __init__(self, port, speed, t = 1):
I2C.__init__(self, port, speed, t);
I2C.__init__(self, port, speed, t)
def get_byte(self, i2caddr, addr):
""" Read one byte from address addr """
self.send_start_bit();
stat = self.bulk_trans(2, [i2caddr << 1, addr]);
self.send_start_bit();
stat += self.bulk_trans(1, [i2caddr << 1 | 1]);
r = self.read_byte();
self.send_nack();
self.send_stop_bit();
self.send_start_bit()
stat = self.bulk_trans(2, [i2caddr << 1, addr])
self.send_start_bit()
stat += self.bulk_trans(1, [i2caddr << 1 | 1])
r = self.read_byte()
self.send_nack()
self.send_stop_bit()
if stat.find(chr(0x01)) != -1:
raise IOError, "I2C command on address 0x%02x not acknowledged!" % (i2caddr);
return ord(r);
raise IOError("I2C command on address 0x%02x not acknowledged!" % (i2caddr))
return ord(r)
def set_byte(self, i2caddr, addr, value):
""" Write one byte to address addr """
self.send_start_bit();
stat = self.bulk_trans(3, [i2caddr << 1, addr, value]);
self.send_stop_bit();
self.send_start_bit()
stat = self.bulk_trans(3, [i2caddr << 1, addr, value])
self.send_stop_bit()
if stat.find(chr(0x01)) != -1:
raise IOError, "I2C command on address 0x%02x not acknowledged!" % (i2caddr);
raise IOError("I2C command on address 0x%02x not acknowledged!" % (i2caddr))
def command(self, i2caddr, cmd):
""" Writes one byte command to slave """
self.send_start_bit();
stat = self.bulk_trans(2, [i2caddr << 1, cmd]);
self.send_stop_bit();
self.send_start_bit()
stat = self.bulk_trans(2, [i2caddr << 1, cmd])
self.send_stop_bit()
if stat[0] == chr(0x01):
raise IOError, "I2C command on address 0x%02x not acknowledged!" % (i2caddr);
raise IOError("I2C command on address 0x%02x not acknowledged!" % (i2caddr))
def set_word(self, i2caddr, addr, value):
""" Writes two byte value (big-endian) to address addr """
vh = value / 256;
vl = value % 256;
self.send_start_bit();
stat = self.bulk_trans(4, [i2caddr << 1, addr, vh, vl]);
self.send_stop_bit();
vh = value / 256
vl = value % 256
self.send_start_bit()
stat = self.bulk_trans(4, [i2caddr << 1, addr, vh, vl])
self.send_stop_bit()
if stat.find(chr(0x01)) != -1:
raise IOError, "I2C command on address 0x%02x not acknowledged!" % (i2caddr);
raise IOError("I2C command on address 0x%02x not acknowledged!" % (i2caddr))
def get_word(self, i2caddr, addr):
""" Reads two byte value (big-endian) from address addr """
self.send_start_bit();
stat = self.bulk_trans(2, [i2caddr << 1, addr]);
self.send_start_bit();
stat += self.bulk_trans(1, [i2caddr << 1 | 1]);
rh = self.read_byte();
self.send_ack();
rl = self.read_byte();
self.send_nack();
self.send_stop_bit();
self.send_start_bit()
stat = self.bulk_trans(2, [i2caddr << 1, addr])
self.send_start_bit()
stat += self.bulk_trans(1, [i2caddr << 1 | 1])
rh = self.read_byte()
self.send_ack()
rl = self.read_byte()
self.send_nack()
self.send_stop_bit()
if stat.find(chr(0x01)) != -1:
raise IOError, "I2C command on address 0x%02x not acknowledged!" % (i2caddr);
return ord(rh) * 256 + ord(rl);
raise IOError("I2C command on address 0x%02x not acknowledged!" % (i2caddr))
return ord(rh) * 256 + ord(rl)
'''some standard functions for i2c communication'''
......
......@@ -23,68 +23,68 @@ You should have received a copy of the GNU General Public License
along with pyBusPirate. If not, see <http://www.gnu.org/licenses/>.
"""
try:
from .BitBang import BBIO
except ValueError:
from BitBang import BBIO
from .BitBang import BBIO
class SPISpeed:
_30KHZ = 0b000
_125KHZ = 0b001
_250KHZ = 0b010
_1MHZ = 0b011
_2MHZ = 0b100
_2_6MHZ = 0b101
_4MHZ = 0b110
_8MHZ = 0b111
_30KHZ = 0b000
_125KHZ = 0b001
_250KHZ = 0b010
_1MHZ = 0b011
_2MHZ = 0b100
_2_6MHZ = 0b101
_4MHZ = 0b110
_8MHZ = 0b111
class SPICfg:
OUT_TYPE = 0x8
IDLE = 0x4
CLK_EDGE = 0x2
SAMPLE = 0x1
OUT_TYPE = 0x8
IDLE = 0x4
CLK_EDGE = 0x2
SAMPLE = 0x1
class SPI_OUT_TYPE:
HIZ = 0
_3V3 = 1
class SPI(BBIO):
def low_nibble(self, nibble):
self.check_mode('spi')
self.port.write(chr(0x20 | nibble))
self.timeout(0.1)
return self.response(1, True)
def high_nibble(self, nibble):
self.check_mode('spi')
self.port.write(chr(0x30 | nibble))
self.timeout(0.1)
return self.response(1, True)
def cfg_spi(self, spi_cfg):
self.check_mode('spi')
self.port.write(chr(0x80 | spi_cfg))
self.timeout(0.1)
return self.response()
def read_spi_cfg(self):
self.check_mode('spi')
self.port.write("\x90")
self.timeout(0.1)
return self.response(1, True)
'''kept in for legacy code NOT SUPPORTED AT ALL. DO NOT USE'''
def CS_Low(self):
'''exactly the same as cs_low in the bitbang library.'''
self.check_mode('spi')
self.port.write("\x02")
self.timeout(0.1)
return self.response(1, True)
def CS_High(self):
'''see CS_Low for what I think'''
self.check_mode('spi')
self.port.write("\x03")
self.timeout(0.1)
return self.response(1, True)
class SPIOutType:
HIZ = 0
_3V3 = 1
class SPI(BBIO):
def cfg_spi(self, spi_cfg):
""" Set SPI configuration
:param spi_cfg: Values defined in SPICfg
"""
self.check_mode('spi')
self.write(0x80 | spi_cfg)
self.timeout(0.1)
resp = self.response(1, True)
if resp != '\x01':
raise ValueError("Could not set SPI configuration", resp)
def read_spi_cfg(self):
""" Read SPI configuration
:return: Values defined in SPICfg
"""
self.check_mode('spi')
self.write(0x90)
self.timeout(0.1)
return self.response(1, True)
def transfer(self, txdata):
""" Transfer data to/from SPI
:param txdata: List of data to send
:return: List of recieved data
"""
self.check_mode('spi')
length = len(txdata)
self.write(0x10 + length-1)
for data in txdata:
self.write(data)
return self.response(length+1, True)
def cs_low(self):
self.write(0x02)
return self.response(1)
def cs_high(self):
self.write(0x03)
return self.response(1)
......@@ -23,67 +23,65 @@ You should have received a copy of the GNU General Public License
along with pyBusPirate. If not, see <http://www.gnu.org/licenses/>.
"""
try:
from .BitBang import BBIO
except ValueError:
from BitBang import BBIO
from .BitBang import BBIO
FOSC = (32000000 / 2)
class UARTCfg:
OUTPUT_TYPE = 0x10
DATABITS = 0x0C
STOPBITS = 0x02
POLARITY = 0x01
OUTPUT_TYPE = 0x10
DATABITS = 0x0C
STOPBITS = 0x02
POLARITY = 0x01
class UARTSpeed:
_300 = 0b0000
_1200 = 0b0001
_2400 = 0b0010
_4800 = 0b0011
_9600 = 0b0100
_19200 = 0b0101
_33250 = 0b0110
_38400 = 0b0111
_57600 = 0b1000
_115200 = 0b1001
class UART(BBIO):
def manual_speed_cfg(self, baud):
self.check_mode('uart')
BRG = ((FOSC) / (4 * baud)) - 1
BRGH = ((BRG >> 8) & 0xFF)
BRGL = (BRG & 0xFF)
self.port.write("\x02")
self.port.write(BRGH)
self.port.write(BRGL)
self.timeout(0.1)
return self.response()
def begin_input(self):
self.check_mode('uart')
self.port.write("\x04")
def end_input(self):
self.check_mode('uart')
self.port.write("\x05")
def enter_bridge_mode(self):
self.check_mode('uart')
self.port.write("\x0F")
self.timeout(0.1)
return self.response(1, True)
def set_cfg(self, cfg):
self.check_mode('uart')
self.port.write(0xC0 | cfg)
self.timeout(0.1)
return self.response(1, True)
def read_cfg(self):
self.check_mode('uart')
self.port.write("\xD0")
self.timeout(0.1)
return self.response(1, True)
class UARTSpeed:
_300 = 0b0000
_1200 = 0b0001
_2400 = 0b0010
_4800 = 0b0011
_9600 = 0b0100
_19200 = 0b0101
_33250 = 0b0110
_38400 = 0b0111
_57600 = 0b1000
_115200 = 0b1001
class UART(BBIO):
def manual_speed_cfg(self, baud):
self.check_mode('uart')
BRG = ((FOSC) / (4 * baud)) - 1
BRGH = ((BRG >> 8) & 0xFF)
BRGL = (BRG & 0xFF)
self.port.write(chr(0x02))
self.port.write(chr(BRGH))
self.port.write(chr(BRGL))
self.timeout(0.1)
return self.response()
def begin_input(self):
self.check_mode('uart')
self.port.write(chr(0x04))
def end_input(self):
self.check_mode('uart')
self.port.write(chr(0x05))
def enter_bridge_mode(self):
self.check_mode('uart')
self.port.write(chr(0x0f))
self.timeout(0.1)
return self.response(1, True)
def set_cfg(self, cfg):
self.check_mode('uart')
self.port.write(chr(0xC0 | cfg))
self.timeout(0.1)
return self.response(1, True)
def read_cfg(self):
self.check_mode('uart')
self.port.write(chr(0xd0))
self.timeout(0.1)
return self.response(1, True)
......@@ -19,51 +19,40 @@ 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/>.
"""
try:
from .BitBang import BBIO
from .I2C import I2C
from .onewire import _1WIRE
from .rawwire import RawWire
from .SPI import SPI
from .UART import UART
except ValueError:
from BitBang import BBIO
from I2C import I2C
from onewire import _1WIRE
from rawwire import RawWire
from SPI import SPI
from UART import UART
'''
from .BitBang import BBIO
from .I2C import I2C
from .onewire import OneWire
from .rawwire import RawWire
from .SPI import SPI
from .UART import UART
"""
Some notes:
normal Values (sent to the uc) are mapped to AUX|MOSI|CLK|MISO|CS.
decoded values are mapped to AUX|CLK|MOSI|CS|MISO
The reason for doing this is to make it easier to
deal with the standard cables. If you have a different cable, you should set BBIO.t to False
in order to use normal data outputs.
'''
"""
class UC(BBIO, I2C, _1WIRE, RawWire, SPI, UART):
'''This class brings together all of the modules under a single class, allowing you to switch
to other modules, do a function, and then switch back transparently. The class will keep track
of where you are and raise an Error if you do something wrong.
The variables bp_port, bp_dir, and bp_config store the values that it sees in each respective mode,
and the variable mode stores which mode the bus pirate is in.
IMPORTANT: Keep in mind that switching modes always makes the pins go to HiZ and the power supplies
turn off. This can suck for certain applications (like if you are manualy wiggling a clock
or reset signal), but you can design around it with external pullups and external inverters.
YOU HAVE TO RECONFIGURE ALL SETTINGS WHENEVER YOU SWITCH MODES.
Note: current tested versions are only BBIO and I2C, but the other ones should work. Go to
________________.com and post any errors, problems or helpful revisions so that the code
can be updated
'''
pass
"""This class brings together all of the modules under a single class, allowing you to switch
to other modules, do a function, and then switch back transparently. The class will keep track
of where you are and raise an Error if you do something wrong.
The variables bp_port, bp_dir, and bp_config store the values that it sees in each respective mode,
and the variable mode stores which mode the bus pirate is in.
IMPORTANT: Keep in mind that switching modes always makes the pins go to HiZ and the power supplies
turn off. This can suck for certain applications (like if you are manualy wiggling a clock
or reset signal), but you can design around it with external pullups and external inverters.
YOU HAVE TO RECONFIGURE ALL SETTINGS WHENEVER YOU SWITCH MODES.
Note: current tested versions are only BBIO and I2C, but the other ones should work. Go to
________________.com and post any errors, problems or helpful revisions so that the code
can be updated
"""
pass
if __name__ == 'main':
pass
......@@ -19,139 +19,61 @@ 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/>.
"""
try:
from . import I2C
from . import BitBang
from . import UC
except ValueError:
import I2C
import BitBang
import UC
from . import I2C
import sys
if __name__ == '__main__':
import time
def init_i2c(bp_device, power = 'on', pullups = 'on', speed = I2C.I2CSpeed._50KHZ):
'''initializes i2c mode with some common settings hardwired'''
if not bp_device.enter_I2C():
return None
if not bp_device.configure_peripherals(power, pullups):
return None
if not bp_device.set_speed(speed):
return None
bp_device.timeout(0.1)
return 1
def init_bb(bp_device, power = 'on', pullups = 'on'):
'''initializes bit bang mode with the most common settings'''
if not bp_device.enter_bb():
return None
if not bp_device.configure_peripherals(power, pullups):
return None
bp_device.timeout(0.1)
return 1
def init_i2c(bp_device, power='on', pullups='on', speed=I2C.I2CSpeed._50KHZ):
"""initializes i2c mode with some common settings hardwired"""
if not bp_device.enter_I2C():
return None
if not bp_device.configure_peripherals(power, pullups):
return None
if not bp_device.set_speed(speed):
return None
bp_device.timeout(0.1)
return 1
def init_bb(bp_device, power='on', pullups='on'):
"""initializes bit bang mode with the most common settings"""
if not bp_device.enter_bb():
return None
if not bp_device.configure_peripherals(power, pullups):
return None
bp_device.timeout(0.1)
return 1
def i2c_write_data(bp_device, data):
'''send data, first byte should be address. NOTE: Address must include the write bit
Created by Peter Huewe peterhuewe@gmx.de'''
bp_device.send_start_bit()
ack_signals = bp_device.bulk_trans(len(data), data)
bp_device.send_stop_bit()
ack_signals = list(ack_signals)
for n in range(len(ack_signals)):
ack_signals[int(n)] = ord(ack_signals[int(n)])
return ack_signals
def sniff_i2c_devices(bp_device, power = 'off'):
init_i2c(bp_device, power)
working_addr = []
for n in range(128):
bp_device.send_start_bit()
ack_sig = list(bp_device.bulk_trans(1, [n << 1]))
bp_device.send_stop_bit()
for p in range(len(ack_sig)):
ack_sig[p] = ord(ack_sig[p])
"""send data, first byte should be address. NOTE: Address must include the write bit
Created by Peter Huewe peterhuewe@gmx.de"""
bp_device.send_start_bit()
ack_signals = bp_device.bulk_trans(len(data), data)
bp_device.send_stop_bit()
ack_signals = list(ack_signals)
for n in range(len(ack_signals)):
ack_signals[int(n)] = ord(ack_signals[int(n)])
return ack_signals
def sniff_i2c_devices(bp_device, power='off'):
init_i2c(bp_device, power)
working_addr = []
for n in range(128):
bp_device.send_start_bit()
ack_sig = list(bp_device.bulk_trans(1, [n << 1]))
bp_device.send_stop_bit()
for p in range(len(ack_sig)):
ack_sig[p] = ord(ack_sig[p])
if 0 in ack_sig:
working_addr += [n]
print working_addr
return working_addr
if 0 in ack_sig:
working_addr += [n]
def init_bus_pirate(mode = 'uc', timeout = None, port = None):
'''connects the bus pirate over a range of possible ports and returns its object'''
if mode is 'uc':
bp_device = UC.UC()
if mode is 'bb':
bp_device = BitBang.BBIO()
if mode is 'i2c':
bp_device = I2C.I2C()
#add your own if you want. I mostly just use the uc one
if port is None:
if sys.platform == 'win32':
if not bp_device.connect(4, 115200, timeout): # 4 connects to port 5 on my computer. This may not work for you.
return None
elif sys.platform == 'linux2':
for n in range(4):
if bp_device.connect("/dev/ttyUSB" + str(n), 115200, timeout):
break
else:
return None
else:
if not bp_device.connect(port, 115200, timeout):
return None
bp_device.enter_bb()
return bp_device
if __name__ == '__main__':
def speed_test_pin(bp_device):
'''a simple speed test I've been using to see how fast the bp can communicate.'''
bp_device.enter_bb()
bp_device.configure_peripherals('on', 'on')
bp_device.set_dir(0b11100) #lower two pins output
bp_device.set_port(0)
periods = []
for i in range(500):
periods.append(time.time())
bp_device.set_port(0b1)