A fork of pulp-os for the xteink4 adding custom apps
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

bigger fonts, better adc interrupts

hans 0cf807e5 e42d2ffd

+65 -45
+24 -14
kernel/src/drivers/input.rs
··· 71 71 press_since: Instant, 72 72 long_press_fired: bool, 73 73 last_repeat: Instant, 74 + hold_consumed: bool, 74 75 queue: EventQueue, 75 76 } 76 77 ··· 85 86 press_since: now, 86 87 long_press_fired: false, 87 88 last_repeat: now, 89 + hold_consumed: false, 88 90 queue: EventQueue::new(), 89 91 } 90 92 } 91 93 92 94 pub fn reset_hold_state(&mut self) { 93 - let now = Instant::now(); 94 - self.press_since = now; 95 - self.long_press_fired = false; 96 - self.last_repeat = now; 95 + self.hold_consumed = true; 97 96 } 98 97 99 98 pub fn poll(&mut self) -> Option<Event> { ··· 105 104 let now = Instant::now(); 106 105 107 106 if raw != self.candidate { 107 + // raw deviated from stable; restart hold timer so 108 + // sub-debounce releases don't accumulate into LongPress 109 + if self.stable.is_some() && raw != self.stable { 110 + self.press_since = now; 111 + self.long_press_fired = false; 112 + self.last_repeat = now; 113 + } 108 114 self.candidate = raw; 109 115 self.candidate_since = now; 110 116 } ··· 118 124 if debounced != self.stable { 119 125 if let Some(old) = self.stable { 120 126 self.queue.push(Event::Release(old)); 127 + self.hold_consumed = false; 121 128 } 122 129 if let Some(new) = debounced { 123 130 self.queue.push(Event::Press(new)); ··· 130 137 } 131 138 132 139 if let Some(btn) = self.stable { 133 - let held = now - self.press_since; 140 + if !self.hold_consumed { 141 + let held = now - self.press_since; 134 142 135 - if !self.long_press_fired && held >= Duration::from_millis(LONG_PRESS_MS) { 136 - self.long_press_fired = true; 137 - self.last_repeat = now; 138 - return Some(Event::LongPress(btn)); 139 - } 143 + if !self.long_press_fired && held >= Duration::from_millis(LONG_PRESS_MS) { 144 + self.long_press_fired = true; 145 + self.last_repeat = now; 146 + return Some(Event::LongPress(btn)); 147 + } 140 148 141 - if self.long_press_fired && (now - self.last_repeat) >= Duration::from_millis(REPEAT_MS) 142 - { 143 - self.last_repeat = now; 144 - return Some(Event::Repeat(btn)); 149 + if self.long_press_fired 150 + && (now - self.last_repeat) >= Duration::from_millis(REPEAT_MS) 151 + { 152 + self.last_repeat = now; 153 + return Some(Event::Repeat(btn)); 154 + } 145 155 } 146 156 } 147 157
+4 -4
kernel/src/kernel/console.rs
··· 1 1 // boot console: accumulates text lines during hardware init, rendered 2 2 // once to EPD before the app layer takes over 3 3 // 4 - // uses the embedded-graphics built-in FONT_6X13 -- no TTF assets or 4 + // uses the embedded-graphics built-in FONT_9X18 -- no TTF assets or 5 5 // build.rs font pipeline needed; the kernel can show boot progress 6 6 // on a bare display with nothing but this mono font 7 7 8 8 use embedded_graphics::mono_font::MonoTextStyle; 9 - use embedded_graphics::mono_font::ascii::FONT_6X13; 9 + use embedded_graphics::mono_font::ascii::FONT_9X18; 10 10 use embedded_graphics::pixelcolor::BinaryColor; 11 11 use embedded_graphics::prelude::*; 12 12 use embedded_graphics::text::Text; ··· 17 17 const MAX_LINE_LEN: usize = 76; 18 18 const LEFT_MARGIN: i32 = 8; 19 19 const TOP_MARGIN: i32 = 6; 20 - const LINE_H: i32 = 15; 20 + const LINE_H: i32 = 20; 21 21 22 22 pub struct BootConsole { 23 23 lines: [[u8; MAX_LINE_LEN]; MAX_LINES], ··· 52 52 } 53 53 54 54 pub fn draw(&self, strip: &mut StripBuffer) { 55 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::On); 55 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::On); 56 56 for i in 0..self.count { 57 57 let len = self.lengths[i] as usize; 58 58 let text = core::str::from_utf8(&self.lines[i][..len]).unwrap_or("");
+15 -5
kernel/src/kernel/scheduler.rs
··· 168 168 // if sleep_deep somehow returned; this version correctly returns 169 169 // early so the caller can enter_sleep and continue the loop 170 170 fn handle_input<A: AppLayer>(&mut self, hw_event: Event, app_mgr: &mut A) -> bool { 171 + let _ = tasks::IDLE_SLEEP_DUE.try_take(); 172 + 171 173 if hw_event == Event::LongPress(Button::Power) { 172 174 return true; 173 175 } 174 176 177 + let suppressed_before = app_mgr.suppress_deferred_input(); 175 178 let transition = app_mgr.dispatch_event(hw_event, &mut *self.bm_cache); 176 179 177 180 if transition != Transition::None { 178 181 app_mgr.apply_transition(transition, &mut self.handle()); 182 + tasks::request_hold_reset(); 183 + } else if app_mgr.suppress_deferred_input() != suppressed_before { 179 184 tasks::request_hold_reset(); 180 185 } 181 186 ··· 325 330 // the TICK_MS timeout ensures is_busy is re-checked regularly 326 331 // even during long background operations. 327 332 // 328 - // first non-None transition wins; hold is reset so the held button 329 - // doesn't re-fire LongPress/Repeat for the remainder of the waveform 333 + // first non-None transition wins; hold reset prevents the held 334 + // button from re-firing LongPress/Repeat for the waveform 330 335 async fn busy_wait_with_background<A: AppLayer>( 331 336 &mut self, 332 337 app_mgr: &mut A, ··· 357 362 }; 358 363 359 364 if let Some(hw_event) = ev { 360 - if !app_mgr.suppress_deferred_input() { 365 + let _ = tasks::IDLE_SLEEP_DUE.try_take(); 366 + 367 + let suppressed_before = app_mgr.suppress_deferred_input(); 368 + if !suppressed_before { 361 369 let t = app_mgr.dispatch_event(hw_event, &mut *self.bm_cache); 362 370 if t != Transition::None && deferred.is_none() { 363 371 deferred = Some(t); 372 + tasks::request_hold_reset(); 373 + } else if app_mgr.suppress_deferred_input() != suppressed_before { 364 374 tasks::request_hold_reset(); 365 375 } 366 376 } ··· 376 386 // on real hardware this never returns (wake = full MCU reset) 377 387 pub async fn enter_sleep(&mut self, reason: &str) { 378 388 use embedded_graphics::mono_font::MonoTextStyle; 379 - use embedded_graphics::mono_font::ascii::FONT_6X13; 389 + use embedded_graphics::mono_font::ascii::FONT_9X18; 380 390 use embedded_graphics::pixelcolor::BinaryColor; 381 391 use embedded_graphics::prelude::*; 382 392 use embedded_graphics::text::Text; ··· 394 404 395 405 self.epd 396 406 .full_refresh_async(self.strip, &mut self.delay, &|s: &mut StripBuffer| { 397 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::On); 407 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::On); 398 408 let _ = Text::new("(sleep)", Point::new(210, 400), style).draw(s); 399 409 }) 400 410 .await;
+1 -1
kernel/src/lib.rs
··· 1 1 // pulp-kernel -- hardware drivers, scheduling, and system core 2 2 // 3 3 // generic over AppLayer; never imports concrete apps or fonts 4 - // ships a built-in mono font (FONT_6X13) for boot console and 4 + // ships a built-in mono font (FONT_9X18) for boot console and 5 5 // sleep screen; distros bring their own proportional fonts 6 6 7 7 #![no_std]
+6 -6
kernel/src/ui/widget.rs
··· 1 1 // region geometry, alignment helpers, progress bar, loading indicator 2 2 3 3 use embedded_graphics::{ 4 - mono_font::MonoTextStyle, mono_font::ascii::FONT_6X13, pixelcolor::BinaryColor, prelude::*, 4 + mono_font::MonoTextStyle, mono_font::ascii::FONT_9X18, pixelcolor::BinaryColor, prelude::*, 5 5 primitives::PrimitiveStyle, primitives::Rectangle, text::Text, 6 6 }; 7 7 ··· 154 154 155 155 // loading indicator for 1-bit e-paper 156 156 // draws "msg...pct%" centered vertically in the region using the 157 - // built-in FONT_6X13 mono font; works without any custom bitmap 157 + // built-in FONT_9X18 mono font; works without any custom bitmap 158 158 // fonts loaded, usable from any app or the kernel itself 159 159 // 160 160 // typical usage: ··· 176 176 let _ = write!(fmt, "{}...{}%", msg, pct.min(100)); 177 177 let text = fmt.as_str(); 178 178 179 - // FONT_6X13: 6px wide, 13px tall, ~10px ascent 180 - // center vertically; baseline = region.y + (h + 7) / 2 181 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::On); 182 - let baseline_y = region.y as i32 + (region.h as i32 + 7) / 2; 179 + // FONT_9X18: 9px wide, 18px tall, ~14px ascent 180 + // center vertically; baseline = region.y + (h + 9) / 2 181 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::On); 182 + let baseline_y = region.y as i32 + (region.h as i32 + 9) / 2; 183 183 Text::new(text, Point::new(region.x as i32 + 2, baseline_y), style) 184 184 .draw(strip) 185 185 .unwrap();
+15 -15
src/apps/reader/mod.rs
··· 13 13 use core::fmt::Write; 14 14 15 15 use embedded_graphics::mono_font::MonoTextStyle; 16 - use embedded_graphics::mono_font::ascii::FONT_6X13; 16 + use embedded_graphics::mono_font::ascii::FONT_9X18; 17 17 use embedded_graphics::pixelcolor::BinaryColor; 18 18 use embedded_graphics::prelude::*; 19 19 use embedded_graphics::primitives::{PrimitiveStyle, Rectangle}; ··· 42 42 pub(super) const HEADER_Y: u16 = CONTENT_TOP + 2; 43 43 pub(super) const HEADER_H: u16 = 16; 44 44 pub(super) const TEXT_Y: u16 = HEADER_Y + HEADER_H + 2; 45 - pub(super) const LINE_H: u16 = 13; 46 - pub(super) const CHARS_PER_LINE: usize = 66; 47 - pub(super) const LINES_PER_PAGE: usize = 58; 45 + pub(super) const LINE_H: u16 = 20; 46 + pub(super) const CHARS_PER_LINE: usize = 51; 47 + pub(super) const LINES_PER_PAGE: usize = 37; 48 48 pub(super) const PAGE_BUF: usize = 8192; 49 49 pub(super) const MAX_PAGES: usize = 1024; 50 50 ··· 79 79 POSITION_OVERLAY_H, 80 80 ); 81 81 82 - pub(super) const LOADING_REGION: Region = Region::new(MARGIN, TEXT_Y, 464, 18); 82 + pub(super) const LOADING_REGION: Region = Region::new(MARGIN, TEXT_Y, 464, 24); 83 83 84 84 pub const QA_FONT_SIZE: u8 = 1; 85 85 pub(super) const QA_PREV_CHAPTER: u8 = 3; ··· 595 595 if let Some(f) = font { 596 596 f.draw_aligned(strip, region, text, align, BinaryColor::On); 597 597 } else { 598 - let tw = text.len() as u32 * 6; 599 - let pos = align.position(region, embedded_graphics::geometry::Size::new(tw, 13)); 600 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::On); 601 - Text::new(text, Point::new(pos.x, pos.y + 13), style) 598 + let tw = text.len() as u32 * 9; 599 + let pos = align.position(region, embedded_graphics::geometry::Size::new(tw, 18)); 600 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::On); 601 + Text::new(text, Point::new(pos.x, pos.y + 18), style) 602 602 .draw(strip) 603 603 .unwrap(); 604 604 } ··· 1297 1297 font.draw_str_fg(strip, entry.title_str(), fg, cx, baseline); 1298 1298 } 1299 1299 } else { 1300 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::On); 1300 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::On); 1301 1301 let vis_max = (TEXT_AREA_H / LINE_H) as usize; 1302 1302 let visible = vis_max.min(toc_len.saturating_sub(self.epub.toc_scroll)); 1303 1303 for i in 0..visible { ··· 1422 1422 } 1423 1423 } 1424 1424 } else { 1425 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::On); 1425 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::On); 1426 1426 for i in 0..self.pg.line_count { 1427 1427 let span = self.pg.lines[i]; 1428 1428 let start = span.start as usize; ··· 1499 1499 BinaryColor::Off, 1500 1500 ); 1501 1501 } else { 1502 - let tw = text.len() as u32 * 6; 1503 - let pos = Alignment::Center.position(POSITION_OVERLAY, Size::new(tw, 13)); 1504 - let style = MonoTextStyle::new(&FONT_6X13, BinaryColor::Off); 1505 - Text::new(text, Point::new(pos.x, pos.y + 13), style) 1502 + let tw = text.len() as u32 * 9; 1503 + let pos = Alignment::Center.position(POSITION_OVERLAY, Size::new(tw, 18)); 1504 + let style = MonoTextStyle::new(&FONT_9X18, BinaryColor::Off); 1505 + Text::new(text, Point::new(pos.x, pos.y + 18), style) 1506 1506 .draw(strip) 1507 1507 .unwrap(); 1508 1508 }