|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
I2C Bus Interface (IIC) target (peripheral) role – polling mode. More...
#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_i2c.h"#include "ra8_i2c_internal.h"#include "ra8_i2c_regs.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_i2c_peripheral_limits_t : uint32_t { k_ra8_i2c_peripheral_poll_limit = 200000U } |
| Spin budgets and validation bounds for the target plane. More... | |
| enum | ra8_i2c_peripheral_const_t : uint8_t { k_ra8_i2c_peripheral_addr_7b_max = 0x7FU , k_ra8_i2c_peripheral_slot_max = 2U , k_ra8_i2c_peripheral_addr_shift = (uint8_t)k_ra8_i2c_sarl_sva_pos , k_ra8_i2c_peripheral_saru_7bit = 0U , k_ra8_i2c_peripheral_icier_arm } |
| Addressing constants for the target plane. More... | |
Functions | |
| bool | priv_ra8_i2c_internal_peripheral_poll_done (uint8_t icsr1, uint8_t icsr2) |
| Poll-exit predicate: an own-address match or a STOP was observed. | |
| bool | priv_ra8_i2c_internal_peripheral_rx_continue (uint8_t icsr2, uint32_t received, uint32_t capacity) |
| Receive-loop predicate: keep draining while no STOP and room remains. | |
| bool | priv_ra8_i2c_internal_peripheral_tx_done (uint8_t icsr2) |
| Transmit-completion predicate: the controller ended the read. | |
| bool | priv_ra8_i2c_internal_peripheral_tx_continue (uint8_t icsr2, uint32_t sent, uint32_t len) |
| Transmit-loop predicate: keep sending while no NACK and data remains. | |
| static ra8_i2c_peripheral_event_t | internal_i2c_target_classify (uint8_t icsr1, uint8_t iccr2) |
| Classify a latched address-match snapshot into a poll event. | |
| static ra8_err_t | internal_i2c_target_wait (volatile const r_i2c_regs_t *reg, uint8_t mask) |
| Wait (bounded) for a flag in ICSR2 to set. | |
| static void | internal_i2c_target_set_addr (volatile r_i2c_regs_t *reg, uint8_t slot, uint8_t addr_7b) |
| Programme a 7-bit own address into the SARLy/SARUy pair for a slot. | |
| static uint8_t | internal_i2c_target_icser_mask (uint8_t slot, bool general_call) |
| Build the ICSER enable mask for one own-address slot. | |
| ra8_err_t | priv_ra8_i2c_internal_target_drain_rx (volatile r_i2c_regs_t *reg, uint8_t *buf, uint32_t capacity, uint32_t *out_count) |
| Implementation of priv_ra8_i2c_internal_target_drain_rx() – trailing-byte ICDRR drain. | |
| static void | internal_i2c_target_fill_tx (volatile r_i2c_regs_t *reg, const uint8_t *data, uint32_t len, uint32_t *out_sent) |
| Push controller-read data bytes from data into ICDRT. | |
| static bool | internal_i2c_target_finish_tx (volatile r_i2c_regs_t *reg) |
| Close a target-transmit frame: wait for end, release SCL, clear flags. | |
| ra8_err_t | ra8_i2c_peripheral_init (uint8_t channel, const ra8_i2c_peripheral_cfg_t *cfg) |
| Arm an IIC channel to answer as an I2C target (peripheral). | |
| ra8_err_t | ra8_i2c_peripheral_deinit (uint8_t channel) |
| Disarm own-address matching, returning the channel to controller use. | |
| ra8_err_t | ra8_i2c_peripheral_poll (uint8_t channel, ra8_i2c_peripheral_event_t *out_event) |
| Wait (bounded) for a controller to address this target. | |
| ra8_err_t | ra8_i2c_peripheral_receive (uint8_t channel, uint8_t *buf, uint32_t capacity, uint32_t *out_received) |
| Drain a controller-write transaction into buf (target receive). | |
| ra8_err_t | ra8_i2c_peripheral_transmit (uint8_t channel, const uint8_t *data, uint32_t len, uint32_t *out_sent) |
| Answer a controller-read transaction from data (target transmit). | |
| static ra8_i2c_peripheral_event_t | internal_i2c_dispatch_event (uint8_t icsr1, uint8_t icsr2, uint8_t iccr2) |
| Classify an own-address / STOP status snapshot into a dispatch event. | |
| ra8_err_t | ra8_i2c_peripheral_attach_handler (uint8_t channel, ra8_i2c_peripheral_event_fn_t fn, void *ctx) |
| Attach (or detach) the address-match callback for a channel. | |
| void | ra8_i2c_peripheral_dispatch (uint8_t channel) |
| Snapshot the latched target status and fire the attached callback. | |
I2C Bus Interface (IIC) target (peripheral) role – polling mode.
Target-role plane of the RA8D2 RIIC polling driver, split out of ra8_i2c.c so the controller transfer plane stays under the file-size cap. Lets the RA8D2 answer a remote controller once one of its own-address slots matches. This driver uses the inclusive "target / peripheral" terminology for that role while keeping the HUM's register names (SARLy, AASy, ...) verbatim so cross-referencing the manual stays easy.
Mirrors FSP r_iic_slave collapsed into synchronous helpers – no DTC fast path and no interrupt path. Own-address matching, clock stretching and both transfer directions are implemented; the controller transfer plane in ra8_i2c.c and the bring-up plane in ra8_i2c_config.c are unchanged. Both planes share s_i2c_state and the log tag via ra8_i2c_internal.h.
Target-role state machine (synchronous reduction of HUM Ch 39.3.5 / 39.3.6):
* +-----------------------------------------------+ * | TARGET_IDLE | * | (peripheral mode, ICCR2.MST = 0, own-address | * | match armed in ICSER, AASy flags clear) | * +-----------------------------------------------+ * | poll: AASy/GCA set | poll: AASy/GCA set * | and ICCR2.TRS = 0 | and ICCR2.TRS = 1 * v (controller WRITE) v (controller READ) * +------------------+ +-------------------+ * | RX_ACTIVE | | TX_ACTIVE | * | dummy-read addr, | | push ICDRT while | * | read ICDRR while | | TDRE set and no | * | RDRF set and room| | NACK, until len | * +------------------+ +-------------------+ * | STOP or buffer full | NACK (controller end) * | (clear ICSR2.STOP) | or sent == len; wait * | | TEND, dummy-read ICDRR, * v v clear NACKF/STOP * +-----------------------------------------------+ * | TARGET_IDLE | * +-----------------------------------------------+ *
Owns every write to the RIIC own-address and target-transfer registers. See HUM Ch 39 "I2C Bus Interface (IIC)", p 2367-2444.
Definition in file ra8_i2c_peripheral.c.
| enum ra8_i2c_peripheral_const_t : uint8_t |
Addressing constants for the target plane.
Definition at line 80 of file ra8_i2c_peripheral.c.
| enum ra8_i2c_peripheral_limits_t : uint32_t |
Spin budgets and validation bounds for the target plane.
| Enumerator | |
|---|---|
| k_ra8_i2c_peripheral_poll_limit | Generic spin budget for status-flag polls, matching the controller plane: ~200k iterations keeps the worst-case stall under a few ms. |
Definition at line 70 of file ra8_i2c_peripheral.c.
|
static |
Classify an own-address / STOP status snapshot into a dispatch event.
Reduces the latched snapshot to a single ra8_i2c_peripheral_event_t. An own-address (or general-call) match decodes via ICCR2.TRS to read (controller reads -> target transmits) or write (controller writes -> target receives) through internal_i2c_target_classify. With no match a latched ICSR2.STOP decodes to stop; otherwise none. Match and STOP are mutually exclusive in hardware – the AASy flags clear on the STOP – so a match is tested first.
| [in] | icsr1 | Snapshot of ICSR1 (own-address detection flags). |
| [in] | icsr2 | Snapshot of ICSR2 (STOP detection flag). |
| [in] | iccr2 | Snapshot of ICCR2 (transmit/receive mode bit TRS). |
| k_ra8_i2c_peripheral_event_write | Match, controller writes. |
| k_ra8_i2c_peripheral_event_read | Match, controller reads. |
| k_ra8_i2c_peripheral_event_stop | No match but a STOP is latched. |
| k_ra8_i2c_peripheral_event_none | Neither a match nor a STOP. |
Definition at line 581 of file ra8_i2c_peripheral.c.
References internal_i2c_target_classify(), k_ra8_i2c_msk_icsr2_stop, k_ra8_i2c_peripheral_event_none, and k_ra8_i2c_peripheral_event_stop.
Referenced by ra8_i2c_peripheral_dispatch().
|
static |
Classify a latched address-match snapshot into a poll event.
Returns none when no own-address / general-call flag is set; otherwise decodes ICCR2.TRS, which the hardware sets to 1 when the controller's R/W# bit was 1 (controller read -> target transmit) and leaves 0 for a write.
| [in] | icsr1 | Snapshot of ICSR1 (own-address detection flags). |
| [in] | iccr2 | Snapshot of ICCR2 (transmit/receive mode bit TRS). |
| k_ra8_i2c_peripheral_event_none | No own-address match latched. |
| k_ra8_i2c_peripheral_event_read | Match and TRS = 1 (controller reads). |
| k_ra8_i2c_peripheral_event_write | Match and TRS = 0 (controller writes). |
Definition at line 151 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_msk_iccr2_trs, k_ra8_i2c_msk_icsr1_match, k_ra8_i2c_peripheral_event_none, k_ra8_i2c_peripheral_event_read, k_ra8_i2c_peripheral_event_write, and RA8_INTERNAL.
Referenced by internal_i2c_dispatch_event(), and ra8_i2c_peripheral_poll().
|
static |
Push controller-read data bytes from data into ICDRT.
The per-byte transmit loop extracted from ra8_i2c_peripheral_transmit. Each iteration waits for ICSR2.TDRE, then – while priv_ra8_i2c_internal_peripheral_tx_continue holds (no controller NACK and bytes remain) – writes one byte to ICDRT. Stops on NACK, on a TDRE timeout, or when every byte is queued. The loop is bounded by len + 1 (NASA P10 Rule 2). The completion status is left to internal_i2c_target_finish_tx.
| [in] | reg | Channel register block. |
| [in] | data | Source buffer. |
| [in] | len | Bytes available to send (non-zero). |
| [out] | out_sent | Number of bytes accepted by the controller. |
Definition at line 332 of file ra8_i2c_peripheral.c.
References r_i2c_regs_t::ICDRT, r_i2c_regs_t::ICSR2, internal_i2c_target_wait(), k_ra8_i2c_msk_icsr2_tdre, k_ra8_ok, priv_ra8_i2c_internal_peripheral_tx_continue(), and RA8_INTERNAL.
Referenced by ra8_i2c_peripheral_transmit().
|
static |
Close a target-transmit frame: wait for end, release SCL, clear flags.
Implements steps 4-7 of HUM Ch 39.3.5 p 2405: wait for the controller's TEND or NACK, snapshot whether the frame ended cleanly via priv_ra8_i2c_internal_peripheral_tx_done, dummy-read ICDRR to release SCL, then clear NACKF and STOP (W0C) for the next transfer.
| [in] | reg | Channel register block. |
| true | TEND or NACK was latched within the spin budget. |
| false | The end-of-frame poll timed out. |
Definition at line 378 of file ra8_i2c_peripheral.c.
References r_i2c_regs_t::ICDRR, r_i2c_regs_t::ICSR2, internal_i2c_target_wait(), k_ra8_i2c_msk_icsr2_nackf, k_ra8_i2c_msk_icsr2_stop, k_ra8_i2c_msk_icsr2_tend, priv_ra8_i2c_internal_peripheral_tx_done(), and RA8_INTERNAL.
Referenced by ra8_i2c_peripheral_transmit().
|
static |
Build the ICSER enable mask for one own-address slot.
SARyE for slot y is bit y of ICSER, so the slot enable is 1 << slot; GCAE is OR-ed in when the general-call address is also to be answered (HUM Ch 39.2.7 p 2380).
| [in] | slot | Own-address comparator slot (0, 1 or 2). |
| [in] | general_call | True to also enable general-call matching. |
| 0 | Never (at least one SARyE bit is always set). |
Definition at line 264 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_msk_icser_gcae, k_ra8_i2c_msk_icser_sar0e, and RA8_INTERNAL.
Referenced by ra8_i2c_peripheral_init().
|
static |
Programme a 7-bit own address into the SARLy/SARUy pair for a slot.
Writes addr_7b left-shifted into SARLy.SVA[6:0] and clears SARUy to select the 7-bit address format (HUM Ch 39.2.13 p 2390, Ch 39.2.14 p 2391). The three comparator slots are discrete registers, so a switch selects the pair rather than indexing.
| [in] | reg | Channel register block. |
| [in] | slot | Own-address comparator slot (0, 1 or 2). |
| [in] | addr_7b | 7-bit own address (already range-checked). |
Definition at line 218 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_peripheral_addr_shift, k_ra8_i2c_peripheral_saru_7bit, k_ra8_i2c_peripheral_slot_0, k_ra8_i2c_peripheral_slot_1, r_i2c_regs_t::SARL0, r_i2c_regs_t::SARL1, r_i2c_regs_t::SARL2, r_i2c_regs_t::SARU0, r_i2c_regs_t::SARU1, and r_i2c_regs_t::SARU2.
Referenced by ra8_i2c_peripheral_init().
|
static |
Wait (bounded) for a flag in ICSR2 to set.
Spins up to k_ra8_i2c_peripheral_poll_limit iterations reading ICSR2 and returning success the moment the masked flag is observed set. The fixed bound satisfies NASA P10 Rule 2.
| [in] | reg | Channel register block. |
| [in] | mask | Bit mask to test against ICSR2. |
| k_ra8_ok | Masked flag observed set. |
| k_ra8_err_hw_timeout | Spin budget exhausted before the flag set. |
Definition at line 185 of file ra8_i2c_peripheral.c.
References r_i2c_regs_t::ICSR2, k_ra8_err_hw_timeout, k_ra8_i2c_peripheral_poll_limit, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_i2c_target_fill_tx(), internal_i2c_target_finish_tx(), priv_ra8_i2c_internal_target_drain_rx(), and ra8_i2c_peripheral_receive().
| bool priv_ra8_i2c_internal_peripheral_poll_done | ( | uint8_t | icsr1, |
| uint8_t | icsr2 ) |
Poll-exit predicate: an own-address match or a STOP was observed.
Drives the bounded wait in ra8_i2c_peripheral_poll. The match flags come from ICSR1 (AAS0/1/2, GCA); STOP comes from ICSR2. Promoted so the OR can be exercised with independent influence under MC/DC.
| [in] | icsr1 | Snapshot of ICSR1 (own-address detection flags). |
| [in] | icsr2 | Snapshot of ICSR2 (STOP detection flag). |
| true | An own-address match or a STOP condition is latched. |
| false | Neither – keep spinning. |
Definition at line 99 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_msk_icsr1_match, and k_ra8_i2c_msk_icsr2_stop.
Referenced by ra8_i2c_peripheral_poll().
| bool priv_ra8_i2c_internal_peripheral_rx_continue | ( | uint8_t | icsr2, |
| uint32_t | received, | ||
| uint32_t | capacity ) |
Receive-loop predicate: keep draining while no STOP and room remains.
Drives the per-byte loop in ra8_i2c_peripheral_receive. Promoted so the AND can be exercised with independent influence under MC/DC.
| [in] | icsr2 | Snapshot of ICSR2 (STOP detection flag). |
| [in] | received | Bytes stored so far. |
| [in] | capacity | Destination buffer size. |
| true | No STOP latched and received < capacity. |
| false | A STOP is latched or the buffer is full. |
Definition at line 105 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_msk_icsr2_stop.
Referenced by priv_ra8_i2c_internal_target_drain_rx().
| bool priv_ra8_i2c_internal_peripheral_tx_continue | ( | uint8_t | icsr2, |
| uint32_t | sent, | ||
| uint32_t | len ) |
Transmit-loop predicate: keep sending while no NACK and data remains.
Drives the per-byte loop in ra8_i2c_peripheral_transmit. Promoted so the AND can be exercised with independent influence under MC/DC.
| [in] | icsr2 | Snapshot of ICSR2 (NACKF detection flag). |
| [in] | sent | Bytes accepted by the controller so far. |
| [in] | len | Number of bytes available to send. |
| true | No NACK latched and sent < len. |
| false | The controller NACKed or all bytes are queued. |
Definition at line 118 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_msk_icsr2_nackf.
Referenced by internal_i2c_target_fill_tx().
| bool priv_ra8_i2c_internal_peripheral_tx_done | ( | uint8_t | icsr2 | ) |
Transmit-completion predicate: the controller ended the read.
Used by ra8_i2c_peripheral_transmit after the data loop to confirm the frame closed cleanly. Promoted so the OR can be exercised under MC/DC.
| [in] | icsr2 | Snapshot of ICSR2 (NACKF and TEND flags). |
| true | NACKF or TEND is latched. |
| false | Neither – transmission is still in progress. |
Definition at line 112 of file ra8_i2c_peripheral.c.
References k_ra8_i2c_msk_icsr2_nackf, and k_ra8_i2c_msk_icsr2_tend.
Referenced by internal_i2c_target_finish_tx().
| ra8_err_t priv_ra8_i2c_internal_target_drain_rx | ( | volatile r_i2c_regs_t * | reg, |
| uint8_t * | buf, | ||
| uint32_t | capacity, | ||
| uint32_t * | out_count ) |
Implementation of priv_ra8_i2c_internal_target_drain_rx() – trailing-byte ICDRR drain.
Drain controller-write data bytes from ICDRR into buf.
Definition at line 274 of file ra8_i2c_peripheral.c.
References r_i2c_regs_t::ICDRR, r_i2c_regs_t::ICSR2, internal_i2c_target_wait(), k_ra8_i2c_msk_icsr2_rdrf, k_ra8_i2c_msk_icsr2_stop, k_ra8_ok, and priv_ra8_i2c_internal_peripheral_rx_continue().
Referenced by ra8_i2c_peripheral_receive().
|
nodiscard |
Attach (or detach) the address-match callback for a channel.
Stores fn and ctx in the channel's driver state so a later ra8_i2c_peripheral_dispatch can fire the callback when a controller addresses this target or a STOP ends a transaction. Pass fn == NULL to detach; dispatch then becomes a no-op for the channel. The handler is independent of ra8_i2c_peripheral_poll, which never consults it.
| [in] | channel | Channel index (0, 1 or 2). |
| [in] | fn | Callback to fire on a decoded event, or NULL to detach. |
| [in] | ctx | Opaque context passed back to fn (may be NULL). |
| k_ra8_ok | Handler stored for the channel. |
| k_ra8_err_invalid_arg | channel out of range. |
Definition at line 594 of file ra8_i2c_peripheral.c.
References k_ra8_err_invalid_arg, k_ra8_i2c_channel_count, k_ra8_ok, and s_i2c_state.
Referenced by riic_target_arm().
|
nodiscard |
Disarm own-address matching, returning the channel to controller use.
| [in] | channel | Channel index. |
| k_ra8_ok | ICSER cleared, WAIT released. |
| k_ra8_err_invalid_arg | channel out of range. |
| k_ra8_err_not_initialized | Target role was not armed for this channel. |
Definition at line 435 of file ra8_i2c_peripheral.c.
References r_i2c_regs_t::ICIER, r_i2c_regs_t::ICMR3, r_i2c_regs_t::ICSER, k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_i2c_msk_icmr3_wait, k_ra8_i2c_peripheral_icier_arm, k_ra8_ok, ra8_i2c_regs(), and s_i2c_state.
| void ra8_i2c_peripheral_dispatch | ( | uint8_t | channel | ) |
Snapshot the latched target status and fire the attached callback.
Reads ICSR1 (own-address match flags), ICSR2 (STOP) and ICCR2 (TRS) once, classifies them into an ra8_i2c_peripheral_event_t (an own-address match decodes to write / read from TRS; otherwise a latched STOP decodes to stop), and – when the event is not none and a handler is attached – invokes the handler with the registered context. Read-only with respect to the bus: it clears no flags and queues no data, leaving the data-phase flag handling to ra8_i2c_peripheral_receive / ra8_i2c_peripheral_transmit the handler calls. Safe to call from the RIIC RXI / TXI / STPI ISR or a poll loop; a no-op when the channel is invalid, not armed, or has no handler.
| [in] | channel | Channel index (0, 1 or 2). |
Definition at line 605 of file ra8_i2c_peripheral.c.
References r_i2c_regs_t::ICCR2, r_i2c_regs_t::ICSR1, r_i2c_regs_t::ICSR2, internal_i2c_dispatch_event(), k_ra8_i2c_peripheral_event_none, ra8_i2c_regs(), and s_i2c_state.
Referenced by main().
|
nodiscard |
Arm an IIC channel to answer as an I2C target (peripheral).
Programmes one own-address slot (SARLy = own_addr_7b << 1 in 7-bit format, SARUy = 0) and enables the matching ICSER.SARyE bit, plus ICSER.GCAE when general_call is set, so the hardware raises ICSR1.AASy / ICSR1.GCA on a matching address (HUM Ch 39.2.7 p 2380, Ch 39.2.9 p 2382, Ch 39.2.13 p 2390). When clock_stretch is set, ICMR3.WAIT is armed so SCL is held low between the ninth and first clocks until the byte is serviced. When irq_enable is set, ICIER's RIE / TIE / SPIE bits are armed so the RIIC RXI / TXI / STPI interrupts fire on an own-address match and a STOP; wire those vectors to ra8_i2c_peripheral_dispatch. The channel stays in peripheral mode (ICCR2.MST = 0) until a matching address arrives.
| [in] | channel | Channel index (0, 1 or 2). |
| [in] | cfg | Configuration descriptor (non-NULL). |
| k_ra8_ok | Own-address slot armed. |
| k_ra8_err_null_ptr | cfg is NULL or channel invalid. |
| k_ra8_err_invalid_arg | own_addr_7b > 0x7F or slot out of range. |
Definition at line 403 of file ra8_i2c_peripheral.c.
References ra8_i2c_peripheral_cfg_t::clock_stretch, g_i2c_tag, ra8_i2c_peripheral_cfg_t::general_call, r_i2c_regs_t::ICIER, r_i2c_regs_t::ICMR3, r_i2c_regs_t::ICSER, internal_i2c_target_icser_mask(), internal_i2c_target_set_addr(), ra8_i2c_peripheral_cfg_t::irq_enable, k_ra8_err_invalid_arg, k_ra8_i2c_msk_icmr3_wait, k_ra8_i2c_peripheral_addr_7b_max, k_ra8_i2c_peripheral_icier_arm, k_ra8_i2c_peripheral_slot_max, k_ra8_ok, ra8_i2c_peripheral_cfg_t::own_addr_7b, RA8_CHECK_NULL_PTR, ra8_i2c_regs(), s_i2c_state, and ra8_i2c_peripheral_cfg_t::slot.
Referenced by riic_target_arm().
|
nodiscard |
Wait (bounded) for a controller to address this target.
Spins on ICSR1 / ICSR2 until an own-address match or a STOP is observed, then classifies the transaction from ICSR1 (match flags) and ICCR2.TRS: write when the controller will send data (target receives), read when the controller will clock data out (target transmits). Returns none if the bounded spin elapses without a match.
State machine: IDLE --match,R/W=0--> (write) --match,R/W=1--> (read).
| [in] | channel | Channel index. |
| [out] | out_event | Decoded event (non-NULL). |
| k_ra8_ok | *out_event populated (may be none). |
| k_ra8_err_null_ptr | out_event NULL or channel invalid. |
| k_ra8_err_not_initialized | Target role not armed for this channel. |
Definition at line 454 of file ra8_i2c_peripheral.c.
References g_i2c_tag, r_i2c_regs_t::ICCR2, r_i2c_regs_t::ICSR1, r_i2c_regs_t::ICSR2, internal_i2c_target_classify(), k_ra8_err_not_initialized, k_ra8_i2c_peripheral_event_none, k_ra8_i2c_peripheral_poll_limit, k_ra8_ok, priv_ra8_i2c_internal_peripheral_poll_done(), RA8_CHECK_NULL_PTR, ra8_i2c_regs(), and s_i2c_state.
|
nodiscard |
Drain a controller-write transaction into buf (target receive).
Mirrors HUM Ch 39.3.6 "Peripheral Receive Operation" p 2408: dummy-read ICDRR to discard the matched address byte, then read each data byte from ICDRR as ICSR2.RDRF sets, stopping when ICSR2.STOP is detected or buf fills. Clears ICSR2.STOP before returning. Clock stretching (if armed) gives the loop time to read each byte before the controller clocks the next.
State machine: RX_ACTIVE --RDRF--> store byte ... --STOP|full--> IDLE.
| [in] | channel | Channel index. |
| [out] | buf | Destination buffer (non-NULL). |
| [in] | capacity | Buffer size in bytes (non-zero). |
| [out] | out_received | Number of bytes stored (non-NULL). |
| k_ra8_ok | Bytes received (possibly zero) up to STOP. |
| k_ra8_err_null_ptr | buf / out_received NULL or channel invalid. |
| k_ra8_err_invalid_arg | capacity is zero. |
| k_ra8_err_not_initialized | Target role not armed. |
| k_ra8_err_hw_timeout | No byte arrived within the spin budget. |
Definition at line 483 of file ra8_i2c_peripheral.c.
References g_i2c_tag, r_i2c_regs_t::ICDRR, r_i2c_regs_t::ICSR2, internal_i2c_target_wait(), k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_i2c_msk_icsr2_rdrf, k_ra8_i2c_msk_icsr2_stop, k_ra8_ok, priv_ra8_i2c_internal_target_drain_rx(), RA8_CHECK_NULL_PTR, ra8_i2c_regs(), and s_i2c_state.
Referenced by riic_target_on_event().
|
nodiscard |
Answer a controller-read transaction from data (target transmit).
Mirrors HUM Ch 39.3.5 "Peripheral Transmit Operation" p 2405: push each byte to ICDRT as ICSR2.TDRE sets, stopping when the controller NACKs the last byte it wants (ICSR2.NACKF) or the buffer is exhausted, then waits for TEND / NACKF, dummy-reads ICDRR to release SCL, and clears NACKF / STOP.
State machine: TX_ACTIVE --TDRE--> push byte ... --NACK|sent==len--> IDLE.
| [in] | channel | Channel index. |
| [in] | data | Source buffer (non-NULL). |
| [in] | len | Bytes available to send (non-zero). |
| [out] | out_sent | Number of bytes the controller accepted (non-NULL). |
| k_ra8_ok | Transmit completed (controller NACK is a normal end-of-read, not an error). |
| k_ra8_err_null_ptr | data / out_sent NULL or channel invalid. |
| k_ra8_err_invalid_arg | len is zero. |
| k_ra8_err_not_initialized | Target role not armed. |
| k_ra8_err_hw_timeout | TDRE never armed before any byte was sent. |
Definition at line 519 of file ra8_i2c_peripheral.c.
References g_i2c_tag, internal_i2c_target_fill_tx(), internal_i2c_target_finish_tx(), k_ra8_err_hw_timeout, k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_i2c_regs(), and s_i2c_state.
Referenced by riic_target_on_event().