diff --git a/firmware/src/board.rs b/firmware/src/board.rs index 47180d7..0d3fb9c 100644 --- a/firmware/src/board.rs +++ b/firmware/src/board.rs @@ -24,9 +24,8 @@ const AI_ERRN: u8 = 0x10; // PL4 const ERR_LATCHN: u8 = 0x20; // PL5 const ERR_RESN: u8 = 0x01; // PQ0 -const PWM_LOAD: u16 = (/*pwmclk*/16_000_000u32 / /*freq*/100_000) as u16; -const UART_DIV_16P6: u32 = /*altclk*/16_000_000 * (1 << /*len(divfrac)*/6) / - (/*clkdiv*/16 * /*baud*/115200); +const PWM_LOAD: u16 = (/*pwmclk*/120_000_000u32 / /*freq*/100_000) as u16; +const UART_DIV: u32 = (((/*sysclk*/120_000_000 * 8) / /*baud*/115200) + 1) / 2; 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_OFFSET: f32 = 96.0; 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_MED: f32 = 13201320132.0132; 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.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.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)); 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 sysctl.rcgcgpio.modify(|_, w| { w.r0().bit(true) @@ -199,7 +205,7 @@ pub fn init() { while !sysctl.prgpio.read().r13().bit() {} while !sysctl.prgpio.read().r14().bit() {} - // Set up UART0 at 115200 + // Set up UART0 let gpio_a = tm4c129x::GPIO_PORTA_AHB.borrow(cs); gpio_a.dir.write(|w| w.dir().bits(0b11)); gpio_a.den.write(|w| w.den().bits(0b11)); @@ -210,9 +216,9 @@ pub fn init() { while !sysctl.pruart.read().r0().bit() {} let uart_0 = tm4c129x::UART0.borrow(cs); - uart_0.cc.write(|w| w.cs().altclk()); - uart_0.ibrd.write(|w| w.divint().bits((UART_DIV_16P6 >> 6) as u16)); - uart_0.fbrd.write(|w| w.divfrac().bits(UART_DIV_16P6 as u8)); + uart_0.cc.write(|w| w.cs().sysclk()); + uart_0.ibrd.write(|w| w.divint().bits((UART_DIV / 64) as u16)); + 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.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() {} let adc0 = tm4c129x::ADC0.borrow(cs); - // Due to silicon erratum, this HAS to use PLL. PIOSC is not a suitable source. - // fADC=32 MHz - adc0.cc.write(|w| w.cs().syspll().clkdiv().bits(10)); + // VCO 480 / 15 = 32MHz ADC clock + adc0.cc.write(|w| w.cs().syspll().clkdiv().bits(15-1)); adc0.im.write(|w| w.mask0().bit(true)); adc0.emux.write(|w| w.em0().always()); adc0.ssmux0.write(|w| { diff --git a/firmware/src/electrometer.rs b/firmware/src/electrometer.rs index a1bc436..e005d9d 100644 --- a/firmware/src/electrometer.rs +++ b/firmware/src/electrometer.rs @@ -4,7 +4,7 @@ pub struct Electrometer { range: board::ElectrometerRange, out_of_range_count: u8, ignore_count: u8, - ic_buffer: [f32; 64], + ic_buffer: [f32; 512], ic_buffer_count: usize, last_ic: Option } @@ -20,7 +20,7 @@ impl Electrometer { range: board::ElectrometerRange::Med, out_of_range_count: 0, ignore_count: 0, - ic_buffer: [0.0; 64], + ic_buffer: [0.0; 512], ic_buffer_count: 0, last_ic: None } @@ -48,7 +48,7 @@ impl Electrometer { if new_range.is_some() { self.out_of_range_count += 1; - if self.out_of_range_count < 10 { + if self.out_of_range_count < 75 { new_range = None; } } else { @@ -56,7 +56,7 @@ impl Electrometer { } if new_range.is_some() { - self.ignore_count = 20; + self.ignore_count = 150; self.ic_buffer_count = 0; self.last_ic = None; self.range = new_range.unwrap(); diff --git a/firmware/src/loop_anode.rs b/firmware/src/loop_anode.rs index 90f7ebc..923557e 100644 --- a/firmware/src/loop_anode.rs +++ b/firmware/src/loop_anode.rs @@ -4,11 +4,11 @@ use board; use pid; const PID_PARAMETERS: pid::Parameters = pid::Parameters { - kp: 0.035, - ki: 0.025, + kp: 0.2, + ki: 0.05, kd: 0.0, output_min: 0.0, - output_max: 30.0, + output_max: 225.0, integral_min: -700.0, integral_max: 700.0 }; @@ -44,7 +44,7 @@ impl Controller { } pub fn set_target(&mut self, volts: f32) { - self.target = 0.0; + self.target = volts; self.pid.set_target(volts); } diff --git a/firmware/src/loop_cathode.rs b/firmware/src/loop_cathode.rs index 2109e53..884ea37 100644 --- a/firmware/src/loop_cathode.rs +++ b/firmware/src/loop_cathode.rs @@ -4,21 +4,21 @@ use board; use pid; const FBI_PID_PARAMETERS: pid::Parameters = pid::Parameters { - kp: 350.0, - ki: 70.0, - kd: 10.0, + kp: 400.0, + ki: 20.0, + kd: 0.0, output_min: 0.5, output_max: 3.1, - integral_min: -0.05, - integral_max: 0.05 + integral_min: -0.1, + integral_max: 0.1 }; const FV_PID_PARAMETERS: pid::Parameters = pid::Parameters { - kp: 1.90, - ki: 0.35, + kp: 40.0, + ki: 1.0, kd: 0.0, output_min: 0.0, - output_max: 20.0, + output_max: 150.0, integral_min: -50.0, integral_max: 50.0 }; diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 0dd0168..ea156d7 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -1,4 +1,4 @@ -#![feature(used, const_fn, core_float)] +#![feature(used, const_fn, core_float, asm)] #![no_std] extern crate cortex_m; @@ -67,13 +67,29 @@ impl fmt::Write for UART0 { } 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(); cortex_m::interrupt::free(|cs| { - // Enable FPU - let scb = tm4c129x::SCB.borrow(cs); - scb.enable_fpu(); - let nvic = tm4c129x::NVIC.borrow(cs); nvic.enable(Interrupt::ADC0SS0); @@ -127,23 +143,36 @@ Ready."#); if time > next_blink { led_state = !led_state; - next_blink = time + 100; + next_blink = time + 1000; board::set_led(1, led_state); } - if time > next_info { - // FIXME: done in ISR now because of FPU snafu - /*cortex_m::interrupt::free(|cs| { - LOOP_CATHODE.borrow(cs).borrow().debug_print(); - });*/ - next_info = next_info + 300; + 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; } if board::error_latched() { match latch_reset_time { None => { println!("Protection latched"); - latch_reset_time = Some(time + 1000); + latch_reset_time = Some(time + 10000); } Some(t) => if time > t { latch_reset_time = None; @@ -187,21 +216,6 @@ extern fn adc0_ss0(_ctxt: ADC0SS0) { let time = TIME.borrow(cs); 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); - } - } }); }