ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_c6link_pump.c File Reference

The transaction loop: handshake, clock, classify, route. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_c6link.h"
#include "ra8_c6link_internal.h"
Include dependency graph for ra8_c6link_pump.c:

Go to the source code of this file.

Functions

static bool internal_c6link_pump_handshake (ra8_c6link_t *link)
 Wait, bounded, for the co-processor to arm HANDSHAKE.
static bool internal_c6link_pump_receive (ra8_c6link_t *link, ra8_c6link_stats_t *stats)
 Account for one classified frame and route the real ones.
ra8_err_t priv_c6link_pump (ra8_c6link_t *link, uint16_t max_transactions, ra8_c6link_stats_t *stats)
 Clock transactions until the budget or the wait says stop.

Detailed Description

The transaction loop: handshake, clock, classify, route.

Tag
[Ring 4 / PAL] {World: NS}

This link is polled, not interrupt-driven. Every byte in either direction moves inside a transaction that this loop starts, and a transaction only happens when the co-processor has raised HANDSHAKE to say it has latched a transmit buffer. That is upstream's spi_transaction_task reduced to what a host with one thread and no queues needs:

  1. wait, bounded, for HANDSHAKE;
  2. transmit either the one staged payload or an idle filler frame;
  3. clock k_ra8_c6link_frame_bytes full duplex;
  4. classify what came back and route it.

A co-processor that has not armed the line k_ra8_c6link_hs_giveup times running is not there. Spending the whole budget re-asking proves nothing and turns "the harness is unplugged" into a minutes-long hang, so the loop stops and the caller gets a timeout it can report.

Since
0.1.0

Definition in file ra8_c6link_pump.c.

Function Documentation

◆ internal_c6link_pump_handshake()

bool internal_c6link_pump_handshake ( ra8_c6link_t * link)
static

Wait, bounded, for the co-processor to arm HANDSHAKE.

The co-processor only latches its transmit buffer once it has raised the line, so a transaction started before that clocks nothing useful in either direction.

Parameters
[in,out]linkOpen handle; must be non-null.
Returns
true when HANDSHAKE read active within the budget.
Return values
trueThe co-processor is ready for a transaction.
falsek_ra8_c6link_hs_wait_ms elapsed with the line inactive.
Precondition
The transport seam is bound.
HANDSHAKE is configured as an input by the backend.
Postcondition
No link state is modified.
At most k_ra8_c6link_hs_wait_ms elapsed.
Note
The loop is bounded by k_ra8_c6link_hs_wait_ms (NASA Rule 2).
Since
0.1.0

Definition at line 53 of file ra8_c6link_pump.c.

References ra8_c6link_transport::ctx, ra8_c6link_transport::delay_ms, ra8_c6link_transport::handshake_active, k_ra8_c6link_hs_poll_ms, k_ra8_c6link_hs_wait_ms, RA8_INTERNAL, and ra8_c6link::transport.

Referenced by priv_c6link_pump().

◆ internal_c6link_pump_receive()

bool internal_c6link_pump_receive ( ra8_c6link_t * link,
ra8_c6link_stats_t * stats )
static

Account for one classified frame and route the real ones.

Classifies first and routes second, so a frame that failed its integrity check reaches no consumer at all.

Parameters
[in,out]linkOpen handle; must be non-null.
[in,out]statsCounters for the running pump; must be non-null.
Returns
true when the outstanding wait was satisfied.
Return values
trueThe awaited answer arrived; the pump should stop.
falseKeep clocking.
Precondition
The transfer has completed and the receive transaction is stable.
stats is the caller's live counter block.
Postcondition
Exactly one class counter in stats advanced.
A payload reached a consumer only if its checksum verified.
Note
Ordering matches upstream's process_spi_rx_buf().
Since
0.1.0

Definition at line 81 of file ra8_c6link_pump.c.

References ra8_c6link_stats::bad_checksum, ra8_c6link_stats::data, ra8_c6link_stats::idle, k_ra8_c6link_frame_bad_checksum, k_ra8_c6link_frame_data, k_ra8_c6link_frame_idle, k_ra8_c6link_frame_malformed, ra8_c6link_stats::malformed, priv_c6link_dispatch(), priv_c6link_frame_classify(), RA8_INTERNAL, and ra8_c6link::rx.

Referenced by priv_c6link_pump().

◆ priv_c6link_pump()

ra8_err_t priv_c6link_pump ( ra8_c6link_t * link,
uint16_t max_transactions,
ra8_c6link_stats_t * stats )
nodiscard

Clock transactions until the budget or the wait says stop.

The implementation behind ra8_c6link_poll, and the loop every request runs inside. Split out so the public entry point stays a validation wrapper and so tests can drive it against a co-processor model directly.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]max_transactionsTransactions this call may clock; non-zero.
[out]statsCounters describing the run; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe pump ran to its budget or until the wait was satisfied.
k_ra8_err_hw_timeoutHANDSHAKE never went active.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
link is open and its transport is bound.
stats has been cleared by the caller.
Postcondition
At most max_transactions transactions were clocked.
Any staged payload was transmitted, or is still staged.
Note
Not thread-safe; one pump at a time owns the transport.
Example:
(void)priv_c6link_pump(link, (uint16_t)k_ra8_c6link_rpc_transfers, &stats);
See also
priv_c6link_dispatch
Since
0.1.0

Definition at line 105 of file ra8_c6link_pump.c.

References ra8_c6link_transport::ctx, ra8_c6link_transport::delay_ms, ra8_c6link_stats::hs_timeouts, internal_c6link_pump_handshake(), internal_c6link_pump_receive(), k_ra8_c6link_frame_bytes, k_ra8_c6link_gap_ms, k_ra8_c6link_hs_giveup, k_ra8_err_hw_timeout, k_ra8_err_null_ptr, k_ra8_err_spi_error, k_ra8_ok, priv_c6link_frame_filler(), priv_c6link_frame_seal(), RA8_PRIV, ra8_c6link::rx, ra8_c6link::stats, ra8_c6link_transport::transfer, ra8_c6link_stats::transfers, ra8_c6link::transport, ra8_c6link::tx, ra8_c6link::tx_if, and ra8_c6link::tx_len.

Referenced by priv_c6link_rpc_call(), ra8_c6link_await_ready(), ra8_c6link_eth_send(), and ra8_c6link_poll().