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

The esp-hosted SPI full-duplex wire format, hand-decoded. More...

#include <stdint.h>
Include dependency graph for c6_proto.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  c6_hdr_t
 Decoded esp-hosted payload header plus the locally recomputed sum. More...

Enumerations

enum  c6_proto_dim_t : uint16_t {
  k_c6_proto_buf_size = 1600U ,
  k_c6_proto_hdr_size = 12U ,
  k_c6_proto_payload_max = 1588U
}
 Fixed transport dimensions of the esp-hosted SPI FD transport. More...
enum  c6_hdr_offset_t : uint8_t {
  k_c6_hdr_off_iface = 0U ,
  k_c6_hdr_off_flags = 1U ,
  k_c6_hdr_off_len_lo = 2U ,
  k_c6_hdr_off_len_hi = 3U ,
  k_c6_hdr_off_off_lo = 4U ,
  k_c6_hdr_off_off_hi = 5U ,
  k_c6_hdr_off_csum_lo = 6U ,
  k_c6_hdr_off_csum_hi = 7U ,
  k_c6_hdr_off_seq_lo = 8U ,
  k_c6_hdr_off_seq_hi = 9U ,
  k_c6_hdr_off_throttle = 10U ,
  k_c6_hdr_off_pkttype = 11U
}
 Byte offsets of every field in the esp-hosted payload header. More...
enum  c6_if_type_t : uint8_t {
  k_c6_if_invalid = 0U ,
  k_c6_if_sta = 1U ,
  k_c6_if_ap = 2U ,
  k_c6_if_serial = 3U ,
  k_c6_if_hci = 4U ,
  k_c6_if_priv = 5U ,
  k_c6_if_test = 6U ,
  k_c6_if_eth = 7U ,
  k_c6_if_max = 8U
}
 esp-hosted interface identifiers carried in if_type. More...
enum  c6_proto_priv_t : uint8_t {
  k_c6_priv_pkt_event = 0x33U ,
  k_c6_priv_event_init = 0x22U ,
  k_c6_dummy_if_num = 0x0FU
}
 Private-interface packet and event tags, plus the filler signature. More...
enum  c6_bitop_t : uint8_t {
  k_c6_shift_nibble = 4U ,
  k_c6_mask_nibble = 0x0FU ,
  k_c6_shift_byte = 8U ,
  k_c6_mask_throttle = 0x03U
}
 Shifts and masks used to unpack the header. More...
enum  c6_frame_kind_t : uint8_t {
  k_c6_frame_garbage = 0U ,
  k_c6_frame_idle = 1U ,
  k_c6_frame_data = 2U ,
  k_c6_frame_bad_csum = 3U
}
 Classification of one received 1600-byte transaction. More...

Functions

void c6_probe_decode_header (const uint8_t *buf, c6_hdr_t *out)
 Unpack the twelve-byte esp-hosted payload header.
uint16_t c6_probe_checksum (const uint8_t *buf, uint16_t count)
 Recompute the esp-hosted checksum over a received frame.
c6_frame_kind_t c6_probe_classify (const c6_hdr_t *h)
 Judge a decoded header against the upstream receive rules.
void c6_probe_print_header (const c6_hdr_t *h)
 Print the decoded header fields on one console line.
void c6_probe_dump_payload (const uint8_t *buf, uint16_t len)
 Hex-dump the leading payload bytes of a received frame.

Detailed Description

The esp-hosted SPI full-duplex wire format, hand-decoded.

Everything in this header is a fact about the protocol, not about this probe: the transport dimensions, the twelve-byte payload header and its field offsets, the interface identifiers, and the operations that decode, checksum, classify and print a received frame (implemented by src/c6_frame.c). c6_probe.h carries the probe's own contract – its budgets, its side-band map and its transfer flow – and includes this header for the types they share.

The split is a responsibility boundary, not just a size one: a second consumer of this link (the first-party esp-hosted port, when it lands) will need these constants and will not want the probe's diagnostics.

Nothing from esp-hosted-mcu is vendored. Every constant below is hand-decoded from the pinned upstream tree (commit 949bb30, firmware 2.12.11; see coprocessor/esp32c6/pins.env), and each block names the upstream file it came from:

  • common/esp_hosted_header.hstruct esp_payload_header.
  • common/transport/esp_hosted_transport.h – buffer size, interface identifiers, compute_checksum().
  • host/drivers/transport/spi/spi_drv.c – reference host pacing and receive validation.

[Ring 6 / App] {World: S}

Since
0.1.0

Definition in file c6_proto.h.

Enumeration Type Documentation

◆ c6_bitop_t

enum c6_bitop_t : uint8_t

Shifts and masks used to unpack the header.

Every one of these names a field boundary in struct esp_payload_header; none is a bare literal at a use site.

Invariant
Each shift is smaller than the width of the field it moves.
Example:
const uint8_t if_num = (uint8_t)((iface >> k_c6_shift_nibble) & k_c6_mask_nibble);
@ k_c6_shift_nibble
if_num sits in the upper nibble.
Definition c6_proto.h:194
@ k_c6_mask_nibble
Four-bit field mask.
Definition c6_proto.h:195
See also
c6_hdr_offset_t
Enumerator
k_c6_shift_nibble 

if_num sits in the upper nibble.

k_c6_mask_nibble 

Four-bit field mask.

k_c6_shift_byte 

Little-endian high-byte shift.

k_c6_mask_throttle 

throttle_cmd occupies bits 1:0.

Definition at line 193 of file c6_proto.h.

◆ c6_frame_kind_t

enum c6_frame_kind_t : uint8_t

Classification of one received 1600-byte transaction.

Mirrors the acceptance rules of process_spi_rx_buf() in esp-hosted-mcu host/drivers/transport/spi/spi_drv.c, with the C6's idle filler frame recognised ahead of them so a quiet-but-alive link is never mistaken for a dead one.

Invariant
Exactly one kind describes any received buffer.
Example:
if (c6_probe_classify(&hdr) == k_c6_frame_data) { ... }
@ k_c6_frame_data
Real frame, checksum verified.
Definition c6_proto.h:227
c6_frame_kind_t c6_probe_classify(const c6_hdr_t *h)
Judge a decoded header against the upstream receive rules.
Definition c6_frame.c:95
See also
c6_probe_classify
Enumerator
k_c6_frame_garbage 

No recognisable esp-hosted structure.

k_c6_frame_idle 

The C6's idle filler frame.

k_c6_frame_data 

Real frame, checksum verified.

k_c6_frame_bad_csum 

Header shape sane, checksum mismatched.

Definition at line 224 of file c6_proto.h.

◆ c6_hdr_offset_t

enum c6_hdr_offset_t : uint8_t

Byte offsets of every field in the esp-hosted payload header.

Hand-decoded from struct esp_payload_header in esp-hosted-mcu common/esp_hosted_header.h. The struct is packed and every multi-byte field is little-endian on the wire (the reference host wraps each one in le16toh / htole16). Byte 0 packs two nibbles: if_type occupies bits 3:0 and if_num bits 7:4, which is how the little-endian ABI lays out the two four-bit members in declaration order.

Invariant
Every offset is below k_c6_proto_hdr_size.
Example:
const uint8_t iface = rx[k_c6_hdr_off_iface];
@ k_c6_hdr_off_iface
if_type[3:0] | if_num[7:4].
Definition c6_proto.h:96
See also
c6_hdr_t
Enumerator
k_c6_hdr_off_iface 

if_type[3:0] | if_num[7:4].

k_c6_hdr_off_flags 

Fragment / wake / power-save bits.

k_c6_hdr_off_len_lo 

Payload length, low byte.

k_c6_hdr_off_len_hi 

Payload length, high byte.

k_c6_hdr_off_off_lo 

Payload offset, low byte.

k_c6_hdr_off_off_hi 

Payload offset, high byte.

k_c6_hdr_off_csum_lo 

Checksum, low byte.

k_c6_hdr_off_csum_hi 

Checksum, high byte.

k_c6_hdr_off_seq_lo 

Sequence number, low byte.

k_c6_hdr_off_seq_hi 

Sequence number, high byte.

k_c6_hdr_off_throttle 

throttle_cmd[1:0] | reserved[7:2].

k_c6_hdr_off_pkttype 

reserved3 / hci_ or priv_pkt_type.

Definition at line 95 of file c6_proto.h.

◆ c6_if_type_t

enum c6_if_type_t : uint8_t

esp-hosted interface identifiers carried in if_type.

Mirrors esp_hosted_if_type_t in esp-hosted-mcu common/esp_hosted_interface.h. k_c6_if_max doubles as the "this frame carries nothing" marker: both the reference host (spi_drv.c) and the C6's peripheral-side SPI driver stamp it into the header of an idle filler transaction.

Invariant
Values are contiguous from zero, matching the upstream enum.
Example:
tx[k_c6_hdr_off_iface] = (uint8_t)k_c6_if_max; // idle filler frame
@ k_c6_if_max
Idle filler marker.
Definition c6_proto.h:139
See also
c6_proto_priv_t
Enumerator
k_c6_if_invalid 

Unused slot zero.

k_c6_if_sta 

Wi-Fi station data.

k_c6_if_ap 

Wi-Fi soft-AP data.

k_c6_if_serial 

Control-plane (RPC) channel.

k_c6_if_hci 

Bluetooth HCI.

k_c6_if_priv 

Private events, e.g.

the INIT event.

k_c6_if_test 

Raw throughput test channel.

k_c6_if_eth 

Ethernet data.

k_c6_if_max 

Idle filler marker.

Definition at line 130 of file c6_proto.h.

◆ c6_proto_dim_t

enum c6_proto_dim_t : uint16_t

Fixed transport dimensions of the esp-hosted SPI FD transport.

Source: esp-hosted-mcu common/transport/esp_hosted_transport.h (ESP_TRANSPORT_SPI_MAX_BUF_SIZE) and common/esp_hosted_header.h (struct esp_payload_header, twelve packed bytes). Both peers set the transaction length to the full buffer regardless of how much payload is live, so the controller must always clock exactly k_c6_proto_buf_size bytes.

Invariant
k_c6_proto_payload_max + k_c6_proto_hdr_size == k_c6_proto_buf_size.
Example:
static uint8_t rx[k_c6_proto_buf_size];
@ k_c6_proto_buf_size
Bytes clocked per transaction.
Definition c6_proto.h:68
See also
c6_hdr_offset_t
Enumerator
k_c6_proto_buf_size 

Bytes clocked per transaction.

k_c6_proto_hdr_size 

sizeof(struct esp_payload_header).

k_c6_proto_payload_max 

Largest payload the header may claim.

Definition at line 67 of file c6_proto.h.

◆ c6_proto_priv_t

enum c6_proto_priv_t : uint8_t

Private-interface packet and event tags, plus the filler signature.

ESP_PRIV_PACKET_TYPE / ESP_PRIV_EVENT_TYPE come from esp-hosted-mcu common/transport/esp_hosted_transport.h. The C6 queues exactly one private event at boot – an ESP_PRIV_EVENT_INIT carried on k_c6_if_priv – and it stays queued until a host drains it, which is what makes it the ideal first-light payload.

get_next_tx_buffer() in the C6's peripheral-side SPI driver zeroes a buffer and stamps if_type = ESP_MAX_IF plus if_num = 0xF for an idle filler frame, leaving length, offset and checksum at zero. Recognising that signature matters: an idle frame proves the wire, the clock polarity and the C6's SPI peripheral are all live even after the queued INIT event has been drained, and it is trivially distinguishable from a dead bus reading all-zero or all-ones.

Invariant
k_c6_dummy_if_num fits in the header's four-bit field.
Example:
const bool idle = (h.if_type == (uint8_t)k_c6_if_max) &&
(h.if_num == (uint8_t)k_c6_dummy_if_num);
@ k_c6_dummy_if_num
if_num the C6 stamps into filler frames.
Definition c6_proto.h:174
See also
c6_if_type_t
Enumerator
k_c6_priv_pkt_event 

priv_pkt_type of an event frame.

k_c6_priv_event_init 

event_type of the boot INIT event.

k_c6_dummy_if_num 

if_num the C6 stamps into filler frames.

Definition at line 171 of file c6_proto.h.

Function Documentation

◆ c6_probe_checksum()

uint16_t c6_probe_checksum ( const uint8_t * buf,
uint16_t count )

Recompute the esp-hosted checksum over a received frame.

compute_checksum() in esp-hosted-mcu common/transport/esp_hosted_transport.h is a plain 16-bit sum of every byte from the start of the header through the end of the payload. Both peers zero the checksum field before summing (process_spi_rx_buf in host/drivers/transport/spi/spi_drv.c), so the two checksum bytes are skipped here instead of being cleared, which leaves the receive buffer intact for the hex dump.

Parameters
[in]bufReceive buffer.
[in]countBytes to sum: header offset plus payload length.
Returns
The 16-bit sum, or zero when buf is NULL.
Return values
0buf was NULL, count was zero, or the sum is zero.
Precondition
buf holds at least count bytes.
count is no larger than k_c6_proto_buf_size.
Postcondition
The buffer is unmodified.
Overflow wraps at 16 bits, exactly as upstream does.
Note
Requires buf to be stable for the duration of the call.
Example:
const uint16_t sum = c6_probe_checksum(rx, (uint16_t)(h.offset + h.len));
uint16_t c6_probe_checksum(const uint8_t *buf, uint16_t count)
Recompute the esp-hosted checksum over a received frame.
Definition c6_frame.c:55
See also
c6_probe_decode_header
Since
0.1.0

Definition at line 55 of file c6_frame.c.

References k_c6_hdr_off_csum_hi, k_c6_hdr_off_csum_lo, and k_c6_proto_buf_size.

Referenced by c6_probe_decode_header().

◆ c6_probe_classify()

c6_frame_kind_t c6_probe_classify ( const c6_hdr_t * h)

Judge a decoded header against the upstream receive rules.

Parameters
[in]hDecoded header.
Returns
The frame classification.
Return values
k_c6_frame_idleIdle filler frame from the C6.
k_c6_frame_dataReal frame whose checksum verified.
k_c6_frame_bad_csumReal-looking frame with a bad checksum.
k_c6_frame_garbageNo esp-hosted structure at all, or NULL input.
Precondition
h was produced by c6_probe_decode_header.
h is non-NULL for a real verdict.
Postcondition
h is unmodified.
Exactly one classification is returned.
Note
Pure function; safe from any context.
Example:
c6_frame_kind_t
Classification of one received 1600-byte transaction.
Definition c6_proto.h:224
See also
c6_frame_kind_t
Since
0.1.0

Judge a decoded header against the upstream receive rules.

Definition at line 95 of file c6_frame.c.

References c6_hdr_t::checksum, c6_hdr_t::computed, c6_hdr_t::if_num, c6_hdr_t::if_type, k_c6_dummy_if_num, k_c6_frame_bad_csum, k_c6_frame_data, k_c6_frame_garbage, k_c6_frame_idle, k_c6_if_max, k_c6_proto_hdr_size, k_c6_proto_payload_max, c6_hdr_t::len, and c6_hdr_t::offset.

Referenced by internal_report_frame().

◆ c6_probe_decode_header()

void c6_probe_decode_header ( const uint8_t * buf,
c6_hdr_t * out )

Unpack the twelve-byte esp-hosted payload header.

Parameters
[in]bufReceive buffer holding a completed transaction.
[out]outDecoded header; ignored when NULL.
Precondition
buf holds at least k_c6_proto_hdr_size bytes.
out is non-NULL for anything to be stored.
Postcondition
Every out field is populated from the wire bytes.
out->computed holds the locally recomputed checksum.
Note
Performs no validation; c6_probe_classify judges the result.
Example:
c6_hdr_t h = {};
void c6_probe_decode_header(const uint8_t *buf, c6_hdr_t *out)
Unpack the twelve-byte esp-hosted payload header.
Definition c6_frame.c:72
Decoded esp-hosted payload header plus the locally recomputed sum.
Definition c6_proto.h:246
See also
c6_probe_classify
Since
0.1.0

Definition at line 72 of file c6_frame.c.

References c6_probe_checksum(), c6_hdr_t::checksum, c6_hdr_t::computed, c6_hdr_t::flags, c6_hdr_t::if_num, c6_hdr_t::if_type, internal_le16(), k_c6_hdr_off_csum_lo, k_c6_hdr_off_flags, k_c6_hdr_off_iface, k_c6_hdr_off_len_lo, k_c6_hdr_off_off_lo, k_c6_hdr_off_pkttype, k_c6_hdr_off_seq_lo, k_c6_hdr_off_throttle, k_c6_mask_nibble, k_c6_mask_throttle, k_c6_proto_hdr_size, k_c6_proto_payload_max, k_c6_shift_nibble, c6_hdr_t::len, c6_hdr_t::offset, c6_hdr_t::pkt_type, c6_hdr_t::seq_num, and c6_hdr_t::throttle.

Referenced by internal_report_frame().

◆ c6_probe_dump_payload()

void c6_probe_dump_payload ( const uint8_t * buf,
uint16_t len )

Hex-dump the leading payload bytes of a received frame.

Parameters
[in]bufReceive buffer.
[in]lenPayload length claimed by the header.
Precondition
The board UART console has been initialised.
buf holds a completed transaction.
Postcondition
At most k_c6_probe_dump_bytes payload bytes were printed.
buf is unmodified.
Note
Not thread-safe.
Example:
void c6_probe_dump_payload(const uint8_t *buf, uint16_t len)
Hex-dump the leading payload bytes of a received frame.
Definition c6_frame.c:142
See also
c6_probe_print_header
Since
0.1.0

Definition at line 142 of file c6_frame.c.

References c6_probe_put_hex(), c6_probe_puts(), k_c6_fmt_hex_byte, k_c6_probe_dump_bytes, and k_c6_proto_hdr_size.

Referenced by internal_report_frame().

◆ c6_probe_print_header()

void c6_probe_print_header ( const c6_hdr_t * h)

Print the decoded header fields on one console line.

Parameters
[in]hDecoded header; ignored when NULL.
Precondition
The board UART console has been initialised.
h is non-NULL for anything to be printed.
Postcondition
Exactly one console line was emitted when h is non-NULL.
h is unmodified.
Note
Not thread-safe.
Example:
void c6_probe_print_header(const c6_hdr_t *h)
Print the decoded header fields on one console line.
Definition c6_frame.c:116
See also
c6_probe_dump_payload
Since
0.1.0

Definition at line 116 of file c6_frame.c.

References c6_probe_put_hex(), c6_probe_put_u32(), c6_probe_puts(), c6_hdr_t::checksum, c6_hdr_t::computed, c6_hdr_t::flags, c6_hdr_t::if_num, c6_hdr_t::if_type, k_c6_fmt_hex_byte, k_c6_fmt_hex_word, c6_hdr_t::len, c6_hdr_t::offset, c6_hdr_t::pkt_type, and c6_hdr_t::seq_num.

Referenced by internal_report_frame().