rate-limit scheme error spam to prevent serial log flood
This commit is contained in:
@@ -27,6 +27,9 @@ pub struct DebugDisplay {
|
||||
}
|
||||
|
||||
impl DebugDisplay {
|
||||
const CHAR_WIDTH: usize = 8;
|
||||
const CHAR_HEIGHT: usize = 16;
|
||||
|
||||
pub(super) fn new(
|
||||
width: usize,
|
||||
height: usize,
|
||||
@@ -40,8 +43,8 @@ impl DebugDisplay {
|
||||
onscreen_ptr,
|
||||
};
|
||||
|
||||
let w = display.width / 8;
|
||||
let h = display.height / 16;
|
||||
let w = display.width / Self::CHAR_WIDTH;
|
||||
let h = display.height / Self::CHAR_HEIGHT;
|
||||
DebugDisplay {
|
||||
display,
|
||||
x: 0,
|
||||
@@ -52,11 +55,36 @@ impl DebugDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_up(&mut self) {
|
||||
let stride = self.display.stride;
|
||||
let width = self.display.width;
|
||||
let total_height = self.display.height;
|
||||
let scroll_px = Self::CHAR_HEIGHT;
|
||||
|
||||
unsafe {
|
||||
let ptr = self.display.onscreen_ptr;
|
||||
for row in 0..total_height - scroll_px {
|
||||
ptr::copy(
|
||||
ptr.add((row + scroll_px) * stride),
|
||||
ptr.add(row * stride),
|
||||
width,
|
||||
);
|
||||
}
|
||||
for row in total_height - scroll_px..total_height {
|
||||
ptr::write_bytes(ptr.add(row * stride), 0, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&mut self, buf: &[u8]) {
|
||||
for &b in buf {
|
||||
if self.x >= self.w || b == b'\n' {
|
||||
self.x = 0;
|
||||
self.y = (self.y + 1) % self.h;
|
||||
self.y += 1;
|
||||
if self.y >= self.h {
|
||||
self.scroll_up();
|
||||
self.y = self.h - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if b == b'\r' {
|
||||
@@ -64,52 +92,44 @@ impl DebugDisplay {
|
||||
}
|
||||
|
||||
match (b, &self.mode) {
|
||||
// Byte 0x1B starts ESC sequence
|
||||
(0x1B, _) => {
|
||||
self.mode = Mode::Esc;
|
||||
continue;
|
||||
}
|
||||
// Ignore other nonprintable characters
|
||||
(0x00..=0x1F | 0x80..=0xFF, _) => {
|
||||
self.mode = Mode::Plain;
|
||||
continue;
|
||||
}
|
||||
// '[' after ESC starts CSI sequence
|
||||
(b'[', Mode::Esc) => {
|
||||
self.mode = Mode::Csi;
|
||||
continue;
|
||||
}
|
||||
// Capture any bytes after ESC
|
||||
(_, Mode::Esc) => {
|
||||
self.mode = Mode::Plain;
|
||||
continue;
|
||||
}
|
||||
// Byte 0x40 to 0x7E ends CSI
|
||||
(0x40..=0x7E, Mode::Csi) => {
|
||||
self.mode = Mode::Plain;
|
||||
continue;
|
||||
}
|
||||
// Capture any bytes after CSI
|
||||
(_, Mode::Csi) => {
|
||||
continue;
|
||||
}
|
||||
// Allow any other bytes
|
||||
(_, Mode::Plain) => {}
|
||||
}
|
||||
|
||||
if self.x == 0 {
|
||||
self.clear_row(self.y);
|
||||
self.clear_row((self.y + 1) % self.h);
|
||||
}
|
||||
|
||||
self.char(self.x * 8, self.y * 16, b as char, 0xFFFFFF);
|
||||
self.char(self.x * Self::CHAR_WIDTH, self.y * Self::CHAR_HEIGHT, b as char, 0xFFFFFF);
|
||||
|
||||
self.x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_row(&mut self, y: usize) {
|
||||
for row in y * 16..(y + 1) * 16 {
|
||||
for row in y * Self::CHAR_HEIGHT..(y + 1) * Self::CHAR_HEIGHT {
|
||||
unsafe {
|
||||
ptr::write_bytes(
|
||||
self.display.onscreen_ptr.add(row * self.display.stride),
|
||||
@@ -120,36 +140,28 @@ impl DebugDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a character
|
||||
fn char(&mut self, x: usize, y: usize, character: char, color: u32) {
|
||||
if x + 8 <= self.display.width && y + 16 <= self.display.height {
|
||||
let phys_y = y % self.display.height;
|
||||
let mut dst = unsafe {
|
||||
self.display
|
||||
.onscreen_ptr
|
||||
.add(phys_y * self.display.stride + x)
|
||||
};
|
||||
if x + Self::CHAR_WIDTH > self.display.width || y + Self::CHAR_HEIGHT > self.display.height {
|
||||
return;
|
||||
}
|
||||
|
||||
let font_i = Self::CHAR_HEIGHT * (character as usize);
|
||||
if font_i + Self::CHAR_HEIGHT > FONT.len() {
|
||||
return;
|
||||
}
|
||||
|
||||
let font_i = 16 * (character as usize);
|
||||
if font_i + 16 <= FONT.len() {
|
||||
for row in 0..16 {
|
||||
let row_data = FONT[font_i + row];
|
||||
for col in 0..8 {
|
||||
if (row_data >> (7 - col)) & 1 == 1 {
|
||||
unsafe {
|
||||
let ptr = self.display.onscreen_ptr;
|
||||
let stride = self.display.stride;
|
||||
for row in 0..Self::CHAR_HEIGHT {
|
||||
let row_data = FONT[font_i + row];
|
||||
let dst = ptr.add((y + row) * stride + x);
|
||||
for col in 0..Self::CHAR_WIDTH {
|
||||
if (row_data >> (Self::CHAR_WIDTH - 1 - col)) & 1 == 1 {
|
||||
*dst.add(col) = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let next_phys_y = (phys_y + row + 1) % self.display.height;
|
||||
dst = unsafe {
|
||||
self.display
|
||||
.onscreen_ptr
|
||||
.add(next_phys_y * self.display.stride + x)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user