1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
4 """SPI Class for NXP LPC4330"""
5 from greatfet import GreatFET
9 """Custom I2C Class for NXP LPC4330"""
15 self._frequency = None
16 self.buffer_size = 255
36 # pylint: disable=too-many-arguments,unused-argument
48 """Initialize the Port"""
49 # Figure out the mode based on phase and polarity
50 polarity = int(polarity)
52 self._mode = (polarity << 1) | phase
54 # Using API due to possible interface change
55 self._spi = self._gf.apis.spi
56 # Check baudrate against presets and adjust to the closest one
57 if self._frequency is None:
58 preset = self._find_closest_preset(baudrate)
60 preset = self._presets[self._frequency]
61 clock_prescale_rate, serial_clock_rate = preset
62 self._spi.init(serial_clock_rate, clock_prescale_rate)
64 # Set the polarity and phase (the "SPI mode").
65 self._spi.set_clock_polarity_and_phase(self._mode)
67 # pylint: enable=too-many-arguments
69 def _find_closest_preset(self, target_frequency):
70 """Loop through self._frequencies and find the closest
71 setting. Return the preset values and set the frequency
75 for frequency, preset in self._presets.items():
76 if self._frequency is None or abs(frequency - target_frequency) < abs(
77 self._frequency - target_frequency
79 self._frequency = frequency
80 closest_preset = preset
86 """Return the current frequency"""
87 return self._frequency
89 def write(self, buf, start=0, end=None):
90 """Write data from the buffer to SPI"""
91 end = end if end else len(buf)
92 self._transmit(buf[start:end])
94 # pylint: disable=unused-argument
95 def readinto(self, buf, start=0, end=None, write_value=0):
96 """Read data from SPI and into the buffer"""
97 end = end if end else len(buf)
98 result = self._transmit([write_value] * (end - start), end - start)
99 for i, b in enumerate(result):
102 # pylint: enable=unused-argument
104 # pylint: disable=too-many-arguments
106 self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
108 """Perform a half-duplex write from buffer_out and then
109 read data into buffer_in
111 out_end = out_end if out_end else len(buffer_out)
112 in_end = in_end if in_end else len(buffer_in)
114 result = self._transmit(buffer_out[out_start:out_end], in_end - in_start)
115 for i, b in enumerate(result):
116 buffer_in[in_start + i] = b
118 # pylint: enable=too-many-arguments
120 def _transmit(self, data, receive_length=None):
121 data_to_transmit = bytearray(data)
122 data_received = bytearray()
124 if receive_length is None:
125 receive_length = len(data)
127 # If we need to receive more than we've transmitted, extend the data out.
128 if receive_length > len(data):
129 padding = receive_length - len(data)
130 data_to_transmit.extend([0] * padding)
132 # Transmit our data in chunks of the buffer size.
133 while data_to_transmit:
134 # Extract a single data chunk from the transmit buffer.
135 chunk = data_to_transmit[0 : self.buffer_size]
136 del data_to_transmit[0 : self.buffer_size]
138 # Finally, exchange the data.
139 response = self._spi.clock_data(len(chunk), bytes(chunk))
140 data_received.extend(response)
142 # Once we're done, return the data received.
143 return bytes(data_received)