Skip to content

Commit

Permalink
Set and read I3C addresses in the right fields (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
swenson authored Dec 9, 2024
1 parent d614c01 commit e543a67
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 25 deletions.
16 changes: 9 additions & 7 deletions emulator/periph/src/i3c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Abstract:
--*/

use crate::i3c_protocol::{I3cController, I3cTarget, I3cTcriResponseXfer, ResponseDescriptor};
use crate::{DynamicI3cAddress, I3cIncomingCommandClient, I3cTcriCommand, IbiDescriptor};
use crate::{I3cIncomingCommandClient, I3cTcriCommand, IbiDescriptor};
use emulator_bus::{Clock, ReadWriteRegister, Timer};
use emulator_cpu::Irq;
use emulator_registers_generated::i3c::I3cPeripheral;
Expand Down Expand Up @@ -272,12 +272,14 @@ impl I3cPeripheral for I3c {
&mut self,
_size: RvSize,
) -> ReadWriteRegister<u32, StbyCrDeviceAddr::Register> {
ReadWriteRegister::new(
self.i3c_target
.get_address()
.unwrap_or(DynamicI3cAddress::new(0x3d).unwrap())
.into(),
)
let val = match self.i3c_target.get_address() {
Some(addr) => {
StbyCrDeviceAddr::DynamicAddr.val(addr.into())
+ StbyCrDeviceAddr::DynamicAddrValid::SET
}
None => StbyCrDeviceAddr::StaticAddr.val(0x3d) + StbyCrDeviceAddr::StaticAddrValid::SET,
};
ReadWriteRegister::new(val.value)
}

fn read_i3c_ec_tti_extcap_header(
Expand Down
56 changes: 39 additions & 17 deletions runtime/i3c/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,16 @@ use crate::hil::I3CTargetInfo;
use crate::hil::{RxClient, TxClient};
use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
use core::cell::Cell;
use kernel::hil::time::Alarm;
use kernel::hil::time::AlarmClient;
use kernel::hil::time::Time;
use kernel::hil::time::{Alarm, AlarmClient, Time};
use kernel::utilities::cells::{OptionalCell, TakeCell};
use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
use kernel::utilities::StaticRef;
use kernel::{debug, ErrorCode};
use registers_generated::i3c::bits::HcControl::{BusEnable, ModeSelector};
use registers_generated::i3c::bits::InterruptStatus;
use registers_generated::i3c::bits::QueueThldCtrl;
use registers_generated::i3c::bits::RingHeadersSectionOffset;
use registers_generated::i3c::bits::StbyCrCapabilities;
use registers_generated::i3c::bits::StbyCrControl;
use registers_generated::i3c::bits::StbyCrDeviceChar;
use registers_generated::i3c::bits::TtiQueueThldCtrl;
use registers_generated::i3c::bits::{ControllerDeviceAddr, InterruptEnable};
use registers_generated::i3c::bits::{
InterruptEnable, InterruptStatus, QueueThldCtrl, RingHeadersSectionOffset, StbyCrCapabilities,
StbyCrControl, StbyCrDeviceAddr, StbyCrDeviceChar, TtiQueueThldCtrl,
};
use registers_generated::i3c::regs::I3c;
use registers_generated::i3c::I3C_CSR_ADDR;
use tock_registers::register_bitfields;
Expand Down Expand Up @@ -164,6 +158,11 @@ impl<'a, A: Alarm<'a>> I3CCore<'a, A> {
panic!("RING_HEADERS_SECTION_OFFSET is not 0");
}

// initialize timing registers
self.registers.t_r_reg.set(0x2);
self.registers.t_hd_dat_reg.set(0xa);
self.registers.t_su_dat_reg.set(0xa);

// Setup the threshold for the HCI queues (in the internal/private software data structures):
self.registers.queue_thld_ctrl.modify(
QueueThldCtrl::CmdEmptyBufThld.val(0)
Expand Down Expand Up @@ -467,14 +466,37 @@ impl<'a, A: Alarm<'a>> crate::hil::I3CTarget<'a> for I3CCore<'a, A> {
}

fn get_device_info(&self) -> I3CTargetInfo {
let dynamic_addr = self
let dynamic_addr = if self
.registers
.controller_device_addr
.read(ControllerDeviceAddr::DynamicAddr) as u8;

.stby_cr_device_addr
.read(StbyCrDeviceAddr::DynamicAddrValid)
== 1
{
Some(
self.registers
.stby_cr_device_addr
.read(StbyCrDeviceAddr::DynamicAddr) as u8,
)
} else {
None
};
let static_addr = if self
.registers
.stby_cr_device_addr
.read(StbyCrDeviceAddr::StaticAddrValid)
== 1
{
Some(
self.registers
.stby_cr_device_addr
.read(StbyCrDeviceAddr::StaticAddr) as u8,
)
} else {
None
};
I3CTargetInfo {
static_addr: None,
dynamic_addr: Some(dynamic_addr),
static_addr,
dynamic_addr,
max_read_len: MAX_READ_WRITE_SIZE,
max_write_len: MAX_READ_WRITE_SIZE,
}
Expand Down
17 changes: 16 additions & 1 deletion runtime/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,23 @@ pub(crate) fn test_i3c_simple() -> Option<u32> {
// Safety: this is run after the board has initialized the chip.
let chip = unsafe { crate::CHIP.unwrap() };
chip.peripherals.i3c.enable();
// check that we have a dynamic address from the driver
if chip
.peripherals
.i3c
.get_device_info()
.dynamic_addr
.is_none()
{
println!(
"Failed to get address: dynamic {:?} static {:?}",
chip.peripherals.i3c.get_device_info().dynamic_addr,
chip.peripherals.i3c.get_device_info().static_addr,
);
fail();
}
chip.peripherals.i3c.disable();
Some(0)
success();
}

/// Tests that writes are handled properly
Expand Down

0 comments on commit e543a67

Please sign in to comment.