| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|
|
|
|
|
| |
When issuing a timed command, if there is no room in the command FIFO
and there is a timed command queue'd up, wait for a long time before
timing out.
|
| |
|
|
|
|
|
|
|
| |
Now link instances must have the ability to report the corresponding
physical adapter that is used for the local side of the link. This
information can be used to help identify when multiple links share
the same adapter.
|
|
|
|
| |
Now the user can choose which transport is used in connect() calls.
|
|
|
|
|
|
| |
Add an async message queue that aggregates errors from multiple sources.
Errors can come from the strs packets originating from the stream
endpoint or from the radio block through control packets to the host.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Because the initialization state of SEPs is a graph-wide property,
link_stream_managers and mgmt_portals cannot rely on their private
members to determine if they can reset an SEP. Move the call to
init SEPs into the epid_allocator, and have it call into a
mgmt_portal to gain access to the SEP.
Thus, link_stream_managers only request that an epid_allocator
ensure an SEP is numbered and initialized, and they provide a path
to communicate with the SEP. The epid_allocator will ensure init
only happens once, so a stream currently running on another
link_stream_manager does not get interrupted. This could happen,
for example, if the OSTRM went to one device, and the ISTRM came
from another. In general, EPIDs should only be assigned once.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change data transports to use the mgmt_portal from the
link_stream_manager. The initialization state of a device's EPIDs
needs to be shared amongst all the SEP users. Otherwise, an RX
transport may attempt to do a full reset of the SEP while TX is
streaming (for example).
TODO: The code contained here is not sufficient to handle multiple
links that can access the same SEPs, as those would have different
link_stream_managers, and thus, different mgmt_portal instances and
views of the SEP state.
|
|
|
|
|
| |
The convenience call that flushed all the blocks would throw during
timeout. Now, it returns a bool whether or not the flush was successful.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This introduces the concept of a resolution context, because the
property propagation algorithm needs to behave differently when called
during an initialization step (e.g. when the graph is committed), or
when the user changes a property on one of the nodes after it was
committed.
The algorithm is modified as follows:
- When called during an initialization step, then all nodes get resolved
at least once. If nodes added new properties, then all nodes get
touched again until the max number of iterations is reached.
- When called because a node modified one of its properties, then that
node is always resolved first. From there, all other nodes are
resolved in topological order. However, the algorithm immediately
terminates as soon as there are no more dirty nodes.
- When called because a node modified one of its properties, but the
graph is currently not in a committed state, then that node will do
a local property resolution.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Property propagation and action handling depend on the release state,
but they are lengthy operations. It is therefore imperative to not
change the release/commit state during those methods.
This commit changes the following:
- Change the release state counter from an atomic to a non-atomic
variable
- Instead, use a mutex to lock the release state counter, and use the
same mutex for locking access to the property propagation and action
handling
The rfnoc_graph now tries to release the graph before shutting down
blocks to make sure they don't get destroyed while those algorithms are
still running.
|
|
|
|
|
| |
This adds a method to the radio to check if an async message is valid,
which can be used to ack async messages immediately.
|
|
|
|
|
| |
This is a helper method for property resolution, where set_rate() is not
appropriate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In order to enable overrun handling through the action API, a few new
features are implemented:
- The RX streamer can now accept stream command actions. The streamer
will interpret stream command actions as a request to send stream
commands upstream to all producers.
- A new action type is defined ('restart request') which is understood
by the radio and streamer, and is a handshake between producers and
consumers. In this case, it will ask the radio to send a stream
command itself.
When an RX streamer receives an overrun, it will now run the following
algorithm:
1. Stop all upstream producers (this was already in the code before this
commit).
2. If no restart is required, Wait for the radios to have space in the
downstream blocks.
The radio, if it was in continuous streaming mode before the overrun,
includes a flag in its initial action whether or not to restart the
streaming. Also, it will wait for the stop stream command from the
streamer. When it receives that, it will initiate a restart request
handshake.
3. The streamer submits a restart request action upstream. This action
will be received by the radio.
The radio will then check the current time, and send a stream command
action back downstream.
4. The RX streamer receives the stream command action, and uses it to
send another stream command to all upstream producers. This way, all
upstream producers receive a start command for the same time.
|
|
|
|
|
|
|
|
| |
Sending actions to self is useful because calling post_action() from
within an action handler will not actually trigger the action. Instead,
it will defer delivery of the action. Allowing sending actions to self
will allow to add another action, in deterministic order, and the
execution of another action handler.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Add device ID constants (e.g., E310 == 0xE310, X300 == 0xA300). These
are stored in the device FPGA, and can be used for decisions later
- Blocks can be specific to a device. For example, x300_radio_control
can only work on an X300 series device.
- Because blocks can be device-specific, all radio blocks can now share
a common Noc-ID (0x12AD1000).
- The registry and factory functions are modified to acommodate for
this.
- The motherboard access is now also factored into the same registry
macro.
|
|
|
|
|
|
|
|
|
| |
Async messages (like, e.g., overrun messages) can include a timestamp.
This change enables access to the timestamp in the async message
handler. It is up to the FPGA block implementation to include the
timestamp, if desired/necessary. The definition of the timestamp may
also depend on the block, for example, the overrun async message will
include the time when the overrun occurred.
|
|
|
|
|
|
|
| |
This will receive async messages from the radio, and print OUL
characters where appropriate.
When an overrun message is received, it will send an action upstream to
initiate overrun handling.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
transports:
Transports build on I/O service and implements flow control and
sequence number checking.
The rx streamer subclass extends the streamer implementation to connect
it to the rfnoc graph. It receives configuration values from property
propagation and configures the streamer accordingly. It also implements
the issue_stream_cmd rx_streamer API method.
Add implementation of rx streamer creation and method to connect it to
an rfnoc block.
rfnoc_graph: Cache more connection info, clarify contract
Summary of changes:
- rfnoc_graph stores more information about static connections at the
beginning. Some search algorithms are replaced by simpler lookups.
- The contract for connect() was clarified. It is required to call
connect, even for static connections.
|
|
|
|
|
|
| |
The valid bit helps prevent placeholder defaults from being
propagated through the graph. Values that are not valid will
not be forwarded.
|
|
|
|
| |
Implement uhd::rfnoc::rfnoc_graph::enumerate_*_connections()
|
|
|
|
|
| |
This will call init_props() on every block after the device
initialization is complete, but before control returns to the user.
|
|
|
|
|
|
| |
During construction of the rfnoc_graph, flush and reset each block in
each motherboard we need to enumerate. This will ensure that each
block is in a clean state when we construct it's block controller.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
During registration, blocks must now specify which clock they are using
for the timebase (i.e., for timed commands) and for the ctrlport (this
is used to determine the length of sleeps and polls). For example, the
X300 provides bus_clk and radio_clk; typically, the former is used for
the control port, and the latter for the timebase clock.
Another virtual clock is called "__graph__", and it means the clock is
derived from property propagation via the graph.
The actual clocks are provided by the mb_iface. It has two new API
calls: get_timebase_clock() and get_ctrlport_clock(), which take an
argument as to which clock exactly is requested. On block
initialization, those clock_iface objects are copied into the block
controller.
The get_tick_rate() API call for blocks now exclusively checks the
timebase clock_iface, and will no longer cache the current tick rate in
a separate _tick_rate member variable. Block controllers can't manually
modify the clock_iface, unless they also have access to the
mb_controller (like the radio block), and that mb_controller has
provided said access.
This commit also adds the clock selection API changes to the DDC block,
the Null block, and the default block.
|
|
|
|
|
| |
An immutable clock means it has a locked frequency, and attempts to
change the frequency will cause an exception to be thrown.
|
|
|
|
|
|
|
|
| |
On destruction, the rfnoc_graph will call shutdown() on all blocks. This
allows a safe de-initialization of blocks independent of the lifetime of
the noc_block_base::sptr.
Also adds the shutdown feature to null_block_control.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
These changes add APIs to instantiate the new transports. However,
only the control/management transport is currently implemented. It
uses the chdr_ctrl_xport.
Also update the mgmt_portal to use an ephemeral reference to the
shared transport, to indicate that it has no ownership of the
transport's memory.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
chdr_ctrl_xport is a dumb-pipe transport for RFNoC control transactions
and management frames.
Also remove the I/O service's check on num_recv_frames and num_send_frames.
The transports may request additional virtual channels, so the send_io_if
and recv_io_if may not reserve additional frames, as they are shared with
a previously-allocated instance.
Note: this uses a mutex to force sequentual access to the
chdr_ctrl_xport. This is supposed to go away when the multi threaded
xport is done.
|
| |
|
|
|
|
|
|
|
|
| |
Applying clang format for upcoming changes.
clang-format -i --style=file host/lib/usrp/cores/gpio_atr_3000.cpp
clang-format -i --style=file \
host/lib/include/uhdlib/usrp/cores/gpio_atr_3000.hpp
|
|
|
|
|
|
| |
The existing implementation assumes registers are spaced 4 bytes apart.
In the current radio block design, all backward compatible registers are
spaced 8 bytes apart. This adds a feature to configure that offset.
|
|
|
|
|
|
| |
This is a single atomic allocator in the global uhd::rfnoc namespace, so
that devices can allocate themselves device IDs without having to confer
with the rest of the RFNoC infrastructure.
|
|
|
|
|
| |
This converts from register_iface& to wb_iface::sptr. Useful for
connecting new block controllers with older interfaces.
|
|
|
|
|
|
| |
Following the changes in RX frontend controls, TX frontend register
offsets are now arguments to the factory function. They default to 4,
which is what the register offset was in the file before these changes.
|
|
|
|
|
|
|
|
| |
Changing how we calculate RX frontend register addresses to allow for
different register offsets. The register addresses are now calculated
in a manor similar to how gpio_atr_300_impl does register address
calculations, which is to allow a reg_offset to be passes in at
construction. The current default is reg_offset=4.
|
|
|
|
|
| |
Removes the requirement for a wb_iface, and also the requirement for
regs to be 4 addresses apart.
|
|
|
|
|
| |
This API lets blocks decide if their current topology is OK for them,
and make decisions based on their topology.
|
| |
|
|
|
|
|
|
|
|
|
| |
The mb_controller is an interface to hardware-specific functions of the
motherboard. The API works in two ways:
- The user can request access to it, and thus interact directly with the
motherboard
- RFNoC blocks can request access to it, if they need to interact with
the motherboard themselves.
|
|
|
|
|
| |
The management looks at the transport endianness from the packet
factory to determine if the byte_swapper in the FPGA needs to be enabled
|
| |
|
| |
|
|
|
|
|
| |
- Fleshed out mb_iface
- Managers currently only export ctrl APIs. Data APIs TBD
|
|
|
|
|
|
| |
- chdr_ctrl_endpoint can manage multiple dest EPIDs
- Moved from both_xports_t to a special defs in rfnoc_common
- Changed data-structures where appropriate
|
|
|
|
|
|
| |
- Moved chdr_packet and chdr_types from rfnoc/chdr to rfnoc and updated
all references
- Moved non-CHDR definitions to rfnoc_common.hpp
|
| |
|
|
|
|
| |
This contains both_links_t
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The inline_io_service connects transports to links without any
worker threads. Send operations go directly to the link, and recv
will perform the I/O as part of the get_recv_buffer() call.
The inline_io_service also supports muxed links natively. The receive
mux is entirely inline. There is no separate thread for the
inline_io_service, and that continues here. A queue is created for
each client of the mux, and packets are processed as they come in. If
a packet is to go up to a different client, the packet is queued up
for later. When that client attempts to recv(), the queue is checked
first, and the attempts to receive from the link happen ONLY if no
packet was found.
Also add mock transport to test I/O service APIs. Tests I/O service
construction and some basic packet transmision. One case will also
uses a single link that is shared between the send and recv transports.
That link is muxed between two compatible but different transports.
|