forked from M-Labs/ionpak-thermostat
increase clock frequency, enable FPU correctly
This commit is contained in:
parent
52c123f215
commit
914dc7f6c8
|
@ -24,9 +24,8 @@ const AI_ERRN: u8 = 0x10; // PL4
|
||||||
const ERR_LATCHN: u8 = 0x20; // PL5
|
const ERR_LATCHN: u8 = 0x20; // PL5
|
||||||
const ERR_RESN: u8 = 0x01; // PQ0
|
const ERR_RESN: u8 = 0x01; // PQ0
|
||||||
|
|
||||||
const PWM_LOAD: u16 = (/*pwmclk*/16_000_000u32 / /*freq*/100_000) as u16;
|
const PWM_LOAD: u16 = (/*pwmclk*/120_000_000u32 / /*freq*/100_000) as u16;
|
||||||
const UART_DIV_16P6: u32 = /*altclk*/16_000_000 * (1 << /*len(divfrac)*/6) /
|
const UART_DIV: u32 = (((/*sysclk*/120_000_000 * 8) / /*baud*/115200) + 1) / 2;
|
||||||
(/*clkdiv*/16 * /*baud*/115200);
|
|
||||||
|
|
||||||
|
|
||||||
pub const AV_ADC_GAIN: f32 = 6.792703150912105;
|
pub const AV_ADC_GAIN: f32 = 6.792703150912105;
|
||||||
|
@ -36,7 +35,7 @@ pub const FBI_ADC_OFFSET: f32 = 96.0;
|
||||||
pub const FD_ADC_GAIN: f32 = 3111.1111111111104;
|
pub const FD_ADC_GAIN: f32 = 3111.1111111111104;
|
||||||
pub const FD_ADC_OFFSET: f32 = 96.0;
|
pub const FD_ADC_OFFSET: f32 = 96.0;
|
||||||
pub const FBV_ADC_GAIN: f32 = 49.13796058269066;
|
pub const FBV_ADC_GAIN: f32 = 49.13796058269066;
|
||||||
pub const FBV_PWM_GAIN: f32 = 0.5730803571428571;
|
pub const FBV_PWM_GAIN: f32 = 0.07641071428571428;
|
||||||
pub const IC_ADC_GAIN_LOW: f32 = 1333333333333.3333;
|
pub const IC_ADC_GAIN_LOW: f32 = 1333333333333.3333;
|
||||||
pub const IC_ADC_GAIN_MED: f32 = 13201320132.0132;
|
pub const IC_ADC_GAIN_MED: f32 = 13201320132.0132;
|
||||||
pub const IC_ADC_GAIN_HIGH: f32 = 133320001.3332;
|
pub const IC_ADC_GAIN_HIGH: f32 = 133320001.3332;
|
||||||
|
@ -171,12 +170,19 @@ pub fn init() {
|
||||||
sysctl.moscctl.write(|w| w.noxtal().bit(false));
|
sysctl.moscctl.write(|w| w.noxtal().bit(false));
|
||||||
sysctl.moscctl.modify(|_, w| w.pwrdn().bit(false).oscrng().bit(true));
|
sysctl.moscctl.modify(|_, w| w.pwrdn().bit(false).oscrng().bit(true));
|
||||||
|
|
||||||
// Set up PLL with fVCO=320 MHz
|
// Prepare flash for the high-freq clk
|
||||||
|
sysctl.memtim0.write(|w| unsafe { w.bits(0x01950195u32) });
|
||||||
|
sysctl.rsclkcfg.write(|w| unsafe { w.bits(0x80000000u32) });
|
||||||
|
|
||||||
|
// Set up PLL with fVCO=480 MHz
|
||||||
sysctl.pllfreq1.write(|w| w.q().bits(0).n().bits(4));
|
sysctl.pllfreq1.write(|w| w.q().bits(0).n().bits(4));
|
||||||
sysctl.pllfreq0.write(|w| w.mint().bits(64).pllpwr().bit(true));
|
sysctl.pllfreq0.write(|w| w.mint().bits(96).pllpwr().bit(true));
|
||||||
sysctl.rsclkcfg.modify(|_, w| w.pllsrc().mosc().newfreq().bit(true));
|
sysctl.rsclkcfg.modify(|_, w| w.pllsrc().mosc().newfreq().bit(true));
|
||||||
while !sysctl.pllstat.read().lock().bit() {}
|
while !sysctl.pllstat.read().lock().bit() {}
|
||||||
|
|
||||||
|
// Switch to PLL (sysclk=120MHz)
|
||||||
|
sysctl.rsclkcfg.write(|w| unsafe { w.bits(0b1_0_0_1_0011_0000_0000000000_0000000011) });
|
||||||
|
|
||||||
// Bring up GPIO ports A, D, E, F, G, K, L, P, Q
|
// Bring up GPIO ports A, D, E, F, G, K, L, P, Q
|
||||||
sysctl.rcgcgpio.modify(|_, w| {
|
sysctl.rcgcgpio.modify(|_, w| {
|
||||||
w.r0().bit(true)
|
w.r0().bit(true)
|
||||||
|
@ -199,7 +205,7 @@ pub fn init() {
|
||||||
while !sysctl.prgpio.read().r13().bit() {}
|
while !sysctl.prgpio.read().r13().bit() {}
|
||||||
while !sysctl.prgpio.read().r14().bit() {}
|
while !sysctl.prgpio.read().r14().bit() {}
|
||||||
|
|
||||||
// Set up UART0 at 115200
|
// Set up UART0
|
||||||
let gpio_a = tm4c129x::GPIO_PORTA_AHB.borrow(cs);
|
let gpio_a = tm4c129x::GPIO_PORTA_AHB.borrow(cs);
|
||||||
gpio_a.dir.write(|w| w.dir().bits(0b11));
|
gpio_a.dir.write(|w| w.dir().bits(0b11));
|
||||||
gpio_a.den.write(|w| w.den().bits(0b11));
|
gpio_a.den.write(|w| w.den().bits(0b11));
|
||||||
|
@ -210,9 +216,9 @@ pub fn init() {
|
||||||
while !sysctl.pruart.read().r0().bit() {}
|
while !sysctl.pruart.read().r0().bit() {}
|
||||||
|
|
||||||
let uart_0 = tm4c129x::UART0.borrow(cs);
|
let uart_0 = tm4c129x::UART0.borrow(cs);
|
||||||
uart_0.cc.write(|w| w.cs().altclk());
|
uart_0.cc.write(|w| w.cs().sysclk());
|
||||||
uart_0.ibrd.write(|w| w.divint().bits((UART_DIV_16P6 >> 6) as u16));
|
uart_0.ibrd.write(|w| w.divint().bits((UART_DIV / 64) as u16));
|
||||||
uart_0.fbrd.write(|w| w.divfrac().bits(UART_DIV_16P6 as u8));
|
uart_0.fbrd.write(|w| w.divfrac().bits((UART_DIV % 64) as u8));
|
||||||
uart_0.lcrh.write(|w| w.wlen()._8().fen().bit(true));
|
uart_0.lcrh.write(|w| w.wlen()._8().fen().bit(true));
|
||||||
uart_0.ctl.write(|w| w.rxe().bit(true).txe().bit(true).uarten().bit(true));
|
uart_0.ctl.write(|w| w.rxe().bit(true).txe().bit(true).uarten().bit(true));
|
||||||
|
|
||||||
|
@ -288,9 +294,8 @@ pub fn init() {
|
||||||
while !sysctl.pradc.read().r0().bit() {}
|
while !sysctl.pradc.read().r0().bit() {}
|
||||||
|
|
||||||
let adc0 = tm4c129x::ADC0.borrow(cs);
|
let adc0 = tm4c129x::ADC0.borrow(cs);
|
||||||
// Due to silicon erratum, this HAS to use PLL. PIOSC is not a suitable source.
|
// VCO 480 / 15 = 32MHz ADC clock
|
||||||
// fADC=32 MHz
|
adc0.cc.write(|w| w.cs().syspll().clkdiv().bits(15-1));
|
||||||
adc0.cc.write(|w| w.cs().syspll().clkdiv().bits(10));
|
|
||||||
adc0.im.write(|w| w.mask0().bit(true));
|
adc0.im.write(|w| w.mask0().bit(true));
|
||||||
adc0.emux.write(|w| w.em0().always());
|
adc0.emux.write(|w| w.em0().always());
|
||||||
adc0.ssmux0.write(|w| {
|
adc0.ssmux0.write(|w| {
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub struct Electrometer {
|
||||||
range: board::ElectrometerRange,
|
range: board::ElectrometerRange,
|
||||||
out_of_range_count: u8,
|
out_of_range_count: u8,
|
||||||
ignore_count: u8,
|
ignore_count: u8,
|
||||||
ic_buffer: [f32; 64],
|
ic_buffer: [f32; 512],
|
||||||
ic_buffer_count: usize,
|
ic_buffer_count: usize,
|
||||||
last_ic: Option<f32>
|
last_ic: Option<f32>
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ impl Electrometer {
|
||||||
range: board::ElectrometerRange::Med,
|
range: board::ElectrometerRange::Med,
|
||||||
out_of_range_count: 0,
|
out_of_range_count: 0,
|
||||||
ignore_count: 0,
|
ignore_count: 0,
|
||||||
ic_buffer: [0.0; 64],
|
ic_buffer: [0.0; 512],
|
||||||
ic_buffer_count: 0,
|
ic_buffer_count: 0,
|
||||||
last_ic: None
|
last_ic: None
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl Electrometer {
|
||||||
|
|
||||||
if new_range.is_some() {
|
if new_range.is_some() {
|
||||||
self.out_of_range_count += 1;
|
self.out_of_range_count += 1;
|
||||||
if self.out_of_range_count < 10 {
|
if self.out_of_range_count < 75 {
|
||||||
new_range = None;
|
new_range = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -56,7 +56,7 @@ impl Electrometer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if new_range.is_some() {
|
if new_range.is_some() {
|
||||||
self.ignore_count = 20;
|
self.ignore_count = 150;
|
||||||
self.ic_buffer_count = 0;
|
self.ic_buffer_count = 0;
|
||||||
self.last_ic = None;
|
self.last_ic = None;
|
||||||
self.range = new_range.unwrap();
|
self.range = new_range.unwrap();
|
||||||
|
|
|
@ -4,11 +4,11 @@ use board;
|
||||||
use pid;
|
use pid;
|
||||||
|
|
||||||
const PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
const PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
||||||
kp: 0.035,
|
kp: 0.2,
|
||||||
ki: 0.025,
|
ki: 0.05,
|
||||||
kd: 0.0,
|
kd: 0.0,
|
||||||
output_min: 0.0,
|
output_min: 0.0,
|
||||||
output_max: 30.0,
|
output_max: 225.0,
|
||||||
integral_min: -700.0,
|
integral_min: -700.0,
|
||||||
integral_max: 700.0
|
integral_max: 700.0
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,7 @@ impl Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_target(&mut self, volts: f32) {
|
pub fn set_target(&mut self, volts: f32) {
|
||||||
self.target = 0.0;
|
self.target = volts;
|
||||||
self.pid.set_target(volts);
|
self.pid.set_target(volts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,21 @@ use board;
|
||||||
use pid;
|
use pid;
|
||||||
|
|
||||||
const FBI_PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
const FBI_PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
||||||
kp: 350.0,
|
kp: 400.0,
|
||||||
ki: 70.0,
|
ki: 20.0,
|
||||||
kd: 10.0,
|
kd: 0.0,
|
||||||
output_min: 0.5,
|
output_min: 0.5,
|
||||||
output_max: 3.1,
|
output_max: 3.1,
|
||||||
integral_min: -0.05,
|
integral_min: -0.1,
|
||||||
integral_max: 0.05
|
integral_max: 0.1
|
||||||
};
|
};
|
||||||
|
|
||||||
const FV_PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
const FV_PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
||||||
kp: 1.90,
|
kp: 40.0,
|
||||||
ki: 0.35,
|
ki: 1.0,
|
||||||
kd: 0.0,
|
kd: 0.0,
|
||||||
output_min: 0.0,
|
output_min: 0.0,
|
||||||
output_max: 20.0,
|
output_max: 150.0,
|
||||||
integral_min: -50.0,
|
integral_min: -50.0,
|
||||||
integral_max: 50.0
|
integral_max: 50.0
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(used, const_fn, core_float)]
|
#![feature(used, const_fn, core_float, asm)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate cortex_m;
|
extern crate cortex_m;
|
||||||
|
@ -67,13 +67,29 @@ impl fmt::Write for UART0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// 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() {
|
||||||
board::init();
|
board::init();
|
||||||
|
|
||||||
cortex_m::interrupt::free(|cs| {
|
cortex_m::interrupt::free(|cs| {
|
||||||
// Enable FPU
|
|
||||||
let scb = tm4c129x::SCB.borrow(cs);
|
|
||||||
scb.enable_fpu();
|
|
||||||
|
|
||||||
let nvic = tm4c129x::NVIC.borrow(cs);
|
let nvic = tm4c129x::NVIC.borrow(cs);
|
||||||
nvic.enable(Interrupt::ADC0SS0);
|
nvic.enable(Interrupt::ADC0SS0);
|
||||||
|
|
||||||
|
@ -127,23 +143,36 @@ Ready."#);
|
||||||
|
|
||||||
if time > next_blink {
|
if time > next_blink {
|
||||||
led_state = !led_state;
|
led_state = !led_state;
|
||||||
next_blink = time + 100;
|
next_blink = time + 1000;
|
||||||
board::set_led(1, led_state);
|
board::set_led(1, led_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if time > next_info {
|
if time >= next_info {
|
||||||
// FIXME: done in ISR now because of FPU snafu
|
let (anode, cathode, electrometer) = cortex_m::interrupt::free(|cs| {
|
||||||
/*cortex_m::interrupt::free(|cs| {
|
(LOOP_ANODE.borrow(cs).borrow().get_status(),
|
||||||
LOOP_CATHODE.borrow(cs).borrow().debug_print();
|
LOOP_CATHODE.borrow(cs).borrow().get_status(),
|
||||||
});*/
|
ELECTROMETER.borrow(cs).borrow().get_status())
|
||||||
next_info = next_info + 300;
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if board::error_latched() {
|
if board::error_latched() {
|
||||||
match latch_reset_time {
|
match latch_reset_time {
|
||||||
None => {
|
None => {
|
||||||
println!("Protection latched");
|
println!("Protection latched");
|
||||||
latch_reset_time = Some(time + 1000);
|
latch_reset_time = Some(time + 10000);
|
||||||
}
|
}
|
||||||
Some(t) => if time > t {
|
Some(t) => if time > t {
|
||||||
latch_reset_time = None;
|
latch_reset_time = None;
|
||||||
|
@ -187,21 +216,6 @@ extern fn adc0_ss0(_ctxt: ADC0SS0) {
|
||||||
|
|
||||||
let time = TIME.borrow(cs);
|
let time = TIME.borrow(cs);
|
||||||
time.set(time.get() + 1);
|
time.set(time.get() + 1);
|
||||||
|
|
||||||
if time.get() % 300 == 0 {
|
|
||||||
println!("");
|
|
||||||
/*loop_anode.get_status().debug_print();
|
|
||||||
loop_cathode.get_status().debug_print();
|
|
||||||
electrometer.get_status().debug_print();*/
|
|
||||||
let cathode_status = loop_cathode.get_status();
|
|
||||||
let electrometer_status = electrometer.get_status();
|
|
||||||
if cathode_status.fbi.is_some() && electrometer_status.ic.is_some() {
|
|
||||||
let fbi = cathode_status.fbi.unwrap();
|
|
||||||
let ic = electrometer_status.ic.unwrap();
|
|
||||||
let pressure = ic/fbi/18.75154;
|
|
||||||
println!("{:.1e} mbar", pressure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue