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

ra8_io I2C-bus facade – one controller-transfer vtable over thechip's two I2C implementations. More...

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

Go to the source code of this file.

Data Structures

struct  ra8_io_i2c_bus_t
 Caller-allocated I2C-bus handle binding a backend to its context. More...

Typedefs

typedef struct ra8_io_i2c_bus_iface ra8_io_i2c_bus_iface_t

Functions

ra8_err_t ra8_io_i2c_bus_write (const ra8_io_i2c_bus_t *bus, uint8_t addr, const uint8_t *data, uint32_t len, bool send_stop)
 Controller write of len bytes to 7-bit address addr.
ra8_err_t ra8_io_i2c_bus_read (const ra8_io_i2c_bus_t *bus, uint8_t addr, uint8_t *data, uint32_t len)
 Controller read of len bytes from 7-bit address addr.
ra8_err_t ra8_io_i2c_bus_transfer (const ra8_io_i2c_bus_t *bus, uint8_t addr, const uint8_t *wr, uint32_t wr_len, uint8_t *rd, uint32_t rd_len)
 Combined write-then-RESTART-then-read in one bus transaction.
ra8_err_t ra8_io_i2c_bus_as_ops (const ra8_io_i2c_bus_t *bus, ra8_i2c_bus_ops_t *out)
 Expose a bound bus through the Ring-3 seam ra8_i2c_bus_ops_t.

Detailed Description

ra8_io I2C-bus facade – one controller-transfer vtable over the

chip's two I2C implementations.

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

The RA8D2 implements I2C twice: the classic RIIC block (ra8_i2c.h, three channels) and the I3C block's I2C-compatibility mode (ra8_i3c.h, one channel). Their controller transfer surfaces are byte-for-byte identical, but every consumer used to hard-wire one side by function name. This facade gives callers one handle-based surface so the physical peripheral a board revision routes to a device is a bind-time decision, not a call-site rewrite.

Modeled directly on the ra8_io_blockdev_t pattern: the handle (ra8_io_i2c_bus_t) is caller-allocated; a backend _bind_*() helper (see ra8_io_i2c_bus_riic.h and ra8_io_i2c_bus_i3c_compat.h) fills the opaque vtable with thin trampolines to the existing ra8_i2c_* / ra8_i3c_* drivers, unmodified. No dynamic allocation occurs and no MMIO happens here – the wrapped drivers carry every HUM citation.

Bus bring-up (peripheral init, bit-rate) stays with the caller. This facade is deliberately separate from ra8_io_spi_bus.h: I2C carries an in-band 7-bit address and is half-duplex request/response, while SPI has out-of-band chip select and is simultaneous full-duplex – one merged shape would ignore a parameter or grow capability checks.

Boundary with Ring-3 device drivers

A Ring-3 device driver (e.g. ra8_touch, ra8_smbus) must not depend on this Ring-4 facade – that would invert ring ordering (see docs/RING_AND_WORLD.md). The sanctioned bridge is ra8_io_i2c_bus_as_ops, which exposes a bound bus through the Ring-3 seam ra8_i2c_bus_ops_t (ra8_i2c_bus_ops.h), mirroring ra8_io_blockdev_as_fs_backend().

Example:
(void)ra8_io_i2c_bus_bind_i3c_compat(&bus, 0U); // today's board
// (void)ra8_io_i2c_bus_bind_riic(&bus, 1U); // future board revision
uint8_t reg_ptr[2] = {0x81U, 0x40U};
uint8_t status = 0U;
(void)ra8_io_i2c_bus_transfer(&bus, 0x5DU, reg_ptr, 2U, &status, 1U);
ra8_err_t ra8_io_i2c_bus_transfer(const ra8_io_i2c_bus_t *bus, uint8_t addr, const uint8_t *wr, uint32_t wr_len, uint8_t *rd, uint32_t rd_len)
Combined write-then-RESTART-then-read in one bus transaction.
ra8_err_t ra8_io_i2c_bus_bind_i3c_compat(ra8_io_i2c_bus_t *bus, uint8_t channel)
Bind bus to I3C channel channel in I2C-compatibility mode.
Caller-allocated I2C-bus handle binding a backend to its context.
Since
0.1.0

Definition in file ra8_io_i2c_bus.h.

Typedef Documentation

◆ ra8_io_i2c_bus_iface_t

Definition at line 84 of file ra8_io_i2c_bus.h.

Function Documentation

◆ ra8_io_i2c_bus_as_ops()

ra8_err_t ra8_io_i2c_bus_as_ops ( const ra8_io_i2c_bus_t * bus,
ra8_i2c_bus_ops_t * out )
nodiscard

Expose a bound bus through the Ring-3 seam ra8_i2c_bus_ops_t.

Fills out with trampolines that forward the seam's write / read / transfer into this facade, with out->ctx pointing at bus. This is the sanctioned bridge for handing a bound bus to a Ring-3 device driver (e.g. ra8_touch, ra8_smbus) without the driver depending upward on ra8_io – the exact analogue of ra8_io_blockdev_as_fs_backend().

Parameters
[in]busBound bus handle (must out-live every seam call).
[out]outSeam to populate.
Returns
ra8_err_t Error code.
Return values
k_ra8_ok*out wired to bus.
k_ra8_err_null_ptrbus or out was NULL.
k_ra8_err_not_initializedNo backend is bound to bus.
Precondition
A backend has been bound into bus.
out is writable and out-lives no call made through it after bus is destroyed.
Postcondition
On success all three seam rows are non-NULL and out->ctx references bus.
No bus or handle state is mutated.
Note
bus must remain valid for the entire lifetime of the seam.
See also
ra8_i2c_bus_ops_t The Ring-3 seam definition.
Since
0.1.0

Definition at line 231 of file ra8_io_i2c_bus.c.

References ra8_i2c_bus_ops_t::ctx, internal_ops_read(), internal_ops_transfer(), internal_ops_write(), internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_i2c_bus_ops_t::read, s_tag, ra8_i2c_bus_ops_t::transfer, and ra8_i2c_bus_ops_t::write.

Referenced by main(), and ra8_board_touch_open().

◆ ra8_io_i2c_bus_read()

ra8_err_t ra8_io_i2c_bus_read ( const ra8_io_i2c_bus_t * bus,
uint8_t addr,
uint8_t * data,
uint32_t len )
nodiscard

Controller read of len bytes from 7-bit address addr.

Forwards to the bound backend's read primitive (ra8_i2c_read or ra8_i3c_read). Issues START, the address byte with R/W# = 1, drains len bytes, then issues STOP and releases the bus.

Parameters
[in]busBound bus handle.
[out]dataDestination buffer (non-NULL).
[in]addr7-bit peripheral address.
[in]lenByte count (non-zero).
Returns
ra8_err_t Error code.
Return values
k_ra8_okBytes received.
k_ra8_err_null_ptrbus or data was NULL.
k_ra8_err_not_initializedNo backend is bound to bus.
k_ra8_err_invalid_arglen is zero.
k_ra8_err_nackPeripheral did not acknowledge.
k_ra8_err_hw_timeoutBus stalled.
Precondition
A backend has been bound into bus.
The underlying channel was initialised by its own driver init.
Postcondition
On success data[0 .. len) holds the received bytes.
STOP was issued and the bus released (success or failure).
Note
Not thread-safe with respect to the same channel.
See also
ra8_io_i2c_bus_write Controller-write counterpart.
Since
0.1.0

Definition at line 93 of file ra8_io_i2c_bus.c.

References ra8_io_i2c_bus_t::ctx, ra8_io_i2c_bus_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_io_i2c_bus_iface::read, and s_tag.

Referenced by internal_ops_read().

◆ ra8_io_i2c_bus_transfer()

ra8_err_t ra8_io_i2c_bus_transfer ( const ra8_io_i2c_bus_t * bus,
uint8_t addr,
const uint8_t * wr,
uint32_t wr_len,
uint8_t * rd,
uint32_t rd_len )
nodiscard

Combined write-then-RESTART-then-read in one bus transaction.

Forwards to the bound backend's combined primitive (ra8_i2c_transfer or ra8_i3c_transfer) – the classic "address a register, read its contents" shape: write wr_len bytes, repeated START, read rd_len bytes, STOP.

Parameters
[in]busBound bus handle.
[in]addr7-bit peripheral address.
[in]wrBytes to send first (NULL only when wr_len 0).
[in]wr_lenNumber of bytes to send.
[out]rdDestination buffer (NULL only when rd_len 0).
[in]rd_lenNumber of bytes to read.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBoth phases completed; STOP issued.
k_ra8_err_null_ptrbus was NULL, or a required buffer was NULL.
k_ra8_err_not_initializedNo backend is bound to bus.
k_ra8_err_invalid_argBoth lengths zero.
k_ra8_err_nackPeripheral did not acknowledge.
k_ra8_err_hw_timeoutBus stalled.
Precondition
A backend has been bound into bus.
The underlying channel was initialised by its own driver init.
Postcondition
On success both phases completed and STOP was issued.
On failure the bus is released where the transport allows.
Note
Not thread-safe with respect to the same channel.
Since
0.1.0

Definition at line 103 of file ra8_io_i2c_bus.c.

References ra8_io_i2c_bus_t::ctx, ra8_io_i2c_bus_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_io_i2c_bus_iface::transfer.

Referenced by iic_facade_controller_phase(), and internal_ops_transfer().

◆ ra8_io_i2c_bus_write()

ra8_err_t ra8_io_i2c_bus_write ( const ra8_io_i2c_bus_t * bus,
uint8_t addr,
const uint8_t * data,
uint32_t len,
bool send_stop )
nodiscard

Controller write of len bytes to 7-bit address addr.

Forwards to the bound backend's write primitive (ra8_i2c_write or ra8_i3c_write; the I3C driver's inverted restart flag is adapted by the backend). When send_stop is true the transaction ends with STOP; when false the bus is held so the next call injects a repeated-START.

Parameters
[in]busBound bus handle.
[in]addr7-bit peripheral address.
[in]dataBytes to send (non-NULL when len > 0).
[in]lenByte count.
[in]send_stoptrue = STOP after the payload; false = hold the bus.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPayload transmitted.
k_ra8_err_null_ptrbus was NULL, or data NULL with len > 0.
k_ra8_err_not_initializedNo backend is bound to bus.
k_ra8_err_nackPeripheral did not acknowledge.
k_ra8_err_hw_timeoutBus stalled.
Precondition
A backend has been bound into bus.
The underlying channel was initialised by its own driver init.
Postcondition
On success the payload has been transmitted per send_stop.
On failure the bus is released where the transport allows.
Note
Not thread-safe with respect to the same channel.
See also
ra8_io_i2c_bus_transfer Write-then-read in one transaction.
Since
0.1.0

Definition at line 78 of file ra8_io_i2c_bus.c.

References ra8_io_i2c_bus_t::ctx, ra8_io_i2c_bus_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_io_i2c_bus_iface::write.

Referenced by internal_ops_write().