]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_linux/spi.py
Update bpim2zero.py
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / generic_linux / spi.py
1 """Generic Linux SPI class using PureIO's SPI class"""
2 import Adafruit_PureIO.spi as spi
3 from adafruit_blinka.agnostic import detector
4
5
6 class SPI:
7     """SPI Class"""
8
9     MSB = 0
10     LSB = 1
11     CPHA = 1
12     CPOL = 2
13
14     baudrate = 100000
15     mode = 0
16     bits = 8
17
18     def __init__(self, portid):
19         if isinstance(portid, tuple):
20             self._spi = spi.SPI(device=portid)
21         else:
22             self._spi = spi.SPI(device=(portid, 0))
23         self.clock_pin = None
24         self.mosi_pin = None
25         self.miso_pin = None
26         self.chip = None
27
28     # pylint: disable=too-many-arguments,unused-argument
29     def init(
30         self,
31         baudrate=100000,
32         polarity=0,
33         phase=0,
34         bits=8,
35         firstbit=MSB,
36         sck=None,
37         mosi=None,
38         miso=None,
39     ):
40         """Initialize SPI"""
41         mode = 0
42         if polarity:
43             mode |= self.CPOL
44         if phase:
45             mode |= self.CPHA
46         self.baudrate = baudrate
47         self.mode = mode
48         self.bits = bits
49         self.chip = detector.chip
50
51         # Pins are not used
52         self.clock_pin = sck
53         self.mosi_pin = mosi
54         self.miso_pin = miso
55
56     # pylint: enable=too-many-arguments,unused-argument
57
58     # pylint: disable=unnecessary-pass
59     def set_no_cs(self):
60         """Setting so that SPI doesn't automatically set the CS pin"""
61         # No kernel seems to support this, so we're just going to pass
62         pass
63
64     # pylint: enable=unnecessary-pass
65
66     @property
67     def frequency(self):
68         """Return the current baudrate"""
69         return self.baudrate
70
71     def write(self, buf, start=0, end=None):
72         """Write data from the buffer to SPI"""
73         if not buf:
74             return
75         if end is None:
76             end = len(buf)
77         try:
78             # self._spi.open(self._port, 0)
79             self.set_no_cs()
80             self._spi.max_speed_hz = self.baudrate
81             self._spi.mode = self.mode
82             self._spi.bits_per_word = self.bits
83             self._spi.writebytes(buf[start:end])
84             # self._spi.close()
85         except FileNotFoundError:
86             print("Could not open SPI device - check if SPI is enabled in kernel!")
87             raise
88
89     def readinto(self, buf, start=0, end=None, write_value=0):
90         """Read data from SPI and into the buffer"""
91         if not buf:
92             return
93         if end is None:
94             end = len(buf)
95         try:
96             # self._spi.open(self._port, 0)
97             # self.set_no_cs()
98             self._spi.max_speed_hz = self.baudrate
99             self._spi.mode = self.mode
100             self._spi.bits_per_word = self.bits
101             data = self._spi.transfer([write_value] * (end - start))
102             for i in range(end - start):  # 'readinto' the given buffer
103                 buf[start + i] = data[i]
104             # self._spi.close()
105         except FileNotFoundError:
106             print("Could not open SPI device - check if SPI is enabled in kernel!")
107             raise
108
109     # pylint: disable=too-many-arguments
110     def write_readinto(
111         self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
112     ):
113         """Perform a half-duplex write from buffer_out and then
114         read data into buffer_in
115         """
116         if not buffer_out or not buffer_in:
117             return
118         if out_end is None:
119             out_end = len(buffer_out)
120         if in_end is None:
121             in_end = len(buffer_in)
122         if out_end - out_start != in_end - in_start:
123             raise RuntimeError("Buffer slices must be of equal length.")
124         try:
125             # self._spi.open(self._port, 0)
126             # self.set_no_cs()
127             self._spi.max_speed_hz = self.baudrate
128             self._spi.mode = self.mode
129             self._spi.bits_per_word = self.bits
130             data = self._spi.transfer(list(buffer_out[out_start : out_end + 1]))
131             for i in range((in_end - in_start)):
132                 buffer_in[i + in_start] = data[i]
133             # self._spi.close()
134         except FileNotFoundError:
135             print("Could not open SPI device - check if SPI is enabled in kernel!")
136             raise
137
138     # pylint: enable=too-many-arguments