Repository navigation
Expand file tree
/
Copy pathi2c.py
More file actions
108 lines (81 loc) · 3.43 KB
/
Copy pathi2c.py
File metadata and controls
108 lines (81 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""Handy I2C message building for CodeBug."""
# I2C messages
I2C_CONTROL_GO_BUSY = 0x01
I2C_CONTROL_SEND_ADDR = 0x02
I2C_CONTROL_MASTER_FINAL_ACK = 0x04
I2C_CONTROL_WAIT_FOR_ACK = 0x08
I2C_CONTROL_ACK_AFTER_READ = 0x10
I2C_CONTROL_STOP = 0x20
I2C_CONTROL_START = 0x40
I2C_CONTROL_READ_NOT_WRITE = 0x80
class CodeBugI2CMaster():
"""Performs I2C I/O transactions on the CodeBug I2C bus.
Transactions are performed by passing one or more I2C I/O messages
to the transaction method of the I2CMaster. I2C I/O messages are
created with the reading and writing functions defined in the
`codebug_tether.i2c module`.
CodeBugI2CMaster acts as a context manager, allowing it to be used in a
with statement. This is for compatibility with other I2CMasters,
which this is intended to be used in place of. On its own there is
no need to use this as a context manager.
For example:
import codebug_tether
from codebug_tether.i2c import (I2CMaster, writing)
codebug = codebug_tether.CodeBug()
with I2CMaster(codebug) as i2c:
i2c.transaction(writing(0x20, bytes([0x01, 0xFF])))
"""
def __init__(self, codebug):
"""
:param codebug: The CodeBug through which to send I2C data.
:type codebug: `codebug_tether.core.CodeBug`
"""
self.codebug = codebug
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
pass
def transaction(self, *msgs):
"""Perform an I2C I/O transaction. I2CMasters usually return one
bytes array per read operation. Since CodeBug is only capable of one
it doens't normally do this.
"""
return [bytes(self.codebug.i2c_transaction(*msgs))]
class I2CMessage():
"""Data structure for building I2C message patterns."""
def __init__(self, control, address, data, length):
self.control = control
self.address = address
self.data = data
self.length = length
# I2C message generators (feel free to go ahead and form your own I2C messages)
def writing_bytes(addr, *data_bytes):
"""An I2C I/O message that writes one or more bytes of data.
Each byte is passed as an argument to this function.
writing_bytes(addr, 1, 2, 3)
"""
return writing(addr, data_bytes)
def writing(address, data_bytes):
"""Returns a standard I2C write message. Address is limited to 7 bits.
The bytes are passed to this function as a sequence.
writing_bytes(addr, (1, 2, 3))
"""
data = bytes(data_bytes)
return I2CMessage(control=(I2C_CONTROL_START |
I2C_CONTROL_SEND_ADDR |
I2C_CONTROL_WAIT_FOR_ACK |
I2C_CONTROL_GO_BUSY),
address=(0x7f & address),
data=data,
length=len(data))
def reading(address, length):
"""Returns a standard I2C read message. Address is limited to 7 bits."""
return I2CMessage(control=(I2C_CONTROL_START |
I2C_CONTROL_SEND_ADDR |
I2C_CONTROL_WAIT_FOR_ACK |
I2C_CONTROL_ACK_AFTER_READ |
I2C_CONTROL_READ_NOT_WRITE |
I2C_CONTROL_GO_BUSY),
address=(0x7f & address),
data=list(),
length=length)