1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
4 """I2C Class for Binho Nova"""
6 from adafruit_blinka.microcontroller.nova import Connection
10 """Custom I2C Class for Binho Nova"""
12 WHR_PAYLOAD_MAX_LENGTH = 1024
14 def __init__(self, *, frequency=400000):
15 self._nova = Connection.getInstance()
16 self._nova.setNumericalBase(10)
17 self._nova.setOperationMode(0, "I2C")
18 self._nova.setPullUpStateI2C(0, "EN")
19 self._nova.setClockI2C(0, frequency)
21 self._novaCMDVer = "0"
22 if hasattr(self._nova, "getCommandVer"):
23 response = self._nova.getCommandVer().split(" ")
24 if response[0] != "-NG":
25 self._novaCMDVer = response[1]
28 """Close Nova on delete"""
32 """Perform an I2C Device Scan"""
35 for i in range(8, 121):
36 result = self._nova.scanAddrI2C(0, i << 1)
38 resp = result.split(" ")
45 def writeto(self, address, buffer, *, start=0, end=None, stop=True):
46 """Write data from the buffer to an address"""
47 end = end if end else len(buffer)
49 if int(self._novaCMDVer) >= 1:
50 chunks, rest = divmod(end - start, self.WHR_PAYLOAD_MAX_LENGTH)
51 for i in range(chunks):
52 chunk_start = start + i * self.WHR_PAYLOAD_MAX_LENGTH
53 chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
54 self._nova.writeToReadFromI2C(
59 chunk_end - chunk_start,
60 buffer[chunk_start:chunk_end],
63 self._nova.writeToReadFromI2C(
64 0, address << 1, stop, readBytes, rest, buffer[-1 * rest :]
67 self._nova.startI2C(0, address << 1)
69 for i in range(start, end):
70 self._nova.writeByteI2C(0, buffer[i])
75 self._nova.endI2C(0, True)
77 # pylint: disable=unused-argument
78 def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
79 """Read data from an address and into the buffer"""
80 end = end if end else len(buffer)
81 result = self._nova.readBytesI2C(0, address << 1, len(buffer[start:end]))
84 resp = result.split(" ")
86 for i in range(len(buffer[start:end])):
87 buffer[start + i] = int(resp[2 + i])
90 "Received error response from Binho Nova, result = " + result
93 # pylint: disable=too-many-locals,too-many-branches
94 def writeto_then_readfrom(
106 """Write data from buffer_out to an address and then
107 read data from an address and into buffer_in
109 out_end = out_end if out_end else len(buffer_out)
110 in_end = in_end if in_end else len(buffer_in)
111 if int(self._novaCMDVer) >= 1:
112 totalIn = in_end - in_start
113 totalOut = out_end - out_start
115 if totalOut > totalIn:
116 totalBytes = totalOut
117 chunks, rest = divmod(totalBytes, self.WHR_PAYLOAD_MAX_LENGTH)
121 for i in range(chunks):
122 # calculate the number of bytes to be written and read
123 numInBytes = self.WHR_PAYLOAD_MAX_LENGTH
124 if totalIn < self.WHR_PAYLOAD_MAX_LENGTH:
126 numOutBytes = self.WHR_PAYLOAD_MAX_LENGTH
127 if totalOut < self.WHR_PAYLOAD_MAX_LENGTH:
128 numOutBytes = totalOut
130 # setup the buffer out chunk offset
133 chunk_start = out_start + i * self.WHR_PAYLOAD_MAX_LENGTH
134 chunk_end = chunk_start + numOutBytes
135 buffer = buffer_out[chunk_start:chunk_end]
137 result = self._nova.writeToReadFromI2C(
138 0, address << 1, stop, numInBytes, numOutBytes, buffer
140 totalIn -= numInBytes
141 totalOut -= numOutBytes
145 resp = result.split(" ")
148 for j in range(numInBytes):
150 in_start + i * self.WHR_PAYLOAD_MAX_LENGTH + j
151 ] = int(resp[j * 2] + resp[j * 2 + 1], 16)
154 "Received error response from Binho Nova, result = " + result
157 self._nova.startI2C(0, address << 1)
159 for i in range(out_start, out_end):
160 self._nova.writeByteI2C(0, buffer_out[i])
165 self._nova.endI2C(0, True)
167 result = self._nova.readBytesI2C(
168 0, address << 1, len(buffer_in[in_start:in_end])
172 resp = result.split(" ")
174 for i in range(len(buffer_in[in_start:in_end])):
175 buffer_in[in_start + i] = int(resp[2 + i])
178 "Received error response from Binho Nova, result = " + result
182 # pylint: enable=unused-argument,too-many-locals,too-many-branches