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

The single integration boundary between this firmware and the ESP32-C6. More...

#include <stdint.h>
#include "ra8_c6link_transport.h"
#include "ra8_err.h"
#include "ra8_mdl_protocol.h"
Include dependency graph for ra8_c6link.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

 One IEEE 802 address, by value. More...
 Identity the co-processor reports about itself. More...
 One decoded co-processor announcement. More...
 What the co-processor said when a request did not succeed. More...
 What one pump did on the wire, counted rather than inferred. More...
 Everything ra8_c6link_open needs that the link cannot discover. More...
 The one outstanding request a link is waiting on. More...
 Caller-allocated link handle. More...

Typedefs

typedef struct ra8_c6link_mac ra8_c6link_mac_t
typedef struct ra8_c6link_fw_version ra8_c6link_fw_version_t
typedef struct ra8_c6link_event ra8_c6link_event_t
typedef struct ra8_c6link_fault ra8_c6link_fault_t
typedef struct ra8_c6link_stats ra8_c6link_stats_t
typedef void(* ra8_c6link_event_cb_t) (void *ctx, const ra8_c6link_event_t *ev)
 Receiver for one decoded co-processor announcement.
typedef void(* ra8_c6link_rx_cb_t) (void *ctx, const uint8_t *frame, uint16_t len)
 Receiver for one 802.3 frame the co-processor forwarded.
typedef struct ra8_c6link_cfg ra8_c6link_cfg_t
typedef ra8_err_t(* ra8_c6link_take_fn_t) (void *ctx, const void *msg)
 Extractor that copies an answer's fields out.
typedef struct ra8_c6link_wait ra8_c6link_wait_t
typedef struct ra8_c6link ra8_c6link_t

Enumerations

enum  ra8_c6link_geometry_t : uint16_t {
  k_ra8_c6link_frame_bytes = 1600U ,
  k_ra8_c6link_header_bytes = 12U ,
  k_ra8_c6link_max_payload = 1588U ,
  k_ra8_c6link_mac_bytes = 6U ,
  k_ra8_c6link_ssid_max = 32U ,
  k_ra8_c6link_dma_align = 64U ,
  k_ra8_c6link_arena_min = 2048U
}
 Fixed sizes of the esp-hosted wire this link speaks. More...
enum  ra8_c6link_budget_t : uint16_t {
  k_ra8_c6link_hs_wait_ms = 200U ,
  k_ra8_c6link_hs_poll_ms = 1U ,
  k_ra8_c6link_hs_giveup = 3U ,
  k_ra8_c6link_gap_ms = 2U ,
  k_ra8_c6link_rpc_transfers = 64U ,
  k_ra8_c6link_announce_transfers = 8U
}
 Default pacing and bounds the link works to. More...
enum  ra8_c6link_event_kind_t : uint8_t {
  k_ra8_c6link_event_boot = 0U ,
  k_ra8_c6link_event_sta_connected = 1U ,
  k_ra8_c6link_event_sta_disconnected = 2U ,
  k_ra8_c6link_event_wifi = 3U
}
 The co-processor announcements this link surfaces to its owner. More...

Functions

ra8_err_t ra8_c6link_open (ra8_c6link_t *link, const ra8_c6link_cfg_t *cfg)
 Bind a transport to a link handle and make it usable.
ra8_err_t ra8_c6link_close (ra8_c6link_t *link)
 Release a link handle.
bool ra8_c6link_is_open (const ra8_c6link_t *link)
 Report whether a handle is currently open.
ra8_err_t ra8_c6link_poll (ra8_c6link_t *link, uint16_t max_transactions, ra8_c6link_stats_t *stats)
 Clock transactions, delivering whatever the co-processor sends.
ra8_err_t ra8_c6link_await_ready (ra8_c6link_t *link, uint16_t max_transactions, ra8_c6link_fw_version_t *out)
 Announce this host and prove the co-processor is answering.
ra8_err_t ra8_c6link_fw_version (ra8_c6link_t *link, ra8_c6link_fw_version_t *out)
 Ask the co-processor to identify itself.
ra8_err_t ra8_c6link_eth_send (ra8_c6link_t *link, const uint8_t *frame, uint16_t len)
 Hand one 802.3 frame to the co-processor for transmission.
ra8_err_t ra8_c6link_last_fault (const ra8_c6link_t *link, ra8_c6link_fault_t *out)
 Report the last request that failed on this link.

Detailed Description

The single integration boundary between this firmware and the ESP32-C6.

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

Application code reaches the co-processor here and nowhere else. Above this header there is no protobuf, no TLV envelope, no payload header, no checksum and no SPI: there is a link you open, poll, send Ethernet frames on, and receive events from. Below it, ra8_c6link_transport_t is the only thing that touches hardware.

What the wire actually is, and why this API looks like this
The esp-hosted control plane is one protobuf message type (Rpc) inside a two-tag TLV envelope inside a twelve-byte payload header, and the data plane is a bare 802.3 frame inside that same payload header. The co-processor decodes protobuf, not C structures: WifiStaConfig is a message with named fields and upstream's own host converts to it field by field, so no struct layout, field order or padding on this side ever reaches the C6. That was measured on the bench before this library was written (see #490), and it is why this file defines the handful of small types a caller genuinely needs rather than reproducing ESP-IDF's wifi_*_t surface for an ABI compatibility the link does not have.
Liveness is measured, never inferred
Neither boot announcement is load-bearing here. The ESP_PRIV_IF ESP_PRIV_EVENT_INIT frame upstream normally uses is unusable on this co-processor build – transmitted with a non-zero if_num but checksummed as if that nibble were zero, so every conformant host drops it (#529) – and the Event_ESPInit RPC event that replaces it is a one-shot fired when the co-processor boots, which on this bench is not when the RA8 boots: the C6 has its own supply. Both are reported (k_ra8_c6link_event_boot) and neither is a precondition. ra8_c6link_await_ready establishes liveness by asking a question and getting an answer, which is true whenever it is true.
Threading
A link handle is single-threaded. Every entry point that can move bytes (ra8_c6link_poll and everything built on it) owns the transport for its duration, so two threads must not share one handle without external serialisation. Callbacks run inside those calls, on the calling thread.
Example:
.transport = seam,
.arena = s_arena,
.arena_bytes = (uint32_t)sizeof s_arena,
.event_cb = on_event,
.cb_ctx = nullptr,
};
if (ra8_c6link_open(&s_link, &cfg) == k_ra8_ok) {
}
static ra8_c6link_t s_link
Definition c6_cam_app.c:44
static uint8_t s_arena[k_c6_cam_arena_bytes]
Definition c6_cam_app.c:43
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
See also
ra8_c6link_wifi.h Station bring-up and association on top of this link
ra8_c6link_transport.h The hardware seam this facade is built on
Since
0.1.0

Definition in file ra8_c6link.h.

Typedef Documentation

◆ ra8_c6link_cfg_t

◆ ra8_c6link_event_cb_t

typedef void(* ra8_c6link_event_cb_t) (void *ctx, const ra8_c6link_event_t *ev)

Receiver for one decoded co-processor announcement.

Parameters
[in]ctxOpaque context from ra8_c6link_cfg::cb_ctx.
[in]evDecoded announcement; never null and valid only for the duration of the call.
Returns
Nothing.
Note
Runs inside ra8_c6link_poll on the polling thread, with the transport in use. It must not call back into the link.
Since
0.1.0

Definition at line 389 of file ra8_c6link.h.

◆ ra8_c6link_event_t

◆ ra8_c6link_fault_t

◆ ra8_c6link_fw_version_t

◆ ra8_c6link_mac_t

◆ ra8_c6link_rx_cb_t

typedef void(* ra8_c6link_rx_cb_t) (void *ctx, const uint8_t *frame, uint16_t len)

Receiver for one 802.3 frame the co-processor forwarded.

Parameters
[in]ctxOpaque context from ra8_c6link_cfg::cb_ctx.
[in]frameFrame bytes, starting at the destination address; never null and valid only for the duration of the call.
[in]lenFrame length in bytes; never zero, never above k_ra8_c6link_max_payload.
Returns
Nothing.
Note
Runs inside ra8_c6link_poll on the polling thread, with the transport in use. Copy anything that must outlive the call.
Since
0.1.0

Definition at line 407 of file ra8_c6link.h.

◆ ra8_c6link_stats_t

◆ ra8_c6link_t

typedef struct ra8_c6link ra8_c6link_t

◆ ra8_c6link_take_fn_t

typedef ra8_err_t(* ra8_c6link_take_fn_t) (void *ctx, const void *msg)

Extractor that copies an answer's fields out.

Treat as private.

Declared here only because ra8_c6link_wait_t must have a complete layout for ra8_c6link_t to be caller-allocated. The msg argument is really a const Rpc* from the generated codec; it is typed opaquely so this public header needs no esp-hosted include path. Only translation units inside libs/ra8_c6link/src/ ever produce or call one.

Parameters
[in]ctxExtractor context supplied alongside the request.
[in]msgThe decoded answer, valid only for the duration of the call.
Returns
ra8_err_t Whatever the extractor decided about the answer.
Return values
k_ra8_okThe answer was accepted and its fields copied out.
Note
Runs inside the pump, on the polling thread.
Since
0.1.0

Definition at line 462 of file ra8_c6link.h.

◆ ra8_c6link_wait_t

Enumeration Type Documentation

◆ ra8_c6link_budget_t

enum ra8_c6link_budget_t : uint16_t

Default pacing and bounds the link works to.

Every one of these exists to give a loop a statically provable bound (NASA Power of 10 Rule 2) and to turn "the co-processor never answered" into a returned error instead of a hang. The transaction rate is the bench-proven one: c6_hosted_init and c6_fw_version both ran the link at 5 MHz with a two-millisecond gap between transactions and zero bad checksums.

Invariant
k_ra8_c6link_hs_giveup is at least two, so one missed sample is never enough to declare the co-processor absent.
k_ra8_c6link_rpc_transfers x k_ra8_c6link_hs_wait_ms bounds the worst-case wall time of one RPC call.
Example:
(void)ra8_c6link_poll(&link, (uint16_t)k_ra8_c6link_rpc_transfers, &stats);
See also
ra8_c6link_poll
Since
0.1.0
Enumerator
k_ra8_c6link_hs_wait_ms 

Milliseconds to wait for HANDSHAKE before abandoning a transaction.

k_ra8_c6link_hs_poll_ms 

Sampling period while waiting for HANDSHAKE.

k_ra8_c6link_hs_giveup 

Consecutive HANDSHAKE timeouts after which a pump stops early.

A co-processor that has not armed the line three times running is not there, and spending the rest of the budget re-asking turns "absent" into a minutes-long hang.

k_ra8_c6link_gap_ms 

Settling gap between consecutive transactions.

k_ra8_c6link_rpc_transfers 

Transactions one RPC call may clock while waiting for its response.

k_ra8_c6link_announce_transfers 

Transactions ra8_c6link_await_ready spends on the announcement before it probes.

Enough to place the capabilities frame and drain whatever the co-processor volunteers behind it; the bench bring-up settled on the same figure. Readiness is decided by the probe that follows, not by this budget, so a larger one would only lengthen the absent-hardware case.

Definition at line 155 of file ra8_c6link.h.

◆ ra8_c6link_event_kind_t

enum ra8_c6link_event_kind_t : uint8_t

The co-processor announcements this link surfaces to its owner.

Deliberately short. These are the four unsolicited messages a station join and its supervision actually depend on; every other event the protocol defines is counted as unhandled rather than half-decoded into a type nobody consumes.

Invariant
k_ra8_c6link_event_boot is the only announcement that can arrive before any request has been sent.
Every kind maps one-to-one onto a generated RPC_ID__Event_*.
Example:
if (ev->kind == k_ra8_c6link_event_sta_disconnected) { link_down(); }
See also
ra8_c6link_event_t
Since
0.1.0
Enumerator
k_ra8_c6link_event_boot 

Event_ESPInit: the co-processor has booted and is accepting RPC.

k_ra8_c6link_event_sta_connected 

Event_StaConnected: the station has associated with an AP.

k_ra8_c6link_event_sta_disconnected 

Event_StaDisconnected: the station has lost or left its AP.

k_ra8_c6link_event_wifi 

Event_WifiEventNoArgs: a Wi-Fi event carrying only its own id, reported verbatim in ra8_c6link_event::wifi_event_id.

Definition at line 255 of file ra8_c6link.h.

◆ ra8_c6link_geometry_t

enum ra8_c6link_geometry_t : uint16_t

Fixed sizes of the esp-hosted wire this link speaks.

These are protocol facts, not tuning knobs. Each is cross-checked against the vendored esp-hosted headers by a static_assert in ra8_c6link_frame.c, so an upstream change breaks the build here instead of silently mis-framing. They are restated rather than included so that this public header – and therefore every consumer of the facade, including the NetX Duo glue – needs no esp-hosted include path at all.

Invariant
k_ra8_c6link_frame_bytes is the byte count clocked in one full-duplex transaction, in both directions, always.
k_ra8_c6link_max_payload is k_ra8_c6link_frame_bytes - k_ra8_c6link_header_bytes.
Example:
static uint8_t frame[k_ra8_c6link_frame_bytes];
See also
ra8_c6link_transport_t
Since
0.1.0
Enumerator
k_ra8_c6link_frame_bytes 

Bytes in one transaction; ESP_TRANSPORT_SPI_MAX_BUF_SIZE upstream.

k_ra8_c6link_header_bytes 

sizeof(struct esp_payload_header) on this ABI.

k_ra8_c6link_max_payload 

Largest payload one frame can carry.

k_ra8_c6link_mac_bytes 

Octets in an IEEE 802 address.

k_ra8_c6link_ssid_max 

Octets in the longest SSID 802.11 allows.

k_ra8_c6link_dma_align 

Alignment the transport expects of a transaction buffer.

The handle's two frames carry it so a DMA-capable backend can clock them without a bounce buffer.

k_ra8_c6link_arena_min 

Smallest decode arena ra8_c6link_open accepts.

The largest message this library decodes is the station's AP record, whose nested country and HE sub-messages plus their binary fields fit inside this with room to spare; a smaller arena would fail a decode at run time rather than at open, which is the wrong place to find out.

Definition at line 108 of file ra8_c6link.h.

Function Documentation

◆ ra8_c6link_await_ready()

ra8_err_t ra8_c6link_await_ready ( ra8_c6link_t * link,
uint16_t max_transactions,
ra8_c6link_fw_version_t * out )
nodiscard

Announce this host and prove the co-processor is answering.

Transmits the privileged host-capabilities frame – upstream's send_slave_config(), byte for byte – drains the few transactions behind LEGACY-OK: send_slave_config() is the upstream esp-hosted symbol name it so anything the co-processor volunteers reaches the event callback, and then decides readiness by asking a question and getting an answer: one identity exchange, whose reply is handed back in out.

Readiness is deliberately not the boot event. Event_ESPInit is emitted once, when the co-processor boots. On this bench the ESP32-C6 has its own supply, so resetting the RA8 does not reboot it and that event is long gone – it was consumed by whichever application was clocking the bus when it fired. A facade that waited for it therefore worked exactly once, on a freshly-flashed co-processor, and timed out on every run after. Waiting on a one-shot announcement to decide a steady-state property is the same defect #529 records against the ESP_PRIV_IF frame, wearing the RPC layer's clothes; the fix is to stop inferring liveness and measure it.

The announcement is still sent, because a co-processor that has just booted services no RPC until the host has introduced itself. Sending it to one that is already up is harmless – it re-states capabilities that have not changed.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]max_transactionsTransactions the announcement phase may clock; must be non-zero. See k_ra8_c6link_announce_transfers.
[out]outReceives the co-processor's identity; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe co-processor answered; out is populated.
k_ra8_err_null_ptrlink or out was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_argmax_transactions was zero.
k_ra8_err_busyA payload is already staged on link.
k_ra8_err_invalid_sizeThe capabilities frame would not fit, which is a build-time impossibility and therefore a corrupted handle.
k_ra8_err_timeoutThe identity request went unanswered.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_spi_errorThe transport refused a transfer.
k_ra8_err_protocol_errorThe answer arrived malformed.
Precondition
The transport is up.
The caller has no payload staged on link.
Postcondition
On success out holds the identity and the link is usable.
At most max_transactions transactions were clocked announcing, plus k_ra8_c6link_rpc_transfers probing.
Note
Not thread-safe; it pumps.
A boot event that does arrive during the announcement phase still reaches the event callback as k_ra8_c6link_event_boot. It is reportable; it is simply not load-bearing.
Example:
&link, (uint16_t)k_ra8_c6link_announce_transfers, &fw);
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
See also
ra8_c6link_fw_version
ra8_c6link_poll
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: both phases are bounded by explicit transaction budgets.
  • Rule 5: four preconditions and two postconditions are checked.

Definition at line 233 of file ra8_c6link.c.

References k_ra8_c6link_caps_bytes, k_ra8_c6link_header_bytes, k_ra8_err_busy, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::open, priv_c6link_caps(), priv_c6link_pump(), ra8_c6link_fw_version(), ra8_c6link::tx, ra8_c6link::tx_if, and ra8_c6link::tx_len.

Referenced by c6_join_phase_ready(), c6_wifi_phase_ready(), internal_c6_cam_prepare_link(), internal_c6link_op_open(), and internal_open_and_join().

◆ ra8_c6link_close()

ra8_err_t ra8_c6link_close ( ra8_c6link_t * link)
nodiscard

Release a link handle.

Drops the transport binding, the callbacks and the arena reference, and marks the handle closed. The transport itself is not torn down – whoever brought it up owns that.

Parameters
[in,out]linkHandle to release; must be non-null and open.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe handle is closed.
k_ra8_err_null_ptrlink was null.
k_ra8_err_not_initializedlink was not open.
Precondition
No pump is running against link.
The caller no longer needs the last fault or counters.
Postcondition
The handle reports closed.
No callback registered through link is invoked again.
Note
Not thread-safe; close from the same context that opened.
Example:
See also
ra8_c6link_open
Since
0.1.0

Definition at line 178 of file ra8_c6link.c.

References ra8_c6link::arena, ra8_c6link::cb_ctx, ra8_c6link::event_cb, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::open, ra8_c6link::rx_cb, ra8_c6link::stats, ra8_c6link::transport, ra8_c6link::tx_len, and ra8_c6link::wait.

Referenced by internal_c6link_op_close(), and internal_run().

◆ ra8_c6link_eth_send()

ra8_err_t ra8_c6link_eth_send ( ra8_c6link_t * link,
const uint8_t * frame,
uint16_t len )
nodiscard

Hand one 802.3 frame to the co-processor for transmission.

Stages the frame on the station interface and pumps until a transaction has carried it out. The data plane needs no protobuf: the frame is the payload, behind the same twelve-byte header the control plane uses.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]frameFrame bytes, starting at the destination address; must be non-null.
[in]lenFrame length; must be non-zero and at most k_ra8_c6link_max_payload.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe frame was clocked out.
k_ra8_err_null_ptrlink or frame was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_sizelen was zero or above the payload cap.
k_ra8_err_busyAnother payload is already staged.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The station has been started; frames sent before that are discarded by the co-processor.
len bytes are readable at frame.
Postcondition
On success the frame has left this host.
Anything the co-processor sent during the same transactions was delivered to the registered callbacks.
Note
Not thread-safe; it pumps.
Warning
There is no transmit queue: one frame is staged at a time, which is what an IP driver that transmits from one thread needs and no more.
Example:
(void)ra8_c6link_eth_send(&link, packet, packet_len);
See also
ra8_c6link_rx_cb_t
Since
0.1.0

Definition at line 338 of file ra8_c6link.c.

References k_ra8_c6link_header_bytes, k_ra8_c6link_hs_giveup, k_ra8_c6link_max_payload, k_ra8_err_busy, k_ra8_err_hw_timeout, k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::open, priv_c6link_pump(), ra8_c6link::tx, ra8_c6link::tx_if, and ra8_c6link::tx_len.

Referenced by internal_handle_send().

◆ ra8_c6link_fw_version()

ra8_err_t ra8_c6link_fw_version ( ra8_c6link_t * link,
ra8_c6link_fw_version_t * out )
nodiscard

Ask the co-processor to identify itself.

Issues Req_GetCoprocessorFwVersion and decodes the answer. This is the cheapest complete proof that the whole stack works – framing, checksum, TLV, protobuf, correlation – because the answer is a fact the host can check rather than merely receive.

Parameters
[in,out]linkOpen handle; must be non-null.
[out]outIdentity to fill; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout holds the co-processor's answer.
k_ra8_err_null_ptrlink or out was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_busyA request is already outstanding on link.
k_ra8_err_timeoutThe co-processor did not answer within the budget.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_protocol_errorThe answer arrived but reported a failure.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The transport is up.
No other request is outstanding on link.
Postcondition
On success every field of out is set from the answer.
On failure the handle's last fault names this request.
Note
Not thread-safe; it pumps.
Example:
(void)ra8_c6link_fw_version(&link, &fw);
See also
ra8_c6link_last_fault
Since
0.1.0

Definition at line 310 of file ra8_c6link.c.

References internal_c6link_take_fw(), k_ra8_err_not_initialized, k_ra8_err_null_ptr, ra8_c6link::open, and priv_c6link_rpc_call().

Referenced by ra8_c6link_await_ready().

◆ ra8_c6link_is_open()

bool ra8_c6link_is_open ( const ra8_c6link_t * link)
nodiscard

Report whether a handle is currently open.

Parameters
[in]linkHandle to inspect; null reads as closed.
Returns
true when ra8_c6link_open has succeeded and no close has run since.
Return values
trueThe handle is usable.
falseThe handle is null, never opened, or closed.
Precondition
None; safe at any time, including before any open.
The caller tolerates a value a concurrent close may stale.
Postcondition
No state is modified.
The returned value reflects the flag at the moment of the read.
Note
Safe from any context; a single aligned load.
Example:
See also
ra8_c6link_open
Since
0.1.0

Definition at line 198 of file ra8_c6link.c.

References ra8_c6link::open.

Referenced by ra8_c6link_wifi_ap_info(), ra8_c6link_wifi_join(), ra8_c6link_wifi_leave(), ra8_c6link_wifi_mac(), ra8_c6link_wifi_start(), and ra8_c6link_wifi_stop().

◆ ra8_c6link_last_fault()

ra8_err_t ra8_c6link_last_fault ( const ra8_c6link_t * link,
ra8_c6link_fault_t * out )
nodiscard

Report the last request that failed on this link.

Parameters
[in]linkOpen handle; must be non-null.
[out]outFault record to fill; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout holds the record; an all-zero record means no request has failed since the handle was opened.
k_ra8_err_null_ptrlink or out was null.
Precondition
The handle has been opened at least once.
The caller reads the record before issuing another request, which would overwrite it.
Postcondition
No link state is modified.
out is fully written, including on the no-fault path.
Note
Safe from any context; it copies two words.
Example:
(void)ra8_c6link_last_fault(&link, &f);
See also
ra8_c6link_fault
Since
0.1.0

Definition at line 203 of file ra8_c6link.c.

References ra8_c6link::fault, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by c6_join_report_fault(), and c6_wifi_report_fault().

◆ ra8_c6link_open()

ra8_err_t ra8_c6link_open ( ra8_c6link_t * link,
const ra8_c6link_cfg_t * cfg )
nodiscard

Bind a transport to a link handle and make it usable.

Validates the seam and the arena, copies both into the handle, and resets every counter. No hardware is touched: bringing the transport itself up (pin routing, bus open, clocking) belongs to the backend that fills the seam, and happens before this call.

Parameters
[out]linkHandle to initialise; must be non-null.
[in]cfgConfiguration; must be non-null with every transport row filled and an arena of at least k_ra8_c6link_arena_min bytes.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe link is open.
k_ra8_err_null_ptrlink, cfg, a transport row, or the arena pointer was null.
k_ra8_err_invalid_sizearena_bytes is below k_ra8_c6link_arena_min.
k_ra8_err_invalid_statelink is already open.
Precondition
The transport backend is already up and can clock a transaction.
link is zero-initialised, or has been closed.
Postcondition
On success the handle reports open and every counter is zero.
On failure link is not modified.
Note
Not thread-safe; open once from a single-threaded bring-up path.
Warning
The arena and everything the transport seam points at must outlive the link.
Example:
if (ra8_c6link_open(&s_link, &cfg) != k_ra8_ok) { report(); }
See also
ra8_c6link_close
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 3: no allocation; the arena is the caller's.
  • Rule 5: four preconditions and two postconditions are checked.

Definition at line 146 of file ra8_c6link.c.

References ra8_c6link::arena, ra8_c6link_cfg::arena, ra8_c6link::arena_bytes, ra8_c6link_cfg::arena_bytes, ra8_c6link::arena_last, ra8_c6link::arena_used, ra8_c6link::boot_seen, ra8_c6link::cb_ctx, ra8_c6link_cfg::cb_ctx, ra8_c6link::event_cb, ra8_c6link_cfg::event_cb, ra8_c6link::fault, internal_c6link_check_cfg(), k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::next_uid, ra8_c6link::open, ra8_c6link::rx_cb, ra8_c6link_cfg::rx_cb, ra8_c6link::stats, ra8_c6link::transport, ra8_c6link_cfg::transport, ra8_c6link::tx_if, ra8_c6link::tx_len, and ra8_c6link::wait.

Referenced by c6_join_open_link(), c6_wifi_open_link(), internal_c6_cam_open_link(), internal_c6link_op_open(), and internal_open_and_join().

◆ ra8_c6link_poll()

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

Clock transactions, delivering whatever the co-processor sends.

The pump. Each iteration waits for HANDSHAKE, transmits either a staged payload or an idle filler frame, clocks k_ra8_c6link_frame_bytes both ways, and classifies what came back: filler is counted, malformed and checksum-failing frames are counted and dropped, and well-formed frames are routed by interface – control plane to the RPC decoder, station traffic to the receive callback.

Call it to drive the link when no request is outstanding: to drain events, to receive Ethernet frames, or to give a staged transmit somewhere to go. Requests issued through this library pump internally and need no help.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]max_transactionsTransactions this call may clock; must be non-zero.
[out]statsCounters describing the run, or null to discard them.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe pump ran; stats says what happened.
k_ra8_err_null_ptrlink was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_argmax_transactions was zero.
k_ra8_err_hw_timeoutHANDSHAKE never went active, so not one transaction was clocked.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The transport is up and no other context is driving it.
Callbacks registered at open are safe to invoke now.
Postcondition
At most max_transactions transactions were clocked.
stats, when non-null, holds the counts for exactly this call.
Note
Not thread-safe; one pump at a time owns the transport.
Warning
Callbacks run inside this call and must not re-enter the link.
Example:
(void)ra8_c6link_poll(&link, 16U, &st);
See also
ra8_c6link_stats
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: the transaction loop is bounded by max_transactions and the handshake wait by k_ra8_c6link_hs_wait_ms.
  • Rule 5: three preconditions and two postconditions are checked.

Definition at line 212 of file ra8_c6link.c.

References k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_err_null_ptr, ra8_c6link::open, and priv_c6link_pump().

Referenced by c6_join_wait_connected(), c6_wifi_phase_station(), internal_c6_cam_wait_connected(), internal_c6link_op_service(), internal_rx_worker_entry(), and internal_wait_connected().