drtio: fix garbage data on transmission

pull/176/head
mwojcik 2022-03-30 17:07:58 +08:00
parent ad3aeb5109
commit 77ca020450
2 changed files with 12 additions and 18 deletions

View File

@ -57,21 +57,15 @@ pub fn has_rx_error(linkno: u8) -> bool {
}
}
pub fn copy_work_buffer(src: *mut u16, dst: *mut u16, len: isize) {
pub fn copy_work_buffer(src: *mut u32, dst: *mut u32, len: isize) {
// AXI writes must be 4-byte aligned (drtio proto doesn't care for that),
// and AXI burst reads/writes are not implemented yet in gateware
// thus the need for a work buffer for transmitting and copying it over
unsafe {
for i in (0..(len/2)).step_by(2) {
*dst.offset(i) = *src.offset(i);
for i in (0..(len/4)).step_by(2) {
//mix offsets to prevent bursts
*dst.offset(i+1) = *src.offset(i+1);
}
// workaround for corrupted writes
// check and re-write
for i in 0..len {
if *dst.offset(i) != *src.offset(i) {
*dst.offset(i) = *src.offset(i);
}
*dst.offset(i) = *src.offset(i);
}
}
}
@ -82,11 +76,11 @@ fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
let linkidx = linkno as usize;
unsafe {
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u16;
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u32;
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
// work buffer to accomodate axi burst reads
let mut buf: [u8; 1024] = [0; 1024];
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u16, len as isize);
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, len as isize);
let result = f(&buf[0..len]);
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
Ok(Some(result?))
@ -140,12 +134,12 @@ fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
let linkno = linkno as usize;
unsafe {
while (DRTIOAUX[linkno].aux_tx_read)() != 0 {}
let ptr = DRTIOAUX_MEM[linkno].base as *mut u16;
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
let len = DRTIOAUX_MEM[linkno].size / 2;
// work buffer, works with unaligned mem access
let mut buf: [u8; 1024] = [0; 1024];
let len = f(&mut buf[0..len])?;
copy_work_buffer(buf.as_mut_ptr() as *mut u16, ptr, len as isize);
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
(DRTIOAUX[linkno].aux_tx_write)(1);
Ok(())

View File

@ -42,11 +42,11 @@ async fn receive<F, T>(linkno: u8, f: F) -> Result<Option<T>, Error>
let linkidx = linkno as usize;
unsafe {
if (DRTIOAUX[linkidx].aux_rx_present_read)() == 1 {
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u16;
let ptr = (DRTIOAUX_MEM[linkidx].base + DRTIOAUX_MEM[linkidx].size / 2) as *mut u32;
let len = (DRTIOAUX[linkidx].aux_rx_length_read)() as usize;
// work buffer to accomodate axi burst reads
let mut buf: [u8; 1024] = [0; 1024];
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u16, len as isize);
copy_work_buffer(ptr, buf.as_mut_ptr() as *mut u32, len as isize);
let result = f(&buf[0..len]);
(DRTIOAUX[linkidx].aux_rx_present_write)(1);
Ok(Some(result?))
@ -106,12 +106,12 @@ async fn transmit<F>(linkno: u8, f: F) -> Result<(), Error>
let linkno = linkno as usize;
unsafe {
let _ = block_async!(tx_ready(linkno)).await;
let ptr = DRTIOAUX_MEM[linkno].base as *mut u16;
let ptr = DRTIOAUX_MEM[linkno].base as *mut u32;
let len = DRTIOAUX_MEM[linkno].size / 2;
// work buffer, works with unaligned mem access
let mut buf: [u8; 1024] = [0; 1024];
let len = f(&mut buf[0..len])?;
copy_work_buffer(buf.as_mut_ptr() as *mut u16, ptr, len as isize);
copy_work_buffer(buf.as_mut_ptr() as *mut u32, ptr, len as isize);
(DRTIOAUX[linkno].aux_tx_length_write)(len as u16);
(DRTIOAUX[linkno].aux_tx_write)(1);
Ok(())