ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_i3c_i2c.c
Go to the documentation of this file.
1
47
48#include "ra8_i3c_i2c.h"
49
50#include <stdint.h>
51
52#include "ra8_attributes.h"
53#include "ra8_check.h"
54#include "ra8_err.h"
55#include "ra8_hw_err.h"
57#include "ra8_i3c_i2c_regs.h"
58#include "ra8_log.h"
59#include "ra8_mstp.h"
60
76bool priv_i3c_i2c_len_buf_invalid(uint32_t len, const void* buf)
77{
78 return (len != 0U) && (buf == nullptr);
79}
80
96bool priv_i3c_i2c_should_dispatch(uint8_t mask, const void* cb)
97{
98 return (mask != 0U) && (cb != nullptr);
99}
100
102static const char* s_tag = "IIC_B";
103
122
133
160RA8_INTERNAL static uint8_t internal_i3c_i2c_half_period(uint32_t bus_hz, uint32_t pclka_hz)
161{
162 /* mcdc-deactivated: both args validated by ra8_i3c_i2c_init upstream; defensive duplicate. */
163 if ((bus_hz == 0U) || (pclka_hz == 0U)) {
164 return 0U;
165 }
166 enum : uint32_t {
167 k_ra8_i3c_i2c_period_split = 2U,
168 k_ra8_i3c_i2c_max_field = 0xFFU,
169 };
170 const uint32_t total = pclka_hz / bus_hz;
171 const uint32_t half = total / k_ra8_i3c_i2c_period_split;
172 if (half == 0U) {
173 return 0U;
174 }
175 uint32_t value = half - 1U;
176 if (value > k_ra8_i3c_i2c_max_field) {
177 value = k_ra8_i3c_i2c_max_field;
178 }
179 return (uint8_t)value;
180}
181
202 uint32_t mask)
203{
204 for (uint32_t i = 0U; i < k_ra8_i3c_i2c_poll_limit; i++) {
205#if defined(RA8_OFF_TARGET) && defined(UNIT_TEST)
206 /* HUM Ch 40.2.50 "NTST : Normal Transfer Status Register" p 2498 */
207 if (ra8_fake_mmio_poll(&reg->NTST, i, (reg->NTST & mask) != 0U)) {
208#else
209 /* HUM Ch 40.2.50 "NTST : Normal Transfer Status Register" p 2498 */
210 if ((reg->NTST & mask) != 0U) {
211#endif
212 return k_ra8_ok;
213 }
214 }
216}
217
243{
244 /* HUM Ch 40.2.4 "RSTCTL : Reset Control Register" p 2451 */
246 reg->RSTCTL = 0U;
247 for (uint32_t i = 0U; i < k_ra8_i3c_i2c_poll_limit; i++) {
248 /* HUM Ch 40.2.4 "RSTCTL : Reset Control Register" p 2451 */
249 const bool reset_clear = (reg->RSTCTL & k_ra8_i3c_i2c_msk_rstctl_ri3crst) == 0U;
250#if defined(RA8_OFF_TARGET) && defined(UNIT_TEST)
251 /* HUM Ch 40.2.4 "RSTCTL : Reset Control Register" p 2451 */
252 const bool observed = ra8_fake_mmio_poll(&reg->RSTCTL, i, reset_clear);
253#else
254 const bool observed = reset_clear;
255#endif
256 if (observed) {
257 return k_ra8_ok;
258 }
259 }
261}
262
278{
279 /* HUM Ch 40.2.32 "CNDCTL : Condition Control Register" p 2479 */
281}
282
301{
302 /* HUM Ch 40.2.32 "CNDCTL : Condition Control Register" p 2479 */
304}
305
326{
327 /* Clear the prior STOP-detect flag so the NEXT transaction sees a
328 * fresh edge. W0C semantics. */
331}
332
348{
349 enum : uint32_t {
350 k_ra8_i3c_i2c_bst_clear_mask = k_ra8_i3c_i2c_msk_bst_stcnddf | k_ra8_i3c_i2c_msk_bst_spcnddf |
354 };
355 /* HUM Ch 40.2.46 "BST : Bus Status Register" p 2490 */
356 reg->BST = reg->BST & ~k_ra8_i3c_i2c_bst_clear_mask;
357}
358
380ra8_err_t priv_i3c_i2c_send_address(volatile r_i3c_i2c_regs_t* reg, uint8_t address_byte)
381{
382 /* Wait for first TDBEF0 (set after START condition is on the bus).
383 * HUM Ch 40.2.50 "NTST : Normal Transfer Status Register" p 2498 */
385 if (err != k_ra8_ok) {
386 return err;
387 }
388 /* HUM Ch 40.2.35 "NTDTBP0 : Normal Transfer Data Buffer Port 0" p 2481 */
389 reg->NTDTBP0 = (uint32_t)address_byte;
390 return k_ra8_ok;
391}
392
412{
413 if ((bst & k_ra8_i3c_i2c_msk_bst_nackdf) != 0U) {
414 return k_ra8_err_nack;
415 }
416 if ((bst & k_ra8_i3c_i2c_msk_bst_alf) != 0U) {
417 return k_ra8_err_hw_error;
418 }
419 if ((bst & k_ra8_i3c_i2c_msk_bst_todf) != 0U) {
421 }
422 return k_ra8_ok;
423}
424
446{
447 return (reg->BCST & k_ra8_i3c_i2c_msk_bcst_bfref) != 0U;
448}
449
450/* =============================================================================
451 * Init / deinit -- mirrors FSP's controller-open sequence.
452 * =============================================================================
453 */
454
473 const ra8_i3c_i2c_cfg_t* cfg)
474{
475 /* HUM Ch 40.2.14 "REFCKCTL : Reference Clock Control Register" p 2463 */
476 reg->REFCKCTL = 0U;
477
478 /* HUM Ch 40.2.15 "STDBR : Standard Bit Rate Register" p 2463 */
479 const uint8_t half = internal_i3c_i2c_half_period(cfg->bus_hz, cfg->pclka_hz);
480 const uint32_t stdbr = ((uint32_t)half << (uint32_t)k_ra8_i3c_i2c_stdbr_sbrlo_pos) |
481 ((uint32_t)half << (uint32_t)k_ra8_i3c_i2c_stdbr_sbrho_pos);
482 reg->STDBR = stdbr;
483
484 /* HUM Ch 40.2.12 "BFCTL : Bus Function Control Register" p 2459 */
485 uint32_t bfctl =
489 }
490 reg->BFCTL = bfctl;
491
492 /* HUM Ch 40.2.24 "ACKCTL : Acknowledge Control Register" p 2473 */
494 /* HUM Ch 40.2.25 "SCSTRCTL : SCL Stretch Control Register" p 2474 */
495 reg->SCSTRCTL = 0U;
496
497 /* BUSE=1: drive the bus.
498 * HUM Ch 40.2.2 "BCTL : Bus Control Register" p 2449 */
500}
501
531{
532 /* The I3C/IIC_B shared block needs both MSTPB4 (I3C) AND MSTPB9 */
533 /* (IIC0) ungated; ungating only MSTPB4 leaves the channel-0 IIC */
534 /* controller powered down and any START hangs in BCST before */
535 /* TDBEF0 ever rises. Mirrors */
536 /* ra8_board_ek_ra8d2.c::internal_io_expander_apply. */
537 /* HUM Ch 11.2.7 "MSTPCRB : Module Stop Control Register B" p 444 */
539 RA8_RETURN_ON_ERROR(mst_err, s_tag, "iic_b_init: mstp i3c");
540 const ra8_err_t iic0_err = ra8_mstp_enable(k_ra8_mstp_iic0);
541 RA8_RETURN_ON_ERROR(iic0_err, s_tag, "iic_b_init: mstp iic0");
542
543 /* HUM Ch 40.2.92 "CECTL : Clock Enable Control Register" p 2543 */
545 /* BUSE=0: detach SCL/SDA before reset.
546 * HUM Ch 40.2.2 "BCTL : Bus Control Register" p 2449 */
547 reg->BCTL = 0U;
548
549 const ra8_err_t reset_err = internal_i3c_i2c_reset(reg);
550 RA8_RETURN_ON_ERROR(reset_err, s_tag, "iic_b_init: reset");
551
552 /* HUM Ch 40.2.1 "PRTS : Protocol Selection" p 2449 -- the I3C IP
553 * defaults to PRTMD=0 (I3C FIFO buffer transfer, command-queue
554 * driven). This polling driver writes NTDTBP0 directly, so it must
555 * switch the IP into PRTMD=1 (I2C single-buffer transfer) before
556 * any START / STOP / address byte is issued. Without this write the
557 * peripheral silently swallows writes to NTDTBP0 as stray I3C
558 * FIFO entries and never drives SCL. */
560 return k_ra8_ok;
561}
562
563ra8_err_t ra8_i3c_i2c_init(uint8_t channel, const ra8_i3c_i2c_cfg_t* cfg)
564{
565 RA8_CHECK_NULL_PTR(cfg, s_tag, "iic_b_init: cfg");
566 if (cfg->bus_hz == 0U) {
568 }
569 volatile r_i3c_i2c_regs_t* reg = i3c_i2c_regs(channel);
570 if (reg == nullptr) {
572 }
573
574 const ra8_err_t br_err = internal_i3c_i2c_block_bringup(reg);
575 RA8_RETURN_ON_ERROR(br_err, s_tag, "iic_b_init: block bringup");
576
578
579 s_iic_b_state[channel].cb = nullptr;
580 s_iic_b_state[channel].ctx = nullptr;
581 s_iic_b_state[channel].initialized = true;
582 s_iic_b_state[channel].bus_held = false;
583
584 ra8_log_info_val(s_tag, "iic_b_init channel", (uint32_t)channel);
585 return k_ra8_ok;
586}
587
589{
590 volatile r_i3c_i2c_regs_t* reg = i3c_i2c_regs(channel);
591 if (reg == nullptr) {
593 }
594 /* BUSE=0: release the bus.
595 * HUM Ch 40.2.2 "BCTL : Bus Control Register" p 2449 */
596 reg->BCTL = 0U;
597 /* HUM Ch 40.2.92 "CECTL : Clock Enable Control Register" p 2543 */
598 reg->CECTL = 0U;
599 s_iic_b_state[channel].cb = nullptr;
600 s_iic_b_state[channel].ctx = nullptr;
601 s_iic_b_state[channel].initialized = false;
602 s_iic_b_state[channel].bus_held = false;
604}
605
606ra8_err_t ra8_i3c_i2c_set_clock(uint8_t channel, uint32_t bus_hz, uint32_t pclka_hz)
607{
608 volatile r_i3c_i2c_regs_t* reg = i3c_i2c_regs(channel);
609 if (reg == nullptr) {
611 }
612 if ((bus_hz == 0U) || (pclka_hz == 0U)) {
614 }
615 /* HUM Ch 40.2.15 "STDBR : Standard Bit Rate Register" p 2463 */
616 const uint8_t half = internal_i3c_i2c_half_period(bus_hz, pclka_hz);
617 reg->STDBR = ((uint32_t)half << (uint32_t)k_ra8_i3c_i2c_stdbr_sbrlo_pos) |
618 ((uint32_t)half << (uint32_t)k_ra8_i3c_i2c_stdbr_sbrho_pos);
619 return k_ra8_ok;
620}
621
622/* =============================================================================
623 * Polling write -- mirrors FSP's controller-run path + TXI.
624 * =============================================================================
625 */
626
643RA8_INTERNAL static void internal_i3c_i2c_open_phase(volatile r_i3c_i2c_regs_t* reg, bool bus_held)
644{
645 if (bus_held) {
647 } else {
649 }
650}
651
674internal_i3c_i2c_drain_tx(volatile r_i3c_i2c_regs_t* reg, const uint8_t* data, uint32_t len)
675{
676 ra8_err_t err = k_ra8_ok;
677 for (uint32_t i = 0U; i < len; i++) {
679 if (err != k_ra8_ok) {
680 break;
681 }
682 if ((reg->BST & k_ra8_i3c_i2c_msk_bst_nackdf) != 0U) {
683 break;
684 }
685 /* HUM Ch 40.2.35 "NTDTBP0 : Normal Transfer Data Buffer Port 0" p 2481 */
686 reg->NTDTBP0 = (uint32_t)data[i];
687 }
688 return err;
689}
690
711 uint8_t channel,
712 ra8_err_t err,
713 bool restart)
714{
715 if ((err != k_ra8_ok) || !restart) {
717 s_iic_b_state[channel].bus_held = false;
718 } else {
719 s_iic_b_state[channel].bus_held = true;
720 }
722}
723
744 bool bus_held)
745{
746 if (bus_held) {
747 return k_ra8_ok;
748 }
750}
751
753 uint8_t target_7b,
754 const uint8_t* data,
755 uint32_t len,
756 bool restart)
757{
758 volatile r_i3c_i2c_regs_t* reg = i3c_i2c_regs(channel);
759 RA8_CHECK_NULL_PTR(reg, s_tag, "iic_b_write: channel");
760 RA8_CHECK_NULL_PTR(data, s_tag, "iic_b_write: data");
761
762 const bool bus_held = s_iic_b_state[channel].bus_held;
763 const ra8_err_t busy_gate = internal_i3c_i2c_busy_gate(reg, bus_held);
764 if (busy_gate != k_ra8_ok) {
765 return busy_gate;
766 }
767
769 internal_i3c_i2c_open_phase(reg, bus_held);
770
771 const uint8_t address_byte =
772 (uint8_t)(((uint32_t)target_7b << k_ra8_i3c_i2c_addr_shift) | k_ra8_i3c_i2c_addr_rw_write);
773 ra8_err_t err = priv_i3c_i2c_send_address(reg, address_byte);
774 if (err != k_ra8_ok) {
776 s_iic_b_state[channel].bus_held = false;
777 return err;
778 }
779
780 err = internal_i3c_i2c_drain_tx(reg, data, len);
781 const ra8_err_t bst_err = internal_i3c_i2c_status_from_bst(reg->BST);
782 if (bst_err != k_ra8_ok) {
783 err = bst_err;
784 }
785 internal_i3c_i2c_finalize(reg, channel, err, restart);
786 return err;
787}
788
789/* =============================================================================
790 * Polling read -- mirrors FSP's controller-run path + RXI.
791 * =============================================================================
792 */
793
817internal_i3c_i2c_drain_rx(volatile r_i3c_i2c_regs_t* reg, uint8_t* out, uint32_t len)
818{
819 ra8_err_t err = k_ra8_ok;
820 for (uint32_t i = 0U; i < len; i++) {
821 if (i == (len - 1U)) {
822 /* HUM Ch 40.2.24 "ACKCTL : Acknowledge Control Register" p 2473 */
824 }
826 if (err != k_ra8_ok) {
827 break;
828 }
829 /* HUM Ch 40.2.35 "NTDTBP0 : Normal Transfer Data Buffer Port 0" p 2481 */
830 out[i] = (uint8_t)(reg->NTDTBP0 & k_ra8_i3c_i2c_byte_mask);
831 }
832 return err;
833}
834
863internal_i3c_i2c_rx_phase(volatile r_i3c_i2c_regs_t* reg, uint8_t* buf, uint32_t len)
864{
866 if (err == k_ra8_ok) {
867 (void)reg->NTDTBP0;
868 err = internal_i3c_i2c_drain_rx(reg, buf, len);
869 }
871 return err;
872}
873
875ra8_i3c_i2c_read(uint8_t channel, uint8_t target_7b, uint8_t* buf, uint32_t len, bool restart)
876{
877 volatile r_i3c_i2c_regs_t* reg = i3c_i2c_regs(channel);
878 RA8_CHECK_NULL_PTR(reg, s_tag, "iic_b_read: channel");
879 RA8_CHECK_NULL_PTR(buf, s_tag, "iic_b_read: buf");
880 if (len == 0U) {
882 }
883
884 const bool bus_held = s_iic_b_state[channel].bus_held;
885 const ra8_err_t busy_gate = internal_i3c_i2c_busy_gate(reg, bus_held);
886 if (busy_gate != k_ra8_ok) {
887 return busy_gate;
888 }
889
891 internal_i3c_i2c_open_phase(reg, bus_held);
892
893 const uint8_t address_byte =
894 (uint8_t)(((uint32_t)target_7b << k_ra8_i3c_i2c_addr_shift) | k_ra8_i3c_i2c_addr_rw_read);
895 ra8_err_t err = priv_i3c_i2c_send_address(reg, address_byte);
896 if (err != k_ra8_ok) {
898 s_iic_b_state[channel].bus_held = false;
899 return err;
900 }
901
902 err = internal_i3c_i2c_rx_phase(reg, buf, len);
903 const ra8_err_t bst_err = internal_i3c_i2c_status_from_bst(reg->BST);
904 if (bst_err != k_ra8_ok) {
905 err = bst_err;
906 }
907 internal_i3c_i2c_finalize(reg, channel, err, restart);
908 return err;
909}
910
911/* =============================================================================
912 * Combined transfer -- write-then-RESTART-then-read.
913 * =============================================================================
914 */
915
917 uint8_t target_7b,
918 const uint8_t* tx,
919 uint32_t tx_len,
920 uint8_t* rx,
921 uint32_t rx_len)
922{
923 if (i3c_i2c_regs(channel) == nullptr) {
924 return k_ra8_err_null_ptr;
925 }
926 if ((tx_len == 0U) && (rx_len == 0U)) {
928 }
929 if ((tx_len != 0U) && (tx == nullptr)) {
930 return k_ra8_err_null_ptr;
931 }
932 if (priv_i3c_i2c_len_buf_invalid(rx_len, rx)) {
933 return k_ra8_err_null_ptr;
934 }
935
936 /* Phase 1: write (hold the bus for the upcoming read).
937 * Skipped entirely when tx_len == 0 -- this degenerates the call
938 * into a plain read, matching FSP's expectation that a zero-byte
939 * tx phase means "no register-pointer update needed". */
940 if (tx_len != 0U) {
941 const ra8_err_t w_err =
942 ra8_i3c_i2c_write(channel, target_7b, tx, tx_len, /*restart=*/(rx_len != 0U));
943 if (w_err != k_ra8_ok) {
944 return w_err;
945 }
946 }
947
948 /* Phase 2: read (close the bus normally). */
949 if (rx_len != 0U) {
950 const ra8_err_t r_err = ra8_i3c_i2c_read(channel, target_7b, rx, rx_len, /*restart=*/false);
951 if (r_err != k_ra8_ok) {
952 return r_err;
953 }
954 }
955 return k_ra8_ok;
956}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#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.
Definition ra8_check.h:184
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
Definition ra8_err.h:195
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
Definition ra8_err.h:310
@ k_ra8_err_nack
Peer responded with NACK (negative acknowledgement).
Definition ra8_err.h:435
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Bounded wait-flag primitives for RA8D2 HAL drivers.
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.
static void internal_i3c_i2c_open_phase(volatile r_i3c_i2c_regs_t *reg, bool bus_held)
Issue START or RESTART based on whether the bus is currently held by a previous restart=true call.
static ra8_err_t internal_i3c_i2c_drain_tx(volatile r_i3c_i2c_regs_t *reg, const uint8_t *data, uint32_t len)
Push len bytes from data into NTDTBP0.
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.
void priv_i3c_i2c_start(volatile r_i3c_i2c_regs_t *reg)
Issue a START condition.
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.
static ra8_err_t internal_i3c_i2c_wait_ntst(volatile r_i3c_i2c_regs_t *reg, uint32_t mask)
Wait for a flag in NTST to set.
bool priv_i3c_i2c_should_dispatch(uint8_t mask, const void *cb)
Pure dispatch-callback predicate – see header for full contract.
Definition ra8_i3c_i2c.c:96
ra8_i3c_i2c_state_t s_iic_b_state[k_ra8_i3c_i2c_channel_count]
Per-channel state table indexed by channel.
ra8_err_t ra8_i3c_i2c_deinit(uint8_t channel)
Tear down the IIC_B channel.
static ra8_err_t internal_i3c_i2c_reset(volatile r_i3c_i2c_regs_t *reg)
Pulse-reset the I3C peripheral via RSTCTL.RI3CRST.
static ra8_err_t internal_i3c_i2c_status_from_bst(uint32_t bst)
Map the latched BST error bits to a high-level status code.
static ra8_err_t internal_i3c_i2c_busy_gate(volatile const r_i3c_i2c_regs_t *reg, bool bus_held)
Bus-busy gate: rejects new transactions while BCST.BFREF is clear, unless the channel is in a held-bu...
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.
static ra8_err_t internal_i3c_i2c_drain_rx(volatile r_i3c_i2c_regs_t *reg, uint8_t *out, uint32_t len)
Drain len bytes from NTDTBP0 into out.
static void internal_i3c_i2c_apply_init_regs(volatile r_i3c_i2c_regs_t *reg, const ra8_i3c_i2c_cfg_t *cfg)
Apply the post-reset register defaults for an IIC_B channel.
void priv_i3c_i2c_clear_bst(volatile r_i3c_i2c_regs_t *reg)
Clear all latched bus-status flags ahead of a new transaction.
bool priv_i3c_i2c_len_buf_invalid(uint32_t len, const void *buf)
Pure len/buf reject predicate – see header for full contract.
Definition ra8_i3c_i2c.c:76
static bool internal_i3c_i2c_bus_free(volatile const r_i3c_i2c_regs_t *reg)
True when the bus is free as reported by BCST.BFREF.
ra8_err_t priv_i3c_i2c_send_address(volatile r_i3c_i2c_regs_t *reg, uint8_t address_byte)
Send a single address byte and wait for TDBEF0 to be ready for the next slot.
static void internal_i3c_i2c_finalize(volatile r_i3c_i2c_regs_t *reg, uint8_t channel, ra8_err_t err, bool restart)
Decide STOP vs hold and update channel state accordingly.
void priv_i3c_i2c_stop(volatile r_i3c_i2c_regs_t *reg)
Issue a STOP condition.
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.
static ra8_err_t internal_i3c_i2c_rx_phase(volatile r_i3c_i2c_regs_t *reg, uint8_t *buf, uint32_t len)
Run the data phase of an RX transaction (dummy-read + drain).
static void internal_i3c_i2c_restart(volatile r_i3c_i2c_regs_t *reg)
Issue a repeated-START (Sr) condition.
static uint8_t internal_i3c_i2c_half_period(uint32_t bus_hz, uint32_t pclka_hz)
Compute STDBR.SBRLO / SBRHO half-period count from PCLKA.
internal_i3c_i2c_t
Implementation constants – spin budgets, addressing helpers.
@ k_ra8_i3c_i2c_addr_rw_write
R/W bit value for a write transaction (0 in LSB).
@ k_ra8_i3c_i2c_addr_rw_read
R/W bit value for a read transaction (1 in LSB).
@ k_ra8_i3c_i2c_poll_limit
Generic spin budget for status-flag polls.
@ k_ra8_i3c_i2c_byte_mask
8-bit byte mask for narrowing 32-bit reads from NTDTBP0.
@ k_ra8_i3c_i2c_addr_shift
Shift count to convert a 7-bit address into the on-the-wire byte.
static ra8_err_t internal_i3c_i2c_block_bringup(volatile r_i3c_i2c_regs_t *reg)
Bring the IIC_B block up: MSTP release, CECTL clock, reset, and switch the I3C IP into I2C single-buf...
IIC_B (I3C unified IP, I2C-only mode) controller driver.
@ k_ra8_i3c_i2c_speed_fast_plus
1 MHz Fm+.
Definition ra8_i3c_i2c.h:65
Test-access surface for ra8_i3c_i2c internal helpers (MC/DC).
IIC_B (I3C-based I2C) register layout for the Renesas RA8D2.
@ k_ra8_i3c_i2c_channel_count
HUM Ch 40.1.1, p 2445.
static volatile r_i3c_i2c_regs_t * i3c_i2c_regs(uint8_t channel)
Get a pointer to the IIC_B / I3C channel channel.
@ k_ra8_i3c_i2c_msk_ackctl_ackt
HUM 40.2 ACKCTL.ACKT, p 2468.
@ k_ra8_i3c_i2c_msk_bst_nackdf
HUM 40.2 BST.NACKDF, p 2482.
@ k_ra8_i3c_i2c_msk_bfctl_nale
HUM 40.2 BFCTL.NALE, p 2461.
@ k_ra8_i3c_i2c_msk_rstctl_ri3crst
HUM 40.2 RSTCTL.RI3CRST, p 2456.
@ k_ra8_i3c_i2c_msk_bfctl_scsyne
HUM 40.2 BFCTL.SCSYNE, p 2461.
@ k_ra8_i3c_i2c_msk_cndctl_spcnd
HUM 40.2 CNDCTL.SPCND, p 2473.
@ k_ra8_i3c_i2c_msk_prts_prtmd
HUM 40.2.1 PRTS.PRTMD, p 2449.
@ k_ra8_i3c_i2c_msk_bst_spcnddf
HUM 40.2 BST.SPCNDDF, p 2482.
@ k_ra8_i3c_i2c_msk_bst_stcnddf
HUM 40.2 BST.STCNDDF, p 2482.
@ k_ra8_i3c_i2c_msk_bcst_bfref
HUM 40.2 BCST.BFREF, p 2491.
@ k_ra8_i3c_i2c_msk_cndctl_stcnd
HUM 40.2 CNDCTL.STCND, p 2473.
@ k_ra8_i3c_i2c_msk_bst_tendf
HUM 40.2 BST.TENDF, p 2482.
@ k_ra8_i3c_i2c_msk_ntst_tdbef0
HUM 40.2 NTST.TDBEF0, p 2486.
@ k_ra8_i3c_i2c_msk_bst_alf
HUM 40.2 BST.ALF, p 2482.
@ k_ra8_i3c_i2c_msk_bst_todf
HUM 40.2 BST.TODF, p 2482.
@ k_ra8_i3c_i2c_msk_bctl_buse
HUM 40.2 BCTL.BUSE, p 2454.
@ k_ra8_i3c_i2c_msk_bfctl_fmpe
HUM 40.2 BFCTL.FMPE, p 2461.
@ k_ra8_i3c_i2c_msk_cectl_clke
HUM 40.2 CECTL.CLKE, p 2453.
@ k_ra8_i3c_i2c_msk_ntst_rdbff0
HUM 40.2 NTST.RDBFF0, p 2486.
@ k_ra8_i3c_i2c_msk_bfctl_male
HUM 40.2 BFCTL.MALE, p 2461.
@ k_ra8_i3c_i2c_msk_ackctl_acktwp
HUM 40.2 ACKCTL.ACKTWP,p 2468.
@ k_ra8_i3c_i2c_msk_cndctl_srcnd
HUM 40.2 CNDCTL.SRCND, p 2473.
@ k_ra8_i3c_i2c_stdbr_sbrlo_pos
HUM 40.2 STDBR.SBRLO, p 2462.
@ k_ra8_i3c_i2c_stdbr_sbrho_pos
HUM 40.2 STDBR.SBRHO, p 2462.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
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.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
@ k_ra8_mstp_iic0
MSTPB9 IIC0.
@ k_ra8_mstp_i3c
MSTPB4 I3C.
Memory-mapped register block for one IIC_B / I3C channel.
volatile uint32_t NTST
+0x1E0 Normal Transfer Status (HUM 40.2, p 2486).
volatile uint32_t REFCKCTL
+0x070 Reference Clock Control (HUM 40.2, p 2462).
volatile uint32_t BCST
+0x210 Bus Condition Status (HUM 40.2, p 2491).
volatile uint32_t CECTL
+0x010 Clock Enable Control (HUM 40.2, p 2453).
volatile uint32_t STDBR
+0x074 Standard Bit Rate (HUM 40.2, p 2462).
volatile uint32_t BST
+0x1D0 Bus Status (HUM 40.2, p 2482).
volatile uint32_t BCTL
+0x014 Bus Control (HUM 40.2, p 2454).
volatile uint32_t PRTS
+0x000 Protocol Selection (HUM 40.2, p 2452).
volatile uint32_t SCSTRCTL
+0x0A4 SCL Stretch Control (HUM 40.2, p 2469).
volatile uint32_t ACKCTL
+0x0A0 Acknowledge Control (HUM 40.2, p 2468).
volatile uint32_t RSTCTL
+0x020 Reset Control (HUM 40.2, p 2456).
volatile uint32_t NTDTBP0
+0x158 Normal Tx/Rx Data Buffer 0 (HUM 40.2, p 2476).
volatile uint32_t BFCTL
+0x060 Bus Function Control (HUM 40.2, p 2461).
volatile uint32_t CNDCTL
+0x140 Condition Control (HUM 40.2, p 2473).
Configuration descriptor for ra8_i3c_i2c_init.
Definition ra8_i3c_i2c.h:77
uint32_t bus_hz
Target I2C clock rate in Hz.
Definition ra8_i3c_i2c.h:78
uint32_t pclka_hz
Current PCLKA / I3CCLK frequency for STDBR calc.
Definition ra8_i3c_i2c.h:79
Per-channel dispatch state shared across the driver's TUs.