]> defiant.homedns.org Git - pyshared.git/blob - bus_pirate.py
bus_pirate: fix i2c addr handling
[pyshared.git] / bus_pirate.py
1 #!/usr/bin/env python
2 # -*- coding: iso-8859-15 -*-
3
4 import serial
5 import struct
6
7 dPinToBit = {
8                 "POWER": 6,
9                 "PULLUP": 5,
10                 "AUX": 4,
11                 "MOSI": 3,
12                 "CLK": 2,
13                 "MISO": 1,
14                 "CS": 0
15 }
16
17 # http://dangerousprototypes.com/docs/Bitbang
18 # http://dangerousprototypes.com/docs/SPI_(binary)
19 class BP:
20         def __init__(self, sDevice):
21                 self.pSerial = serial.Serial(sDevice, baudrate=115200, timeout=0.1)
22                 self.mode_bit_bang()
23                 self.io_state = 0
24                 self.io_dir = 0
25
26         def command(self, cmd, num_read):
27                 self.pSerial.write(cmd)
28                 return self.pSerial.read(num_read)
29
30         def mode_bit_bang(self):
31                 for i in range(20):
32                         if self.command(chr(0x0), 5) == "BBIO1":
33                                 return
34                 raise Exception("Failed to enter bit bang mode")
35
36         def mode_spi(self, mode, speed):
37                 if self.command(chr(0x1), 4) != "SPI1":
38                         raise Exception()
39                 self.spi_set_mode(mode)
40                 self.spi_set_speed(speed)
41
42         def spi_set_mode(self, mode):
43                 if mode not in range(0, 4):
44                         raise Exception("Unknown mode")
45                 if mode == 0:
46                         self.spi_command(chr(0b10001000))
47                 elif mode == 1:
48                         self.spi_command(chr(0b10001010))
49                 elif mode == 2:
50                         self.spi_command(chr(0b10001100))
51                 elif mode == 3:
52                         self.spi_command(chr(0b10001110))
53
54         def spi_set_speed(self, speed):
55                 lSpeeds = ["30kHz", "125kHz", "250kHz", "1MHz", "2MHz", "2.6MHz", "4MHz", "8MHz"]
56                 val = lSpeeds.index(speed)
57                 self.spi_command(chr(0b01100000 | val))
58
59         def power_enable(self):
60                 self.set_io("POWER", True)
61         
62         def get_adc(self):
63                 s = self.command(chr(0x14), 2)
64                 v = struct.unpack(">h", s)
65                 return v[0]/1024.0*6.6
66
67         def spi_command(self, cmd):
68                 ret = self.command(cmd, 1)
69                 if ord(ret) != 0x1:
70                         raise Exception()
71         
72         def spi_write(self, data, num_read=0):
73                 if len(data) > 4096:
74                         raise Exception("SPI Data String too long")
75                 return self.spi_command(struct.pack(">Bhh%ds" % len(data), 0x04, len(data), num_read, data))
76
77         def set_io_output(self, pin):
78                 if pin not in dPinToBit.keys():
79                         raise Exception("Bad output pin")
80                 self.io_dir &= ~(1 << dPinToBit[pin])
81                 state = 0b01000000 | self.io_dir
82                 self.command(chr(state), 1)
83
84         def set_io_input(self, pin):
85                 if pin not in dPinToBit.keys():
86                         raise Exception("Bad input pin")
87                 self.io_dir |= (1 << dPinToBit[pin])
88                 state = 0b01000000 | self.io_dir
89                 self.command(chr(state), 1)
90
91         def set_io(self, pin, val):
92                 if pin not in dPinToBit.keys():
93                         raise Exception("Bad output pin")
94                 if val:
95                         self.io_state |=  (1 << dPinToBit[pin])
96                 else:
97                         self.io_state &= ~(1 << dPinToBit[pin])
98                 state = self.update_io()
99
100         def update_io(self):
101                 state = self.command(chr(0b10000000 | self.io_state), 1)
102                 return ord(state)
103
104         def get_io(self, pin):
105                 if pin not in dPinToBit.keys():
106                         raise Exception("Bad I/O pin")
107                 state = self.update_io()
108                 return state & (1 << dPinToBit[pin])
109
110         def mode_i2c(self, bEnablePower=False, bEnablePullup=False, iSpeedkHz=100):
111                 if self.command(chr(0x2), 4) != "I2C1":
112                         raise Exception()
113
114                 dSpeeds = {
115                         5: 0x0,
116                         50: 0x1,
117                         100: 0x2,
118                         400: 0x3,
119                 }
120                 if iSpeedkHz not in dSpeeds.keys():
121                         raise Exception("Invalid I2C speed")
122                 ret = self.command(chr(0b01100000 | dSpeeds[iSpeedkHz]), 1)
123                 if ord(ret) != 0x1:
124                         raise Exception()
125
126                 periphals = 0b01000000
127                 if bEnablePower:
128                         periphals |= (1<<3)
129                 if bEnablePullup:
130                         periphals |= (1<<2)
131                 ret = self.command(chr(periphals), 1)
132                 if ord(ret) != 0x1:
133                         raise Exception()
134
135         def i2c_write(self, addr, reg, s):
136                 # 1. Write
137                 # command (1) | number of write bytes (2) | number of read bytes (2) | bytes to write (0..)
138                 msg = struct.pack(">BHHBB%ds" % len(s), 0x08, 2+len(s), 0, addr, reg, s)
139                 ret = self.command(msg, 1)
140
141                 if ord(ret[0]) != 0x1:
142                         raise Exception("I2C write error")
143
144         def i2c_read(self, addr, reg, num_read):
145                 # set reg
146                 self.i2c_write(addr, reg, "")
147
148                 # command (1) | number of write bytes (2) | number of read bytes (2) | bytes to write (0..)
149                 msg = struct.pack(">BHHB", 0x08, 1, num_read, addr | 0x1)
150                 ret = self.command(msg, 1 + num_read)
151
152                 if ord(ret[0]) != 0x1:
153                         raise Exception("I2C read error")
154
155                 return ret[1:]
156
157         def i2c_search(self):
158                 for i in range(128):
159                         msg = struct.pack(">BHHB", 0x08, 1, 1, i)
160                         ret = self.command(msg, 1)
161                         if ord(ret) == 0x1:
162                                 print "Found I2C Addr: 0x%x" % (i & ~0x1)