Public Access
- Nano: B data is drawn fast enough for the serial line. A hex digit arrives every 87 us; with a division and four drawPixel() calls per digit a lit digit took about 105 us, so dense frames (all yellow, the panda bitmap) overflowed the 64 byte receive buffer: frames not shown or wrong, "Line too long", frame check repairs that failed the same way. Now the parser counts columns and rows and BROSE9323::drawDots() sets the 4 dots (about 20 us). - ESP32: Power off and the start of the night draw the off image also when slow mode had the power off already (it powers on for it, once) - Tests: drawDots() against drawPixel(), off image in slow mode - Version 2.19.3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
2.4 KiB
C++
79 lines
2.4 KiB
C++
// Fake display driver for the native tests: records every call instead of flipping dots
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "Arduino.h"
|
|
#include "dot_sequence.h" // the real one, from lib/BROSE9323
|
|
|
|
struct DisplayCall
|
|
{
|
|
std::string what;
|
|
int a, b, c;
|
|
};
|
|
|
|
class BROSE9323
|
|
{
|
|
public:
|
|
std::vector<DisplayCall> calls;
|
|
bool direct = false;
|
|
bool effect_running = false; // what busy() returns
|
|
bool refresh_running = false; // what refreshing() returns
|
|
uint16_t crc_value = 0; // what crc() returns
|
|
|
|
BROSE9323(uint8_t, uint8_t, uint8_t, uint16_t) {}
|
|
|
|
void begin() { log("begin"); }
|
|
void display(bool force = false, bool instant = false) { log("display", force, instant); }
|
|
void drawPixel(int16_t x, int16_t y, uint16_t color) { log(direct ? "directPixel" : "pixel", x, y, color); }
|
|
// Recorded as the pixel calls it stands for (the real one is tested in test_driver)
|
|
void drawDots(int16_t x, int16_t y, uint8_t bits, bool color)
|
|
{
|
|
log("dots", x, y, bits);
|
|
for (int i = 0; i < 4; i++)
|
|
if (bits & (8 >> i))
|
|
drawPixel(x + i, y, color);
|
|
}
|
|
void fillScreen(uint16_t color) { log("fill", color); }
|
|
void setDirect(bool d) { direct = d; }
|
|
void setTiming(uint16_t t) { log("timing", t); }
|
|
void setGap(uint16_t t) { log("gap", t); }
|
|
void setPulses(uint8_t n) { log("pulses", n); }
|
|
void setEffect(uint8_t effect, uint16_t time_ms, uint8_t flags = 0) { log("effect", effect, time_ms, flags); }
|
|
bool update() { return effect_running; }
|
|
bool busy() const { return effect_running; }
|
|
void startRefresh() { log("refresh"); }
|
|
bool refreshing() const { return refresh_running; }
|
|
uint16_t crc() const { return crc_value; }
|
|
void printBuffer() { log("printBuffer"); }
|
|
void setCursor(int16_t x, int16_t y) { log("cursor", x, y); }
|
|
void setTextColor(uint16_t color, uint16_t background) { log("textColor", color, background); }
|
|
void setTextSize(uint8_t size) { log("textSize", size); }
|
|
size_t write(uint8_t ch)
|
|
{
|
|
log("write", ch);
|
|
return 1;
|
|
}
|
|
void println() { log("newline"); }
|
|
|
|
// Helpers for the tests
|
|
int count(const std::string &what) const
|
|
{
|
|
int n = 0;
|
|
for (const DisplayCall &call : calls)
|
|
n += call.what == what;
|
|
return n;
|
|
}
|
|
const DisplayCall *last(const std::string &what) const
|
|
{
|
|
for (auto it = calls.rbegin(); it != calls.rend(); ++it)
|
|
if (it->what == what)
|
|
return &*it;
|
|
return nullptr;
|
|
}
|
|
|
|
private:
|
|
void log(const char *what, int a = 0, int b = 0, int c = 0) { calls.push_back({what, a, b, c}); }
|
|
};
|