diff --git a/.cargo/config.toml b/.cargo/config.toml index 515ce02..59a6b3c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ [build] target = "avr-none" -rustflags = ["-C", "target-cpu=atmega328p"] +rustflags = ["-C", "target-cpu=atmega328p", "--emit=llvm-ir"] [target.'cfg(target_arch = "avr")'] runner = "ravedude" diff --git a/Cargo.toml b/Cargo.toml index 43aef42..637f70a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,9 @@ panic = "abort" [profile.release] panic = "abort" +opt-level = "s" # Size is more important than performance on MSP430. +codegen-units = 1 # Better size optimization. +lto = "fat" # _Much_ better size optimization. [build] -rustflags = ["-C", "link-args=-lc"] +rustflags = ["-C", "link-args=-lc", "--emit=llvm-ir"] diff --git a/Ravedude.toml b/Ravedude.toml index 39554a7..7a01d55 100644 --- a/Ravedude.toml +++ b/Ravedude.toml @@ -1,7 +1,14 @@ [general] -board = "uno" +port = "/dev/ttyUSB0" serial-baudrate = 57600 open-console = true +[board.avrdude] +# avrdude configuration +programmer = "arduino" +partno = "m328p" +baudrate = 57600 +do-chip-erase = true + # For documentation about this file, check here: # https://github.com/Rahix/avr-hal/blob/main/ravedude/README.md#ravedudetoml-format diff --git a/images/large.qoi b/images/large.qoi index 9ebd755..d72c608 100644 Binary files a/images/large.qoi and b/images/large.qoi differ diff --git a/images/sheep.xcf b/images/sheep.xcf index 15175fa..20d0e5a 100644 Binary files a/images/sheep.xcf and b/images/sheep.xcf differ diff --git a/src/qoi.rs b/src/qoi.rs index bdff872..886cc9b 100644 --- a/src/qoi.rs +++ b/src/qoi.rs @@ -14,7 +14,8 @@ use crate::{ }; // https://qoiformat.org/qoi-specification.pdf -const image: &[u8; 1253] = include_bytes!("../images/hi.qoi"); +const LARGE: &[u8; 1966] = include_bytes!("../images/large.qoi"); +const SHEEP: &[u8; 852] = include_bytes!("../images/sheep.qoi"); #[derive(Debug, uDebug)] pub enum QoiErr { @@ -22,34 +23,52 @@ pub enum QoiErr { UnexpectedEOF, } +#[derive(Default)] +struct LargeIter { + index: usize, +} + +impl Iterator for LargeIter { + type Item = u8; + + fn next(&mut self) -> Option { + if self.index >= N { + return None; + } + let old_idx = self.index; + self.index += 1; + Some(SHEEP[old_idx]) + } +} + pub fn draw_image( serial: &mut Usart, Pin, CoreClock>, display: &mut Display, position: Position, ) -> Result<(), QoiErr> { - let mut iter = image.iter(); + let mut iter = LargeIter::<852>::default(); if let (Some(113), Some(111), Some(105), Some(102)) = (iter.next(), iter.next(), iter.next(), iter.next()) { - fn next<'a>(iter: &mut Iter<'a, u8>) -> Result<&'a u8, QoiErr> { + fn next(iter: &mut LargeIter) -> Result { iter.next().ok_or(QoiErr::UnexpectedEOF) } let width = u32::from_be_bytes([ - *next(&mut iter)?, - *next(&mut iter)?, - *next(&mut iter)?, - *next(&mut iter)?, + next(&mut iter)?, + next(&mut iter)?, + next(&mut iter)?, + next(&mut iter)?, ]) as u16; let height = u32::from_be_bytes([ - *next(&mut iter)?, - *next(&mut iter)?, - *next(&mut iter)?, - *next(&mut iter)?, + next(&mut iter)?, + next(&mut iter)?, + next(&mut iter)?, + next(&mut iter)?, ]) as u16; - let channels = *next(&mut iter)?; - let colorspace = *next(&mut iter)?; + let channels = next(&mut iter)?; + let colorspace = next(&mut iter)?; ufmt::uwriteln!(serial, "Successfully read QOI header").unwrap(); @@ -61,7 +80,7 @@ pub fn draw_image( }, ); - let qoi_iter = QoiIterator::from(iter, serial, width * height); + let qoi_iter = QoiIterator::from(&mut iter, serial, width * height); // let mut chunks = qoi_iter.array_chunks::(); // while let Some(array) = chunks.next() { @@ -96,7 +115,7 @@ pub fn draw_image( } struct QoiIterator<'a> { - inner: Iter<'a, u8>, + inner: &'a mut dyn Iterator, serial: &'a mut Usart, Pin, CoreClock>, prev_pixels: [Rgb565; 64], last_pixel: Rgb565, @@ -107,7 +126,7 @@ struct QoiIterator<'a> { impl<'a> QoiIterator<'a> { fn from( - bytes: Iter<'a, u8>, + bytes: &'a mut dyn Iterator, serial: &'a mut Usart, Pin, CoreClock>, expected: u16, ) -> Self { @@ -138,19 +157,19 @@ impl<'a> Iterator for QoiIterator<'a> { return Some(self.last_pixel); } if let Some(byte) = self.inner.next() { - let color = if *byte == 0xff { + let color = if byte == 0xff { let red = self.inner.next().unwrap(); let green = self.inner.next().unwrap(); let blue = self.inner.next().unwrap(); let _alpha = self.inner.next().unwrap(); // ufmt::uwriteln!(self.serial, "RGBA: {} {} {} {}", red, green, blue, alpha).unwrap(); - Rgb565(*red, *green, *blue) - } else if *byte == 0b11111110 { + Rgb565(red, green, blue) + } else if byte == 0b11111110 { let red = self.inner.next().unwrap(); let green = self.inner.next().unwrap(); let blue = self.inner.next().unwrap(); // ufmt::uwriteln!(self.serial, "RGB: {} {} {}", red, green, blue).unwrap(); - Rgb565(*red, *green, *blue) + Rgb565(red, green, blue) } else { let tag = (0b11000000 & byte) >> 6; let data = 0b00111111 & byte;