runtime.rs: wide rtio data

This commit is contained in:
Robert Jördens 2016-11-21 23:12:16 +01:00 committed by Sebastien Bourdeauducq
parent 2d62a89143
commit eab18d8e34
2 changed files with 42 additions and 4 deletions

View File

@ -102,6 +102,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
api!(rtio_get_counter = ::rtio::get_counter),
api!(rtio_log),
api!(rtio_output = ::rtio::output),
api!(rtio_output_list = ::rtio::output_list),
api!(rtio_input_timestamp = ::rtio::input_timestamp),
api!(rtio_input_data = ::rtio::input_data),

View File

@ -1,4 +1,6 @@
use board::csr;
use core::ptr::{read_volatile, write_volatile};
use core::slice;
const RTIO_O_STATUS_FULL: u32 = 1;
const RTIO_O_STATUS_UNDERFLOW: u32 = 2;
@ -21,6 +23,21 @@ pub extern fn get_counter() -> i64 {
}
}
#[inline(always)]
pub unsafe fn rtio_o_data_write(w: u32) {
write_volatile(
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1) as isize),
w);
}
#[inline(always)]
pub unsafe fn rtio_i_data_read() -> u32 {
read_volatile(
csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize)
)
}
#[inline(never)]
unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) {
if status & RTIO_O_STATUS_FULL != 0 {
@ -57,7 +74,27 @@ pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) {
csr::rtio::chan_sel_write(channel);
csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr);
csr::rtio::o_data_write(data);
rtio_o_data_write(data);
csr::rtio::o_we_write(1);
let status = csr::rtio::o_status_read();
if status != 0 {
process_exceptional_status(timestamp, channel, status);
}
}
}
pub extern fn output_list(timestamp: i64, channel: u32, addr: u32,
&(len, ptr): &(usize, *const u32)) {
unsafe {
csr::rtio::chan_sel_write(channel);
csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr);
let data = slice::from_raw_parts(ptr, len);
for i in 0..data.len() {
write_volatile(
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize),
data[i]);
}
csr::rtio::o_we_write(1);
let status = csr::rtio::o_status_read();
if status != 0 {
@ -117,7 +154,7 @@ pub extern fn input_data(channel: u32) -> u32 {
}
}
let data = csr::rtio::i_data_read();
let data = rtio_i_data_read();
csr::rtio::i_re_write(1);
data
}
@ -134,14 +171,14 @@ pub fn log(timestamp: i64, data: &[u8]) {
word <<= 8;
word |= data[i] as u32;
if i % 4 == 0 {
csr::rtio::o_data_write(word);
rtio_o_data_write(word);
csr::rtio::o_we_write(1);
word = 0;
}
}
word <<= 8;
csr::rtio::o_data_write(word);
rtio_o_data_write(word);
csr::rtio::o_we_write(1);
}
}