]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/nova/spi.py
fix no self use
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / nova / spi.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """SPI Class for Binho Nova"""
5 from adafruit_blinka.microcontroller.nova import Connection
6
7
8 class SPI:
9     """Custom SPI Class for Binho Nova"""
10
11     MSB = 0
12     BUFFER_PAYLOAD_MAX_LENGTH = 64
13     WHR_PAYLOAD_MAX_LENGTH = 1024
14
15     def __init__(self, clock):
16         self._nova = Connection.getInstance()
17         self._nova.setNumericalBase(10)
18         self._nova.setOperationMode(0, "SPI")
19         self._nova.setClockSPI(0, clock)
20         self._nova.setModeSPI(0, 0)
21         self._nova.setIOpinMode(0, "DOUT")
22         self._nova.setIOpinMode(1, "DOUT")
23         self._nova.beginSPI(0)
24         self._novaCMDVer = "0"
25         if hasattr(self._nova, "getCommandVer"):
26             response = self._nova.getCommandVer().split(" ")
27             if response[0] != "-NG":
28                 self._novaCMDVer = response[1]
29
30         # Cpol and Cpha set by mode
31         # Mode  Cpol Cpha
32         #  0     0    0
33         #  1     0    1
34         #  2     1    0
35         #  3     1    1
36
37     def __del__(self):
38         """Close Nova on delete"""
39         self._nova.close()
40
41     # pylint: disable=too-many-arguments,unused-argument
42     def init(
43         self,
44         baudrate=1000000,
45         polarity=0,
46         phase=0,
47         bits=8,
48         firstbit=MSB,
49         sck=None,
50         mosi=None,
51         miso=None,
52     ):
53         """Initialize the Port"""
54         self._nova.setClockSPI(0, baudrate)
55         self._nova.setModeSPI(0, (polarity << 1) | (phase))
56
57     # pylint: enable=too-many-arguments,unused-argument
58
59     @staticmethod
60     def get_received_data(lineOutput):
61         """Return any received data"""
62         return lineOutput.split("RXD ")[1]
63
64     @property
65     def frequency(self):
66         """Return the current frequency"""
67         return self._nova.getClockSPI(0).split("CLK ")[1]
68
69     def write(self, buf, start=0, end=None):
70         """Write data from the buffer to SPI"""
71         end = end if end else len(buf)
72         payloadMaxLength = self.BUFFER_PAYLOAD_MAX_LENGTH
73         if int(self._novaCMDVer) >= 1:
74             payloadMaxLength = self.WHR_PAYLOAD_MAX_LENGTH
75         chunks, rest = divmod(end - start, payloadMaxLength)
76
77         for i in range(chunks):
78             chunk_start = start + i * payloadMaxLength
79             chunk_end = chunk_start + payloadMaxLength
80             if int(self._novaCMDVer) >= 1:
81                 self._nova.writeToReadFromSPI(
82                     0, True, False, chunk_end - chunk_start, buf[chunk_start:chunk_end]
83                 )
84             else:
85                 self._nova.clearBuffer(0)
86                 self._nova.writeToBuffer(0, 0, buf[chunk_start:chunk_end])
87                 self._nova.transferBufferSPI(0, chunk_end - chunk_start + 1)
88         if rest:
89             if int(self._novaCMDVer) >= 1:
90                 self._nova.writeToReadFromSPI(0, True, False, rest, buf[-1 * rest :])
91             else:
92                 self._nova.clearBuffer(0)
93                 self._nova.writeToBuffer(0, 0, buf[-1 * rest :])
94                 self._nova.transferBufferSPI(0, rest)
95
96     def readinto(self, buf, start=0, end=None, write_value=0):
97         """Read data from SPI and into the buffer"""
98         end = end if end else len(buf)
99         if int(self._novaCMDVer) >= 1:
100             chunks, rest = divmod(end - start, self.WHR_PAYLOAD_MAX_LENGTH)
101             i = 0
102             for i in range(chunks):
103                 chunk_start = start + i * self.WHR_PAYLOAD_MAX_LENGTH
104                 chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
105                 result = self._nova.writeToReadFromSPI(
106                     0, False, True, chunk_end - chunk_start, write_value
107                 )
108                 if result != "-NG":
109                     resp = result.split(" ")
110                     resp = resp[2]
111                     # loop over half of resp len as we're reading 2 chars at a time to form a byte
112                     loops = int(len(resp) / 2)
113                     for j in range(loops):
114                         buf[(i * self.WHR_PAYLOAD_MAX_LENGTH) + start + j] = int(
115                             resp[j * 2] + resp[j * 2 + 1], 16
116                         )
117                 else:
118                     raise RuntimeError(
119                         "Received error response from Binho Nova, result = " + result
120                     )
121             if rest:
122                 result = self._nova.writeToReadFromSPI(
123                     0, False, True, rest, write_value
124                 )
125                 if result != "-NG":
126                     resp = result.split(" ")
127                     resp = resp[2]
128
129                     # loop over half of resp len as we're reading 2 chars at a time to form a byte
130                     loops = int(len(resp) / 2)
131                     for j in range(loops):
132                         buf[(i * self.WHR_PAYLOAD_MAX_LENGTH) + start + j] = int(
133                             resp[j * 2] + resp[j * 2 + 1], 16
134                         )
135                 else:
136                     raise RuntimeError(
137                         "Received error response from Binho Nova, result = " + result
138                     )
139         else:
140             for i in range(start, end):
141                 buf[start + i] = int(
142                     self.get_received_data(self._nova.transferSPI(0, write_value))
143                 )
144
145     # pylint: disable=too-many-arguments,too-many-locals,too-many-branches
146     def write_readinto(
147         self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
148     ):
149         """Perform a half-duplex write from buffer_out and then
150         read data into buffer_in
151         """
152         out_end = out_end if out_end else len(buffer_out)
153         in_end = in_end if in_end else len(buffer_in)
154         readlen = in_end - in_start
155         writelen = out_end - out_start
156         if readlen > writelen:
157             # resize out and pad with 0's
158             tmp = bytearray(buffer_out)
159             tmp.extend([0] * (readlen - len(buffer_out)))
160             buffer_out = tmp
161
162         if int(self._novaCMDVer) >= 1:
163             chunks, rest = divmod(len(buffer_out), self.WHR_PAYLOAD_MAX_LENGTH)
164             i = 0
165             for i in range(chunks):
166                 chunk_start = out_start + i * self.WHR_PAYLOAD_MAX_LENGTH
167                 chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
168                 result = self._nova.writeToReadFromSPI(
169                     0,
170                     True,
171                     True,
172                     chunk_end - chunk_start,
173                     buffer_out[chunk_start:chunk_end],
174                 )
175
176                 if result != "-NG":
177                     resp = result.split(" ")
178                     resp = resp[2]
179
180                     # loop over half of resp len as we're reading 2 chars at a time to form a byte
181                     loops = int(len(resp) / 2)
182                     for j in range(loops):
183                         buffer_in[
184                             (i * self.WHR_PAYLOAD_MAX_LENGTH) + in_start + j
185                         ] = int(resp[j * 2] + resp[j * 2 + 1], 16)
186                 else:
187                     raise RuntimeError(
188                         "Received error response from Binho Nova, result = " + result
189                     )
190             if rest:
191                 result = self._nova.writeToReadFromSPI(
192                     0, True, True, rest, buffer_out[-1 * rest :]
193                 )
194                 if result != "-NG":
195                     resp = result.split(" ")
196                     resp = resp[2]
197
198                     # loop over half of resp len as we're reading 2 chars at a time to form a byte
199                     loops = int(len(resp) / 2)
200                     for j in range(loops):
201                         buffer_in[
202                             (i * self.WHR_PAYLOAD_MAX_LENGTH) + in_start + j
203                         ] = int(resp[j * 2] + resp[j * 2 + 1], 16)
204                 else:
205                     raise RuntimeError(
206                         "Received error response from Binho Nova, result = " + result
207                     )
208             print(buffer_in)
209         else:
210             for data_out in buffer_out:
211                 data_in = int(
212                     self.get_received_data(self._nova.transferSPI(0, data_out))
213                 )
214                 if i < readlen:
215                     buffer_in[in_start + i] = data_in
216                 i += 1
217
218     # pylint: enable=too-many-arguments,too-many-locals,too-many-branches