|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
The esp-hosted transaction pump: frame in, frame out, counted. More...
#include <stdint.h>#include "c6_fwver.h"#include "esp_hosted_header.h"#include "esp_hosted_interface.h"#include "esp_hosted_os_abstraction.h"#include "esp_hosted_transport.h"#include "port_esp_hosted_host_config.h"#include "port_esp_hosted_host_os.h"#include "ra8_esp_hosted_port.h"#include "transport_drv.h"Go to the source code of this file.
Enumerations | |
| enum | c6_fwver_proto_t : uint16_t { k_c6_fwver_hdr_bytes = (uint16_t)sizeof(struct esp_payload_header) , k_c6_fwver_max_payload = (uint16_t)MAX_PAYLOAD_SIZE , k_c6_fwver_nibble_mask = 0x0FU , k_c6_fwver_ifnum_shift = 4U } |
| Protocol constants the pump judges a received frame against. More... | |
Functions | |
| static void | c6_fwver_tx_clear (void) |
| Zero the whole transmit frame. | |
| static void | c6_fwver_tx_filler (void) |
| Stamp the transmit frame as the host's idle filler. | |
| static void | c6_fwver_tx_frame (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len) |
| Wrap a payload in a payload header, checksum included. | |
| static bool | c6_fwver_wait_handshake (void) |
| Wait, bounded, for the co-processor to arm HANDSHAKE. | |
| static uint16_t | c6_fwver_rx_checksum (uint16_t span) |
| Recompute the received frame's checksum over header plus payload. | |
| static void | c6_fwver_print_reject (const char *why, uint16_t calc) |
| Print every header field of a frame the pump is about to drop. | |
| static bool | c6_fwver_ifnum_defect (uint16_t calc, uint16_t stated) |
| Decide whether a checksum failure is the known if_num defect. | |
| static bool | c6_fwver_rx_dispatch (c6_fwver_sink_t sink, c6_fwver_pump_stats_t *stats) |
| Classify the received frame and deliver it if it is real. | |
| static ra8_err_t | c6_fwver_pump_check (const uint8_t *payload, uint16_t payload_len, uint16_t max_transfers, const c6_fwver_pump_stats_t *stats) |
| Reject a pump request whose arguments cannot be honoured. | |
| ra8_err_t | c6_fwver_link_pump (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t payload_len, uint16_t max_transfers, c6_fwver_sink_t sink, c6_fwver_pump_stats_t *stats) |
| Clock full-duplex transactions until the sink is satisfied. | |
Variables | |
| static c6_fwver_frame_t | s_c6_fwver_tx |
| Transmit buffer for the frame the pump is currently clocking. | |
| static c6_fwver_frame_t | s_c6_fwver_rx |
| Receive buffer the co-processor's frame lands in. | |
The esp-hosted transaction pump: frame in, frame out, counted.
This is the application's own reduction of the vendored spi_transaction_task down to what a bring-up needs. The vendored task cannot be used here: it lives in transport_drv.c, which is written against ESP-IDF's Wi-Fi API and is deliberately not compiled into this tree (see cmake/esp_hosted.cmake). What it does on the wire, though, is small and fully specified, and this file does exactly that and nothing more:
Filler frames are counted rather than delivered. Their header is genuinely not a header – the co-processor stamps if_type = ESP_MAX_IF, if_num = 0x0F and leaves offset at zero – which is why c6_hosted_init first read one as "offset is not the payload-header size". Judging a filler frame by the rules for a data frame is a false negative, and this file does not repeat it.
Definition in file c6_fwver_link.c.
| enum c6_fwver_proto_t : uint16_t |
Protocol constants the pump judges a received frame against.
Each is derived from a vendored header, so an upstream change to the payload header or the transport buffer moves this file with it instead of leaving a stale literal behind.
Definition at line 70 of file c6_fwver_link.c.
|
static |
Decide whether a checksum failure is the known if_num defect.
The ESP32-C6 running esp-hosted-mcu 2.12.11 transmits its bootup ESP_PRIV_IF INIT event with a non-zero if_num in the header's first byte, but computes the frame checksum with that nibble still zero. The shortfall is therefore exactly if_num << 4, and a host that tests for that can say so by name instead of reporting an unexplained mismatch.
This DIAGNOSES; it does not excuse. The frame is still dropped, because the bytes on the wire do not match the integrity check that accompanies them and a host that decoded them anyway would be trusting an unverified header.
| [in] | calc | Checksum recomputed over the frame as received. |
| [in] | stated | Checksum the co-processor put in the header. |
| true | The mismatch is fully explained by the defect above. |
| false | The mismatch is something else, and stays unexplained. |
calc and stated genuinely disagree. Definition at line 295 of file c6_fwver_link.c.
References k_c6_fwver_ifnum_shift, and s_c6_fwver_rx.
Referenced by c6_fwver_rx_dispatch().
|
nodiscard |
Clock full-duplex transactions until the sink is satisfied.
The pump is this application's stand-in for the vendored spi_transaction_task, reduced to what a bring-up needs: it transmits at most one payload, then keeps clocking filler frames so the co-processor has transactions to answer in. Each iteration waits for HANDSHAKE, builds either the pending payload frame or an ESP_MAX_IF filler, clocks _h_do_bus_transfer, and classifies what came back. Frames that are well-formed and carry a payload go to sink; filler and malformed frames are counted and dropped.
| [in] | if_type | Interface type for the transmitted payload, from esp_hosted_if_type_t. Ignored when payload_len is zero. |
| [in] | if_num | Interface number for the transmitted payload, 0..15. |
| [in] | payload | Payload to transmit once, or null to pump filler only. |
| [in] | payload_len | Length of payload in bytes; must be zero when payload is null and at most k_c6_fwver_tx_max otherwise. |
| [in] | max_transfers | Transactions this call may clock; must be non-zero. |
| [in] | sink | Receiver for well-formed frames, or null to count only. |
| [out] | stats | Counters describing the run; must be non-null. |
| k_ra8_ok | The pump ran; stats says what happened. |
| k_ra8_err_null_ptr | stats was null, or payload_len was non-zero with a null payload. |
| k_ra8_err_invalid_arg | payload_len exceeds k_c6_fwver_tx_max, or max_transfers was zero. |
| k_ra8_err_not_initialized | The esp-hosted port is not up, so the vtable behind g_h cannot be called. |
| k_ra8_err_hw_timeout | HANDSHAKE never went active, so not one transaction was clocked. |
| k_ra8_err_spi_error | A bus transfer did not return RET_OK. |
max_transfers transactions were clocked. stats holds the counts for exactly this call.max_transfers and the HANDSHAKE wait by k_c6_fwver_hs_wait_ms.Definition at line 395 of file c6_fwver_link.c.
References c6_fwver_pump_stats::bus_error, c6_fwver_pump_check(), c6_fwver_rx_dispatch(), c6_fwver_tx_filler(), c6_fwver_tx_frame(), c6_fwver_wait_handshake(), g_h, c6_fwver_pump_stats::hs_timeouts, k_c6_fwver_frame_bytes, k_c6_fwver_gap_ms, k_c6_fwver_hs_giveup, k_ra8_err_hw_timeout, k_ra8_err_spi_error, k_ra8_ok, RET_OK, s_c6_fwver_rx, s_c6_fwver_tx, c6_fwver_pump_stats::sink_stopped, and c6_fwver_pump_stats::transfers.
Referenced by c6_fwver_phase_caps(), and c6_fwver_phase_request().
|
static |
Print every header field of a frame the pump is about to drop.
| [in] | why | Short reason, printed verbatim; must be non-null. |
| [in] | calc | Recomputed checksum, or zero when it was not computed. |
Definition at line 239 of file c6_fwver_link.c.
References c6_fwver_put_hex(), c6_fwver_put_u32(), c6_fwver_puts(), k_c6_fwver_hdr_bytes, k_c6_fwver_hex_byte, k_c6_fwver_hex_word, and s_c6_fwver_rx.
Referenced by c6_fwver_rx_dispatch().
|
static |
Reject a pump request whose arguments cannot be honoured.
| [in] | payload | Payload the caller passed, possibly null. |
| [in] | payload_len | Length the caller passed. |
| [in] | max_transfers | Transaction budget the caller passed. |
| [in] | stats | Counter block the caller passed, possibly null. |
| k_ra8_ok | Every argument is usable. |
| k_ra8_err_null_ptr | stats was null, or a length came with no buffer. |
| k_ra8_err_invalid_arg | max_transfers was zero. |
| k_ra8_err_invalid_size | payload_len exceeds k_c6_fwver_tx_max. |
| k_ra8_err_not_initialized | The esp-hosted port is not up. |
Definition at line 375 of file c6_fwver_link.c.
References k_c6_fwver_tx_max, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, and ra8_esp_hosted_port_is_ready().
Referenced by c6_fwver_link_pump().
|
static |
Recompute the received frame's checksum over header plus payload.
| [in] | span | Bytes the checksum is defined over. |
span is at most k_c6_fwver_frame_bytes. Definition at line 216 of file c6_fwver_link.c.
References s_c6_fwver_rx.
Referenced by c6_fwver_rx_dispatch().
|
static |
Classify the received frame and deliver it if it is real.
| [in] | sink | Receiver for a well-formed data frame, or null. |
| [in,out] | stats | Counters to update; must be non-null. |
| true | The sink accepted the frame and wants no more transactions. |
| false | Keep pumping. |
stats is the caller's live counter block. stats was incremented. Definition at line 317 of file c6_fwver_link.c.
References c6_fwver_pump_stats::bad_checksum, c6_fwver_ifnum_defect(), c6_fwver_print_reject(), c6_fwver_puts(), c6_fwver_rx_checksum(), c6_fwver_pump_stats::frames, c6_fwver_pump_stats::idle, c6_fwver_pump_stats::ifnum_defect, k_c6_fwver_hdr_bytes, k_c6_fwver_max_payload, c6_fwver_pump_stats::malformed, and s_c6_fwver_rx.
Referenced by c6_fwver_link_pump().
|
static |
Zero the whole transmit frame.
Definition at line 119 of file c6_fwver_link.c.
References k_c6_fwver_frame_bytes, and s_c6_fwver_tx.
Referenced by c6_fwver_tx_filler(), and c6_fwver_tx_frame().
|
static |
Stamp the transmit frame as the host's idle filler.
Definition at line 138 of file c6_fwver_link.c.
References c6_fwver_tx_clear(), k_c6_fwver_nibble_mask, and s_c6_fwver_tx.
Referenced by c6_fwver_link_pump().
|
static |
Wrap a payload in a payload header, checksum included.
| [in] | if_type | Interface type for the frame. |
| [in] | if_num | Interface number for the frame. |
| [in] | payload | Payload bytes; must be non-null. |
| [in] | len | Payload length, at most k_c6_fwver_max_payload. |
len bytes are readable at payload. len is at most k_c6_fwver_max_payload. Definition at line 161 of file c6_fwver_link.c.
References c6_fwver_tx_clear(), k_c6_fwver_hdr_bytes, k_c6_fwver_nibble_mask, and s_c6_fwver_tx.
Referenced by c6_fwver_link_pump().
|
static |
Wait, bounded, for the co-processor to arm HANDSHAKE.
| true | The co-processor is ready for a transaction. |
| false | k_c6_fwver_hs_wait_ms elapsed with the line inactive. |
Definition at line 189 of file c6_fwver_link.c.
References g_h, H_GPIO_HANDSHAKE_Pin, H_GPIO_HANDSHAKE_Port, H_HS_VAL_ACTIVE, k_c6_fwver_hs_poll_ms, and k_c6_fwver_hs_wait_ms.
Referenced by c6_fwver_link_pump().
|
static |
Receive buffer the co-processor's frame lands in.
Same type and alignment as s_c6_fwver_tx.
Definition at line 107 of file c6_fwver_link.c.
Referenced by c6_fwver_ifnum_defect(), c6_fwver_link_pump(), c6_fwver_print_reject(), c6_fwver_rx_checksum(), and c6_fwver_rx_dispatch().
|
static |
Transmit buffer for the frame the pump is currently clocking.
A c6_fwver_frame_t, so the payload header is reached through a union member rather than a cast. Aligned to k_c6_fwver_dma_align, the alignment the transport expects of a transaction buffer.
Definition at line 96 of file c6_fwver_link.c.
Referenced by c6_fwver_link_pump(), c6_fwver_tx_clear(), c6_fwver_tx_filler(), and c6_fwver_tx_frame().