ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_riic.c
Go to the documentation of this file.
1
39
40#include <stdint.h>
41#include <stdio.h>
42
43#include "board_console.h"
44#include "board_periph_block.h"
47
49typedef enum : uint32_t {
52
64typedef enum : uint64_t {
65 k_riic_base = 0x4025E000UL,
66 k_riic_stride = 0x100UL,
68 k_riic_span = 0x100UL * 3UL,
82
84typedef enum : uint32_t {
92
104
106typedef enum : uint32_t {
109
111typedef enum : uint32_t {
117
139
148
151 (uint8_t)k_riic_tgt_payload0,
152 (uint8_t)k_riic_tgt_payload1,
153};
154
156typedef enum : uint32_t {
163
177typedef struct {
179 uint32_t icsr2;
180 bool busy;
182 bool acked;
183 bool reading;
184 uint8_t target_7b;
186 uint32_t rx_len;
187 uint32_t rx_pos;
189 /* Target (peripheral) role: this model is the synthetic external controller. */
191 uint8_t tgt_own_addr;
192 uint8_t tgt_phase;
193 uint32_t tgt_icsr2;
194 uint32_t tgt_wr_pos;
195 uint32_t tgt_rd_len;
196 uint32_t tgt_cycles;
200
203
204/* =============================================================================
205 * RIIC controller model -- the transfer state machine the ra8_i2c.c polling
206 * driver drives (START / RESTART / addr / write / read / STOP).
207 * =============================================================================
208 */
209
220{
221 s->busy = true;
222 s->addr_done = false;
223 s->acked = false;
224 s->reading = false;
225 s->rx_len = 0U;
226 s->rx_pos = 0U;
227 s->rx_primed = false;
228 /* Transmit buffer is empty so the driver can write the address byte; clear
229 * the stale condition / fault flags so the new phase reports its own. */
230 s->icsr2 = (uint32_t)k_riic_icsr2_tdre;
231}
232
243{
244 if (s->acked) {
246 if (dev != nullptr) {
247 if (dev->stop != nullptr) {
248 dev->stop(dev->ctx);
249 }
250 }
251 /* Console I2C tab: one line per completed (ACKed) RIIC transaction at STOP
252 * (RIIC shares the I2C tab with the IIC_B model). */
254 if (s->reading) {
255 (void)snprintf(ln,
256 sizeof(ln),
257 "RIIC addr=0x%02X R %uB",
258 (unsigned)s->target_7b,
259 (unsigned)s->rx_len);
260 } else {
261 (void)snprintf(ln, sizeof(ln), "RIIC addr=0x%02X W", (unsigned)s->target_7b);
262 }
264 }
265 s->busy = false;
266 s->addr_done = false;
267 s->icsr2 = (uint32_t)k_riic_icsr2_stop;
268}
269
280RA8_INTERNAL static void internal_riic_address_phase(riic_state_t* s, uint8_t address_byte)
281{
282 s->target_7b =
283 (uint8_t)((uint32_t)address_byte >> (uint32_t)k_riic_addr_shift) & (uint8_t)k_riic_addr_mask7;
284 s->reading = ((uint32_t)address_byte & (uint32_t)k_riic_addr_rnw) != 0U;
285 s->addr_done = true;
286
288 if (dev == nullptr) {
289 /* No device at this address: NACK it (scan reports ack=0). */
290 s->acked = false;
291 s->icsr2 |=
292 ((uint32_t)k_riic_icsr2_nackf | (uint32_t)k_riic_icsr2_tend | (uint32_t)k_riic_icsr2_tdre);
293 return;
294 }
295 s->acked = true;
296 /* Address ACKed: TEND lets the scan / write proceed, TDRE re-arms TX. */
297 s->icsr2 |= ((uint32_t)k_riic_icsr2_tend | (uint32_t)k_riic_icsr2_tdre);
298 if (s->reading) {
299 /* Pre-fetch the device's response for this read so ICDRR reads serve it. */
300 s->rx_len = dev->read(dev->ctx, s->rx, (uint32_t)k_riic_dev_rx_max);
301 s->rx_pos = 0U;
302 s->rx_primed = false;
303 s->icsr2 |= (uint32_t)k_riic_icsr2_rdrf; /* RX data ready */
304 }
305}
306
318{
319 const uint8_t byte = (uint8_t)(value & (uint32_t)k_riic_byte_mask);
320 if (!s->addr_done) {
322 return;
323 }
324 if (!s->acked) {
325 return; /* NACKed address: swallow further writes until STOP */
326 }
328 if ((dev != nullptr) && (dev->write != nullptr)) {
329 dev->write(dev->ctx, byte);
330 }
331 /* Buffer empty again and the byte was accepted: TDRE + TEND for the next. */
332 s->icsr2 |= ((uint32_t)k_riic_icsr2_tdre | (uint32_t)k_riic_icsr2_tend);
333}
334
347{
348 if (!s->rx_primed) {
349 /* The controller-receive flow does one dummy ICDRR read to start the clock
350 * before the first real byte (HUM Ch 39.3.4). */
351 s->rx_primed = true;
352 return 0U;
353 }
354 uint8_t b = 0U;
355 if (s->rx_pos < s->rx_len) {
356 b = s->rx[s->rx_pos];
357 s->rx_pos++;
358 }
359 s->icsr2 |= (uint32_t)k_riic_icsr2_rdrf; /* keep RX-ready for the next byte */
360 return (uint32_t)b;
361}
362
374RA8_INTERNAL static void internal_riic_iccr2_write(riic_state_t* s, uint64_t off, uint32_t value)
375{
376 if ((value & ((uint32_t)k_riic_iccr2_st | (uint32_t)k_riic_iccr2_rs)) != 0U) {
378 /* ST / RS auto-clear once the condition is issued; the driver spins on RS
379 * reading 0 after a repeated-START, so drop both request bits. */
380 s->reg[off] = (uint8_t)(value & ~((uint32_t)k_riic_iccr2_st | (uint32_t)k_riic_iccr2_rs));
381 } else if ((value & (uint32_t)k_riic_iccr2_sp) != 0U) {
383 s->reg[off] = (uint8_t)(value & ~(uint32_t)k_riic_iccr2_sp);
384 }
385}
386
387/* =============================================================================
388 * RIIC target (peripheral) model -- ra8_emulator is the synthetic external
389 * controller, driving a write-then-read script at the firmware's own address so
390 * the real ra8_i2c_peripheral_* driver (receive / transmit / dispatch) runs.
391 * =============================================================================
392 */
393
404{
405 s->tgt_phase = (uint8_t)k_riic_tgt_write;
406 s->tgt_wr_pos = 0U;
407 s->tgt_icsr2 = (uint32_t)k_riic_icsr2_rdrf; /* address + first data byte ready */
408}
409
420{
421 s->tgt_phase = (uint8_t)k_riic_tgt_read;
422 s->tgt_rd_len = 0U;
423 s->tgt_icsr2 = (uint32_t)k_riic_icsr2_tdre | (uint32_t)k_riic_icsr2_tend;
424}
425
436{
437 bool ok = (s->tgt_rd_len == (uint32_t)k_riic_tgt_payload_len);
438 for (uint32_t i = 0U; i < (uint32_t)k_riic_tgt_payload_len; i++) {
439 if (s->tgt_rd[i] != s_k_riic_tgt_payload[i]) {
440 ok = false;
441 }
442 }
443 if (!ok) {
444 s->tgt_echo_bad = true;
445 }
446 s->tgt_cycles++;
447 if (s->tgt_cycles < (uint32_t)k_riic_tgt_cycles) {
449 } else {
450 s->tgt_phase = (uint8_t)k_riic_tgt_done;
451 s->tgt_icsr2 = 0U; /* no match, no STOP: dispatch reports no event forever. */
452 }
453}
454
466{
467 if ((icser & (uint32_t)k_riic_icser_slots) == 0U) {
468 s->tgt_armed = false;
469 s->tgt_phase = (uint8_t)k_riic_tgt_idle;
470 return;
471 }
472 uint8_t sarl = s->reg[k_riic_off_sarl0];
473 if ((icser & (uint32_t)k_riic_icser_sar1e) != 0U) {
474 sarl = s->reg[k_riic_off_sarl1];
475 } else if ((icser & (uint32_t)k_riic_icser_sar2e) != 0U) {
476 sarl = s->reg[k_riic_off_sarl2];
477 }
478 s->tgt_own_addr = (uint8_t)((uint32_t)sarl >> (uint32_t)k_riic_addr_shift);
479 s->tgt_armed = true;
481}
482
495{
496 if (s->tgt_phase == (uint8_t)k_riic_tgt_write) {
497 return (uint32_t)k_riic_icsr1_aas0;
498 }
499 if (s->tgt_phase == (uint8_t)k_riic_tgt_read) {
500 return (uint32_t)k_riic_icsr1_aas0;
501 }
502 return 0U;
503}
504
517{
518 uint32_t v = (uint32_t)s->reg[k_riic_off_iccr2] & ~(uint32_t)k_riic_iccr2_trs;
519 if (s->tgt_phase == (uint8_t)k_riic_tgt_read) {
520 v |= (uint32_t)k_riic_iccr2_trs;
521 }
522 return v;
523}
524
537{
538 if (s->tgt_phase != (uint8_t)k_riic_tgt_write) {
539 return 0U; /* read-phase SCL-release dummy read / idle: no receive data. */
540 }
541 uint8_t b = 0U;
542 if (s->tgt_wr_pos == 0U) {
543 /* Step 1: the matched address byte the driver dummy-reads to discard. */
544 b = (uint8_t)((uint32_t)s->tgt_own_addr << (uint32_t)k_riic_addr_shift);
545 } else if (s->tgt_wr_pos <= (uint32_t)k_riic_tgt_payload_len) {
546 b = s_k_riic_tgt_payload[s->tgt_wr_pos - 1U];
547 }
548 s->tgt_wr_pos++;
549 if (s->tgt_wr_pos > (uint32_t)k_riic_tgt_payload_len) {
550 s->tgt_icsr2 = (uint32_t)k_riic_icsr2_stop; /* all served: STOP, drop RDRF. */
551 } else {
552 s->tgt_icsr2 = (uint32_t)k_riic_icsr2_rdrf;
553 }
554 return (uint32_t)b;
555}
556
568{
569 if (s->tgt_phase != (uint8_t)k_riic_tgt_read) {
570 return;
571 }
572 if (s->tgt_rd_len < (uint32_t)k_riic_tgt_cap) {
573 s->tgt_rd[s->tgt_rd_len] = byte;
574 }
575 s->tgt_rd_len++;
576 /* TDRE|TEND stay asserted (begin_read) so fill_tx keeps pushing to completion. */
577}
578
590{
591 s->tgt_icsr2 &= value; /* condition flags are write-0-to-clear. */
592 if (s->tgt_phase == (uint8_t)k_riic_tgt_write) {
593 internal_riic_target_begin_read(s); /* receive() cleared STOP -> controller now reads. */
594 } else if (s->tgt_phase == (uint8_t)k_riic_tgt_read) {
595 internal_riic_target_complete_read(s); /* finish_tx cleared NACKF/STOP -> cycle done. */
596 }
597}
598
612{
613 if (off == (uint64_t)k_riic_off_icsr1) {
615 }
616 if (off == (uint64_t)k_riic_off_icsr2) {
617 return s->tgt_icsr2;
618 }
619 if (off == (uint64_t)k_riic_off_iccr2) {
621 }
622 if (off == (uint64_t)k_riic_off_icdrr) {
624 }
625 return s->reg[off]; /* reflect every other register */
626}
627
640RA8_INTERNAL static uint64_t internal_riic_reg_read(riic_state_t* s, uint64_t off)
641{
642 if (s->tgt_armed) {
643 return internal_riic_target_reg_read(s, off);
644 }
645 if (off == (uint64_t)k_riic_off_icsr2) {
646 return s->icsr2;
647 }
648 if (off == (uint64_t)k_riic_off_iccr2) {
649 /* BBSY tracks an open transaction; the request bits already read back 0. */
650 uint32_t v = s->reg[off] & ~(uint32_t)k_riic_iccr2_bbsy;
651 if (s->busy) {
652 v |= (uint32_t)k_riic_iccr2_bbsy;
653 }
654 return v;
655 }
656 if (off == (uint64_t)k_riic_off_icdrr) {
657 return internal_riic_icdrr_read(s);
658 }
659 return s->reg[off]; /* reflect every other register */
660}
661
673RA8_INTERNAL static void internal_riic_reg_write(riic_state_t* s, uint64_t off, uint32_t value)
674{
675 s->reg[off] = (uint8_t)(value & (uint32_t)k_riic_byte_mask);
676 if (off == (uint64_t)k_riic_off_icser) {
677 /* ICSER arms / disarms the own-address responder; it is the target trigger. */
679 return;
680 }
681 if (s->tgt_armed) {
682 if (off == (uint64_t)k_riic_off_icdrt) {
683 internal_riic_target_icdrt(s, (uint8_t)(value & (uint32_t)k_riic_byte_mask));
684 } else if (off == (uint64_t)k_riic_off_icsr2) {
686 }
687 return;
688 }
689 if (off == (uint64_t)k_riic_off_iccr2) {
690 internal_riic_iccr2_write(s, off, value);
691 } else if (off == (uint64_t)k_riic_off_icdrt) {
693 } else if (off == (uint64_t)k_riic_off_icsr2) {
694 /* Condition / fault flags are write-0-to-clear: keep only the model's
695 * internal flags whose bit is still written as 1 by the driver's RMW. */
696 s->icsr2 &= value;
697 }
698}
699
713RA8_INTERNAL static uint64_t internal_riic_read(uc_engine* uc, uint64_t addr, unsigned size)
714{
715 (void)uc;
716 (void)size;
717 const uint32_t ch = (uint32_t)((addr - (uint64_t)k_riic_base) / (uint64_t)k_riic_stride);
718 const uint64_t off = (addr - (uint64_t)k_riic_base) % (uint64_t)k_riic_stride;
719 if (off >= (uint64_t)k_riic_reg_bytes) {
720 return 0U; /* outside the modelled register file */
721 }
722 return internal_riic_reg_read(&s_riic[ch], off);
723}
724
737RA8_INTERNAL static void
738internal_riic_write(uc_engine* uc, uint64_t addr, unsigned size, uint64_t value)
739{
740 (void)uc;
741 (void)size;
742 const uint32_t ch = (uint32_t)((addr - (uint64_t)k_riic_base) / (uint64_t)k_riic_stride);
743 const uint64_t off = (addr - (uint64_t)k_riic_base) % (uint64_t)k_riic_stride;
744 if (off >= (uint64_t)k_riic_reg_bytes) {
745 return; /* outside the modelled register file */
746 }
747 internal_riic_reg_write(&s_riic[ch], off, (uint32_t)value);
748}
749
759{
760 for (uint32_t i = 0U; i < (uint32_t)k_riic_count; i++) {
761 s_riic[i] = (riic_state_t){};
762 }
764}
765
775{
777 for (uint32_t ch = 0U; ch < (uint32_t)k_riic_count; ch++) {
778 if (s_riic[ch].tgt_cycles > 0U) {
779 (void)priv_emu_io_errf(" RIIC target : own 0x%02X serviced %u controller write+read "
780 "cycle(s), echo=%s\n",
781 (unsigned)s_riic[ch].tgt_own_addr,
782 (unsigned)s_riic[ch].tgt_cycles,
783 s_riic[ch].tgt_echo_bad ? "MISMATCH" : "OK");
784 }
785 }
786}
787
790 .base = (uint64_t)k_riic_base,
791 .span = (uint64_t)k_riic_span,
792 .order = (uint32_t)k_block_order_i2c,
793 .read = internal_riic_read,
795 .tick = nullptr,
796 .reset = internal_riic_reset,
797 .report = internal_riic_report,
798 .name = "RIIC+PI4IOE",
799};
800
Multi-channel console log store backing the board view's tabbed console.
void board_console_push(board_console_ch_t ch, const char *line)
Append one completed line to a channel ring and the ALL ring.
@ k_board_console_ch_i2c
I2C (IIC_B + RIIC) transfer summaries.
Decentralized peripheral-block registry for the board emulator core.
void board_periph_register_block(const board_periph_block_t *block)
Register a peripheral block's descriptor with the core registry.
@ k_block_order_i2c
I3C/I2C + GT911 (no tick today).
riic_addr_t
I2C address-byte layout on the wire (addr<<1 | R/W).
@ k_riic_addr_shift
7-bit address occupies bits [7:1].
@ k_riic_addr_rnw
LSB: 1 == read, 0 == write.
@ k_riic_dev_rx_max
Per-read device response staging cap.
@ k_riic_addr_mask7
7-bit target-address mask.
@ k_riic_byte_mask
One data byte.
static uint32_t internal_riic_target_iccr2(const riic_state_t *s)
ICCR2 read in target mode: assert TRS only while the controller reads.
riic_icser_bit_t
ICSER (status enable) own-address slot-enable bits (ra8_i2c_regs.h).
@ k_riic_icser_sar0e
SAR0E: own-address slot 0 enable (bit 0).
@ k_riic_icser_slots
Any own-address slot enabled (SARyE).
@ k_riic_icser_sar1e
SAR1E: own-address slot 1 enable (bit 1).
@ k_riic_icser_sar2e
SAR2E: own-address slot 2 enable (bit 2).
static void internal_riic_target_open(riic_state_t *s, uint32_t icser)
(Dis)arm target mode on an ICSER write; latch the firmware's own address.
static void internal_riic_close_transfer(riic_state_t *s)
Close a transaction (STOP): release the bus and notify the device.
riic_icsr2_bit_t
ICSR2 (status 2) flags the driver polls / clears (ra8_i2c_regs.h).
@ k_riic_icsr2_start
START: start-condition detected (bit 2).
@ k_riic_icsr2_rdrf
RDRF: receive data full (bit 5).
@ k_riic_icsr2_tmof
TMOF: timeout detected (bit 0).
@ k_riic_icsr2_nackf
NACKF: NACK detected (bit 4).
@ k_riic_icsr2_tdre
TDRE: transmit data empty (bit 7).
@ k_riic_icsr2_tend
TEND: transmit end (bit 6).
@ k_riic_icsr2_stop
STOP: stop-condition detected (bit 3).
@ k_riic_icsr2_al
AL: arbitration lost (bit 1).
static void internal_riic_reset(void)
Clear the RIIC channels + expander state and (re)populate the bus.
static void internal_riic_address_phase(riic_state_t *s, uint8_t address_byte)
Consume the address byte after a (re)START: select + ACK a device.
riic_tgt_stim_t
Target-mode synthetic-controller payload + script size.
@ k_riic_tgt_payload1
Second byte the synthetic controller writes.
@ k_riic_tgt_payload_len
Bytes per write (and expected echo length).
@ k_riic_tgt_cycles
Write+read cycles the stimulus drives.
@ k_riic_tgt_cap
Echo-capture buffer bound.
@ k_riic_tgt_payload0
First byte the synthetic controller writes.
static void internal_riic_open_transfer(riic_state_t *s)
Begin a transaction (START or repeated-START): arm the address phase.
riic_icsr1_bit_t
ICSR1 (status 1) own-address match flags (ra8_i2c_regs.h).
@ k_riic_icsr1_aas0
AAS0: own-address slot 0 matched (bit 0).
static uint64_t internal_riic_target_reg_read(riic_state_t *s, uint64_t off)
Register read while target mode is armed (own-address responder path).
static uint64_t internal_riic_reg_read(riic_state_t *s, uint64_t off)
Read a register from one modelled RIIC channel.
riic_map_t
RIIC block geometry (ra8_i2c_regs.h, byte-wide register file).
@ k_riic_off_iccr1
ICCR1 control 1 (ICE / IICRST).
@ k_riic_off_sarl2
SARL2 own-address low, slot 2.
@ k_riic_count
IIC0 / IIC1 / IIC2.
@ k_riic_span
All three channel windows.
@ k_riic_base
IIC0 base (channel 0).
@ k_riic_reg_bytes
Shadow byte count for one channel.
@ k_riic_off_icser
ICSER own-address enable (SARyE).
@ k_riic_off_icmr3
ICMR3 mode 3 (ACKWP/ACKBT/WAIT).
@ k_riic_off_icdrt
ICDRT transmit data register.
@ k_riic_off_sarl0
SARL0 own-address low, slot 0.
@ k_riic_stride
Bytes per RIIC channel.
@ k_riic_off_icsr2
ICSR2 status 2 (TDRE/TEND/...).
@ k_riic_off_iccr2
ICCR2 control 2 (ST/RS/SP/BBSY).
@ k_riic_off_icsr1
ICSR1 status 1 (AASy own-addr).
@ k_riic_off_sarl1
SARL1 own-address low, slot 1.
@ k_riic_off_icdrr
ICDRR receive data register.
static void internal_riic_report(void)
Print the PI4IOE line and any target-role responder activity.
static void internal_riic_target_icsr2_write(riic_state_t *s, uint32_t value)
ICSR2 W0C write in target mode: advance the write->read->done script.
static uint64_t internal_riic_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the RIIC window: route to the addressed channel.
riic_console_t
Console-tap line buffer capacity for a RIIC transaction summary.
@ k_riic_console_line_cap
Max chars in a "RIIC addr=.. .." line.
static void internal_riic_target_icdrt(riic_state_t *s, uint8_t byte)
ICDRT write in target mode: capture the firmware's echo byte.
riic_iccr2_bit_t
ICCR2 (control 2) bits the model acts on (ra8_i2c_regs.h).
@ k_riic_iccr2_st
ST: issue START (bit 1).
@ k_riic_iccr2_bbsy
BBSY: bus-busy flag, RO (bit 7).
@ k_riic_iccr2_rs
RS: issue repeated-START (bit 2).
@ k_riic_iccr2_sp
SP: issue STOP (bit 3).
@ k_riic_iccr2_trs
TRS: transmit/receive mode (bit 5).
@ k_riic_iccr2_mst
MST: controller/peripheral (bit 6).
static const uint8_t s_k_riic_tgt_payload[k_riic_tgt_payload_len]
The synthetic controller's write payload (echoed back on read).
static uint32_t internal_riic_target_icdrr(riic_state_t *s)
ICDRR read in target mode: serve the address byte, then the payload.
static void internal_riic_target_complete_read(riic_state_t *s)
Close one cycle: verify the echo, then loop the script or quiesce the bus.
static void internal_riic_reg_write(riic_state_t *s, uint64_t off, uint32_t value)
Write a register on one modelled RIIC channel.
static void internal_board_periph_riic_register(void)
Self-register the RIIC block before main runs (decentralized).
static const board_periph_block_t s_k_riic_block
This block's descriptor (static lifetime; the core keeps the pointer).
static void internal_riic_icdrt_write(riic_state_t *s, uint32_t value)
Handle a write to ICDRT (address byte, then controller TX payload).
static void internal_riic_target_begin_read(riic_state_t *s)
Arm the read phase: present transmit-ready + transmit-end for the echo.
static void internal_riic_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the RIIC window: route to the addressed channel.
riic_tgt_phase_t
RIIC target (peripheral) role: phases + synthetic external controller.
@ k_riic_tgt_read
Controller is reading the echo (TDRE/TEND).
@ k_riic_tgt_done
Script complete; the bus is quiet (no match).
@ k_riic_tgt_write
Controller is writing the payload (RDRF/STOP).
@ k_riic_tgt_idle
No own address armed; target model inert.
static void internal_riic_target_begin_write(riic_state_t *s)
Arm the write phase: present the address-match + receive-ready state.
static uint32_t internal_riic_icdrr_read(riic_state_t *s)
Serve one ICDRR read from the staged device response.
static void internal_riic_iccr2_write(riic_state_t *s, uint64_t off, uint32_t value)
Dispatch an ICCR2 write -> START / repeated-START / STOP.
static uint32_t internal_riic_target_icsr1(const riic_state_t *s)
ICSR1 read in target mode: assert the own-address match while active.
static riic_state_t s_riic[k_riic_count]
The three modelled RIIC controller channels.
Internal RIIC bus-device registry and board-device models.
riic_device_t * priv_riic_device_find(uint8_t addr_7b)
Find the registered RIIC device answering one 7-bit address.
void priv_riic_devices_reset(void)
Reset and repopulate the board's RIIC device registry.
void priv_riic_devices_report(void)
Report activity observed by the registered board devices.
Bounded raw-descriptor I/O seam for the RA8 emulator.
emu_io_result_t priv_emu_io_errf(const char *format,...)
Format bounded text and write it to the injected error descriptor.
-proof
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
static ra8_err_t internal_riic_read(void *ctx, uint8_t addr, uint8_t *data, uint32_t len)
RIIC backend: controller read.
static ra8_err_t internal_riic_write(void *ctx, uint8_t addr, const uint8_t *data, uint32_t len, bool send_stop)
RIIC backend: controller write.
A modelled peripheral block's self-description for the core registry.
One device registered on the modelled RIIC bus.
uint32_t(* read)(void *ctx, uint8_t *buf, uint32_t max)
Device->controller.
void(* stop)(void *ctx)
STOP/transfer end.
void(* write)(void *ctx, uint8_t byte)
Controller->device.
One RIIC channel: register shadow + a controller transfer machine.
bool rx_primed
The dummy first ICDRR read was consumed.
uint8_t tgt_phase
riic_tgt_phase_t of the current script.
uint8_t target_7b
7-bit address selected this transfer.
uint8_t tgt_rd[k_riic_tgt_cap]
Captured echo bytes (bounds-checked).
uint32_t tgt_icsr2
Target-role ICSR2 flags (RDRF/STOP/...).
uint8_t tgt_own_addr
Firmware's 7-bit own address (SARLy>>1).
uint32_t tgt_rd_len
Bytes the firmware transmitted this read.
uint32_t icsr2
ICSR2 flags (TDRE/TEND/RDRF/NACKF).
bool addr_done
Address phase of the (re)START done.
uint8_t rx[k_riic_dev_rx_max]
Staged device response for a read.
uint32_t tgt_wr_pos
ICDRR serves consumed this write (0=addr).
bool reading
Current transfer direction is read.
bool tgt_echo_bad
A firmware echo did not match the write.
uint32_t rx_len
Valid bytes in rx.
uint32_t tgt_cycles
Completed write+read cycles.
uint32_t rx_pos
Next byte index served from rx.
bool acked
The addressed target ACKed.
bool tgt_armed
Own address enabled (ICSER.SARyE set).
bool busy
True between START and STOP.
uint8_t reg[k_riic_reg_bytes]
Reflect-on-read register shadow.