-
-
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