From b771ae29b926c1976f9ac1545f3b73525bfbdf50 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Thu, 16 Oct 2025 16:39:10 +0800 Subject: [PATCH 1/7] i3c: add initial ASPEED AST1060 I3C driver implementation Includes: - i3c_controller.rs: main controller logic for master/target - i3c_master.rs: master mode operations (DAA, private xfer, CCC handling) - i3c_target.rs: target mode support and IBI response flow - i3c_config.rs: configuration structure and timing setup - ibi_workq.rs: IBI workqueue handler and task scheduling - ccc.rs: CCC command helpers (ENEC, GETSTATUS, SETDASA, etc.) - ast1060_i3c.rs: AST1060-specific register mapping and initialization - i3c_test.rs: basic test hooks for controller and device ops - mod.rs: module integration and trait exports This commit introduces the initial functional version of the ASPEED I3C driver in Rust, supporting both master and target modes, CCC handling, IBI workqueue, and configuration flow based on the Zephyr reference. Signed-off-by: Steven Lee --- Cargo.lock | 8 + Cargo.toml | 5 +- src/i3c/ast1060_i3c.rs | 2122 ++++++++++++++++++++++++++++++ src/i3c/ccc.rs | 423 ++++++ src/i3c/i3c_config.rs | 379 ++++++ src/i3c/i3c_controller.rs | 93 ++ src/i3c/i3c_master.rs | 142 ++ src/i3c/i3c_target.rs | 109 ++ src/i3c/ibi_workq.rs | 112 ++ src/i3c/mod.rs | 9 + src/lib.rs | 1 + src/main.rs | 57 +- src/pinctrl.rs | 5 + src/tests/functional/i3c_test.rs | 233 ++++ src/tests/functional/mod.rs | 1 + 15 files changed, 3697 insertions(+), 2 deletions(-) create mode 100644 src/i3c/ast1060_i3c.rs create mode 100644 src/i3c/ccc.rs create mode 100644 src/i3c/i3c_config.rs create mode 100644 src/i3c/i3c_controller.rs create mode 100644 src/i3c/i3c_master.rs create mode 100644 src/i3c/i3c_target.rs create mode 100644 src/i3c/ibi_workq.rs create mode 100644 src/i3c/mod.rs create mode 100644 src/tests/functional/i3c_test.rs diff --git a/Cargo.lock b/Cargo.lock index 6b6d361..69b8177 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,7 @@ dependencies = [ "ast1060-pac", "cortex-m", "cortex-m-rt", + "critical-section", "embedded-hal 1.0.0", "embedded-hal 1.0.0-alpha.1", "embedded-io", @@ -173,6 +174,7 @@ checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" dependencies = [ "bare-metal", "bitfield", + "critical-section", "embedded-hal 0.2.7", "volatile-register", ] @@ -198,6 +200,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "embedded-hal" version = "0.2.7" diff --git a/Cargo.toml b/Cargo.toml index ffb99d7..bd2367a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ edition = "2021" default = [] std = [] i2c_target = [] +i3c_master = [] +i3c_target = [] test-rsa = [] test-ecdsa = [] test-hmac = [] @@ -38,7 +40,8 @@ heapless = "0.8.0" nb = "1.1.0" paste = "1.0" -cortex-m = { version = "0.7.5" } +critical-section = "1.2" +cortex-m = { version = "0.7.5", features = ["critical-section-single-core"] } cortex-m-rt = { version = "0.6.5", features = ["device"] } panic-halt = "1.0.0" diff --git a/src/i3c/ast1060_i3c.rs b/src/i3c/ast1060_i3c.rs new file mode 100644 index 0000000..1eab290 --- /dev/null +++ b/src/i3c/ast1060_i3c.rs @@ -0,0 +1,2122 @@ +// Licensed under the Apache-2.0 license + +use crate::common::{DummyDelay, Logger}; +use crate::i3c::ccc::{ + ccc_events_all_set, ccc_events_set, ccc_rstact_all, ccc_rstdaa_all, CccPayload, + CccRstActDefByte, I3C_CCC_DEVCTRL, I3C_CCC_ENTDAA, I3C_CCC_EVT_ALL, I3C_CCC_EVT_HJ, + I3C_CCC_EVT_INTR, I3C_CCC_SETHID, +}; +use crate::i3c::i3c_config::{Completion, I3cConfig}; +use crate::i3c::ibi_workq; +use core::cell::RefCell; +use core::marker::PhantomData; +use core::ptr::read_volatile; +use core::sync::atomic::Ordering; +use cortex_m::peripheral::NVIC; +use critical_section::Mutex; +use embedded_hal::delay::DelayNs; + +pub const I3C_MSG_WRITE: u8 = 0x0; +pub const I3C_MSG_READ: u8 = 0x1; +pub const I3C_MSG_STOP: u8 = 0x2; + +pub const I3C_BUS_I2C_STD_TLOW_MIN_NS: u32 = 4_700; +pub const I3C_BUS_I2C_STD_THIGH_MIN_NS: u32 = 4_000; +pub const I3C_BUS_I2C_STD_TR_MAX_NS: u32 = 1_000; +pub const I3C_BUS_I2C_STD_TF_MAX_NS: u32 = 300; + +pub const I3C_BUS_I2C_FM_TLOW_MIN_NS: u32 = 1_300; +pub const I3C_BUS_I2C_FM_THIGH_MIN_NS: u32 = 600; +pub const I3C_BUS_I2C_FM_TR_MAX_NS: u32 = 300; +pub const I3C_BUS_I2C_FM_TF_MAX_NS: u32 = 300; + +pub const I3C_BUS_I2C_FMP_TLOW_MIN_NS: u32 = 500; +pub const I3C_BUS_I2C_FMP_THIGH_MIN_NS: u32 = 260; +pub const I3C_BUS_I2C_FMP_TR_MAX_NS: u32 = 120; +pub const I3C_BUS_I2C_FMP_TF_MAX_NS: u32 = 120; + +pub const I3C_BUS_THIGH_MAX_NS: u32 = 41; + +pub const NSEC_PER_SEC: u32 = 1_000_000_000; +pub const SDA_TX_HOLD_MIN: u32 = 0b001; +pub const SDA_TX_HOLD_MAX: u32 = 0b111; + +pub const SLV_DCR_MASK: u32 = 0x0000_ff00; +pub const SLV_EVENT_CTRL: u32 = 0x38; +pub const SLV_EVENT_CTRL_MWL_UPD: u32 = bit(7); +pub const SLV_EVENT_CTRL_MRL_UPD: u32 = bit(6); +pub const SLV_EVENT_CTRL_HJ_REQ: u32 = bit(3); +pub const SLV_EVENT_CTRL_SIR_EN: u32 = bit(0); + +pub const I3CG_REG1_SCL_IN_SW_MODE_VAL: u32 = bit(23); +pub const I3CG_REG1_SDA_IN_SW_MODE_VAL: u32 = bit(27); +pub const I3CG_REG1_SCL_IN_SW_MODE_EN: u32 = bit(28); +pub const I3CG_REG1_SDA_IN_SW_MODE_EN: u32 = bit(29); + +pub const CM_TFR_STS_MASTER_HALT: u8 = 0xf; +pub const CM_TFR_STS_TARGET_HALT: u8 = 0x6; + +pub const COMMAND_QUEUE_PORT: u32 = 0x0c; + +// --- single-bit flags --- +pub const COMMAND_PORT_PEC: u32 = bit(31); +pub const COMMAND_PORT_TOC: u32 = bit(30); +pub const COMMAND_PORT_READ_TRANSFER: u32 = bit(28); +pub const COMMAND_PORT_SDAP: u32 = bit(27); +pub const COMMAND_PORT_ROC: u32 = bit(26); +pub const COMMAND_PORT_DBP: u32 = bit(25); +pub const COMMAND_PORT_CP: u32 = bit(15); +pub const COMMAND_PORT_SPEED: u32 = bits(23, 21); +pub const COMMAND_PORT_DEV_INDEX: u32 = bits(20, 16); +pub const COMMAND_PORT_CMD: u32 = bits(14, 7); +pub const COMMAND_PORT_TID: u32 = bits(6, 3); +pub const COMMAND_PORT_ARG_DB: u32 = bits(15, 8); +pub const COMMAND_PORT_ARG_DATA_LEN: u32 = bits(31, 16); +pub const COMMAND_PORT_ATTR: u32 = bits(2, 0); +pub const COMMAND_PORT_DEV_COUNT: u32 = bits(25, 21); + +pub const TID_TARGET_IBI: u32 = 0x1; +pub const TID_TARGET_RD_DATA: u32 = 0x2; +pub const TID_TARGET_MASTER_WR: u32 = 0x8; +pub const TID_TARGET_MASTER_DEF: u32 = 0xf; + +pub const COMMAND_ATTR_XFER_CMD: u32 = 0; +pub const COMMAND_ATTR_XFER_ARG: u32 = 1; +pub const COMMAND_ATTR_SHORT_ARG: u32 = 2; +pub const COMMAND_ATTR_ADDR_ASSGN_CMD: u32 = 3; +pub const COMMAND_ATTR_SLAVE_DATA_CMD: u32 = 0; + +pub const DEV_ADDR_TABLE_LEGACY_I2C_DEV: u32 = bit(31); +pub const DEV_ADDR_TABLE_DYNAMIC_ADDR: u32 = bits(23, 16); +pub const DEV_ADDR_TABLE_MR_REJECT: u32 = bit(14); +pub const DEV_ADDR_TABLE_SIR_REJECT: u32 = bit(13); +pub const DEV_ADDR_TABLE_IBI_MDB: u32 = bit(12); +pub const DEV_ADDR_TABLE_IBI_PEC: u32 = bit(11); +pub const DEV_ADDR_TABLE_STATIC_ADDR: u32 = bits(6, 0); + +pub const IBI_QUEUE_STATUS: u32 = 0x18; +pub const IBIQ_STATUS_IBI_ID: u32 = bits(15, 8); +pub const IBIQ_STATUS_IBI_ID_SHIFT: u32 = 8; +pub const IBIQ_STATUS_IBI_DATA_LEN: u32 = bits(7, 0); +pub const IBIQ_STATUS_IBI_DATA_LEN_SHIFT: u32 = 0; + +pub const RESET_CTRL_IBI_QUEUE: u32 = bit(5); +pub const RESET_CTRL_RX_FIFO: u32 = bit(4); +pub const RESET_CTRL_TX_FIFO: u32 = bit(3); +pub const RESET_CTRL_RESP_QUEUE: u32 = bit(2); +pub const RESET_CTRL_CMD_QUEUE: u32 = bit(1); +pub const RESET_CTRL_SOFT: u32 = bit(0); + +pub const RESET_CTRL_ALL: u32 = RESET_CTRL_IBI_QUEUE +| RESET_CTRL_RX_FIFO +| RESET_CTRL_TX_FIFO +| RESET_CTRL_RESP_QUEUE +| RESET_CTRL_CMD_QUEUE +| RESET_CTRL_SOFT; + +pub const RESET_CTRL_QUEUES: u32 = RESET_CTRL_IBI_QUEUE +| RESET_CTRL_RX_FIFO +| RESET_CTRL_TX_FIFO +| RESET_CTRL_RESP_QUEUE +| RESET_CTRL_CMD_QUEUE; + +pub const RESET_CTRL_XFER_QUEUES: u32 = +RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE | RESET_CTRL_CMD_QUEUE; + +pub const RESPONSE_QUEUE_PORT: u32 = 0x10; +pub const RESPONSE_PORT_ERR_STATUS_SHIFT: u32 = 28; +pub const RESPONSE_PORT_ERR_STATUS_MASK: u32 = genmask(31, 28); +pub const RESPONSE_PORT_TID_SHIFT: u32 = 24; +pub const RESPONSE_PORT_TID_MASK: u32 = genmask(27, 24); +pub const RESPONSE_PORT_DATA_LEN_SHIFT: u32 = 0; +pub const RESPONSE_PORT_DATA_LEN_MASK: u32 = genmask(15, 0); + +pub const RESPONSE_NO_ERROR: u32 = 0; +pub const RESPONSE_ERROR_CRC: u32 = 1; +pub const RESPONSE_ERROR_PARITY: u32 = 2; +pub const RESPONSE_ERROR_FRAME: u32 = 3; +pub const RESPONSE_ERROR_IBA_NACK: u32 = 4; +pub const RESPONSE_ERROR_ADDRESS_NACK: u32 = 5; +pub const RESPONSE_ERROR_OVER_UNDER_FLOW: u32 = 6; +pub const RESPONSE_ERROR_TRANSF_ABORT: u32 = 8; +pub const RESPONSE_ERROR_I2C_W_NACK_ERR: u32 = 9; +pub const RESPONSE_ERROR_EARLY_TERMINATE: u32 = 10; +pub const RESPONSE_ERROR_PEC_ERR: u32 = 12; + +pub const INTR_STATUS: u32 = 0x3c; +pub const INTR_STATUS_EN: u32 = 0x40; +pub const INTR_SIGNAL_EN: u32 = 0x44; +pub const INTR_FORCE: u32 = 0x48; + +pub const INTR_BUSOWNER_UPDATE_STAT: u32 = bit(13); +pub const INTR_IBI_UPDATED_STAT: u32 = bit(12); +pub const INTR_READ_REQ_RECV_STAT: u32 = bit(11); +pub const INTR_DEFSLV_STAT: u32 = bit(10); +pub const INTR_TRANSFER_ERR_STAT: u32 = bit(9); +pub const INTR_DYN_ADDR_ASSGN_STAT: u32 = bit(8); +pub const INTR_CCC_UPDATED_STAT: u32 = bit(6); +pub const INTR_TRANSFER_ABORT_STAT: u32 = bit(5); +pub const INTR_RESP_READY_STAT: u32 = bit(4); +pub const INTR_CMD_QUEUE_READY_STAT: u32 = bit(3); +pub const INTR_IBI_THLD_STAT: u32 = bit(2); +pub const INTR_RX_THLD_STAT: u32 = bit(1); +pub const INTR_TX_THLD_STAT: u32 = bit(0); +pub const I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE: u32 = bit(2); + +#[must_use] +pub const fn bit(n: u32) -> u32 { + 1 << n +} +#[must_use] +pub const fn bits(h: u32, l: u32) -> u32 { + ((1u32 << (h - l + 1)) - 1) << l +} +#[must_use] +pub const fn field_prep(mask: u32, val: u32) -> u32 { + (val << mask.trailing_zeros()) & mask +} +const fn field_get(val: u32, mask: u32, shift: u32) -> u32 { + (val & mask) >> shift +} +const fn genmask(msb: u32, lsb: u32) -> u32 { + let width = msb - lsb + 1; + if width >= 32 { + u32::MAX + } else { + ((1u32 << width) - 1) << lsb + } +} + +const MAX_CMDS: usize = 32; + +#[derive(Debug)] +pub enum I3cDrvError { + NoDatPos, + NoMsgs, + TooManyMsgs, + InvalidArgs, + Timeout, + NoSuchDev, + Access, + IoError, + Invalid, +} + +#[derive(Clone, Copy)] +struct Handler { + func: fn(usize), + ctx: usize, +} + +static BUS_HANDLERS: [Mutex>>; 4] = [ + Mutex::new(RefCell::new(None)), + Mutex::new(RefCell::new(None)), + Mutex::new(RefCell::new(None)), + Mutex::new(RefCell::new(None)), +]; + +pub fn register_i3c_irq_handler(bus: usize, func: fn(usize), ctx: usize) { + assert!(bus < 4); + critical_section::with(|cs| { + *BUS_HANDLERS[bus].borrow(cs).borrow_mut() = Some(Handler { func, ctx }); + }); +} + +#[inline] +fn dispatch_irq(bus: usize) { + critical_section::with(|cs| { + if let Some(h) = *BUS_HANDLERS[bus].borrow(cs).borrow() { + (h.func)(h.ctx); + } + }); +} + +#[no_mangle] +pub extern "C" fn i3c() { + dispatch_irq(0); +} +#[no_mangle] +pub extern "C" fn i3c1() { + dispatch_irq(1); +} +#[no_mangle] +pub extern "C" fn i3c2() { + dispatch_irq(2); +} +#[no_mangle] +pub extern "C" fn i3c3() { + dispatch_irq(3); +} + +#[repr(u32)] +pub enum SpeedI3c { + Sdr0 = 0x0, + Sdr1 = 0x1, + Sdr2 = 0x2, + Sdr3 = 0x3, + Sdr4 = 0x4, + HdrTs = 0x5, + HdrDdr = 0x6, + I2cFmAsI3c = 0x7, +} + +#[repr(u32)] +pub enum SpeedI2c { + Fm = 0x0, + Fmp = 0x1, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Tid { + TargetIbi = 0x1, + TargetRdData = 0x2, + TargetMasterWr = 0x8, + TargetMasterDef = 0xF, +} + +pub enum I3cStatus { + Ok, + Timeout, + Busy, + Pending, + Invalid, +} + +#[derive(Debug)] +pub struct I3cCmd<'a> { + pub cmd_lo: u32, + pub cmd_hi: u32, + pub tx: Option<&'a [u8]>, + pub rx: Option<&'a mut [u8]>, + pub tx_len: u32, + pub rx_len: u32, + pub ret: i32, +} + +pub struct I3cMsg<'a> { + pub buf: Option<&'a mut [u8]>, + pub actual_len: u32, + pub num_xfer: u32, + pub flags: u8, + pub hdr_mode: u8, + pub hdr_cmd_mode: u8, +} + +pub struct I3cXfer<'cmds, 'buf> { + pub cmds: &'cmds mut [I3cCmd<'buf>], + pub ret: i32, + pub done: Completion, +} + +impl<'cmds, 'buf> I3cXfer<'cmds, 'buf> { + pub fn new(cmds: &'cmds mut [I3cCmd<'buf>]) -> Self { + Self { + cmds, + ret: 0, + done: Completion::new(), + } + } + + pub fn ncmds(&self) -> usize { + self.cmds.len() + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct I3cPid(pub u64); + +impl I3cPid { + #[must_use] + pub const fn manuf_id(self) -> u16 { + ((self.0 >> 33) & 0x1FFF) as u16 + } + #[must_use] + pub const fn has_random_lower32(self) -> bool { + (self.0 & (1u64 << 32)) != 0 + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct I3cDeviceId { + pub pid: I3cPid, +} + +impl I3cDeviceId { + #[must_use] + pub const fn new(pid: u64) -> Self { + Self { pid: I3cPid(pid) } + } +} + +pub const I3C_BROADCAST_ADDR: u8 = 0x7E; +pub const I3C_MAX_ADDR: u8 = 0x7F; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum I3cIbiType { + TargetIntr, + ControllerRoleRequest, + HotJoin, + WorkqueueCb, +} + +#[derive(Clone, Copy, Debug)] +pub struct I3cIbi<'a> { + pub ibi_type: I3cIbiType, + pub payload: Option<&'a [u8]>, +} + +impl<'a> I3cIbi<'a> { + #[inline] + #[must_use] + pub fn payload_len(&self) -> u8 { + self.payload + .map_or(0, |p| u8::try_from(p.len().min(u8::MAX as usize)).unwrap_or(u8::MAX)) + } + + #[must_use] + pub fn first_byte(&self) -> Option { + self.payload.and_then(|p| p.first().copied()) + } +} + +pub trait HardwareInterface { + fn init(&mut self, config: &mut I3cConfig); + fn bus_num(&self) -> u8; + fn enable_irq(&mut self); + fn disable_irq(&mut self); + fn i3c_enable(&mut self, config: &I3cConfig); + fn i3c_disable(&mut self, is_secondary: bool); + fn core_reset_assert(&mut self, bus: u8); + fn core_reset_deassert(&mut self, bus: u8); + fn global_reset_assert(&mut self); + fn global_reset_deassert(&mut self); + fn clock_on(&mut self, bus: u8); + fn set_role(&mut self, is_secondary: bool); + fn init_clock(&mut self, config: &mut I3cConfig); + fn get_clock_rate(&self) -> u32; + fn calc_i2c_clk(&mut self, fscl_hz: u32) -> (u32, u32); + fn init_pid(&mut self, config: &mut I3cConfig, bus: u8); + fn enter_sw_mode(&mut self); + fn exit_sw_mode(&mut self); + fn i3c_toggle_scl_in(&mut self, count: u32); + fn gen_internal_stop(&mut self); + fn i3c_bus_init(&mut self, config: &mut I3cConfig); + fn even_parity(byte: u8) -> bool; + fn set_ibi_mdb(&mut self, mdb: u8); + fn exit_halt(&mut self, config: &mut I3cConfig); + fn enter_halt(&mut self, by_sw: bool, config: &mut I3cConfig); + fn reset_ctrl(&mut self, reset: u32); + fn wr_tx_fifo(&mut self, bytes: &[u8]); + fn rd_fifo(&mut self, read_word: F, out: &mut [u8]) + where + F: FnMut() -> u32; + fn drain_fifo(&mut self, read_word: F, len: usize) + where + F: FnMut() -> u32; + fn rd_rx_fifo(&mut self, out: &mut [u8]); + fn rd_ibi_fifo(&mut self, out: &mut [u8]); + fn ibi_enable(&mut self, config: &mut I3cConfig, addr: u8) -> Result<(), I3cDrvError>; + fn start_xfer(&mut self, config: &mut I3cConfig, xfer: &mut I3cXfer); + fn end_xfer(&mut self, config: &mut I3cConfig); + fn get_addr_pos(&mut self, config: &I3cConfig, addr: u8) -> Option; + fn detach_i3c_dev(&mut self, pos: usize); + fn attach_i3c_dev(&mut self, pos: usize, addr: u8) -> Result<(), I3cDrvError>; + fn do_ccc(&mut self, config: &mut I3cConfig, ccc: &mut CccPayload) -> Result<(), I3cDrvError>; + fn do_entdaa(&mut self, config: &mut I3cConfig, index: u32) -> Result<(), I3cDrvError>; + fn handle_unsolicited(&mut self, config: &mut I3cConfig); + fn priv_xfer_build_cmds<'a>( + &mut self, + cmds: &mut [I3cCmd<'a>], + msgs: &mut [I3cMsg<'a>], + pos: u8, + ) -> Result<(), I3cDrvError>; + fn priv_xfer( + &mut self, + config: &mut I3cConfig, + pid: u64, + msgs: &mut [I3cMsg], + ) -> Result<(), I3cDrvError>; + fn target_tx_write(&mut self, buf: &[u8]); + fn handle_ibi_sir(&mut self, config: &mut I3cConfig, addr: u8, len: usize); + fn handle_ibis(&mut self, config: &mut I3cConfig); + fn i3c_aspeed_isr(&mut self, config: &mut I3cConfig); + // target apis + fn target_handle_response_ready(&mut self, config: &mut I3cConfig); + fn target_pending_read_notify( + &mut self, + config: &mut I3cConfig, + buf: &[u8], + notifier: &mut I3cIbi, + ) -> Result<(), I3cDrvError>; + fn target_handle_ccc_update(&mut self, config: &mut I3cConfig); +} + +pub trait Instance { + fn ptr() -> *const ast1060_pac::i3c::RegisterBlock; + fn ptr_global() -> *const ast1060_pac::i3cglobal::RegisterBlock; + fn scu() -> *const ast1060_pac::scu::RegisterBlock; + const BUS_NUM: u8; +} + +macro_rules! macro_i3c { + ($I3cx: ident, $x: literal) => { + impl Instance for ast1060_pac::$I3cx { + fn ptr() -> *const ast1060_pac::i3c::RegisterBlock { + ast1060_pac::$I3cx::ptr() + } + + fn ptr_global() -> *const ast1060_pac::i3cglobal::RegisterBlock { + ast1060_pac::I3cglobal::ptr() + } + + fn scu() -> *const ast1060_pac::scu::RegisterBlock { + ast1060_pac::Scu::ptr() + } + const BUS_NUM: u8 = $x; + } + }; +} + +macro_i3c!(I3c, 0); +macro_i3c!(I3c1, 1); +macro_i3c!(I3c2, 2); +macro_i3c!(I3c3, 3); + +pub struct Ast1060I3c { + pub i3c: &'static ast1060_pac::i3c::RegisterBlock, + pub i3cg: &'static ast1060_pac::i3cglobal::RegisterBlock, + pub scu: &'static ast1060_pac::scu::RegisterBlock, + pub logger: L, + _marker: PhantomData, +} + +impl Ast1060I3c { + pub fn new(logger: L) -> Self { + let i3c = unsafe { &*I3C::ptr() }; + let i3cg = unsafe { &*I3C::ptr_global() }; + let scu = unsafe { &*I3C::scu() }; + Self { + i3c, + i3cg, + scu, + logger, + _marker: PhantomData, + } + } +} + +macro_rules! i3c_debug { + ($logger:expr, $($arg:tt)*) => {{ + use core::fmt::Write as _; + let mut buf: heapless::String<128> = heapless::String::new(); + let _ = write!(&mut buf, $($arg)*); + $logger.debug(buf.as_str()); + }}; +} + +#[allow(unused_macros)] +macro_rules! read_i3cg_reg0 { + ($self:expr, $bus:expr) => {{ + match $bus { + 0 => $self.i3cg.i3c010().read().bits(), + 1 => $self.i3cg.i3c020().read().bits(), + 2 => $self.i3cg.i3c030().read().bits(), + 3 => $self.i3cg.i3c040().read().bits(), + _ => panic!("invalid I3C bus index: {}", $bus), + } + }}; +} + +macro_rules! read_i3cg_reg1 { + ($self:expr, $bus:expr) => {{ + match $bus { + 0 => $self.i3cg.i3c014().read().bits(), + 1 => $self.i3cg.i3c024().read().bits(), + 2 => $self.i3cg.i3c034().read().bits(), + 3 => $self.i3cg.i3c044().read().bits(), + _ => panic!("invalid I3C bus index: {}", $bus), + } + }}; +} + +macro_rules! write_i3cg_reg0 { + ($self:expr, $bus:expr, |$w:ident| $body:expr) => {{ + match $bus { + 0 => $self.i3cg.i3c010().write(|$w| $body), + 1 => $self.i3cg.i3c020().write(|$w| $body), + 2 => $self.i3cg.i3c030().write(|$w| $body), + 3 => $self.i3cg.i3c040().write(|$w| $body), + _ => panic!("invalid I3C bus index: {}", $bus), + } + }}; +} + +macro_rules! write_i3cg_reg1 { + ($self:expr, $bus:expr, |$w:ident| $body:expr) => {{ + match $bus { + 0 => $self.i3cg.i3c014().write(|$w| $body), + 1 => $self.i3cg.i3c024().write(|$w| $body), + 2 => $self.i3cg.i3c034().write(|$w| $body), + 3 => $self.i3cg.i3c044().write(|$w| $body), + _ => panic!("invalid I3C bus index: {}", $bus), + } + }}; +} + +#[allow(unused_macros)] +macro_rules! modify_i3cg_reg0 { + ($self:expr, $bus:expr, |$r:ident, $w:ident| $body:expr) => {{ + match $bus { + 0 => $self.i3cg.i3c010().modify(|$r, $w| $body), + 1 => $self.i3cg.i3c020().modify(|$r, $w| $body), + 2 => $self.i3cg.i3c030().modify(|$r, $w| $body), + 3 => $self.i3cg.i3c040().modify(|$r, $w| $body), + _ => panic!("invalid I3C bus index: {}", $bus), + } + }}; +} + +macro_rules! modify_i3cg_reg1 { + ($self:expr, $bus:expr, |$r:ident, $w:ident| $body:expr) => {{ + match $bus { + 0 => $self.i3cg.i3c014().modify(|$r, $w| $body), + 1 => $self.i3cg.i3c024().modify(|$r, $w| $body), + 2 => $self.i3cg.i3c034().modify(|$r, $w| $body), + 3 => $self.i3cg.i3c044().modify(|$r, $w| $body), + _ => panic!("invalid I3C bus index: {}", $bus), + } + }}; +} + +macro_rules! i3c_dat_read { + ($self:expr, $pos:expr) => {{ + match ($pos) { + 0 => $self.i3c.i3cd280().read().bits(), + 1 => $self.i3c.i3cd284().read().bits(), + 2 => $self.i3c.i3cd288().read().bits(), + 3 => $self.i3c.i3cd28c().read().bits(), + 4 => $self.i3c.i3cd290().read().bits(), + 5 => $self.i3c.i3cd294().read().bits(), + 6 => $self.i3c.i3cd298().read().bits(), + 7 => $self.i3c.i3cd29c().read().bits(), + _ => 0, + } + }}; +} + +macro_rules! i3c_dat_write { + ($self:expr, $pos:expr, |$w:ident| $body:expr) => {{ + match ($pos) { + 0 => { + $self.i3c.i3cd280().write(|$w| $body); + } + 1 => { + $self.i3c.i3cd284().write(|$w| $body); + } + 2 => { + $self.i3c.i3cd288().write(|$w| $body); + } + 3 => { + $self.i3c.i3cd28c().write(|$w| $body); + } + 4 => { + $self.i3c.i3cd290().write(|$w| $body); + } + 5 => { + $self.i3c.i3cd294().write(|$w| $body); + } + 6 => { + $self.i3c.i3cd298().write(|$w| $body); + } + 7 => { + $self.i3c.i3cd29c().write(|$w| $body); + } + _ => { /* ignore */ } + } + }}; +} + +#[allow(unused_macros)] +macro_rules! i3c_dat_modify { + ($self:expr, $pos:expr, |$r:ident, $w:ident| $body:expr) => {{ + match ($pos) { + 0 => { + $self.i3c.i3cd280().modify(|$r, $w| $body); + } + 1 => { + $self.i3c.i3cd284().modify(|$r, $w| $body); + } + 2 => { + $self.i3c.i3cd288().modify(|$r, $w| $body); + } + 3 => { + $self.i3c.i3cd28c().modify(|$r, $w| $body); + } + 4 => { + $self.i3c.i3cd290().modify(|$r, $w| $body); + } + 5 => { + $self.i3c.i3cd294().modify(|$r, $w| $body); + } + 6 => { + $self.i3c.i3cd298().modify(|$r, $w| $body); + } + 7 => { + $self.i3c.i3cd29c().modify(|$r, $w| $body); + } + _ => { /* ignore */ } + } + }}; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum PollError { + Timeout, +} + +pub fn poll_with_timeout( + mut read_reg: F, + mut condition: C, + delay: &mut D, + delay_ns: u32, + max_iters: u32, +) -> Result +where + F: FnMut() -> u32, + C: FnMut(u32) -> bool, + D: embedded_hal::delay::DelayNs, +{ + for _ in 0..max_iters { + let val = read_reg(); + if condition(val) { + return Ok(val); + } + delay.delay_ns(delay_ns); + } + Err(PollError::Timeout) +} + +impl HardwareInterface for Ast1060I3c { + #[allow(clippy::too_many_lines)] + fn init(&mut self, config: &mut I3cConfig) { + i3c_debug!(self.logger, "i3c init"); + + // Global reset is shared, so just need to deassert it + self.global_reset_deassert(); + + write_i3cg_reg1!(self, I3C::BUS_NUM, |w| unsafe { + w.actmode() + .bits(1) + .instid() + .bits(I3C::BUS_NUM) + .staticaddr() + .bits(0x74) + }); + let reg = read_i3cg_reg1!(self, I3C::BUS_NUM); + i3c_debug!(self.logger, "i3cg_reg1: {:#x}", reg); + + write_i3cg_reg0!(self, I3C::BUS_NUM, |w| unsafe { w.bits(0x0) }); + let reg = read_i3cg_reg0!(self, I3C::BUS_NUM); + i3c_debug!(self.logger, "i3cg_reg0: {:#x}", reg); + + let mut delay = DummyDelay {}; + self.core_reset_assert(I3C::BUS_NUM); + self.clock_on(I3C::BUS_NUM); + self.core_reset_deassert(I3C::BUS_NUM); + self.i3c_disable(config.is_secondary); + unsafe { + let scu090: u32 = 0x7e6e_2090; + + let reg: u32 = read_volatile(scu090 as *const u32); + i3c_debug!(self.logger, "scu090: {:#x}", reg); + + let scu050: u32 = 0x7e6e_2050; + + let reg: u32 = read_volatile(scu050 as *const u32); + i3c_debug!(self.logger, "scu050: {:#x}", reg); + } + + i3c_debug!( + self.logger, + "bus num: {}, is_secondary: {}", + I3C::BUS_NUM, + config.is_secondary + ); + // Reset controller + self.i3c.i3cd034().write(|w| { + w.ibiqueue_sw_rst() + .set_bit() + .rx_buffer_sw_rst() + .set_bit() + .tx_buffer_sw_rst() + .set_bit() + .response_queue_sw_rst() + .set_bit() + .cmd_queue_sw_rst() + .set_bit() + .core_sw_rst() + .set_bit() + }); + + let _ = poll_with_timeout( + || self.i3c.i3cd034().read().bits(), + |val| val == 0, + &mut delay, + 100_000, + 1_000_000, + ); + + self.set_role(config.is_secondary); + self.init_clock(config); + // init interrupt mask + self.i3c.i3cd03c().write(|w| unsafe { w.bits(0xffff_ffff) }); + if config.is_secondary { + self.i3c.i3cd040().write(|w| { + w.transfererrstaten() + .set_bit() + .respreadystatintren() + .set_bit() + .cccupdatedstaten() + .set_bit() + .dynaddrassgnstaten() + .set_bit() + .ibiupdatedstaten() + .set_bit() + .readreqrecvstaten() + .set_bit() + }); + + self.i3c.i3cd044().write(|w| { + w.transfererrsignalen() + .set_bit() + .respreadysignalintren() + .set_bit() + .cccupdatedsignalen() + .set_bit() + .dynaddrassgnsignalen() + .set_bit() + .ibiupdatedsignalen() + .set_bit() + .readreqrecvsignalen() + .set_bit() + }); + } else { + self.i3c.i3cd040().write(|w| { + w.transfererrstaten() + .set_bit() + .respreadystatintren() + .set_bit() + }); + + self.i3c.i3cd044().write(|w| { + w.transfererrsignalen() + .set_bit() + .respreadysignalintren() + .set_bit() + }); + } + + config.sir_allowed_by_sw = false; + + // Init hardware queues + self.i3c + .i3cd01c() + .write(|w| unsafe { w.ibidata_threshold_value().bits(31) }); + + self.i3c + .i3cd020() + .modify(|_, w| unsafe { w.rx_buffer_threshold_value().bits(0) }); + + // Init PID and DCR for target/secondary mode + self.init_pid(config, I3C::BUS_NUM); + + // Get max device and DAT start addr + config.maxdevs = self.i3c.i3cd05c().read().devaddrtabledepth().bits(); + config.free_pos = if config.maxdevs == 32 { + u32::MAX + } else { + (1u32 << config.maxdevs) - 1 + }; + config.need_da = 0; + + // Init DAT + for i in 0..(config.maxdevs) { + i3c_dat_write!(self, i, |w| { + w.sirreject().set_bit().mrreject().set_bit() + }); + i3c_debug!( + self.logger, + "dat_addr[{}] = {:#x}", + i, + i3c_dat_read!(self, i) + ); + } + + self.i3c.i3cd02c().write(|w| unsafe { w.bits(0xffff_ffff) }); + self.i3c.i3cd030().write(|w| unsafe { w.bits(0xffff_ffff) }); + self.i3c + .i3cd000() + .modify(|_, w| w.hot_join_ack_nack_ctrl().set_bit()); + + if config.is_secondary { + self.i3c + .i3cd004() + .write(|w| unsafe { w.dev_static_addr().bits(9).static_addr_valid().set_bit() }); + } else { + self.i3c + .i3cd004() + .write(|w| unsafe { w.dev_dynamic_addr().bits(8).dynamic_addr_valid().set_bit() }); + } + + self.i3c_enable(config); + + // Perform bus initialization + if !config.is_secondary { + self.i3c_bus_init(config); + } + + i3c_debug!(self.logger, "i3c enabled"); + // Enable hot-join + if !config.is_secondary { + self.i3c + .i3cd040() + .modify(|_, w| w.ibithldstaten().set_bit()); + self.i3c + .i3cd044() + .modify(|_, w| w.ibithldsignalen().set_bit()); + } + self.i3c + .i3cd000() + .modify(|_, w| w.hot_join_ack_nack_ctrl().clear_bit()); + i3c_debug!(self.logger, "i3c init done"); + i3c_debug!( + self.logger, + "i3c i3cd000: {:#x}", + self.i3c.i3cd000().read().bits() + ); + } + + fn bus_num(&self) -> u8 { + I3C::BUS_NUM + } + + fn enable_irq(&mut self) { + unsafe { + match I3C::BUS_NUM { + 0 => NVIC::unmask(ast1060_pac::Interrupt::i3c), + 1 => NVIC::unmask(ast1060_pac::Interrupt::i3c1), + 2 => NVIC::unmask(ast1060_pac::Interrupt::i3c2), + 3 => NVIC::unmask(ast1060_pac::Interrupt::i3c3), + _ => {} + } + } + } + + fn disable_irq(&mut self) { + match I3C::BUS_NUM { + 0 => NVIC::mask(ast1060_pac::Interrupt::i3c), + 1 => NVIC::mask(ast1060_pac::Interrupt::i3c1), + 2 => NVIC::mask(ast1060_pac::Interrupt::i3c2), + 3 => NVIC::mask(ast1060_pac::Interrupt::i3c3), + _ => {} + } + } + + fn i3c_disable(&mut self, is_secondary: bool) { + i3c_debug!(self.logger, "i3c disable"); + if self.i3c.i3cd000().read().enbl_i3cctrl().bit_is_clear() { + return; + } + + if is_secondary { + // enter sw mode + self.enter_sw_mode(); + } + self.i3c + .i3cd000() + .modify(|_, w| w.enbl_i3cctrl().clear_bit()); + + if is_secondary { + self.i3c_toggle_scl_in(8); + self.gen_internal_stop(); + self.exit_sw_mode(); + } + } + + fn core_reset_assert(&mut self, bus: u8) { + match bus { + 0 => self.scu.scu050().modify(|_, w| w.rst_i3c0ctrl().set_bit()), + 1 => self.scu.scu050().modify(|_, w| w.rst_i3c1ctrl().set_bit()), + 2 => self.scu.scu050().modify(|_, w| w.rst_i3c2ctrl().set_bit()), + 3 => self.scu.scu050().modify(|_, w| w.rst_i3c3ctrl().set_bit()), + _ => panic!("invalid I3C bus index: {bus}"), + }; + } + + fn core_reset_deassert(&mut self, bus: u8) { + let mask = 1u32 << (8 + u32::from(bus)); + self.scu + .scu054() + .modify(|_, w| unsafe { w.scu050sys_rst_ctrl_clear_reg2().bits(mask) }); + } + + fn global_reset_assert(&mut self) { + self.scu + .scu050() + .modify(|_, w| w.rst_i3cregdmactrl().set_bit()); + } + + fn global_reset_deassert(&mut self) { + self.scu + .scu054() + .modify(|_, w| unsafe { w.scu050sys_rst_ctrl_clear_reg2().bits(0x80) }); + } + + fn clock_on(&mut self, bus: u8) { + let mask = 1u32 << (8 + u32::from(bus)); + self.scu + .scu094() + .modify(|_, w| unsafe { w.scu090clk_stop_ctrl_clear_reg_set2().bits(mask) }); + } + + fn set_role(&mut self, is_secondary: bool) { + if is_secondary { + self.i3c + .i3cd0b0() + .modify(|_, w| unsafe { w.dev_op_mode().bits(1) }); + } else { + self.i3c + .i3cd0b0() + .modify(|_, w| unsafe { w.dev_op_mode().bits(0) }); + } + } + + fn init_clock(&mut self, config: &mut I3cConfig) { + let clk_rate = self.get_clock_rate(); + i3c_debug!(self.logger, "i3c clock rate: {} Hz", clk_rate); + config.core_period = (1_000_000_000_u32).div_ceil(clk_rate); + + // I2C FM + let (i2c_hi, i2c_lo) = self.calc_i2c_clk(config.i2c_scl_hz); + let hcnt: u32 = i2c_hi.div_ceil(config.core_period); + let lcnt: u32 = i2c_lo.div_ceil(config.core_period); + self.i3c.i3cd0bc().write(|w| unsafe { + w.i2cfmhcnt() + .bits(u16::try_from(hcnt).unwrap_or(u16::MAX)) + .i2cfmlcnt() + .bits(u16::try_from(lcnt).unwrap_or(u16::MAX)) + }); + + // I2C FMP + let (i2c_hi, i2c_lo) = self.calc_i2c_clk(1_000_000); + let hcnt: u32 = i2c_hi.div_ceil(config.core_period); + let lcnt: u32 = i2c_lo.div_ceil(config.core_period); + self.i3c.i3cd0c0().write(|w| unsafe { + w.i2cfmphcnt() + .bits(u8::try_from(hcnt).unwrap_or(u8::MAX)) + .i2cfmplcnt() + .bits(u16::try_from(lcnt).unwrap_or(u16::MAX)) + }); + + // I3C OD + self.i3c + .i3cd0b4() + .write(|w| unsafe { w.i3codhcnt().bits(0x64).i3codlcnt().bits(0x64) }); + + // I3C PP + let hcnt = config.i3c_pp_scl_hi_period_ns.div_ceil(config.core_period); + let lcnt = config.i3c_pp_scl_lo_period_ns.div_ceil(config.core_period); + self.i3c + .i3cd0b8() + .write(|w| unsafe { w.i3cpphcnt().bits(u8::try_from(hcnt).unwrap_or(u8::MAX)).i3cpplcnt().bits(u8::try_from(lcnt).unwrap_or(u8::MAX)) }); + + // SDA TX hold time + let mut lcnt: u32 = (config.sda_tx_hold_ns) + .div_ceil(config.core_period) + .clamp(SDA_TX_HOLD_MIN, SDA_TX_HOLD_MAX); + + lcnt &= 0xfff8_ffff; + self.i3c.i3cd0d0().write(|w| unsafe { w.bits(lcnt) }); + self.i3c.i3cd0d4().write(|w| unsafe { w.bits(0xffff_007c) }); + } + + fn get_clock_rate(&self) -> u32 { + 200_000_000 + } + + fn calc_i2c_clk(&mut self, fscl_hz: u32) -> (u32, u32) { + use core::cmp::max; + + debug_assert!(fscl_hz > 0); + let period_ns: u32 = (1_000_000_000u32).div_ceil(fscl_hz); + + let (lo_min, hi_min): (u32, u32) = if fscl_hz <= 100_000 { + ( + (I3C_BUS_I2C_STD_TLOW_MIN_NS + I3C_BUS_I2C_STD_TF_MAX_NS).div_ceil(period_ns), + (I3C_BUS_I2C_STD_THIGH_MIN_NS + I3C_BUS_I2C_STD_TR_MAX_NS).div_ceil(period_ns), + ) + } else if fscl_hz <= 400_000 { + ( + (I3C_BUS_I2C_FM_TLOW_MIN_NS + I3C_BUS_I2C_FM_TF_MAX_NS).div_ceil(period_ns), + (I3C_BUS_I2C_FM_THIGH_MIN_NS + I3C_BUS_I2C_FM_TR_MAX_NS).div_ceil(period_ns), + ) + } else { + ( + (I3C_BUS_I2C_FMP_TLOW_MIN_NS + I3C_BUS_I2C_FMP_TF_MAX_NS).div_ceil(period_ns), + (I3C_BUS_I2C_FMP_THIGH_MIN_NS + I3C_BUS_I2C_FMP_TR_MAX_NS).div_ceil(period_ns), + ) + }; + + let leftover = period_ns.saturating_sub(lo_min + hi_min); + let lo = lo_min + leftover / 2; + let hi = max(period_ns.saturating_sub(lo), hi_min); + + (hi as u32, lo) + } + + fn init_pid(&mut self, config: &mut I3cConfig, bus: u8) { + self.i3c + .i3cd070() + .write(|w| unsafe { w.slvmipimfgid().bits(0x3f6).slvpiddcr().clear_bit() }); + + let rev_id: u32 = self.scu.scu004().read().hw_rev_id().bits().into(); + let mut reg: u32 = rev_id << 16 | u32::from(bus) << 12; + reg |= 0xa000_0000; + self.i3c.i3cd074().write(|w| unsafe { w.bits(reg) }); + let mut reg: u32 = self.i3c.i3cd078().read().bits(); + reg &= !SLV_DCR_MASK; + reg |= (config.dcr << 8) | 0x66; + self.i3c.i3cd078().write(|w| unsafe { w.bits(reg) }); + } + + fn enter_sw_mode(&mut self) { + i3c_debug!(self.logger, "enter sw mode"); + let bus = I3C::BUS_NUM; + let mut reg = read_i3cg_reg1!(self, bus); + reg |= I3CG_REG1_SCL_IN_SW_MODE_VAL | I3CG_REG1_SDA_IN_SW_MODE_VAL; + modify_i3cg_reg1!(self, bus, |_r, w| unsafe { w.bits(reg) }); + reg |= I3CG_REG1_SCL_IN_SW_MODE_EN | I3CG_REG1_SDA_IN_SW_MODE_EN; + modify_i3cg_reg1!(self, bus, |_r, w| unsafe { w.bits(reg) }); + } + + fn exit_sw_mode(&mut self) { + let bus = I3C::BUS_NUM; + let mut reg = read_i3cg_reg1!(self, bus); + reg &= !(I3CG_REG1_SCL_IN_SW_MODE_EN | I3CG_REG1_SDA_IN_SW_MODE_EN); + modify_i3cg_reg1!(self, bus, |_r, w| unsafe { w.bits(reg) }); + } + + fn i3c_enable(&mut self, config: &I3cConfig) { + i3c_debug!(self.logger, "i3c enable"); + if config.is_secondary { + i3c_debug!(self.logger, "i3c enable as secondary"); + self.i3c.i3cd038().write(|w| unsafe { w.bits(0) }); + self.enter_sw_mode(); + // Enable hot-join + self.i3c.i3cd000().modify(|_, w| { + w.enbl_adaption_of_i2ci3cmode() + .clear_bit() + .ibipayloaden() + .set_bit() + .enbl_i3cctrl() + .set_bit() + }); + i3c_debug!( + self.logger, + "1 i3c i3cd000: {:#x}", + self.i3c.i3cd000().read().bits() + ); + let wait_cnt = &self.i3c.i3cd0d4().read().i3cibifree().bits(); + let wait_ns = u32::from(*wait_cnt) * config.core_period; + let mut delay = DummyDelay {}; + i3c_debug!(self.logger, "wait_ns: {}", wait_ns); + delay.delay_ns(wait_ns * 100_u32); + self.i3c_toggle_scl_in(8); + if self.i3c.i3cd000().read().enbl_i3cctrl().bit_is_set() { + self.gen_internal_stop(); + } + i3c_debug!( + self.logger, + "2 i3c i3cd000: {:#x}", + self.i3c.i3cd000().read().bits() + ); + self.exit_sw_mode(); + } else { + self.i3c.i3cd000().modify(|_, w| { + w.i3cbroadcast_addr_include() + .set_bit() + .enbl_i3cctrl() + .set_bit() + }); + } + } + + fn i3c_toggle_scl_in(&mut self, count: u32) { + let bus = I3C::BUS_NUM; + for _ in 0..count { + modify_i3cg_reg1!(self, bus, |r, w| unsafe { + w.bits(r.bits() & !I3CG_REG1_SCL_IN_SW_MODE_VAL) + }); + modify_i3cg_reg1!(self, bus, |r, w| unsafe { + w.bits(r.bits() | I3CG_REG1_SCL_IN_SW_MODE_VAL) + }); + } + } + + fn gen_internal_stop(&mut self) { + let bus = I3C::BUS_NUM; + modify_i3cg_reg1!(self, bus, |r, w| unsafe { + w.bits(r.bits() & !I3CG_REG1_SCL_IN_SW_MODE_VAL) + }); + modify_i3cg_reg1!(self, bus, |r, w| unsafe { + w.bits(r.bits() & !I3CG_REG1_SDA_IN_SW_MODE_VAL) + }); + modify_i3cg_reg1!(self, bus, |r, w| unsafe { + w.bits(r.bits() | I3CG_REG1_SCL_IN_SW_MODE_VAL) + }); + modify_i3cg_reg1!(self, bus, |r, w| unsafe { + w.bits(r.bits() | I3CG_REG1_SDA_IN_SW_MODE_VAL) + }); + } + + fn i3c_bus_init(&mut self, config: &mut I3cConfig) { + i3c_debug!(self.logger, "i3c bus init"); + let rc = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActResetWholeTarget); + if let Ok(()) = rc {} else { let _ = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActPeriphralOnly); return; } + + let _ = ccc_rstdaa_all(self, config); + let events = I3C_CCC_EVT_ALL; + let _ = ccc_events_all_set(self, config, false, events); + let _ = ccc_events_all_set(self, config, true, I3C_CCC_EVT_HJ); + i3c_debug!(self.logger, "i3c bus init done"); + } + + fn even_parity(byte: u8) -> bool { + let mut parity = false; + let mut b = byte; + + while b != 0 { + parity = !parity; + b &= b - 1; + } + + !parity + } + + fn set_ibi_mdb(&mut self, mdb: u8) { + self.i3c + .i3cd000() + .modify(|_, w| unsafe { w.mdb().bits(mdb) }); + } + + fn exit_halt(&mut self, config: &mut I3cConfig) { + let state = self.i3c.i3cd054().read().cmtfrstatus().bits(); + let expected = if config.is_secondary { + CM_TFR_STS_TARGET_HALT + } else { + CM_TFR_STS_MASTER_HALT + }; + + if state != expected { + return; + } + + self.i3c.i3cd000().modify(|_, w| w.i3cresume().set_bit()); + + let rc = poll_with_timeout( + || u32::from(self.i3c.i3cd054().read().cmtfrstatus().bits()), + |val| val != u32::from(expected), + &mut DummyDelay {}, + 10000, + 1_000_000, + ); + + if rc.is_err() { + i3c_debug!(self.logger, "exit_halt: timeout"); + } + } + + fn enter_halt(&mut self, by_sw: bool, config: &mut I3cConfig) { + let expected = if config.is_secondary { + CM_TFR_STS_TARGET_HALT + } else { + CM_TFR_STS_MASTER_HALT + }; + + if by_sw { + self.i3c.i3cd000().modify(|_, w| w.i3cabort().set_bit()); + } + + let rc = poll_with_timeout( + || u32::from(self.i3c.i3cd054().read().cmtfrstatus().bits()), + |val| val == u32::from(expected), + &mut DummyDelay {}, + 10000, + 1_000_000, + ); + + if rc.is_err() { + i3c_debug!(self.logger, "enter_halt: timeout"); + } + } + + fn reset_ctrl(&mut self, reset: u32) { + let reg = reset & RESET_CTRL_ALL; + + if reg == 0 { + return; + } + + self.i3c.i3cd034().write(|w| unsafe { w.bits(reg) }); + let rc = poll_with_timeout( + || self.i3c.i3cd034().read().bits(), + |val| val == 0, + &mut DummyDelay {}, + 10_000, + 1_000_000, + ); + + if rc.is_err() { + i3c_debug!(self.logger, "reset_ctrl: timeout"); + } + } + + fn wr_tx_fifo(&mut self, bytes: &[u8]) { + let mut chunks = bytes.chunks_exact(4); + for chunk in &mut chunks { + let word = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]); + self.i3c + .i3cd014() + .write(|w| unsafe { w.tx_data_port().bits(word) }); + } + + let rem = chunks.remainder(); + if !rem.is_empty() { + let mut tmp = [0u8; 4]; + tmp[..rem.len()].copy_from_slice(rem); + let word = u32::from_le_bytes(tmp); + self.i3c + .i3cd014() + .write(|w| unsafe { w.tx_data_port().bits(word) }); + } + } + + fn rd_fifo(&mut self, mut read_word: F, out: &mut [u8]) + where + F: FnMut() -> u32, + { + let mut chunks = out.chunks_exact_mut(4); + for chunk in &mut chunks { + let val = read_word(); + chunk.copy_from_slice(&val.to_le_bytes()); + } + + let rem = chunks.into_remainder(); + if !rem.is_empty() { + let val = read_word(); + let bytes = val.to_le_bytes(); + rem.copy_from_slice(&bytes[..rem.len()]); + } + } + + fn rd_rx_fifo(&mut self, out: &mut [u8]) { + self.rd_fifo(|| self.i3c.i3cd014().read().rx_data_port().bits(), out); + } + + fn rd_ibi_fifo(&mut self, out: &mut [u8]) { + self.rd_fifo(|| self.i3c.i3cd018().read().bits(), out); + } + + fn ibi_enable(&mut self, config: &mut I3cConfig, addr: u8) -> Result<(), I3cDrvError> { + let dev_idx = config + .attached + .find_dev_idx_by_addr(addr) + .ok_or(I3cDrvError::NoSuchDev)?; + i3c_debug!(self.logger, "ibi_enable: dev_idx={}", dev_idx); + let pos_opt = config + .attached + .pos_of(dev_idx) + .or(config.attached.devices[dev_idx].pos); + + let pos: u8 = pos_opt.ok_or(I3cDrvError::NoDatPos)?; + i3c_debug!(self.logger, "ibi_enable: pos={}", pos); + let dev = &config.attached.devices[dev_idx]; + let tgt_bcr: u32 = u32::from(dev.bcr); + let mut reg = i3c_dat_read!(self, u32::from(pos)); + reg &= !DEV_ADDR_TABLE_SIR_REJECT; + if tgt_bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE != 0 { + reg |= DEV_ADDR_TABLE_IBI_MDB | DEV_ADDR_TABLE_IBI_PEC; + } + + i3c_dat_write!(self, pos, |w| unsafe { w.bits(reg) }); + + let mut sir_reject = self.i3c.i3cd030().read().bits(); + sir_reject &= !bit(pos.into()); + self.i3c.i3cd030().write(|w| unsafe { w.bits(sir_reject) }); + + self.i3c + .i3cd040() + .modify(|_, w| w.ibithldstaten().set_bit()); + + self.i3c + .i3cd044() + .modify(|_, w| w.ibithldsignalen().set_bit()); + + let events = I3C_CCC_EVT_INTR; + let _ = ccc_events_set(self, config, dev.dyn_addr, true, events); + + i3c_debug!(self.logger, "i3cd030 (SIR reject) = {:#x}", sir_reject); + i3c_debug!( + self.logger, + "i3cd040 (IBI thld) = {:#x}", + self.i3c.i3cd040().read().bits() + ); + i3c_debug!( + self.logger, + "i3cd044 (IBI thld sig) = {:#x}", + self.i3c.i3cd044().read().bits() + ); + i3c_debug!( + self.logger, + "i3cd280 dat_addr[{}] = {:#x}", + pos, + i3c_dat_read!(self, u32::from(pos)) + ); + i3c_debug!(self.logger, "ibi_enable done"); + Ok(()) + } + + fn start_xfer(&mut self, config: &mut I3cConfig, xfer: &mut I3cXfer) { + let prev = config + .curr_xfer + .swap(core::ptr::from_mut(xfer).cast::<()>(), Ordering::AcqRel); + // debug_assert!(prev.is_null(), "previous xfer still in flight"); + if !prev.is_null() { + i3c_debug!(self.logger, "start_xfer: previous xfer still in flight"); + } + + xfer.ret = -1; + xfer.done.reset(); + + for cmd in xfer.cmds.iter() { + if let Some(tx) = cmd.tx { + let take = tx.len().min(cmd.tx_len as usize); + if take > 0 { + i3c_debug!(self.logger, "start_xfer: write {} bytes", take); + self.wr_tx_fifo(&tx[..take]); + } + } + } + self.i3c.i3cd01c().modify(|_, w| unsafe { + w.response_buffer_threshold_value() + .bits(u8::try_from(xfer.cmds.len().saturating_sub(1)).unwrap_or(0)) + }); + i3c_debug!( + self.logger, + "value of i3cd01c: {:#x}", + self.i3c.i3cd01c().read().bits() + ); + + for cmd in xfer.cmds.iter() { + i3c_debug!( + self.logger, + "start_xfer: cmd: cmd_hi={:#x}, cmd_lo={:#x}", + cmd.cmd_hi, + cmd.cmd_lo + ); + self.i3c.i3cd00c().write(|w| unsafe { w.bits(cmd.cmd_hi) }); + self.i3c.i3cd00c().write(|w| unsafe { w.bits(cmd.cmd_lo) }); + } + } + + fn end_xfer(&mut self, config: &mut I3cConfig) { + let p = config + .curr_xfer + .swap(core::ptr::null_mut(), Ordering::AcqRel); + if p.is_null() { + i3c_debug!(self.logger, "end_xfer: no current xfer"); + return; + } + let xfer: &mut I3cXfer = unsafe { &mut *(p.cast::()) }; + + let nresp = self.i3c.i3cd04c().read().respbufblr().bits() as usize; + + for _ in 0..nresp { + let resp = self.i3c.i3cd010().read().bits(); + + let tid = field_get(resp, RESPONSE_PORT_TID_MASK, RESPONSE_PORT_TID_SHIFT) as usize; + let rx_len = field_get( + resp, + RESPONSE_PORT_DATA_LEN_MASK, + RESPONSE_PORT_DATA_LEN_SHIFT, + ) as usize; + let err = field_get( + resp, + RESPONSE_PORT_ERR_STATUS_MASK, + RESPONSE_PORT_ERR_STATUS_SHIFT, + ); + + i3c_debug!( + self.logger, + "end_xfer: tid={}, rx_len={}, err={}", + tid, + rx_len, + err + ); + if tid >= xfer.cmds.len() { + if rx_len > 0 { + self.drain_fifo(|| self.i3c.i3cd014().read().rx_data_port().bits(), rx_len); + } + continue; + } + + let cmd = &mut xfer.cmds[tid]; + cmd.rx_len = u32::try_from(rx_len).unwrap_or(0); + cmd.ret = i32::try_from(err).unwrap_or(-1); + + if rx_len == 0 { + continue; + } + + if err == 0 { + if let Some(rx_buf) = cmd.rx.as_deref_mut() { + self.rd_rx_fifo(&mut rx_buf[..rx_len]); + } + } + } + let mut ret = 0; + for i in 0..nresp { + let r = xfer.cmds[i].ret; + if r != 0 { + ret = r; + } + } + + if ret != 0 { + self.enter_halt(false, config); + self.reset_ctrl(RESET_CTRL_QUEUES); + self.exit_halt(config); + } + + xfer.ret = ret; + xfer.done.complete(); + } + + fn get_addr_pos(&mut self, config: &I3cConfig, addr: u8) -> Option { + config + .addrs + .iter() + .take(config.maxdevs as usize) + .position(|&a| a == addr) + .and_then(|i| u8::try_from(i).ok()) + } + + fn detach_i3c_dev(&mut self, pos: usize) { + i3c_dat_write!(self, pos, |w| { + w.sirreject().set_bit().mrreject().set_bit() + }); + } + + fn attach_i3c_dev(&mut self, pos: usize, addr: u8) -> Result<(), I3cDrvError> { + let mut da_with_parity = addr; + if Self::even_parity(addr) { + da_with_parity |= 1 << 7; + } + + i3c_dat_write!(self, pos, |w| unsafe { + w.sirreject() + .set_bit() + .mrreject() + .set_bit() + .devdynamicaddr() + .bits(da_with_parity) + }); + + Ok(()) + } + + #[allow(clippy::too_many_lines)] + fn do_ccc(&mut self, config: &mut I3cConfig, payload: &mut CccPayload<'_, '_>) -> Result<(), I3cDrvError> { + // init i3c_cmd to all 0 + let mut cmds = [I3cCmd { + cmd_lo: 0, + cmd_hi: 0, + tx: None, + rx: None, + tx_len: 0, + rx_len: 0, + ret: 0, + }]; + + let mut pos = 0; + let mut rnw: bool = false; + let mut is_broadcast = false; + + let (id, data_len) = { + let Some(ccc) = payload.ccc.as_ref() else { return Err(I3cDrvError::Invalid) }; + (ccc.id, ccc.data.as_deref().map_or(0, <[u8]>::len)) + }; + + let dbp_is_direct = id > 0x7F; + let db: u8 = if dbp_is_direct && data_len > 0 { + payload + .ccc + .as_ref() + .and_then(|c| c.data.as_deref()) + .map_or(0, |d| d[0]) + } else { + 0 + }; + + { + let cmd = &mut cmds[0]; + + if id <= 0x7F { + // -------- Broadcast CCC -------- + is_broadcast = true; + + if data_len > 0 { + if let Some(d) = payload.ccc.as_ref().and_then(|c| c.data.as_deref()) { + cmd.tx = Some(d); + cmd.tx_len = u32::try_from(data_len).map_err(|_| I3cDrvError::Invalid)?; + } + } + } else { + let Some(tgt_addr) = payload + .targets + .as_ref() + .and_then(|ts| ts.first()) + .map(|t| t.addr) + else { + return Err(I3cDrvError::Invalid); + }; + // -------- Direct CCC -------- + let pos_ops = config.attached.pos_of_addr(tgt_addr); + i3c_debug!( + self.logger, + "do_ccc: tgt_addr=0x{:02x}, pos_ops={:?}", + tgt_addr, + pos_ops + ); + pos = match pos_ops { + Some(p) => p, + None => return Err(I3cDrvError::Invalid), + }; + i3c_debug!( + self.logger, + "do_ccc: tgt_addr=0x{:02x}, pos={}", + tgt_addr, + pos + ); + + let Some(tp) = payload.targets.as_deref_mut().and_then(|ts| ts.first_mut()) + else { + return Err(I3cDrvError::Invalid); + }; + + rnw = tp.rnw; + + if rnw { + let len = tp.data.as_deref().map_or(0, <[u8]>::len); + if len == 0 { + return Err(I3cDrvError::Invalid) + } + cmd.rx_len = u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?; + cmd.rx = tp.data.as_deref_mut(); + } else { + let (d_opt, len) = match tp.data.as_deref() { + Some(d) => (Some(d), d.len()), + None => (None, 0), + }; + cmd.tx = d_opt; + cmd.tx_len = u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?; + tp.num_xfer = len; + } + } + } + + let cmd = &mut cmds[0]; + cmd.cmd_hi = field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_ARG); + + if dbp_is_direct && data_len > 0 { + cmd.cmd_lo |= COMMAND_PORT_DBP; + cmd.cmd_hi |= field_prep(COMMAND_PORT_ARG_DB, db.into()); + } + + if rnw { + cmd.cmd_hi |= field_prep(COMMAND_PORT_ARG_DATA_LEN, cmd.rx_len); + } else { + cmd.cmd_hi |= field_prep(COMMAND_PORT_ARG_DATA_LEN, cmd.tx_len); + } + + cmd.cmd_lo |= field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_CMD) + | field_prep(COMMAND_PORT_CMD, id.into()) + | field_prep(COMMAND_PORT_READ_TRANSFER, u32::from(rnw)) + | COMMAND_PORT_CP + | COMMAND_PORT_ROC + | COMMAND_PORT_TOC; + + if !is_broadcast { + cmd.cmd_lo |= field_prep(COMMAND_PORT_DEV_INDEX, u32::from(pos)); + } + + if id == I3C_CCC_SETHID || id == I3C_CCC_DEVCTRL { + cmd.cmd_lo |= field_prep(COMMAND_PORT_SPEED, SpeedI3c::I2cFmAsI3c as u32); + } + + let mut xfer = I3cXfer::new(&mut cmds[..]); + self.start_xfer(config, &mut xfer); + + let mut delay = DummyDelay {}; + if !xfer.done.wait_for_us(1_000_000_000, &mut delay) { + self.enter_halt(true, config); + self.reset_ctrl(RESET_CTRL_XFER_QUEUES); + self.exit_halt(config); + let _ = config + .curr_xfer + .swap(core::ptr::null_mut(), Ordering::AcqRel); + } + + let ret = xfer.ret; + if ret == i32::try_from(RESPONSE_ERROR_IBA_NACK).map_err(|_| I3cDrvError::Invalid)? { + return Ok(()); + } + + if is_broadcast { + if let Some(ccc_rw) = payload.ccc.as_mut() { + if let Some(d) = ccc_rw.data.as_deref() { + ccc_rw.num_xfer = d.len(); + } + } + } + + match ret { + 0 => Ok(()), + _ => Err(I3cDrvError::Invalid), + } + } + + fn do_entdaa(&mut self, config: &mut I3cConfig, pos: u32) -> Result<(), I3cDrvError> { + i3c_debug!(self.logger, "do_entdaa: pos={}", pos); + let cmd = I3cCmd { + cmd_lo: field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_ADDR_ASSGN_CMD) + | field_prep(COMMAND_PORT_CMD, u32::from(I3C_CCC_ENTDAA)) + | field_prep(COMMAND_PORT_DEV_COUNT, 1) + | field_prep(COMMAND_PORT_DEV_INDEX, pos) + | COMMAND_PORT_ROC + | COMMAND_PORT_TOC, + cmd_hi: field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_ARG), + tx: None, + rx: None, + tx_len: 0, + rx_len: 0, + ret: 0, + }; + + i3c_debug!( + self.logger, + "do_entdaa: cmd_lo=0x{:08x}, cmd_hi=0x{:08x}", + cmd.cmd_lo, + cmd.cmd_hi + ); + let mut cmds = [cmd]; + let mut xfer = I3cXfer::new(&mut cmds[..]); + xfer.ret = -1; + + self.start_xfer(config, &mut xfer); + + let mut delay = DummyDelay {}; + + if !xfer.done.wait_for_us(1_000_000_000, &mut delay) { + self.enter_halt(true, config); + self.reset_ctrl(RESET_CTRL_XFER_QUEUES); + self.exit_halt(config); + let _ = config + .curr_xfer + .swap(core::ptr::null_mut(), Ordering::AcqRel); + return Err(I3cDrvError::Invalid); + } + + i3c_debug!(self.logger, "do_entdaa: xfer done"); + match xfer.ret { + 0 => Ok(()), + _ => Err(I3cDrvError::Invalid), + } + } + + fn handle_unsolicited(&mut self, _config: &mut I3cConfig) { + // todo + } + + fn priv_xfer_build_cmds<'a>( + &mut self, + cmds: &mut [I3cCmd<'a>], + msgs: &mut [I3cMsg<'a>], + pos: u8, + ) -> Result<(), I3cDrvError> { + let cmds_len = cmds.len(); + if cmds_len != msgs.len() { + return Err(I3cDrvError::Invalid); + } + + for i in 0..cmds_len { + let (is_read, ptr, len) = { + let m = &mut msgs[i]; + let is_read = (m.flags & I3C_MSG_READ) != 0; + + if is_read { + let buf = match m.buf.as_deref_mut() { + Some(b) if !b.is_empty() => b, + _ => return Err(I3cDrvError::Invalid), + }; + (true, buf.as_mut_ptr(), buf.len()) + } else { + let buf = match m.buf.as_deref() { + Some(b) if !b.is_empty() => b, + _ => return Err(I3cDrvError::Invalid), + }; + m.num_xfer = u32::try_from(buf.len()).map_err(|_| I3cDrvError::Invalid)?; + (false, buf.as_ptr().cast_mut(), buf.len()) + } + }; + + let cmd = &mut cmds[i]; + *cmd = I3cCmd { + cmd_hi: field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_ARG) + | field_prep(COMMAND_PORT_ARG_DATA_LEN, u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?), + cmd_lo: field_prep(COMMAND_PORT_TID, u32::try_from(i).map_err(|_| I3cDrvError::Invalid)?) + | field_prep(COMMAND_PORT_DEV_INDEX, u32::from(pos)) + | COMMAND_PORT_ROC, + tx: None, + rx: None, + tx_len: 0, + rx_len: 0, + ret: 0, + }; + + if is_read { + let rx_slice: &'a mut [u8] = unsafe { core::slice::from_raw_parts_mut(ptr, len) }; + cmd.rx = Some(rx_slice); + cmd.rx_len = u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?; + cmd.cmd_lo |= COMMAND_PORT_READ_TRANSFER; + } else { + let tx_slice: &'a [u8] = + unsafe { core::slice::from_raw_parts(ptr.cast_const(), len) }; + cmd.tx = Some(tx_slice); + cmd.tx_len = u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?; + } + + let is_last = i + 1 == cmds_len; + if is_last { + cmd.cmd_lo |= COMMAND_PORT_TOC; + } + } + + Ok(()) + } + + fn priv_xfer( + &mut self, + config: &mut I3cConfig, + pid: u64, + msgs: &mut [I3cMsg], + ) -> Result<(), I3cDrvError> { + let pos_opt = config.attached.pos_of_pid(pid); + let pos: u8 = pos_opt.ok_or(I3cDrvError::NoDatPos)?; + + let mut cmds: heapless::Vec = heapless::Vec::new(); + for _ in 0..msgs.len() { + cmds.push(I3cCmd { + cmd_lo: 0, + cmd_hi: 0, + tx: None, + rx: None, + tx_len: 0, + rx_len: 0, + ret: 0, + }) + .unwrap(); + } + + let ret = self.priv_xfer_build_cmds(cmds.as_mut_slice(), msgs, pos); + match ret { + Ok(()) => {}, + Err(e) => return Err(e), + } + + let mut xfer = I3cXfer::new(cmds.as_mut_slice()); + self.start_xfer(config, &mut xfer); + + let mut delay = DummyDelay {}; + if !xfer.done.wait_for_us(1_000_000_000, &mut delay) { + self.enter_halt(true, config); + self.reset_ctrl(RESET_CTRL_XFER_QUEUES); + self.exit_halt(config); + let _ = config + .curr_xfer + .swap(core::ptr::null_mut(), Ordering::AcqRel); + return Err(I3cDrvError::Timeout); + } + + for (i, m) in msgs.iter_mut().enumerate() { + if (m.flags & I3C_MSG_READ) != 0 { + m.actual_len = xfer.cmds[i].rx_len; + } + } + + match xfer.ret { + 0 => Ok(()), + _ => Err(I3cDrvError::Timeout), + } + } + + fn target_tx_write(&mut self, buf: &[u8]) { + self.wr_tx_fifo(buf); + let cmd = field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_SLAVE_DATA_CMD) + | field_prep(COMMAND_PORT_ARG_DATA_LEN, u32::try_from(buf.len()).map_or(0, |v| v)) + | field_prep(COMMAND_PORT_TID, Tid::TargetRdData as u32); + + self.i3c.i3cd00c().write(|w| unsafe { w.bits(cmd) }); + } + + fn drain_fifo(&mut self, mut read_word: F, len: usize) + where + F: FnMut() -> u32, + { + let nwords = (len + 3) >> 2; + for _ in 0..nwords { + let _ = read_word(); + } + } + + fn handle_ibi_sir(&mut self, config: &mut I3cConfig, addr: u8, len: usize) { + i3c_debug!(self.logger, "handle_ibi_sir: addr=0x{:02x}", addr); + let pos = config.attached.pos_of_addr(addr); + if pos.is_none() { + i3c_debug!( + self.logger, + "handle_ibi_sir: no such addr in attached devices" + ); + self.drain_fifo(|| self.i3c.i3cd018().read().bits(), len); + } + + let mut ibi_buf: [u8; 2] = [0u8; 2]; + let take = core::cmp::min(len, ibi_buf.len()); + self.rd_ibi_fifo(&mut ibi_buf[..take]); + let bus = I3C::BUS_NUM as usize; + ibi_workq::i3c_ibi_work_enqueue_target_irq(bus, addr, &ibi_buf[..take]); + } + + fn handle_ibis(&mut self, config: &mut I3cConfig) { + i3c_debug!(self.logger, "handle_ibis"); + let nibis = self.i3c.i3cd04c().read().ibistatuscnt().bits(); + + i3c_debug!(self.logger, "Number of IBIs: {}", nibis); + if nibis == 0 { + return; + } + + for _ in 0..nibis { + // i3c_debug!(self.logger, "i3cd018 (IBI Queue status) = {:#x}", self.i3c.i3cd018().read().bits()); + let reg = self.i3c.i3cd018().read().bits(); + + let ibi_id = field_get(reg, IBIQ_STATUS_IBI_ID, IBIQ_STATUS_IBI_ID_SHIFT); + let ibi_data_len = field_get( + reg, + IBIQ_STATUS_IBI_DATA_LEN, + IBIQ_STATUS_IBI_DATA_LEN_SHIFT, + ) as usize; + let ibi_addr = (ibi_id >> 1) & 0x7F; + let rnw = (ibi_id & 1) != 0; + i3c_debug!( + self.logger, + "IBI: addr=0x{:02x}, rnw={}, len={}", + ibi_addr, + rnw, + ibi_data_len + ); + if ibi_addr != 2 && rnw { + // sirq + self.handle_ibi_sir(config, ibi_addr as u8, ibi_data_len); + } else if ibi_addr == 2 && !rnw { + // hot-join + let bus = I3C::BUS_NUM as usize; + i3c_debug!(self.logger, "Hot-join IBI"); + ibi_workq::i3c_ibi_work_enqueue_hotjoin(bus); + } else { + // normal ibi + i3c_debug!(self.logger, "Normal IBI"); + self.drain_fifo(|| self.i3c.i3cd018().read().bits(), ibi_data_len); + } + } + } + + fn i3c_aspeed_isr(&mut self, config: &mut I3cConfig) { + self.disable_irq(); + let status = self.i3c.i3cd03c().read().bits(); + i3c_debug!(self.logger, "[ISR] 0x{:08x}", status); + if status == 0 { + self.enable_irq(); + return; + } + + if config.is_secondary { + if status & INTR_DYN_ADDR_ASSGN_STAT != 0 { + let da = self.i3c.i3cd004().read().dev_dynamic_addr().bits(); + if let Some(tc) = &mut config.target_config { + tc.addr = Some(da); + } + ibi_workq::i3c_ibi_work_enqueue_target_da_assignment(I3C::BUS_NUM.into()); + } + + if (status & INTR_RESP_READY_STAT) != 0 { + i3c_debug!(self.logger, "Response ready"); + self.target_handle_response_ready(config); + } + + if (status & INTR_CCC_UPDATED_STAT) != 0 { + self.target_handle_ccc_update(config); + } + } else { + i3c_debug!(self.logger, "Primary controller interrupt"); + if (status & (INTR_RESP_READY_STAT | INTR_TRANSFER_ERR_STAT | INTR_TRANSFER_ABORT_STAT)) + != 0 + { + i3c_debug!(self.logger, "Transfer complete/err/abort"); + self.end_xfer(config); + } + + if (status & INTR_IBI_THLD_STAT) != 0 { + i3c_debug!(self.logger, "IBI threshold reached"); + self.handle_ibis(config); + } + } + + self.i3c.i3cd03c().write(|w| unsafe { w.bits(status) }); + self.enable_irq(); + } + + fn target_handle_response_ready(&mut self, config: &mut I3cConfig) { + let nresp = self.i3c.i3cd04c().read().respbufblr().bits(); + + for _ in 0..nresp { + let resp = self.i3c.i3cd010().read().bits(); + + let tid = field_get(resp, RESPONSE_PORT_TID_MASK, RESPONSE_PORT_TID_SHIFT) as usize; + let rx_len = field_get( + resp, + RESPONSE_PORT_DATA_LEN_MASK, + RESPONSE_PORT_DATA_LEN_SHIFT, + ) as usize; + let err = field_get( + resp, + RESPONSE_PORT_ERR_STATUS_MASK, + RESPONSE_PORT_ERR_STATUS_SHIFT, + ); + i3c_debug!( + self.logger, + "Response: tid={}, rx_len={}, err={}", + tid, + rx_len, + err + ); + + if err != 0 { + self.enter_halt(false, config); + self.reset_ctrl(RESET_CTRL_QUEUES); + self.exit_halt(config); + continue; + } + + if rx_len != 0 { + let mut buf: [u8; 256] = [0u8; 256]; + self.rd_rx_fifo(&mut buf[..rx_len]); + i3c_debug!(self.logger, "Response data: {:02x?}", &buf[..rx_len]); + } + + if tid == Tid::TargetIbi as usize { + config.target_ibi_done.complete(); + } + + if tid == Tid::TargetRdData as usize { + config.target_data_done.complete(); + } + } + } + + fn target_pending_read_notify( + &mut self, + config: &mut I3cConfig, + buf: &[u8], + notifier: &mut I3cIbi, + ) -> Result<(), I3cDrvError> { + let reg = self.i3c.i3cd038().read().bits(); + i3c_debug!(self.logger, "target_pending_read_notify: reg=0x{:08x}", reg); + if !(config.sir_allowed_by_sw && (reg & SLV_EVENT_CTRL_SIR_EN != 0)) { + return Err(I3cDrvError::Access); + } + + let Some(mdb) = notifier.first_byte() else { + return Err(I3cDrvError::Invalid); + }; + + self.set_ibi_mdb(mdb); + if let Some(p) = notifier.payload { + if !p.is_empty() { + self.wr_tx_fifo(p); + } + } + + let payload_len = u32::try_from(notifier.payload.map_or(0, <[u8]>::len)).map_err(|_| I3cDrvError::Invalid)?; + let cmd: u32 = field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_SLAVE_DATA_CMD) + | field_prep(COMMAND_PORT_ARG_DATA_LEN, payload_len) + | field_prep(COMMAND_PORT_TID, Tid::TargetIbi as u32); + self.i3c.i3cd00c().write(|w| unsafe { w.bits(cmd) }); + + config.target_ibi_done.reset(); + + self.i3c + .i3cd01c() + .modify(|_, w| unsafe { w.response_buffer_threshold_value().bits(0) }); + + self.target_tx_write(buf); + config.target_data_done.reset(); + + self.i3c.i3cd08c().write(|w| w.sir().set_bit()); + + let mut delay = DummyDelay {}; + + if !config.target_ibi_done.wait_for_us(1_000_000_000, &mut delay) { + i3c_debug!(self.logger, "SIR timeout! Reset I3C controller"); + self.enter_halt(false, config); + self.reset_ctrl(RESET_CTRL_QUEUES); + self.exit_halt(config); + return Err(I3cDrvError::IoError) + } + + if !config + .target_data_done + .wait_for_us(1_000_000_000, &mut delay) + { + // C: wait master read timeout -> disable/reset/enable queues + i3c_debug!(self.logger, "wait master read timeout! Reset queues"); + self.i3c_disable(config.is_secondary); + self.reset_ctrl(RESET_CTRL_QUEUES); + self.i3c_enable(config); + return Err(I3cDrvError::Timeout) + } + + Ok(()) + } + + fn target_handle_ccc_update(&mut self, config: &mut I3cConfig) { + let event = self.i3c.i3cd038().read().bits(); + self.i3c.i3cd038().write(|w| unsafe { w.bits(event) }); + i3c_debug!(self.logger, "CCC update event: 0x{:08x}", event); + let reg = self.i3c.i3cd054().read().cmtfrstatus().bits(); + if reg == CM_TFR_STS_TARGET_HALT { + self.enter_halt(true, config); + self.exit_halt(config); + } + } +} diff --git a/src/i3c/ccc.rs b/src/i3c/ccc.rs new file mode 100644 index 0000000..bde0477 --- /dev/null +++ b/src/i3c/ccc.rs @@ -0,0 +1,423 @@ +// Licensed under the Apache-2.0 license + +use super::ast1060_i3c::HardwareInterface; +use super::i3c_config::I3cConfig; + +pub const I3C_CCC_RSTDAA: u8 = 0x6; +pub const I3C_CCC_ENTDAA: u8 = 0x7; +pub const I3C_CCC_SETHID: u8 = 0x61; +pub const I3C_CCC_DEVCTRL: u8 = 0x62; +pub const I3C_CCC_SETDASA: u8 = 0x87; +pub const I3C_CCC_SETNEWDA: u8 = 0x88; +pub const I3C_CCC_GETPID: u8 = 0x8d; +pub const I3C_CCC_GETBCR: u8 = 0x8e; +pub const I3C_CCC_GETSTATUS: u8 = 0x90; + +pub const I3C_CCC_EVT_INTR: u8 = 1 << 0; +pub const I3C_CCC_EVT_CR: u8 = 1 << 1; +pub const I3C_CCC_EVT_HJ: u8 = 1 << 3; +pub const I3C_CCC_EVT_ALL: u8 = I3C_CCC_EVT_INTR | I3C_CCC_EVT_CR | I3C_CCC_EVT_HJ; + +#[derive(Debug)] +pub enum CccError { + InvalidParam, + NotFound, + NoFreeSlot, + Invalid, +} + +#[derive(Debug)] +pub struct CccTargetPayload<'a> { + /// Target 7‑bit dynamic address (left‑aligned; driver decides if LSB is R/W). + pub addr: u8, + /// `false` = write, `true` = read. + pub rnw: bool, + /// Data buffer for write (source) or read (destination). + pub data: Option<&'a mut [u8]>, + /// Actual bytes transferred (driver fills on return). + pub num_xfer: usize, +} + +#[derive(Debug)] +pub struct Ccc<'a> { + pub id: u8, + /// Optional CCC data immediately following the CCC byte. + pub data: Option<&'a mut [u8]>, + /// Actual bytes transferred (driver fills on return). + pub num_xfer: usize, +} + +/// One CCC transaction description. +#[derive(Debug)] +pub struct CccPayload<'a, 'b> { + pub ccc: Option>, + /// Optional list of direct‑CCC target payloads. + pub targets: Option<&'b mut [CccTargetPayload<'a>]>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CccRstActDefByte { + CccRstActNoReset = 0x0, + CccRstActPeriphralOnly = 0x1, + CccRstActResetWholeTarget = 0x2, + CccRstActDebugNetworkAdapter = 0x3, + CccRstActVirtualTargetDetect = 0x4, +} + +impl CccRstActDefByte { + #[inline] + fn as_byte(self) -> u8 { + self as u8 + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum GetStatusFormat { + Fmt1, + Fmt2(GetStatusDefByte), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum GetStatusDefByte { + /// 0x00 - TGTSTAT + TgtStat, + /// 0x91 - PRECR + Precr, +} + +impl GetStatusDefByte { + #[inline] + fn as_byte(self) -> u8 { + match self { + GetStatusDefByte::TgtStat => 0x00, + GetStatusDefByte::Precr => 0x91, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum GetStatusResp { + Fmt1 { + status: u16, + }, + Fmt2 { + kind: GetStatusDefByte, + raw_u16: u16, + }, +} + +const fn i3c_ccc_enec(broadcast: bool) -> u8 { + if broadcast { + 0x00 + } else { + 0x80 + } +} + +const fn i3c_ccc_disec(broadcast: bool) -> u8 { + if broadcast { + 0x01 + } else { + 0x81 + } +} + +const fn i3c_ccc_rstact(broadcast: bool) -> u8 { + if broadcast { + 0x2a + } else { + 0x9a + } +} + +pub fn ccc_events_all_set(hw: &mut H, config: &mut I3cConfig, enable: bool, events: u8) -> Result<(), CccError> +where + H: HardwareInterface, +{ + let id = if enable { + i3c_ccc_enec(true) + } else { + i3c_ccc_disec(true) + }; + let rc = hw.do_ccc( + config, + &mut CccPayload { + ccc: Some(Ccc { + id, + data: Some(&mut [events]), + num_xfer: 0, + }), + targets: None, + }, + ); + + match rc { + Ok(()) => Ok(()), + _ => Err(CccError::Invalid), + } +} + +pub fn ccc_events_set( hw: &mut H, config: &mut I3cConfig, da: u8, enable: bool, events: u8,) -> Result<(), CccError> +where + H: HardwareInterface, +{ + if da == 0 { + return Err(CccError::InvalidParam); + } + + let mut ev_buf = [events]; + let tgt = CccTargetPayload { + addr: da, + rnw: false, + data: Some(&mut ev_buf[..]), + num_xfer: 0, + }; + + let mut tgts = [tgt]; + let ccc_id = if enable { + i3c_ccc_enec(false) + } else { + i3c_ccc_disec(false) + }; + let ccc = Ccc { + id: ccc_id, + data: None, + num_xfer: 0, + }; + + let mut payload = CccPayload { + ccc: Some(ccc), + targets: Some(&mut tgts[..]), + }; + + let rc = hw.do_ccc(config, &mut payload); + match rc { + Ok(()) => Ok(()), + _ => Err(CccError::Invalid), + } +} + +pub fn ccc_rstact_all(hw: &mut H, config: &mut I3cConfig, action: CccRstActDefByte) -> Result<(), CccError> +where + H: HardwareInterface, +{ + let mut db = [action.as_byte()]; + let ccc = Ccc { + id: i3c_ccc_rstact(true), + data: Some(&mut db[..]), + num_xfer: 0, + }; + let mut payload = CccPayload { + ccc: Some(ccc), + targets: None, + }; + + let rc = hw.do_ccc(config, &mut payload); + match rc { + Ok(()) => Ok(()), + _ => Err(CccError::Invalid), + } +} + +pub fn ccc_getbcr(hw: &mut H, config: &mut I3cConfig, dyn_addr: u8) -> Result +where + H: HardwareInterface, +{ + if dyn_addr == 0 { + return Err(CccError::InvalidParam); + } + + let mut bcr_buf = [0u8; 1]; + + let tgt = CccTargetPayload { + addr: dyn_addr, + rnw: true, + data: Some(&mut bcr_buf[..]), + num_xfer: 0, + }; + let mut tgts = [tgt]; + + let ccc = Ccc { + id: I3C_CCC_GETBCR, + data: None, + num_xfer: 0, + }; + let mut payload = CccPayload { + ccc: Some(ccc), + targets: Some(&mut tgts[..]), + }; + + let rc = hw.do_ccc(config, &mut payload); + match rc { + Ok(()) => Ok(bcr_buf[0]), + _ => Err(CccError::Invalid), + } +} + +pub fn ccc_setnewda(hw: &mut H, config: &mut I3cConfig, curr_da: u8, new_da: u8) -> Result<(), CccError> +where + H: HardwareInterface, +{ + if curr_da == 0 || new_da == 0 { + return Err(CccError::InvalidParam); + } + + let pos = config.attached.pos_of_addr(curr_da); + if pos.is_none() { + return Err(CccError::NotFound); + } + + if !config.addrbook.is_free(new_da) { + return Err(CccError::NoFreeSlot); + } + let mut new_dyn_addr = (new_da & 0x7F) << 1; + let tgt = CccTargetPayload { + addr: curr_da, + rnw: false, + data: Some(core::slice::from_mut(&mut new_dyn_addr)), + num_xfer: 0, + }; + let mut tgts = [tgt]; + let ccc = Ccc { + id: I3C_CCC_SETNEWDA, + data: None, + num_xfer: 0, + }; + let mut payload = CccPayload { + ccc: Some(ccc), + targets: Some(&mut tgts[..]), + }; + + let rc = hw.do_ccc(config, &mut payload); + match rc { + Ok(()) => Ok(()), + _ => Err(CccError::Invalid), + } +} + +fn bytes_to_pid(bytes: &[u8]) -> u64 { + bytes + .iter() + .take(6) + .fold(0u64, |acc, &b| (acc << 8) | u64::from(b)) +} + +pub fn ccc_getpid(hw: &mut H, config: &mut I3cConfig, dyn_addr: u8) -> Result +where + H: HardwareInterface, +{ + let mut pid_buf = [0u8; 6]; + + let tgt = CccTargetPayload { + addr: dyn_addr, + rnw: true, + data: Some(&mut pid_buf[..]), + num_xfer: 0, + }; + let mut tgts = [tgt]; + + let ccc = Ccc { + id: I3C_CCC_GETPID, + data: None, + num_xfer: 0, + }; + let mut payload = CccPayload { + ccc: Some(ccc), + targets: Some(&mut tgts[..]), + }; + + let rc = hw.do_ccc(config, &mut payload); + match rc { + Ok(()) => Ok(bytes_to_pid(&pid_buf)), + _ => Err(CccError::Invalid), + } +} + +pub fn ccc_getstatus( + hw: &mut H, + config: &mut I3cConfig, + da: u8, + fmt: GetStatusFormat, +) -> Result +where + H: HardwareInterface, +{ + let mut data_buf = [0u8; 2]; + + let mut defbyte_buf = [0u8; 1]; + + let tgt = CccTargetPayload { + addr: da, + rnw: true, + data: Some(&mut data_buf[..]), + num_xfer: 0, + }; + + let mut ccc = Ccc { + id: I3C_CCC_GETSTATUS, + data: None, + num_xfer: 0, + }; + + let kind_opt = match fmt { + GetStatusFormat::Fmt1 => None, + GetStatusFormat::Fmt2(kind) => { + defbyte_buf[0] = kind.as_byte(); + ccc.data = Some(&mut defbyte_buf[..]); + Some(kind) + } + }; + + let mut targets_arr = [tgt]; + let mut payload = CccPayload { + ccc: Some(ccc), + targets: Some(&mut targets_arr[..]), + }; + + let rc = hw.do_ccc(config, &mut payload); + match rc { + Ok(()) => { + let val = u16::from_be_bytes(data_buf); + + let resp = match kind_opt { + None => GetStatusResp::Fmt1 { status: val }, + Some(kind) => GetStatusResp::Fmt2 { kind, raw_u16: val }, + }; + Ok(resp) + } + + _ => Err(CccError::Invalid), + } + +} + +pub fn ccc_getstatus_fmt1(hw: &mut H, config: &mut I3cConfig, da: u8) -> Result +where + H: HardwareInterface, +{ + match ccc_getstatus(hw, config, da, GetStatusFormat::Fmt1) { + Ok(GetStatusResp::Fmt1 { status }) => Ok(status), + _ => Err(CccError::Invalid), + } +} + +pub fn ccc_rstdaa_all(hw: &mut H, config: &mut I3cConfig) -> Result<(), CccError> +where + H: HardwareInterface, +{ + let rc = hw.do_ccc( + config, + &mut CccPayload { + ccc: Some(Ccc { + id: I3C_CCC_RSTDAA, + data: None, + num_xfer: 0, + }), + targets: None, + }, + ); + match rc { + Ok(()) => Ok(()), + _ => Err(CccError::Invalid), + } +} diff --git a/src/i3c/i3c_config.rs b/src/i3c/i3c_config.rs new file mode 100644 index 0000000..cd35442 --- /dev/null +++ b/src/i3c/i3c_config.rs @@ -0,0 +1,379 @@ +// Licensed under the Apache-2.0 license + +use core::marker::PhantomData; +use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering}; +use embedded_hal::delay::DelayNs; +use heapless::Vec; + + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum I3cConfigError { + AddrInUse, + AddrExhausted, + NoFreeSlot, + DevNotFound, + DevAlreadyAttached, + InvalidParam, + Other, +} + +#[derive(Default)] +pub struct CommonState { + _phantom: PhantomData<()>, +} + +#[derive(Default)] +pub struct CommonCfg { + _phantom: PhantomData<()>, +} + +#[derive(Clone, Copy)] +pub struct ResetSpec { + pub id: u32, + pub active_high: bool, +} + +pub struct I3cTargetConfig { + pub flags: u8, + pub addr: Option, + pub mdb: u8, +} + +impl I3cTargetConfig { + #[must_use] + pub const fn new(flags: u8, addr: Option, mdb: u8) -> Self { + Self { flags, addr, mdb } + } +} + +pub struct AddrBook { + pub in_use: [bool; 128], + pub reserved: [bool; 128], +} + +impl Default for AddrBook { + fn default() -> Self { + Self::new() + } +} + +impl AddrBook { + #[must_use] + pub const fn new() -> Self { + Self { + in_use: [false; 128], + reserved: [false; 128], + } + } + + #[inline] + #[must_use] + pub fn is_free(&self, a: u8) -> bool { + !self.in_use[a as usize] && !self.reserved[a as usize] + } + + pub fn reserve_defaults(&mut self) { + for a in 0usize..=7 { + self.reserved[a] = true; + } + self.reserved[0x7E_usize] = true; + for i in 0..=7 { + let alt = 0x7E ^ (1u8 << i); + if alt <= 0x7E { + self.reserved[alt as usize] = true; + } + } + } + + pub fn alloc_from(&mut self, start: u8) -> Option { + let mut a = start.max(8); + while a < 0x7F { + if self.is_free(a) { + // self.in_use[a as usize] = true; + return Some(a); + } + a += 1; + } + None + } + + #[inline] + pub fn mark_use(&mut self, a: u8, used: bool) { + if a != 0 { + self.in_use[a as usize] = used; + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum DevKind { + I3c, + I2c, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct DeviceEntry { + pub kind: DevKind, + pub pid: Option, + pub static_addr: u8, + pub dyn_addr: u8, + pub desired_da: u8, + pub bcr: u8, + pub dcr: u8, + pub maxrd: u8, + pub maxwr: u8, + pub mrl: u16, + pub mwl: u16, + pub max_ibi: u8, + pub ibi_en: bool, + pub pos: Option, +} + +pub struct Attached { + pub devices: Vec, + pub by_pos: [Option; 8], +} + +impl Default for Attached { + fn default() -> Self { + Self::new() + } +} + +impl Attached { + #[must_use] + pub const fn new() -> Self { + Self { + devices: heapless::Vec::new(), + by_pos: [None; 8], + } + } + + pub fn attach(&mut self, dev: DeviceEntry) -> Result { + let idx = self.devices.len(); + self.devices.push(dev).map_err(|_| I3cConfigError::NoFreeSlot)?; + Ok(idx) + } + + pub fn detach(&mut self, dev_idx: usize) { + if dev_idx >= self.devices.len() { + return; + } + + if let Some(pos) = self.devices[dev_idx].pos { + if let Some(p) = self.by_pos.get_mut(pos as usize) { + *p = None; + } + } + + self.devices.remove(dev_idx); + for bp in &mut self.by_pos { + if let Some(idx) = *bp { + let idx_usize = idx as usize; + if idx_usize > dev_idx { + *bp = Some(u8::try_from(idx_usize - 1).expect("idx too large")); + } + } + } + } + + pub fn detach_by_pos(&mut self, pos: usize) { + if let Some(Some(dev_idx)) = self.by_pos.get(pos) { + self.detach(*dev_idx as usize); + } + } + #[must_use] + pub fn pos_of(&self, dev_idx: usize) -> Option { + self.by_pos + .iter() + .position(|&v| v == Some(u8::try_from(dev_idx).expect("dev_idx too large"))) + .and_then(|p| u8::try_from(p).ok()) + } + #[must_use] + pub fn find_dev_idx_by_addr(&self, da: u8) -> Option { + self.devices.iter().position(|d| d.dyn_addr == da) + } + #[must_use] + pub fn pos_of_addr(&self, da: u8) -> Option { + let dev_idx = self.devices.iter().position(|d| d.dyn_addr == da)?; + self.pos_of(dev_idx) + } + #[must_use] + pub fn pos_of_pid(&self, pid: u64) -> Option { + let dev_idx = self.devices.iter().position(|d| d.pid == Some(pid))?; + self.pos_of(dev_idx) + } + + #[inline] + pub fn map_pos(&mut self, pos: u8, idx: u8) { + self.by_pos[pos as usize] = Some(idx); + } + + #[inline] + pub fn unmap_pos(&mut self, pos: u8) { + self.by_pos[pos as usize] = None; + } +} + +pub struct Completion { + done: AtomicBool, +} + +impl Default for Completion { + fn default() -> Self { + Self::new() + } +} + +impl Completion { + #[must_use] + pub const fn new() -> Self { + Self { + done: AtomicBool::new(false), + } + } + + #[inline] + pub fn reset(&self) { + self.done.store(false, Ordering::Release); + } + + #[inline] + pub fn complete(&self) { + self.done.store(true, Ordering::Release); + + cortex_m::asm::sev(); + } + + #[inline] + pub fn is_completed(&self) -> bool { + self.done.load(Ordering::Acquire) + } + + pub fn wait_for_us(&self, timeout_us: u32, delay: &mut D) -> bool { + let mut left = timeout_us; + while !self.is_completed() { + if left == 0 { + return false; + } + delay.delay_us(1); + left -= 1; + } + true + } +} + +pub struct I3cConfig { + // Optional: your own “common” higher-level state + pub common: CommonState, + + pub target_config: Option, + pub addrbook: AddrBook, + pub attached: Attached, + + // Concurrency + pub curr_xfer: AtomicPtr<()>, + + // Timing/phy params (ns) + pub core_period: u32, + pub i2c_scl_hz: u32, + pub i3c_scl_hz: u32, + pub i3c_pp_scl_hi_period_ns: u32, + pub i3c_pp_scl_lo_period_ns: u32, + pub i3c_od_scl_hi_period_ns: u32, + pub i3c_od_scl_lo_period_ns: u32, + pub sda_tx_hold_ns: u32, + pub is_secondary: bool, + + // Tables/indices + pub maxdevs: u16, + pub free_pos: u32, + pub need_da: u32, + + pub addrs: [u8; 8], + pub dcr: u32, + + // Target-mode data + pub sir_allowed_by_sw: bool, + pub target_ibi_done: Completion, + pub target_data_done: Completion, +} + +impl Default for I3cConfig { + fn default() -> Self { + Self::new() + } +} + +impl I3cConfig { + #[must_use] + pub fn new() -> Self { + Self { + common: CommonState::default(), + target_config: None, + addrbook: AddrBook::new(), + attached: Attached::new(), + curr_xfer: AtomicPtr::new(core::ptr::null_mut()), + core_period: 0, + i2c_scl_hz: 0, + i3c_scl_hz: 0, + i3c_pp_scl_hi_period_ns: 0, + i3c_pp_scl_lo_period_ns: 0, + i3c_od_scl_hi_period_ns: 0, + i3c_od_scl_lo_period_ns: 0, + sda_tx_hold_ns: 0, + is_secondary: false, + maxdevs: 8, + free_pos: 0, + need_da: 0, + addrs: [0; 8], + dcr: 0, + sir_allowed_by_sw: false, + target_ibi_done: Completion::new(), + target_data_done: Completion::new(), + } + } + + pub fn init_runtime_fields(&mut self) { + self.addrbook = AddrBook::new(); + self.addrbook.reserve_defaults(); + self.attached = Attached::new(); + } + pub fn pick_initial_da(&mut self, static_addr: u8, desired: u8) -> Option { + if desired != 0 && self.addrbook.is_free(desired) { + self.addrbook.mark_use(desired, true); + return Some(desired); + } + if static_addr != 0 && self.addrbook.is_free(static_addr) { + self.addrbook.mark_use(static_addr, true); + return Some(static_addr); + } + self.addrbook.alloc_from(8) + } + + pub fn reassign_da(&mut self, from: u8, to: u8) -> Result<(), I3cConfigError> { + if from == to { + return Ok(()); + } + if !self.addrbook.is_free(to) { + return Err(I3cConfigError::AddrInUse); + } + + self.addrbook.mark_use(from, false); + self.addrbook.mark_use(to, true); + + if let Some((i, mut e)) = self + .attached + .devices + .iter() + .enumerate() + .find_map(|(i, d)| (d.dyn_addr == from).then_some((i, *d))) + { + e.dyn_addr = to; + self.attached.devices[i] = e; + Ok(()) + } else { + Err(I3cConfigError::DevNotFound) + } + } +} diff --git a/src/i3c/i3c_controller.rs b/src/i3c/i3c_controller.rs new file mode 100644 index 0000000..3d08d22 --- /dev/null +++ b/src/i3c/i3c_controller.rs @@ -0,0 +1,93 @@ +// Licensed under the Apache-2.0 license + +use crate::common::Logger; +use crate::i3c::ast1060_i3c::register_i3c_irq_handler; +use crate::i3c::ast1060_i3c::HardwareInterface; +use crate::i3c::i3c_config::{DevKind, DeviceEntry, I3cConfig}; + +const I3C_BROADCAST_ADDR: u8 = 0x7E; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum AttachError { + OutOfRange, + AddrInUse, +} + +pub struct I3cController { + pub hw: H, + pub config: I3cConfig, + pub logger: L, +} + +impl I3cController { + pub fn init(&mut self) { + let ctx = core::ptr::from_mut::(self) as usize; + let bus = self.hw.bus_num() as usize; + register_i3c_irq_handler(bus, Self::irq_trampoline, ctx); + + self.hw.enable_irq(); + self.hw.init(&mut self.config); + } + + fn irq_trampoline(ctx: usize) { + let ctrl: &mut Self = unsafe { &mut *(ctx as *mut Self) }; + ctrl.hw.i3c_aspeed_isr(&mut ctrl.config); + } + + pub fn attach_i3c_dev(&mut self, pid: u64, desired_da: u8, slot: u8) -> Result<(), AttachError> { + if desired_da == 0 || desired_da >= I3C_BROADCAST_ADDR { + return Err(AttachError::OutOfRange); + } + + let dev = DeviceEntry { + kind: DevKind::I3c, + pid: Some(pid), + static_addr: 0, + dyn_addr: desired_da, + desired_da, + bcr: 0, + dcr: 0, + maxrd: 0, + maxwr: 0, + mrl: 0, + mwl: 0, + max_ibi: 0, + ibi_en: false, + pos: Some(slot), + }; + + let idx = self + .config + .attached + .attach(dev) + .map_err(|_| AttachError::AddrInUse)?; + self.config.attached.map_pos(slot, u8::try_from(idx).map_err(|_| AttachError::OutOfRange)?); + self.config.addrbook.mark_use(desired_da, true); + let rc = self.hw.attach_i3c_dev(slot.into(), desired_da); + match rc { + Ok(()) => Ok(()), + Err(_) => { + Err(AttachError::AddrInUse) + } + } + } + + pub fn detach_i3c_dev(&mut self, pos: usize) { + self.config.attached.detach_by_pos(pos); + self.hw.detach_i3c_dev(pos); + } + + pub fn detach_i3c_dev_by_idx(&mut self, dev_idx: usize) { + let dev = &self.config.attached.devices[dev_idx]; + + if dev.dyn_addr != 0 { + self.config.addrbook.mark_use(dev.dyn_addr, false); + } + + if let Some(pos) = dev.pos { + self.hw.detach_i3c_dev(pos.into()); + } + + self.config.attached.detach(dev_idx); + } +} diff --git a/src/i3c/i3c_master.rs b/src/i3c/i3c_master.rs new file mode 100644 index 0000000..d0854d4 --- /dev/null +++ b/src/i3c/i3c_master.rs @@ -0,0 +1,142 @@ +// Licensed under the Apache-2.0 license + +use proposed_traits::i3c_master::{Error, ErrorKind, ErrorType, I3c, I3cSpeed}; + +use embedded_hal::i2c::SevenBitAddress; + +use crate::common::Logger; +use crate::i3c::ast1060_i3c::HardwareInterface; +use crate::i3c::ccc; +use crate::i3c::i3c_controller::I3cController; + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct I3cMasterError(pub ErrorKind); + +impl Error for I3cMasterError { + #[inline] + fn kind(&self) -> ErrorKind { + self.0 + } +} + +impl From for I3cMasterError { + #[inline] + fn from(k: ErrorKind) -> Self { + I3cMasterError(k) + } +} + +impl ErrorType for I3cController { + type Error = I3cMasterError; +} + +impl I3c for I3cController { + fn assign_dynamic_address( + &mut self, + static_address: SevenBitAddress, + ) -> Result { + let slot = self + .config + .attached + .pos_of_addr(static_address) + .ok_or(I3cMasterError(ErrorKind::DynamicAddressConflict))?; + + let rc = self.hw.do_entdaa(&mut self.config, slot.into()); + match rc { + Ok(()) => {} + Err(_) => { + return Err(I3cMasterError(ErrorKind::DynamicAddressConflict)); + } + } + + let pid = { + ccc::ccc_getpid(&mut self.hw, &mut self.config, static_address) + .map_err(|_| I3cMasterError(ErrorKind::InvalidCcc))? + }; + + let dev_idx = self + .config + .attached + .find_dev_idx_by_addr(static_address) + .ok_or(I3cMasterError(ErrorKind::Other))?; + + let old_pid = { + self.config + .attached + .devices + .get(dev_idx) + .ok_or(I3cMasterError(ErrorKind::Other))? + .pid + }; + if let Some(op) = old_pid { + if pid != op { + return Err(I3cMasterError(ErrorKind::Other)); + } + } + + let bcr = ccc::ccc_getbcr(&mut self.hw, &mut self.config, static_address) + .map_err(|_| I3cMasterError(ErrorKind::InvalidCcc))?; + + { + let dev = self + .config + .attached + .devices + .get_mut(dev_idx) + .ok_or(I3cMasterError(ErrorKind::Other))?; + + dev.pid = Some(pid); + dev.bcr = bcr; + } + + let dyn_addr: SevenBitAddress = { + let dev = self + .config + .attached + .devices + .get(dev_idx) + .ok_or(I3cMasterError(ErrorKind::Other))?; + + dev.dyn_addr + }; + + let ret = self.hw.ibi_enable(&mut self.config, dyn_addr); + match ret { + Ok(()) => {} + _ => { + return Err(I3cMasterError(ErrorKind::Other)); + } + } + + Ok(dyn_addr) + } + + fn acknowledge_ibi(&mut self, address: SevenBitAddress) -> Result<(), Self::Error> { + let dev_idx = self + .config + .attached + .find_dev_idx_by_addr(address) + .ok_or(I3cMasterError(ErrorKind::Other))?; + + if self.config.attached.devices[dev_idx].pid.is_none() { + return Err(I3cMasterError(ErrorKind::Other)); + } + + Ok(()) + } + + fn handle_hot_join(&mut self) -> Result<(), Self::Error> { + // only need to call assign_dynamic_address after receiving hot-join IBI + Ok(()) + } + + fn set_bus_speed(&mut self, _speed: I3cSpeed) -> Result<(), Self::Error> { + // ast1060 i3c c driver doesn't support changing bus speed + Ok(()) + } + + fn request_mastership(&mut self) -> Result<(), Self::Error> { + // ast1060 controller doesn't support multi-master + Ok(()) + } +} diff --git a/src/i3c/i3c_target.rs b/src/i3c/i3c_target.rs new file mode 100644 index 0000000..a7d948f --- /dev/null +++ b/src/i3c/i3c_target.rs @@ -0,0 +1,109 @@ +// Licensed under the Apache-2.0 license + +use core::convert::Infallible; + +use embedded_hal::i2c::ErrorType as HalI2cErrorType; +use proposed_traits::i2c_target::I2CCoreTarget; +use proposed_traits::i3c_target::{DynamicAddressable, I3CCoreTarget, IBICapable}; + +use crate::i3c::ast1060_i3c::{HardwareInterface, I3cIbi, I3cIbiType}; +use crate::i3c::i3c_config::I3cTargetConfig; +use crate::i3c::i3c_controller::I3cController; + +impl HalI2cErrorType for I3cController { + type Error = Infallible; +} + +impl I2CCoreTarget for I3cController { + #[inline] + fn init(&mut self, own_addr: u8) -> Result<(), Self::Error> { + if let Some(t) = self.config.target_config.as_mut() { + if t.addr.is_none() { + t.addr = Some(own_addr); + } + } else { + self.config.target_config = + Some(I3cTargetConfig::new(0, Some(own_addr), /*mdb*/ 0xae)); + } + Ok(()) + } + + #[inline] + fn on_address_match(&mut self, addr: u8) -> bool { + self.config + .target_config + .as_ref() + .and_then(|t| t.addr) + .map_or(false, |da| da == addr) + } + + #[inline] + fn on_transaction_start(&mut self, _is_read: bool) {} + + #[inline] + fn on_stop(&mut self) {} +} + +impl I3CCoreTarget for I3cController {} + +impl DynamicAddressable for I3cController { + fn on_dynamic_address_assigned(&mut self, _new_address: u8) { + self.config.sir_allowed_by_sw = true; + } +} + +impl IBICapable for I3cController { + fn wants_ibi(&self) -> bool { + // In ast1060, we don't need to tell the controller that we want IBI + true + } + + fn get_ibi_payload(&mut self, buffer: &mut [u8]) -> Result { + let (da, mdb) = match self.config.target_config.as_ref() { + Some(t) => ( + match t.addr { + Some(da) => da, + None => return Ok(0), + }, + t.mdb, + ), + None => return Ok(0), + }; + + let addr_rnw = (da << 1) | 0x1; + let mut crc = crc8_ccitt(0, &[addr_rnw]); + crc = crc8_ccitt(crc, &[mdb]); + + let payload = [mdb, crc]; + let mut ibi = I3cIbi { + ibi_type: I3cIbiType::TargetIntr, + payload: Some(&payload), + }; + let rc = self + .hw + .target_pending_read_notify(&mut self.config, buffer, &mut ibi); + + match rc { + Ok(()) => Ok(buffer.len() + payload.len()), + _ => Ok(0), + } + } + + fn on_ibi_acknowledged(&mut self) {} +} + +#[inline] +fn crc8_ccitt(mut crc: u8, data: &[u8]) -> u8 { + for &b in data { + let mut x = crc ^ b; + for _ in 0..8 { + x = if (x & 0x80) != 0 { + (x << 1) ^ 0x07 + } else { + x << 1 + }; + } + crc = x; + } + crc +} diff --git a/src/i3c/ibi_workq.rs b/src/i3c/ibi_workq.rs new file mode 100644 index 0000000..70be7b6 --- /dev/null +++ b/src/i3c/ibi_workq.rs @@ -0,0 +1,112 @@ +// Licensed under the Apache-2.0 license + +use core::cell::RefCell; +use critical_section::Mutex; +use heapless::spsc::Queue; + +const IBIQ_DEPTH: usize = 16; +const IBI_DATA_MAX: u8 = 16; + +#[derive(Debug, Clone, Copy)] +pub enum IbiWork { + HotJoin, + Sirq { + addr: u8, + len: u8, + data: [u8; IBI_DATA_MAX as usize], + }, + TargetDaAssignment, +} + +static mut IBIQ_BUFS: [Queue; 4] = + [Queue::new(), Queue::new(), Queue::new(), Queue::new()]; + +struct IbiBus { + prod: Option>, + cons: Option>, +} + +static IBI_WORKQS: [Mutex>; 4] = [ + Mutex::new(RefCell::new(IbiBus { + prod: None, + cons: None, + })), + Mutex::new(RefCell::new(IbiBus { + prod: None, + cons: None, + })), + Mutex::new(RefCell::new(IbiBus { + prod: None, + cons: None, + })), + Mutex::new(RefCell::new(IbiBus { + prod: None, + cons: None, + })), +]; + +fn ensure_ibiq_split(bus: usize) { + assert!(bus < 4); + critical_section::with(|cs| { + let mut b = IBI_WORKQS[bus].borrow(cs).borrow_mut(); + if b.prod.is_none() || b.cons.is_none() { + let (p, c) = unsafe { IBIQ_BUFS[bus].split() }; + b.prod = Some(p); + b.cons = Some(c); + } + }); +} + +#[must_use] +pub fn i3c_ibi_workq_consumer( + bus: usize, +) -> heapless::spsc::Consumer<'static, IbiWork, IBIQ_DEPTH> { + assert!(bus < 4); + critical_section::with(|cs| { + let mut b = IBI_WORKQS[bus].borrow(cs).borrow_mut(); + if b.prod.is_none() || b.cons.is_none() { + let (p, c) = unsafe { IBIQ_BUFS[bus].split() }; + b.prod = Some(p); + b.cons = Some(c); + } + b.cons.take().expect("IBI consumer already taken") + }) +} + +pub fn i3c_ibi_work_enqueue_target_da_assignment(bus: usize) { + ensure_ibiq_split(bus); + critical_section::with(|cs| { + if let Some(p) = IBI_WORKQS[bus].borrow(cs).borrow_mut().prod.as_mut() { + let _ = p.enqueue(IbiWork::TargetDaAssignment); + } + }); +} + +#[inline] +pub fn i3c_ibi_work_enqueue_hotjoin(bus: usize) { + ensure_ibiq_split(bus); + critical_section::with(|cs| { + if let Some(p) = IBI_WORKQS[bus].borrow(cs).borrow_mut().prod.as_mut() { + let _ = p.enqueue(IbiWork::HotJoin); + } + }); +} + +#[inline] +pub fn i3c_ibi_work_enqueue_target_irq(bus: usize, addr: u8, data: &[u8]) { + ensure_ibiq_split(bus); + let mut ibi_buf = [0u8; IBI_DATA_MAX as usize]; + let take = core::cmp::min(IBI_DATA_MAX as usize, data.len()); + ibi_buf[..take].copy_from_slice(&data[..take]); + critical_section::with(|cs| { + if let Some(p) = IBI_WORKQS[bus].borrow(cs).borrow_mut().prod.as_mut() { + let _ = p.enqueue(IbiWork::Sirq { + addr, + // len: take as u8, + len: u8::try_from(take).map_err(|_| ()) + .unwrap_or(IBI_DATA_MAX), + data: ibi_buf, + }); + } + }); +} diff --git a/src/i3c/mod.rs b/src/i3c/mod.rs new file mode 100644 index 0000000..43b21a2 --- /dev/null +++ b/src/i3c/mod.rs @@ -0,0 +1,9 @@ +// Licensed under the Apache-2.0 license + +pub mod ast1060_i3c; +pub mod ccc; +pub mod i3c_config; +pub mod i3c_controller; +pub mod i3c_master; +pub mod i3c_target; +pub mod ibi_workq; diff --git a/src/lib.rs b/src/lib.rs index 5a5bd51..79bc115 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ pub mod hace_controller; pub mod hash; pub mod hmac; pub mod i2c; +pub mod i3c; pub mod pinctrl; pub mod rsa; pub mod spi; diff --git a/src/main.rs b/src/main.rs index 0587686..fbee4f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,7 +52,7 @@ unsafe fn pre_init() { write_volatile(cache_area_offset as *mut u32, cache_val); let cache_inval_offset: u32 = 0x7e6e_2a54; - let cache_inval_val = 0x8660_0000; + let cache_inval_val = 0x81e0_0000; write_volatile(cache_inval_offset as *mut u32, cache_inval_val); // Enable Cache @@ -97,6 +97,54 @@ fn test_wdt(uart: &mut UartController<'_>) { } } + +#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] +fn release_bmc_spi(uart: &mut UartController<'_>) { + uart.write_all(b"\r\n####### SPIM0 setup #######\r\n") + .unwrap(); + let allow_cmds: [u8; 27] = [ + 0x03, 0x13, 0x0b, 0x0c, 0x6b, 0x6c, 0x01, 0x05, 0x35, 0x06, 0x04, 0x20, 0x21, 0x9f, 0x5a, + 0xb7, 0xe9, 0x32, 0x34, 0xd8, 0xdc, 0x02, 0x12, 0x15, 0x31, 0x3b, 0x3c, + ]; + + let read_blocked_regions = [RegionInfo { + /*pfm*/ + start: 0x0400_0000, + length: 0x0002_0000, + }]; + + let write_blocked_regions = [RegionInfo { + start: 0x0000_0000, + length: 0x0800_0000, + }]; + let mut spi_monitor0 = SpiMonitor::::new( + true, + SpimExtMuxSel::SpimExtMuxSel1, + &allow_cmds, + u8::try_from(allow_cmds.len()).unwrap(), + &read_blocked_regions, + u8::try_from(read_blocked_regions.len()).unwrap(), + &write_blocked_regions, + u8::try_from(write_blocked_regions.len()).unwrap(), + ); + spi_monitor0.spim_sw_rst(); + spi_monitor0.aspeed_spi_monitor_init(); + spi_monitor0.spim_ext_mux_config(SpimExtMuxSel::SpimExtMuxSel0); + // print spim pointer value +} + +#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] +fn setup_bmc_sequence(uart_controller: &mut UartController) { + // Enable BMC flash power + gpio_test::test_gpio_flash_power(uart_controller); + + // Release BMC SPI + release_bmc_spi(uart_controller); + + // Release BMC Reset + gpio_test::test_gpio_bmc_reset(uart_controller); +} + #[no_mangle] pub static HALT: AtomicBool = AtomicBool::new(true); @@ -168,6 +216,13 @@ fn main() -> ! { i2c_test::test_i2c_master(&mut uart_controller); #[cfg(feature = "i2c_target")] i2c_test::test_i2c_slave(&mut uart_controller); + #[cfg(any(feature = "i3c_master", feature = "i3c_target"))] + setup_bmc_sequence(&mut uart_controller); + #[cfg(feature = "i3c_master")] + i3c_test::test_i3c_master(&mut uart_controller); + #[cfg(feature = "i3c_target")] + i3c_test::test_i3c_target(&mut uart_controller); + test_wdt(&mut uart_controller); run_timer_tests(&mut uart_controller); diff --git a/src/pinctrl.rs b/src/pinctrl.rs index e75aa39..1694ef8 100644 --- a/src/pinctrl.rs +++ b/src/pinctrl.rs @@ -1726,6 +1726,11 @@ paste! { pub const PINCTRL_I2C13: &[PinctrlPin] = &[PIN_SCU4B8_22, PIN_SCU4B8_23, CLR_PIN_SCU418_22, CLR_PIN_SCU418_23]; + pub const PINCTRL_I3C0: &[PinctrlPin] = &[PIN_SCU418_16, PIN_SCU418_17, CLR_PIN_SCU4B8_8, CLR_PIN_SCU4B8_9]; + pub const PINCTRL_I3C1: &[PinctrlPin] = &[PIN_SCU418_18, PIN_SCU418_19, CLR_PIN_SCU4B8_10, CLR_PIN_SCU4B8_11]; + pub const PINCTRL_I3C2: &[PinctrlPin] = &[PIN_SCU418_20, PIN_SCU418_21, CLR_PIN_SCU4B8_12, CLR_PIN_SCU4B8_13]; + pub const PINCTRL_I3C3: &[PinctrlPin] = &[PIN_SCU418_22, PIN_SCU418_23, CLR_PIN_SCU4B8_14, CLR_PIN_SCU4B8_15]; + pub const PINCTRL_GPIOA0: &[PinctrlPin] = &[CLR_PIN_SCU410_0, CLR_PIN_SCU4B0_0, CLR_PIN_SCU690_0]; pub const PINCTRL_GPIOA1: &[PinctrlPin] = &[CLR_PIN_SCU410_1, CLR_PIN_SCU4B0_1, CLR_PIN_SCU690_1]; pub const PINCTRL_GPIOA2: &[PinctrlPin] = &[CLR_PIN_SCU410_2, CLR_PIN_SCU4B0_2, CLR_PIN_SCU690_2]; diff --git a/src/tests/functional/i3c_test.rs b/src/tests/functional/i3c_test.rs new file mode 100644 index 0000000..03f7b76 --- /dev/null +++ b/src/tests/functional/i3c_test.rs @@ -0,0 +1,233 @@ +// Licensed under the Apache-2.0 license + +use crate::common::{DummyDelay, NoOpLogger, UartLogger}; +use crate::i3c::ast1060_i3c::HardwareInterface; +use crate::i3c::ast1060_i3c::I3cMsg; +use crate::i3c::ast1060_i3c::{Ast1060I3c, I3C_MSG_READ, I3C_MSG_STOP}; +use crate::i3c::i3c_config::I3cConfig; +use crate::i3c::i3c_config::I3cTargetConfig; +use crate::i3c::i3c_controller::I3cController; +use crate::i3c::ibi_workq::{i3c_ibi_workq_consumer, IbiWork}; +use crate::pinctrl; +use crate::uart::{self, Config, UartController}; +use ast1060_pac::Peripherals; +use core::ptr::read_volatile; +use embedded_hal::delay::DelayNs; +use embedded_io::Write; +use proposed_traits::i3c_master::I3c; +// I3cTarget +use proposed_traits::i3c_target::{DynamicAddressable, IBICapable}; + +pub fn dump_i3c_controller_registers(uart: &mut UartController<'_>, base: u32) { + // [7e7a4000] 80000200 00008009 000f40bb 00000000 + // [7e7a4010] 00000000 00000000 00000000 001f0000 + // [7e7a4020] 01010001 00000000 00000000 ffffffff + unsafe { + let reg_base = base as *mut u32; + writeln!(uart, "rust I3C reg dump:\r").unwrap(); + for i in 0..0xc0 { + let v = read_volatile(reg_base.add(i)); + if i % 4 == 0 { + write!(uart, "[{:08x}]", base + u32::try_from(i).unwrap() * 4).unwrap(); + } + write!(uart, " {v:08x}").unwrap(); + if i % 4 == 3 { + writeln!(uart, "\r").unwrap(); + } + } + } +} + +pub fn test_i3c_master(uart: &mut UartController<'_>) { + let peripherals = unsafe { Peripherals::steal() }; + let mut delay = DummyDelay {}; + let mut dbg_uart = UartController::new(peripherals.uart, &mut delay); + + writeln!(uart, "\r\n####### I3C master test #######\r\n").unwrap(); + unsafe { + dbg_uart.init(&Config { + baud_rate: 115_200, + word_length: uart::WordLength::Eight as u8, + parity: uart::Parity::None, + stop_bits: uart::StopBits::One, + clock: 24_000_000, + }); + } + + pinctrl::Pinctrl::apply_pinctrl_group(pinctrl::PINCTRL_I3C2); + let hw = Ast1060I3c::::new(UartLogger::new(&mut dbg_uart)); + + let mut ctrl = I3cController { + hw, + config: I3cConfig::new(), + logger: NoOpLogger, + }; + + { + let c = &mut ctrl.config; + c.init_runtime_fields(); + c.is_secondary = false; + c.i2c_scl_hz = 1_000_000; + c.i3c_scl_hz = 12_500_000; + c.i3c_pp_scl_hi_period_ns = 250; + c.i3c_pp_scl_lo_period_ns = 250; + c.i3c_od_scl_hi_period_ns = 0; + c.i3c_od_scl_lo_period_ns = 0; + c.sda_tx_hold_ns = 20; + } + + let mut ibi_cons = i3c_ibi_workq_consumer(ctrl.hw.bus_num() as usize); + let known_pid = 0x07ec_0503_1000u64; + let ctrl_dev_slot0 = 0; + ctrl.init(); + + let dyn_addr = if let Some(da) = ctrl.config.addrbook.alloc_from(8) { + ctrl.attach_i3c_dev(known_pid, da, ctrl_dev_slot0).unwrap(); + writeln!(uart, "Pre-attached dev at slot 0, dyn addr {da}\r").unwrap(); + da + } else { + writeln!(uart, "no dyn addr\r").unwrap(); + return; + }; + + // Dump I3C2 registers + // dump_i3c_controller_registers(uart, 0x7e7a_4000); + writeln!(uart, "ctrl dev at slot 0, dyn addr {dyn_addr}\r").unwrap(); + loop { + if let Some(work) = ibi_cons.dequeue() { + match work { + IbiWork::HotJoin => { + writeln!(uart, "[IBI] hotjoin\r").unwrap(); + let _ = ctrl.handle_hot_join(); + ctrl.assign_dynamic_address(dyn_addr).unwrap(); + } + IbiWork::Sirq { addr, len, data } => { + writeln!(uart, "[IBI] SIRQ from 0x{addr:02x}, len {len}\r").unwrap(); + writeln!(uart, " IBI payload:").unwrap(); + for i in 0..len { + write!(uart, " {:02x}", data[i as usize]).unwrap(); + } + writeln!(uart, "\r").unwrap(); + match ctrl.acknowledge_ibi(addr) { + Ok(()) => {} + Err(e) => { + writeln!(uart, " acknowledge_ibi failed: {e:?}\r").unwrap(); + } + } + let mut rx_buf = [0u8; 128]; + let mut msgs = [I3cMsg { + buf: Some(&mut rx_buf[..]), + actual_len: 128, + num_xfer: 0, + flags: I3C_MSG_READ | I3C_MSG_STOP, + hdr_mode: 0, + hdr_cmd_mode: 0, + }]; + let _ = ctrl.hw.priv_xfer(&mut ctrl.config, known_pid, &mut msgs); + writeln!(uart, " read data:").unwrap(); + for i in 0..msgs[0].actual_len { + write!(uart, " {:02x}", rx_buf[i as usize]).unwrap(); + } + writeln!(uart, "\r").unwrap(); + } + IbiWork::TargetDaAssignment => { + writeln!(uart, "[IBI] TargetDaAssignment\r").unwrap(); + } + } + } + } +} + +pub fn test_i3c_target(uart: &mut UartController<'_>) { + let peripherals = unsafe { Peripherals::steal() }; + let mut delay = DummyDelay {}; + let mut dbg_uart = UartController::new(peripherals.uart, &mut delay); + + writeln!(uart, "\r\n####### I3C target test #######\r\n").unwrap(); + unsafe { + dbg_uart.init(&Config { + baud_rate: 115_200, + word_length: uart::WordLength::Eight as u8, + parity: uart::Parity::None, + stop_bits: uart::StopBits::One, + clock: 24_000_000, + }); + } + + pinctrl::Pinctrl::apply_pinctrl_group(pinctrl::PINCTRL_I3C2); + let hw = Ast1060I3c::::new(UartLogger::new(&mut dbg_uart)); + + let mut ctrl = I3cController { + hw, + config: I3cConfig::new(), + logger: NoOpLogger, + }; + + { + let c = &mut ctrl.config; + c.init_runtime_fields(); + // Configure as target + c.is_secondary = true; + c.i2c_scl_hz = 1_000_000; + c.i3c_scl_hz = 12_500_000; + c.i3c_pp_scl_hi_period_ns = 36; + c.i3c_pp_scl_lo_period_ns = 36; + c.i3c_od_scl_hi_period_ns = 0; + c.i3c_od_scl_lo_period_ns = 0; + c.sda_tx_hold_ns = 20; + c.dcr = 0xcc; + c.target_config = Some(I3cTargetConfig::new(0, Some(0), 0xae)); + } + let mut ibi_cons = i3c_ibi_workq_consumer(ctrl.hw.bus_num() as usize); + ctrl.init(); + let dyn_addr = 9; + let dev_idx = 0; + let _ = ctrl.hw.attach_i3c_dev(dev_idx, dyn_addr); + // Dump I3C2 registers + // dump_i3c_controller_registers(uart, 0x7e7a_4000); + loop { + if let Some(work) = ibi_cons.dequeue() { + match work { + IbiWork::HotJoin => { + // do nothing in target mode + writeln!(uart, "[IBI] hotjoin\r").unwrap(); + } + IbiWork::Sirq { addr, len, data: _ } => { + // do nothing in target mode + writeln!(uart, "[IBI] SIRQ from 0x{addr:02x}, len {len}\r").unwrap(); + } + IbiWork::TargetDaAssignment => { + let mut delay = DummyDelay {}; + delay.delay_ns(4_000_000_000); + writeln!(uart, "[IBI] TargetDaAssignment\r").unwrap(); + let da = ctrl.config.target_config.as_ref().unwrap().addr; + writeln!( + uart, + " dyn addr 0x{:02x} was assigned by master\r", + da.unwrap() + ) + .unwrap(); + ctrl.on_dynamic_address_assigned(da.unwrap()); + break; + } + } + } + } + let mut ibi_count = 0; + loop { + let mut delay = DummyDelay {}; + delay.delay_ns(4_000_000_000); + let mut data = [0u8; 16]; + for (i, b) in data.iter_mut().enumerate() { + *b = u8::try_from(i).unwrap(); + } + writeln!(uart, "send ibi #{ibi_count}\r").unwrap(); + ctrl.get_ibi_payload(&mut data).unwrap(); + ibi_count += 1; + if ibi_count > 100 { + break; + } + } + + writeln!(uart, "I3C target test done\r").unwrap(); +} diff --git a/src/tests/functional/mod.rs b/src/tests/functional/mod.rs index f37c0d5..259980c 100644 --- a/src/tests/functional/mod.rs +++ b/src/tests/functional/mod.rs @@ -5,6 +5,7 @@ pub mod gpio_test; pub mod hash_test; pub mod hmac_test; pub mod i2c_test; +pub mod i3c_test; pub mod rsa_test; pub mod rsa_test_vec; pub mod timer_test; From 3ea963b02152c316ead1433f39b9e839e5e496da Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Thu, 16 Oct 2025 16:46:09 +0800 Subject: [PATCH 2/7] i3c: Fix format issues Fix format issues Signed-off-by: Steven Lee --- src/i3c/ast1060_i3c.rs | 141 ++++++++++++++++++++++---------------- src/i3c/ccc.rs | 33 +++++++-- src/i3c/i3c_config.rs | 5 +- src/i3c/i3c_controller.rs | 16 +++-- src/i3c/ibi_workq.rs | 3 +- src/main.rs | 1 - 6 files changed, 124 insertions(+), 75 deletions(-) diff --git a/src/i3c/ast1060_i3c.rs b/src/i3c/ast1060_i3c.rs index 1eab290..db115f8 100644 --- a/src/i3c/ast1060_i3c.rs +++ b/src/i3c/ast1060_i3c.rs @@ -108,20 +108,20 @@ pub const RESET_CTRL_CMD_QUEUE: u32 = bit(1); pub const RESET_CTRL_SOFT: u32 = bit(0); pub const RESET_CTRL_ALL: u32 = RESET_CTRL_IBI_QUEUE -| RESET_CTRL_RX_FIFO -| RESET_CTRL_TX_FIFO -| RESET_CTRL_RESP_QUEUE -| RESET_CTRL_CMD_QUEUE -| RESET_CTRL_SOFT; + | RESET_CTRL_RX_FIFO + | RESET_CTRL_TX_FIFO + | RESET_CTRL_RESP_QUEUE + | RESET_CTRL_CMD_QUEUE + | RESET_CTRL_SOFT; pub const RESET_CTRL_QUEUES: u32 = RESET_CTRL_IBI_QUEUE -| RESET_CTRL_RX_FIFO -| RESET_CTRL_TX_FIFO -| RESET_CTRL_RESP_QUEUE -| RESET_CTRL_CMD_QUEUE; + | RESET_CTRL_RX_FIFO + | RESET_CTRL_TX_FIFO + | RESET_CTRL_RESP_QUEUE + | RESET_CTRL_CMD_QUEUE; pub const RESET_CTRL_XFER_QUEUES: u32 = -RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE | RESET_CTRL_CMD_QUEUE; + RESET_CTRL_RX_FIFO | RESET_CTRL_TX_FIFO | RESET_CTRL_RESP_QUEUE | RESET_CTRL_CMD_QUEUE; pub const RESPONSE_QUEUE_PORT: u32 = 0x10; pub const RESPONSE_PORT_ERR_STATUS_SHIFT: u32 = 28; @@ -369,8 +369,9 @@ impl<'a> I3cIbi<'a> { #[inline] #[must_use] pub fn payload_len(&self) -> u8 { - self.payload - .map_or(0, |p| u8::try_from(p.len().min(u8::MAX as usize)).unwrap_or(u8::MAX)) + self.payload.map_or(0, |p| { + u8::try_from(p.len().min(u8::MAX as usize)).unwrap_or(u8::MAX) + }) } #[must_use] @@ -862,10 +863,10 @@ impl HardwareInterface for Ast1060I3c { self.i3c .i3cd004() .write(|w| unsafe { w.dev_static_addr().bits(9).static_addr_valid().set_bit() }); - } else { - self.i3c - .i3cd004() - .write(|w| unsafe { w.dev_dynamic_addr().bits(8).dynamic_addr_valid().set_bit() }); + } else { + self.i3c + .i3cd004() + .write(|w| unsafe { w.dev_dynamic_addr().bits(8).dynamic_addr_valid().set_bit() }); } self.i3c_enable(config); @@ -984,10 +985,10 @@ impl HardwareInterface for Ast1060I3c { self.i3c .i3cd0b0() .modify(|_, w| unsafe { w.dev_op_mode().bits(1) }); - } else { - self.i3c - .i3cd0b0() - .modify(|_, w| unsafe { w.dev_op_mode().bits(0) }); + } else { + self.i3c + .i3cd0b0() + .modify(|_, w| unsafe { w.dev_op_mode().bits(0) }); } } @@ -1026,9 +1027,12 @@ impl HardwareInterface for Ast1060I3c { // I3C PP let hcnt = config.i3c_pp_scl_hi_period_ns.div_ceil(config.core_period); let lcnt = config.i3c_pp_scl_lo_period_ns.div_ceil(config.core_period); - self.i3c - .i3cd0b8() - .write(|w| unsafe { w.i3cpphcnt().bits(u8::try_from(hcnt).unwrap_or(u8::MAX)).i3cpplcnt().bits(u8::try_from(lcnt).unwrap_or(u8::MAX)) }); + self.i3c.i3cd0b8().write(|w| unsafe { + w.i3cpphcnt() + .bits(u8::try_from(hcnt).unwrap_or(u8::MAX)) + .i3cpplcnt() + .bits(u8::try_from(lcnt).unwrap_or(u8::MAX)) + }); // SDA TX hold time let mut lcnt: u32 = (config.sda_tx_hold_ns) @@ -1182,7 +1186,11 @@ impl HardwareInterface for Ast1060I3c { fn i3c_bus_init(&mut self, config: &mut I3cConfig) { i3c_debug!(self.logger, "i3c bus init"); let rc = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActResetWholeTarget); - if let Ok(()) = rc {} else { let _ = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActPeriphralOnly); return; } + if let Ok(()) = rc { + } else { + let _ = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActPeriphralOnly); + return; + } let _ = ccc_rstdaa_all(self, config); let events = I3C_CCC_EVT_ALL; @@ -1288,7 +1296,7 @@ impl HardwareInterface for Ast1060I3c { self.i3c .i3cd014() .write(|w| unsafe { w.tx_data_port().bits(word) }); - } + } let rem = chunks.remainder(); if !rem.is_empty() { @@ -1536,7 +1544,11 @@ impl HardwareInterface for Ast1060I3c { } #[allow(clippy::too_many_lines)] - fn do_ccc(&mut self, config: &mut I3cConfig, payload: &mut CccPayload<'_, '_>) -> Result<(), I3cDrvError> { + fn do_ccc( + &mut self, + config: &mut I3cConfig, + payload: &mut CccPayload<'_, '_>, + ) -> Result<(), I3cDrvError> { // init i3c_cmd to all 0 let mut cmds = [I3cCmd { cmd_lo: 0, @@ -1553,7 +1565,9 @@ impl HardwareInterface for Ast1060I3c { let mut is_broadcast = false; let (id, data_len) = { - let Some(ccc) = payload.ccc.as_ref() else { return Err(I3cDrvError::Invalid) }; + let Some(ccc) = payload.ccc.as_ref() else { + return Err(I3cDrvError::Invalid); + }; (ccc.id, ccc.data.as_deref().map_or(0, <[u8]>::len)) }; @@ -1587,9 +1601,9 @@ impl HardwareInterface for Ast1060I3c { .as_ref() .and_then(|ts| ts.first()) .map(|t| t.addr) - else { - return Err(I3cDrvError::Invalid); - }; + else { + return Err(I3cDrvError::Invalid); + }; // -------- Direct CCC -------- let pos_ops = config.attached.pos_of_addr(tgt_addr); i3c_debug!( @@ -1609,17 +1623,16 @@ impl HardwareInterface for Ast1060I3c { pos ); - let Some(tp) = payload.targets.as_deref_mut().and_then(|ts| ts.first_mut()) - else { - return Err(I3cDrvError::Invalid); - }; + let Some(tp) = payload.targets.as_deref_mut().and_then(|ts| ts.first_mut()) else { + return Err(I3cDrvError::Invalid); + }; rnw = tp.rnw; if rnw { let len = tp.data.as_deref().map_or(0, <[u8]>::len); if len == 0 { - return Err(I3cDrvError::Invalid) + return Err(I3cDrvError::Invalid); } cmd.rx_len = u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?; cmd.rx = tp.data.as_deref_mut(); @@ -1705,12 +1718,12 @@ impl HardwareInterface for Ast1060I3c { | field_prep(COMMAND_PORT_DEV_INDEX, pos) | COMMAND_PORT_ROC | COMMAND_PORT_TOC, - cmd_hi: field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_ARG), - tx: None, - rx: None, - tx_len: 0, - rx_len: 0, - ret: 0, + cmd_hi: field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_ARG), + tx: None, + rx: None, + tx_len: 0, + rx_len: 0, + ret: 0, }; i3c_debug!( @@ -1783,15 +1796,20 @@ impl HardwareInterface for Ast1060I3c { let cmd = &mut cmds[i]; *cmd = I3cCmd { cmd_hi: field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_XFER_ARG) - | field_prep(COMMAND_PORT_ARG_DATA_LEN, u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?), - cmd_lo: field_prep(COMMAND_PORT_TID, u32::try_from(i).map_err(|_| I3cDrvError::Invalid)?) - | field_prep(COMMAND_PORT_DEV_INDEX, u32::from(pos)) - | COMMAND_PORT_ROC, - tx: None, - rx: None, - tx_len: 0, - rx_len: 0, - ret: 0, + | field_prep( + COMMAND_PORT_ARG_DATA_LEN, + u32::try_from(len).map_err(|_| I3cDrvError::Invalid)?, + ), + cmd_lo: field_prep( + COMMAND_PORT_TID, + u32::try_from(i).map_err(|_| I3cDrvError::Invalid)?, + ) | field_prep(COMMAND_PORT_DEV_INDEX, u32::from(pos)) + | COMMAND_PORT_ROC, + tx: None, + rx: None, + tx_len: 0, + rx_len: 0, + ret: 0, }; if is_read { @@ -1836,11 +1854,11 @@ impl HardwareInterface for Ast1060I3c { ret: 0, }) .unwrap(); - } + } let ret = self.priv_xfer_build_cmds(cmds.as_mut_slice(), msgs, pos); match ret { - Ok(()) => {}, + Ok(()) => {} Err(e) => return Err(e), } @@ -1873,7 +1891,10 @@ impl HardwareInterface for Ast1060I3c { fn target_tx_write(&mut self, buf: &[u8]) { self.wr_tx_fifo(buf); let cmd = field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_SLAVE_DATA_CMD) - | field_prep(COMMAND_PORT_ARG_DATA_LEN, u32::try_from(buf.len()).map_or(0, |v| v)) + | field_prep( + COMMAND_PORT_ARG_DATA_LEN, + u32::try_from(buf.len()).map_or(0, |v| v), + ) | field_prep(COMMAND_PORT_TID, Tid::TargetRdData as u32); self.i3c.i3cd00c().write(|w| unsafe { w.bits(cmd) }); @@ -2067,7 +2088,8 @@ impl HardwareInterface for Ast1060I3c { } } - let payload_len = u32::try_from(notifier.payload.map_or(0, <[u8]>::len)).map_err(|_| I3cDrvError::Invalid)?; + let payload_len = u32::try_from(notifier.payload.map_or(0, <[u8]>::len)) + .map_err(|_| I3cDrvError::Invalid)?; let cmd: u32 = field_prep(COMMAND_PORT_ATTR, COMMAND_ATTR_SLAVE_DATA_CMD) | field_prep(COMMAND_PORT_ARG_DATA_LEN, payload_len) | field_prep(COMMAND_PORT_TID, Tid::TargetIbi as u32); @@ -2086,24 +2108,27 @@ impl HardwareInterface for Ast1060I3c { let mut delay = DummyDelay {}; - if !config.target_ibi_done.wait_for_us(1_000_000_000, &mut delay) { + if !config + .target_ibi_done + .wait_for_us(1_000_000_000, &mut delay) + { i3c_debug!(self.logger, "SIR timeout! Reset I3C controller"); self.enter_halt(false, config); self.reset_ctrl(RESET_CTRL_QUEUES); self.exit_halt(config); - return Err(I3cDrvError::IoError) + return Err(I3cDrvError::IoError); } if !config .target_data_done - .wait_for_us(1_000_000_000, &mut delay) + .wait_for_us(1_000_000_000, &mut delay) { // C: wait master read timeout -> disable/reset/enable queues i3c_debug!(self.logger, "wait master read timeout! Reset queues"); self.i3c_disable(config.is_secondary); self.reset_ctrl(RESET_CTRL_QUEUES); self.i3c_enable(config); - return Err(I3cDrvError::Timeout) + return Err(I3cDrvError::Timeout); } Ok(()) diff --git a/src/i3c/ccc.rs b/src/i3c/ccc.rs index bde0477..0372dfb 100644 --- a/src/i3c/ccc.rs +++ b/src/i3c/ccc.rs @@ -130,7 +130,12 @@ const fn i3c_ccc_rstact(broadcast: bool) -> u8 { } } -pub fn ccc_events_all_set(hw: &mut H, config: &mut I3cConfig, enable: bool, events: u8) -> Result<(), CccError> +pub fn ccc_events_all_set( + hw: &mut H, + config: &mut I3cConfig, + enable: bool, + events: u8, +) -> Result<(), CccError> where H: HardwareInterface, { @@ -157,7 +162,13 @@ where } } -pub fn ccc_events_set( hw: &mut H, config: &mut I3cConfig, da: u8, enable: bool, events: u8,) -> Result<(), CccError> +pub fn ccc_events_set( + hw: &mut H, + config: &mut I3cConfig, + da: u8, + enable: bool, + events: u8, +) -> Result<(), CccError> where H: HardwareInterface, { @@ -197,7 +208,11 @@ where } } -pub fn ccc_rstact_all(hw: &mut H, config: &mut I3cConfig, action: CccRstActDefByte) -> Result<(), CccError> +pub fn ccc_rstact_all( + hw: &mut H, + config: &mut I3cConfig, + action: CccRstActDefByte, +) -> Result<(), CccError> where H: HardwareInterface, { @@ -254,7 +269,12 @@ where } } -pub fn ccc_setnewda(hw: &mut H, config: &mut I3cConfig, curr_da: u8, new_da: u8) -> Result<(), CccError> +pub fn ccc_setnewda( + hw: &mut H, + config: &mut I3cConfig, + curr_da: u8, + new_da: u8, +) -> Result<(), CccError> where H: HardwareInterface, { @@ -290,8 +310,8 @@ where let rc = hw.do_ccc(config, &mut payload); match rc { - Ok(()) => Ok(()), - _ => Err(CccError::Invalid), + Ok(()) => Ok(()), + _ => Err(CccError::Invalid), } } @@ -388,7 +408,6 @@ where _ => Err(CccError::Invalid), } - } pub fn ccc_getstatus_fmt1(hw: &mut H, config: &mut I3cConfig, da: u8) -> Result diff --git a/src/i3c/i3c_config.rs b/src/i3c/i3c_config.rs index cd35442..fd0cd66 100644 --- a/src/i3c/i3c_config.rs +++ b/src/i3c/i3c_config.rs @@ -5,7 +5,6 @@ use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering}; use embedded_hal::delay::DelayNs; use heapless::Vec; - #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum I3cConfigError { AddrInUse, @@ -151,7 +150,9 @@ impl Attached { pub fn attach(&mut self, dev: DeviceEntry) -> Result { let idx = self.devices.len(); - self.devices.push(dev).map_err(|_| I3cConfigError::NoFreeSlot)?; + self.devices + .push(dev) + .map_err(|_| I3cConfigError::NoFreeSlot)?; Ok(idx) } diff --git a/src/i3c/i3c_controller.rs b/src/i3c/i3c_controller.rs index 3d08d22..0cc37ed 100644 --- a/src/i3c/i3c_controller.rs +++ b/src/i3c/i3c_controller.rs @@ -34,7 +34,12 @@ impl I3cController { ctrl.hw.i3c_aspeed_isr(&mut ctrl.config); } - pub fn attach_i3c_dev(&mut self, pid: u64, desired_da: u8, slot: u8) -> Result<(), AttachError> { + pub fn attach_i3c_dev( + &mut self, + pid: u64, + desired_da: u8, + slot: u8, + ) -> Result<(), AttachError> { if desired_da == 0 || desired_da >= I3C_BROADCAST_ADDR { return Err(AttachError::OutOfRange); } @@ -61,14 +66,15 @@ impl I3cController { .attached .attach(dev) .map_err(|_| AttachError::AddrInUse)?; - self.config.attached.map_pos(slot, u8::try_from(idx).map_err(|_| AttachError::OutOfRange)?); + self.config.attached.map_pos( + slot, + u8::try_from(idx).map_err(|_| AttachError::OutOfRange)?, + ); self.config.addrbook.mark_use(desired_da, true); let rc = self.hw.attach_i3c_dev(slot.into(), desired_da); match rc { Ok(()) => Ok(()), - Err(_) => { - Err(AttachError::AddrInUse) - } + Err(_) => Err(AttachError::AddrInUse), } } diff --git a/src/i3c/ibi_workq.rs b/src/i3c/ibi_workq.rs index 70be7b6..6b4b8f3 100644 --- a/src/i3c/ibi_workq.rs +++ b/src/i3c/ibi_workq.rs @@ -103,8 +103,7 @@ pub fn i3c_ibi_work_enqueue_target_irq(bus: usize, addr: u8, data: &[u8]) { let _ = p.enqueue(IbiWork::Sirq { addr, // len: take as u8, - len: u8::try_from(take).map_err(|_| ()) - .unwrap_or(IBI_DATA_MAX), + len: u8::try_from(take).map_err(|_| ()).unwrap_or(IBI_DATA_MAX), data: ibi_buf, }); } diff --git a/src/main.rs b/src/main.rs index c250a0d..ebe75fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -101,7 +101,6 @@ fn test_wdt(uart: &mut UartController<'_>) { } } - #[cfg(any(feature = "i3c_master", feature = "i3c_target"))] fn release_bmc_spi(uart: &mut UartController<'_>) { uart.write_all(b"\r\n####### SPIM0 setup #######\r\n") From 28790bd97daf97aefdfe4c4fe169d407f1ab3127 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Fri, 17 Oct 2025 13:43:05 +0800 Subject: [PATCH 3/7] i3c: Remove hardcoded timing settings Remove hardcoded timing settings. Signed-off-by: Steven Lee --- src/i3c/ast1060_i3c.rs | 118 +++++++++++++++++------------------------ src/main.rs | 7 +++ 2 files changed, 55 insertions(+), 70 deletions(-) diff --git a/src/i3c/ast1060_i3c.rs b/src/i3c/ast1060_i3c.rs index db115f8..41439bb 100644 --- a/src/i3c/ast1060_i3c.rs +++ b/src/i3c/ast1060_i3c.rs @@ -2,9 +2,7 @@ use crate::common::{DummyDelay, Logger}; use crate::i3c::ccc::{ - ccc_events_all_set, ccc_events_set, ccc_rstact_all, ccc_rstdaa_all, CccPayload, - CccRstActDefByte, I3C_CCC_DEVCTRL, I3C_CCC_ENTDAA, I3C_CCC_EVT_ALL, I3C_CCC_EVT_HJ, - I3C_CCC_EVT_INTR, I3C_CCC_SETHID, + ccc_events_set, CccPayload, I3C_CCC_DEVCTRL, I3C_CCC_ENTDAA, I3C_CCC_EVT_INTR, I3C_CCC_SETHID, }; use crate::i3c::i3c_config::{Completion, I3cConfig}; use crate::i3c::ibi_workq; @@ -40,6 +38,7 @@ pub const I3C_BUS_THIGH_MAX_NS: u32 = 41; pub const NSEC_PER_SEC: u32 = 1_000_000_000; pub const SDA_TX_HOLD_MIN: u32 = 0b001; pub const SDA_TX_HOLD_MAX: u32 = 0b111; +pub const SDA_TX_HOLD_MASK: u32 = 0x0007_0000; // bits 18:16 pub const SLV_DCR_MASK: u32 = 0x0000_ff00; pub const SLV_EVENT_CTRL: u32 = 0x38; @@ -401,7 +400,6 @@ pub trait HardwareInterface { fn exit_sw_mode(&mut self); fn i3c_toggle_scl_in(&mut self, count: u32); fn gen_internal_stop(&mut self); - fn i3c_bus_init(&mut self, config: &mut I3cConfig); fn even_parity(byte: u8) -> bool; fn set_ibi_mdb(&mut self, mdb: u8); fn exit_halt(&mut self, config: &mut I3cConfig); @@ -424,7 +422,6 @@ pub trait HardwareInterface { fn attach_i3c_dev(&mut self, pos: usize, addr: u8) -> Result<(), I3cDrvError>; fn do_ccc(&mut self, config: &mut I3cConfig, ccc: &mut CccPayload) -> Result<(), I3cDrvError>; fn do_entdaa(&mut self, config: &mut I3cConfig, index: u32) -> Result<(), I3cDrvError>; - fn handle_unsolicited(&mut self, config: &mut I3cConfig); fn priv_xfer_build_cmds<'a>( &mut self, cmds: &mut [I3cCmd<'a>], @@ -845,12 +842,6 @@ impl HardwareInterface for Ast1060I3c { i3c_dat_write!(self, i, |w| { w.sirreject().set_bit().mrreject().set_bit() }); - i3c_debug!( - self.logger, - "dat_addr[{}] = {:#x}", - i, - i3c_dat_read!(self, i) - ); } self.i3c.i3cd02c().write(|w| unsafe { w.bits(0xffff_ffff) }); @@ -871,11 +862,6 @@ impl HardwareInterface for Ast1060I3c { self.i3c_enable(config); - // Perform bus initialization - if !config.is_secondary { - self.i3c_bus_init(config); - } - i3c_debug!(self.logger, "i3c enabled"); // Enable hot-join if !config.is_secondary { @@ -995,52 +981,77 @@ impl HardwareInterface for Ast1060I3c { fn init_clock(&mut self, config: &mut I3cConfig) { let clk_rate = self.get_clock_rate(); i3c_debug!(self.logger, "i3c clock rate: {} Hz", clk_rate); - config.core_period = (1_000_000_000_u32).div_ceil(clk_rate); + config.core_period = (NSEC_PER_SEC).div_ceil(clk_rate); + + let ns_to_cnt_u8 = + |ns: u32| -> u8 { u8::try_from(ns.div_ceil(config.core_period)).unwrap_or(u8::MAX) }; + let ns_to_cnt_u16 = + |ns: u32| -> u16 { u16::try_from(ns.div_ceil(config.core_period)).unwrap_or(u16::MAX) }; // I2C FM - let (i2c_hi, i2c_lo) = self.calc_i2c_clk(config.i2c_scl_hz); - let hcnt: u32 = i2c_hi.div_ceil(config.core_period); - let lcnt: u32 = i2c_lo.div_ceil(config.core_period); + let (fm_hi_ns, fm_lo_ns) = self.calc_i2c_clk(config.i2c_scl_hz); self.i3c.i3cd0bc().write(|w| unsafe { w.i2cfmhcnt() - .bits(u16::try_from(hcnt).unwrap_or(u16::MAX)) + .bits(ns_to_cnt_u16(fm_hi_ns)) .i2cfmlcnt() - .bits(u16::try_from(lcnt).unwrap_or(u16::MAX)) + .bits(ns_to_cnt_u16(fm_lo_ns)) }); // I2C FMP - let (i2c_hi, i2c_lo) = self.calc_i2c_clk(1_000_000); - let hcnt: u32 = i2c_hi.div_ceil(config.core_period); - let lcnt: u32 = i2c_lo.div_ceil(config.core_period); + let (i2c_fmp_hi_ns, i2c_fmp_lo_ns) = self.calc_i2c_clk(1_000_000); self.i3c.i3cd0c0().write(|w| unsafe { w.i2cfmphcnt() - .bits(u8::try_from(hcnt).unwrap_or(u8::MAX)) + .bits(ns_to_cnt_u8(i2c_fmp_hi_ns)) .i2cfmplcnt() - .bits(u16::try_from(lcnt).unwrap_or(u16::MAX)) + .bits(ns_to_cnt_u16(i2c_fmp_lo_ns)) }); // I3C OD - self.i3c - .i3cd0b4() - .write(|w| unsafe { w.i3codhcnt().bits(0x64).i3codlcnt().bits(0x64) }); + let (od_hi_ns, od_lo_ns) = + if config.i3c_od_scl_hi_period_ns != 0 && config.i3c_od_scl_lo_period_ns != 0 { + ( + config.i3c_od_scl_hi_period_ns, + config.i3c_od_scl_lo_period_ns, + ) + } else { + (i2c_fmp_hi_ns, i2c_fmp_lo_ns) + }; + self.i3c.i3cd0b4().write(|w| unsafe { + w.i3codhcnt() + .bits(ns_to_cnt_u8(od_hi_ns)) + .i3codlcnt() + .bits(ns_to_cnt_u8(od_lo_ns)) + }); // I3C PP - let hcnt = config.i3c_pp_scl_hi_period_ns.div_ceil(config.core_period); - let lcnt = config.i3c_pp_scl_lo_period_ns.div_ceil(config.core_period); + let (i3c_pp_hi_ns, i3c_pp_lo_ns) = + if config.i3c_pp_scl_hi_period_ns != 0 && config.i3c_pp_scl_lo_period_ns != 0 { + ( + config.i3c_pp_scl_hi_period_ns, + config.i3c_pp_scl_lo_period_ns, + ) + } else { + let total_ns = NSEC_PER_SEC.div_ceil(config.i3c_scl_hz.max(1)); + let hi_ns = core::cmp::min(I3C_BUS_THIGH_MAX_NS, total_ns.saturating_sub(1)); + let lo_ns = total_ns.saturating_sub(hi_ns).max(1); + (hi_ns, lo_ns) + }; self.i3c.i3cd0b8().write(|w| unsafe { w.i3cpphcnt() - .bits(u8::try_from(hcnt).unwrap_or(u8::MAX)) + .bits(ns_to_cnt_u8(i3c_pp_hi_ns)) .i3cpplcnt() - .bits(u8::try_from(lcnt).unwrap_or(u8::MAX)) + .bits(ns_to_cnt_u8(i3c_pp_lo_ns)) }); // SDA TX hold time - let mut lcnt: u32 = (config.sda_tx_hold_ns) + let hold_steps = (config.sda_tx_hold_ns) .div_ceil(config.core_period) .clamp(SDA_TX_HOLD_MIN, SDA_TX_HOLD_MAX); + let mut reg = self.i3c.i3cd0d0().read().bits(); + reg = (reg & !SDA_TX_HOLD_MASK) | ((hold_steps & 0x7) << 16); + self.i3c.i3cd0d0().write(|w| unsafe { w.bits(reg) }); - lcnt &= 0xfff8_ffff; - self.i3c.i3cd0d0().write(|w| unsafe { w.bits(lcnt) }); + // BUS_FREE_TIMING self.i3c.i3cd0d4().write(|w| unsafe { w.bits(0xffff_007c) }); } @@ -1125,25 +1136,14 @@ impl HardwareInterface for Ast1060I3c { .enbl_i3cctrl() .set_bit() }); - i3c_debug!( - self.logger, - "1 i3c i3cd000: {:#x}", - self.i3c.i3cd000().read().bits() - ); let wait_cnt = &self.i3c.i3cd0d4().read().i3cibifree().bits(); let wait_ns = u32::from(*wait_cnt) * config.core_period; let mut delay = DummyDelay {}; - i3c_debug!(self.logger, "wait_ns: {}", wait_ns); delay.delay_ns(wait_ns * 100_u32); self.i3c_toggle_scl_in(8); if self.i3c.i3cd000().read().enbl_i3cctrl().bit_is_set() { self.gen_internal_stop(); } - i3c_debug!( - self.logger, - "2 i3c i3cd000: {:#x}", - self.i3c.i3cd000().read().bits() - ); self.exit_sw_mode(); } else { self.i3c.i3cd000().modify(|_, w| { @@ -1183,22 +1183,6 @@ impl HardwareInterface for Ast1060I3c { }); } - fn i3c_bus_init(&mut self, config: &mut I3cConfig) { - i3c_debug!(self.logger, "i3c bus init"); - let rc = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActResetWholeTarget); - if let Ok(()) = rc { - } else { - let _ = ccc_rstact_all(self, config, CccRstActDefByte::CccRstActPeriphralOnly); - return; - } - - let _ = ccc_rstdaa_all(self, config); - let events = I3C_CCC_EVT_ALL; - let _ = ccc_events_all_set(self, config, false, events); - let _ = ccc_events_all_set(self, config, true, I3C_CCC_EVT_HJ); - i3c_debug!(self.logger, "i3c bus init done"); - } - fn even_parity(byte: u8) -> bool { let mut parity = false; let mut b = byte; @@ -1398,7 +1382,6 @@ impl HardwareInterface for Ast1060I3c { let prev = config .curr_xfer .swap(core::ptr::from_mut(xfer).cast::<()>(), Ordering::AcqRel); - // debug_assert!(prev.is_null(), "previous xfer still in flight"); if !prev.is_null() { i3c_debug!(self.logger, "start_xfer: previous xfer still in flight"); } @@ -1757,10 +1740,6 @@ impl HardwareInterface for Ast1060I3c { } } - fn handle_unsolicited(&mut self, _config: &mut I3cConfig) { - // todo - } - fn priv_xfer_build_cmds<'a>( &mut self, cmds: &mut [I3cCmd<'a>], @@ -2123,7 +2102,6 @@ impl HardwareInterface for Ast1060I3c { .target_data_done .wait_for_us(1_000_000_000, &mut delay) { - // C: wait master read timeout -> disable/reset/enable queues i3c_debug!(self.logger, "wait master read timeout! Reset queues"); self.i3c_disable(config.is_secondary); self.reset_ctrl(RESET_CTRL_QUEUES); diff --git a/src/main.rs b/src/main.rs index ebe75fc..8a8f923 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,12 +8,17 @@ use core::sync::atomic::AtomicBool; use aspeed_ddk::uart::{Config, UartController}; use aspeed_ddk::watchdog::WdtController; use ast1060_pac::Peripherals; +#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] +use ast1060_pac::Spipf; use ast1060_pac::{Wdt, Wdt1}; use aspeed_ddk::ecdsa::AspeedEcdsa; use aspeed_ddk::hace_controller::HaceController; use aspeed_ddk::rsa::AspeedRsa; use aspeed_ddk::spi; + +#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] +use aspeed_ddk::spimonitor::{RegionInfo, SpiMonitor, SpimExtMuxSel}; use aspeed_ddk::syscon::{ClockId, ResetId, SysCon}; use fugit::MillisDurationU32 as MilliSeconds; @@ -22,6 +27,8 @@ use aspeed_ddk::tests::functional::gpio_test; use aspeed_ddk::tests::functional::hash_test::run_hash_tests; use aspeed_ddk::tests::functional::hmac_test::run_hmac_tests; use aspeed_ddk::tests::functional::i2c_test; +#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] +use aspeed_ddk::tests::functional::i3c_test; use aspeed_ddk::tests::functional::rsa_test::run_rsa_tests; use aspeed_ddk::tests::functional::timer_test::run_timer_tests; use panic_halt as _; From 73b6b7b44a0de9fdcf041fc853a8afe8a7824c11 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Thu, 23 Oct 2025 16:52:30 +0800 Subject: [PATCH 4/7] i3c_master: update functional test case for prot evb Originally, the I3C functional test cases were designed for the DCSCM card. This update adjust them to work with the ast1060_prot EVB. Signed-off-by: Steven Lee --- ast10x0.bin | Bin 0 -> 110552 bytes slee@sleepi4.local | 149 +++++++++++++++++++++++++++++++ src/i3c/ast1060_i3c.rs | 9 -- src/main.rs | 53 ----------- src/pinctrl.rs | 5 ++ src/tests/functional/i3c_test.rs | 45 ++++++++-- uart_ast10x0.bin | Bin 0 -> 110556 bytes 7 files changed, 192 insertions(+), 69 deletions(-) create mode 100755 ast10x0.bin create mode 100644 slee@sleepi4.local create mode 100644 uart_ast10x0.bin diff --git a/ast10x0.bin b/ast10x0.bin new file mode 100755 index 0000000000000000000000000000000000000000..e6daf01d39ca3928b8a8e0fd0ecc0f8e906fd599 GIT binary patch literal 110552 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%0At!j$25IOgGD@tPoSog3Ni5xXibw1ahU8 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 B=I8(b literal 0 HcmV?d00001 diff --git a/slee@sleepi4.local b/slee@sleepi4.local new file mode 100644 index 0000000..cbaf0f9 --- /dev/null +++ b/slee@sleepi4.local @@ -0,0 +1,149 @@ +# If you come from bash you might have to change your $PATH. +# export PATH=$HOME/bin:/usr/local/bin:$PATH + +# Path to your oh-my-zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +# Set name of the theme to load --- if set to "random", it will +# load a random theme each time oh-my-zsh is loaded, in which case, +# to know which specific one was loaded, run: echo $RANDOM_THEME +# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes +# ZSH_THEME="oxide" +ZSH_THEME="dpoggi" +# ZSH_THEME="half-life" +# ZSH_THEME="kafeitu" + +# Set list of themes to pick from when loading at random +# Setting this variable when ZSH_THEME=random will cause zsh to load +# a theme from this variable instead of looking in $ZSH/themes/ +# If set to an empty array, this variable will have no effect. +# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. +# Case-sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment one of the following lines to change the auto-update behavior +zstyle ':omz:update' mode disabled # disable automatic updates +# zstyle ':omz:update' mode auto # update automatically without asking +# zstyle ':omz:update' mode reminder # just remind me to update when it's time + +# Uncomment the following line to change how often to auto-update (in days). +# zstyle ':omz:update' frequency 13 + +# Uncomment the following line if pasting URLs and other text is messed up. +DISABLE_MAGIC_FUNCTIONS="true" + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# You can set one of the optional three formats: +# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# or set a custom format using the strftime function format specifications, +# see 'man strftime' for details. +# HIST_STAMPS="mm/dd/yyyy" + +# Would you like to use another custom folder than $ZSH/custom? +# ZSH_CUSTOM=/path/to/new-custom-folder + +# Which plugins would you like to load? +# Standard plugins can be found in $ZSH/plugins/ +# Custom plugins may be added to $ZSH_CUSTOM/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=( + git + ) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +# if [[ -n $SSH_CONNECTION ]]; then +# export EDITOR='vim' +# else +# export EDITOR='mvim' +# fi + +# Compilation flags +# export ARCHFLAGS="-arch x86_64" + +# Set personal aliases, overriding those provided by oh-my-zsh libs, +# plugins, and themes. Aliases can be placed here, though oh-my-zsh +# users are encouraged to define aliases within the ZSH_CUSTOM folder. +# For a full list of active aliases, run `alias`. +# +# Example aliases +# alias zshconfig="mate ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" +. "$HOME/.cargo/env" + +obmc_autojump() { + cd $(python3 ~/jj.py $1 $2) +} + +# alias jj='source ~/jj.sh' +alias nvim=~/nvim-linux-x86_64/bin/nvim +alias vim='nvim' +alias vimdiff='nvim -d' +export PATH=~/.local/bin:"$PATH" +export PATH=~/.local/usr/bin:"$PATH" +export LD_LIBRARY_PATH=~/.local/lib:~/.local/usr/lib + +alias jj=obmc_autojump + +alias ls='lsd' +alias l='ls -l' +alias la='ls -a' +alias lla='ls -la' +alias lt='ls --tree' +alias ll='ls -alF' +alias llb='ls -l --size=bytes' +alias tio=/usr/local/bin/tio +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion +. "$HOME/.cargo/env" + +source ~/.zplug/init.zsh + +# Set the priority when loading +# e.g., zsh-syntax-highlighting must be loaded +# after executing compinit command and sourcing other plugins +# (If the defer tag is given 2 or above, run after compinit command) +zplug "zsh-users/zsh-syntax-highlighting", defer:2 +zplug "zsh-users/zsh-autosuggestions" + +bindkey '^n' autosuggest-execute + +zplug load + +[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh diff --git a/src/i3c/ast1060_i3c.rs b/src/i3c/ast1060_i3c.rs index 41439bb..5028ad2 100644 --- a/src/i3c/ast1060_i3c.rs +++ b/src/i3c/ast1060_i3c.rs @@ -1402,11 +1402,6 @@ impl HardwareInterface for Ast1060I3c { w.response_buffer_threshold_value() .bits(u8::try_from(xfer.cmds.len().saturating_sub(1)).unwrap_or(0)) }); - i3c_debug!( - self.logger, - "value of i3cd01c: {:#x}", - self.i3c.i3cd01c().read().bits() - ); for cmd in xfer.cmds.iter() { i3c_debug!( @@ -1908,7 +1903,6 @@ impl HardwareInterface for Ast1060I3c { } fn handle_ibis(&mut self, config: &mut I3cConfig) { - i3c_debug!(self.logger, "handle_ibis"); let nibis = self.i3c.i3cd04c().read().ibistatuscnt().bits(); i3c_debug!(self.logger, "Number of IBIs: {}", nibis); @@ -1978,16 +1972,13 @@ impl HardwareInterface for Ast1060I3c { self.target_handle_ccc_update(config); } } else { - i3c_debug!(self.logger, "Primary controller interrupt"); if (status & (INTR_RESP_READY_STAT | INTR_TRANSFER_ERR_STAT | INTR_TRANSFER_ABORT_STAT)) != 0 { - i3c_debug!(self.logger, "Transfer complete/err/abort"); self.end_xfer(config); } if (status & INTR_IBI_THLD_STAT) != 0 { - i3c_debug!(self.logger, "IBI threshold reached"); self.handle_ibis(config); } } diff --git a/src/main.rs b/src/main.rs index 8a8f923..4a4b51c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,8 +8,6 @@ use core::sync::atomic::AtomicBool; use aspeed_ddk::uart::{Config, UartController}; use aspeed_ddk::watchdog::WdtController; use ast1060_pac::Peripherals; -#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] -use ast1060_pac::Spipf; use ast1060_pac::{Wdt, Wdt1}; use aspeed_ddk::ecdsa::AspeedEcdsa; @@ -17,8 +15,6 @@ use aspeed_ddk::hace_controller::HaceController; use aspeed_ddk::rsa::AspeedRsa; use aspeed_ddk::spi; -#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] -use aspeed_ddk::spimonitor::{RegionInfo, SpiMonitor, SpimExtMuxSel}; use aspeed_ddk::syscon::{ClockId, ResetId, SysCon}; use fugit::MillisDurationU32 as MilliSeconds; @@ -108,53 +104,6 @@ fn test_wdt(uart: &mut UartController<'_>) { } } -#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] -fn release_bmc_spi(uart: &mut UartController<'_>) { - uart.write_all(b"\r\n####### SPIM0 setup #######\r\n") - .unwrap(); - let allow_cmds: [u8; 27] = [ - 0x03, 0x13, 0x0b, 0x0c, 0x6b, 0x6c, 0x01, 0x05, 0x35, 0x06, 0x04, 0x20, 0x21, 0x9f, 0x5a, - 0xb7, 0xe9, 0x32, 0x34, 0xd8, 0xdc, 0x02, 0x12, 0x15, 0x31, 0x3b, 0x3c, - ]; - - let read_blocked_regions = [RegionInfo { - /*pfm*/ - start: 0x0400_0000, - length: 0x0002_0000, - }]; - - let write_blocked_regions = [RegionInfo { - start: 0x0000_0000, - length: 0x0800_0000, - }]; - let mut spi_monitor0 = SpiMonitor::::new( - true, - SpimExtMuxSel::SpimExtMuxSel1, - &allow_cmds, - u8::try_from(allow_cmds.len()).unwrap(), - &read_blocked_regions, - u8::try_from(read_blocked_regions.len()).unwrap(), - &write_blocked_regions, - u8::try_from(write_blocked_regions.len()).unwrap(), - ); - spi_monitor0.spim_sw_rst(); - spi_monitor0.aspeed_spi_monitor_init(); - spi_monitor0.spim_ext_mux_config(SpimExtMuxSel::SpimExtMuxSel0); - // print spim pointer value -} - -#[cfg(any(feature = "i3c_master", feature = "i3c_target"))] -fn setup_bmc_sequence(uart_controller: &mut UartController) { - // Enable BMC flash power - gpio_test::test_gpio_flash_power(uart_controller); - - // Release BMC SPI - release_bmc_spi(uart_controller); - - // Release BMC Reset - gpio_test::test_gpio_bmc_reset(uart_controller); -} - #[no_mangle] pub static HALT: AtomicBool = AtomicBool::new(true); @@ -415,8 +364,6 @@ fn main() -> ! { i2c_test::test_i2c_master(&mut uart_controller); #[cfg(feature = "i2c_target")] i2c_test::test_i2c_slave(&mut uart_controller); - #[cfg(any(feature = "i3c_master", feature = "i3c_target"))] - setup_bmc_sequence(&mut uart_controller); #[cfg(feature = "i3c_master")] i3c_test::test_i3c_master(&mut uart_controller); #[cfg(feature = "i3c_target")] diff --git a/src/pinctrl.rs b/src/pinctrl.rs index 1694ef8..9399cad 100644 --- a/src/pinctrl.rs +++ b/src/pinctrl.rs @@ -1731,6 +1731,11 @@ paste! { pub const PINCTRL_I3C2: &[PinctrlPin] = &[PIN_SCU418_20, PIN_SCU418_21, CLR_PIN_SCU4B8_12, CLR_PIN_SCU4B8_13]; pub const PINCTRL_I3C3: &[PinctrlPin] = &[PIN_SCU418_22, PIN_SCU418_23, CLR_PIN_SCU4B8_14, CLR_PIN_SCU4B8_15]; + pub const PINCTRL_HVI3C0: &[PinctrlPin] = &[CLR_PIN_SCU418_8, CLR_PIN_SCU418_9, CLR_PIN_SCU418_16, PIN_SCU418_17, PIN_SCU4B8_8, PIN_SCU4B8_9]; + pub const PINCTRL_HVI3C1: &[PinctrlPin] = &[CLR_PIN_SCU418_10, CLR_PIN_SCU418_11, CLR_PIN_SCU418_18, PIN_SCU418_19, PIN_SCU4B8_10, PIN_SCU4B8_11]; + pub const PINCTRL_HVI3C2: &[PinctrlPin] = &[CLR_PIN_SCU418_12, CLR_PIN_SCU418_13, CLR_PIN_SCU418_20, PIN_SCU418_21, PIN_SCU4B8_12, PIN_SCU4B8_13]; + pub const PINCTRL_HVI3C3: &[PinctrlPin] = &[CLR_PIN_SCU418_14, CLR_PIN_SCU418_15, CLR_PIN_SCU418_22, PIN_SCU418_23, PIN_SCU4B8_14, PIN_SCU4B8_15]; + pub const PINCTRL_GPIOA0: &[PinctrlPin] = &[CLR_PIN_SCU410_0, CLR_PIN_SCU4B0_0, CLR_PIN_SCU690_0]; pub const PINCTRL_GPIOA1: &[PinctrlPin] = &[CLR_PIN_SCU410_1, CLR_PIN_SCU4B0_1, CLR_PIN_SCU690_1]; pub const PINCTRL_GPIOA2: &[PinctrlPin] = &[CLR_PIN_SCU410_2, CLR_PIN_SCU4B0_2, CLR_PIN_SCU690_2]; diff --git a/src/tests/functional/i3c_test.rs b/src/tests/functional/i3c_test.rs index 03f7b76..1f4724f 100644 --- a/src/tests/functional/i3c_test.rs +++ b/src/tests/functional/i3c_test.rs @@ -3,7 +3,7 @@ use crate::common::{DummyDelay, NoOpLogger, UartLogger}; use crate::i3c::ast1060_i3c::HardwareInterface; use crate::i3c::ast1060_i3c::I3cMsg; -use crate::i3c::ast1060_i3c::{Ast1060I3c, I3C_MSG_READ, I3C_MSG_STOP}; +use crate::i3c::ast1060_i3c::{Ast1060I3c, I3C_MSG_READ, I3C_MSG_STOP, I3C_MSG_WRITE}; use crate::i3c::i3c_config::I3cConfig; use crate::i3c::i3c_config::I3cTargetConfig; use crate::i3c::i3c_controller::I3cController; @@ -54,7 +54,7 @@ pub fn test_i3c_master(uart: &mut UartController<'_>) { }); } - pinctrl::Pinctrl::apply_pinctrl_group(pinctrl::PINCTRL_I3C2); + pinctrl::Pinctrl::apply_pinctrl_group(pinctrl::PINCTRL_HVI3C2); let hw = Ast1060I3c::::new(UartLogger::new(&mut dbg_uart)); let mut ctrl = I3cController { @@ -77,12 +77,14 @@ pub fn test_i3c_master(uart: &mut UartController<'_>) { } let mut ibi_cons = i3c_ibi_workq_consumer(ctrl.hw.bus_num() as usize); - let known_pid = 0x07ec_0503_1000u64; + // let known_pid = 0x07ec_0503_1000u64; + let known_pid = 0x07ec_a003_2000u64; let ctrl_dev_slot0 = 0; ctrl.init(); let dyn_addr = if let Some(da) = ctrl.config.addrbook.alloc_from(8) { ctrl.attach_i3c_dev(known_pid, da, ctrl_dev_slot0).unwrap(); + ctrl.hw.ibi_enable(&mut ctrl.config, da).unwrap(); writeln!(uart, "Pre-attached dev at slot 0, dyn addr {da}\r").unwrap(); da } else { @@ -93,6 +95,8 @@ pub fn test_i3c_master(uart: &mut UartController<'_>) { // Dump I3C2 registers // dump_i3c_controller_registers(uart, 0x7e7a_4000); writeln!(uart, "ctrl dev at slot 0, dyn addr {dyn_addr}\r").unwrap(); + let mut received_count = 0; + loop { if let Some(work) = ibi_cons.dequeue() { match work { @@ -124,10 +128,37 @@ pub fn test_i3c_master(uart: &mut UartController<'_>) { hdr_cmd_mode: 0, }]; let _ = ctrl.hw.priv_xfer(&mut ctrl.config, known_pid, &mut msgs); - writeln!(uart, " read data:").unwrap(); - for i in 0..msgs[0].actual_len { - write!(uart, " {:02x}", rx_buf[i as usize]).unwrap(); + let rx_len = msgs[0].actual_len as usize; + writeln!( + uart, + "[MASTER <== TARGET] MASTER READ: {:02x?}", + &rx_buf[..rx_len] + ) + .unwrap(); + writeln!(uart, "\r").unwrap(); + received_count += 1; + if received_count > 10 { + writeln!(uart, "I3C master test done\r").unwrap(); + break; } + + // send data to target + let mut tx_buf: [u8; 16] = [ + 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe, 0x11, 0x22, 0x33, 0x44, + 0x55, 0x66, 0x77, 0x88, + ]; + let tx_len = tx_buf.len() as u32; + + let mut tx_msgs = [I3cMsg { + buf: Some(&mut tx_buf[..]), + actual_len: tx_len, + num_xfer: 0, + flags: I3C_MSG_WRITE | I3C_MSG_STOP, + hdr_mode: 0, + hdr_cmd_mode: 0, + }]; + let _ = ctrl.hw.priv_xfer(&mut ctrl.config, known_pid, &mut tx_msgs); + writeln!(uart, "[MASTER ==> TARGET] MASTER WRITE: {:02x?}", tx_buf).unwrap(); writeln!(uart, "\r").unwrap(); } IbiWork::TargetDaAssignment => { @@ -154,7 +185,7 @@ pub fn test_i3c_target(uart: &mut UartController<'_>) { }); } - pinctrl::Pinctrl::apply_pinctrl_group(pinctrl::PINCTRL_I3C2); + pinctrl::Pinctrl::apply_pinctrl_group(pinctrl::PINCTRL_HVI3C2); let hw = Ast1060I3c::::new(UartLogger::new(&mut dbg_uart)); let mut ctrl = I3cController { diff --git a/uart_ast10x0.bin b/uart_ast10x0.bin new file mode 100644 index 0000000000000000000000000000000000000000..f212870eb5e0188bdaa62efab04785978506b936 GIT binary patch literal 110556 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�+b2h>fkV7hU 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%0At!j$25IOgGD@tPoSog3Ni5xXibw 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 EFXa#DZ~y=R literal 0 HcmV?d00001 From 6768d54f7b5aab79a3b3a274a2130c6d4d558c3b Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Thu, 23 Oct 2025 17:07:50 +0800 Subject: [PATCH 5/7] i3c_master: fix clippy issue Signed-off-by: Steven Lee --- src/tests/functional/i3c_test.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/functional/i3c_test.rs b/src/tests/functional/i3c_test.rs index 1f4724f..ce4e47c 100644 --- a/src/tests/functional/i3c_test.rs +++ b/src/tests/functional/i3c_test.rs @@ -38,6 +38,7 @@ pub fn dump_i3c_controller_registers(uart: &mut UartController<'_>, base: u32) { } } +#[allow(clippy::too_many_lines)] pub fn test_i3c_master(uart: &mut UartController<'_>) { let peripherals = unsafe { Peripherals::steal() }; let mut delay = DummyDelay {}; @@ -147,7 +148,7 @@ pub fn test_i3c_master(uart: &mut UartController<'_>) { 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, ]; - let tx_len = tx_buf.len() as u32; + let tx_len = u32::try_from(tx_buf.len()).unwrap(); let mut tx_msgs = [I3cMsg { buf: Some(&mut tx_buf[..]), @@ -158,7 +159,7 @@ pub fn test_i3c_master(uart: &mut UartController<'_>) { hdr_cmd_mode: 0, }]; let _ = ctrl.hw.priv_xfer(&mut ctrl.config, known_pid, &mut tx_msgs); - writeln!(uart, "[MASTER ==> TARGET] MASTER WRITE: {:02x?}", tx_buf).unwrap(); + writeln!(uart, "[MASTER ==> TARGET] MASTER WRITE: {tx_buf:02x?}").unwrap(); writeln!(uart, "\r").unwrap(); } IbiWork::TargetDaAssignment => { From 1683d05418ae0878e0a246abddd55c131a73b722 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Thu, 23 Oct 2025 17:11:07 +0800 Subject: [PATCH 6/7] Removed prebuilt binary Signed-off-by: Steven Lee --- ast10x0.bin | Bin 110552 -> 0 bytes uart_ast10x0.bin | Bin 110556 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 ast10x0.bin delete mode 100644 uart_ast10x0.bin diff --git a/ast10x0.bin b/ast10x0.bin deleted file mode 100755 index e6daf01d39ca3928b8a8e0fd0ecc0f8e906fd599..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110552 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%0At!j$25IOgGD@tPoSog3Ni5xXibw1ahU8 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 B=I8(b diff --git a/uart_ast10x0.bin b/uart_ast10x0.bin deleted file mode 100644 index f212870eb5e0188bdaa62efab04785978506b936..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110556 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�+b2h>fkV7hU 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%0At!j$25IOgGD@tPoSog3Ni5xXibw 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 EFXa#DZ~y=R From 086b44303bd07458f6b650ba9a4327afeb9e5d6f Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Thu, 23 Oct 2025 17:28:31 +0800 Subject: [PATCH 7/7] i3c_target: Update I3C functional test case for prot evb Originally, the I3C functional test cases were designed for the DCSCM card. This update adjust them to work with the ast1060_prot EVB. Signed-off-by: Steven Lee --- slee@sleepi4.local | 149 ------------------------------- src/i3c/ast1060_i3c.rs | 28 +++++- src/i3c/i3c_target.rs | 1 - src/pinctrl.rs | 8 +- src/tests/functional/i3c_test.rs | 19 +++- 5 files changed, 45 insertions(+), 160 deletions(-) delete mode 100644 slee@sleepi4.local diff --git a/slee@sleepi4.local b/slee@sleepi4.local deleted file mode 100644 index cbaf0f9..0000000 --- a/slee@sleepi4.local +++ /dev/null @@ -1,149 +0,0 @@ -# If you come from bash you might have to change your $PATH. -# export PATH=$HOME/bin:/usr/local/bin:$PATH - -# Path to your oh-my-zsh installation. -export ZSH="$HOME/.oh-my-zsh" - -# Set name of the theme to load --- if set to "random", it will -# load a random theme each time oh-my-zsh is loaded, in which case, -# to know which specific one was loaded, run: echo $RANDOM_THEME -# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes -# ZSH_THEME="oxide" -ZSH_THEME="dpoggi" -# ZSH_THEME="half-life" -# ZSH_THEME="kafeitu" - -# Set list of themes to pick from when loading at random -# Setting this variable when ZSH_THEME=random will cause zsh to load -# a theme from this variable instead of looking in $ZSH/themes/ -# If set to an empty array, this variable will have no effect. -# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) - -# Uncomment the following line to use case-sensitive completion. -# CASE_SENSITIVE="true" - -# Uncomment the following line to use hyphen-insensitive completion. -# Case-sensitive completion must be off. _ and - will be interchangeable. -# HYPHEN_INSENSITIVE="true" - -# Uncomment one of the following lines to change the auto-update behavior -zstyle ':omz:update' mode disabled # disable automatic updates -# zstyle ':omz:update' mode auto # update automatically without asking -# zstyle ':omz:update' mode reminder # just remind me to update when it's time - -# Uncomment the following line to change how often to auto-update (in days). -# zstyle ':omz:update' frequency 13 - -# Uncomment the following line if pasting URLs and other text is messed up. -DISABLE_MAGIC_FUNCTIONS="true" - -# Uncomment the following line to disable colors in ls. -# DISABLE_LS_COLORS="true" - -# Uncomment the following line to disable auto-setting terminal title. -DISABLE_AUTO_TITLE="true" - -# Uncomment the following line to enable command auto-correction. -# ENABLE_CORRECTION="true" - -# Uncomment the following line to display red dots whilst waiting for completion. -# You can also set it to another string to have that shown instead of the default red dots. -# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" -# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) -# COMPLETION_WAITING_DOTS="true" - -# Uncomment the following line if you want to disable marking untracked files -# under VCS as dirty. This makes repository status check for large repositories -# much, much faster. -DISABLE_UNTRACKED_FILES_DIRTY="true" - -# Uncomment the following line if you want to change the command execution time -# stamp shown in the history command output. -# You can set one of the optional three formats: -# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" -# or set a custom format using the strftime function format specifications, -# see 'man strftime' for details. -# HIST_STAMPS="mm/dd/yyyy" - -# Would you like to use another custom folder than $ZSH/custom? -# ZSH_CUSTOM=/path/to/new-custom-folder - -# Which plugins would you like to load? -# Standard plugins can be found in $ZSH/plugins/ -# Custom plugins may be added to $ZSH_CUSTOM/plugins/ -# Example format: plugins=(rails git textmate ruby lighthouse) -# Add wisely, as too many plugins slow down shell startup. -plugins=( - git - ) - -source $ZSH/oh-my-zsh.sh - -# User configuration - -# export MANPATH="/usr/local/man:$MANPATH" - -# You may need to manually set your language environment -# export LANG=en_US.UTF-8 - -# Preferred editor for local and remote sessions -# if [[ -n $SSH_CONNECTION ]]; then -# export EDITOR='vim' -# else -# export EDITOR='mvim' -# fi - -# Compilation flags -# export ARCHFLAGS="-arch x86_64" - -# Set personal aliases, overriding those provided by oh-my-zsh libs, -# plugins, and themes. Aliases can be placed here, though oh-my-zsh -# users are encouraged to define aliases within the ZSH_CUSTOM folder. -# For a full list of active aliases, run `alias`. -# -# Example aliases -# alias zshconfig="mate ~/.zshrc" -# alias ohmyzsh="mate ~/.oh-my-zsh" -. "$HOME/.cargo/env" - -obmc_autojump() { - cd $(python3 ~/jj.py $1 $2) -} - -# alias jj='source ~/jj.sh' -alias nvim=~/nvim-linux-x86_64/bin/nvim -alias vim='nvim' -alias vimdiff='nvim -d' -export PATH=~/.local/bin:"$PATH" -export PATH=~/.local/usr/bin:"$PATH" -export LD_LIBRARY_PATH=~/.local/lib:~/.local/usr/lib - -alias jj=obmc_autojump - -alias ls='lsd' -alias l='ls -l' -alias la='ls -a' -alias lla='ls -la' -alias lt='ls --tree' -alias ll='ls -alF' -alias llb='ls -l --size=bytes' -alias tio=/usr/local/bin/tio -export NVM_DIR="$HOME/.nvm" -[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm -[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion -. "$HOME/.cargo/env" - -source ~/.zplug/init.zsh - -# Set the priority when loading -# e.g., zsh-syntax-highlighting must be loaded -# after executing compinit command and sourcing other plugins -# (If the defer tag is given 2 or above, run after compinit command) -zplug "zsh-users/zsh-syntax-highlighting", defer:2 -zplug "zsh-users/zsh-autosuggestions" - -bindkey '^n' autosuggest-execute - -zplug load - -[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh diff --git a/src/i3c/ast1060_i3c.rs b/src/i3c/ast1060_i3c.rs index 5028ad2..233b875 100644 --- a/src/i3c/ast1060_i3c.rs +++ b/src/i3c/ast1060_i3c.rs @@ -439,6 +439,7 @@ pub trait HardwareInterface { fn handle_ibis(&mut self, config: &mut I3cConfig); fn i3c_aspeed_isr(&mut self, config: &mut I3cConfig); // target apis + fn target_ibi_raise_hj(&self, config: &mut I3cConfig) -> Result<(), I3cDrvError>; fn target_handle_response_ready(&mut self, config: &mut I3cConfig); fn target_pending_read_notify( &mut self, @@ -1964,7 +1965,6 @@ impl HardwareInterface for Ast1060I3c { } if (status & INTR_RESP_READY_STAT) != 0 { - i3c_debug!(self.logger, "Response ready"); self.target_handle_response_ready(config); } @@ -1987,6 +1987,25 @@ impl HardwareInterface for Ast1060I3c { self.enable_irq(); } + fn target_ibi_raise_hj(&self, config: &mut I3cConfig) -> Result<(), I3cDrvError> { + if !config.is_secondary { + return Err(I3cDrvError::Invalid); + } + let hj_support = self.i3c.i3cd008().read().slvhjcap().bit(); + if !hj_support { + return Err(I3cDrvError::Invalid); + } + + let addr_valid = self.i3c.i3cd004().read().dynamic_addr_valid().bit(); + if addr_valid { + return Err(I3cDrvError::Access); + } + + self.i3c.i3cd038().write(|w| unsafe { w.bits(8) }); // set HJ request + + Ok(()) + } + fn target_handle_response_ready(&mut self, config: &mut I3cConfig) { let nresp = self.i3c.i3cd04c().read().respbufblr().bits(); @@ -2022,7 +2041,11 @@ impl HardwareInterface for Ast1060I3c { if rx_len != 0 { let mut buf: [u8; 256] = [0u8; 256]; self.rd_rx_fifo(&mut buf[..rx_len]); - i3c_debug!(self.logger, "Response data: {:02x?}", &buf[..rx_len]); + i3c_debug!( + self.logger, + "[MASTER ==> TARGET] TARGET READ: {:02x?}", + &buf[..rx_len] + ); } if tid == Tid::TargetIbi as usize { @@ -2042,7 +2065,6 @@ impl HardwareInterface for Ast1060I3c { notifier: &mut I3cIbi, ) -> Result<(), I3cDrvError> { let reg = self.i3c.i3cd038().read().bits(); - i3c_debug!(self.logger, "target_pending_read_notify: reg=0x{:08x}", reg); if !(config.sir_allowed_by_sw && (reg & SLV_EVENT_CTRL_SIR_EN != 0)) { return Err(I3cDrvError::Access); } diff --git a/src/i3c/i3c_target.rs b/src/i3c/i3c_target.rs index a7d948f..a55bb86 100644 --- a/src/i3c/i3c_target.rs +++ b/src/i3c/i3c_target.rs @@ -54,7 +54,6 @@ impl DynamicAddressable for I3c impl IBICapable for I3cController { fn wants_ibi(&self) -> bool { - // In ast1060, we don't need to tell the controller that we want IBI true } diff --git a/src/pinctrl.rs b/src/pinctrl.rs index 9399cad..732d240 100644 --- a/src/pinctrl.rs +++ b/src/pinctrl.rs @@ -1731,10 +1731,10 @@ paste! { pub const PINCTRL_I3C2: &[PinctrlPin] = &[PIN_SCU418_20, PIN_SCU418_21, CLR_PIN_SCU4B8_12, CLR_PIN_SCU4B8_13]; pub const PINCTRL_I3C3: &[PinctrlPin] = &[PIN_SCU418_22, PIN_SCU418_23, CLR_PIN_SCU4B8_14, CLR_PIN_SCU4B8_15]; - pub const PINCTRL_HVI3C0: &[PinctrlPin] = &[CLR_PIN_SCU418_8, CLR_PIN_SCU418_9, CLR_PIN_SCU418_16, PIN_SCU418_17, PIN_SCU4B8_8, PIN_SCU4B8_9]; - pub const PINCTRL_HVI3C1: &[PinctrlPin] = &[CLR_PIN_SCU418_10, CLR_PIN_SCU418_11, CLR_PIN_SCU418_18, PIN_SCU418_19, PIN_SCU4B8_10, PIN_SCU4B8_11]; - pub const PINCTRL_HVI3C2: &[PinctrlPin] = &[CLR_PIN_SCU418_12, CLR_PIN_SCU418_13, CLR_PIN_SCU418_20, PIN_SCU418_21, PIN_SCU4B8_12, PIN_SCU4B8_13]; - pub const PINCTRL_HVI3C3: &[PinctrlPin] = &[CLR_PIN_SCU418_14, CLR_PIN_SCU418_15, CLR_PIN_SCU418_22, PIN_SCU418_23, PIN_SCU4B8_14, PIN_SCU4B8_15]; + pub const PINCTRL_HVI3C0: &[PinctrlPin] = &[CLR_PIN_SCU418_8, CLR_PIN_SCU418_9, CLR_PIN_SCU418_16, CLR_PIN_SCU418_17, PIN_SCU4B8_8, PIN_SCU4B8_9]; + pub const PINCTRL_HVI3C1: &[PinctrlPin] = &[CLR_PIN_SCU418_10, CLR_PIN_SCU418_11, CLR_PIN_SCU418_18, CLR_PIN_SCU418_19, PIN_SCU4B8_10, PIN_SCU4B8_11]; + pub const PINCTRL_HVI3C2: &[PinctrlPin] = &[CLR_PIN_SCU418_12, CLR_PIN_SCU418_13, CLR_PIN_SCU418_20, CLR_PIN_SCU418_21, PIN_SCU4B8_12, PIN_SCU4B8_13]; + pub const PINCTRL_HVI3C3: &[PinctrlPin] = &[CLR_PIN_SCU418_14, CLR_PIN_SCU418_15, CLR_PIN_SCU418_22, CLR_PIN_SCU418_23, PIN_SCU4B8_14, PIN_SCU4B8_15]; pub const PINCTRL_GPIOA0: &[PinctrlPin] = &[CLR_PIN_SCU410_0, CLR_PIN_SCU4B0_0, CLR_PIN_SCU690_0]; pub const PINCTRL_GPIOA1: &[PinctrlPin] = &[CLR_PIN_SCU410_1, CLR_PIN_SCU4B0_1, CLR_PIN_SCU690_1]; diff --git a/src/tests/functional/i3c_test.rs b/src/tests/functional/i3c_test.rs index ce4e47c..254a307 100644 --- a/src/tests/functional/i3c_test.rs +++ b/src/tests/functional/i3c_test.rs @@ -206,17 +206,28 @@ pub fn test_i3c_target(uart: &mut UartController<'_>) { c.i3c_pp_scl_lo_period_ns = 36; c.i3c_od_scl_hi_period_ns = 0; c.i3c_od_scl_lo_period_ns = 0; - c.sda_tx_hold_ns = 20; + c.sda_tx_hold_ns = 0; + // c.sda_tx_hold_ns = 20; c.dcr = 0xcc; c.target_config = Some(I3cTargetConfig::new(0, Some(0), 0xae)); } let mut ibi_cons = i3c_ibi_workq_consumer(ctrl.hw.bus_num() as usize); ctrl.init(); - let dyn_addr = 9; + let dyn_addr = 8; let dev_idx = 0; let _ = ctrl.hw.attach_i3c_dev(dev_idx, dyn_addr); + writeln!( + uart, + "I3C target dev at slot {dev_idx}, dyn addr {dyn_addr}\r" + ) + .unwrap(); // Dump I3C2 registers // dump_i3c_controller_registers(uart, 0x7e7a_4000); + let mut delay = DummyDelay {}; + delay.delay_ns(4_000_000_000); + writeln!(uart, "waiting for dynamic address assignment...\r").unwrap(); + let _ = ctrl.hw.target_ibi_raise_hj(&mut ctrl.config); + // dump_i3c_controller_registers(uart, 0x7e7a_4000); loop { if let Some(work) = ibi_cons.dequeue() { match work { @@ -254,9 +265,11 @@ pub fn test_i3c_target(uart: &mut UartController<'_>) { *b = u8::try_from(i).unwrap(); } writeln!(uart, "send ibi #{ibi_count}\r").unwrap(); + writeln!(uart, "[MASTER <== TARGET] TARGET WRITE: {data:02x?}").unwrap(); + writeln!(uart, "\r").unwrap(); ctrl.get_ibi_payload(&mut data).unwrap(); ibi_count += 1; - if ibi_count > 100 { + if ibi_count > 10 { break; } }