class MCP3008(object): """ MCP3008 ADC (Analogue-to-Digital converter). """ def __init__(self, bus=0, device=0, channel=0): self.bus = bus self.device = device self.channel = channel self.spi = SpiDev() def __enter__(self): self.open() return self def open(self): self.spi.open(self.bus, self.device) def read(self): adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def __exit__(self, type, value, traceback): self.close() def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1000000 # 1MHz def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def read_7(self, channel): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3208: def __init__(self, bus=0, device=0, channel=0): self.bus, self.device, self.channel = bus, device, channel self.spi = SpiDev() def __enter__(self): self.open() self.spi.max_speed_hz = 200000 return self def open(self): self.spi.open(self.bus, self.device) def read(self): if self.channel > 7 or self.channel < 0: return -1 adc = self.spi.xfer2([(24 + self.channel) << 2, 0, 0]) data = (adc[1] << 4) | (adc[2] >> 4) return data def __exit__(self, type, value, traceback): self.close() def close(self): self.spi.close()
class SPI: def __init__(self, bus_index: int, dev_index: int, freq: int = DEFAULT_FREQ): self.bus = bus_index self.dev = dev_index self.freq = freq self._spi = None self._open() def __del__(self): self._close() def _open(self): if not self._spi: self._spi = SpiDev() try: self._spi.open(self.bus, self.dev) except FileNotFoundError: raise SPIError(self.bus, self.dev) self._spi.max_speed_hz = self.freq def _close(self): if self._spi: self._spi.close() self._spi = None def send(self, data: Union[bytes, List[int]]): self._spi.writebytes2(bytes(data))
class MCP3008: def __init__(self, bus=0, device=0): self.spi = SpiDev() self.spi.open(bus, device) #Connect to the specified SPI device (CS) ############################### Read ###################################### # Input: the channel to read from (default is 0) # Output: raw digital ADc reading # Remarks: Technical Note: this is a 12-bit ADC ########################################################################### def read(self, channel=0): # to initiate communication with MCP, send 3 bytes # 0000 0001 | 0 0 0 0 0000 | 0000 00000 # start bit | SNGL/DIFF D2 D1 D0 XXXX | XXXX XXXXX # Perform SPI transaction. CS on RPi will be held active between blocks adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) # (0000 1000 + channel) << 4 # ???? ?nullB9B8 | B7B6B5B4 B3B2B1B0 # bitmask: keep B9B0 and shift'em to the beginning, the resulted integer + last byte value return ((adc[1] & 3) << 8) + adc[2] ############################### Close ###################################### # Disconnects from the interface. ########################################################################### def close(self): self.spi.close()
class HWSPI(SPI): """ Hardware SPI """ def __init__(self, device, ce, config): """ Args: device (int): the number of SPI device ce (int): the number of chip select of SPI device config (SPIConfig): """ self._device = device self._ce = ce self._config = config self._spi = SpiDev() def open(self): logger.info("Open SPI(%d,%d)", self._device, self._ce) self._spi.open(self._device, self._ce) self._spi.mode = self._config.mode self._spi.max_speed_hz = self._config.speed def close(self): logger.info("Close SPI(%d,%d)", self._device, self._ce) self._spi.close() def transfer(self, writedata, readsize): buf = self._spi.xfer(writedata + [0] * readsize) return buf[len(writedata):]
class MCP3008Controller(object): def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1000000 # 1MHz self.myLogger = MyLogger(self.__class__.__name__) self.myLogger.info('Init MCP3008') def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel = 0): cmd1 = 4 | 2 | (( channel & 4) >> 2) cmd2 = (channel & 3) << 6 adc = self.spi.xfer2([cmd1, cmd2, 0]) self.myLogger.debug("Read SPI: %s" % adc) data = ((adc[1] & 15) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1000000 # 1MHz def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel): #print channel # cmd1 = 4 | 2 | (( channel & 4) >> 2) # print cmd1 # cmd2 = (channel & 3) << 6 # # adc = self.spi.xfer2([cmd1, cmd2, 0]) # print adc # data = ((adc[1] & 15) << 8) + adc[2]''' adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] # print data return data def read_7(self, channel): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] #print data return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, dev=0, max_speed_hz=7629): self.bus = bus self.dev = dev self.max_speed_hz = max_speed_hz self.spi = SpiDev() def __enter__(self): self.open() return self def __exit__(self, type, value, traceback): self.close() def read(self, ch=0): if ch > 7 or ch < 0: return -1 r = self.spi.xfer2([1, 8 + ch << 4, 0]) data = ((r[1] & 3) << 8) + r[2] return data def open(self): self.spi.open(self.bus, self.dev) self.spi.max_speed_hz = self.max_speed_hz def close(self): self.spi.close()
class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1000000 # 1MHz def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel = 0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def read_all(self): data = [] for i in range(8): adc = self.spi.xfer2([1, (8 + i) << 4, 0]) data.append(((adc[1] & 3) << 8) + adc[2]) return data def read_3(self): data = [] for i in range(3): adc = self.spi.xfer2([1, (8 + i) << 4, 0]) data.append(((adc[1] & 3) << 8) + adc[2]) return data def close(self): self.spi.close()
class SPIDataLink(DataLink): """Clase que gestiona un enlace Serial Peripheral Interface (SPI). :param max_speed: máxima velocidad en herzios del enlace de datos. :param bus: Identificador del bus SPI que se usa para el enlace de datos. :param device: Línea de selección de chip SPI activa en el enlace de datos. Ejemplo de uso para pedir una medida del primer canal analógico de un conversor ADC MCP3202 conectado a la línea de selección de chip 0 de Raspberry Pi: >>> from pida.links import SPIDataLink >>> link = SPIDataLink(1000000, 0, 0) >>> link.open() >>> request = [1, 2 << 6, 0] >>> response = link.transfer(request) >>> link.close() """ def __init__(self, max_speed, bus, device): DataLink.__init__(self, max_speed) self._bus = bus self._device = device self._spi = SpiDev() @property def bus(self): """Identificador del bus SPI que se usa para el enlace de datos. .. note:: Raspberry Pi ofrece a través de su puerto GPIO un único bus SPI cuyo identificador es 0. Es una propiedad de sólo lectura. """ return self._bus @property def device(self): """Línea de selección de chip SPI activa en el enlace de datos. .. note:: El bus SPI 0 de Raspberry Pi puede, a través del puerto GPIO, activar dos líneas de selección de chip SPI: 0 y 1. Es una propiedad de sólo lectura. """ return self._device def open(self): self._spi.open(self._bus, self._device) self._spi.max_speed_hz = self.max_speed def close(self): self._spi.close() def transfer(self, data): return self._spi.xfer2(data)
class MCP3008: def __init__(self, bus, slave): self.__spi = SpiDev() self.__spi.open(bus, slave) self.__spi.max_speed_hz = 10**5 def read_channel(self, channel): channel = (channel * 0x10) + 0x80 value = self.__spi.xfer2([0x1, channel, 0x0]) return (value[1] & 3) << 8 | value[2] def close_bus(self): self.__spi.close()
class SpiDevice(object): def __init__(self, bus, device): self.spi = SpiDev() self.bus = bus self.device = device def init(self): self.spi.open(self.bus, self.device) def transfer(self, data): return self.spi.xfer2(data) def close(self): self.spi.close()
def read_touch_screen(channel): """Read the HackPack touchscreen coordinates.""" spi = SpiDev() spi.open(1, 0) spi.no_cs = True spi.max_speed_hz = 2000000 # Manual chip select GPIO.output(CS_TOUCH, 1) GPIO.output(CS_TOUCH, 0) responseData = spi.xfer([channel, 0, 0]) GPIO.output(CS_TOUCH, 1) spi.close() return (responseData[1] << 5) | (responseData[2] >> 3)
def value_to_percent(channel=0): spi = SpiDev() spi.open(0, 0) spi.max_speed_hz = 20**5 spi_data = spi.xfer2([1, (8 + channel) << 4, 0]) spi.close() licht_waarde = int((spi_data[1] << 8) + spi_data[2]) licht_percent = round((licht_waarde / 1023 * 100), 2) digitale_waarde = float((spi_data[1] << 8) + spi_data[2]) # decibels = round((digitale_waarde+83.2073) /11.003 , 2) decibels = (20.0 * math.log10(digitale_waarde / 5.0)) # return print("lichtsterkte: ", licht_percent) return print("decibels: ", decibels)
class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) def read(self, channel = 0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class _SpiDeviceWrapper(object): """A wrapper around a SPI device to share the same device between multiple objects.""" def __init__(self, bus=0, device=0): self.spi = SpiDev() self.bus = bus self.device = device def __del__(self): self.spi.close() def __call__(self, channel): if self.spi.fileno() == -1: self.spi.open(self.bus, self.device) return _Light_MCP3008(self.spi, channel)
class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) def read(self, channel = 0): adc = self.spi.xfer2([6|(Channel&4)>>2,(Channel&3)<<6,0]) data = ((adc[1] & 15) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) def read(self, channel=0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) self.spi.max_speed_hz = 700000 #alterei a frequencia do SPI data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0, channel=0): self.bus, self.device = bus, device self.channel = channel self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) def read(self): adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus = bus self.device = device self.spi = SpiDev() def read_channel(self, ch): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = int(10e5) commando_bytes = [1, (8 | ch) << 4, 0] val = self.spi.xfer2(commando_bytes) self.spi.close() # print("MCP MSB: {}".format(bin(val[1]))) # print("MCP LSB: {}".format(bin(val[2]))) val = ((val[1] & 3) << 8) | val[2] # print("MCP VALUE: {}".format(bin(val))) return val
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) def read(self, channel=0): self.spi.max_speed_hz = 135000 adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) #print(adc) - debug data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: """Convertisseur analogique numerique""" def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() self.spi.max_speed_hz = 1350000 self.spi.mode = 0b11 def open(self): self.spi.open(self.bus, self.device) def read(self, channel=0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.abrir() def abrir(self): self.spi.open(self.bus, self.device) def leer(self, channel): if ((channel > 7) or (channel < 0)): return -1 self.spi.max_speed_hz = 1350000 adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def cerrar(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() # Creation object spi self.open() self.spi.max_speed_hz = 1350000 self.spi.mode = 0b11 def open(self): """ Ouverture port 0 , chip select 0""" self.spi.open(self.bus, self.device) def read(self, channel=0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) def read(self, adc_channel=0): # 0-7 channels available only if ((adc_channel > 7) or (adc_channel < 0)): return -1 r = self.spi.xfer2([1, (8 + adc_channel) << 4, 0]) adc_output = ((r[1] & 3) << 8) + r[2] return adc_output def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) # doesn't seem to work without this # https://www.takaitra.com/spi-device-raspberry-pi/ self.spi.max_speed_hz = 1350000 def read(self, channel=0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3202: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 self.spi.mode = 0b00 def read(self, channel=0): self.spi.max_speed_hz = 1000000 self.spi.mode = 0b00 adc = self.spi.xfer2([1, (0b10100000 + (channel << 6)), 0]) data = (((adc[1] & 0b1111) << 8) + adc[2]) * 3.3 / 4096 return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus = 0, device = 0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # 1MHz def read(self, channel = 0): cmd1 = 4 | 2 | (( channel & 4) >> 2) cmd2 = (channel & 3) << 6 adc = self.spi.xfer2([cmd1, cmd2, 0]) data = ((adc[1] & 15) << 8) + adc[2] return data def close(self): self.spi.close()
class MCP3008: def __init__(self, bus=0, device=0): self.bus, self.device = bus, device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 # ab Raspbian-Version "Buster" erforderlich! def read(self, channel=0): adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) if 0 <= adc[1] <= 3: data = ((adc[1] & 3) << 8) + adc[2] return data else: return 0 def close(self): self.spi.close()
class SPI2ADC: def __init__(self, bus=0, device=0): self.bus = bus self.device = device self.spi = SpiDev() self.open() def open(self): self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 def read(self, channel = 0): adc = self.spi.xfer([0xbe, 0xef]) #adc = self.spi.xfer2([0x01, 0x08, 0]) #data = ((adc[1] & 3) << 8) + adc[2] return adc #return data def close(self): self.spi.close()
class MCP3008(MyCommon): #---------- MCP3008::init ------------------------------------------------- def __init__(self, bus=0, device=0, log=None): self.log = log self.console = None self.bus, self.device = bus, device try: self.spi = SpiDev() self.open() self.spi.max_speed_hz = 250000 # 250kHz except Exception as e1: self.LogErrorLine("Error in MPC308 init: " + str(e1)) self.FatalError( "Error on opening SPI device: enable SPI or install CT HAT") #---------- MCP3008::open ------------------------------------------------- def open(self): try: self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 250000 # 250kHz except Exception as e1: self.LogErrorLine("Error in MPC308 open: " + str(e1)) #---------- MCP3008::read ------------------------------------------------- def read(self, channel=0): try: adc = self.spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data except Exception as e1: self.LogErrorLine("Error in MPC308 read: " + str(e1)) #---------- MCP3008::close ------------------------------------------------ def close(self): try: self.spi.close() except Exception as e1: self.LogErrorLine("Error in MPC308 close: " + str(e1))
class MCP3008: def __init__(self, bus = 0, device = 0, channel = 0): self.bus, self.device, self.channel = bus, device, channel self.spi = SpiDev() def __enter__(self): self.open() return self def open(self): self.spi.open(self.bus, self.device) def read(self): adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def __exit__(self, type, value, traceback): self.close() def close(self): self.spi.close()
class ADC: """Analog joystick attached to a MCP3008 A/D converter.""" def __init__( self, bus=1, channel=0, device=1, ): """Define which SPI device is the A/D Converter on.""" self.bus = bus self.device = device self.channel = channel self.spi = SpiDev() def open(self): """Claim the SPI channel when asked.""" self.spi.open(self.bus, self.device) self.spi.max_speed_hz = 1000000 self.spi.mode = 0b00 def read(self): """Ask the device for a reading on a channel.""" adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def close_spi(self): """Close the SPI channel when asked.""" self.spi.close() def __enter__(self): """Magic function if you use 'with'.""" self.open() return self def __exit__(self, type, value, traceback): """Magic function if you use 'with'.""" self.close_spi()
class Temperature(object): def __init__(self, major=0, minor=0): self.spi = SpiDev() self.spi.open(major, minor) def rawread(self): return self.spi.xfer2([0, 0]) def read(self): return self.calc_temp(self.rawread()) @staticmethod def calc_temp(buf): return (((buf[0] << 8) | buf[1]) >> 3) * 0.0625 def cleanup(self): self.spi.close() def __enter__(self): return self def __exit__(self, type_, value, traceback): self.cleanup()
print "read eeprom" cmd = [0x03, 0] + [0 for i in range(8*16)] res = spi.xfer2(cmd) print res if __name__ == "__main__": GPIO.setup("P9_11", GPIO.OUT) GPIO.setup("P9_12", GPIO.OUT) GPIO.setup("P9_13", GPIO.OUT) GPIO.setup("P9_14", GPIO.OUT) GPIO.setup("P9_15", GPIO.OUT) #spi = SPI() #spi.open(0, 0) #spi.msh = 0 spi = SpiDev(1,0) spi.mode = 3 spi.max_speed_hz = 100000 check_eeprom_status() write_eeprom(3, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) GPIO.cleanup() spi.close()
class LocalPiHardwareSPI(SPI, Device): def __init__(self, factory, port, device): self._port = port self._device = device self._interface = None if SpiDev is None: raise ImportError('failed to import spidev') super(LocalPiHardwareSPI, self).__init__() pins = SPI_HARDWARE_PINS[port] self.pin_factory.reserve_pins( self, pins['clock'], pins['mosi'], pins['miso'], pins['select'][device] ) self._interface = SpiDev() self._interface.open(port, device) self._interface.max_speed_hz = 500000 def close(self): if getattr(self, '_interface', None): self._interface.close() self._interface = None self.pin_factory.release_all(self) super(LocalPiHardwareSPI, self).close() @property def closed(self): return self._interface is None def __repr__(self): try: self._check_open() return 'SPI(port=%d, device=%d)' % (self._port, self._device) except DeviceClosed: return 'SPI(closed)' def transfer(self, data): """ Writes data (a list of integer words where each word is assumed to have :attr:`bits_per_word` bits or less) to the SPI interface, and reads an equivalent number of words, returning them as a list of integers. """ return self._interface.xfer2(data) def _get_clock_mode(self): return self._interface.mode def _set_clock_mode(self, value): self._interface.mode = value def _get_lsb_first(self): return self._interface.lsbfirst def _set_lsb_first(self, value): self._interface.lsbfirst = bool(value) def _get_select_high(self): return self._interface.cshigh def _set_select_high(self, value): self._interface.cshigh = bool(value) def _get_bits_per_word(self): return self._interface.bits_per_word def _set_bits_per_word(self, value): self._interface.bits_per_word = value
class Matrix(object): ''' The class which models the operation of the Olimex 8x8 RGB LED matrix. The numbering scheme used when defining the pins are with respect to the BCM numbering scheme. Wiring: - VCC = driving voltage for the matrix. 5 volts. - GND = ground connection from the matrix. - DIN = data in for the matrix, GPIO pin 10 (SPI MOSI). - CS = chip select, depending on SPI channel selection. - CLK = serial clock, GPIO pin 11 (SPI SCK). ''' def __init__(self, spidevice=0): ''' Basic constructor for our driver class. @param: spidevice - the SPI device to be used. Acts as a chip-enable. The Raspberry PI B+ has two such device output pins in-built. Defaults to 0. @return: None ''' if spidevice != 1: spidevice = 0 self.__spi = SpiDev() self.__spi.mode = 0b01 self.__spi.open(0, spidevice) self.__buffer = [0] * 24 def drawpixel(self, pixel): ''' Draws a given Pixel object to the internal buffer. The buffer is formed of 24 bytes. Each byte represents a single color, the n'th bit being whether that particular color is active in the n'th led of that row. The colors are ordered in reverse. (BGR). @param: pixel - a Pixel object. @return: the Pixel encoded as a byte. ''' # current row we're on: row = 3 * pixel.y # clear currently present color by unsetting the corresponding bit from # the three color bytes: self.__buffer[row] &= ~(1 << pixel.x) # clear red. self.__buffer[row + 1] &= ~(1 << pixel.x) # clear green. self.__buffer[row + 2] &= ~(1 << pixel.x) # clear blue. # set red bit for this pixel, if necessary: if pixel.color in [Color.red, Color.white, Color.brown, Color.purple]: self.__buffer[row] |= 1 << pixel.x # set green bit: if pixel.color in [Color.green, Color.white, Color.turquoise, Color.brown]: self.__buffer[row + 1] |= 1 << pixel.x # set blue bit: if pixel.color in [Color.blue, Color.white, Color.turquoise, Color.purple]: self.__buffer[row + 2] |= 1 << pixel.x def write(self): ''' Serially writes the whole of the video buffer to the matrix. ''' self.__spi.xfer(self.__buffer) def clear(self): ''' Clears both the internal buffer and the matrix. ''' self.__buffer = [0] * 24 self.write() def cleanup(self): ''' Clears all registers and terminates the SPI connection. ''' self.clear() self.__spi.close()
class SPIDataLink(FullDuplexDataLink): """Clase que gestiona un enlace Serial Peripheral Interface (SPI). :param bus: Identificador del bus SPI que se usa para el enlace de datos. :param device: Línea de selección de chip SPI activa en el enlace de datos. :param configuration: Configuración del enlace de datos Ejemplo de uso: >>> from pida.links import SPIDataLinkConfiguration, SPIDataLink >>> configuration = SPIDataLinkConfiguration(mode=0, max_speed_hz=32000000) >>> with SPIDataLink(0, 0, configuration) as link: request = [0x00, 0x01, 0xFF] response = link.transfer(request) >>> response [0, 1, 255] """ def __init__(self, bus, device, configuration): self._bus = bus self._device = device self._configuration = configuration self._spi = SpiDev() def _apply_configuration(self): self._spi.mode = self._configuration.mode self._spi.max_speed_hz = self._configuration.max_speed_hz @property def bus(self): """Identificador del bus SPI que se usa para el enlace de datos. .. note:: Raspberry Pi ofrece a través de su puerto GPIO un único bus SPI cuyo identificador es 0. Es una propiedad de sólo lectura. """ return self._bus @property def device(self): """Línea de selección de chip SPI activa en el enlace de datos. .. note:: El bus SPI 0 de Raspberry Pi puede, a través del puerto GPIO, activar dos líneas de selección de chip SPI: 0 y 1. Es una propiedad de sólo lectura. """ return self._device def open(self): self._spi.open(self._bus, self._device) self._apply_configuration() def close(self): self._spi.close() def transfer(self, data): return self._spi.xfer2(data) def __enter__(self): self.open() return self def __exit__(self, exc_type, exc_val, exc_tb): self.close() @property def max_speed_hz(self): return self._configuration.max_speed_hz @property def mode(self): return self._configuration.mode
class CpPhy(object): # Profibus baud-rates PB_PHY_BAUD_9600 = 0 PB_PHY_BAUD_19200 = 1 PB_PHY_BAUD_45450 = 2 PB_PHY_BAUD_93750 = 3 PB_PHY_BAUD_187500 = 4 PB_PHY_BAUD_500000 = 5 PB_PHY_BAUD_1500000 = 6 PB_PHY_BAUD_3000000 = 7 PB_PHY_BAUD_6000000 = 8 PB_PHY_BAUD_12000000 = 9 # RTS mode PB_PHY_RTS_ALWAYS_LO = 0 PB_PHY_RTS_ALWAYS_HI = 1 PB_PHY_RTS_SENDING_HI = 2 PB_PHY_RTS_SENDING_LO = 3 # GPIO numbers (BCM) GPIO_RESET = 17 GPIO_IRQ = 27 GPIO_SS = 8 GPIO_MISO = 9 GPIO_MOSI = 10 GPIO_SCK = 11 baud2id = { 9600 : PB_PHY_BAUD_9600, 19200 : PB_PHY_BAUD_19200, 45450 : PB_PHY_BAUD_45450, 93750 : PB_PHY_BAUD_93750, 187500 : PB_PHY_BAUD_187500, 500000 : PB_PHY_BAUD_500000, 1500000 : PB_PHY_BAUD_1500000, 3000000 : PB_PHY_BAUD_3000000, 6000000 : PB_PHY_BAUD_6000000, 12000000 : PB_PHY_BAUD_12000000, } def __init__(self, device=0, chipselect=0, debug=False): self.device = device self.chipselect = chipselect self.debug = debug try: try: # Initialize GPIOs GPIO.setmode(GPIO.BCM) # Use Broadcom numbers GPIO.setwarnings(False) GPIO.setup(self.GPIO_RESET, GPIO.OUT, initial=GPIO.LOW) GPIO.setup(self.GPIO_IRQ, GPIO.IN, pull_up_down=GPIO.PUD_OFF) GPIO.add_event_detect(self.GPIO_IRQ, GPIO.RISING) time.sleep(0.05) except RuntimeError as e: raise PhyError("Failed to initialize GPIOs: %s" %\ str(e)) # Initialize SPI try: self.spi = SpiDev() self.spi.open(device, chipselect) except IOError as e: raise PhyError("Failed to open SPI device %d.%d: %s" %\ (device, chipselect, str(e))) try: self.spi.mode = 0; self.spi.bits_per_word = 8; self.spi.cshigh = False self.spi.lsbfirst = False self.spi.max_speed_hz = 200000; except IOError as e: try: self.spi.close() self.spi = None except: pass raise PhyError("Failed to configure SPI device %d.%d: %s" %\ (device, chipselect, str(e))) # Get the controller out of hardware reset GPIO.output(self.GPIO_RESET, GPIO.HIGH) time.sleep(0.2) # Send a software reset self.sendReset() # Upload default config self.profibusSetPhyConfig() except: GPIO.cleanup() raise def cleanup(self): self.spi.close() self.spi = None GPIO.cleanup() # Poll for received packet. # timeout => In seconds. 0 = none, Negative = unlimited. def poll(self, timeout=0): limit = TimeLimited(timeout) while GPIO.event_detected(self.GPIO_IRQ): if limit.exceed(): return None limit.sleep(0.001) limit.add(0.5) while not limit.exceed(): fc = self.spi.readbytes(1)[0] if fc != CpPhyMessage.RPI_PACK_NOP: break else: return None reply = [ fc ] reply.extend(self.spi.readbytes(CpPhyMessage.RASPI_PACK_HDR_LEN - 1)) payloadLen = reply[1] & 0xFF if payloadLen: reply.extend(self.spi.readbytes(payloadLen)) message = CpPhyMessage(0) message.setRawData(reply) if self.debug: print("[PHY] recv msg:", message) return message def __sendMessage(self, message): if self.debug: print("[PHY] send msg:", message) self.spi.writebytes(message.getRawData()) def sendReset(self): self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_RESET)) reply = self.poll(timeout=-1) if reply.fc != CpPhyMessage.RPI_PACK_ACK: raise PhyError("Failed to reset PHY") def profibusSetPhyConfig(self, baudrate=19200, rxTimeoutMs=100, bitErrorChecks=True, rtsMode=PB_PHY_RTS_SENDING_HI): try: baudID = self.baud2id[baudrate] except KeyError: raise PhyError("Invalid baud-rate") if rxTimeoutMs < 1 or rxTimeoutMs > 255: raise PhyError("Invalid RX timeout") payload = [ baudID, rxTimeoutMs, 1 if bitErrorChecks else 0, rtsMode & 0xFF ] message = CpPhyMessage(CpPhyMessage.RPI_PACK_SETCFG, payload) self.__sendMessage(message) reply = self.poll(timeout=-1) if reply.fc != CpPhyMessage.RPI_PACK_ACK: raise PhyError("Failed to upload config") def profibusSend_SDN(self, telegramData): self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_PB_SDN, telegramData)) def profibusSend_SRD(self, telegramData): self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_PB_SRD, telegramData))
class SPIHardwareInterface(Device): def __init__(self, port, device): self._device = None super(SPIHardwareInterface, self).__init__() # XXX How can we detect conflicts with existing GPIO instances? This # isn't ideal ... in fact, it's downright crap and doesn't guard # against conflicts created *after* this instance, but it's all I can # come up with right now ... conflicts = (11, 10, 9, (8, 7)[device]) with _PINS_LOCK: for pin in _PINS: if pin.number in conflicts: raise GPIOPinInUse( 'pin %r is already in use by another gpiozero object' % pin ) self._device_num = device self._device = SpiDev() self._device.open(port, device) self._device.max_speed_hz = 500000 def close(self): if self._device: try: self._device.close() finally: self._device = None super(SPIHardwareInterface, self).close() @property def closed(self): return self._device is None def __repr__(self): try: self._check_open() return ( "hardware SPI on clock_pin=11, mosi_pin=10, miso_pin=9, " "select_pin=%d" % ( 8 if self._device_num == 0 else 7)) except DeviceClosed: return "hardware SPI closed" def read(self, n): return self.transfer((0,) * n) def write(self, data): return len(self.transfer(data)) def transfer(self, data): """ Writes data (a list of integer words where each word is assumed to have :attr:`bits_per_word` bits or less) to the SPI interface, and reads an equivalent number of words, returning them as a list of integers. """ return self._device.xfer2(data) def _get_clock_mode(self): return self._device.mode def _set_clock_mode(self, value): self._device.mode = value def _get_clock_polarity(self): return bool(self.mode & 2) def _set_clock_polarity(self, value): self.mode = self.mode & (~2) | (bool(value) << 1) def _get_clock_phase(self): return bool(self.mode & 1) def _set_clock_phase(self, value): self.mode = self.mode & (~1) | bool(value) def _get_lsb_first(self): return self._device.lsbfirst def _set_lsb_first(self, value): self._device.lsbfirst = bool(value) def _get_select_high(self): return self._device.cshigh def _set_select_high(self, value): self._device.cshigh = bool(value) def _get_bits_per_word(self): return self._device.bits_per_word def _set_bits_per_word(self, value): self._device.bits_per_word = value clock_polarity = property(_get_clock_polarity, _set_clock_polarity) clock_phase = property(_get_clock_phase, _set_clock_phase) clock_mode = property(_get_clock_mode, _set_clock_mode) lsb_first = property(_get_lsb_first, _set_lsb_first) select_high = property(_get_select_high, _set_select_high) bits_per_word = property(_get_bits_per_word, _set_bits_per_word)