|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
The three transport slots of the esp-hosted OS-abstraction vtable. More...
#include <stdint.h>#include "port_esp_hosted_host_os.h"#include "port_esp_hosted_host_spi.h"#include "ra8_attributes.h"#include "ra8_board_ek_ra8d2_connectors.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_esp_hosted_pins.h"#include "ra8_esp_hosted_spi_internal.h"#include "ra8_gpio_constants.h"#include "ra8_io_spi_bus.h"#include "ra8_io_spi_bus_sci_spi.h"#include "ra8_log.h"#include "ra8_pin_interface.h"#include "ra8_port_constants.h"#include "ra8_port_utils.h"#include "ra8_sci_spi.h"#include "ra8_spi.h"#include "transport_drv.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_esp_hosted_spi_frame_t : uint16_t { k_ra8_esp_hosted_spi_frame_bytes = (uint16_t)MAX_TRANSPORT_BUFFER_SIZE } |
| The frame bound this port supplies, as a named constant. More... | |
Functions | |
| static const ra8_pin_interface_t * | internal_pin_if (void) |
| Report the pin driver the chip select is driven through. | |
| static const ra8_io_spi_bus_t * | internal_bus (void) |
| Report the bus the transfer slot should clock through. | |
| static ra8_err_t | internal_route_data_pins (void) |
| Route the three Pmod1 SPI data pins to the SCI peripheral. | |
| static void | internal_release_pins (void) |
| Hand every pin the transport claimed back to the pin validator. | |
| ra8_err_t | priv_ra8_esp_hosted_spi_open (uint8_t sci_channel, uint32_t pclk_hz, uint32_t sck_hz) |
| Route the Pmod1 SPI pins and open the SCI Simple-SPI channel. | |
| ra8_err_t | priv_ra8_esp_hosted_spi_close (void) |
| Close the SCI Simple-SPI channel and release every pin it took. | |
| bool | priv_ra8_esp_hosted_spi_is_open (void) |
| Report whether the SCI Simple-SPI channel is currently open. | |
| void | priv_ra8_esp_hosted_spi_set_bus (const ra8_io_spi_bus_t *bus) |
| Replace the SPI bus the transfer slot clocks frames through. | |
| void | priv_ra8_esp_hosted_spi_set_pin_interface (const ra8_pin_interface_t *iface) |
| Replace the pin driver the transfer slot drives chip select with. | |
| static void * | internal_bus_init (void) |
| _h_bus_init: hand the vendored transport its opaque bus handle. | |
| static int | internal_bus_deinit (void *bus_handle) |
| _h_bus_deinit: close the channel behind an opaque bus handle. | |
| static int | internal_do_bus_transfer (void *transfer_context) |
| _h_do_bus_transfer: clock one full-duplex esp-hosted frame. | |
| ra8_err_t | priv_ra8_esp_hosted_spi_bind (hosted_osi_funcs_t *out) |
| Populate the three transport slots of the OS-abstraction vtable. | |
Variables | |
| static const char *const | s_tag = "eh_spi" |
| Log tag identifying lines emitted by the SPI transport slice. | |
| static ra8_io_spi_bus_t | s_bus |
| Bus handle bound to the SCI Simple-SPI channel by the open. | |
| static const ra8_io_spi_bus_t * | s_injected_bus |
| Test-injected replacement for s_bus, or null in production. | |
| static const ra8_pin_interface_t * | s_pin_if |
| Pin driver the chip select is configured and driven through. | |
| static uint8_t | s_channel |
| SCI channel the open brought up, meaningful only while s_open. | |
| static bool | s_open |
| True between a successful open and its matching close. | |
| const ra8_pin_interface_t | g_ra8_gpio_pin_interface |
The three transport slots of the esp-hosted OS-abstraction vtable.
One esp-hosted transaction is one 1600-byte full-duplex SPI frame: the host clocks a transmit buffer out while the co-processor clocks its own frame back, and both directions complete or neither does. That is exactly the shape of ra8_io_spi_bus_write_read, so the transfer slot is a single call to it wrapped in chip-select sequencing.
Definition in file ra8_esp_hosted_spi.c.
| enum ra8_esp_hosted_spi_frame_t : uint16_t |
The frame bound this port supplies, as a named constant.
MAX_TRANSPORT_BUFFER_SIZE is whichever value transport_drv.h picked up from the port header its transport-selection chain chose. Binding it to an enumerator here gives the assertion below a symbol to compare against the constant the vendored SPI driver actually clocks, instead of comparing one spelling of a macro with another spelling of the same macro.
| Enumerator | |
|---|---|
| k_ra8_esp_hosted_spi_frame_bytes | Bytes clocked in one full-duplex transaction, from the port header. |
Definition at line 96 of file ra8_esp_hosted_spi.c.
|
static |
Report the bus the transfer slot should clock through.
An injected bus wins over the internally bound one, so a test can drive the transfer path with no channel open. When neither is available the result is null and the caller reports failure rather than clocking a dead channel.
| non-null | A backend vtable is bound into the returned handle. |
| nullptr | Nothing is injected and no open has bound a backend. |
Definition at line 232 of file ra8_esp_hosted_spi.c.
References s_bus, and s_injected_bus.
Referenced by internal_bus_init(), and internal_do_bus_transfer().
|
static |
_h_bus_deinit: close the channel behind an opaque bus handle.
Accepts only the handle _h_bus_init produced, so a stray pointer cannot tear the transport down. A close on an already-closed bus reports failure rather than success, which is what lets the port's own teardown tell "I closed it" from "it was already gone".
| [in] | bus_handle | The handle _h_bus_init returned. |
| RET_OK | The channel was closed and its pins released. |
| RET_INVALID | bus_handle was null or not ours. |
| RET_FAIL | The bus was not open, or the HAL refused. |
Definition at line 446 of file ra8_esp_hosted_spi.c.
References k_ra8_ok, priv_ra8_esp_hosted_spi_close(), RET_FAIL, RET_INVALID, RET_OK, and s_bus.
Referenced by priv_ra8_esp_hosted_spi_bind().
|
static |
_h_bus_init: hand the vendored transport its opaque bus handle.
The channel itself is opened by the port's bring-up, not here: the vendored driver has no clocking configuration to give and simply asserts that the handle is non-null. Reporting null when no bus is usable is therefore the honest answer – it makes the transport refuse to start rather than clock a channel that was never enabled.
| non-null | A bus is bound and transfers can proceed. |
| nullptr | No open has run and nothing was injected. |
Definition at line 411 of file ra8_esp_hosted_spi.c.
References internal_bus(), ra8_log_warn, s_bus, and s_tag.
Referenced by priv_ra8_esp_hosted_spi_bind().
|
static |
_h_do_bus_transfer: clock one full-duplex esp-hosted frame.
Validates the context and both buffers, asserts the chip select, exchanges the caller's frame in a single full-duplex transfer, deasserts the chip select and reports what the bus did. The transmit size is the caller's – the vendored driver sets it to MAX_SPI_BUFFER_SIZE – but it is bounded against MAX_TRANSPORT_BUFFER_SIZE here as well, because the receive buffer is only ever that large and a longer transfer would overrun it.
The chip select is deasserted on every path that asserted it, including the failure path, so a bus error cannot leave the co-processor selected.
| [in,out] | transfer_context | A struct hosted_transport_context_t with both buffers set and tx_buf_size in bytes. |
| RET_OK | The frame was exchanged; rx_buf holds the reply. |
| RET_INVALID | Null context, a null buffer, or a size of zero or more than one frame. |
| RET_FAIL | No bus is bound, the chip select would not move, or the bus reported an error. |
Definition at line 492 of file ra8_esp_hosted_spi.c.
References ra8_pin_interface_t::ctx, internal_bus(), internal_pin_if(), k_ra8_esp_hosted_pin_chip_select, k_ra8_level_high, k_ra8_level_low, k_ra8_ok, k_ra8_spi_width_8, MAX_TRANSPORT_BUFFER_SIZE, ra8_io_spi_bus_write_read(), ra8_log_error_val, RET_FAIL, RET_INVALID, RET_OK, s_tag, and ra8_pin_interface_t::write.
Referenced by priv_ra8_esp_hosted_spi_bind().
|
static |
Report the pin driver the chip select is driven through.
Folds the "nothing injected" case onto the production instance so every caller can use the result without a null test.
| non-null | Always. |
Definition at line 205 of file ra8_esp_hosted_spi.c.
References g_ra8_gpio_pin_interface, and s_pin_if.
Referenced by internal_do_bus_transfer(), and priv_ra8_esp_hosted_spi_open().
|
static |
Hand every pin the transport claimed back to the pin validator.
Used both by the failure unwind inside the open and by the close, so the two cannot disagree about which pins the transport owns. Release failures are ignored on purpose: a pin that was never claimed is exactly the case the unwind has to tolerate.
Definition at line 303 of file ra8_esp_hosted_spi.c.
References k_ra8_board_pmod1_spi_cipo, k_ra8_board_pmod1_spi_copi, k_ra8_board_pmod1_spi_sck, k_ra8_esp_hosted_pin_chip_select, and ra8_gpio_release().
Referenced by priv_ra8_esp_hosted_spi_close(), and priv_ra8_esp_hosted_spi_open().
|
static |
Route the three Pmod1 SPI data pins to the SCI peripheral.
The chip select is deliberately not routed here: esp-hosted needs it driven by software for the whole frame, so it stays a GPIO output. The three data pins take the SCI peripheral function, which the Simple-SPI mode of the SCI shares with its asynchronous mode.
| k_ra8_ok | All three pins are routed. |
| k_ra8_err_gpio_conflict | A pin is owned by another module. |
| k_ra8_err_hw_unmapped | The PFS window for a pin is not mapped. |
Definition at line 264 of file ra8_esp_hosted_spi.c.
References k_ra8_board_pmod1_spi_cipo, k_ra8_board_pmod1_spi_copi, k_ra8_board_pmod1_spi_sck, k_ra8_ok, k_ra8_psel_sci_async, and ra8_pfs_route_peripheral().
Referenced by priv_ra8_esp_hosted_spi_open().
|
nodiscard |
Populate the three transport slots of the OS-abstraction vtable.
Writes _h_bus_init, _h_bus_deinit and _h_do_bus_transfer into out and touches nothing else, so the GPIO and RTOS slices may fill theirs in any order relative to this call.
| [out] | out | Vtable to populate; must be non-null. |
| k_ra8_ok | The three rows are populated. |
| k_ra8_err_null_ptr | out was null. |
out points at storage that out-lives the vendored core. out are non-null. out is modified.Definition at line 524 of file ra8_esp_hosted_spi.c.
References internal_bus_deinit(), internal_bus_init(), internal_do_bus_transfer(), 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().
|
nodiscard |
Close the SCI Simple-SPI channel and release every pin it took.
Exact reverse of priv_ra8_esp_hosted_spi_open: the channel is disabled and its module-stop gate released, then the chip select and the three routed data pins are handed back to the pin validator. The bound bus handle is cleared so a later transfer attempt fails rather than driving a dead channel.
| k_ra8_ok | Everything was released. |
| k_ra8_err_not_initialized | The bus was not open. |
| k_ra8_err_spi_error | The HAL refused to disable the channel. |
Definition at line 360 of file ra8_esp_hosted_spi.c.
References internal_release_pins(), k_ra8_err_not_initialized, k_ra8_err_spi_error, k_ra8_ok, RA8_PRIV, ra8_sci_spi_deinit(), s_bus, s_channel, and s_open.
Referenced by internal_bus_deinit(), and internal_unwind().
|
nodiscard |
Report whether the SCI Simple-SPI channel is currently open.
Reads the single module-state flag, so the port can decide whether a close is needed and tests can assert the open/close state machine without reaching into the module.
| true | The channel is open and bound. |
| false | The channel was never opened, failed to open, or was closed. |
Definition at line 372 of file ra8_esp_hosted_spi.c.
|
nodiscard |
Route the Pmod1 SPI pins and open the SCI Simple-SPI channel.
Performs, in order: route SCK, COPI and CIPO to the SCI peripheral through the PFS; take the chip select as a GPIO output idling high (deasserted); bring the SCI channel up at mode 3, MSB first, at the requested bit rate; and bind the channel into the ra8_io SPI-bus facade so the transfer slot can drive it. Any failure unwinds the steps already taken, so a failed open leaves no pin claimed.
The channel argument must name the Pmod1 Simple-SPI channel. The port routes the Pmod1 pin trio and nothing else, so accepting a different channel would clock a peripheral whose pins were never routed.
| [in] | sci_channel | SCI channel carrying Simple-SPI; must equal the board's Pmod1 channel. |
| [in] | pclk_hz | Live PCLKA rate in hertz; non-zero. |
| [in] | sck_hz | Requested bit rate in hertz; non-zero. |
| k_ra8_ok | The bus is open and bound. |
| k_ra8_err_invalid_arg | A clock was zero, or the channel is not the Pmod1 one. |
| k_ra8_err_invalid_state | The bus is already open. |
| k_ra8_err_gpio_conflict | A link pin is owned by another module. |
| k_ra8_err_spi_error | The SCI channel would not come up. |
pclk_hz reflects the live PCLKA rate. Definition at line 311 of file ra8_esp_hosted_spi.c.
References ra8_pin_interface_t::ctx, internal_pin_if(), internal_release_pins(), internal_route_data_pins(), k_ra8_board_pmod1_sci_channel, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_spi_error, k_ra8_esp_hosted_pin_chip_select, k_ra8_esp_hosted_spi_mode, k_ra8_level_high, k_ra8_ok, ra8_pin_interface_t::output_init, ra8_io_spi_bus_bind_sci_spi(), ra8_log_error_val, ra8_log_info_val, RA8_PRIV, ra8_sci_spi_deinit(), ra8_sci_spi_init(), s_bus, s_channel, s_open, and s_tag.
Referenced by internal_bring_up().
| void priv_ra8_esp_hosted_spi_set_bus | ( | const ra8_io_spi_bus_t * | bus | ) |
Replace the SPI bus the transfer slot clocks frames through.
Dependency-injection seam. Production leaves it unset, in which case the slot uses the handle priv_ra8_esp_hosted_spi_open bound to the SCI channel. Host tests point it at a recording ra8_io_spi_bus_iface so the whole transfer path – argument validation, chip-select sequencing, error propagation – runs with no silicon and no open channel.
| [in] | bus | Replacement bus handle, or null to fall back on the handle the open bound. Must out-live every later transfer. |
bus, when non-null, has a bound backend vtable. bus. Definition at line 377 of file ra8_esp_hosted_spi.c.
References RA8_PRIV, and s_injected_bus.
| void priv_ra8_esp_hosted_spi_set_pin_interface | ( | const ra8_pin_interface_t * | iface | ) |
Replace the pin driver the transfer slot drives chip select with.
Dependency-injection seam, separate from the GPIO slice's own seam because the two translation units are independent. Production leaves it at g_ra8_gpio_pin_interface; tests point it at a recorder so the order of "chip select low, frame, chip select high" can be asserted rather than assumed.
| [in] | iface | Replacement interface, or null to restore the production instance. Must out-live every later transfer. |
iface, when non-null, has non-null output_init and write rows. iface. Definition at line 382 of file ra8_esp_hosted_spi.c.
|
extern |
Definition at line 502 of file gpio.c.
Referenced by internal_pin_if(), and priv_ra8_esp_hosted_gpio_pin_interface().
|
static |
Bus handle bound to the SCI Simple-SPI channel by the open.
Caller-allocated by contract of ra8_io_spi_bus_t, so the storage lives here for the lifetime of the image; iface is null until an open binds a backend into it.
Definition at line 127 of file ra8_esp_hosted_spi.c.
Referenced by internal_bus(), internal_bus_deinit(), internal_bus_init(), priv_ra8_esp_hosted_spi_close(), and priv_ra8_esp_hosted_spi_open().
|
static |
SCI channel the open brought up, meaningful only while s_open.
Remembered so the close can disable exactly the channel that was enabled, without the caller having to repeat it.
Definition at line 162 of file ra8_esp_hosted_spi.c.
Referenced by priv_ra8_esp_hosted_spi_close(), and priv_ra8_esp_hosted_spi_open().
|
static |
Test-injected replacement for s_bus, or null in production.
Kept separate from s_bus so an injection survives an open and an open does not clobber an injection.
Definition at line 139 of file ra8_esp_hosted_spi.c.
Referenced by internal_bus(), and priv_ra8_esp_hosted_spi_set_bus().
|
static |
True between a successful open and its matching close.
The single piece of state the open/close pair maintains; the transfer slot deliberately does not consult it, because an injected bus makes a transfer meaningful with no channel open at all.
Definition at line 175 of file ra8_esp_hosted_spi.c.
Referenced by internal_handle_init(), internal_rx_acceptable(), internal_rx_worker_entry(), internal_send_blocked(), nx_ether_driver_c6(), priv_ra8_esp_hosted_spi_close(), priv_ra8_esp_hosted_spi_is_open(), and priv_ra8_esp_hosted_spi_open().
|
static |
Pin driver the chip select is configured and driven through.
Null means "use the production instance", which keeps the seam usable before any initialisation has run.
Definition at line 151 of file ra8_esp_hosted_spi.c.
|
static |
Log tag identifying lines emitted by the SPI transport slice.
Distinct from the vendored driver's own spi tag so a reader can tell a port-side refusal from a transport-side one.
Definition at line 71 of file ra8_esp_hosted_spi.c.