Factor out hardware SPI pin numbers; this is a effectively a rebase (and
minor modification) of @lurch's original patch which conflicted after
the merge of the remote-spi branch.
This commit is contained in:
Dave Jones
2017-06-20 23:16:59 +01:00
parent a10c037f64
commit 1022b0b0de
3 changed files with 58 additions and 32 deletions

View File

@@ -15,7 +15,7 @@ except ImportError:
SpiDev = None SpiDev = None
from . import SPI from . import SPI
from .pi import PiFactory, PiPin from .pi import PiFactory, PiPin, SPI_HARDWARE_PINS
from .spi import SPISoftwareBus from .spi import SPISoftwareBus
from ..devices import Device, SharedMixin from ..devices import Device, SharedMixin
from ..output_devices import OutputDevice from ..output_devices import OutputDevice
@@ -81,11 +81,12 @@ class LocalPiHardwareSPI(SPI, Device):
self._interface = None self._interface = None
self._address = factory.address + ('SPI(port=%d, device=%d)' % (port, device),) self._address = factory.address + ('SPI(port=%d, device=%d)' % (port, device),)
super(LocalPiHardwareSPI, self).__init__() super(LocalPiHardwareSPI, self).__init__()
pins = SPI_HARDWARE_PINS[port]
self._reserve_pins( self._reserve_pins(
factory.pin_address(11), factory.pin_address(pins['clock']),
factory.pin_address(10), factory.pin_address(pins['mosi']),
factory.pin_address(9), factory.pin_address(pins['miso']),
factory.pin_address((8, 7)[device]) factory.pin_address(pins['select'][device])
) )
self._interface = SpiDev() self._interface = SpiDev()
self._interface.open(port, device) self._interface.open(port, device)

View File

@@ -32,6 +32,16 @@ from ..exc import (
) )
SPI_HARDWARE_PINS = {
0: {
'clock': 11,
'mosi': 10,
'miso': 9,
'select': (8, 7),
},
}
class PiFactory(Factory): class PiFactory(Factory):
""" """
Abstract base class representing hardware attached to a Raspberry Pi. This Abstract base class representing hardware attached to a Raspberry Pi. This
@@ -105,21 +115,24 @@ class PiFactory(Factory):
if kwargs: if kwargs:
raise SPIBadArgs( raise SPIBadArgs(
'unrecognized keyword argument %s' % kwargs.popitem()[0]) 'unrecognized keyword argument %s' % kwargs.popitem()[0])
if all(( for port, pins in SPI_HARDWARE_PINS.items():
spi_args['clock_pin'] == 11, if all((
spi_args['mosi_pin'] == 10, spi_args['clock_pin'] == pins['clock'],
spi_args['miso_pin'] == 9, spi_args['mosi_pin'] == pins['mosi'],
spi_args['select_pin'] in (7, 8), spi_args['miso_pin'] == pins['miso'],
)): spi_args['select_pin'] in pins['select'],
try: )):
return self.spi_classes[('hardware', shared)]( try:
self, port=0, device=0 if spi_args['select_pin'] == 8 else 1 return self.spi_classes[('hardware', shared)](
) self, port=port,
except Exception as e: device=pins['select'].index(spi_args['select_pin'])
warnings.warn( )
SPISoftwareFallback( except Exception as e:
'failed to initialize hardware SPI, falling back to ' warnings.warn(
'software (error was: %s)' % str(e))) SPISoftwareFallback(
'failed to initialize hardware SPI, falling back to '
'software (error was: %s)' % str(e)))
break
# Convert all pin arguments to integer GPIO numbers. This is necessary # Convert all pin arguments to integer GPIO numbers. This is necessary
# to ensure the shared-key for shared implementations get matched # to ensure the shared-key for shared implementations get matched
# correctly, and is a bit of a hack for the pigpio bit-bang # correctly, and is a bit of a hack for the pigpio bit-bang
@@ -139,16 +152,17 @@ class PiFactory(Factory):
Returns a tuple of ``(spi_args, other_args)``. Returns a tuple of ``(spi_args, other_args)``.
""" """
pin_defaults = {
'clock_pin': 11,
'mosi_pin': 10,
'miso_pin': 9,
'select_pin': 8,
}
dev_defaults = { dev_defaults = {
'port': 0, 'port': 0,
'device': 0, 'device': 0,
} }
default_hw = SPI_HARDWARE_PINS[dev_defaults['port']]
pin_defaults = {
'clock_pin': default_hw['clock'],
'mosi_pin': default_hw['mosi'],
'miso_pin': default_hw['miso'],
'select_pin': default_hw['select'][dev_defaults['device']],
}
spi_args = { spi_args = {
key: value for (key, value) in kwargs.items() key: value for (key, value) in kwargs.items()
if key in pin_defaults or key in dev_defaults if key in pin_defaults or key in dev_defaults
@@ -171,10 +185,15 @@ class PiFactory(Factory):
} }
if spi_args['port'] != 0: if spi_args['port'] != 0:
raise SPIBadArgs('port 0 is the only valid SPI port') raise SPIBadArgs('port 0 is the only valid SPI port')
if spi_args['device'] not in (0, 1): selected_hw = SPI_HARDWARE_PINS[spi_args['port']]
raise SPIBadArgs('device must be 0 or 1') try:
selected_hw['select'][spi_args['device']]
except IndexError:
raise SPIBadArgs(
'device must be in the range 0..%d' %
len(selected_hw['select']))
spi_args = { spi_args = {
key: value if key != 'select_pin' else (8, 7)[spi_args['device']] key: value if key != 'select_pin' else selected_hw['select'][spi_args['device']]
for key, value in pin_defaults.items() for key, value in pin_defaults.items()
} }
else: else:

View File

@@ -12,7 +12,7 @@ from weakref import proxy
import pigpio import pigpio
from . import SPI from . import SPI
from .pi import PiPin, PiFactory from .pi import PiPin, PiFactory, SPI_HARDWARE_PINS
from .data import pi_info from .data import pi_info
from ..devices import Device from ..devices import Device
from ..mixins import SharedMixin from ..mixins import SharedMixin
@@ -299,10 +299,16 @@ class PiGPIOHardwareSPI(SPI, Device):
self._factory = proxy(factory) self._factory = proxy(factory)
self._handle = None self._handle = None
super(PiGPIOHardwareSPI, self).__init__() super(PiGPIOHardwareSPI, self).__init__()
pins = SPI_HARDWARE_PINS[port]
self._reserve_pins(*( self._reserve_pins(*(
factory.address + ('GPIO%d' % pin,) factory.address + ('GPIO%d' % pin,)
for pin in (11, 10, 9, (8, 7)[device]) for pin in (
)) pins['clock'],
pins['mosi'],
pins['miso'],
pins['select'][device]
)
))
self._spi_flags = 8 << 16 self._spi_flags = 8 << 16
self._baud = 500000 self._baud = 500000
self._handle = self._factory.connection.spi_open( self._handle = self._factory.connection.spi_open(