|
|
|
@ -3,6 +3,7 @@ use crc; |
|
|
|
|
use core_io::{ErrorKind as IoErrorKind, Error as IoError}; |
|
|
|
|
use io::{proto::ProtoRead, proto::ProtoWrite, Cursor}; |
|
|
|
|
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds}; |
|
|
|
|
use libcortex_a9::asm::dmb; |
|
|
|
|
use crate::mem::mem::DRTIOAUX_MEM; |
|
|
|
|
use crate::pl::csr::DRTIOAUX; |
|
|
|
|
use crate::drtioaux_proto::Error as ProtocolError; |
|
|
|
@ -57,14 +58,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) { |
|
|
|
|
for i in 0..(len/4) { |
|
|
|
|
*dst.offset(i) = *src.offset(i); |
|
|
|
|
*dst.offset(i+1) = *src.offset(i+1); |
|
|
|
|
//data memory barrier to prevent bursts
|
|
|
|
|
dmb(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -75,11 +77,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?)) |
|
|
|
@ -133,12 +135,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(()) |
|
|
|
|