60 return (target > addr_mask) || (max_len == 0U);
85 return (mode != sdr_val) && (mode != ddr_val) && (mode != ts_val);
89static const char*
s_tag =
"I3C";
244 while (i + k_word_size <= len) {
245 uint32_t w = (uint32_t)data[i];
256 w |= ((uint32_t)data[i]) << s;
287 while (i + k_word_size <= len) {
288 const uint32_t w = reg->
NTDTBP0;
296 const uint32_t w = reg->
NTDTBP0;
439 fn(ctx, (uint32_t)mask);
445 const uint32_t mask = reg->
INST;
496 for (uint8_t i = 0U; i < target_count; ++i) {
499 k_pid_bcr_dcr_bytes = 8U,
503 uint8_t pid_bcr_dcr[k_pid_bcr_dcr_bytes] = {};
506 targets[i].pid[j] = pid_bcr_dcr[j];
508 targets[i].bcr = pid_bcr_dcr[k_idx_bcr];
509 targets[i].dcr = pid_bcr_dcr[k_idx_dcr];
534 reg->
NCMDQP = (uint32_t)dynamic_addr;
560 if ((len > 0U) && (payload ==
nullptr)) {
577 for (uint8_t i = 0U; i < len; ++i) {
593ra8_i3c_recv_ccc(uint8_t ccc, uint8_t target_addr, uint8_t* buf, uint8_t max_len, uint8_t* got_len)
621ra8_i3c_write(uint8_t channel, uint8_t addr,
const uint8_t* data, uint32_t len,
bool restart)
633 const uint8_t target_addr = addr;
637 if ((len > 0U) && (data ==
nullptr)) {
652 for (uint32_t i = 0U; i < len; ++i) {
678 const uint8_t target_addr = addr;
879 k_ra8_i3c_ntibivctl_one_target = 1U,
905 const uint32_t sdyad =
931 const uint32_t status = reg->
NIBIQP;
934 const uint8_t ibi_id =
943 k_ibi_id_hot_join = 0x02U,
947 }
else if (ibi_id == k_ibi_id_hot_join) {
953 const uint8_t k_max_ibi_payload = (uint8_t)(
sizeof(out_ibi->
payload));
954 uint8_t to_copy = len;
955 if (to_copy > k_max_ibi_payload) {
956 to_copy = k_max_ibi_payload;
959 for (uint8_t i = 0U; i < k_max_ibi_payload; ++i) {
966 k_ibi_last_mask = 1U,
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_ISR_SAFE
The function is callable from interrupt context.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_data
No application data available (e.g.
@ k_ra8_err_invalid_arg
Invalid function argument.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
ra8_err_t ra8_i3c_exit_stop(void)
Exit MSTP-gated stop (native mode).
static uint32_t internal_ra8_i3c_ccc_cmd_word(uint8_t ccc, uint8_t target_addr, bool rnw)
Build a CCC-type command descriptor word.
ra8_err_t ra8_i3c_target_open(uint8_t static_addr)
Enter peripheral (target) mode (native mode).
ra8_err_t ra8_i3c_read(uint8_t channel, uint8_t addr, uint8_t *buf, uint32_t len, bool restart)
Read len bytes from addr.
ra8_err_t ra8_i3c_get_status(uint32_t *out_mask)
Read the native INST status register (native mode).
static void internal_ra8_i3c_fifo_read(volatile const r_i3c_regs_t *reg, uint8_t *out, uint32_t len)
Drain len bytes from NTDTBP0 into out.
ra8_err_t ra8_i3c_transfer(uint8_t channel, uint8_t addr, const uint8_t *wr, uint32_t wr_len, uint8_t *rd, uint32_t rd_len)
Write-then-read with repeated-START framing (I2C mode).
ra8_err_t ra8_i3c_send_ccc(uint8_t ccc, uint8_t target_addr, const uint8_t *payload, uint8_t len)
Generic CCC send – broadcast or directed write (native mode).
ra8_err_t ra8_i3c_peripheral_send(uint8_t channel, const uint8_t *data, uint32_t len)
Queue bytes for the controller to read (responder mode).
ra8_err_t ra8_i3c_clear_status(uint32_t mask)
Clear native INST status bits (native mode).
void ra8_i3c_dispatch(uint8_t channel)
Snapshot status and fire the channel's callback.
ra8_err_t ra8_i3c_deinit(uint8_t channel)
Tear down an I3C channel and gate the peripheral.
ra8_err_t ra8_i3c_peripheral_receive(uint8_t channel, uint8_t *buf, uint32_t len)
Read bytes the controller wrote (responder mode).
ra8_err_t ra8_i3c_enter_stop(void)
Put native I3C0 into MSTP-gated stop (native mode).
ra8_err_t ra8_i3c_peripheral_status(uint8_t channel, uint8_t *out_mask)
Read the latched responder-mode status (responder mode).
ra8_err_t ra8_i3c_set_dynamic_address(uint8_t static_addr, uint8_t dynamic_addr)
Issue SETDASA to assign one target a dynamic address (native mode).
ra8_err_t ra8_i3c_bus_enable(bool enable)
Enable/disable bus-primary operation via BCTL.BUSE (native mode).
ra8_err_t ra8_i3c_dynamic_address_assign(ra8_i3c_daa_target_t *targets, uint8_t target_count)
Issue ENTDAA to enumerate I3C targets (native mode).
bool priv_ra8_i3c_internal_hdr_mode_invalid(uint32_t sdr_val, uint32_t ddr_val, uint32_t ts_val, uint32_t mode)
Pure HDR-mode-invalid predicate – see header for full contract.
ra8_err_t ra8_i3c_attach_handler(uint8_t channel, ra8_i3c_event_fn_t fn, void *ctx)
Attach an event callback for a channel.
ra8_err_t ra8_i3c_ibi_enable(uint8_t target_addr)
Enable inbound IBI capture for a target (native mode).
ra8_err_t ra8_i3c_abort(uint8_t channel)
Abort an in-flight I2C transfer and release the bus (I2C mode).
bool priv_ra8_i3c_internal_recv_ccc_invalid(uint8_t addr_mask, uint8_t target, uint8_t max_len)
Pure recv-ccc-invalid predicate – see header for full contract.
ra8_err_t ra8_i3c_scan(uint8_t channel, uint8_t addr, bool *out_acked)
Probe whether a 7-bit address acknowledges (I2C mode).
static ra8_i3c_event_fn_t s_i3c_fn
Currently registered IRQ callback (NULL when detached).
ra8_err_t ra8_i3c_ibi_read(ra8_i3c_ibi_t *out_ibi)
Drain one inbound IBI from NIBIQP (native mode).
static void internal_ra8_i3c_reset_sequence(volatile r_i3c_regs_t *reg)
Internal-error reset bring-up sequence per FSP R_I3C_Open.
static ra8_i3c_chan_state_t s_i3c_chan[k_ra8_i3c_i2c_channel_count]
One state slot per I3C channel (RA8D2 exposes I3C0 only).
ra8_err_t ra8_i3c_recv_ccc(uint8_t ccc, uint8_t target_addr, uint8_t *buf, uint8_t max_len, uint8_t *got_len)
Generic CCC receive – directed read (native mode).
ra8_err_t ra8_i3c_set_address(uint32_t addr)
Programme the primary dynamic address (native mode).
ra8_err_t ra8_i3c_write(uint8_t channel, uint8_t addr, const uint8_t *data, uint32_t len, bool restart)
Write len bytes to addr.
static void * s_i3c_ctx
Opaque context handed back to s_i3c_fn.
ra8_err_t ra8_i3c_ibi_drain(ra8_i3c_ibi_t *ibi)
Pop one inbound IBI (alias of ra8_i3c_ibi_read, native mode).
static uint32_t internal_ra8_i3c_xfer_cmd_word(uint8_t target_addr, bool rnw)
Build the first word of a regular-transfer command descriptor.
ra8_err_t ra8_i3c_set_hdr_mode(uint8_t target_addr, ra8_i3c_hdr_mode_t mode)
Programme the NCMDQP transfer-mode field for a target (native mode).
ra8_err_t ra8_i3c_get_errors(uint8_t channel, uint8_t *out_mask)
Read the latched I2C error mask (I2C mode).
ra8_err_t ra8_i3c_peripheral_open(uint8_t channel, const ra8_i3c_peripheral_cfg_t *cfg)
Open a channel in I2C-compat responder mode.
ra8_err_t ra8_i3c_clear_errors(uint8_t channel)
Clear latched I2C error bits (I2C mode).
ra8_err_t ra8_i3c_reset_dynamic_addresses(void)
Issue RSTDAA to clear all dynamic addresses (native mode).
ra8_err_t ra8_i3c_init(uint8_t channel, const ra8_i3c_cfg_t *cfg)
Initialise an I3C channel in the configured mode.
ra8_err_t ra8_i3c_peripheral_close(uint8_t channel)
Close responder mode on a channel.
ra8_err_t ra8_i3c_set_clock(uint8_t channel, uint32_t bus_hz, uint32_t pclka_hz)
Re-programme the I2C bit rate (I2C mode).
static void internal_ra8_i3c_fifo_write(volatile r_i3c_regs_t *reg, const uint8_t *data, uint32_t len)
Push a payload buffer through NTDTBP0 in 32-bit chunks.
I3C Bus Interface driver – unified native-I3C + I2C-compat modes.
ra8_i3c_mode_t
Operating mode selected per channel at ra8_i3c_init.
@ k_ra8_i3c_mode_i2c
Legacy I2C-compatibility controller.
@ k_ra8_i3c_ibi_type_main_request
Mainship request.
@ k_ra8_i3c_ibi_type_interrupt
Peripheral-initiated IBI.
@ k_ra8_i3c_ibi_type_hot_join
Hot-join request.
void(* ra8_i3c_event_fn_t)(void *ctx, uint32_t status)
Event callback fired by ra8_i3c_dispatch.
ra8_i3c_hdr_mode_t
HDR transfer-mode selector for ra8_i3c_set_hdr_mode (native).
@ k_ra8_i3c_hdr_mode_sdr
Plain SDR transfer (default).
@ k_ra8_i3c_hdr_mode_ts
HDR-TS.
@ k_ra8_i3c_hdr_mode_ddr
HDR-DDR.
IIC_B (I3C unified IP, I2C-only mode) controller driver.
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_abort(uint8_t channel)
Cancel any in-flight transaction and return the channel to idle.
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_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_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_clear_errors(uint8_t channel)
Clear latched error flags in BST.
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_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.
IIC_B (I3C in I2C-only mode) peripheral driver – mirrors FSP r_iic_b_peripheral.
ra8_err_t ra8_i3c_i2c_peripheral_status(uint8_t channel, uint8_t *out_mask)
Read latched peripheral-side status mask.
ra8_err_t ra8_i3c_i2c_peripheral_send(uint8_t channel, const uint8_t *data, uint32_t len)
Push len bytes into NTDTBP0 in response to a controller-read.
ra8_err_t ra8_i3c_i2c_peripheral_open(uint8_t channel, const ra8_i3c_i2c_peripheral_cfg_t *cfg)
Open a channel as an IIC_B peripheral.
ra8_err_t ra8_i3c_i2c_peripheral_receive(uint8_t channel, uint8_t *buf, uint32_t len)
Drain len bytes from NTDTBP0 after a controller-write.
ra8_err_t ra8_i3c_i2c_peripheral_close(uint8_t channel)
Close the peripheral channel.
IIC_B (I3C-based I2C) register layout for the Renesas RA8D2.
@ k_ra8_i3c_i2c_channel_count
HUM Ch 40.1.1, p 2445.
Test-access surface for ra8_i3c internal helpers (MC/DC).
I3C Bus Interface register layout for the Renesas RA8D2.
@ k_ra8_i3c_shift_b1
Shift for byte 1 in a word.
@ k_ra8_i3c_byte_shift
Bits per byte.
@ k_ra8_i3c_addr_shift_in_ibi_id
IBI ID = (addr << 1) | RnW.
@ k_ra8_i3c_shift_b3
Shift for byte 3 in a word.
@ k_ra8_i3c_word_size
Bytes per FIFO word.
@ k_ra8_i3c_byte_mask
Mask covering one byte.
@ k_ra8_i3c_shift_b2
Shift for byte 2 in a word.
@ k_ra8_i3c_pid_bytes
48-bit Provisional ID.
@ k_ra8_i3c_immediate_max_bytes
Immediate-data transfer cap.
@ k_ra8_i3c_addr_mask
7-bit dynamic address mask.
@ k_ra8_i3c_setdasa_payload_bytes
SETDASA carries one address byte.
@ k_ra8_i3c_max_targets
Cap on ENTDAA device-table size.
@ k_ra8_i3c_ibi_status_last_shift
RA8 I3C ibi status last shift.
@ k_ra8_i3c_ibi_status_length_mask
RA8 I3C ibi status length mask.
@ k_ra8_i3c_ibi_status_ibi_st_mask
IBI status type bit 31.
@ k_ra8_i3c_ibi_status_id_mask
RA8 I3C ibi status ID mask.
@ k_ra8_i3c_ibi_status_id_shift
RA8 I3C ibi status ID shift.
@ k_ra8_i3c_ibi_status_length_shift
RA8 I3C ibi status length shift.
@ k_ra8_i3c_ntst_ibiqeff_mask
IBI Queue Empty/Full bit 2.
@ k_ra8_i3c_ntst_cmdqef_mask
Cmd Queue Empty bit 3.
static volatile r_i3c_regs_t * ra8_i3c(void)
Get pointer to I3C0.
@ k_ra8_i3c_ccc_b_rstdaa
Broadcast Reset Dynamic Address Assignment.
@ k_ra8_i3c_ccc_direct_mask
Bit set in direct CCC opcodes.
@ k_ra8_i3c_ccc_d_setdasa
Direct Set Dynamic Address from Static Address.
@ k_ra8_i3c_ccc_b_entdaa
Broadcast Enter Dynamic Address Assignment.
@ k_ra8_i3c_rstctl_intlrst_mask
Internal software reset.
@ k_ra8_i3c_rstctl_ri3crst_mask
I3C software reset.
@ k_ra8_i3c_cmd_code_shift
CCC opcode position.
@ k_ra8_i3c_cmd_attr_shift
RA8 I3C cmd attr shift.
@ k_ra8_i3c_cmd_immed_bytes_shift
Immediate byte count [24:23].
@ k_ra8_i3c_cmd_addr_count_shift
ENTDAA device count.
@ k_ra8_i3c_cmd_attr_immed
Immediate-data transfer attribute.
@ k_ra8_i3c_cmd_roc_shift
Response-on-Completion.
@ k_ra8_i3c_cmd_cp_shift
Command Present (CCC) flag.
@ k_ra8_i3c_cmd_xfer_mode_shift
RA8 I3C cmd xfer mode shift.
@ k_ra8_i3c_cmd_dev_index_shift
Device-table index.
@ k_ra8_i3c_cmd_attr_addr_assgn
Address-assignment attribute.
@ k_ra8_i3c_cmd_xfer_length_shift
Transfer length [31:16].
@ k_ra8_i3c_cmd_rnw_shift
Read-not-Write direction bit.
@ k_ra8_i3c_cmd_xfer_length_max
RA8 I3C cmd xfer length maximum.
@ k_ra8_i3c_cmd_toc_shift
Terminate-on-Completion (STOP).
@ k_ra8_i3c_cmd_hdr_mode_mask
RA8 I3C cmd hdr mode mask.
@ k_ra8_i3c_bctl_buse_mask
BUSE bit 31.
@ k_ra8_i3c_bctl_slve_mask
SLVE bit 16 (peripheral-mode enable).
@ k_ra8_i3c_nsdvad_sdyad_mask
RA8 I3C nsdvad sdyad mask.
@ k_ra8_i3c_nsdvad_sdyad_shift
SDYAD bits [22:16].
@ k_ra8_i3c_nsdvad_sdyadv_mask
SDYADV bit 31.
@ k_ra8_i3c_ntibivctl_vlcnt_shift
RA8 I3C ntibivctl vlcnt shift.
@ k_ra8_i3c_ntibivctl_vlcnt_mask
Valid-entry count [7:0].
@ k_ra8_i3c_msdvad_mdyad_shift
MDYAD bits [22:16].
@ k_ra8_i3c_msdvad_addr_max
7-bit dynamic address.
@ k_ra8_i3c_msdvad_mdyadv_mask
MDYADV bit 31.
@ k_ra8_i3c_msdvad_mdyad_mask
RA8 I3C msdvad mdyad mask.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info(tag, message)
RA8 log info.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Module Stop Control (MSTP) register layout for the Renesas RA8D2.
@ k_ra8_mstp_i3c
MSTPB4 I3C.
Partial RA8D2 I3C0 register window.
volatile uint32_t NSDVAD
+0x0B4 Peripheral Device Address Register (peripheral-mode dynamic address + valid).
volatile uint32_t NTST
+0x1E0 Normal Transfer Status Register.
volatile uint32_t NTDTBP0
+0x158 Normal Transfer Data Buffer Port Register 0.
volatile uint32_t INSTFC
+0x03C Internal Status Force Register.
volatile uint32_t NCMDQP
+0x150 Normal Command Queue Port Register.
volatile uint32_t NIBIQP
+0x17C Normal IBI Queue Port Register.
volatile uint32_t INIE
+0x038 Internal Interrupt Enable Register.
volatile uint32_t BCTL
+0x014 Bus Control Register.
volatile uint32_t INST
+0x030 Internal Status Register.
volatile uint32_t NTIBIVCTL
+0x0B8 IBI Valid Control Register (peripheral-side IBI queue valid count).
volatile uint32_t PRTS
+0x000 Protocol Selection Register.
volatile uint32_t INSTE
+0x034 Internal Status Enable Register.
volatile uint32_t CECTL
+0x010 Clock Enable Control Register.
volatile uint32_t MSDVAD
+0x018 Controller Device Address Register.
volatile uint32_t RSTCTL
+0x020 Reset Control Register.
Per-channel bring-up configuration for ra8_i3c_init.
uint32_t bus_hz
Target bus clock in Hz (I2C mode).
ra8_i3c_mode_t mode
Operating mode for this channel.
uint32_t pclka_hz
Source clock for the bit-rate calc (I2C).
Per-channel driver bookkeeping for the unified driver.
ra8_i3c_mode_t mode
Native vs I2C-compat for this channel.
bool initialized
Set between ra8_i3c_init / _deinit.
One target entry filled in by ENTDAA (native mode).
Configuration descriptor for ra8_i3c_i2c_init.
Configuration descriptor for ra8_i3c_i2c_peripheral_open.
Decoded IBI inbound descriptor (native mode).
uint8_t payload[8]
Up to 8 bytes of payload.
uint8_t payload_len
Bytes that follow in payload[].
ra8_i3c_ibi_type_t type
IBI / HJ / MR classification.
uint8_t address
Originating dynamic address.
uint8_t last
1 if this is the final fragment.
Bring-up configuration for I2C-compat responder mode.
uint8_t peripheral_addr_7b
7-bit own address.
uint8_t general_call
Non-zero -> answer general-call address.