2 # -*- coding: iso-8859-15 -*-
18 # http://dangerousprototypes.com/docs/Bitbang
19 # http://dangerousprototypes.com/docs/SPI_(binary)
21 def __init__(self, sDevice):
22 self.lock = threading.Lock()
23 self.pSerial = serial.Serial(sDevice, baudrate=115200, timeout=0.1)
28 def command(self, cmd, num_read):
30 self.pSerial.write(cmd)
31 return self.pSerial.read(num_read)
33 def mode_bit_bang(self):
35 if self.command(chr(0x0), 5) == "BBIO1":
37 raise Exception("Failed to enter bit bang mode")
39 def mode_spi(self, mode, speed):
40 if self.command(chr(0x1), 4) != "SPI1":
42 self.spi_set_mode(mode)
43 self.spi_set_speed(speed)
45 def spi_set_mode(self, mode):
46 if mode not in range(0, 4):
47 raise Exception("Unknown mode")
49 self.spi_command(chr(0b10001000))
51 self.spi_command(chr(0b10001010))
53 self.spi_command(chr(0b10001100))
55 self.spi_command(chr(0b10001110))
57 def spi_set_speed(self, speed):
58 lSpeeds = ["30kHz", "125kHz", "250kHz", "1MHz", "2MHz", "2.6MHz", "4MHz", "8MHz"]
59 val = lSpeeds.index(speed)
60 self.spi_command(chr(0b01100000 | val))
62 def power_enable(self):
63 self.set_io("POWER", True)
66 s = self.command(chr(0x14), 2)
67 v = struct.unpack(">h", s)
68 return v[0]/1024.0*6.6
70 # http://codepad.org/qtYpZmIF
71 def pwm(self, freq, duty_cycle_percent):
72 lPrescaler = {0:1, 1:8 , 2:64, 3:256}
78 # find needed prescaler
80 prescaler = lPrescaler[i]
81 PRy = period * 1.0 / (Tcy * prescaler)
83 OCR = int(PRy * duty_cycle_percent)
85 if PRy < (2 ** 16 - 1):
86 break # valid value for PRy, keep values
88 cmd = struct.pack(">BBHH", 0b00010010, i, OCR, PRy)
89 ret = self.command(cmd, 1)
93 def spi_command(self, cmd):
94 ret = self.command(cmd, 1)
98 def spi_write(self, data, num_read=0):
100 raise Exception("SPI Data String too long")
101 return self.spi_command(struct.pack(">Bhh%ds" % len(data), 0x04, len(data), num_read, data))
103 def set_io_output(self, pin):
104 if pin not in dPinToBit.keys():
105 raise Exception("Bad output pin")
106 self.io_dir &= ~(1 << dPinToBit[pin])
107 state = 0b01000000 | self.io_dir
108 self.command(chr(state), 1)
110 def set_io_input(self, pin):
111 if pin not in dPinToBit.keys():
112 raise Exception("Bad input pin")
113 self.io_dir |= (1 << dPinToBit[pin])
114 state = 0b01000000 | self.io_dir
115 self.command(chr(state), 1)
117 def set_io(self, pin, val):
118 if pin not in dPinToBit.keys():
119 raise Exception("Bad output pin")
121 self.io_state |= (1 << dPinToBit[pin])
123 self.io_state &= ~(1 << dPinToBit[pin])
124 state = self.update_io()
127 state = self.command(chr(0b10000000 | self.io_state), 1)
130 def get_io(self, pin):
131 if pin not in dPinToBit.keys():
132 raise Exception("Bad I/O pin")
133 state = self.update_io()
134 return state & (1 << dPinToBit[pin])
136 def mode_i2c(self, bEnablePower=False, bEnablePullup=False, iSpeedkHz=100):
137 if self.command(chr(0x2), 4) != "I2C1":
146 if iSpeedkHz not in dSpeeds.keys():
147 raise Exception("Invalid I2C speed")
148 ret = self.command(chr(0b01100000 | dSpeeds[iSpeedkHz]), 1)
152 periphals = 0b01000000
157 ret = self.command(chr(periphals), 1)
161 def i2c_ping(self, addr):
163 # command (1) | number of write bytes (2) | number of read bytes (2) | bytes to write (0..)
164 msg = struct.pack(">BHHB", 0x08, 1, 0, addr)
165 ret = self.command(msg, 1)
167 if ord(ret[0]) != 0x1:
168 raise Exception("I2C ping failed")
170 def i2c_write(self, addr, reg, s):
172 # command (1) | number of write bytes (2) | number of read bytes (2) | bytes to write (0..)
173 msg = struct.pack(">BHHBB%ds" % len(s), 0x08, 2+len(s), 0, addr, reg, s)
174 ret = self.command(msg, 1)
176 if ord(ret[0]) != 0x1:
177 raise Exception("I2C write error")
179 def i2c_read(self, addr, reg, num_read):
182 self.i2c_write(addr, reg, "")
184 # command (1) | number of write bytes (2) | number of read bytes (2) | bytes to write (0..)
185 msg = struct.pack(">BHHB", 0x08, 1, num_read, addr | 0x1)
186 ret = self.command(msg, 1 + num_read)
188 if ord(ret[0]) != 0x1:
189 raise Exception("I2C read error")
193 def i2c_search(self):
195 msg = struct.pack(">BHHB", 0x08, 1, 1, i)
196 ret = self.command(msg, 1)
198 print "Found I2C Addr: 0x%x" % (i & ~0x1)