/ adafruit_bus_device / spi_device.py
spi_device.py
1 # The MIT License (MIT) 2 # 3 # Copyright (c) 2016 Scott Shawcroft for Adafruit Industries 4 # 5 # Permission is hereby granted, free of charge, to any person obtaining a copy 6 # of this software and associated documentation files (the "Software"), to deal 7 # in the Software without restriction, including without limitation the rights 8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 # copies of the Software, and to permit persons to whom the Software is 10 # furnished to do so, subject to the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included in 13 # all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 # THE SOFTWARE. 22 # pylint: disable=too-few-public-methods 23 24 """ 25 `adafruit_bus_device.spi_device` - SPI Bus Device 26 ==================================================== 27 """ 28 29 __version__ = "0.0.0-auto.0" 30 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BusDevice.git" 31 32 33 class SPIDevice: 34 """ 35 Represents a single SPI device and manages locking the bus and the device 36 address. 37 38 :param ~busio.SPI spi: The SPI bus the device is on 39 :param ~digitalio.DigitalInOut chip_select: The chip select pin object that implements the 40 DigitalInOut API. 41 :param int extra_clocks: The minimum number of clock cycles to cycle the bus after CS is high. 42 (Used for SD cards.) 43 44 .. note:: This class is **NOT** built into CircuitPython. See 45 :ref:`here for install instructions <bus_device_installation>`. 46 47 Example: 48 49 .. code-block:: python 50 51 import busio 52 import digitalio 53 from board import * 54 from adafruit_bus_device.spi_device import SPIDevice 55 56 with busio.SPI(SCK, MOSI, MISO) as spi_bus: 57 cs = digitalio.DigitalInOut(D10) 58 device = SPIDevice(spi_bus, cs) 59 bytes_read = bytearray(4) 60 # The object assigned to spi in the with statements below 61 # is the original spi_bus object. We are using the busio.SPI 62 # operations busio.SPI.readinto() and busio.SPI.write(). 63 with device as spi: 64 spi.readinto(bytes_read) 65 # A second transaction 66 with device as spi: 67 spi.write(bytes_read) 68 """ 69 70 def __init__( 71 self, 72 spi, 73 chip_select=None, 74 *, 75 baudrate=100000, 76 polarity=0, 77 phase=0, 78 extra_clocks=0 79 ): 80 self.spi = spi 81 self.baudrate = baudrate 82 self.polarity = polarity 83 self.phase = phase 84 self.extra_clocks = extra_clocks 85 self.chip_select = chip_select 86 if self.chip_select: 87 self.chip_select.switch_to_output(value=True) 88 89 def __enter__(self): 90 while not self.spi.try_lock(): 91 pass 92 self.spi.configure( 93 baudrate=self.baudrate, polarity=self.polarity, phase=self.phase 94 ) 95 if self.chip_select: 96 self.chip_select.value = False 97 return self.spi 98 99 def __exit__(self, exc_type, exc_val, exc_tb): 100 if self.chip_select: 101 self.chip_select.value = True 102 if self.extra_clocks > 0: 103 buf = bytearray(1) 104 buf[0] = 0xFF 105 clocks = self.extra_clocks // 8 106 if self.extra_clocks % 8 != 0: 107 clocks += 1 108 for _ in range(clocks): 109 self.spi.write(buf) 110 self.spi.unlock() 111 return False