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

IIC_B (I3C unified IP, I2C-only mode) controller driver. More...

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

Go to the source code of this file.

Data Structures

struct  ra8_i3c_i2c_cfg_t
 Configuration descriptor for ra8_i3c_i2c_init. More...

Typedefs

typedef void(* ra8_i3c_i2c_complete_fn_t) (void *ctx, uint8_t err_mask)
 Transfer-complete / error callback signature.

Enumerations

enum  ra8_i3c_i2c_speed_t : uint32_t {
  k_ra8_i3c_i2c_speed_standard = 100000U ,
  k_ra8_i3c_i2c_speed_fast = 400000U ,
  k_ra8_i3c_i2c_speed_fast_plus = 1000000U
}
 Supported bus speeds (I2C compatibility mode). More...
enum  ra8_i3c_i2c_err_mask_t : uint8_t {
  k_ra8_i3c_i2c_err_none = 0x00U ,
  k_ra8_i3c_i2c_err_arb_lost = 0x01U ,
  k_ra8_i3c_i2c_err_nack = 0x02U ,
  k_ra8_i3c_i2c_err_timeout = 0x04U
}
 Error-mask bits returned by ra8_i3c_i2c_get_errors. More...

Functions

ra8_err_t ra8_i3c_i2c_init (uint8_t channel, const ra8_i3c_i2c_cfg_t *cfg)
 Initialise the IIC_B channel and bring the bus up.
ra8_err_t ra8_i3c_i2c_deinit (uint8_t channel)
 Tear down the IIC_B channel.
ra8_err_t ra8_i3c_i2c_set_clock (uint8_t channel, uint32_t bus_hz, uint32_t pclka_hz)
 Update the bus clock without tearing the channel down.
ra8_err_t ra8_i3c_i2c_write (uint8_t channel, uint8_t target_7b, const uint8_t *data, uint32_t len, bool restart)
 Polling write of len bytes to a 7-bit target address.
ra8_err_t ra8_i3c_i2c_read (uint8_t channel, uint8_t target_7b, uint8_t *buf, uint32_t len, bool restart)
 Polling read of len bytes from a 7-bit target.
ra8_err_t ra8_i3c_i2c_transfer (uint8_t channel, uint8_t target_7b, const uint8_t *tx, uint32_t tx_len, uint8_t *rx, uint32_t rx_len)
 Combined write-then-RESTART-then-read in a single bus transaction.
ra8_err_t ra8_i3c_i2c_abort (uint8_t channel)
 Cancel any in-flight transaction and return the channel to idle.
ra8_err_t ra8_i3c_i2c_scan (uint8_t channel, uint8_t target_7b, bool *out_acked)
 Probe whether a 7-bit address ACKs.
ra8_err_t ra8_i3c_i2c_get_errors (uint8_t channel, uint8_t *out_mask)
 Read latched error flags from BST (AL / NACKDF / TODF).
ra8_err_t ra8_i3c_i2c_clear_errors (uint8_t channel)
 Clear latched error flags in BST.
ra8_err_t ra8_i3c_i2c_attach_handler (uint8_t channel, ra8_i3c_i2c_complete_fn_t fn, void *ctx)
 Attach a completion / error callback for the channel.
void ra8_i3c_i2c_dispatch_eri (uint8_t channel)
 Dispatch the bus-error IRQ source.

Detailed Description

IIC_B (I3C unified IP, I2C-only mode) controller driver.

Tag
[Ring 3 / HAL] {World: NS}

Polling-mode controller driver for the RA8D2 I3C peripheral operated in I2C compatibility mode (HUM Ch 40 "I3C Bus Interface (I3C)", p 2445-2701). The peripheral name in FSP and in this codebase is IIC_B – it replaces the legacy IIC block that older RA parts carried.

The public surface mirrors FSP r_iic_b_master minus DTC:

Definition in file ra8_i3c_i2c.h.

Typedef Documentation

◆ ra8_i3c_i2c_complete_fn_t

typedef void(* ra8_i3c_i2c_complete_fn_t) (void *ctx, uint8_t err_mask)

Transfer-complete / error callback signature.

Parameters
[in]ctxCaller-supplied context.
[in]err_maskOR of k_ra8_i3c_i2c_err_* bits; zero on success.

Definition at line 100 of file ra8_i3c_i2c.h.

Enumeration Type Documentation

◆ ra8_i3c_i2c_err_mask_t

enum ra8_i3c_i2c_err_mask_t : uint8_t

Error-mask bits returned by ra8_i3c_i2c_get_errors.

Enumerator
k_ra8_i3c_i2c_err_none 

No latched error.

k_ra8_i3c_i2c_err_arb_lost 

BST.ALF set.

k_ra8_i3c_i2c_err_nack 

BST.NACKDF set.

k_ra8_i3c_i2c_err_timeout 

BST.TODF set.

Definition at line 86 of file ra8_i3c_i2c.h.

◆ ra8_i3c_i2c_speed_t

enum ra8_i3c_i2c_speed_t : uint32_t

Supported bus speeds (I2C compatibility mode).

Per HUM Ch 40.1.1 Table 40.1 "I2C specifications", p 2445.

Enumerator
k_ra8_i3c_i2c_speed_standard 

100 kHz Sm.

k_ra8_i3c_i2c_speed_fast 

400 kHz Fm.

k_ra8_i3c_i2c_speed_fast_plus 

1 MHz Fm+.

Definition at line 62 of file ra8_i3c_i2c.h.

Function Documentation

◆ ra8_i3c_i2c_abort()

ra8_err_t ra8_i3c_i2c_abort ( uint8_t channel)
nodiscard

Cancel any in-flight transaction and return the channel to idle.

Mirrors FSP's R_IIC_B_MASTER_Abort controller abort-sequence helper for the polling driver. Steps:

  1. Mask BIE / NTIE so a pending interrupt cannot fire mid-tear-down.
  2. Issue STOP (unconditional). The hardware will eventually drive SPCNDDF; the polling helpers don't gate on it because no further bus traffic is expected from this channel until the next ra8_i3c_i2c_write / _read clears BST again.
  3. Clear all latched bus-status flags.
Parameters
[in]channelChannel index.
Returns
ra8_err_t.
Return values
k_ra8_okAbort issued.
k_ra8_err_invalid_argChannel out of range.
Precondition
Channel previously initialized.
Postcondition
Channel is idle; BST flags cleared.
Since
0.1.0

Definition at line 99 of file ra8_i3c_i2c_control.c.

References r_i3c_i2c_regs_t::BIE, i3c_i2c_regs(), k_ra8_err_invalid_arg, k_ra8_ok, r_i3c_i2c_regs_t::NTIE, priv_i3c_i2c_clear_bst(), priv_i3c_i2c_stop(), and s_iic_b_state.

Referenced by ra8_i3c_abort().

◆ ra8_i3c_i2c_attach_handler()

ra8_err_t ra8_i3c_i2c_attach_handler ( uint8_t channel,
ra8_i3c_i2c_complete_fn_t fn,
void * ctx )
nodiscard

Attach a completion / error callback for the channel.

Parameters
[in]channelChannel index.
[in]fnCallback fired from the dispatch helpers, or NULL to detach.
[in]ctxContext pointer passed to the callback.
Returns
ra8_err_t.
Return values
k_ra8_okCallback registered.
k_ra8_err_invalid_argChannel out of range.
Precondition
Channel previously initialized.
Postcondition
BIE / NTIE bits track fn non-null status.
Since
0.1.0

Definition at line 201 of file ra8_i3c_i2c_control.c.

References r_i3c_i2c_regs_t::BIE, i3c_i2c_regs(), k_ra8_err_invalid_arg, k_ra8_i3c_i2c_msk_bie_alie, k_ra8_i3c_i2c_msk_bie_nackdie, k_ra8_i3c_i2c_msk_bie_tendie, k_ra8_i3c_i2c_msk_bie_todie, k_ra8_i3c_i2c_msk_ntie_rdbfie0, k_ra8_i3c_i2c_msk_ntie_tdbeie0, k_ra8_ok, r_i3c_i2c_regs_t::NTIE, and s_iic_b_state.

◆ ra8_i3c_i2c_clear_errors()

ra8_err_t ra8_i3c_i2c_clear_errors ( uint8_t channel)
nodiscard

Clear latched error flags in BST.

Parameters
[in]channelChannel index.
Returns
ra8_err_t.
Return values
k_ra8_okError bits W0C cleared.
k_ra8_err_invalid_argChannel out of range.
Since
0.1.0

< RA8 I3C I2C error clear mask.

Definition at line 181 of file ra8_i3c_i2c_control.c.

References r_i3c_i2c_regs_t::BST, i3c_i2c_regs(), k_ra8_err_invalid_arg, k_ra8_i3c_i2c_msk_bst_alf, k_ra8_i3c_i2c_msk_bst_nackdf, k_ra8_i3c_i2c_msk_bst_todf, and k_ra8_ok.

Referenced by ra8_i3c_clear_errors(), ra8_i3c_dispatch(), and ra8_i3c_i2c_dispatch_eri().

◆ ra8_i3c_i2c_deinit()

ra8_err_t ra8_i3c_i2c_deinit ( uint8_t channel)
nodiscard

Tear down the IIC_B channel.

Parameters
[in]channelChannel index.
Returns
ra8_err_t.
Return values
k_ra8_okChannel torn down, MSTP gated.
k_ra8_err_invalid_argchannel out of range.
Precondition
Caller is not in the middle of a transfer.
Postcondition
BCTL.BUSE cleared and I3C MSTP bit ref-released.
Since
0.1.0

Definition at line 588 of file ra8_i3c_i2c.c.

References r_i3c_i2c_regs_t::BCTL, r_i3c_i2c_regs_t::CECTL, i3c_i2c_regs(), k_ra8_err_invalid_arg, k_ra8_mstp_i3c, ra8_mstp_disable(), and s_iic_b_state.

Referenced by ra8_i3c_deinit().

◆ ra8_i3c_i2c_dispatch_eri()

void ra8_i3c_i2c_dispatch_eri ( uint8_t channel)

Dispatch the bus-error IRQ source.

Test-callable shim that mirrors the ERI handler in FSP's r_iic_b_master: it samples BST, masks the latched error bits back to k_ra8_i3c_i2c_err_*, clears them, and fires the registered callback with that mask if it is non-zero.

Parameters
[in]channelChannel index.
Since
0.1.0
Precondition
Driver state has been initialized by the matching *_init.
Caller has validated all pointer parameters.
Postcondition
Side effects are limited to those documented in the header.
No global state is modified on the error path.
Note
Thread safety: see the header declaration.

Definition at line 228 of file ra8_i3c_i2c_control.c.

References k_ra8_i3c_i2c_channel_count, priv_i3c_i2c_should_dispatch(), ra8_i3c_i2c_clear_errors(), ra8_i3c_i2c_get_errors(), and s_iic_b_state.

◆ ra8_i3c_i2c_get_errors()

ra8_err_t ra8_i3c_i2c_get_errors ( uint8_t channel,
uint8_t * out_mask )
nodiscard

Read latched error flags from BST (AL / NACKDF / TODF).

Parameters
[in]channelChannel index.
[out]out_maskOR of k_ra8_i3c_i2c_err_* bits.
Returns
ra8_err_t.
Return values
k_ra8_okout_mask populated.
k_ra8_err_null_ptrout_mask is NULL.
k_ra8_err_invalid_argchannel out of range.
Since
0.1.0

Definition at line 170 of file ra8_i3c_i2c_control.c.

References r_i3c_i2c_regs_t::BST, i3c_i2c_regs(), internal_i3c_i2c_decode_errors(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_i3c_dispatch(), ra8_i3c_get_errors(), and ra8_i3c_i2c_dispatch_eri().

◆ ra8_i3c_i2c_init()

ra8_err_t ra8_i3c_i2c_init ( uint8_t channel,
const ra8_i3c_i2c_cfg_t * cfg )
nodiscard

Initialise the IIC_B channel and bring the bus up.

Parameters
[in]channelChannel index (only 0 is valid on RA8D2).
[in]cfgConfiguration descriptor.
Returns
ra8_err_t.
Return values
k_ra8_okChannel initialized, BCTL.BUSE = 1.
k_ra8_err_null_ptrcfg is NULL.
k_ra8_err_invalid_argchannel out of range or cfg->bus_hz zero.
k_ra8_err_hw_timeoutRSTCTL.RI3CRST didn't self-clear.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init has been called.
Postcondition
On success BCTL.BUSE is set and the channel is ready to service ra8_i3c_i2c_write / ra8_i3c_i2c_read.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 563 of file ra8_i3c_i2c.c.

References ra8_i3c_i2c_cfg_t::bus_hz, i3c_i2c_regs(), internal_i3c_i2c_apply_init_regs(), internal_i3c_i2c_block_bringup(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_info_val, RA8_RETURN_ON_ERROR, s_iic_b_state, and s_tag.

Referenced by ra8_i3c_init().

◆ ra8_i3c_i2c_read()

ra8_err_t ra8_i3c_i2c_read ( uint8_t channel,
uint8_t target_7b,
uint8_t * buf,
uint32_t len,
bool restart )
nodiscard

Polling read of len bytes from a 7-bit target.

Mirrors FSP's R_IIC_B_MASTER_Read minus DTC:

  1. Reject the call if the bus is busy (BCST.BFREF == 0) AND no repeated-START is in progress (i.e. caller did not hold the bus via a prior ra8_i3c_i2c_write(..., restart=true)).
  2. Issue a START (or RESTART when the bus is already held).
  3. Send (target_7b << 1) | 1 as the address byte.
  4. Drain len bytes from NTDTBP0; ACK every byte except the last, which is NACKed via ACKCTL.ACKT (paired with ACKTWP).
  5. Issue a STOP unless restart == true.

State machine: IDLE -> ADDR_TX -> DATA_RX -> { STOP | hold for RESTART } -> IDLE.

Parameters
[in]channelChannel index.
[in]target_7b7-bit peripheral address.
[out]bufDestination buffer (non-NULL).
[in]lenByte count (non-zero).
[in]restartWhen true, suppress the trailing STOP.
Returns
ra8_err_t.
Return values
k_ra8_okTransfer succeeded.
k_ra8_err_null_ptrbuf is NULL or channel invalid.
k_ra8_err_invalid_arglen is zero.
k_ra8_err_busyBus busy at entry.
k_ra8_err_hw_timeoutRDBFF0 / TENDF poll timed out.
k_ra8_err_nackPeripheral NACKed the address byte.
k_ra8_err_hw_errorArbitration lost.
Precondition
Channel previously initialized.
Postcondition
BST status flags cleared.
Since
0.1.0

Definition at line 875 of file ra8_i3c_i2c.c.

References r_i3c_i2c_regs_t::BST, i3c_i2c_regs(), internal_i3c_i2c_busy_gate(), internal_i3c_i2c_finalize(), internal_i3c_i2c_open_phase(), internal_i3c_i2c_rx_phase(), internal_i3c_i2c_status_from_bst(), k_ra8_err_invalid_arg, k_ra8_i3c_i2c_addr_rw_read, k_ra8_i3c_i2c_addr_shift, k_ra8_ok, priv_i3c_i2c_clear_bst(), priv_i3c_i2c_send_address(), priv_i3c_i2c_stop(), RA8_CHECK_NULL_PTR, s_iic_b_state, and s_tag.

Referenced by ra8_i3c_i2c_transfer(), and ra8_i3c_read().

◆ ra8_i3c_i2c_scan()

ra8_err_t ra8_i3c_i2c_scan ( uint8_t channel,
uint8_t target_7b,
bool * out_acked )
nodiscard

Probe whether a 7-bit address ACKs.

Issues START, writes the address byte, waits for the ACK / NACK status, and issues STOP. Equivalent to a single i2cdetect sweep entry.

Parameters
[in]channelChannel index.
[in]target_7b7-bit peripheral address.
[out]out_ackedSet to true when the peripheral ACKs, false on NACK.
Returns
ra8_err_t.
Return values
k_ra8_okProbe completed (ACK or NACK).
k_ra8_err_null_ptrout_acked is NULL or channel invalid.
k_ra8_err_hw_timeoutStatus poll timed out.
Precondition
Channel previously initialized.
Since
0.1.0

Definition at line 122 of file ra8_i3c_i2c_control.c.

References r_i3c_i2c_regs_t::BST, i3c_i2c_regs(), k_ra8_err_hw_timeout, k_ra8_i3c_i2c_ctrl_addr_rw_write, k_ra8_i3c_i2c_ctrl_addr_shift, k_ra8_i3c_i2c_ctrl_poll_limit, k_ra8_i3c_i2c_msk_bst_nackdf, k_ra8_i3c_i2c_msk_bst_tendf, k_ra8_ok, priv_i3c_i2c_clear_bst(), priv_i3c_i2c_send_address(), priv_i3c_i2c_start(), priv_i3c_i2c_stop(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ra8_i3c_scan().

◆ ra8_i3c_i2c_set_clock()

ra8_err_t ra8_i3c_i2c_set_clock ( uint8_t channel,
uint32_t bus_hz,
uint32_t pclka_hz )
nodiscard

Update the bus clock without tearing the channel down.

Parameters
[in]channelChannel index.
[in]bus_hzNew bus clock in Hz (non-zero).
[in]pclka_hzCurrent PCLKA frequency in Hz.
Returns
ra8_err_t.
Return values
k_ra8_okSTDBR programmed.
k_ra8_err_invalid_argChannel / clock out of range.
Precondition
Channel previously initialized.
Postcondition
STDBR.SBRLO / SBRHO reflect the new divider.
Since
0.1.0

Definition at line 606 of file ra8_i3c_i2c.c.

References i3c_i2c_regs(), internal_i3c_i2c_half_period(), k_ra8_err_invalid_arg, k_ra8_i3c_i2c_stdbr_sbrho_pos, k_ra8_i3c_i2c_stdbr_sbrlo_pos, k_ra8_ok, and r_i3c_i2c_regs_t::STDBR.

Referenced by ra8_i3c_set_clock().

◆ ra8_i3c_i2c_transfer()

ra8_err_t ra8_i3c_i2c_transfer ( uint8_t channel,
uint8_t target_7b,
const uint8_t * tx,
uint32_t tx_len,
uint8_t * rx,
uint32_t rx_len )
nodiscard

Combined write-then-RESTART-then-read in a single bus transaction.

Convenience wrapper for the most common I2C pattern: write a register address, then read its contents back from the same target. Internally invokes ra8_i3c_i2c_write(..., restart=true) followed by ra8_i3c_i2c_read(..., restart=false). State machine:

IDLE -> ADDR_TX -> DATA_TX -> RESTART -> ADDR_TX(read) -> DATA_RX -> STOP -> IDLE

If either tx_len or rx_len is zero the corresponding phase is skipped (e.g. tx_len = 0 degenerates to a plain read).

Parameters
[in]channelChannel index.
[in]target_7b7-bit peripheral address.
[in]txBytes to send first (e.g. register address). May be NULL only when tx_len == 0.
[in]tx_lenNumber of bytes to send.
[out]rxDestination buffer for the read phase. May be NULL only when rx_len == 0.
[in]rx_lenNumber of bytes to read.
Returns
ra8_err_t.
Return values
k_ra8_okTransfer succeeded; STOP issued.
k_ra8_err_null_ptrtx/rx NULL with non-zero len, or channel invalid.
k_ra8_err_invalid_argBoth tx_len and rx_len are zero.
k_ra8_err_busyBus busy at entry.
k_ra8_err_nackPeripheral NACKed.
k_ra8_err_hw_timeoutPoll timed out.
Precondition
Channel previously initialized.
Postcondition
Bus is released regardless of outcome.
Since
0.1.0

Definition at line 916 of file ra8_i3c_i2c.c.

References i3c_i2c_regs(), k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, priv_i3c_i2c_len_buf_invalid(), ra8_i3c_i2c_read(), and ra8_i3c_i2c_write().

Referenced by ra8_i3c_transfer().

◆ ra8_i3c_i2c_write()

ra8_err_t ra8_i3c_i2c_write ( uint8_t channel,
uint8_t target_7b,
const uint8_t * data,
uint32_t len,
bool restart )
nodiscard

Polling write of len bytes to a 7-bit target address.

Mirrors FSP's R_IIC_B_MASTER_Write flow without the DTC fast path:

  1. Reject the call if the bus is busy (BCST.BFREF == 0).
  2. Issue a START condition.
  3. Send (target_7b << 1) | 0 as the address byte.
  4. Push each payload byte into NTDTBP0 once NTST.TDBEF0 sets.
  5. If restart == false issue a STOP; otherwise leave the bus held and return – the caller is expected to follow this call immediately with another ra8_i3c_i2c_write / ra8_i3c_i2c_read that will inject a repeated-START rather than a fresh START.

State machine: IDLE -> ADDR_TX -> DATA_TX -> { STOP | hold for RESTART } -> IDLE.

On NACK or arbitration loss the transaction is aborted (STOP issued unconditionally) and the matching error code is returned.

Parameters
[in]channelChannel index.
[in]target_7b7-bit peripheral address.
[in]dataBuffer to send (must be non-NULL even when len is zero).
[in]lenByte count.
[in]restartWhen true, suppress the trailing STOP and keep the bus held so the next call (typically a read) issues a repeated-START. When false, STOP is issued and the bus is released.
Returns
ra8_err_t.
Return values
k_ra8_okTransfer succeeded.
k_ra8_err_null_ptrdata is NULL or channel invalid.
k_ra8_err_busyBus busy at entry (BCST.BFREF clear).
k_ra8_err_hw_timeoutTDBEF0 / TENDF poll timed out.
k_ra8_err_nackPeripheral NACKed; STOP was issued.
k_ra8_err_hw_errorArbitration lost; STOP was issued.
Precondition
Channel previously initialized.
Postcondition
On k_ra8_ok and restart == false: STOP issued, bus free.
On k_ra8_ok and restart == true: bus held by controller; next call must be on the same channel/target.
Since
0.1.0

Definition at line 752 of file ra8_i3c_i2c.c.

References r_i3c_i2c_regs_t::BST, i3c_i2c_regs(), internal_i3c_i2c_busy_gate(), internal_i3c_i2c_drain_tx(), internal_i3c_i2c_finalize(), internal_i3c_i2c_open_phase(), internal_i3c_i2c_status_from_bst(), k_ra8_i3c_i2c_addr_rw_write, k_ra8_i3c_i2c_addr_shift, k_ra8_ok, priv_i3c_i2c_clear_bst(), priv_i3c_i2c_send_address(), priv_i3c_i2c_stop(), RA8_CHECK_NULL_PTR, s_iic_b_state, and s_tag.

Referenced by ra8_i3c_i2c_transfer(), and ra8_i3c_write().