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

The eight side-band GPIO slots of the esp-hosted OS-abstraction vtable. More...

#include <stdint.h>
#include "esp_hosted_power_save.h"
#include "port_esp_hosted_host_config.h"
#include "port_esp_hosted_host_os.h"
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_esp_hosted_gpio_internal.h"
#include "ra8_esp_hosted_pins.h"
#include "ra8_icu_regs.h"
#include "ra8_log.h"
#include "ra8_pin_interface.h"
#include "ra8_port_constants.h"
#include "ra8_port_utils.h"
#include "ra8_reset.h"
Include dependency graph for ra8_esp_hosted_gpio.c:

Go to the source code of this file.

Data Structures

struct  ra8_esp_hosted_gpio_irq_row
 One pin served by a real ICU external-interrupt channel. More...

Typedefs

typedef struct ra8_esp_hosted_gpio_irq_row ra8_esp_hosted_gpio_irq_row_t

Enumerations

enum  ra8_esp_hosted_gpio_sentinel_t : uint32_t { k_ra8_esp_hosted_gpio_pin_unwired = 0xFFFFFFFFU }
 The "signal is not wired" pin value as it arrives at a slot. More...
enum  ra8_esp_hosted_gpio_mode_t : uint32_t {
  k_ra8_esp_hosted_gpio_mode_input = 0U ,
  k_ra8_esp_hosted_gpio_mode_output = 1U
}
 Pin directions _h_config_gpio accepts. More...
enum  ra8_esp_hosted_gpio_pull_t : uint32_t {
  k_ra8_esp_hosted_gpio_pull_up = 0U ,
  k_ra8_esp_hosted_gpio_pull_down = 1U
}
 Pull selectors _h_pull_gpio accepts. More...
enum  ra8_esp_hosted_gpio_read_t : uint8_t {
  k_ra8_esp_hosted_gpio_read_low = 0U ,
  k_ra8_esp_hosted_gpio_read_high = 1U
}
 Values _h_read_gpio returns for a successful read. More...

Functions

bool priv_ra8_esp_hosted_gpio_decode_pin (const void *gpio_port, uint32_t gpio_num, ra8_port_pin_t *out_pin)
 Decode the vendored (void* port, uint32_t pin) pair into a pin.
void priv_ra8_esp_hosted_gpio_set_pin_interface (const ra8_pin_interface_t *iface)
 Replace the pin driver the slice reads and writes levels through.
const ra8_pin_interface_tpriv_ra8_esp_hosted_gpio_pin_interface (void)
 Report the pin driver currently installed in the slice.
static uint8_t internal_irq_find (ra8_port_pin_t pin)
 Find the interrupt row watching a pin.
static uint8_t internal_irq_alloc (void)
 Take the first free interrupt row.
static void internal_isr_trampoline (void *ctx)
 ICU handler shim that calls the vendored side-band callback.
static ra8_err_t internal_attach_hardware (ra8_port_pin_t pin, uint8_t irq_num, uint8_t sense, void(*handler)(void *), void *arg)
 Attach a pin to a real ICU external-interrupt channel.
static int internal_config_gpio (void *gpio_port, uint32_t gpio_num, uint32_t mode)
 _h_config_gpio: put a side-band pin in a plain digital mode.
static int internal_config_gpio_as_interrupt (void *gpio_port, uint32_t gpio_num, uint32_t intr_type, void(*gpio_isr_handler)(void *arg), void *arg)
 _h_config_gpio_as_interrupt: watch a side-band pin for an edge.
static int internal_teardown_gpio_interrupt (void *gpio_port, uint32_t gpio_num)
 _h_teardown_gpio_interrupt: stop watching a side-band pin.
static int internal_read_gpio (void *gpio_port, uint32_t gpio_num)
 _h_read_gpio: sample the raw logic level of a side-band pin.
static int internal_write_gpio (void *gpio_port, uint32_t gpio_num, uint32_t value)
 _h_write_gpio: drive a side-band output.
static int internal_pull_gpio (void *gpio_port, uint32_t gpio_num, uint32_t pull_value, uint32_t enable)
 _h_pull_gpio: enable or disable an internal pull on a pin.
static int internal_hold_gpio (void *gpio_port, uint32_t gpio_num, uint32_t hold_value)
 _h_hold_gpio: freeze a pin's state across deep sleep.
static int internal_wakeup_reason (void)
 _h_get_host_wakeup_or_reboot_reason: why the host last started.
ra8_err_t priv_ra8_esp_hosted_gpio_bind (hosted_osi_funcs_t *out)
 Populate the eight GPIO slots of the OS-abstraction vtable.

Variables

static const char *const s_tag = "eh_gpio"
 Log tag identifying lines emitted by the side-band GPIO slice.
static ra8_esp_hosted_gpio_irq_row_t s_irq_rows [k_ra8_esp_hosted_gpio_row_max]
 Pins currently attached to an ICU external-interrupt channel.
static const ra8_pin_interface_ts_pin_if
 The pin driver every level read and write goes through.
const ra8_pin_interface_t g_ra8_gpio_pin_interface

Detailed Description

The eight side-band GPIO slots of the esp-hosted OS-abstraction vtable.

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

The vendored SPI transport touches hardware pins only through these eight function pointers. It hands each one an opaque (void* port, uint32_t pin) pair, which this file decodes back into a packed ra8_port_pin_t exactly inversely to the encoding in port_esp_hosted_host_config.h – including the deliberate detail that port 0 encodes as a null pointer, so the port argument is range-checked after decoding and never null-checked.

Two of the slots need more than a HAL call. _h_config_gpio_as_interrupt has to cope with a package that routes only one of the link's side-band nets to an ICU channel, and falls back on the software edge detector in ra8_esp_hosted_gpio_edge.c for the rest. _h_hold_gpio wants per-pin state retention across deep sleep, which this HAL does not yet expose; it reports that honestly rather than pretending.

Since
0.1.0

Definition in file ra8_esp_hosted_gpio.c.

Typedef Documentation

◆ ra8_esp_hosted_gpio_irq_row_t

Enumeration Type Documentation

◆ ra8_esp_hosted_gpio_mode_t

enum ra8_esp_hosted_gpio_mode_t : uint32_t

Pin directions _h_config_gpio accepts.

Mirrors the vendored H_GPIO_MODE_DEF_* spellings so the slot can switch on a typed value; the static assertions below prove the two encodings agree.

Invariant
Exactly these two directions are accepted; anything else is rejected rather than defaulted.
Example:
if (mode == (uint32_t)k_ra8_esp_hosted_gpio_mode_output) { drive(); }
@ k_ra8_esp_hosted_gpio_mode_output
Push-pull digital output.
See also
priv_ra8_esp_hosted_gpio_bind
Since
0.1.0
Enumerator
k_ra8_esp_hosted_gpio_mode_input 

Digital input.

k_ra8_esp_hosted_gpio_mode_output 

Push-pull digital output.

Definition at line 92 of file ra8_esp_hosted_gpio.c.

◆ ra8_esp_hosted_gpio_pull_t

enum ra8_esp_hosted_gpio_pull_t : uint32_t

Pull selectors _h_pull_gpio accepts.

Mirrors the vendored H_GPIO_PULL_* spellings. Only the pull-up can be honoured on this part; the pull-down selector is recognised so it can be refused explicitly.

Invariant
The two values are distinct, so a refusal cannot be mistaken for a pull-up request.
Example:
if (pull_value == (uint32_t)k_ra8_esp_hosted_gpio_pull_down) { refuse(); }
@ k_ra8_esp_hosted_gpio_pull_down
Internal pull-down (no silicon).
See also
priv_ra8_esp_hosted_gpio_bind
Since
0.1.0
Enumerator
k_ra8_esp_hosted_gpio_pull_up 

Internal pull-up.

k_ra8_esp_hosted_gpio_pull_down 

Internal pull-down (no silicon).

Definition at line 112 of file ra8_esp_hosted_gpio.c.

◆ ra8_esp_hosted_gpio_read_t

Values _h_read_gpio returns for a successful read.

The vendored driver compares the result against H_HS_VAL_* / H_DR_VAL_*, which are plain 0 and 1, so the raw logic level is returned without inversion.

Invariant
Both values are non-negative, and every failure code the slot can return is negative, so a failure never reads as a level.
Example:
gpio_pin_state_t hs = g_h.funcs->_h_read_gpio(port, pin);
uint8_t gpio_pin_state_t
Logic level read back from, or driven onto, a side-band pin.
ra8_board_eth_pin_t pin
Pin.
struct hosted_config_t g_h
The handle the vendored core dereferences to reach the vtable.
See also
priv_ra8_esp_hosted_gpio_bind
Since
0.1.0
Enumerator
k_ra8_esp_hosted_gpio_read_low 

Pin read low.

k_ra8_esp_hosted_gpio_read_high 

Pin read high.

Definition at line 132 of file ra8_esp_hosted_gpio.c.

◆ ra8_esp_hosted_gpio_sentinel_t

The "signal is not wired" pin value as it arrives at a slot.

The vendored vtable takes the pin as uint32_t while the configuration macros produce -1 for an unwired signal, so the sentinel reaches a slot converted to all ones.

Invariant
Numerically greater than k_ra8_pin_max, so the range test would also reject it; the explicit test exists because "not wired" is a different fact from "out of range".
Example:
if (gpio_num == (uint32_t)k_ra8_esp_hosted_gpio_pin_unwired) { reject(); }
@ k_ra8_esp_hosted_gpio_pin_unwired
-1 widened to 32 bits.
See also
priv_ra8_esp_hosted_gpio_decode_pin
Since
0.1.0
Enumerator
k_ra8_esp_hosted_gpio_pin_unwired 

-1 widened to 32 bits.

Definition at line 73 of file ra8_esp_hosted_gpio.c.

Function Documentation

◆ internal_attach_hardware()

ra8_err_t internal_attach_hardware ( ra8_port_pin_t pin,
uint8_t irq_num,
uint8_t sense,
void(* handler )(void *),
void * arg )
static

Attach a pin to a real ICU external-interrupt channel.

Records the row first so the trampoline has a valid context the instant the NVIC line is enabled, then programmes the pin, the IRQCR sense and the handler in one HAL call. The digital filter stays off: the callback only posts a semaphore, so a doubled edge is harmless, while filtering would add latency to the one line that is latency-critical.

Parameters
[in]pinPacked pin to attach.
[in]irq_numICU channel serving pin, 0..15.
[in]senseEdge selector in the ra8_icu_irqmd_t encoding.
[in]handlerVendored callback; must be non-null.
[in]argOpaque argument for handler.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe channel is live.
k_ra8_err_no_memThe interrupt table is full.
k_ra8_err_existsThe channel was already registered.
k_ra8_err_gpio_conflictThe pin is owned by another module.
Precondition
ra8_icu_init and ra8_isr_init have run.
pin has no row yet.
Postcondition
On success the row is occupied and the NVIC line is enabled.
On failure the row is released, so no stale context survives.
Note
Not thread-safe; call from the transport's start-up path.
Since
0.1.0

Definition at line 370 of file ra8_esp_hosted_gpio.c.

References internal_irq_alloc(), internal_isr_trampoline(), k_ra8_err_no_mem, k_ra8_esp_hosted_gpio_irq_priority, k_ra8_esp_hosted_gpio_row_max, k_ra8_icu_fclksel_pclkb, k_ra8_ok, k_ra8_pull_none, pin, ra8_gpio_attach_irq(), ra8_log_error_val, s_irq_rows, and s_tag.

Referenced by internal_config_gpio_as_interrupt().

◆ internal_config_gpio()

int internal_config_gpio ( void * gpio_port,
uint32_t gpio_num,
uint32_t mode )
static

_h_config_gpio: put a side-band pin in a plain digital mode.

Output configuration goes through the injected pin interface, which is the only direction that has a row in ra8_pin_interface_t; input configuration calls the HAL directly. An output comes up at the level that leaves the co-processor OUT of reset, so configuring the pin can never itself assert reset.

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
[in]modeH_GPIO_MODE_DEF_INPUT or H_GPIO_MODE_DEF_OUTPUT.
Returns
int Vendored return code.
Return values
RET_OKThe pin is configured.
RET_INVALIDThe pair did not name a pin, or mode is unknown.
RET_FAILThe HAL refused the configuration.
Precondition
The IOPORT module is powered.
The pin is not already owned by a peripheral.
Postcondition
On RET_OK the pin is in the requested direction.
On any other code no pin state changed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 431 of file ra8_esp_hosted_gpio.c.

References ra8_pin_interface_t::ctx, H_RESET_VAL_INACTIVE, k_ra8_err_invalid_arg, k_ra8_esp_hosted_gpio_mode_input, k_ra8_esp_hosted_gpio_mode_output, k_ra8_ok, k_ra8_pin_none, k_ra8_pull_none, ra8_pin_interface_t::output_init, pin, priv_ra8_esp_hosted_gpio_decode_pin(), priv_ra8_esp_hosted_gpio_pin_interface(), ra8_gpio_input_init(), RET_FAIL, RET_INVALID, and RET_OK.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_config_gpio_as_interrupt()

int internal_config_gpio_as_interrupt ( void * gpio_port,
uint32_t gpio_num,
uint32_t intr_type,
void(* gpio_isr_handler )(void *arg),
void * arg )
static

_h_config_gpio_as_interrupt: watch a side-band pin for an edge.

Asks ra8_esp_hosted_pin_irq_num whether the package routes this pin to the ICU. When it does, a real hardware edge is programmed. When it does not, the pin joins the software edge detector, which delivers the identical callback at a bounded sampling latency instead of a hardware one. The vendored driver is unaware of which path it got, which is what lets the harness move without touching this code.

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
[in]intr_typeEdge selector in the ra8_icu_irqmd_t encoding.
[in]gpio_isr_handlerCallback for the edge; must be non-null.
[in]argOpaque argument handed back to the callback.
Returns
int Vendored return code.
Return values
RET_OKThe pin is watched by one of the two paths.
RET_INVALIDBad pin pair, unknown sense, or a null handler.
RET_FAILThe pin already had a row, or the HAL refused.
Precondition
The ICU and ISR tables are initialised.
The ThreadX kernel is running when the polled path is taken.
Postcondition
On RET_OK exactly one of the two paths owns the pin.
On any other code no pin is claimed by this call.
Note
Not thread-safe.
Since
0.1.0

Definition at line 481 of file ra8_esp_hosted_gpio.c.

References internal_attach_hardware(), internal_irq_find(), k_ra8_esp_hosted_gpio_row_max, k_ra8_esp_hosted_irq_none, k_ra8_icu_irqmd_low, k_ra8_ok, k_ra8_pin_none, pin, priv_ra8_esp_hosted_gpio_decode_pin(), priv_ra8_esp_hosted_gpio_edge_register(), ra8_esp_hosted_pin_irq_num(), RET_FAIL, RET_INVALID, and RET_OK.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_hold_gpio()

int internal_hold_gpio ( void * gpio_port,
uint32_t gpio_num,
uint32_t hold_value )
static

_h_hold_gpio: freeze a pin's state across deep sleep.

The vendored power-save driver calls this on the co-processor reset line so the line keeps its level while the host sleeps. On the RA8D2 that retention is DPSBYCR.IOKEEP, which is a whole-chip control applied to Deep Software Standby, and libs/ra8_hal exposes it only as one field of the configuration ra8_lpm_init consumes – there is no per-pin hold and no standalone IOKEEP setter. Driving the whole LPM block from a per-pin call would reconfigure far more than the caller asked for, so the request is refused and the caller keeps the pin awake instead of believing in a hold that never happened. Host power save is disabled in this port (H_HOST_PS_ALLOWED is 0), so nothing currently reaches this slot.

TODO(ra8_hal exposes no standalone DPSBYCR.IOKEEP control: io_port_keep is settable only through ra8_lpm_init's whole-block configuration, and there is no per-pin retention API at all)

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
[in]hold_valueH_ENABLE to freeze, H_DISABLE to release.
Returns
int Vendored return code.
Return values
RET_INVALIDThe pair did not name a pin.
RET_FAILNo per-pin retention control is available.
Precondition
The pin was configured by _h_config_gpio.
The caller treats a non-zero result as "the pin is not frozen".
Postcondition
No pin or LPM state is modified.
The caller is never told a hold succeeded.
Note
Not thread-safe.
Warning
Never make this return RET_OK without a real retention control behind it; the caller would sleep with the reset line floating.
Since
0.1.0

Definition at line 725 of file ra8_esp_hosted_gpio.c.

References k_ra8_pin_none, pin, priv_ra8_esp_hosted_gpio_decode_pin(), ra8_log_info_val, ra8_log_warn, RET_FAIL, RET_INVALID, and s_tag.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_irq_alloc()

uint8_t internal_irq_alloc ( void )
static

Take the first free interrupt row.

Rows are never compacted, because a live trampoline holds a pointer to the row it was installed with; allocation therefore only looks for a hole.

Returns
Row index, or k_ra8_esp_hosted_gpio_row_max when the table is full.
Return values
k_ra8_esp_hosted_gpio_row_maxEvery row is occupied.
Precondition
No trampoline is executing against a row being reused.
The caller has already rejected a duplicate registration.
Postcondition
No table state is modified by the search itself.
The result indexes s_irq_rows or equals the table length.
Note
Not thread-safe with respect to the teardown slot.
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: the loop is bounded by the compile-time table length.

Definition at line 298 of file ra8_esp_hosted_gpio.c.

References k_ra8_esp_hosted_gpio_row_max, and s_irq_rows.

Referenced by internal_attach_hardware().

◆ internal_irq_find()

uint8_t internal_irq_find ( ra8_port_pin_t pin)
static

Find the interrupt row watching a pin.

Linear scan over a table of four; a scan cannot be indexed out of range and is faster than any structure at this size.

Parameters
[in]pinPacked pin to look for.
Returns
Row index, or k_ra8_esp_hosted_gpio_row_max when the pin has no hardware row.
Return values
k_ra8_esp_hosted_gpio_row_maxThe pin is not attached to a channel.
Precondition
The table is only mutated with interrupts for these pins disabled.
pin is a packed RA8_PIN value.
Postcondition
No table state is modified.
The result indexes s_irq_rows or equals the table length.
Note
Safe from interrupt context; a pure scan.
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: the loop is bounded by the compile-time table length.

Definition at line 264 of file ra8_esp_hosted_gpio.c.

References k_ra8_esp_hosted_gpio_row_max, pin, and s_irq_rows.

Referenced by internal_config_gpio_as_interrupt(), and internal_teardown_gpio_interrupt().

◆ internal_isr_trampoline()

void internal_isr_trampoline ( void * ctx)
static

ICU handler shim that calls the vendored side-band callback.

Installed against the ICU channel with the owning row as its context, so the hot path is one load and one indirect call. It deliberately does not log and does not block: the callback it invokes posts a semaphore from interrupt context, which is the whole latency budget of the DATA_READY line. Registration validates the handler and publishes the completed row before enabling the interrupt, so both values are guaranteed by the row's invariant rather than checked again in interrupt context.

Parameters
[in]ctxThe ra8_esp_hosted_gpio_irq_row that installed it.
Precondition
ctx points at a row that is still occupied.
The vendored callback is safe to run from interrupt context.
Postcondition
Exactly one callback invocation per accepted edge.
No module state is modified.
Note
Interrupt context: no logging, no blocking, no allocation.
Since
0.1.0

Definition at line 332 of file ra8_esp_hosted_gpio.c.

References ra8_esp_hosted_gpio_irq_row::arg, ra8_esp_hosted_gpio_irq_row::handler, RA8_INTERNAL, and RA8_ISR_SAFE.

Referenced by internal_attach_hardware().

◆ internal_pull_gpio()

int internal_pull_gpio ( void * gpio_port,
uint32_t gpio_num,
uint32_t pull_value,
uint32_t enable )
static

_h_pull_gpio: enable or disable an internal pull on a pin.

The RA8D2 PFS carries a pull-**up** bit and nothing else, so a pull-down request is refused outright: reporting success for it would leave the caller believing a bias exists that no silicon provides. A pull-up is real, and is applied by re-taking the pin as an input with the pull selected – the pin claim is released first because the HAL's input configuration is also its claim, and the pin is already ours by this point.

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
[in]pull_valueH_GPIO_PULL_UP or H_GPIO_PULL_DOWN.
[in]enableNon-zero installs the pull; zero removes it.
Returns
int Vendored return code.
Return values
RET_OKThe requested pull-up state is in force.
RET_INVALIDThe pair did not name a pin, or the selector is unknown.
RET_FAILA pull-down was requested, or the HAL refused.
Precondition
The pin is an input, or may be turned into one.
The IOPORT module is powered.
Postcondition
On RET_OK the pin is an input with the requested pull.
A refused pull-down leaves the pin exactly as it was.
Note
Not thread-safe.
Warning
No internal pull-down exists on this part; fit an external resistor if the harness needs one.
Since
0.1.0

Definition at line 668 of file ra8_esp_hosted_gpio.c.

References k_ra8_esp_hosted_gpio_pull_down, k_ra8_esp_hosted_gpio_pull_up, k_ra8_ok, k_ra8_pin_none, k_ra8_pull_none, k_ra8_pull_up, pin, priv_ra8_esp_hosted_gpio_decode_pin(), ra8_gpio_input_init(), ra8_gpio_release(), ra8_log_warn, RET_FAIL, RET_INVALID, RET_OK, and s_tag.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_read_gpio()

int internal_read_gpio ( void * gpio_port,
uint32_t gpio_num )
static

_h_read_gpio: sample the raw logic level of a side-band pin.

Returns the level uninverted. The vendored driver compares the result against H_HS_VAL_ACTIVE and friends, which already encode the harness polarity, so inverting here would apply that polarity twice. Both failure codes are negative and therefore cannot be mistaken for either level.

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
Returns
int The level, or a vendored failure code.
Return values
0The pin read low.
1The pin read high.
RET_INVALIDThe pair did not name a pin.
RET_FAILThe pin driver could not read the pin.
Precondition
The pin was configured as an input, or is an output being read back.
A pin interface is installed (one always is).
Postcondition
No pin state is modified.
The result is 0, 1, or a negative failure code.
Note
Safe from interrupt context when the installed interface is.
Since
0.1.0

Definition at line 581 of file ra8_esp_hosted_gpio.c.

References ra8_pin_interface_t::ctx, k_ra8_esp_hosted_gpio_read_high, k_ra8_esp_hosted_gpio_read_low, k_ra8_level_high, k_ra8_level_low, k_ra8_ok, k_ra8_pin_none, pin, priv_ra8_esp_hosted_gpio_decode_pin(), priv_ra8_esp_hosted_gpio_pin_interface(), ra8_pin_interface_t::read, RET_FAIL, and RET_INVALID.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_teardown_gpio_interrupt()

int internal_teardown_gpio_interrupt ( void * gpio_port,
uint32_t gpio_num )
static

_h_teardown_gpio_interrupt: stop watching a side-band pin.

Undoes whichever of the two paths took the pin: a hardware row is detached from the ICU and freed, anything else is offered to the software edge detector. A pin that neither path holds is reported as a failure rather than silently accepted, because the vendored driver only calls this for pins it believes it registered.

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
Returns
int Vendored return code.
Return values
RET_OKThe pin is no longer watched.
RET_INVALIDThe pair did not name a pin.
RET_FAILThe pin was not registered, or the HAL refused.
Precondition
No handler for this pin is currently executing.
The pin was registered by _h_config_gpio_as_interrupt.
Postcondition
The pin raises no further callbacks.
The row the pin occupied is free for reuse.
Note
Not thread-safe.
Since
0.1.0

Definition at line 538 of file ra8_esp_hosted_gpio.c.

References internal_irq_find(), k_ra8_esp_hosted_gpio_row_max, k_ra8_ok, k_ra8_pin_none, pin, priv_ra8_esp_hosted_gpio_decode_pin(), priv_ra8_esp_hosted_gpio_edge_unregister(), ra8_gpio_detach_irq(), RET_FAIL, RET_INVALID, RET_OK, and s_irq_rows.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_wakeup_reason()

int internal_wakeup_reason ( void )
static

_h_get_host_wakeup_or_reboot_reason: why the host last started.

Reads the real latched reset cause through ra8_reset_get_cause, which decodes RSTSR0/1/2/3, and folds it onto the three answers the vendored power-save driver understands. Only a Deep Software Standby exit counts as "woke from power save"; every other latched cause is an ordinary reboot, and a failed read is reported as undefined rather than guessed.

Returns
int One of the vendored HOSTED_WAKEUP_* values.
Return values
HOSTED_WAKEUP_DEEP_SLEEPThe part exited Deep Software Standby.
HOSTED_WAKEUP_NORMAL_REBOOTAny other latched reset cause.
HOSTED_WAKEUP_UNDEFINEDThe cause could not be read.
Precondition
The SYSC block is mapped (always true on target and under the host fake mapping).
The reset flags have not been cleared since boot by another module.
Postcondition
No register is modified; the flags stay latched for other readers.
Exactly one of the three vendored values is returned.
Note
Safe from any context; a read-only register decode.
Since
0.1.0

Definition at line 764 of file ra8_esp_hosted_gpio.c.

References k_ra8_ok, k_ra8_reset_cause_deep_sw_standby, k_ra8_reset_cause_unknown, and ra8_reset_get_cause().

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ internal_write_gpio()

int internal_write_gpio ( void * gpio_port,
uint32_t gpio_num,
uint32_t value )
static

_h_write_gpio: drive a side-band output.

Any non-zero value drives the pin high, matching how the vendored driver passes H_RESET_VAL_ACTIVE / H_RESET_VAL_INACTIVE straight through.

Parameters
[in]gpio_portEncoded port index.
[in]gpio_numEncoded pin index, or the unwired sentinel.
[in]valueZero drives low; anything else drives high.
Returns
int Vendored return code.
Return values
RET_OKThe pin holds the requested level.
RET_INVALIDThe pair did not name a pin.
RET_FAILThe pin driver refused the write.
Precondition
The pin was configured as an output.
A pin interface is installed (one always is).
Postcondition
On RET_OK the pin holds value.
On any other code the pin is unchanged.
Note
Not thread-safe with respect to the same pin.
Since
0.1.0

Definition at line 622 of file ra8_esp_hosted_gpio.c.

References ra8_pin_interface_t::ctx, k_ra8_level_high, k_ra8_level_low, k_ra8_ok, k_ra8_pin_none, pin, priv_ra8_esp_hosted_gpio_decode_pin(), priv_ra8_esp_hosted_gpio_pin_interface(), RET_FAIL, RET_INVALID, RET_OK, and ra8_pin_interface_t::write.

Referenced by priv_ra8_esp_hosted_gpio_bind().

◆ priv_ra8_esp_hosted_gpio_bind()

ra8_err_t priv_ra8_esp_hosted_gpio_bind ( hosted_osi_funcs_t * out)
nodiscard

Populate the eight GPIO slots of the OS-abstraction vtable.

Writes _h_config_gpio, _h_config_gpio_as_interrupt, _h_teardown_gpio_interrupt, _h_read_gpio, _h_write_gpio, _h_pull_gpio, _h_hold_gpio and _h_get_host_wakeup_or_reboot_reason into out. No other slot is touched, so the RTOS and transport slices may fill theirs before or after this call in any order.

Parameters
[out]outVtable to populate; must be non-null. Only the eight GPIO rows are written.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe eight rows are populated.
k_ra8_err_null_ptrout was null.
Precondition
out points at storage that out-lives the vendored core.
The pin map in ra8_esp_hosted_pins.h describes the live harness.
Postcondition
The eight GPIO rows of out are non-null.
No non-GPIO row of out is modified.
Note
Not thread-safe; call once from the port's bring-up path.
Warning
Binding does not claim a pin. Pins are claimed lazily by the slots, which is what lets a failed bring-up leave none stranded.
Example:
ra8_err_t priv_ra8_esp_hosted_gpio_bind(hosted_osi_funcs_t *out)
Populate the eight GPIO slots of the OS-abstraction vtable.
hosted_osi_funcs_t g_hosted_osi_funcs
The OS-abstraction vtable the vendored core calls through.
See also
priv_ra8_esp_hosted_spi_bind
Since
0.1.0

Definition at line 776 of file ra8_esp_hosted_gpio.c.

References internal_config_gpio(), internal_config_gpio_as_interrupt(), internal_hold_gpio(), internal_pull_gpio(), internal_read_gpio(), internal_teardown_gpio_interrupt(), internal_wakeup_reason(), internal_write_gpio(), k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_PRIV, and s_tag.

Referenced by priv_ra8_esp_hosted_osi_bind_all().

◆ priv_ra8_esp_hosted_gpio_decode_pin()

bool priv_ra8_esp_hosted_gpio_decode_pin ( const void * gpio_port,
uint32_t gpio_num,
ra8_port_pin_t * out_pin )
nodiscard

Decode the vendored (void* port, uint32_t pin) pair into a pin.

Exact inverse of RA8_ESP_HOSTED_GPIO_PORT / RA8_ESP_HOSTED_GPIO_PIN in port_esp_hosted_host_config.h: the port half is an index carried inside a pointer, so port 0 arrives as a null pointer and must NOT be null-checked – the decoded index is range-checked instead. The pin half arrives as uint32_t, so the vendored -1 "not wired" spelling arrives as 0xFFFFFFFF; that value is rejected explicitly rather than only by the range test, because it is a distinct fact about the harness.

Parameters
[in]gpio_portPort index in pointer clothing. Never dereferenced.
[in]gpio_numPin index within the port, or 0xFFFFFFFF for a signal this harness does not wire.
[out]out_pinReceives the packed RA8_PIN(port, pin) value. Untouched on any rejection.
Returns
Whether the pair named a legal RA8 pin.
Return values
true*out_pin holds the packed pin.
falseout_pin was null, the signal is unwired, or an index was out of range.
Precondition
out_pin is writable when non-null.
gpio_port was produced by RA8_ESP_HOSTED_GPIO_PORT.
Postcondition
On false no output is written.
On true the decoded port is <= k_ra8_port_max and the decoded pin is <= k_ra8_pin_max.
Note
Pure function; safe from interrupt context.
MC/DC:
Decision: (gpio_num == unwired) || (port_idx > port_max) || (gpio_num > pin_max) (3 conditions). Vectors: (F,F,F) accepts; (T,F,F), (F,T,F) and (F,F,T) each reject. Pairing the accepting vector with each rejecting one proves that condition's independent influence: N+1 = 4 vectors.
Example:
(uint32_t)H_GPIO_DATA_READY_Pin, &pin)) {
(void)ra8_gpio_read(pin, &level);
}
#define H_GPIO_DATA_READY_Port
Opaque port handle of the DATA_READY input.
#define H_GPIO_DATA_READY_Pin
Pin index of the DATA_READY input, or -1 when it is not wired.
bool priv_ra8_esp_hosted_gpio_decode_pin(const void *gpio_port, uint32_t gpio_num, ra8_port_pin_t *out_pin)
Decode the vendored (void* port, uint32_t pin) pair into a pin.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
@ k_ra8_pin_none
Sentinel: no pin selected.
ra8_err_t ra8_gpio_read(ra8_port_pin_t pin, ra8_level_t *out_level)
Read a previously-configured input.
Definition gpio.c:210
See also
priv_ra8_esp_hosted_gpio_bind
Since
0.1.0

Definition at line 212 of file ra8_esp_hosted_gpio.c.

References k_ra8_esp_hosted_gpio_pin_unwired, k_ra8_pin_max, k_ra8_port_max, RA8_PIN, and RA8_PRIV.

Referenced by internal_config_gpio(), internal_config_gpio_as_interrupt(), internal_hold_gpio(), internal_pull_gpio(), internal_read_gpio(), internal_teardown_gpio_interrupt(), and internal_write_gpio().

◆ priv_ra8_esp_hosted_gpio_pin_interface()

const ra8_pin_interface_t * priv_ra8_esp_hosted_gpio_pin_interface ( void )
nodiscard

Report the pin driver currently installed in the slice.

Exists so the edge detector, which lives in its own translation unit, can sample levels through exactly the interface the slots write through. It never returns null: an unset seam reads back as the production instance.

Returns
The installed pin interface.
Return values
non-nullAlways; the production instance when nothing was injected.
Precondition
The slice has been linked against libs/ra8_hal.
The caller does not retain the pointer across a seam swap.
Postcondition
No module state is modified.
The returned interface has non-null read and write rows.
Note
Safe from interrupt context; a single aligned load.
Example:
const ra8_pin_interface_t * priv_ra8_esp_hosted_gpio_pin_interface(void)
Report the pin driver currently installed in the slice.
Vtable for a pin driver.
See also
priv_ra8_esp_hosted_gpio_set_pin_interface
Since
0.1.0

Definition at line 233 of file ra8_esp_hosted_gpio.c.

References g_ra8_gpio_pin_interface, RA8_PRIV, and s_pin_if.

Referenced by internal_config_gpio(), internal_read_gpio(), internal_sample(), and internal_write_gpio().

◆ priv_ra8_esp_hosted_gpio_set_pin_interface()

void priv_ra8_esp_hosted_gpio_set_pin_interface ( const ra8_pin_interface_t * iface)

Replace the pin driver the slice reads and writes levels through.

Dependency-injection seam. Production leaves it at g_ra8_gpio_pin_interface; host tests point it at a recorder so pin levels can be driven without hardware. The interface covers output_init, write, read and toggle only, so input configuration, pin release and interrupt attachment still call the HAL directly – those have no row in ra8_pin_interface_t.

Parameters
[in]ifaceReplacement interface, or null to restore the production instance. Must out-live every later slot call.
Precondition
iface, when non-null, has non-null write and read rows.
No slot call is in flight on another thread.
Postcondition
Later reads and writes go through iface.
Passing null restores the production pin driver.
Note
Not thread-safe; intended for bring-up and for tests.
Warning
Swapping the interface does not re-configure any pin; the rows the previous interface configured stay as they were.
Example:
void priv_ra8_esp_hosted_gpio_set_pin_interface(const ra8_pin_interface_t *iface)
Replace the pin driver the slice reads and writes levels through.
See also
priv_ra8_esp_hosted_gpio_pin_interface
Since
0.1.0

Definition at line 228 of file ra8_esp_hosted_gpio.c.

References RA8_PRIV, and s_pin_if.

Variable Documentation

◆ g_ra8_gpio_pin_interface

const ra8_pin_interface_t g_ra8_gpio_pin_interface
extern

Definition at line 502 of file gpio.c.

◆ s_irq_rows

Pins currently attached to an ICU external-interrupt channel.

Statically sized (NASA Power of 10 Rule 3): the link has at most four side-band nets, so the table can never be outgrown by the vendored driver, and an over-request is refused rather than allocated.

Note
Written only by the interrupt-configuration and teardown slots.
Warning
Read from interrupt context through the trampoline's row pointer; never compact or reorder the table while a channel is attached.
Since
0.1.0

Definition at line 190 of file ra8_esp_hosted_gpio.c.

Referenced by internal_attach_hardware(), internal_irq_alloc(), internal_irq_find(), and internal_teardown_gpio_interrupt().

◆ s_pin_if

const ra8_pin_interface_t* s_pin_if
static

The pin driver every level read and write goes through.

Null means "use the production instance", which keeps the seam usable before any initialisation has run.

Note
Swapped only by priv_ra8_esp_hosted_gpio_set_pin_interface.
Warning
Pointing this at a short-lived object leaves the slice reading a dangling vtable.
Since
0.1.0

Definition at line 202 of file ra8_esp_hosted_gpio.c.

Referenced by internal_pin_if(), priv_ra8_esp_hosted_gpio_pin_interface(), priv_ra8_esp_hosted_gpio_set_pin_interface(), and priv_ra8_esp_hosted_spi_set_pin_interface().

◆ s_tag

const char* const s_tag = "eh_gpio"
static

Log tag identifying lines emitted by the side-band GPIO slice.

Short enough to keep a log line readable next to the transport's own spi tag, and distinct from every other tag in this port.

Note
Read-only after load.
Warning
Changing it breaks log filters that key on the string.
Since
0.1.0

Definition at line 55 of file ra8_esp_hosted_gpio.c.