From f2fda320092b8ec0bc6d572dc75753b3a1c631c6 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 12 Sep 2025 16:11:25 +0300 Subject: [PATCH] Configure ravedude --- .cargo/config.toml | 2 +- Cargo.toml | 5 +++- Ravedude.toml | 9 ++++++- images/large.qoi | Bin 1698 -> 1966 bytes images/sheep.xcf | Bin 3602 -> 5562 bytes src/qoi.rs | 59 ++++++++++++++++++++++++++++++--------------- 6 files changed, 52 insertions(+), 23 deletions(-) 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 9ebd755351575fd3971d38cce6d7cfb71be7614a..d72c6085ae86fa7c67189b13be39ad519255a904 100644 GIT binary patch literal 1966 zcmd^8%}T>S5MJ>O7JP-d?0K)gg*VTFC-Dj5lZj2JAt|v{YOoMmt4PF%2^J~@HaL^o z5Xq7>ZSdki_WR~%znz^W=VzxUjIo5ieRiZOHqY243jpK3D8o=h6ts00ybv zRBXR4MT!b-)=kgCj$>-v(t#~P$_;dIC!Fl~@W2&)D)EKGt8~s?O1}O9cy!PU?+((8 zU9gBdsGG{)_$Zal9eIl>uYo>E_0Bzc4{BP+QmND^ud8Pf*3I%d9ec)X$X)pW^=yoF zY6@Dw3*j6=3nt|fC<6wzwi^gY(AU8bui#|(hkEo3N-bLY5yZxLwY8Ckuvpi2LBEWj zp5LH>en3nEuykO9Y4l(sd#g*RVUth8>QnKASh20Muu0lMMZ3H3jI?t(oXMbYb_m-f la!q~bA~~aZw-4uSg+)(mkzK<{S#d)L&;AeQ;?t4seFM<764n3! literal 1698 zcmXTS&rD-rVE6#S%nYG_U)3K}`}_CrN7GSiGzdmh0r45(s3|bpz`zr=zpqA<&uH=? SKKYEQM5}a;0&64?U<3f1F}A$` diff --git a/images/sheep.xcf b/images/sheep.xcf index 15175fa9f131c249d956a2a595517af3a7ab9f5d..20d0e5a3cedb5967c34a61ca6cc5e7154894fd1c 100644 GIT binary patch literal 5562 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 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;