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

Bring-up and teardown of the esp-hosted RA8D2 + ThreadX port. More...

#include "ra8_esp_hosted_port.h"
#include <stdint.h>
#include "esp_hosted_os_abstraction.h"
#include "port_esp_hosted_host_config.h"
#include "port_esp_hosted_host_log.h"
#include "port_esp_hosted_host_os.h"
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_esp_hosted_gpio_internal.h"
#include "ra8_esp_hosted_osi_internal.h"
#include "ra8_esp_hosted_pins.h"
#include "ra8_esp_hosted_port_internal.h"
#include "ra8_esp_hosted_rtos_internal.h"
#include "ra8_esp_hosted_spi_internal.h"
#include "ra8_port_constants.h"
Include dependency graph for ra8_esp_hosted_port.c:

Go to the source code of this file.

Enumerations

enum  ra8_esp_hosted_port_limit_t : uint8_t { k_ra8_esp_hosted_port_sci_channels = 10U }
 Bounds the bring-up path validates against. More...

Functions

 DEFINE_LOG_TAG (port)
ra8_err_t priv_ra8_esp_hosted_port_cfg_check (const ra8_esp_hosted_port_cfg_t *cfg)
 Implementation of priv_ra8_esp_hosted_port_cfg_check() – a pure predicate, so bring-up can reject a configuration before claiming anything.
static bool internal_pin_in_range (uint16_t pin)
 Whether a packed pin code decodes to a legal port and pin index.
ra8_err_t priv_ra8_esp_hosted_port_pins_check_values (uint16_t chip_select, uint16_t handshake, uint16_t data_ready)
 Implementation of priv_ra8_esp_hosted_port_pins_check_values() – distinctness first, then range, so a duplicated assignment is reported as such rather than as an out-of-range pin.
ra8_err_t priv_ra8_esp_hosted_port_pins_check (void)
 Implementation of priv_ra8_esp_hosted_port_pins_check() – applies the value check to the compiled-in map.
static ra8_err_t internal_configure_sideband (void)
 Configure the two side-band nets as digital inputs.
static ra8_err_t internal_unwind (void)
 Release everything the bring-up path may have claimed.
ra8_err_t priv_ra8_esp_hosted_port_first_error (ra8_err_t first, ra8_err_t next)
 Implementation of priv_ra8_esp_hosted_port_first_error() – a pure fold, so the unwind path carries no decision of its own.
static ra8_err_t internal_bring_up (const ra8_esp_hosted_port_cfg_t *cfg)
 Bring the port's slices up in dependency order.
ra8_err_t ra8_esp_hosted_port_init (const ra8_esp_hosted_port_cfg_t *cfg)
 Implementation of ra8_esp_hosted_port_init() – validate, then bring the slices up in dependency order, unwinding on the first failure.
ra8_err_t ra8_esp_hosted_port_deinit (void)
 Implementation of ra8_esp_hosted_port_deinit() – refuses when the port was never up, so a double teardown is visible rather than silently accepted.
bool ra8_esp_hosted_port_is_ready (void)
 Implementation of ra8_esp_hosted_port_is_ready() – one aligned load, so it is safe from any context.
bool ra8_esp_hosted_port_rx_pending (void)
 Report whether the co-processor has queued receive data.

Variables

static bool s_ra8_esp_hosted_port_ready
 Whether the port has completed bring-up and not been torn down.

Detailed Description

Bring-up and teardown of the esp-hosted RA8D2 + ThreadX port.

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

Sequences the port's four slices and unwinds them in the opposite order. The order is not arbitrary:

  1. Validate first, touch nothing. The configuration and the compiled-in pin map are checked before any hardware is claimed, so a mistyped clock or a duplicated pin assignment fails with no pin stranded and no channel half-open.
  2. RTOS pools. Everything after this point may need to allocate, and on this board allocation means the port's fixed ThreadX byte pool – there is no heap.
  3. The vtable. Bound before the pins, because the pins are configured through it: doing it that way exercises the same rows the vendored driver will use, so a binding mistake surfaces during bring-up rather than on the first frame.
  4. The SPI channel, then the two side-band inputs.

Teardown walks back up, and every step runs even if an earlier one reports a problem – a teardown that stops at the first error leaves exactly the stranded pin it was supposed to release.

Since
0.1.0

Definition in file ra8_esp_hosted_port.c.

Enumeration Type Documentation

◆ ra8_esp_hosted_port_limit_t

Bounds the bring-up path validates against.

Named so each rejection reads as a contract violation rather than a comparison against a bare number.

Invariant
k_ra8_esp_hosted_port_sci_channels matches the number of SCI channels the RA8D2 provides.
Example:
if (cfg->sci_channel >= (uint8_t)k_ra8_esp_hosted_port_sci_channels) { reject(); }
@ k_ra8_esp_hosted_port_sci_channels
SCI channels on this part; a channel index must be below this.
See also
priv_ra8_esp_hosted_port_cfg_check
Since
0.1.0
Enumerator
k_ra8_esp_hosted_port_sci_channels 

SCI channels on this part; a channel index must be below this.

Definition at line 73 of file ra8_esp_hosted_port.c.

Function Documentation

◆ DEFINE_LOG_TAG()

DEFINE_LOG_TAG ( port )

◆ internal_bring_up()

ra8_err_t internal_bring_up ( const ra8_esp_hosted_port_cfg_t * cfg)
static

Bring the port's slices up in dependency order.

The second half of ra8_esp_hosted_port_init, split out so validation and bring-up are separately readable and each stays inside the project's function-length limit. Every step depends on the one before it: the RTOS substrate must exist before the vtable can be bound, the vtable must be bound before the edge-poll period or the side-band pins can be reached through it, and the bus must be open before the co-processor is spoken to.

The RTOS init is separate from the chain below it because it is the only step whose failure leaves nothing to release: the err == k_ra8_ok ladder starts once there is state a caller would have to unwind.

The readiness of the port is not re-tested here; ra8_esp_hosted_port_init establishes it before calling, and a second test would be a branch no caller can reach.

Parameters
[in]cfgValidated configuration; must be non-null and already accepted by priv_ra8_esp_hosted_port_cfg_check.
Returns
ra8_err_t Error code.
Return values
k_ra8_okEvery slice came up.
k_ra8_err_null_ptrcfg was null.
k_ra8_err_rtos_errorThe ThreadX substrate would not initialise.
k_ra8_err_spi_errorThe SCI channel would not open.
k_ra8_err_gpio_conflictA side-band pin would not configure.
Precondition
cfg has already passed priv_ra8_esp_hosted_port_cfg_check.
The port is not already up, which the caller has established.
Postcondition
On success every slice is up and the vtable is fully bound.
On failure nothing this call claimed is left claimed; the caller unwinds and the module stays not-ready.
Note
Not thread-safe; part of the single-threaded bring-up path.
See also
ra8_esp_hosted_port_init
Since
0.1.0

Definition at line 306 of file ra8_esp_hosted_port.c.

References ra8_esp_hosted_port_cfg::edge_poll_ms, g_hosted_osi_funcs, internal_configure_sideband(), k_ra8_ok, ra8_esp_hosted_port_cfg::pclk_hz, priv_ra8_esp_hosted_gpio_set_edge_poll_ms(), priv_ra8_esp_hosted_osi_bind_all(), priv_ra8_esp_hosted_rtos_init(), priv_ra8_esp_hosted_spi_open(), RA8_CHECK_NULL_PTR, s_esp_hosted_tag, ra8_esp_hosted_port_cfg::sci_channel, and ra8_esp_hosted_port_cfg::sck_hz.

Referenced by ra8_esp_hosted_port_init().

◆ internal_configure_sideband()

ra8_err_t internal_configure_sideband ( void )
static

Configure the two side-band nets as digital inputs.

Goes through the freshly-bound vtable rather than calling the GPIO HAL directly, so bring-up exercises the same rows the vendored driver will use. A row bound to the wrong function therefore fails here, where the error message names the port, instead of on the first frame.

Returns
ra8_err_t Error code.
Return values
k_ra8_okBoth pins are inputs.
k_ra8_err_gpio_conflictA pin is owned by another module, or a vtable row rejected the request.
Precondition
The vtable has been bound.
Neither pin is currently claimed by another module.
Postcondition
On success both pins are configured as inputs.
On failure neither pin is left half-configured by this call.
Note
Not thread-safe; part of the single-threaded bring-up path.
Since
0.1.0

Definition at line 200 of file ra8_esp_hosted_port.c.

References ESP_LOGE, g_h, H_GPIO_DATA_READY_Pin, H_GPIO_DATA_READY_Port, H_GPIO_HANDSHAKE_Pin, H_GPIO_HANDSHAKE_Port, H_GPIO_MODE_DEF_INPUT, k_ra8_err_gpio_conflict, k_ra8_ok, RET_OK, and s_esp_hosted_tag.

Referenced by internal_bring_up().

◆ internal_pin_in_range()

bool internal_pin_in_range ( uint16_t pin)
static

Whether a packed pin code decodes to a legal port and pin index.

k_ra8_pin_none decodes to port 255, pin 255, so the range test rejects it without needing a separate comparison against the sentinel.

Parameters
[in]pinPacked RA8_PIN(port, pin) code.
Returns
Whether both halves are within range.
Return values
trueThe port is at most k_ra8_port_max and the pin at most k_ra8_pin_max.
falseEither half is out of range, including the no-pin sentinel.
Precondition
The value is a packed pin code, not a raw port or pin index.
The caller treats the no-pin sentinel as a rejection.
Postcondition
No state is modified.
The answer depends only on pin.
Note
Reentrant; a pure predicate.
Since
0.1.0

Definition at line 138 of file ra8_esp_hosted_port.c.

References k_ra8_pin_max, k_ra8_port_max, pin, RA8_PIN_PIN, and RA8_PIN_PORT.

Referenced by priv_ra8_esp_hosted_port_pins_check_values().

◆ internal_unwind()

ra8_err_t internal_unwind ( void )
static

Release everything the bring-up path may have claimed.

Runs every step regardless of what the previous one reported, because a teardown that stops at the first error strands exactly the resource it was meant to release. The first error seen is what it returns.

Returns
ra8_err_t Error code.
Return values
k_ra8_okEvery step released cleanly.
k_ra8_err_rtos_errorThreadX refused to release an object.
k_ra8_err_spi_errorThe SCI channel would not close.
Precondition
No interrupt handler for this port is currently executing.
The vendored transport has been stopped.
Postcondition
Every step has been attempted exactly once.
The module reports not ready.
Note
Not thread-safe; part of the single-threaded teardown path.
Since
0.1.0

Definition at line 239 of file ra8_esp_hosted_port.c.

References g_hosted_osi_funcs, k_ra8_ok, priv_ra8_esp_hosted_port_first_error(), priv_ra8_esp_hosted_rtos_deinit(), priv_ra8_esp_hosted_spi_close(), and s_ra8_esp_hosted_port_ready.

Referenced by ra8_esp_hosted_port_deinit(), and ra8_esp_hosted_port_init().

◆ priv_ra8_esp_hosted_port_cfg_check()

ra8_err_t priv_ra8_esp_hosted_port_cfg_check ( const ra8_esp_hosted_port_cfg_t * cfg)
nodiscard

Implementation of priv_ra8_esp_hosted_port_cfg_check() – a pure predicate, so bring-up can reject a configuration before claiming anything.

Check a port configuration against its documented contract.

Definition at line 95 of file ra8_esp_hosted_port.c.

References ra8_esp_hosted_port_cfg::edge_poll_ms, k_ra8_err_invalid_arg, k_ra8_esp_hosted_port_sci_channels, k_ra8_ok, ra8_esp_hosted_port_cfg::pclk_hz, RA8_CHECK_NULL_PTR, s_esp_hosted_tag, ra8_esp_hosted_port_cfg::sci_channel, and ra8_esp_hosted_port_cfg::sck_hz.

Referenced by ra8_esp_hosted_port_init().

◆ priv_ra8_esp_hosted_port_first_error()

ra8_err_t priv_ra8_esp_hosted_port_first_error ( ra8_err_t first,
ra8_err_t next )
nodiscard

Implementation of priv_ra8_esp_hosted_port_first_error() – a pure fold, so the unwind path carries no decision of its own.

Keep the first error of a teardown sequence, discarding later ones.

Definition at line 258 of file ra8_esp_hosted_port.c.

References k_ra8_ok.

Referenced by internal_unwind().

◆ priv_ra8_esp_hosted_port_pins_check()

ra8_err_t priv_ra8_esp_hosted_port_pins_check ( void )
nodiscard

Implementation of priv_ra8_esp_hosted_port_pins_check() – applies the value check to the compiled-in map.

Check the compiled-in pin map for self-consistency.

Definition at line 170 of file ra8_esp_hosted_port.c.

References k_ra8_esp_hosted_pin_chip_select, k_ra8_esp_hosted_pin_data_ready, k_ra8_esp_hosted_pin_handshake, and priv_ra8_esp_hosted_port_pins_check_values().

Referenced by ra8_esp_hosted_port_init().

◆ priv_ra8_esp_hosted_port_pins_check_values()

ra8_err_t priv_ra8_esp_hosted_port_pins_check_values ( uint16_t chip_select,
uint16_t handshake,
uint16_t data_ready )
nodiscard

Implementation of priv_ra8_esp_hosted_port_pins_check_values() – distinctness first, then range, so a duplicated assignment is reported as such rather than as an out-of-range pin.

Check three candidate pin assignments for self-consistency.

Definition at line 148 of file ra8_esp_hosted_port.c.

References internal_pin_in_range(), k_ra8_err_invalid_arg, and k_ra8_ok.

Referenced by priv_ra8_esp_hosted_port_pins_check().

◆ ra8_esp_hosted_port_deinit()

ra8_err_t ra8_esp_hosted_port_deinit ( void )
nodiscard

Implementation of ra8_esp_hosted_port_deinit() – refuses when the port was never up, so a double teardown is visible rather than silently accepted.

Tear the port down, releasing every pin, interrupt and pool.

Definition at line 364 of file ra8_esp_hosted_port.c.

References internal_unwind(), k_ra8_err_not_initialized, and s_ra8_esp_hosted_port_ready.

◆ ra8_esp_hosted_port_init()

ra8_err_t ra8_esp_hosted_port_init ( const ra8_esp_hosted_port_cfg_t * cfg)
nodiscard

Implementation of ra8_esp_hosted_port_init() – validate, then bring the slices up in dependency order, unwinding on the first failure.

Bring the esp-hosted port up and publish the OS-abstraction vtable.

Definition at line 331 of file ra8_esp_hosted_port.c.

References ESP_LOGE, ESP_LOGI, internal_bring_up(), internal_unwind(), k_ra8_err_invalid_state, k_ra8_ok, priv_ra8_esp_hosted_port_cfg_check(), priv_ra8_esp_hosted_port_pins_check(), s_esp_hosted_tag, s_ra8_esp_hosted_port_ready, ra8_esp_hosted_port_cfg::sci_channel, and ra8_esp_hosted_port_cfg::sck_hz.

Referenced by tx_application_define().

◆ ra8_esp_hosted_port_is_ready()

bool ra8_esp_hosted_port_is_ready ( void )
nodiscard

Implementation of ra8_esp_hosted_port_is_ready() – one aligned load, so it is safe from any context.

Report whether the port is currently initialised.

Definition at line 374 of file ra8_esp_hosted_port.c.

References s_ra8_esp_hosted_port_ready.

Referenced by c6_fwver_pump_check(), c6_hosted_heartbeat(), internal_init_hook(), internal_ra8_esp_hosted_c6link_delay(), internal_ra8_esp_hosted_c6link_handshake(), internal_ra8_esp_hosted_c6link_transfer(), and ra8_esp_hosted_c6link_bind().

◆ ra8_esp_hosted_port_rx_pending()

bool ra8_esp_hosted_port_rx_pending ( void )
nodiscard

Report whether the co-processor has queued receive data.

Samples the held DATA_READY side-band signal through the bound esp-hosted GPIO seam. This is a non-blocking level check for poll schedulers; it does not clock SPI or consume the pending frame.

Returns
Whether one or more receive frames are pending.
Return values
trueDATA_READY is asserted on an initialized port.
falseThe port is not initialized or DATA_READY is inactive.
Precondition
The caller does not concurrently tear the port down.
DATA_READY retains the board-qualified active polarity.
Postcondition
No GPIO, SPI, or queue state is modified.
A true result remains advisory until the caller acquires its wire lock.
Note
Reentrant while the port remains initialized.
Since
0.1.0

Definition at line 379 of file ra8_esp_hosted_port.c.

References g_h, H_DR_VAL_ACTIVE, H_GPIO_DATA_READY_Pin, H_GPIO_DATA_READY_Port, and s_ra8_esp_hosted_port_ready.

Referenced by internal_rx_worker_entry().

Variable Documentation

◆ s_ra8_esp_hosted_port_ready

bool s_ra8_esp_hosted_port_ready
static

Whether the port has completed bring-up and not been torn down.

The single piece of module state. Set only after every slice has reported success, so a partially-initialised port never reports ready.

Note
Read by ra8_esp_hosted_port_is_ready and by the vtable's init hook.
Warning
Do not set it directly; the bring-up path owns it.
Since
0.1.0

Definition at line 89 of file ra8_esp_hosted_port.c.

Referenced by internal_unwind(), ra8_esp_hosted_port_deinit(), ra8_esp_hosted_port_init(), ra8_esp_hosted_port_is_ready(), and ra8_esp_hosted_port_rx_pending().