Skip to content

Commit

Permalink
Merge pull request #593 from betrusted-io/mpw-dev
Browse files Browse the repository at this point in the history
Mpw dev
  • Loading branch information
bunnie authored Nov 18, 2024
2 parents 8beb932 + fe45f40 commit 53de9cc
Show file tree
Hide file tree
Showing 10 changed files with 605 additions and 171 deletions.
6 changes: 5 additions & 1 deletion libs/cramium-hal/src/udma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,10 @@ pub trait Udma {
}
fn udma_busy(&self, bank: Bank) -> bool {
// Safety: only safe when used in the context of UDMA registers.
unsafe { self.csr().base().add(bank as usize).add(DmaReg::Saddr.into()).read_volatile() != 0 }
unsafe {
let saddr = self.csr().base().add(bank as usize).add(DmaReg::Saddr.into()).read_volatile();
// crate::println!("brx: {:x}", saddr);
saddr != 0
}
}
}
53 changes: 40 additions & 13 deletions libs/cramium-hal/src/udma/spim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,17 +608,44 @@ impl Spim {

/// Wait for the pending tx/rx cycle to finish, returns a pointer to the Rx buffer when done.
pub fn txrx_await(&mut self, _use_yield: bool) -> Result<&[u8], xous::Error> {
#[cfg(not(target_os = "xous"))]
if let Some(pending) = self.pending_txrx.take() {
while self.udma_busy(Bank::Tx) || self.udma_busy(Bank::Rx) || self.udma_busy(Bank::Custom) {
#[cfg(feature = "std")]
if _use_yield {
xous::yield_slice();
}
}
while self.udma_busy(Bank::Tx) || self.udma_busy(Bank::Rx) || self.udma_busy(Bank::Custom) {}
Ok(&self.rx_buf()[..pending])
} else {
Err(xous::Error::UseBeforeInit)
}
#[cfg(target_os = "xous")]
{
if let Some(pending) = self.pending_txrx.take() {
let tt = xous_api_ticktimer::Ticktimer::new().unwrap();
let start = tt.elapsed_ms();
let mut now = tt.elapsed_ms();
const TIMEOUT_MS: u64 = 500;
while (self.udma_busy(Bank::Tx) || self.udma_busy(Bank::Rx) || self.udma_busy(Bank::Custom))
&& ((now - start) < TIMEOUT_MS)
{
now = tt.elapsed_ms();
}
if now - start >= TIMEOUT_MS {
log::warn!(
"Timeout in txrx_await(): Tx {:?} Rx {:?} Custom {:?}, Rx SA: {:x}, Rx Cfg: {:x}",
self.udma_busy(Bank::Tx),
self.udma_busy(Bank::Rx),
self.udma_busy(Bank::Custom),
unsafe {
self.csr().base().add(Bank::Rx as usize).add(DmaReg::Saddr.into()).read_volatile()
},
unsafe {
self.csr().base().add(Bank::Rx as usize).add(DmaReg::Cfg.into()).read_volatile()
},
);
}
Ok(&self.rx_buf()[..pending])
} else {
Err(xous::Error::UseBeforeInit)
}
}
}

/// `txrx_data_async` will return as soon as all the pending operations are queued. This will error
Expand Down Expand Up @@ -810,9 +837,9 @@ impl Spim {

// read back the ID result
let cmd_list = [SpimCmd::RxData(self.mode, SpimWordsPerXfer::Words1, 8, SpimEndian::MsbFirst, 3)];
self.send_cmd_list(&cmd_list);
// safety: this is safe because rx_buf_phys() slice is only used as a base/bounds reference
unsafe { self.udma_enqueue(Bank::Rx, &self.rx_buf_phys::<u8>()[..3], CFG_EN | CFG_SIZE_8) };
self.send_cmd_list(&cmd_list);
while self.udma_busy(Bank::Rx) {
#[cfg(feature = "std")]
xous::yield_slice();
Expand All @@ -835,9 +862,9 @@ impl Spim {
// The ID requires 24 bits "dummy" address field, then followed by 2 bytes ID + KGD, and then
// 48 bits of unique ID -- we only retrieve the top 16 of that here.
let cmd_list = [SpimCmd::RxData(self.mode, SpimWordsPerXfer::Words1, 8, SpimEndian::MsbFirst, 7)];
self.send_cmd_list(&cmd_list);
// safety: this is safe because rx_buf_phys() slice is only used as a base/bounds reference
unsafe { self.udma_enqueue(Bank::Rx, &self.rx_buf_phys::<u8>()[..7], CFG_EN | CFG_SIZE_8) };
self.send_cmd_list(&cmd_list);
while self.udma_busy(Bank::Rx) {
#[cfg(feature = "std")]
xous::yield_slice();
Expand Down Expand Up @@ -881,10 +908,10 @@ impl Spim {
// setup the command list for data to send
let cmd_list =
[SpimCmd::TxData(self.mode, SpimWordsPerXfer::Words1, 8 as u8, SpimEndian::MsbFirst, 2 as u32)];
self.send_cmd_list(&cmd_list);
self.tx_buf_mut()[..2].copy_from_slice(&[status, config]);
// safety: this is safe because tx_buf_phys() slice is only used as a base/bounds reference
unsafe { self.udma_enqueue(Bank::Tx, &self.tx_buf_phys::<u8>()[..2], CFG_EN | CFG_SIZE_8) }
self.send_cmd_list(&cmd_list);

while self.udma_busy(Bank::Tx) {
#[cfg(feature = "std")]
Expand Down Expand Up @@ -919,7 +946,6 @@ impl Spim {
// the remaining bytes are junk
self.tx_buf_mut()[3..6].copy_from_slice(&[0xFFu8, 0xFFu8, 0xFFu8]);
self.mem_cs(true);
self.send_cmd_list(&cmd_list);
// safety: this is safe because tx_buf_phys() slice is only used as a base/bounds reference
unsafe {
self.udma_enqueue(
Expand All @@ -928,6 +954,7 @@ impl Spim {
CFG_EN | CFG_SIZE_8,
)
}
self.send_cmd_list(&cmd_list);
let rd_cmd = [SpimCmd::RxData(
self.mode,
SpimWordsPerXfer::Words1,
Expand All @@ -941,11 +968,11 @@ impl Spim {
xous::yield_slice();
}
}
self.send_cmd_list(&rd_cmd);
// safety: this is safe because rx_buf_phys() slice is only used as a base/bounds reference
unsafe {
self.udma_enqueue(Bank::Rx, &self.rx_buf_phys::<u8>()[..chunk.len()], CFG_EN | CFG_SIZE_8)
};
self.send_cmd_list(&rd_cmd);
while self.udma_busy(Bank::Rx) {
// TODO: figure out why this timeout detection code is necessary.
// It seems that some traffic during the UDMA access can cause the UDMA
Expand Down Expand Up @@ -1012,9 +1039,9 @@ impl Spim {
let a = chunk_addr.to_be_bytes();
self.tx_buf_mut()[..3].copy_from_slice(&[a[1], a[2], a[3]]);
self.mem_cs(true);
self.send_cmd_list(&cmd_list);
// safety: this is safe because tx_buf_phys() slice is only used as a base/bounds reference
unsafe { self.udma_enqueue(Bank::Tx, &self.tx_buf_phys::<u8>()[..3], CFG_EN | CFG_SIZE_8) }
self.send_cmd_list(&cmd_list);
let wr_cmd = [SpimCmd::TxData(
self.mode,
SpimWordsPerXfer::Words1,
Expand All @@ -1028,12 +1055,12 @@ impl Spim {
xous::yield_slice();
}
}
self.send_cmd_list(&wr_cmd);
self.tx_buf_mut()[..chunk.len()].copy_from_slice(chunk);
// safety: this is safe because tx_buf_phys() slice is only used as a base/bounds reference
unsafe {
self.udma_enqueue(Bank::Tx, &self.tx_buf_phys::<u8>()[..chunk.len()], CFG_EN | CFG_SIZE_8)
};
self.send_cmd_list(&wr_cmd);
while self.udma_busy(Bank::Tx) {
#[cfg(feature = "std")]
if _use_yield {
Expand Down
2 changes: 1 addition & 1 deletion libs/xous-pl230/src/pl230_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub fn report_api(desc: &str, d: u32) {
{
use core::fmt::Write;
let mut uart = crate::debug::Uart {};
writeln!(uart, "pl230: [{}] 0x{:x}", desc, d).ok();
writeln!(uart, "pl230: [{}] 0x{:x}\r", desc, d).ok();
}
#[cfg(not(feature = "baremetal"))]
log::info!("pl230: [{}] 0x{:x}", desc, d);
Expand Down
32 changes: 27 additions & 5 deletions libs/xous-pl230/src/pl230_tests/units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,18 @@ pub fn basic_tests(pl230: &mut Pl230) -> bool {
// report_api("dma_len", DMA_LEN as u32);
report_api("baseptr", cc_struct.channels.as_ptr() as u32);
report_api("src start", region_a.as_ptr() as u32);
// report_api("baseptr[0]", unsafe{cc_struct.channels.as_ptr().read()}.src_end_ptr);
report_api("baseptr[0]", unsafe { cc_struct.channels.as_ptr().read() }.src_end_ptr);
report_api("dst start", region_b.as_ptr() as u32);
// report_api("baseptr[1]", unsafe{cc_struct.channels.as_ptr().read()}.dst_end_ptr);
// report_api("baseptr[2]", unsafe{cc_struct.channels.as_ptr().read()}.control);
// report_api("baseptr[3]", unsafe{cc_struct.channels.as_ptr().read()}.reserved);
// report_api("baseptr reg", pl230.csr.r(utra::pl230::CTRLBASEPTR));
report_api("baseptr[1]", unsafe { cc_struct.channels.as_ptr().read() }.dst_end_ptr);
report_api("baseptr[2]", unsafe { cc_struct.channels.as_ptr().read() }.control);
report_api("baseptr[3]", unsafe { cc_struct.channels.as_ptr().read() }.reserved);
report_api("baseptr reg", pl230.csr.r(utra::pl230::CTRLBASEPTR));

unsafe {
for i in 0..16 {
report_api("pl230 reg ", pl230.csr.base().add(i as usize).read_volatile());
}
}

// this should kick off the DMA
pl230.csr.wo(utra::pl230::CHNLSWREQUEST, 1);
Expand Down Expand Up @@ -123,6 +129,22 @@ pub fn basic_tests(pl230: &mut Pl230) -> bool {
}
report_api("basic dma result (1=pass)", if passing { 1 } else { 0 });
report_api("errs: ", errs);

report_api("baseptr", cc_struct.channels.as_ptr() as u32);
report_api("src start", region_a.as_ptr() as u32);
report_api("baseptr[0]", unsafe { cc_struct.channels.as_ptr().read() }.src_end_ptr);
report_api("dst start", region_b.as_ptr() as u32);
report_api("baseptr[1]", unsafe { cc_struct.channels.as_ptr().read() }.dst_end_ptr);
report_api("baseptr[2]", unsafe { cc_struct.channels.as_ptr().read() }.control);
report_api("baseptr[3]", unsafe { cc_struct.channels.as_ptr().read() }.reserved);
report_api("baseptr reg", pl230.csr.r(utra::pl230::CTRLBASEPTR));

unsafe {
for i in 0..16 {
report_api("pl230 reg ", pl230.csr.base().add(i as usize).read_volatile());
}
}

passing
}

Expand Down
1 change: 1 addition & 0 deletions loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ xous-pl230 = { path = "../libs/xous-pl230", optional = true, features = [
"pio",
"cramium-soc",
"baremetal",
# "dma-mainram", # PL-230 option - this fails on MPW
] }
xous-pio = { path = "../libs/xous-pio", optional = true, features = [
"tests",
Expand Down
10 changes: 5 additions & 5 deletions loader/src/platform/cramium/cramium.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ pub fn early_init() -> u32 {
clock_tests(&mut udma_uart);
}

// do a PL230/PIO test. Toggles PB15 (PIO0) with an LFSR sequence.
// let mut pl230 = xous_pl230::Pl230::new();
// xous_pl230::pl230_tests::units::basic_tests(&mut pl230);
// xous_pl230::pl230_tests::units::pio_test(&mut pl230);

// Setup some global control registers that will allow the TRNG to operate once the kernel is
// booted. This is done so the kernel doesn't have to exclusively have rights to the SCE global
// registers just for this purpose.
Expand Down Expand Up @@ -692,11 +697,6 @@ pub fn early_init() -> u32 {
let trng_csr = CSR::new(HW_TRNG_BASE as *mut u32);
crate::println!("trng status: {:x}", trng_csr.r(utra::trng::SFR_SR));

// do a PL230/PIO test. Toggles PB15 (PIO0) with an LFSR sequence.
// let mut pl230 = xous_pl230::Pl230::new();
// xous_pl230::pl230_tests::units::basic_tests(&mut pl230);
// xous_pl230::pl230_tests::units::pio_test(&mut pl230);

const BANNER: &'static str = "\n\rKeep pressing keys to continue boot...\r\n";
udma_uart.write(BANNER.as_bytes());

Expand Down
22 changes: 18 additions & 4 deletions services/bao-video/src/homography.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn find_homography(src_points: [(f32, f32); 4], dst_points: [(f32, f32); 4])
}
}

const HOM_FP_SHIFT: i32 = 16;
const HOM_FP_SHIFT: i32 = 18;
const HOM_FP_SCALE: i32 = 1 << HOM_FP_SHIFT;

pub fn matrix3_to_fixp(h: Matrix3<f32>) -> Matrix3<i32> {
Expand All @@ -78,8 +78,22 @@ pub fn apply_fixp_homography(homography: &Matrix3<i32>, point: (i32, i32)) -> (i
let tw = homography[(2, 0)] * x + homography[(2, 1)] * y + homography[(2, 2)];

// Normalize by w to get the final coordinates
let x_transformed = tx / tw;
let y_transformed = ty / tw;
if tw != 0 {
let x_transformed = tx / tw;
let y_transformed = ty / tw;

(x_transformed, y_transformed)
(x_transformed, y_transformed)
} else {
log::info!(
"Homography transformation would divide by 0: possible fixed-point underflow!\n\r {}, {}\n\r {} * {} + {} * {} + {}",
tx,
ty,
homography[(2, 0)],
x,
homography[(2, 1)],
y,
homography[(2, 2)]
);
(0, 0)
}
}
Loading

0 comments on commit 53de9cc

Please sign in to comment.