2017-06-12 19:22:23 +08:00
|
|
|
#![feature(used, const_fn, core_float, asm)]
|
2017-05-04 17:35:26 +08:00
|
|
|
#![no_std]
|
|
|
|
|
|
|
|
extern crate cortex_m;
|
|
|
|
extern crate cortex_m_rt;
|
|
|
|
extern crate tm4c129x;
|
|
|
|
|
2017-05-06 17:17:41 +08:00
|
|
|
use core::cell::{Cell, RefCell};
|
2017-05-09 13:16:00 +08:00
|
|
|
use core::fmt;
|
2017-05-04 17:35:26 +08:00
|
|
|
use cortex_m::exception::Handlers as ExceptionHandlers;
|
2017-05-06 17:17:41 +08:00
|
|
|
use cortex_m::interrupt::Mutex;
|
2017-05-05 19:31:12 +08:00
|
|
|
use tm4c129x::interrupt::Interrupt;
|
2017-05-04 17:35:26 +08:00
|
|
|
use tm4c129x::interrupt::Handlers as InterruptHandlers;
|
|
|
|
|
2017-05-11 14:55:00 +08:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! print {
|
|
|
|
($($arg:tt)*) => ({
|
|
|
|
use core::fmt::Write;
|
|
|
|
write!($crate::UART0, $($arg)*).unwrap()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! println {
|
|
|
|
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
|
|
|
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[macro_use]
|
2017-05-09 15:57:54 +08:00
|
|
|
mod board;
|
2017-05-06 17:17:41 +08:00
|
|
|
mod pid;
|
2017-05-09 15:57:54 +08:00
|
|
|
mod loop_anode;
|
|
|
|
mod loop_cathode;
|
2017-05-11 23:15:01 +08:00
|
|
|
mod electrometer;
|
2017-05-06 17:17:41 +08:00
|
|
|
|
2017-05-11 14:55:00 +08:00
|
|
|
static TIME: Mutex<Cell<u64>> = Mutex::new(Cell::new(0));
|
|
|
|
|
|
|
|
fn get_time() -> u64 {
|
|
|
|
cortex_m::interrupt::free(|cs| {
|
|
|
|
TIME.borrow(cs).get()
|
|
|
|
})
|
|
|
|
}
|
2017-05-06 17:17:41 +08:00
|
|
|
|
2017-05-09 15:57:54 +08:00
|
|
|
static LOOP_ANODE: Mutex<RefCell<loop_anode::Controller>> = Mutex::new(RefCell::new(
|
|
|
|
loop_anode::Controller::new()));
|
2017-05-06 12:32:13 +08:00
|
|
|
|
2017-05-09 15:57:54 +08:00
|
|
|
static LOOP_CATHODE: Mutex<RefCell<loop_cathode::Controller>> = Mutex::new(RefCell::new(
|
|
|
|
loop_cathode::Controller::new()));
|
2017-05-09 13:16:00 +08:00
|
|
|
|
2017-05-11 23:15:01 +08:00
|
|
|
static ELECTROMETER: Mutex<RefCell<electrometer::Electrometer>> = Mutex::new(RefCell::new(
|
|
|
|
electrometer::Electrometer::new()));
|
|
|
|
|
2017-05-09 13:16:00 +08:00
|
|
|
|
|
|
|
pub struct UART0;
|
|
|
|
|
|
|
|
impl fmt::Write for UART0 {
|
|
|
|
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
|
|
|
for c in s.bytes() {
|
|
|
|
unsafe {
|
|
|
|
let uart_0 = tm4c129x::UART0.get();
|
|
|
|
while (*uart_0).fr.read().txff().bit() {}
|
|
|
|
(*uart_0).dr.write(|w| w.data().bits(c))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-04 17:35:26 +08:00
|
|
|
fn main() {
|
2017-06-12 19:22:23 +08:00
|
|
|
// Enable the FPU
|
|
|
|
unsafe {
|
|
|
|
asm!("
|
|
|
|
PUSH {R0, R1}
|
|
|
|
LDR.W R0, =0xE000ED88
|
|
|
|
LDR R1, [R0]
|
|
|
|
ORR R1, R1, #(0xF << 20)
|
|
|
|
STR R1, [R0]
|
|
|
|
DSB
|
|
|
|
ISB
|
|
|
|
POP {R0, R1}
|
|
|
|
");
|
|
|
|
}
|
|
|
|
// Beware of the compiler inserting FPU instructions
|
|
|
|
// in the prologue of functions before the FPU is enabled!
|
|
|
|
main_with_fpu();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline(never)]
|
|
|
|
fn main_with_fpu() {
|
2017-05-09 15:57:54 +08:00
|
|
|
board::init();
|
2017-05-04 19:42:22 +08:00
|
|
|
|
2017-05-09 15:57:54 +08:00
|
|
|
cortex_m::interrupt::free(|cs| {
|
|
|
|
let nvic = tm4c129x::NVIC.borrow(cs);
|
2017-05-05 19:31:12 +08:00
|
|
|
nvic.enable(Interrupt::ADC0SS0);
|
|
|
|
|
2017-05-10 00:10:52 +08:00
|
|
|
let mut loop_anode = LOOP_ANODE.borrow(cs).borrow_mut();
|
|
|
|
let mut loop_cathode = LOOP_CATHODE.borrow(cs).borrow_mut();
|
2017-06-08 21:50:39 +08:00
|
|
|
|
2017-05-17 00:06:31 +08:00
|
|
|
// ZJ-10
|
|
|
|
let anode = 165.0;
|
|
|
|
let cathode_bias = 50.0;
|
|
|
|
let emission = 0.5e-3;
|
2017-06-08 21:50:39 +08:00
|
|
|
|
2017-05-17 00:06:31 +08:00
|
|
|
// ZJ-27
|
2017-06-08 21:50:39 +08:00
|
|
|
/*let anode = 225.0;
|
2017-05-17 00:06:31 +08:00
|
|
|
let cathode_bias = 25.0;
|
2017-06-08 21:50:39 +08:00
|
|
|
let emission = 1.0e-3;*/
|
|
|
|
|
2017-05-17 00:06:31 +08:00
|
|
|
// ZJ-12
|
2017-06-07 15:06:50 +08:00
|
|
|
/*let anode = 200.0;
|
2017-05-17 00:06:31 +08:00
|
|
|
let cathode_bias = 50.0;
|
2017-06-07 15:06:50 +08:00
|
|
|
let emission = 4.0e-3;*/
|
2017-06-08 21:50:39 +08:00
|
|
|
|
|
|
|
// G8130
|
|
|
|
/*let anode = 180.0;
|
2017-06-07 15:06:50 +08:00
|
|
|
let cathode_bias = 30.0;
|
2017-06-08 21:50:39 +08:00
|
|
|
let emission = 4.0e-3;*/
|
|
|
|
|
2017-05-17 00:06:31 +08:00
|
|
|
loop_anode.set_target(anode);
|
|
|
|
loop_cathode.set_emission_target(emission);
|
2017-05-10 00:10:52 +08:00
|
|
|
loop_cathode.set_bias_target(cathode_bias);
|
2017-05-04 17:35:26 +08:00
|
|
|
});
|
2017-05-06 12:33:38 +08:00
|
|
|
|
2017-05-11 14:55:00 +08:00
|
|
|
println!(r#"
|
|
|
|
_ _
|
|
|
|
(_) | |
|
|
|
|
_ ___ _ __ _ __ __ _| |
|
|
|
|
| |/ _ \| '_ \| '_ \ / _` | |/ /
|
|
|
|
| | (_) | | | | |_) | (_| | <
|
|
|
|
|_|\___/|_| |_| .__/ \__,_|_|\_\
|
|
|
|
| |
|
|
|
|
|_|
|
|
|
|
Ready."#);
|
|
|
|
|
|
|
|
let mut next_blink = 0;
|
|
|
|
let mut next_info = 0;
|
|
|
|
let mut led_state = true;
|
|
|
|
let mut latch_reset_time = None;
|
2017-05-06 12:33:38 +08:00
|
|
|
loop {
|
2017-05-09 15:57:54 +08:00
|
|
|
board::process_errors();
|
2017-05-11 14:55:00 +08:00
|
|
|
|
|
|
|
let time = get_time();
|
|
|
|
|
|
|
|
if time > next_blink {
|
|
|
|
led_state = !led_state;
|
2017-06-12 19:22:23 +08:00
|
|
|
next_blink = time + 1000;
|
2017-05-11 14:55:00 +08:00
|
|
|
board::set_led(1, led_state);
|
|
|
|
}
|
|
|
|
|
2017-06-12 19:22:23 +08:00
|
|
|
if time >= next_info {
|
|
|
|
let (anode, cathode, electrometer) = cortex_m::interrupt::free(|cs| {
|
|
|
|
(LOOP_ANODE.borrow(cs).borrow().get_status(),
|
|
|
|
LOOP_CATHODE.borrow(cs).borrow().get_status(),
|
|
|
|
ELECTROMETER.borrow(cs).borrow().get_status())
|
|
|
|
});
|
|
|
|
|
|
|
|
println!("");
|
|
|
|
anode.debug_print();
|
|
|
|
cathode.debug_print();
|
|
|
|
electrometer.debug_print();
|
|
|
|
if cathode.fbi.is_some() && electrometer.ic.is_some() {
|
|
|
|
let fbi = cathode.fbi.unwrap();
|
|
|
|
let ic = electrometer.ic.unwrap();
|
|
|
|
let pressure = ic/fbi/18.75154;
|
|
|
|
println!("{:.1e} mbar", pressure);
|
|
|
|
}
|
|
|
|
|
|
|
|
next_info = next_info + 3000;
|
2017-05-11 14:55:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if board::error_latched() {
|
|
|
|
match latch_reset_time {
|
|
|
|
None => {
|
|
|
|
println!("Protection latched");
|
2017-06-12 19:22:23 +08:00
|
|
|
latch_reset_time = Some(time + 10000);
|
2017-05-11 14:55:00 +08:00
|
|
|
}
|
|
|
|
Some(t) => if time > t {
|
|
|
|
latch_reset_time = None;
|
|
|
|
cortex_m::interrupt::free(|cs| {
|
|
|
|
// reset PID loops as they have accumulated large errors
|
|
|
|
// while the protection was active, which would cause
|
|
|
|
// unnecessary overshoots.
|
|
|
|
LOOP_ANODE.borrow(cs).borrow_mut().reset();
|
|
|
|
LOOP_CATHODE.borrow(cs).borrow_mut().reset();
|
2017-05-11 23:15:01 +08:00
|
|
|
board::reset_error();
|
2017-05-11 14:55:00 +08:00
|
|
|
});
|
|
|
|
println!("Protection reset");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-06 12:33:38 +08:00
|
|
|
}
|
2017-05-04 17:35:26 +08:00
|
|
|
}
|
|
|
|
|
2017-05-09 15:57:54 +08:00
|
|
|
use tm4c129x::interrupt::ADC0SS0;
|
2017-05-11 14:55:00 +08:00
|
|
|
extern fn adc0_ss0(_ctxt: ADC0SS0) {
|
2017-05-05 19:31:12 +08:00
|
|
|
cortex_m::interrupt::free(|cs| {
|
|
|
|
let adc0 = tm4c129x::ADC0.borrow(cs);
|
|
|
|
if adc0.ostat.read().ov0().bit() {
|
|
|
|
panic!("ADC FIFO overflowed")
|
|
|
|
}
|
2017-05-07 00:00:01 +08:00
|
|
|
adc0.isc.write(|w| w.in0().bit(true));
|
2017-05-05 19:31:12 +08:00
|
|
|
|
2017-05-11 14:55:00 +08:00
|
|
|
let ic_sample = adc0.ssfifo0.read().data().bits();
|
2017-05-09 15:57:54 +08:00
|
|
|
let fbi_sample = adc0.ssfifo0.read().data().bits();
|
|
|
|
let fv_sample = adc0.ssfifo0.read().data().bits();
|
|
|
|
let fd_sample = adc0.ssfifo0.read().data().bits();
|
|
|
|
let av_sample = adc0.ssfifo0.read().data().bits();
|
|
|
|
let fbv_sample = adc0.ssfifo0.read().data().bits();
|
|
|
|
|
|
|
|
let mut loop_anode = LOOP_ANODE.borrow(cs).borrow_mut();
|
|
|
|
let mut loop_cathode = LOOP_CATHODE.borrow(cs).borrow_mut();
|
2017-05-11 23:15:01 +08:00
|
|
|
let mut electrometer = ELECTROMETER.borrow(cs).borrow_mut();
|
2017-05-09 15:57:54 +08:00
|
|
|
loop_anode.adc_input(av_sample);
|
|
|
|
loop_cathode.adc_input(fbi_sample, fd_sample, fv_sample, fbv_sample);
|
2017-05-11 23:15:01 +08:00
|
|
|
electrometer.adc_input(ic_sample);
|
2017-05-09 15:57:54 +08:00
|
|
|
|
2017-05-11 14:55:00 +08:00
|
|
|
let time = TIME.borrow(cs);
|
|
|
|
time.set(time.get() + 1);
|
2017-05-10 00:10:52 +08:00
|
|
|
});
|
2017-05-05 19:31:12 +08:00
|
|
|
}
|
|
|
|
|
2017-05-04 17:35:26 +08:00
|
|
|
#[used]
|
|
|
|
#[link_section = ".rodata.exceptions"]
|
|
|
|
pub static EXCEPTIONS: ExceptionHandlers = ExceptionHandlers {
|
|
|
|
..cortex_m::exception::DEFAULT_HANDLERS
|
|
|
|
};
|
|
|
|
|
|
|
|
#[used]
|
|
|
|
#[link_section = ".rodata.interrupts"]
|
|
|
|
pub static INTERRUPTS: InterruptHandlers = InterruptHandlers {
|
2017-05-05 19:31:12 +08:00
|
|
|
ADC0SS0: adc0_ss0,
|
2017-05-04 17:35:26 +08:00
|
|
|
..tm4c129x::interrupt::DEFAULT_HANDLERS
|
|
|
|
};
|