-
-
Save HokieGeek/8fe2de6f19844d7311f0 to your computer and use it in GitHub Desktop.
#!/usr/bin/python | |
import serial | |
import signal | |
import sys | |
import time | |
def BinaryModeEnter(connection): | |
connection.flushInput() | |
for x in range(0, 20): # Try at most 20 times | |
connection.write(b'\x00') # 0000 0000 | |
if b'BBIO' in connection.read(10): | |
return True | |
return False | |
def BinaryModeExit(connection): | |
connection.write(b'\x0F') # 0000 1111 | |
def InterfaceSelect_SPI(connection): | |
# TODO | |
connection.write(b'\x01') # Enter SPI: 0000 0001 | |
## Configure the SPI connection | |
connection.write(b'\x49') # Power ON, CS High 0100 1001 | |
return | |
# def handleSigint(signal, frame): | |
# sys.exit(0) | |
conn = serial.Serial("/dev/buspirate", 115200, timeout=0.1) | |
if BinaryModeEnter(conn): | |
print("Connected") | |
else: | |
print("Error connecting!") | |
ConfigurePower(conn, True) | |
while True: | |
try: | |
print(".", end="", flush=True) | |
time.sleep(2) | |
except KeyboardInterrupt: | |
print("Adios") | |
BinaryModeExit(conn) | |
sys.exit() |
import System.IO | |
import System.Exit | |
import System.Posix.Signals | |
import Control.Concurrent | |
import Control.Monad | |
-- import System.Hardware.Serialport | |
-- port = "/dev/buspirate" | |
-- let startBitbang = 0 | |
-- binaryModeEnter :: IO Handle -> Bool | |
-- binaryModeEnter h | |
-- | hGetLine h == 'BBIO' = True | |
-- Else, do a send or putstr of startBitbang | |
-- h <- hOpenSerial port defaultSerialSettings { commSpeed = CS115200 } | |
-- not hPut_Str_ is my guess... send? | |
-- hGetLine h == 'BBIO' | |
-- hPutStr h startBitbang | |
-- Start power | |
-- hPutStr h \xC0 | |
-- TODO: only get here when the user wants to | |
-- hClose h | |
main :: IO () | |
main = forever $ do | |
tid <- myThreadId | |
installHandler keyboardSignal (Catch (killThread tid)) Nothing | |
putStr "." | |
hFlush stdout | |
threadDelay(2000000) |
#!/usr/bin/python | |
import argparse | |
import serial | |
import signal | |
import struct | |
import sys | |
import time | |
def BinaryModeEnter(connection): | |
connection.flushInput() | |
for x in range(0, 22): # Try at least 20 times | |
connection.write(b'\x00') | |
if b'BBIO' in connection.read(10): | |
print("Entered (or reset) binary mode") | |
return True | |
print("Error connecting!") | |
return False | |
def BinaryModeExit(connection): | |
connection.write(b'\x0F') # 0000 1111 | |
print("Exited binary mode") | |
def ConfigurePower(connection, enabled): | |
if enabled: | |
connection.write(b'\xC0') # 1100 0000 | |
else: | |
connection.write(b'\x80') # 1000 0000 | |
def SelfTest(connection, testType): | |
print("Starting %s self-test" % testType) | |
if testType == "short": | |
connection.write(b'\x10') # 0001 0000 | |
else: | |
print("Please connect the following pins together:") | |
print(" +5 <-> Vpu") | |
print(" +3.3 <-> ADC") | |
input("Press Enter to continue...") | |
connection.write(b'\x11') # 0001 0001 | |
time.sleep(5) # give it time... | |
print("Found %d errors." % int.from_bytes(connection.read(1), byteorder='big')) | |
connection.write(b'\xFF') | |
def ReadVoltage(connection): | |
reading = int.from_bytes(connection.read(2), byteorder='big') | |
return (reading/1024)*6.6 | |
def VoltageProbe(connection): | |
# connection.write(b'\x14') # 0001 0100 | |
# print("%d" % ReadVoltage(connection), flush=True) | |
connection.write(b'\x15') # 0001 0101 | |
while True: | |
try: | |
print("%d" % ReadVoltage(connection), flush=True) | |
time.sleep(1) | |
except KeyboardInterrupt: | |
break | |
def ConfigurePins(connection): | |
print("TODO") | |
def spiEnter(connection): | |
connection.write(b'\x01') | |
if b'SPI' in connection.read(10): | |
print("Entered SPI mode") | |
def spiPeripherals(connection, power, pullups, aux, cs): | |
peripherals = 0x40 | |
if power: | |
peripherals |= 0x08 | |
if pullups: | |
peripherals |= 0x04 | |
if aux: | |
peripherals |= 0x02 | |
if cs: | |
peripherals |= 0x01 | |
print("Setting peripherals to: %s" % str(hex(peripherals))) | |
connection.write(struct.pack('B', peripherals)) | |
# return b'\x01' in connection.read(2) | |
def spiSpeed(connection, speed_str): | |
speed = 0x60 # Implies 30kHz | |
if speed_str == "125k": | |
speed |= 0x01 # 0001 | |
elif speed_str == "250k": | |
speed |= 0x02 # 0010 | |
elif speed_str == "1m": | |
speed |= 0x03 # 0011 | |
elif speed_str == "2m": | |
speed |= 0x04 # 0100 | |
elif speed_str == "2.6m": | |
speed |= 0x05 # 0101 | |
elif speed_str == "4m": | |
speed |= 0x06 # 0110 | |
elif speed_str == "8m": | |
speed |= 0x07 # 0111 | |
else: # 30kHz. Here purely for completeness | |
speed |= 0x00 # 0000 | |
connection.write(struct.pack('B', speed)) | |
def spiToggleChipSelect(connection, high): | |
if high: | |
connection.write(b'\x03') | |
else: | |
connection.write(b'\x02') | |
def spiConfig(connection, pinOutput3v3, clockIdlePhaseHigh, clockEdgeActiveToIdle): | |
config = 0x80 | |
if pinOutput3v3: | |
config |= 0x08 | |
if clockIdlePhaseHigh: | |
config |= 0x04 | |
if clockEdgeActiveToIdle: | |
config |= 0x02 | |
# TODO: sample time? | |
connection.write(struct.pack('B', config)) | |
return b'\x01' in connection.read(2) | |
def spiSniff(connection, csLow): | |
if csLow: | |
connection.write(b'\x06') #000011 10 | |
else: | |
connection.write(b'\x05') #000011 01 | |
while True: | |
try: | |
print("%d" % connection.read(2), flush=True) | |
except KeyboardInterrupt: | |
connection.write(b'\xF0') | |
break | |
def spiBulkTransfer(connection, numBytes, writeBytes, readBytes): | |
# connection.write() | |
print("TODO") | |
def spiWriteThenRead(connection, numBytesToWrite, writeBytes, numBytesToRead, readBytes): | |
print("TODO") | |
connection.write(b'\x04') # WriteThenRead blah | |
# command | |
# def spiWrite(connection): | |
# print("TODO") | |
# def spiRead(connection): | |
# print("TODO") | |
def SpiCommand(connection, arguments): | |
print("SpiCommand") | |
# Commands: sniff, read, write, readwrite | |
parser = argparse.ArgumentParser(add_help=False) | |
parser.add_argument("cmd", choices=['sniff', 'read', 'write', 'readwrite']) | |
parser.add_argument("-p", "--peripherals", action="store") | |
parser.add_argument("-c", "--config", action="store") | |
parser.add_argument("-s", "--speed", action="store") | |
# TODO: input and output files? | |
args = parser.parse_args(arguments) | |
# print(arguments) | |
# print(args.cmd) | |
BinaryModeEnter(conn) | |
spiEnter(connection) | |
## Setup the peripherals | |
if args.peripherals is not None: | |
power = False | |
pullups = False | |
aux = False | |
cs = False | |
for p in args.peripherals.split(','): | |
if p.lower() == "power": | |
power = True | |
elif p.lower() == "pullups": | |
pullups = True | |
elif p.lower() == "aux": | |
aux = True | |
elif p.lower() == "cs": | |
cs = True | |
spiPeripherals(connection, power, pullups, aux, cs) | |
## Set the speed | |
if args.speed is not None: | |
spiSpeed(connection, args.speed) | |
## Configure the SPI settings | |
if args.config is not None: | |
pinOutput3v3 = False | |
clockIdlePhaseHigh = False | |
clockEdgeActiveToIdle = False | |
for c in args.config.split(','): | |
if c.lower() == "3v3": | |
pinOutput3v3 = True | |
elif c.lower() == "clk-idle-high": | |
clockIdlePhaseHigh = True | |
elif c.lower() == "clk-edge-ati": | |
clockEdgeActiveToIdle = True | |
spiConfig(connection, pinOutput3v3, clockIdlePhaseHigh, clockEdgeActiveToIdle) | |
## Execute the operation | |
if cmd == "sniff": | |
spiSniff(connection, False) # TODO: how to do the options | |
# elif cmd == "read": | |
# print("TODO") | |
# elif cmd == "write": | |
# print("TODO") | |
# elif cmd == "readwrite": | |
# print("TODO") | |
## Now exit | |
BinaryModeEnter(connection) | |
BinaryModeExit(connection) | |
## Arguments | |
# [done] --power | |
# --pwm <width> (clear it on exit) | |
# --voltage | |
# --freq | |
# --output <[aux|mosi|clk|miso|cs]> | |
# [done] --test (remind to do pins) | |
parser = argparse.ArgumentParser(prog="buspirate", description="Bus Pirate script interface") | |
parser.add_argument("--device", help="Serial device to use. Defaults to /dev/buspirate", default="/dev/buspirate", action="store") | |
parser.add_argument("-i", "--interactive", help="Enter interactive mode", action="store_true", dest="interactive") | |
parser.add_argument("--power", choices=['on','off'], help="Enable or disable power", action="store") | |
parser.add_argument("--voltage", help="Probe for voltage at ADC pin", action="store_true") | |
parser.add_argument("--test", choices=['short','long'], help="Perform short or long self-test", action="store") | |
parser.add_argument("--enter", help="Resets back to raw bitbang mode", action="store_true") | |
parser.add_argument("--exit", help="Enable or disable power", action="store_true") | |
parser.add_argument("--reset", help="Resets back to raw bitbang mode", action="store_true") | |
parser.add_argument("--spi", help="Performs SPI commands", action="store_true") | |
# parser.add_argument("--i2c", help="Performs I2C commands", action="store_true") | |
# parser.add_argument("--uart", help="Performs UART commands", action="store_true") | |
# parser.add_argument("raw", help="Send raw byte", action="store") | |
args, extra_args = parser.parse_known_args() | |
# if args.spi: | |
# SpiCommand(None, extra_args) | |
# print("args = %s" % args) | |
# print("extra_args = %s" % extra_args) | |
# sys.exit() | |
## Connect | |
conn = serial.Serial(args.device, 115200, timeout=0.1) | |
if args.enter or args.reset: | |
BinaryModeEnter(conn) | |
if args.interactive: | |
print("TODO") | |
# while True: | |
# try: | |
# print(".", end="", flush=True) | |
# time.sleep(2) | |
# except KeyboardInterrupt: | |
# print("Adios") | |
# ConfigurePower(conn, False) | |
# BinaryModeExit(conn) | |
# sys.exit() | |
elif args.test is not None: | |
if BinaryModeEnter(conn): | |
SelfTest(conn, args.test) | |
BinaryModeExit(conn) | |
elif args.power is not None: | |
if BinaryModeEnter(conn): | |
if args.power == "on": | |
ConfigurePower(conn, True) | |
print("Power supplies are ON") | |
else: | |
ConfigurePower(conn, False) | |
print("Power supplies are OFF") | |
elif args.voltage: | |
VoltageProbe(conn) | |
elif args.spi: | |
SpiCommand(conn, extra_args) | |
# if args.raw is not None: | |
# conn.write(????) | |
if args.exit: | |
BinaryModeEnter(conn) | |
BinaryModeExit(conn) |
SPI
http://dangerousprototypes.com/docs/SPI_(binary)
00000000
- Enter raw bitbang mode, reset to raw bitbang mode
00000001
- Enter raw SPI mode, display version string
0000001x
- CS high (1) or low (0)
000011XX
- Sniff SPI traffic when CS low(10)/all(01)
0001xxxx
- Bulk SPI transfer, send/read 1-16 bytes (0=1byte!)
0100wxyz
- Configure peripherals w=power, x=pull-ups, y=AUX, z=CS
01100xxx
- SPI speed
1000wxyz
- SPI config, w=HiZ/3.3v, x=CKP idle, y=CKE edge, z=SMP sample
00000100
- Write then read
00000101
- Write then read, no CS
I2C
http://dangerousprototypes.com/docs/I2C_(binary)
00000000
- Exit to bitbang mode, responds "BBIOx"
00000001
– Display mode version string, responds "I2Cx"
00000010
– I2C start bit
00000011
– I2C stop bit
00000100
- I2C read byte
00000110
- ACK bit
00000111
- NACK bit
00001111
- Start bus sniffer
0001xxxx
– Bulk I2C write, send 1-16 bytes (0=1byte!)
0100wxyz
– Configure peripherals w=power, x=pullups, y=AUX, z=CS
010100xy
- Pull up voltage select (BPV4 only)- x=5v y=3.3v
011000xx
- Set I2C speed, 3=~400kHz, 2=~100kHz, 1=~50kHz, 0=~5kHz (updated in v4.2 firmware)
0x08
- Write then read
UART
http://dangerousprototypes.com/docs/UART_(binary)
00000000
- Exit to bitbang mode, responds "BBIOx"
00000001
– Display mode version string, responds "ARTx"
0000001x
– Start (0)/stop(1) echo UART RX
00000111
– Manual baud rate configuration, send 2 bytes
00001111
- UART bridge mode (reset to exit)
0001xxxx
– Bulk UART write, send 1-16 bytes (0=1byte!)
0100wxyz
– Configure peripherals w=power, x=pullups, y=AUX, z=CS
0110xxxx
- Set UART speed
100wxxyz
– Configure UART settings
Bitbang mode commands
http://dangerousprototypes.com/docs/Bitbang
00000000
- Reset, responds "BBIO1"00000001
- Enter binary SPI mode, responds "SPI1"00000010
- Enter binary I2C mode, responds "I2C1"00000011
- Enter binary UART mode, responds "ART1"00000100
- Enter binary 1-Wire mode, responds "1W01"00000101
- Enter binary raw-wire mode, responds "RAW1"00000110
- Enter OpenOCD JTAG mode0000xxxx
- Reserved for future raw protocol modes00001111
- Reset Bus Pirate0001000x
- Bus Pirate self-tests00010010
- Setup pulse-width modulation (requires 5 byte setup)00010011
- Clear/disable PWM00010100
- Take voltage probe measurement (returns 2 bytes)00010101
- Continuous voltage probe measurement00010110
- Frequency measurement on AUX pin010xxxxx
- Configure pins as input(1) or output(0): AUX|MOSI|CLK|MISO|CS1xxxxxxx
- Set on (1) or off (0): POWER|PULLUP|AUX|MOSI|CLK|MISO|CS