// Just enough Arduino and Adafruit GFX to run the real BROSE9323 driver (Nano build) on // the PC, with a simulated panel: test/test_driver. The panel decodes the pin levels at // each strobe (ENABLE low) into the dot that flips, like the Brose panel electronics. #pragma once #include #include #include #include #include #define A0 14 #define A1 15 #define A2 16 #define A3 17 #define A4 18 #define A5 19 #define OUTPUT 1 // Every micros() call takes a microsecond, so loops that wait for the time end inline uint32_t fake_micros = 0; inline uint32_t micros() { return ++fake_micros; } inline uint32_t millis() { return fake_micros / 1000; } inline void delayMicroseconds(unsigned int us) { fake_micros += us; } inline void pinMode(uint8_t, uint8_t) {} struct FakePanel { static const int W = 84, H = 19, PANEL_W = 28; bool dot[W][H] = {}; int flips[W][H] = {}; // strobes per dot int strobes = 0; bool pins[20] = {}; void clearCounts() { memset(flips, 0, sizeof(flips)); strobes = 0; } void write(uint8_t pin, bool level) { pins[pin] = level; if (pin == 7 && !level) // ENABLE low: flip the addressed dot strobe(); } void strobe() { int panel = pins[3] | pins[5] << 1 | pins[6] << 2; int col_code = pins[8] | pins[10] << 1 | pins[9] << 2 | pins[11] << 3 | pins[12] << 4; int row_code = pins[A3] | pins[A4] << 1 | pins[A2] << 2 | pins[A0] << 3 | pins[A1] << 4; int col = -1, row = -1; for (int c = 0; c < PANEL_W; c++) if (c + 1 + c / 7 == col_code) col = c; for (int r = 0; r < H; r++) if (r + r / 7 == row_code) row = r; if (col < 0 || row < 0 || panel > 2) { fprintf(stderr, "bad address: panel %d col code %d row code %d\n", panel, col_code, row_code); abort(); } int x = panel * PANEL_W + col; dot[x][row] = !pins[4]; // COL_DATA low sets the dot (yellow) flips[x][row]++; strobes++; } }; inline FakePanel panel; inline void digitalWrite(uint8_t pin, int level) { panel.write(pin, level != 0); } struct FakeSerialOut { void write(char) {} void println() {} }; inline FakeSerialOut Serial; // Only what BROSE9323::print() uses class String { public: String(const char *s) : _s(s) {} void replace(const char *from, const char *to) { size_t pos = 0, n = strlen(from); while ((pos = _s.find(from, pos)) != std::string::npos) { _s.replace(pos, n, to); pos += strlen(to); } } const char *c_str() const { return _s.c_str(); } private: std::string _s; }; class Adafruit_GFX { public: Adafruit_GFX(int16_t w, int16_t h) : _width(w), _height(h) {} virtual ~Adafruit_GFX() {} virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0; int16_t width() const { return _width; } int16_t height() const { return _height; } size_t print(const char *s) { return strlen(s); } protected: int16_t _width, _height; };