Implement ADC readout.

This commit is contained in:
whitequark 2017-05-05 11:31:12 +00:00
parent 87e97c4894
commit 5a011ea410
2 changed files with 91 additions and 12 deletions

8
firmware/Cargo.lock generated
View File

@ -4,7 +4,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"cortex-m 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-m-rt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m-rt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tm4c129x 0.3.0 (git+https://github.com/m-labs/dslite2svd)", "tm4c129x 0.4.0 (git+https://github.com/m-labs/dslite2svd)",
] ]
[[package]] [[package]]
@ -42,8 +42,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "tm4c129x" name = "tm4c129x"
version = "0.3.0" version = "0.4.0"
source = "git+https://github.com/m-labs/dslite2svd#f01cff2384123e24b1a8e2d1f81141a1a8bafad9" source = "git+https://github.com/m-labs/dslite2svd#7539765c94fa1643fab8a316e1eeef03d243b8fa"
dependencies = [ dependencies = [
"cortex-m 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "cortex-m 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -68,6 +68,6 @@ dependencies = [
"checksum cortex-m-rt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed494cbd15190fae60f608e6b4690e753df47b5f5e25e95d3c298f801f5c1d0" "checksum cortex-m-rt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ed494cbd15190fae60f608e6b4690e753df47b5f5e25e95d3c298f801f5c1d0"
"checksum cortex-m-semihosting 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54a88e8fd577808637f819107f34eece1b6b45be8db1c56d1c563095b80b655e" "checksum cortex-m-semihosting 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54a88e8fd577808637f819107f34eece1b6b45be8db1c56d1c563095b80b655e"
"checksum r0 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e7bbed8cd0a245bbf3759ebb35c964822b7a8c15ceeeee56d4cc5f060ce518e" "checksum r0 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e7bbed8cd0a245bbf3759ebb35c964822b7a8c15ceeeee56d4cc5f060ce518e"
"checksum tm4c129x 0.3.0 (git+https://github.com/m-labs/dslite2svd)" = "<none>" "checksum tm4c129x 0.4.0 (git+https://github.com/m-labs/dslite2svd)" = "<none>"
"checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d" "checksum vcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45c297f0afb6928cd08ab1ff9d95e99392595ea25ae1b5ecf822ff8764e57a0d"
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286" "checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"

View File

@ -9,15 +9,23 @@ extern crate tm4c129x;
use core::cell::Cell; use core::cell::Cell;
use cortex_m::ctxt::Local; use cortex_m::ctxt::Local;
use cortex_m::exception::Handlers as ExceptionHandlers; use cortex_m::exception::Handlers as ExceptionHandlers;
use tm4c129x::interrupt::Interrupt;
use tm4c129x::interrupt::Handlers as InterruptHandlers; use tm4c129x::interrupt::Handlers as InterruptHandlers;
const LED1: u8 = 0x10; const LED1: u8 = 0x10; //PF1
const LED2: u8 = 0x40; const LED2: u8 = 0x40; //PF3
const HV_PWM: u8 = 0x01; const HV_PWM: u8 = 0x01; //PF0
const FV_PWM: u8 = 0x04; const FV_PWM: u8 = 0x04; //PF2
const FBV_PWM: u8 = 0x01; const FBV_PWM: u8 = 0x01; //PD5
const FD_ADC: u8 = 0x01; //PE0
const FV_ADC: u8 = 0x02; //PE1
const FBI_ADC: u8 = 0x04; //PE2
const IC_ADC: u8 = 0x08; //PE3
const FBV_ADC: u8 = 0x20; //PD5
const AV_ADC: u8 = 0x40; //PD6
const PWM_LOAD: u16 = (/*pwmclk*/16_000_000u32 / /*freq*/100_000) as u16; const PWM_LOAD: u16 = (/*pwmclk*/16_000_000u32 / /*freq*/100_000) as u16;
const ADC_TIMER_LOAD: u32 = /*timerclk*/16_000_000 / /*freq*/100;
fn set_led(nr: u8, state: bool) { fn set_led(nr: u8, state: bool) {
cortex_m::interrupt::free(|cs| { cortex_m::interrupt::free(|cs| {
@ -51,6 +59,7 @@ fn set_fbv_pwm(duty: u16) {
}); });
} }
#[allow(dead_code)]
enum EmissionRange { enum EmissionRange {
Low, // 22K Low, // 22K
Med, // 22K//(200Ω + compensated diode) Med, // 22K//(200Ω + compensated diode)
@ -76,6 +85,7 @@ fn main() {
cortex_m::interrupt::free(|cs| { cortex_m::interrupt::free(|cs| {
let sysctl = tm4c129x::SYSCTL.borrow(cs); let sysctl = tm4c129x::SYSCTL.borrow(cs);
let nvic = tm4c129x::NVIC.borrow(cs);
// Set up system timer // Set up system timer
let systick = tm4c129x::SYST.borrow(cs); let systick = tm4c129x::SYST.borrow(cs);
@ -83,13 +93,17 @@ fn main() {
systick.enable_counter(); systick.enable_counter();
systick.enable_interrupt(); systick.enable_interrupt();
// Bring up GPIO ports F, G, K, P // Bring up GPIO ports D, E, F, G, K, P
sysctl.rcgcgpio.modify(|_, w| { sysctl.rcgcgpio.modify(|_, w| {
w.r5().bit(true) w.r3().bit(true)
.r4().bit(true)
.r5().bit(true)
.r6().bit(true) .r6().bit(true)
.r9().bit(true) .r9().bit(true)
.r13().bit(true) .r13().bit(true)
}); });
while !sysctl.prgpio.read().r3().bit() {}
while !sysctl.prgpio.read().r4().bit() {}
while !sysctl.prgpio.read().r5().bit() {} while !sysctl.prgpio.read().r5().bit() {}
while !sysctl.prgpio.read().r6().bit() {} while !sysctl.prgpio.read().r6().bit() {}
while !sysctl.prgpio.read().r9().bit() {} while !sysctl.prgpio.read().r9().bit() {}
@ -144,6 +158,53 @@ fn main() {
.pwm4en().bit(true) .pwm4en().bit(true)
}); });
// Set up ADC
let gpio_d = tm4c129x::GPIO_PORTD_AHB.borrow(cs);
let gpio_e = tm4c129x::GPIO_PORTE_AHB.borrow(cs);
gpio_d.amsel.write(|w| w.amsel().bits(FBV_ADC|AV_ADC));
gpio_e.amsel.write(|w| w.amsel().bits(FD_ADC|FV_ADC|FBI_ADC|IC_ADC));
sysctl.rcgcadc.modify(|_, w| w.r0().bit(true));
while !sysctl.pradc.read().r0().bit() {}
let adc0 = tm4c129x::ADC0.borrow(cs);
adc0.actss.write(|w| w.asen0().bit(true));
adc0.im.write(|w| w.mask0().bit(true));
adc0.emux.write(|w| w.em0().timer());
adc0.sac.write(|w| w.avg()._64x());
adc0.ctl.write(|w| w.vref().bit(true));
adc0.ssmux0.write(|w| {
w.mux0().bits(0) //IC_ADC
.mux1().bits(1) //FBI_ADC
.mux2().bits(2) //FV_ADC
.mux3().bits(3) //FD_ADC
.mux4().bits(5) //AV_ADC
.mux5().bits(6) //FBV_ADC
});
adc0.ssctl0.write(|w| w.end5().bit(true));
adc0.sstsh0.write(|w| {
w.tsh0()._256()
.tsh1()._256()
.tsh2()._256()
.tsh3()._256()
.tsh4()._256()
.tsh5()._256()
});
nvic.enable(Interrupt::ADC0SS0);
// Set up ADC timer
sysctl.rcgctimer.modify(|_, w| w.r0().bit(true));
while !sysctl.prtimer.read().r0().bit() {}
let timer0 = tm4c129x::TIMER0.borrow(cs);
timer0.cfg.write(|w| w.cfg()._32_bit_timer());
timer0.tamr.write(|w| w.tamr().period());
timer0.tailr.write(|w| unsafe { w.bits(ADC_TIMER_LOAD) });
timer0.adcev.write(|w| w.tatoadcen().bit(true));
timer0.cc.write(|w| w.altclk().bit(true));
timer0.ctl.write(|w| w.taen().bit(true));
set_emission_range(EmissionRange::Med); set_emission_range(EmissionRange::Med);
set_hv_pwm(PWM_LOAD/64); set_hv_pwm(PWM_LOAD/64);
set_fv_pwm(PWM_LOAD/16); set_fv_pwm(PWM_LOAD/16);
@ -151,8 +212,8 @@ fn main() {
}); });
} }
use cortex_m::exception::SysTick;
use cortex_m::exception::SysTick;
extern fn sys_tick(ctxt: SysTick) { extern fn sys_tick(ctxt: SysTick) {
static ELAPSED: Local<Cell<u32>, SysTick> = Local::new(Cell::new(0)); static ELAPSED: Local<Cell<u32>, SysTick> = Local::new(Cell::new(0));
let elapsed = ELAPSED.borrow(&ctxt); let elapsed = ELAPSED.borrow(&ctxt);
@ -168,6 +229,23 @@ extern fn sys_tick(ctxt: SysTick) {
} }
} }
use tm4c129x::interrupt::ADC0SS0;
extern fn adc0_ss0(_ctxt: ADC0SS0) {
cortex_m::interrupt::free(|cs| {
let adc0 = tm4c129x::ADC0.borrow(cs);
if adc0.ostat.read().ov0().bit() {
panic!("ADC FIFO overflowed")
}
let _ic_sample = adc0.ssfifo0.read().data();
let _fbi_sample = adc0.ssfifo0.read().data();
let _fv_sample = adc0.ssfifo0.read().data();
let _fd_sample = adc0.ssfifo0.read().data();
let _av_sample = adc0.ssfifo0.read().data();
let _fbv_sample = adc0.ssfifo0.read().data();
})
}
#[used] #[used]
#[link_section = ".rodata.exceptions"] #[link_section = ".rodata.exceptions"]
pub static EXCEPTIONS: ExceptionHandlers = ExceptionHandlers { pub static EXCEPTIONS: ExceptionHandlers = ExceptionHandlers {
@ -178,5 +256,6 @@ pub static EXCEPTIONS: ExceptionHandlers = ExceptionHandlers {
#[used] #[used]
#[link_section = ".rodata.interrupts"] #[link_section = ".rodata.interrupts"]
pub static INTERRUPTS: InterruptHandlers = InterruptHandlers { pub static INTERRUPTS: InterruptHandlers = InterruptHandlers {
ADC0SS0: adc0_ss0,
..tm4c129x::interrupt::DEFAULT_HANDLERS ..tm4c129x::interrupt::DEFAULT_HANDLERS
}; };