use rb::{Reader, RingBuffer, Writer}; use core::fmt::{self, Write}; use embedded_hal::{digital::v2::OutputPin, serial}; use trinket_m0::{ gpio::{Pa6, Pa7, PfD}, sercom::{Sercom0Pad2, Sercom0Pad3, UART0}, }; static mut LB: RingBuffer = RingBuffer::::new(0); struct JoinedRingBuffer<'a> { lbr: Reader<'a, u8>, lbw: Writer<'a, u8>, } impl<'a> JoinedRingBuffer<'a> { const fn new(rb: &'a RingBuffer) -> Self { let (lbr, lbw) = rb.split(); Self { lbr: lbr, lbw: lbw } } } impl Write for JoinedRingBuffer<'_> { fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { for b in s.bytes() { if let Err(_) = self.lbw.unshift(b) { // Ignore buffer full errors for logging. return Ok(()); } } Ok(()) } } static mut LOGBUF: JoinedRingBuffer = unsafe { JoinedRingBuffer::new(&LB) }; static mut UART0: usize = 0; pub struct Processor { uart: W, led: L, } impl Processor where W: serial::Write, L: OutputPin, { pub fn new(uart: W, led: L) -> Self { // Unsafe because we're creating a mutable alias. unsafe { UART0 = core::mem::transmute(&uart) }; Self { uart: uart, led: led, } } pub fn task(&mut self) { // Unsafe due to mutable static. if unsafe { LOGBUF.lbr.is_empty() } { return; } self.led.set_high().ok(); // Unsafe due to mutable static. while let Some(b) = unsafe { LOGBUF.lbr.shift() } { nb::block!(self.uart.write(b)).ok(); } self.led.set_low().ok(); } } // Write to the UART right now, instead of putting it on a ring // buffer. This function is a huge hack, and only useful for debugging // either before the main loop starts or if the ring buffer is broken. pub unsafe fn write_fmt_now(args: fmt::Arguments, nl: bool) { if UART0 == 0 { return; } let uart: &mut UART0>, Sercom0Pad2>, (), ()> = core::mem::transmute(UART0); fmt::write(uart, args).expect("writing fmt now to uart"); if nl { uart.write_str("\r\n").expect("writing nl now to uart"); } } pub fn write_fmt(args: fmt::Arguments, nl: bool) { // Unsafe due to mutable static. unsafe { fmt::write(&mut LOGBUF, args).expect("writing fmt to log"); if nl { LOGBUF.write_str("\r\n").expect("writing nl to log"); } } }