piezo-ddr-controller/src/main.rs

228 lines
5.5 KiB
Rust
Raw Normal View History

#![no_main]
#![no_std]
2019-09-28 19:15:49 +00:00
// MCU is STM32F303VCT6
//
// Which GPIOs are free to use??
2019-09-28 19:15:49 +00:00
// Rather, which are taken? FROM THE DISCOVERY PDF:
// PA0 - AIN_1 with some filtering
// PA2 - STLINK_TX
// PA3 - STLINK_RX
// PA5 - SCL/SPC, T_JTCK
// PA6 - SA0/SDO, T_JTDO
// PA7 - SDA/SDI/SDO, T_JTDI
// PA8 - MCO (with LPF)
// PA9 - maybe tied to PA11
// PA10 - maybe tied to PA12
// PA11 - D-, maybe tied to PA9
// PA12 - D+, maybe tied to PA10
// PA13 - TMS/SWDIO
// PA14 - TCK/SWCLK
// PA15 - JTDI
// PB0 - T_NRST
// PB2 - GND
// PB3 - T_SWO
// PB4 - JNTRST
// PB5 - SWIM_RST_IN
// PB6 - SWIM_RST, SCL
// PB7 - SWIM_IN, SDA
// PB8 - SWIM
// PB9 - SWIM_IN
// PB10 - SWIM_IN
// PB11 - SWIM
// PB12 - T_SWDIO_IN connected to PB14
// PB13 - T_JTCK
// PB14 - T_JTMS connected to PB12
// PC4 - USARTI_RX
// PC5 - USARTI_TX
// PC13 - 10k pulldown
// PC14 - 10k pulldown (not fitted) tied to PC14-OSC32_IN
// PC15 - tied to PC15-OSC32_OUT
// PE0 - INT1
// PE1 - DRDY/INT2
// PE2 - DRDY
// PE3 - CS_I2C/SPI
// PE4 - INT1
// PE5 - INT2
// PE8 - LD4 blue
// PE9 - LD3 red
// PE10 - LD5 orange
// PE11 - LD7 green
// PE12 - LD9 blue
// PE13 - LD10 red
// PE14 - LD8 orange
// PE15 - LD6 green
// PF0 - tied to PF0-OSC_IN
// PF1 - tied to PF1-OSC_OUT
//
// It looks like Port D is safe to use, most of port c
2019-09-28 19:15:49 +00:00
//
// WHICH PINS CAN BE ROUTED TO THE ADC? (from the device data sheet)
// PA0 - ADC1_IN1
// PA1 - ADC1_IN2
// PA2 - ADC1_IN3
// PA3 - ADC1_IN4
// PA4 - ADC2_IN1
// PA5 - ADC2_IN2
// PA6 - ADC2_IN3
// PA7 - ADC2_IN4
// PB0 - ADC3_IN12
// PB1 - ADC3_IN1
// PB2 - ADC2_IN12
// PB12 - ADC4_IN3
// PB13 - ADC3_IN5
// PB14 - ADC4_IN4
// PB15 - ADC4_IN5
// PC0 - ADC12_IN6
// PC1 - ADC12_IN7
// PC2 - ADC12_IN8
// PC3 - ADC12_IN9
// PC4 - ADC2_IN5
// PC5 - ADC2_IN11
// PD8 - ADC4_IN12
// PD9 - ADC4_IN12
// PD10 - ADC34_IN7
// PD11 - ADC34_IN8
// PD12 - ADC34_IN8
// PD12 - ADC34_IN9
// PD13 - ADC34_IN10
// PD14 - ADC34_IN11
// PE7 - ADC3_IN13
// PE9 - ADC3_IN2
// PE10 - ADC3_IN14
// PE11 - ADC3_IN15
// PE12 - ADC3_IN16
// PE13 - ADC3_IN3
// PE14 - ADC4_IN1
// PE15 - ADC4_IN2
// PF2 - ADC12_IN10
// PF4 - ADC1_IN5
//
// PC0-3 look safe to use as ADC. PF2,4 as well.
//
// ANALOG INPUT
// from 11.3.2:
// For the ADC, DAC, OPAMP, and COMP, configure the desired I/O in analog mode
// in the GPIOx_MODER register and configure the required function in the ADC,
// DAC, OPAMP, and COMP registers.
//
// Need to generate ADC12_CK or ADC34_CK from RCC. Or derived from AHB bus clock. See CKMODE[1:0] of the ADCx_CCR
extern crate panic_itm; // panic handler
mod bsp;
use cortex_m::asm::{bkpt, delay};
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
let per = bsp::init();
// Configure clock gates
per.rcc.ahbenr.modify(|_, w| {
// enable IO Port A (push-button)
2019-09-28 19:15:49 +00:00
w.iopaen().enabled();
// enable IO Pord D (piezo)
2019-09-28 19:15:49 +00:00
w.iopden().enabled();
// enable IO Port E (LEDs)
2019-09-28 19:15:49 +00:00
w.iopeen().enabled();
// enable ADC 1/2
w.adc12en().enabled()
});
// All LEDS are outputs
per.gpioe.moder.modify(|_, w| {
w.moder8().output();
w.moder9().output();
w.moder10().output();
w.moder11().output();
w.moder12().output();
w.moder13().output();
w.moder14().output();
w.moder15().output()
});
// Configure push-button as input;
// Configure PA1 as analog-in
per.gpioa.moder.modify(|_, w| {
w.moder0().input()
.moder1().analog()
});
// Configure piezo as digital input
per.gpiod.moder.modify(|_, w| {
w.moder0().input()
});
// Turn on all the LEDs in the compass
per.gpioe.odr.write(|w| {
w.odr8().set_bit();
w.odr9().set_bit();
w.odr10().set_bit();
w.odr11().set_bit();
w.odr12().set_bit();
w.odr13().set_bit();
w.odr14().set_bit();
w.odr15().set_bit()
});
2019-09-28 19:15:49 +00:00
// Enable the ADC voltage regulator. 15.3.6
// Note: by default ADC will be clocked off the bus clock, divided by two.
per.adc1.cr.modify(|_, w| {
w.deeppwd().clear_bit()
});
// Docs make it sound like this _must_ be two separate writes.
// "T ADCVREG_STUP
// "The software must wait for the startup time of the ADC voltage regulator
// (T ADCVREG_STUP ) before launching a calibration or enabling the ADC."
// 10 uS worst-case
delay(1000); // >= 10 us
bkpt();
2019-09-28 19:15:49 +00:00
per.adc1.cr.modify(|_, w| {
w.advregen().set_bit()
});
// ADC CALIBRATION (15.3.8)
// 1. set ADCALDIF=0 (default)
// Start cal
2019-09-28 19:15:49 +00:00
per.adc1.cr.modify(|_, w| {
w.adcal().set_bit()
});
// Wait for done
while per.adc1.cr.read().adcal().bit() { }
2019-09-28 19:15:49 +00:00
// Enable ADC (15.3.9)
per.adc1.cr.modify(|_, w| {
w.aden().set_bit()
});
2019-09-28 19:15:49 +00:00
// wait for ADRDY=1
while per.adc1.isr.read().adrdy().bit_is_clear() { }
// Configure mux'ing: SQRx (regular conversion), JSQRx (injected conversion; don't use these)
// Draw from ADC1_IN2 -- PA1
per.adc1.sqr1.modify(|_, w| {
unsafe { w.sq1().bits(2) }
});
// Enable continuous mode (i.e. data will just continually appear in DR)
per.adc1.cfgr.modify(|_, w| {
w.cont().set_bit()
});
// Start ADC!
per.adc1.cr.modify(|_, w| {
w.adstart().set_bit()
});
2019-09-28 19:15:49 +00:00
bkpt();
loop {
//let push_button = per.gpioa.idr.read().idr0().bit();
let push_button = per.gpiod.idr.read().idr0().bit();
per.gpioe.odr.modify(|_, w| {
w.odr8().bit(push_button)
});
}
}