Skip to content

Commit 94d7595

Browse files
committed
feature: implement drawcolumn
1 parent f4fc6a2 commit 94d7595

2 files changed

Lines changed: 105 additions & 8 deletions

File tree

src/matrix_panel_fpga.cpp

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,81 @@ bool MatrixPanel_FPGA_SPI::worker_is_idle() const {
498498
return uxQueueMessagesWaiting(tx_q_) == 0 && !worker_busy_;
499499
}
500500

501+
void MatrixPanel_FPGA_SPI::do_drawColumnRGB888_(int16_t x, const uint8_t *data,
502+
size_t length) {
503+
if (!initialized) {
504+
ESP_LOGI("drawColumnRGB888()",
505+
"Tried to set output brightness before begin()");
506+
return;
507+
}
508+
if (data == nullptr) {
509+
ESP_LOGE("MatrixPanel_FPGA_SPI:drawColumnRGB888",
510+
"Invalid data passed to drawColumnRGB888 nullptr! (length=%d)",
511+
length);
512+
return;
513+
}
514+
if (x < 0 || x >= width()) {
515+
ESP_LOGE("MatrixPanel_FPGA_SPI:drawColumnRGB888",
516+
"Invalid column x=%d", x);
517+
return;
518+
}
519+
const size_t expected_len =
520+
static_cast<size_t>(height()) * static_cast<size_t>(3);
521+
if (length != expected_len) {
522+
ESP_LOGE("MatrixPanel_FPGA_SPI:drawColumnRGB888",
523+
"Invalid data length=%d expected=%d", length, expected_len);
524+
return;
525+
}
526+
SpiLockGuard spi_lock(this);
527+
if (!spi_lock.locked())
528+
return;
529+
if (!wait_for_fpga_resetstatus_())
530+
return;
531+
532+
uint8_t header_len = 0;
533+
uint8_t header[3];
534+
header[header_len++] = 'K'; // Command byte
535+
if (PIXELS_PER_ROW <= 0xff) {
536+
header[header_len++] = static_cast<uint8_t>(x);
537+
} else {
538+
header[header_len++] = static_cast<uint8_t>((x >> 8) & 0xFF);
539+
header[header_len++] = static_cast<uint8_t>(x & 0xFF);
540+
}
541+
542+
const size_t total_bytes = length + header_len;
543+
uint8_t buf[total_bytes];
544+
memcpy(buf, header, header_len);
545+
memcpy(&buf[header_len], data, length);
546+
547+
spi_transaction_t t = {
548+
.length = static_cast<size_t>(total_bytes * 8), // bits
549+
.tx_buffer = buf,
550+
};
551+
esp_err_t err = spi_device_transmit(spi_bus, &t);
552+
if (err != ESP_OK) {
553+
ESP_LOGE("MatrixPanel_FPGA_SPI:drawColumnRGB888",
554+
"SPI transmit failed: %s", esp_err_to_name(err));
555+
return;
556+
}
557+
wait_for_fpga_busy_clear_();
558+
}
559+
560+
void MatrixPanel_FPGA_SPI::drawColumnRGB888(int16_t x, const uint8_t *data,
561+
size_t length) {
562+
if (use_worker_) {
563+
if (!tx_q_ || !tx_task_)
564+
return;
565+
Job j;
566+
j.op = Op::DRAW_COL;
567+
j.x = x;
568+
j.data = data;
569+
j.length = length;
570+
(void)xQueueSend(tx_q_, &j, 0);
571+
return;
572+
}
573+
do_drawColumnRGB888_(x, data, length);
574+
}
575+
501576
void MatrixPanel_FPGA_SPI::do_drawPixelRGB888_(int16_t x, int16_t y, uint8_t r,
502577
uint8_t g, uint8_t b) {
503578
if (!initialized) {
@@ -841,7 +916,7 @@ void MatrixPanel_FPGA_SPI::run_test_graphic(uint32_t delay_ms) {
841916
// - red top band drawn through drawRowRGB888
842917
// - green bottom band via fillRect
843918
// - blue center band via fillRect
844-
// - yellow left column, magenta right column for edge accents
919+
// - yellow left band + magenta right band via drawColumnRGB888
845920
// - opposing diagonals (orange/white) to cover drawPixelRGB888
846921
// - centered drawRectRGB888 rect: size=max(4, width/5)xmax(4, height/3)
847922
// BLACK GRADIANT RED
@@ -888,14 +963,31 @@ void MatrixPanel_FPGA_SPI::run_test_graphic(uint32_t delay_ms) {
888963
fillRect(0, middle_y, width, horizontal_band_height, 0x00, 0x00, 0xFF);
889964
delay_if_needed();
890965

891-
// Left accent column: yellow.
892-
fillRect(0, 0, vertical_bar_width, height, 0xFF, 0xFF, 0x33);
966+
// Left accent band: yellow using drawColumnRGB888.
967+
std::vector<uint8_t> column_buf(static_cast<size_t>(height) * 3);
968+
for (int y = 0; y < height; ++y) {
969+
const size_t idx = static_cast<size_t>(y) * 3;
970+
column_buf[idx] = 0xFF;
971+
column_buf[idx + 1] = 0xFF;
972+
column_buf[idx + 2] = 0x33;
973+
}
974+
for (int x = 0; x < vertical_bar_width; ++x) {
975+
drawColumnRGB888(x, column_buf.data(), column_buf.size());
976+
}
893977
wait_for_worker_idle();
894978
delay_if_needed();
895979

896-
// Right accent column: magenta/pink.
897-
fillRect(std::max(width - vertical_bar_width, 0), 0, vertical_bar_width, height,
898-
0xFF, 0x00, 0xFF);
980+
// Right accent band: magenta using drawColumnRGB888.
981+
for (int y = 0; y < height; ++y) {
982+
const size_t idx = static_cast<size_t>(y) * 3;
983+
column_buf[idx] = 0xFF;
984+
column_buf[idx + 1] = 0x00;
985+
column_buf[idx + 2] = 0xFF;
986+
}
987+
const int right_start = std::max(width - vertical_bar_width, 0);
988+
for (int x = right_start; x < width; ++x) {
989+
drawColumnRGB888(x, column_buf.data(), column_buf.size());
990+
}
899991
wait_for_worker_idle();
900992
delay_if_needed();
901993

src/matrix_panel_fpga.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class MatrixPanel_FPGA_SPI {
7070
void fillScreenRGB888(uint8_t r, uint8_t g, uint8_t b);
7171
void drawPixelRGB888(int16_t x, int16_t y, uint8_t r, uint8_t g, uint8_t b);
7272
void drawRowRGB888(const uint8_t y, const uint8_t *data, size_t length);
73+
void drawColumnRGB888(int16_t x, const uint8_t *data, size_t length);
7374
void drawFrameRGB888(const uint8_t *data, size_t length);
7475
bool queue_has_space(size_t slots = 1) const;
7576
bool worker_is_idle() const;
@@ -140,6 +141,7 @@ class MatrixPanel_FPGA_SPI {
140141
void do_drawPixelRGB888_(int16_t x, int16_t y, uint8_t r, uint8_t g,
141142
uint8_t b);
142143
void do_drawRowRGB888_(const uint8_t y, const uint8_t *data, size_t length);
144+
void do_drawColumnRGB888_(int16_t x, const uint8_t *data, size_t length);
143145
void do_drawFrameRGB888_(const uint8_t *data, size_t length);
144146
void do_drawRectRGB888_(int16_t x, int16_t y, int16_t w, int16_t h,
145147
const uint8_t *data, size_t length);
@@ -177,6 +179,7 @@ class MatrixPanel_FPGA_SPI {
177179

178180
enum class Op : uint8_t {
179181
DRAW_ROW,
182+
DRAW_COL,
180183
SWAP,
181184
WATCHDOG,
182185
FILL_SCREEN,
@@ -190,8 +193,8 @@ class MatrixPanel_FPGA_SPI {
190193
};
191194
struct Job {
192195
Op op;
193-
const uint8_t *data = nullptr; // for DRAW_ROW / DRAW_FRAME / DRAW_RECT
194-
size_t length = 0; // for DRAW_ROW / DRAW_FRAME / DRAW_RECT
196+
const uint8_t *data = nullptr; // for DRAW_ROW / DRAW_COL / DRAW_FRAME / DRAW_RECT
197+
size_t length = 0; // for DRAW_ROW / DRAW_COL / DRAW_FRAME / DRAW_RECT
195198

196199
uint8_t y = 0; // row index
197200
int16_t x = 0; // for DRAW_PIXEL / DRAW_RECT / FILL_RECT
@@ -218,6 +221,8 @@ class MatrixPanel_FPGA_SPI {
218221
this->worker_busy_ = true;
219222
if (j.op == Op::DRAW_ROW)
220223
do_drawRowRGB888_(j.y, j.data, j.length);
224+
else if (j.op == Op::DRAW_COL)
225+
do_drawColumnRGB888_(j.x, j.data, j.length);
221226
else if (j.op == Op::SWAP)
222227
do_swapFrame_();
223228
else if (j.op == Op::WATCHDOG)

0 commit comments

Comments
 (0)