#![no_std]
#![no_main]
#![allow(static_mut_refs)]
use embedded_graphics as eg;
use panic_halt as _;
use wio_terminal as wio;
use cortex_m::peripheral::NVIC;
use wio::entry;
use wio::hal::adc::{FreeRunning, InterruptAdc};
use wio::hal::clock::GenericClockController;
use wio::hal::delay::Delay;
use wio::pac::{interrupt, ADC1};
use wio::pac::{CorePeripherals, Peripherals};
use wio::prelude::*;
use core::fmt::Write;
use eg::mono_font::{ascii::FONT_6X12, MonoTextStyle};
use eg::pixelcolor::Rgb565;
use eg::prelude::*;
use eg::primitives::{PrimitiveStyleBuilder, Rectangle};
use eg::text::{Baseline, Text};
use heapless::String;
use heapless::spsc::Queue;
struct Ctx {
adc: InterruptAdc<ADC1, ConversionMode>,
samples: Queue<u16, 8>,
}
static mut CTX: Option<Ctx> = None;
type ConversionMode = FreeRunning;
#[entry]
fn main() -> ! {
let mut peripherals = Peripherals::take().unwrap();
let core = CorePeripherals::take().unwrap();
let mut clocks = GenericClockController::with_external_32kosc(
peripherals.GCLK,
&mut peripherals.MCLK,
&mut peripherals.OSC32KCTRL,
&mut peripherals.OSCCTRL,
&mut peripherals.NVMCTRL,
);
let mut delay = Delay::new(core.SYST, &mut clocks);
let sets = wio::Pins::new(peripherals.PORT).split();
let (display, _backlight) = sets
.display
.init(
&mut clocks,
peripherals.SERCOM7,
&mut peripherals.MCLK,
58.MHz(),
&mut delay,
)
.unwrap();
let mut terminal = Terminal::new(display);
let mut textbuffer = String::<256>::new();
let mut user_led = sets.user_led.into_push_pull_output();
user_led.set_high().unwrap();
let (mut microphone_adc, mut microphone_pin) = {
let (adc, pin) = sets
.microphone
.init(peripherals.ADC1, &mut clocks, &mut peripherals.MCLK);
let interrupt_adc: InterruptAdc<_, ConversionMode> = InterruptAdc::from(adc);
(interrupt_adc, pin)
};
microphone_adc.start_conversion(&mut microphone_pin);
unsafe {
CTX = Some(Ctx {
adc: microphone_adc,
samples: Queue::new(),
});
}
let mut consumer = unsafe { CTX.as_mut().unwrap().samples.split().1 };
terminal.write_str("min,max,avg\n");
unsafe {
NVIC::unmask(interrupt::ADC1_RESRDY);
}
user_led.set_low().unwrap();
loop {
let mut min = core::f32::INFINITY;
let mut max = core::f32::NEG_INFINITY;
let mut sum = 0f32;
let count_max = 83333;
for _count in 0..count_max {
let value = loop {
if let Some(value) = consumer.dequeue() {
break value as f32;
}
};
if value < min {
min = value;
}
if max < value {
max = value
}
sum += value;
}
textbuffer.clear();
writeln!(textbuffer, "{},{},{}", min, max, sum / count_max as f32).unwrap();
terminal.write_str(textbuffer.as_str());
}
}
#[interrupt]
fn ADC1_RESRDY() {
unsafe {
let ctx = CTX.as_mut().unwrap();
let mut producer = ctx.samples.split().0;
if let Some(sample) = ctx.adc.service_interrupt_ready() {
producer.enqueue_unchecked(sample);
}
}
}
struct Terminal<'a> {
text_style: MonoTextStyle<'a, Rgb565>,
cursor: Point,
display: wio::LCD,
}
impl<'a> Terminal<'a> {
pub fn new(mut display: wio::LCD) -> Self {
let style = PrimitiveStyleBuilder::new()
.fill_color(Rgb565::BLACK)
.build();
let backdrop =
Rectangle::with_corners(Point::new(0, 0), Point::new(320, 320)).into_styled(style);
backdrop.draw(&mut display).ok().unwrap();
Self {
text_style: MonoTextStyle::new(&FONT_6X12, Rgb565::WHITE),
cursor: Point::new(0, 0),
display,
}
}
pub fn write_str(&mut self, str: &str) {
for character in str.chars() {
self.write_character(character);
}
}
pub fn write_character(&mut self, c: char) {
if self.cursor.x >= 320 || c == '\n' {
self.cursor = Point::new(0, self.cursor.y + FONT_6X12.character_size.height as i32);
}
if self.cursor.y >= 240 {
let style = PrimitiveStyleBuilder::new()
.fill_color(Rgb565::BLACK)
.build();
let backdrop =
Rectangle::with_corners(Point::new(0, 0), Point::new(320, 320)).into_styled(style);
backdrop.draw(&mut self.display).ok().unwrap();
self.cursor = Point::new(0, 0);
}
if c != '\n' {
let mut buf = [0u8; 8];
Text::with_baseline(
c.encode_utf8(&mut buf),
self.cursor,
self.text_style,
Baseline::Top,
)
.draw(&mut self.display)
.ok()
.unwrap();
self.cursor.x += (FONT_6X12.character_size.width + FONT_6X12.character_spacing) as i32;
}
}
}