149 lines
3.8 KiB
Rust
149 lines
3.8 KiB
Rust
#![no_main]
|
|
#![no_std]
|
|
use defmt_rtt as _; // global logger
|
|
|
|
use panic_probe as _;
|
|
use stm32f1xx_hal as _;
|
|
|
|
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
|
|
// this prevents the panic message being printed *twice* when `defmt::panic` is invoked
|
|
#[defmt::panic_handler]
|
|
fn panic() -> ! {
|
|
cortex_m::asm::udf()
|
|
}
|
|
|
|
use rtic::app;
|
|
|
|
mod si5153;
|
|
|
|
#[app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [TIM2])]
|
|
mod app {
|
|
|
|
use core::num::dec2flt::float;
|
|
|
|
use stm32f1xx_hal::{
|
|
adc,
|
|
gpio::{
|
|
self, gpioa, gpiob, gpioc, Alternate, Analog, Floating, Input, OpenDrain, Output,
|
|
PushPull, CRL,
|
|
},
|
|
i2c,
|
|
i2c::BlockingI2c,
|
|
pac::{ADC1, I2C1},
|
|
prelude::*,
|
|
serial::{self, Config, Serial},
|
|
stm32,
|
|
timer::{self, Event},
|
|
};
|
|
|
|
use systick_monotonic::Systick;
|
|
|
|
use arrayvec::ArrayString;
|
|
|
|
use crate::si5153;
|
|
|
|
type AppI2C1 = BlockingI2c<
|
|
I2C1,
|
|
(
|
|
gpiob::PB6<Alternate<OpenDrain>>,
|
|
gpiob::PB7<Alternate<OpenDrain>>,
|
|
),
|
|
>;
|
|
|
|
#[monotonic(binds = SysTick, default = true)]
|
|
type MonoTimer = Systick<1_000_000>;
|
|
|
|
#[shared]
|
|
struct Shared {}
|
|
|
|
#[local]
|
|
struct Local {
|
|
pll: si5153::Si5153<AppI2C1>,
|
|
i2c: AppI2C1,
|
|
board_led: gpioc::PC13<Output<PushPull>>,
|
|
adc1: adc::Adc<ADC1>,
|
|
mic_in: gpio::Pin<Analog, CRL, 'A', 4>,
|
|
}
|
|
|
|
#[init]
|
|
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
|
let mut flash = cx.device.FLASH.constrain();
|
|
let rcc = cx.device.RCC.constrain();
|
|
|
|
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in
|
|
// `clocks`
|
|
let clocks = rcc
|
|
.cfgr
|
|
.use_hse(8.MHz())
|
|
.sysclk(72.MHz())
|
|
.pclk1(36.MHz())
|
|
.freeze(&mut flash.acr);
|
|
|
|
defmt::info!("Clock Setup done");
|
|
|
|
let mono = Systick::new(cx.core.SYST, clocks.sysclk().to_Hz());
|
|
|
|
let mut afio = cx.device.AFIO.constrain();
|
|
|
|
// Acquire the GPIOC peripheral
|
|
let mut gpioa = cx.device.GPIOA.split();
|
|
let mut gpiob = cx.device.GPIOB.split();
|
|
let mut gpioc = cx.device.GPIOC.split();
|
|
|
|
let board_led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
|
|
|
|
let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl);
|
|
let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl);
|
|
let mut i2c = i2c::BlockingI2c::i2c1(
|
|
cx.device.I2C1,
|
|
(scl, sda),
|
|
&mut afio.mapr,
|
|
i2c::Mode::Standard {
|
|
frequency: 400.kHz(),
|
|
},
|
|
clocks,
|
|
5,
|
|
1,
|
|
5,
|
|
5,
|
|
);
|
|
|
|
let mut pll = si5153::Si5153::new(&i2c);
|
|
pll.init(&mut i2c, 25000000, 800000000, 800000000);
|
|
pll.set_ms_source(&mut i2c, si5153::Multisynth::MS0, si5153::PLL::A);
|
|
|
|
let adc1 = adc::Adc::adc1(cx.device.ADC1, clocks);
|
|
let mic_in = gpioa.pa4.into_analog(&mut gpioa.crl);
|
|
|
|
let mut pwm =
|
|
cx.device
|
|
.TIM2
|
|
.pwm_hz::<Tim3NoRemap, _, _>(pins, &mut afio.mapr, 4800.Hz(), &clocks);
|
|
|
|
transmit::spawn().unwrap();
|
|
|
|
(
|
|
Shared {},
|
|
Local {
|
|
i2c,
|
|
pll,
|
|
board_led,
|
|
adc1,
|
|
mic_in,
|
|
},
|
|
init::Monotonics(mono),
|
|
)
|
|
}
|
|
|
|
#[task(local=[pll, i2c, adc1, mic_in])]
|
|
fn transmit(mut ctx: transmit::Context) {
|
|
let mut adc = ctx.local.adc1;
|
|
let mut mic_in = ctx.local.mic_in;
|
|
|
|
let data: u16 = adc.read(&mut *mic_in).unwrap();
|
|
let sample = (data as f32 / u16::MAX as f32);
|
|
|
|
transmit::spawn_after(208.micros().into()).unwrap();
|
|
}
|
|
}
|