]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/nova/i2c.py
Set executable flag on libgpiod_pulsein64 so pip installs it
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / nova / i2c.py
1 """I2C Class for Binho Nova"""
2
3 from adafruit_blinka.microcontroller.nova import Connection
4
5
6 class I2C:
7     """Custom I2C Class for Binho Nova"""
8
9     WHR_PAYLOAD_MAX_LENGTH = 1024
10
11     def __init__(self, *, frequency=400000):
12         self._nova = Connection.getInstance()
13         self._nova.setNumericalBase(10)
14         self._nova.setOperationMode(0, "I2C")
15         self._nova.setPullUpStateI2C(0, "EN")
16         self._nova.setClockI2C(0, frequency)
17
18         self._novaCMDVer = "0"
19         if hasattr(self._nova, "getCommandVer"):
20             response = self._nova.getCommandVer().split(" ")
21             if response[0] != "-NG":
22                 self._novaCMDVer = response[1]
23
24     def __del__(self):
25         """Close Nova on delete"""
26         self._nova.close()
27
28     def scan(self):
29         """Perform an I2C Device Scan"""
30         scanResults = []
31
32         for i in range(8, 121):
33             result = self._nova.scanAddrI2C(0, i << 1)
34
35             resp = result.split(" ")
36
37             if resp[3] == "OK":
38                 scanResults.append(i)
39
40         return scanResults
41
42     def writeto(self, address, buffer, *, start=0, end=None, stop=True):
43         """Write data from the buffer to an address"""
44         end = end if end else len(buffer)
45         readBytes = 0
46         if int(self._novaCMDVer) >= 1:
47             chunks, rest = divmod(end - start, self.WHR_PAYLOAD_MAX_LENGTH)
48             for i in range(chunks):
49                 chunk_start = start + i * self.WHR_PAYLOAD_MAX_LENGTH
50                 chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
51                 self._nova.writeToReadFromI2C(
52                     0,
53                     address << 1,
54                     stop,
55                     readBytes,
56                     chunk_end - chunk_start,
57                     buffer[chunk_start:chunk_end],
58                 )
59             if rest:
60                 self._nova.writeToReadFromI2C(
61                     0, address << 1, stop, readBytes, rest, buffer[-1 * rest :]
62                 )
63         else:
64             self._nova.startI2C(0, address << 1)
65
66             for i in range(start, end):
67                 self._nova.writeByteI2C(0, buffer[i])
68
69             if stop:
70                 self._nova.endI2C(0)
71             else:
72                 self._nova.endI2C(0, True)
73
74     # pylint: disable=unused-argument
75     def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
76         """Read data from an address and into the buffer"""
77         end = end if end else len(buffer)
78         result = self._nova.readBytesI2C(0, address << 1, len(buffer[start:end]))
79
80         if result != "-NG":
81             resp = result.split(" ")
82
83             for i in range(len(buffer[start:end])):
84                 buffer[start + i] = int(resp[2 + i])
85         else:
86             raise RuntimeError(
87                 "Received error response from Binho Nova, result = " + result
88             )
89
90     # pylint: disable=too-many-locals,too-many-branches
91     def writeto_then_readfrom(
92         self,
93         address,
94         buffer_out,
95         buffer_in,
96         *,
97         out_start=0,
98         out_end=None,
99         in_start=0,
100         in_end=None,
101         stop=False,
102     ):
103         """Write data from buffer_out to an address and then
104         read data from an address and into buffer_in
105         """
106         out_end = out_end if out_end else len(buffer_out)
107         in_end = in_end if in_end else len(buffer_in)
108         if int(self._novaCMDVer) >= 1:
109             totalIn = in_end - in_start
110             totalOut = out_end - out_start
111             totalBytes = totalIn
112             if totalOut > totalIn:
113                 totalBytes = totalOut
114             chunks, rest = divmod(totalBytes, self.WHR_PAYLOAD_MAX_LENGTH)
115             if rest > 0:
116                 chunks += 1
117
118             for i in range(chunks):
119                 # calculate the number of bytes to be written and read
120                 numInBytes = self.WHR_PAYLOAD_MAX_LENGTH
121                 if totalIn < self.WHR_PAYLOAD_MAX_LENGTH:
122                     numInBytes = totalIn
123                 numOutBytes = self.WHR_PAYLOAD_MAX_LENGTH
124                 if totalOut < self.WHR_PAYLOAD_MAX_LENGTH:
125                     numOutBytes = totalOut
126
127                 # setup the buffer out chunk offset
128                 buffer = "0"
129                 if numOutBytes > 0:
130                     chunk_start = out_start + i * self.WHR_PAYLOAD_MAX_LENGTH
131                     chunk_end = chunk_start + numOutBytes
132                     buffer = buffer_out[chunk_start:chunk_end]
133
134                 result = self._nova.writeToReadFromI2C(
135                     0, address << 1, stop, numInBytes, numOutBytes, buffer
136                 )
137                 totalIn -= numInBytes
138                 totalOut -= numOutBytes
139
140                 if result != "-NG":
141                     if numInBytes:
142                         resp = result.split(" ")
143                         resp = resp[2]
144
145                         for j in range(numInBytes):
146                             buffer_in[
147                                 in_start + i * self.WHR_PAYLOAD_MAX_LENGTH + j
148                             ] = int(resp[j * 2] + resp[j * 2 + 1], 16)
149                 else:
150                     raise RuntimeError(
151                         "Received error response from Binho Nova, result = " + result
152                     )
153         else:
154             self._nova.startI2C(0, address << 1)
155
156             for i in range(out_start, out_end):
157                 self._nova.writeByteI2C(0, buffer_out[i])
158
159             if stop:
160                 self._nova.endI2C(0)
161             else:
162                 self._nova.endI2C(0, True)
163
164             result = self._nova.readBytesI2C(
165                 0, address << 1, len(buffer_in[in_start:in_end])
166             )
167
168             if result != "-NG":
169                 resp = result.split(" ")
170
171                 for i in range(len(buffer_in[in_start:in_end])):
172                     buffer_in[in_start + i] = int(resp[2 + i])
173             else:
174                 raise RuntimeError(
175                     "Received error response from Binho Nova, result = " + result
176                 )
177
178
179 # pylint: enable=unused-argument,too-many-locals,too-many-branches