1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2019 Kattni Rembor for Adafruit Industries
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ """
23
+ `adafruit_debug_i2c`
24
+ ================================================================================
25
+
26
+ Wrapper library for debugging I2C.
27
+
28
+
29
+ * Author(s): Roy Hooper, Kattni Rembor
30
+
31
+ Implementation Notes
32
+ --------------------
33
+
34
+ **Software and Dependencies:**
35
+
36
+ * Adafruit CircuitPython firmware for the supported boards:
37
+ https://github.com/adafruit/circuitpython/releases
38
+
39
+ """
40
+
41
+ __version__ = "0.0.0-auto.0"
42
+ __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Debug_I2C.git"
43
+
44
+
45
+ class I2CDebug :
46
+ """
47
+ Wrapper library for debugging I2C.
48
+
49
+ This library wraps an I2C object and prints buffers before writes and after reads.
50
+
51
+ See the I2C documentation for detailed documentation on the methods in this class.
52
+
53
+ :param i2c: An initialized I2C object to debug.
54
+
55
+ This example uses the LIS3DH accelerometer. This lib can be used with any I2C device. Save
56
+ the code to your board.
57
+
58
+ .. code-block:: python
59
+ import adafruit_lis3dh
60
+ from adafruit_debug_i2c import I2CDebug
61
+ import busio
62
+ import board
63
+ import digitalio
64
+
65
+ i2c = I2CDebug(busio.I2C(board.SCL, board.SDA))
66
+ int1 = digitalio.DigitalInOut(board.ACCELEROMETER_INTERRUPT)
67
+ accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19, int1=int1)
68
+
69
+ print(accelerometer.acceleration)
70
+
71
+ for i in range(5):
72
+ print(accelerometer.acceleration)
73
+
74
+ """
75
+ def __init__ (self , i2c ):
76
+ self ._i2c = i2c
77
+ if hasattr (self ._i2c , 'writeto_then_readfrom' ):
78
+ self .writeto_then_readfrom = self ._writeto_then_readfrom
79
+
80
+ def __enter__ (self ):
81
+ """
82
+ No-op used in Context Managers.
83
+ """
84
+ return self ._i2c .__enter__ ()
85
+
86
+ def __exit__ (self , exc_type , exc_val , exc_tb ):
87
+ """
88
+ Automatically deinitialises the hardware on context exit.
89
+ """
90
+ return self ._i2c .__exit__ (exc_type , exc_val , exc_tb )
91
+
92
+ def deinit (self ):
93
+ """
94
+ Releases control of the underlying I2C hardware so other classes can use it.
95
+ """
96
+ return self ._i2c .deinit ()
97
+
98
+ def readfrom_into (self , address , buffer , * args , start = 0 , end = None ):
99
+ """
100
+ Debug version of ``readfrom_into`` that prints the buffer after reading.
101
+
102
+ :param int address: 7-bit device address
103
+ :param bytearray buffer: buffer to write into
104
+ :param int start: Index to start writing at
105
+ :param int end: Index to write up to but not include
106
+
107
+ """
108
+ self ._i2c .readfrom_into (address , buffer , * args , start = start , end = end )
109
+ print ("i2c.readfrom_into at address {}:" .format (hex (address )), [hex (i ) for i in buffer ])
110
+
111
+ def scan (self ):
112
+ """
113
+ Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of those that respond.
114
+
115
+ :return: List of device ids on the I2C bus
116
+ :rtype: list
117
+ """
118
+ return self ._i2c .scan ()
119
+
120
+ def try_lock (self ):
121
+ """
122
+ Attempts to grab the I2C lock. Returns True on success.
123
+
124
+ :return: True when lock has been grabbed
125
+ :rtype: bool
126
+ """
127
+ return self ._i2c .try_lock ()
128
+
129
+ def unlock (self ):
130
+ """
131
+ Releases the I2C lock.
132
+ """
133
+ return self ._i2c .unlock ()
134
+
135
+ def writeto (self , address , buffer , * args , ** kwargs ):
136
+ """
137
+ Debug version of ``write`` that prints the buffer before sending.
138
+
139
+ :param int address: 7-bit device address
140
+ :param bytearray buffer: buffer containing the bytes to write
141
+ :param int start: Index to start writing from
142
+ :param int end: Index to read up to but not include
143
+ :param bool stop: If true, output an I2C stop condition after the
144
+ buffer is written
145
+ """
146
+ self ._i2c .writeto (address , buffer , * args , ** kwargs )
147
+ print ("i2c.writeto at address {}:" .format (hex (address )), [hex (i ) for i in buffer ])
148
+
149
+ def _writeto_then_readfrom (self , address , buffer_out , buffer_in , * args , out_start = 0 ,
150
+ out_end = None , in_start = 0 , in_end = None ):
151
+ """
152
+ Debug version of ``write_readinto`` that prints the ``buffer_out`` before writing and the
153
+ ``buffer_in`` after reading.
154
+
155
+ :TODO Verify parameter documentation is accurate
156
+ :param address: 7-bit device address
157
+ :param bytearray buffer_out: Write out the data in this buffer
158
+ :param bytearray buffer_in: Read data into this buffer
159
+ :param int out_start: Start of the slice of buffer_out to write out:
160
+ ``buffer_out[out_start:out_end]``
161
+ :param int out_end: End of the slice; this index is not included. Defaults to
162
+ ``len(buffer_out)``
163
+ :param int in_start: Start of the slice of ``buffer_in`` to read into:
164
+ ``buffer_in[in_start:in_end]``
165
+ :param int in_end: End of the slice; this index is not included. Defaults to
166
+ ``len(buffer_in)``
167
+ :param stop: If true, output an I2C stop condition after the buffer is written
168
+ """
169
+ print ("i2c.writeto_then_readfrom.buffer_out at address {}:" .format (hex (address )),
170
+ [hex (i ) for i in buffer_out [out_start :out_end ]])
171
+ self ._i2c .writeto_then_readfrom (address , buffer_out , buffer_in , * args , out_start = out_start ,
172
+ out_end = out_end , in_start = in_start , in_end = in_end )
173
+ print ("i2c.writeto_then_readfrom.buffer_in at address {}:" .format (hex (address )),
174
+ [hex (i ) for i in buffer_in [in_start :in_end ]])
0 commit comments