|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
I2C Bus Interface (IIC) bring-up, clock and error-status plane. 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"#include "ra8_log.h"#include "ra8_mstp.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_i2c_brate_t : uint32_t { k_ra8_i2c_br_field_max = 0x1FU , k_ra8_i2c_br_reserved_hi = 0xE0U , k_ra8_i2c_cks_max = 7U , k_ra8_i2c_period_split = 2U } |
| Bit-rate divider field limits (HUM Ch 39.2.15 / 39.2.16). More... | |
Functions | |
| static ra8_mstp_t | internal_i2c_mstp_id (uint8_t channel) |
| Map a channel index to its MSTP gate id. | |
| static uint8_t | internal_i2c_pick_cks (uint32_t *total) |
| Pick the smallest CKS divider and divide *total to match. | |
| static uint8_t | internal_i2c_clamp_half (uint32_t total) |
| Clamp one SCL half-period count to the 5-bit BR field. | |
| static ra8_err_t | internal_i2c_bitrate (uint32_t bus_hz, uint32_t pclkb_hz, uint8_t *out_cks, uint8_t *out_brh, uint8_t *out_brl) |
| Compute the CKS divider and ICBRH/ICBRL half-period counts. | |
| static uint8_t | internal_i2c_decode_errors (uint8_t icsr2) |
| Decode latched ICSR2 error bits into a k_ra8_i2c_err_* mask. | |
| static void | internal_i2c_apply_init_regs (volatile r_i2c_regs_t *reg, uint8_t cks, uint8_t brh, uint8_t brl, bool fast_plus) |
| Apply the bring-up register sequence for an IIC channel. | |
| ra8_err_t | ra8_i2c_init (uint8_t channel, const ra8_i2c_cfg_t *cfg) |
| Initialise an IIC channel as a controller and bring the bus up. | |
| ra8_err_t | ra8_i2c_deinit (uint8_t channel) |
| Tear down an IIC channel. | |
| ra8_err_t | ra8_i2c_set_clock (uint8_t channel, uint32_t bus_hz, uint32_t pclkb_hz) |
| Update the bus clock without tearing the channel down. | |
| ra8_err_t | ra8_i2c_get_errors (uint8_t channel, uint8_t *out_mask) |
| Read latched error flags from ICSR2 (AL / NACKF / TMOF). | |
| ra8_err_t | ra8_i2c_clear_errors (uint8_t channel) |
| Clear latched error flags in ICSR2. | |
I2C Bus Interface (IIC) bring-up, clock and error-status plane.
Configuration-plane half of the RA8D2 RIIC polling driver, split out of ra8_i2c.c to keep each translation unit under the file-size cap. Owns the init / deinit / bit-rate sequence (HUM Ch 39.3.2 "Initial Settings" p 2395), the runtime clock re-program (ra8_i2c_set_clock) and the error-status helpers (ra8_i2c_get_errors / ra8_i2c_clear_errors).
The data-transfer plane (start / write / read / stop / scan) lives in ra8_i2c.c. Both translation units share s_i2c_state and the log tag via ra8_i2c_internal.h.
Owns every write to the RIIC register block performed during channel bring-up and clock setup. See HUM Ch 39 "I2C Bus Interface (IIC)", p 2367-2470.
Definition in file ra8_i2c_config.c.
| enum ra8_i2c_brate_t : uint32_t |
Bit-rate divider field limits (HUM Ch 39.2.15 / 39.2.16).
Definition at line 43 of file ra8_i2c_config.c.
|
static |
Apply the bring-up register sequence for an IIC channel.
Follows HUM Ch 39.3.2 p 2395: hold IIC reset (ICCR1.IICRST with ICE = 0), enable internal reset (ICE = 1), program CKS / ICBRL / ICBRH and the ICFER function bits, then release the reset. FMPE is set for the Fast-mode Plus (>= 1 MHz) bus rate.
| [in] | reg | Channel register block. |
| [in] | cks | CKS divider exponent. |
| [in] | brh | ICBRH register value. |
| [in] | brl | ICBRL register value. |
| [in] | fast_plus | True when the bus runs at Fast-mode Plus. |
Definition at line 270 of file ra8_i2c_config.c.
References r_i2c_regs_t::ICBRH, r_i2c_regs_t::ICBRL, r_i2c_regs_t::ICCR1, r_i2c_regs_t::ICFER, r_i2c_regs_t::ICMR1, k_ra8_i2c_icmr1_cks_pos, k_ra8_i2c_msk_iccr1_ice, k_ra8_i2c_msk_iccr1_iicrst, k_ra8_i2c_msk_icfer_fmpe, k_ra8_i2c_msk_icfer_male, k_ra8_i2c_msk_icfer_nacke, k_ra8_i2c_msk_icfer_scle, and RA8_INTERNAL.
Referenced by ra8_i2c_init().
|
static |
Compute the CKS divider and ICBRH/ICBRL half-period counts.
The RIIC internal reference clock is IICphi = PCLKB / 2^CKS (HUM Ch 39.2.3 p 2374). One SCL bit period is (BRH + 1) + (BRL + 1) IICphi cycles for the SCLE=0 / NFE=0 transfer-rate expression (HUM Ch 39.2.16 expression (1) p 2392). Delegates the CKS search and field clamp to internal_i2c_pick_cks / internal_i2c_clamp_half.
| [in] | bus_hz | Target bus clock (non-zero). |
| [in] | pclkb_hz | PCLKB frequency (non-zero). |
| [out] | out_cks | CKS exponent [0..7]. |
| [out] | out_brh | ICBRH register value (5-bit count + reserved hi). |
| [out] | out_brl | ICBRL register value (5-bit count + reserved hi). |
| k_ra8_ok | Divider computed. |
| k_ra8_err_invalid_arg | A clock argument was zero. |
Definition at line 183 of file ra8_i2c_config.c.
References g_i2c_tag, internal_i2c_clamp_half(), internal_i2c_pick_cks(), k_ra8_err_invalid_arg, k_ra8_i2c_br_reserved_hi, k_ra8_ok, priv_ra8_i2c_internal_clk_invalid(), RA8_CHECK_NULL_PTR, and RA8_INTERNAL.
Referenced by ra8_i2c_init(), and ra8_i2c_set_clock().
|
static |
Clamp one SCL half-period count to the 5-bit BR field.
Splits total evenly between the SCL high and low halves, subtracts the +1 the hardware adds, and clamps to k_ra8_i2c_br_field_max.
| [in] | total | Divided bit-period cycle count. |
| 0 | The divided period collapsed to a single cycle. |
Definition at line 143 of file ra8_i2c_config.c.
References k_ra8_i2c_br_field_max, k_ra8_i2c_period_split, and RA8_INTERNAL.
Referenced by internal_i2c_bitrate().
|
static |
Decode latched ICSR2 error bits into a k_ra8_i2c_err_* mask.
Tests the AL, NACKF and TMOF flags independently and ORs the matching k_ra8_i2c_err_* bit into the result so a caller sees every latched fault in a single mask.
| [in] | icsr2 | Snapshot of ICSR2. |
| k_ra8_i2c_err_none | No fault bit set. |
Definition at line 227 of file ra8_i2c_config.c.
References k_ra8_i2c_err_arb_lost, k_ra8_i2c_err_nack, k_ra8_i2c_err_none, k_ra8_i2c_err_timeout, k_ra8_i2c_icsr2_tmof_pos, k_ra8_i2c_msk_icsr2_al, k_ra8_i2c_msk_icsr2_nackf, and RA8_INTERNAL.
Referenced by ra8_i2c_get_errors().
|
static |
Map a channel index to its MSTP gate id.
IIC0 = MSTPB9, IIC1 = MSTPB8, IIC2 = MSTPB7 per HUM Ch 11.2.7 "MSTPCRB" p 444, encoded in ra8_mstp_regs.h.
| [in] | channel | Channel index (already range-checked by caller). |
| k_ra8_mstp_iic0 | channel is 0. |
| k_ra8_mstp_iic1 | channel is 1. |
| k_ra8_mstp_iic2 | channel is 2 (or any other value, defensively). |
Definition at line 74 of file ra8_i2c_config.c.
References k_ra8_mstp_iic0, k_ra8_mstp_iic1, k_ra8_mstp_iic2, and RA8_INTERNAL.
Referenced by ra8_i2c_deinit(), and ra8_i2c_init().
|
static |
Pick the smallest CKS divider and divide *total to match.
Repeatedly halves the candidate bit-period cycle count until a single SCL half-period fits inside the 5-bit ICBRL/ICBRH field, returning the CKS exponent used. The loop is bounded by k_ra8_i2c_cks_max + 1 iterations (NASA P10 Rule 2).
| [in,out] | total | On entry the full PCLKB / bus_hz cycle count; on return divided by 2^CKS. |
| 0 | The full period already fits the field. |
Definition at line 107 of file ra8_i2c_config.c.
References k_ra8_i2c_br_field_max, k_ra8_i2c_cks_max, k_ra8_i2c_period_split, and RA8_INTERNAL.
Referenced by internal_i2c_bitrate().
|
nodiscard |
Clear latched error flags in ICSR2.
| [in] | channel | Channel index. |
| k_ra8_ok | AL / NACKF / TMOF W0C cleared. |
| k_ra8_err_invalid_arg | Channel out of range. |
< RA8 I2C error clear mask.
Definition at line 393 of file ra8_i2c_config.c.
References r_i2c_regs_t::ICSR2, k_ra8_err_invalid_arg, k_ra8_i2c_icsr2_tmof_pos, k_ra8_i2c_msk_icsr2_al, k_ra8_i2c_msk_icsr2_nackf, k_ra8_ok, and ra8_i2c_regs().
|
nodiscard |
Tear down an IIC channel.
| [in] | channel | Channel index. |
| k_ra8_ok | Channel torn down, MSTP gated. |
| k_ra8_err_invalid_arg | channel out of range. |
Definition at line 338 of file ra8_i2c_config.c.
References r_i2c_regs_t::ICCR1, internal_i2c_mstp_id(), k_ra8_err_invalid_arg, ra8_i2c_regs(), ra8_mstp_disable(), and s_i2c_state.
|
nodiscard |
Read latched error flags from ICSR2 (AL / NACKF / TMOF).
| [in] | channel | Channel index. |
| [out] | out_mask | OR of k_ra8_i2c_err_* bits. |
| k_ra8_ok | out_mask populated. |
| k_ra8_err_null_ptr | out_mask is NULL. |
| k_ra8_err_invalid_arg | channel out of range. |
Definition at line 381 of file ra8_i2c_config.c.
References g_i2c_tag, r_i2c_regs_t::ICSR2, internal_i2c_decode_errors(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, and ra8_i2c_regs().
|
nodiscard |
Initialise an IIC channel as a controller and bring the bus up.
Mirrors the FSP r_iic_master open + HUM Ch 39.3.2 "Initial Settings" p 2395 bring-up: ungate the channel MSTP gate, hold the IIC reset (ICCR1.IICRST), program the bit rate (CKS / ICBRL / ICBRH), enable the function bits in ICFER (MALE / NACKE / SCLE plus FMPE for 1 MHz), then release the reset and set ICCR1.ICE.
| [in] | channel | Channel index (0, 1 or 2). |
| [in] | cfg | Configuration descriptor (non-NULL). |
| k_ra8_ok | Channel initialized, ICCR1.ICE = 1. |
| k_ra8_err_null_ptr | cfg is NULL. |
| k_ra8_err_invalid_arg | channel out of range or cfg->bus_hz / cfg->pclkb_hz zero. |
Definition at line 308 of file ra8_i2c_config.c.
References ra8_i2c_cfg_t::bus_hz, g_i2c_tag, internal_i2c_apply_init_regs(), internal_i2c_bitrate(), internal_i2c_mstp_id(), k_ra8_err_invalid_arg, k_ra8_i2c_speed_fast_plus, k_ra8_ok, ra8_i2c_cfg_t::pclkb_hz, RA8_CHECK_NULL_PTR, ra8_i2c_regs(), ra8_log_info_val, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, and s_i2c_state.
Referenced by internal_io_expander_apply_mask().
|
nodiscard |
Update the bus clock without tearing the channel down.
| [in] | channel | Channel index. |
| [in] | bus_hz | New bus clock in Hz (non-zero). |
| [in] | pclkb_hz | Current PCLKB frequency in Hz (non-zero). |
| k_ra8_ok | CKS / ICBRL / ICBRH reprogrammed. |
| k_ra8_err_invalid_arg | Channel / clock out of range. |
Definition at line 352 of file ra8_i2c_config.c.
References r_i2c_regs_t::ICBRH, r_i2c_regs_t::ICBRL, r_i2c_regs_t::ICMR1, internal_i2c_bitrate(), k_ra8_err_invalid_arg, k_ra8_i2c_cks_max, k_ra8_i2c_icmr1_cks_pos, k_ra8_ok, and ra8_i2c_regs().