mirror of https://github.com/m-labs/artiq.git
Merge remote-tracking branch 'm-labs/master' into phaser2
* m-labs/master: applets: compatibility with older Qt. Closes #629 doc: update LLVM configure command (fixes #628). runtime: match argument signedness between ARTIQ Python and ksupport. runtime: refactor rtio_output_list. runtime: use correct ABI when accepting ARTIQ lists.
This commit is contained in:
commit
d5d17aca9e
|
@ -518,7 +518,7 @@ class AppletsDock(QtWidgets.QDockWidget):
|
||||||
item.setFlags(QtCore.Qt.ItemIsSelectable |
|
item.setFlags(QtCore.Qt.ItemIsSelectable |
|
||||||
QtCore.Qt.ItemIsEditable |
|
QtCore.Qt.ItemIsEditable |
|
||||||
QtCore.Qt.ItemIsUserCheckable |
|
QtCore.Qt.ItemIsUserCheckable |
|
||||||
QtCore.Qt.ItemIsAutoTristate |
|
QtCore.Qt.ItemIsTristate |
|
||||||
QtCore.Qt.ItemIsDragEnabled |
|
QtCore.Qt.ItemIsDragEnabled |
|
||||||
QtCore.Qt.ItemIsDropEnabled |
|
QtCore.Qt.ItemIsDropEnabled |
|
||||||
QtCore.Qt.ItemIsEnabled)
|
QtCore.Qt.ItemIsEnabled)
|
||||||
|
|
|
@ -102,7 +102,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
||||||
api!(rtio_get_counter = ::rtio::get_counter),
|
api!(rtio_get_counter = ::rtio::get_counter),
|
||||||
api!(rtio_log),
|
api!(rtio_log),
|
||||||
api!(rtio_output = ::rtio::output),
|
api!(rtio_output = ::rtio::output),
|
||||||
api!(rtio_output_list = ::rtio::output_list),
|
api!(rtio_output_wide = ::rtio::output_wide),
|
||||||
api!(rtio_input_timestamp = ::rtio::input_timestamp),
|
api!(rtio_input_timestamp = ::rtio::input_timestamp),
|
||||||
api!(rtio_input_data = ::rtio::input_data),
|
api!(rtio_input_data = ::rtio::input_data),
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,9 @@ mod imp {
|
||||||
|
|
||||||
use self::imp::*;
|
use self::imp::*;
|
||||||
|
|
||||||
pub extern fn init(busno: u32) {
|
pub extern fn init(busno: i32) {
|
||||||
|
let busno = busno as u32;
|
||||||
|
|
||||||
// Set SCL as output, and high level
|
// Set SCL as output, and high level
|
||||||
scl_o(busno, true);
|
scl_o(busno, true);
|
||||||
scl_oe(busno, true);
|
scl_oe(busno, true);
|
||||||
|
@ -92,7 +94,9 @@ pub extern fn init(busno: u32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn start(busno: u32) {
|
pub extern fn start(busno: i32) {
|
||||||
|
let busno = busno as u32;
|
||||||
|
|
||||||
// Set SCL high then SDA low
|
// Set SCL high then SDA low
|
||||||
scl_o(busno, true);
|
scl_o(busno, true);
|
||||||
half_period();
|
half_period();
|
||||||
|
@ -100,7 +104,9 @@ pub extern fn start(busno: u32) {
|
||||||
half_period();
|
half_period();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn stop(busno: u32) {
|
pub extern fn stop(busno: i32) {
|
||||||
|
let busno = busno as u32;
|
||||||
|
|
||||||
// First, make sure SCL is low, so that the target releases the SDA line
|
// First, make sure SCL is low, so that the target releases the SDA line
|
||||||
scl_o(busno, false);
|
scl_o(busno, false);
|
||||||
half_period();
|
half_period();
|
||||||
|
@ -112,7 +118,9 @@ pub extern fn stop(busno: u32) {
|
||||||
half_period();
|
half_period();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn write(busno: u32, data: u8) -> bool {
|
pub extern fn write(busno: i32, data: i8) -> bool {
|
||||||
|
let (busno, data) = (busno as u32, data as u8);
|
||||||
|
|
||||||
// MSB first
|
// MSB first
|
||||||
for bit in (0..8).rev() {
|
for bit in (0..8).rev() {
|
||||||
// Set SCL low and set our bit on SDA
|
// Set SCL low and set our bit on SDA
|
||||||
|
@ -135,7 +143,9 @@ pub extern fn write(busno: u32, data: u8) -> bool {
|
||||||
!sda_i(busno)
|
!sda_i(busno)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn read(busno: u32, ack: bool) -> u8 {
|
pub extern fn read(busno: i32, ack: bool) -> i8 {
|
||||||
|
let busno = busno as u32;
|
||||||
|
|
||||||
// Set SCL low first, otherwise setting SDA as input may cause a transition
|
// Set SCL low first, otherwise setting SDA as input may cause a transition
|
||||||
// on SDA with SCL high which will be interpreted as START/STOP condition.
|
// on SDA with SCL high which will be interpreted as START/STOP condition.
|
||||||
scl_o(busno, false);
|
scl_o(busno, false);
|
||||||
|
@ -162,5 +172,5 @@ pub extern fn read(busno: u32, ack: bool) -> u8 {
|
||||||
scl_o(busno, true);
|
scl_o(busno, true);
|
||||||
half_period();
|
half_period();
|
||||||
|
|
||||||
data
|
data as i8
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,22 @@ extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u32) -
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ArtiqList<T> {
|
||||||
|
len: usize,
|
||||||
|
ptr: *const T
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ArtiqList<T> {
|
||||||
|
pub fn from_slice(slice: &'static [T]) -> ArtiqList<T> {
|
||||||
|
ArtiqList { ptr: slice.as_ptr(), len: slice.len() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_slice(&self) -> &[T] {
|
||||||
|
slice::from_raw_parts(self.ptr, self.len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static mut NOW: u64 = 0;
|
static mut NOW: u64 = 0;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -210,35 +226,34 @@ pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception,
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn watchdog_set(ms: i64) -> usize {
|
extern fn watchdog_set(ms: i64) -> i32 {
|
||||||
if ms < 0 {
|
if ms < 0 {
|
||||||
artiq_raise!("ValueError", "cannot set a watchdog with a negative timeout")
|
artiq_raise!("ValueError", "cannot set a watchdog with a negative timeout")
|
||||||
}
|
}
|
||||||
|
|
||||||
send(&WatchdogSetRequest { ms: ms as u64 });
|
send(&WatchdogSetRequest { ms: ms as u64 });
|
||||||
recv!(&WatchdogSetReply { id } => id)
|
recv!(&WatchdogSetReply { id } => id) as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn watchdog_clear(id: usize) {
|
extern fn watchdog_clear(id: i32) {
|
||||||
send(&WatchdogClear { id: id })
|
send(&WatchdogClear { id: id as usize })
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn cache_get(key: *const u8) -> (usize, *const u32) {
|
extern fn cache_get(key: *const u8) -> ArtiqList<i32> {
|
||||||
extern { fn strlen(s: *const c_char) -> size_t; }
|
extern { fn strlen(s: *const c_char) -> size_t; }
|
||||||
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
|
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
|
||||||
let key = unsafe { str::from_utf8_unchecked(key) };
|
let key = unsafe { str::from_utf8_unchecked(key) };
|
||||||
|
|
||||||
send(&CacheGetRequest { key: key });
|
send(&CacheGetRequest { key: key });
|
||||||
recv!(&CacheGetReply { value } => (value.len(), value.as_ptr()))
|
recv!(&CacheGetReply { value } => ArtiqList::from_slice(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn cache_put(key: *const u8, &(len, ptr): &(usize, *const u32)) {
|
extern fn cache_put(key: *const u8, list: ArtiqList<i32>) {
|
||||||
extern { fn strlen(s: *const c_char) -> size_t; }
|
extern { fn strlen(s: *const c_char) -> size_t; }
|
||||||
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
|
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
|
||||||
let key = unsafe { str::from_utf8_unchecked(key) };
|
let key = unsafe { str::from_utf8_unchecked(key) };
|
||||||
|
|
||||||
let value = unsafe { slice::from_raw_parts(ptr, len) };
|
send(&CachePutRequest { key: key, value: unsafe { list.as_slice() } });
|
||||||
send(&CachePutRequest { key: key, value: value });
|
|
||||||
recv!(&CachePutReply { succeeded } => {
|
recv!(&CachePutReply { succeeded } => {
|
||||||
if !succeeded {
|
if !succeeded {
|
||||||
artiq_raise!("CacheError", "cannot put into a busy cache row")
|
artiq_raise!("CacheError", "cannot put into a busy cache row")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use board::csr;
|
use board::csr;
|
||||||
use core::ptr::{read_volatile, write_volatile};
|
use core::ptr::{read_volatile, write_volatile};
|
||||||
use core::slice;
|
use ::ArtiqList;
|
||||||
|
|
||||||
const RTIO_O_STATUS_FULL: u32 = 1;
|
const RTIO_O_STATUS_FULL: u32 = 1;
|
||||||
const RTIO_O_STATUS_UNDERFLOW: u32 = 2;
|
const RTIO_O_STATUS_UNDERFLOW: u32 = 2;
|
||||||
|
@ -26,20 +26,20 @@ pub extern fn get_counter() -> i64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn rtio_o_data_write(w: u32) {
|
pub unsafe fn rtio_o_data_write(offset: usize, data: u32) {
|
||||||
write_volatile(
|
write_volatile(
|
||||||
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1) as isize),
|
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - offset) as isize),
|
||||||
w);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn rtio_i_data_read() -> u32 {
|
pub unsafe fn rtio_i_data_read(offset: usize) -> u32 {
|
||||||
read_volatile(
|
read_volatile(
|
||||||
csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize))
|
csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1 - offset) as isize))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) {
|
unsafe fn process_exceptional_status(timestamp: i64, channel: i32, status: u32) {
|
||||||
if status & RTIO_O_STATUS_FULL != 0 {
|
if status & RTIO_O_STATUS_FULL != 0 {
|
||||||
while csr::rtio::o_status_read() & RTIO_O_STATUS_FULL != 0 {}
|
while csr::rtio::o_status_read() & RTIO_O_STATUS_FULL != 0 {}
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,12 @@ unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) {
|
pub extern fn output(timestamp: i64, channel: i32, addr: i32, data: i32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio::chan_sel_write(channel);
|
csr::rtio::chan_sel_write(channel as u32);
|
||||||
csr::rtio::o_timestamp_write(timestamp as u64);
|
csr::rtio::o_timestamp_write(timestamp as u64);
|
||||||
csr::rtio::o_address_write(addr);
|
csr::rtio::o_address_write(addr as u32);
|
||||||
rtio_o_data_write(data);
|
rtio_o_data_write(0, data as u32);
|
||||||
csr::rtio::o_we_write(1);
|
csr::rtio::o_we_write(1);
|
||||||
let status = csr::rtio::o_status_read();
|
let status = csr::rtio::o_status_read();
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
|
@ -83,17 +83,14 @@ pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn output_list(timestamp: i64, channel: u32, addr: u32,
|
pub extern fn output_wide(timestamp: i64, channel: i32, addr: i32, list: ArtiqList<i32>) {
|
||||||
&(len, ptr): &(usize, *const u32)) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio::chan_sel_write(channel);
|
csr::rtio::chan_sel_write(channel as u32);
|
||||||
csr::rtio::o_timestamp_write(timestamp as u64);
|
csr::rtio::o_timestamp_write(timestamp as u64);
|
||||||
csr::rtio::o_address_write(addr);
|
csr::rtio::o_address_write(addr as u32);
|
||||||
let data = slice::from_raw_parts(ptr, len);
|
let data = list.as_slice();
|
||||||
for i in 0..data.len() {
|
for i in 0..data.len() {
|
||||||
write_volatile(
|
rtio_o_data_write(i, data[i] as u32)
|
||||||
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize),
|
|
||||||
data[i]);
|
|
||||||
}
|
}
|
||||||
csr::rtio::o_we_write(1);
|
csr::rtio::o_we_write(1);
|
||||||
let status = csr::rtio::o_status_read();
|
let status = csr::rtio::o_status_read();
|
||||||
|
@ -103,9 +100,9 @@ pub extern fn output_list(timestamp: i64, channel: u32, addr: u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn input_timestamp(timeout: i64, channel: u32) -> u64 {
|
pub extern fn input_timestamp(timeout: i64, channel: i32) -> u64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio::chan_sel_write(channel);
|
csr::rtio::chan_sel_write(channel as u32);
|
||||||
let mut status;
|
let mut status;
|
||||||
loop {
|
loop {
|
||||||
status = csr::rtio::i_status_read();
|
status = csr::rtio::i_status_read();
|
||||||
|
@ -139,9 +136,9 @@ pub extern fn input_timestamp(timeout: i64, channel: u32) -> u64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern fn input_data(channel: u32) -> u32 {
|
pub extern fn input_data(channel: i32) -> i32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio::chan_sel_write(channel);
|
csr::rtio::chan_sel_write(channel as u32);
|
||||||
loop {
|
loop {
|
||||||
let status = csr::rtio::i_status_read();
|
let status = csr::rtio::i_status_read();
|
||||||
if status == 0 { break }
|
if status == 0 { break }
|
||||||
|
@ -154,9 +151,9 @@ pub extern fn input_data(channel: u32) -> u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = rtio_i_data_read();
|
let data = rtio_i_data_read(0);
|
||||||
csr::rtio::i_re_write(1);
|
csr::rtio::i_re_write(1);
|
||||||
data
|
data as i32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,14 +168,14 @@ pub fn log(timestamp: i64, data: &[u8]) {
|
||||||
word <<= 8;
|
word <<= 8;
|
||||||
word |= data[i] as u32;
|
word |= data[i] as u32;
|
||||||
if i % 4 == 0 {
|
if i % 4 == 0 {
|
||||||
rtio_o_data_write(word);
|
rtio_o_data_write(0, word);
|
||||||
csr::rtio::o_we_write(1);
|
csr::rtio::o_we_write(1);
|
||||||
word = 0;
|
word = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
word <<= 8;
|
word <<= 8;
|
||||||
rtio_o_data_write(word);
|
rtio_o_data_write(0, word);
|
||||||
csr::rtio::o_we_write(1);
|
csr::rtio::o_we_write(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::btree_map::BTreeMap;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Entry {
|
struct Entry {
|
||||||
data: Vec<u32>,
|
data: Vec<i32>,
|
||||||
borrowed: bool
|
borrowed: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ impl Cache {
|
||||||
Cache { entries: BTreeMap::new() }
|
Cache { entries: BTreeMap::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&mut self, key: &str) -> *const [u32] {
|
pub fn get(&mut self, key: &str) -> *const [i32] {
|
||||||
match self.entries.get_mut(key) {
|
match self.entries.get_mut(key) {
|
||||||
None => &[],
|
None => &[],
|
||||||
Some(ref mut entry) => {
|
Some(ref mut entry) => {
|
||||||
|
@ -28,7 +28,7 @@ impl Cache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn put(&mut self, key: &str, data: &[u32]) -> Result<(), ()> {
|
pub fn put(&mut self, key: &str, data: &[i32]) -> Result<(), ()> {
|
||||||
match self.entries.get_mut(key) {
|
match self.entries.get_mut(key) {
|
||||||
None => (),
|
None => (),
|
||||||
Some(ref mut entry) => {
|
Some(ref mut entry) => {
|
||||||
|
|
|
@ -51,8 +51,8 @@ pub enum Message<'a> {
|
||||||
RpcRecvReply(Result<usize, Exception<'a>>),
|
RpcRecvReply(Result<usize, Exception<'a>>),
|
||||||
|
|
||||||
CacheGetRequest { key: &'a str },
|
CacheGetRequest { key: &'a str },
|
||||||
CacheGetReply { value: &'static [u32] },
|
CacheGetReply { value: &'static [i32] },
|
||||||
CachePutRequest { key: &'a str, value: &'static [u32] },
|
CachePutRequest { key: &'a str, value: &'a [i32] },
|
||||||
CachePutReply { succeeded: bool },
|
CachePutReply { succeeded: bool },
|
||||||
|
|
||||||
Log(fmt::Arguments<'a>),
|
Log(fmt::Arguments<'a>),
|
||||||
|
|
|
@ -406,7 +406,7 @@ fn process_kern_message(waiter: Waiter,
|
||||||
&kern::CacheGetRequest { key } => {
|
&kern::CacheGetRequest { key } => {
|
||||||
let value = session.congress.cache.get(key);
|
let value = session.congress.cache.get(key);
|
||||||
kern_send(waiter, &kern::CacheGetReply {
|
kern_send(waiter, &kern::CacheGetReply {
|
||||||
value: unsafe { mem::transmute::<*const [u32], &'static [u32]>(value) }
|
value: unsafe { mem::transmute::<*const [i32], &'static [i32]>(value) }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ fn process_kern_message(waiter: Waiter,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_kern_queued_rpc(stream: &mut TcpStream,
|
fn process_kern_queued_rpc(stream: &mut TcpStream,
|
||||||
session: &mut Session) -> io::Result<()> {
|
_session: &mut Session) -> io::Result<()> {
|
||||||
rpc_queue::dequeue(|slice| {
|
rpc_queue::dequeue(|slice| {
|
||||||
trace!("comm<-kern (async RPC)");
|
trace!("comm<-kern (async RPC)");
|
||||||
let length = NetworkEndian::read_u32(slice) as usize;
|
let length = NetworkEndian::read_u32(slice) as usize;
|
||||||
|
|
|
@ -54,7 +54,7 @@ and the ARTIQ kernels.
|
||||||
|
|
||||||
$ mkdir build
|
$ mkdir build
|
||||||
$ cd build
|
$ cd build
|
||||||
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-or1k -DLLVM_TARGETS_TO_BUILD="OR1K;X86" -DLLVM_ENABLE_ASSERTIONS=ON
|
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-or1k -DLLVM_TARGETS_TO_BUILD="OR1K;X86" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INSTALL_UTILS=ON
|
||||||
$ make -j4
|
$ make -j4
|
||||||
$ sudo make install
|
$ sudo make install
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue