Merge commit '9d1903a' into rtiobusy

* commit '9d1903a':
  coredevice/i2c,ttl,spi: consistent device get
  examples/device_db: remove --no-localhost-bind
  Monkey-patch asyncio create_server (fixes #253).
  pipistrello: drop ttls on pmod, add leds back in
  pipistrello: try with fewer leds/pmod ttl
This commit is contained in:
Robert Jördens 2016-03-09 11:55:08 +01:00
commit 446dcfbfbc
7 changed files with 127 additions and 34 deletions

View File

@ -34,8 +34,8 @@ class PCA9548:
On the KC705, this chip is used for selecting the I2C buses on the two FMC
connectors. HPC=1, LPC=2.
"""
def __init__(self, dmgr, busno=0, address=0xe8):
self.core = dmgr.get("core")
def __init__(self, dmgr, busno=0, address=0xe8, core_device="core"):
self.core = dmgr.get(core_device)
self.busno = busno
self.address = address
@ -77,8 +77,8 @@ class TCA6424A:
On the NIST QC2 hardware, this chip is used for switching the directions
of TTL buffers."""
def __init__(self, dmgr, busno=0, address=0x44):
self.core = dmgr.get("core")
def __init__(self, dmgr, busno=0, address=0x44, core_device="core"):
self.core = dmgr.get(core_device)
self.busno = busno
self.address = address

View File

@ -40,8 +40,8 @@ class SPIMaster:
:param channel: RTIO channel number of the SPI bus to control.
"""
def __init__(self, dmgr, channel):
self.core = dmgr.get("core")
def __init__(self, dmgr, channel, core_device="core"):
self.core = dmgr.get(core_device)
self.ref_period_mu = seconds_to_mu(self.core.coarse_ref_period,
self.core)
self.channel = channel

View File

@ -10,8 +10,8 @@ class TTLOut:
:param channel: channel number
"""
def __init__(self, dmgr, channel):
self.core = dmgr.get("core")
def __init__(self, dmgr, channel, core_device="core"):
self.core = dmgr.get(core_device)
self.channel = channel
# in RTIO cycles
@ -82,8 +82,8 @@ class TTLInOut:
:param channel: channel number
"""
def __init__(self, dmgr, channel):
self.core = dmgr.get("core")
def __init__(self, dmgr, channel, core_device="core"):
self.core = dmgr.get(core_device)
self.channel = channel
# in RTIO cycles
@ -232,8 +232,8 @@ class TTLClockGen:
:param channel: channel number
"""
def __init__(self, dmgr, channel):
self.core = dmgr.get("core")
def __init__(self, dmgr, channel, core_device="core"):
self.core = dmgr.get(core_device)
self.channel = channel
# in RTIO cycles

View File

@ -203,13 +203,6 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
spi_pins = self.platform.request("pmod_extended_spi", 0)
for i, p in enumerate((spi_pins.int, spi_pins.rst,
spi_pins.d0, spi_pins.d1)):
phy = ttl_simple.Inout(p)
self.submodules += phy
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=4,
ofifo_depth=4))
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)
phy = ttl_simple.ClockGen(platform.request("ttl", 15))
@ -220,7 +213,7 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
self.submodules += phy
self.config["RTIO_FIRST_SPI_CHANNEL"] = len(rtio_channels)
rtio_channels.append(rtio.Channel.from_phy(
phy, ofifo_depth=64, ififo_depth=64))
phy, ofifo_depth=256, ififo_depth=256))
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
self.config["DDS_CHANNEL_COUNT"] = 8

View File

@ -7,6 +7,8 @@ import asyncio
import time
import collections
import os
import socket
import itertools
import atexit
import string
@ -243,3 +245,109 @@ def get_windows_drives():
drives.append(letter)
bitmask >>= 1
return drives
if sys.version_info[:3] == (3, 5, 1):
# See https://github.com/m-labs/artiq/issues/253
@asyncio.coroutines.coroutine
def create_server(self, protocol_factory, host=None, port=None,
*,
family=socket.AF_UNSPEC,
flags=socket.AI_PASSIVE,
sock=None,
backlog=100,
ssl=None,
reuse_address=None,
reuse_port=None):
"""Create a TCP server.
The host parameter can be a string, in that case the TCP server is bound
to host and port.
The host parameter can also be a sequence of strings and in that case
the TCP server is bound to all hosts of the sequence. If a host
appears multiple times (possibly indirectly e.g. when hostnames
resolve to the same IP address), the server is only bound once to that
host.
Return a Server object which can be used to stop the service.
This method is a coroutine.
"""
if isinstance(ssl, bool):
raise TypeError('ssl argument must be an SSLContext or None')
if host is not None or port is not None:
if sock is not None:
raise ValueError(
'host/port and sock can not be specified at the same time')
AF_INET6 = getattr(socket, 'AF_INET6', 0)
if reuse_address is None:
reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
sockets = []
if host == '':
hosts = [None]
elif (isinstance(host, str) or
not isinstance(host, collections.Iterable)):
hosts = [host]
else:
hosts = host
fs = [self._create_server_getaddrinfo(host, port, family=family,
flags=flags)
for host in hosts]
infos = yield from asyncio.tasks.gather(*fs, loop=self)
infos = set(itertools.chain.from_iterable(infos))
completed = False
try:
for res in infos:
af, socktype, proto, canonname, sa = res
try:
sock = socket.socket(af, socktype, proto)
except socket.error:
# Assume it's a bad family/type/protocol combination.
if self._debug:
asyncio.log.logger.warning('create_server() failed to create '
'socket.socket(%r, %r, %r)',
af, socktype, proto, exc_info=True)
continue
sockets.append(sock)
if reuse_address:
sock.setsockopt(
socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
if reuse_port:
if not hasattr(socket, 'SO_REUSEPORT'):
raise ValueError(
'reuse_port not supported by socket module')
else:
sock.setsockopt(
socket.SOL_SOCKET, socket.SO_REUSEPORT, True)
# Disable IPv4/IPv6 dual stack support (enabled by
# default on Linux) which makes a single socket
# listen on both address families.
if af == AF_INET6 and hasattr(socket, 'IPPROTO_IPV6'):
sock.setsockopt(socket.IPPROTO_IPV6,
socket.IPV6_V6ONLY,
True)
try:
sock.bind(sa)
except OSError as err:
raise OSError(err.errno, 'error while attempting '
'to bind on address %r: %s'
% (sa, err.strerror.lower()))
completed = True
finally:
if not completed:
for sock in sockets:
sock.close()
else:
if sock is None:
raise ValueError('Neither host/port nor sock were specified')
sockets = [sock]
server = asyncio.base_events.Server(self, sockets)
for sock in sockets:
sock.listen(backlog)
sock.setblocking(False)
self._start_serving(protocol_factory, sock, ssl, server)
if self._debug:
asyncio.log.logger.info("%r is serving", server)
return server
asyncio.base_events.BaseEventLoop.create_server = create_server

View File

@ -132,15 +132,7 @@ When plugged to an adapter, the NIST QC1 hardware can be used. The TTL lines are
+--------------+------------+--------------+
| 21 | USER_LED_4 | Output |
+--------------+------------+--------------+
| 22 | PMOD_4 | Input+Output |
+--------------+------------+--------------+
| 23 | PMOD_5 | Input+Output |
+--------------+------------+--------------+
| 24 | PMOD_6 | Input+Output |
+--------------+------------+--------------+
| 25 | PMOD_7 | Input+Output |
+--------------+------------+--------------+
| 26 | TTL15 | Clock |
| 22 | TTL15 | Clock |
+--------------+------------+--------------+
The input only limitation on channels 0 and 1 comes from the QC-DAQ adapter. When the adapter is not used (and physically unplugged from the Pipistrello board), the corresponding pins on the Pipistrello can be used as outputs. Do not configure these channels as outputs when the adapter is plugged, as this would cause electrical contention.
@ -153,5 +145,5 @@ Interface Type 2 (SPI) and 2A (expanded SPI):
+--------------+--------+--------+--------+--------+
| RTIO channel | CS_N | MOSI | MISO | CLK |
+==============+========+========+========+========+
| 27 | PMOD_0 | PMOD_1 | PMOD_2 | PMOD_3 |
| 23 | PMOD_0 | PMOD_1 | PMOD_2 | PMOD_3 |
+--------------+--------+--------+--------+--------+

View File

@ -154,25 +154,25 @@
# that it always resolves to a network-visible IP address (see documentation).
"host": "::1",
"port": 4000,
"command": "pdq2_controller --no-localhost-bind -p {port} --bind {bind} --simulation --dump qc_q1_0.bin"
"command": "pdq2_controller -p {port} --bind {bind} --simulation --dump qc_q1_0.bin"
},
"qc_q1_1": {
"type": "controller",
"host": "::1",
"port": 4001,
"command": "pdq2_controller --no-localhost-bind -p {port} --bind {bind} --simulation --dump qc_q1_1.bin"
"command": "pdq2_controller -p {port} --bind {bind} --simulation --dump qc_q1_1.bin"
},
"qc_q1_2": {
"type": "controller",
"host": "::1",
"port": 4002,
"command": "pdq2_controller --no-localhost-bind -p {port} --bind {bind} --simulation --dump qc_q1_2.bin"
"command": "pdq2_controller -p {port} --bind {bind} --simulation --dump qc_q1_2.bin"
},
"qc_q1_3": {
"type": "controller",
"host": "::1",
"port": 4003,
"command": "pdq2_controller --no-localhost-bind -p {port} --bind {bind} --simulation --dump qc_q1_3.bin"
"command": "pdq2_controller -p {port} --bind {bind} --simulation --dump qc_q1_3.bin"
},
"electrodes": {
"type": "local",