increase clock frequency, enable FPU correctly

pull/1/head
Sebastien Bourdeauducq 2017-06-12 19:22:23 +08:00
parent 52c123f215
commit 914dc7f6c8
5 changed files with 76 additions and 57 deletions

View File

@ -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| {

View File

@ -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<f32>
}
@ -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();

View File

@ -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);
}

View File

@ -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
};

View File

@ -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);
}
}
});
}