ionpak-thermostat/src/main.rs

154 lines
4.6 KiB
Rust
Raw Normal View History

2017-05-04 17:35:26 +08:00
#![feature(used, const_fn)]
#![no_std]
#[macro_use]
extern crate cortex_m;
extern crate cortex_m_rt;
extern crate tm4c129x;
use core::cell::Cell;
use cortex_m::ctxt::Local;
use cortex_m::exception::Handlers as ExceptionHandlers;
use tm4c129x::interrupt::Handlers as InterruptHandlers;
2017-05-04 18:59:35 +08:00
const LED1: u8 = 0x10;
const LED2: u8 = 0x40;
2017-05-04 19:42:22 +08:00
const HV_PWM: u8 = 0x01;
const FV_PWM: u8 = 0x04;
2017-05-04 21:41:57 +08:00
const FBV_PWM: u8 = 0x01;
2017-05-04 19:42:22 +08:00
2017-05-04 21:41:57 +08:00
const PWM_LOAD: u16 = (/*pwmclk*/16_000_000u32 / /*freq*/100_000) as u16;
2017-05-04 18:59:35 +08:00
fn set_led(nr: u8, state: bool) {
cortex_m::interrupt::free(|cs| {
let gpio_k = tm4c129x::GPIO_PORTK.borrow(cs);
if state {
gpio_k.data.modify(|r, w| w.data().bits(r.data().bits() | nr))
} else {
gpio_k.data.modify(|r, w| w.data().bits(r.data().bits() & !nr))
}
});
}
2017-05-04 21:41:57 +08:00
fn set_hv_pwm(duty: u16) {
2017-05-04 21:12:39 +08:00
cortex_m::interrupt::free(|cs| {
let pwm0 = tm4c129x::PWM0.borrow(cs);
2017-05-04 21:41:57 +08:00
pwm0._0_cmpa.write(|w| w.compa().bits(duty));
2017-05-04 21:12:39 +08:00
});
2017-05-04 19:42:22 +08:00
}
2017-05-04 21:41:57 +08:00
fn set_fv_pwm(duty: u16) {
2017-05-04 21:12:39 +08:00
cortex_m::interrupt::free(|cs| {
let pwm0 = tm4c129x::PWM0.borrow(cs);
2017-05-04 21:41:57 +08:00
pwm0._1_cmpa.write(|w| w.compa().bits(duty));
});
}
fn set_fbv_pwm(duty: u16) {
cortex_m::interrupt::free(|cs| {
let pwm0 = tm4c129x::PWM0.borrow(cs);
pwm0._2_cmpa.write(|w| w.compa().bits(duty));
2017-05-04 21:12:39 +08:00
});
2017-05-04 19:42:22 +08:00
}
2017-05-04 17:35:26 +08:00
fn main() {
hprintln!("Hello, world!");
cortex_m::interrupt::free(|cs| {
2017-05-04 19:42:22 +08:00
let sysctl = tm4c129x::SYSCTL.borrow(cs);
// Set up system timer
2017-05-04 17:35:26 +08:00
let systick = tm4c129x::SYST.borrow(cs);
2017-05-04 19:42:22 +08:00
systick.set_reload(systick.get_ticks_per_10ms());
systick.enable_counter();
systick.enable_interrupt();
2017-05-04 17:35:26 +08:00
2017-05-04 21:41:57 +08:00
// Bring up GPIO ports F, G, K
sysctl.rcgcgpio.modify(|_, w| {
w.r5().bit(true)
.r6().bit(true)
.r9().bit(true)
});
2017-05-04 19:42:22 +08:00
while !sysctl.prgpio.read().r5().bit() {}
2017-05-04 21:41:57 +08:00
while !sysctl.prgpio.read().r6().bit() {}
2017-05-04 18:59:35 +08:00
while !sysctl.prgpio.read().r9().bit() {}
// Set up LEDs
2017-05-04 19:42:22 +08:00
let gpio_k = tm4c129x::GPIO_PORTK.borrow(cs);
2017-05-04 18:59:35 +08:00
gpio_k.dir.write(|w| w.dir().bits(LED1|LED2));
gpio_k.den.write(|w| w.den().bits(LED1|LED2));
2017-05-04 19:42:22 +08:00
// Set up PWMs
let gpio_f = tm4c129x::GPIO_PORTF_AHB.borrow(cs);
gpio_f.dir.write(|w| w.dir().bits(HV_PWM|FV_PWM));
gpio_f.den.write(|w| w.den().bits(HV_PWM|FV_PWM));
gpio_f.afsel.write(|w| w.afsel().bits(HV_PWM|FV_PWM));
gpio_f.pctl.write(|w| unsafe { w.pmc0().bits(6).pmc2().bits(6) });
2017-05-04 21:41:57 +08:00
let gpio_g = tm4c129x::GPIO_PORTG_AHB.borrow(cs);
gpio_g.dir.write(|w| w.dir().bits(FBV_PWM));
gpio_g.den.write(|w| w.den().bits(FBV_PWM));
gpio_g.afsel.write(|w| w.afsel().bits(FBV_PWM));
gpio_g.pctl.write(|w| unsafe { w.pmc0().bits(6) });
2017-05-04 19:42:22 +08:00
sysctl.rcgcpwm.modify(|_, w| w.r0().bit(true));
while !sysctl.prpwm.read().r0().bit() {}
let pwm0 = tm4c129x::PWM0.borrow(cs);
2017-05-04 21:12:39 +08:00
// HV_PWM
2017-05-04 19:42:22 +08:00
pwm0._0_gena.write(|w| w.actload().zero().actcmpad().one());
2017-05-04 21:41:57 +08:00
pwm0._0_load.write(|w| w.load().bits(PWM_LOAD));
pwm0._0_cmpa.write(|w| w.compa().bits(0));
2017-05-04 19:42:22 +08:00
pwm0._0_ctl.write(|w| w.enable().bit(true));
2017-05-04 21:12:39 +08:00
// FV_PWM
2017-05-04 19:42:22 +08:00
pwm0._1_gena.write(|w| w.actload().zero().actcmpad().one());
2017-05-04 21:41:57 +08:00
pwm0._1_load.write(|w| w.load().bits(PWM_LOAD));
pwm0._1_cmpa.write(|w| w.compa().bits(0));
2017-05-04 19:42:22 +08:00
pwm0._1_ctl.write(|w| w.enable().bit(true));
2017-05-04 21:41:57 +08:00
// FBV_PWM
pwm0._2_gena.write(|w| w.actload().zero().actcmpad().one());
pwm0._2_load.write(|w| w.load().bits(PWM_LOAD));
pwm0._2_cmpa.write(|w| w.compa().bits(0));
pwm0._2_ctl.write(|w| w.enable().bit(true));
// Enable all at once
pwm0.enable.write(|w| {
w.pwm0en().bit(true)
.pwm2en().bit(true)
.pwm4en().bit(true)
});
2017-05-04 21:12:39 +08:00
set_hv_pwm(PWM_LOAD/64);
set_fv_pwm(PWM_LOAD/16);
2017-05-04 17:35:26 +08:00
});
}
use cortex_m::exception::SysTick;
extern fn sys_tick(ctxt: SysTick) {
static ELAPSED: Local<Cell<u32>, SysTick> = Local::new(Cell::new(0));
let elapsed = ELAPSED.borrow(&ctxt);
elapsed.set(elapsed.get() + 1);
2017-05-04 18:59:35 +08:00
if elapsed.get() % 100 == 0 {
set_led(LED1, true);
set_led(LED2, false);
}
if elapsed.get() % 100 == 50 {
set_led(LED1, false);
set_led(LED2, true);
}
2017-05-04 17:35:26 +08:00
}
#[used]
#[link_section = ".rodata.exceptions"]
pub static EXCEPTIONS: ExceptionHandlers = ExceptionHandlers {
sys_tick: sys_tick,
..cortex_m::exception::DEFAULT_HANDLERS
};
#[used]
#[link_section = ".rodata.interrupts"]
pub static INTERRUPTS: InterruptHandlers = InterruptHandlers {
..tm4c129x::interrupt::DEFAULT_HANDLERS
};