|
@@ -59,6 +59,7 @@ class CycleEngine {
|
|
|
uint32_t w = this->desc_->window_per_plane ? this->desc_->plane_width : this->desc_->width;
|
|
uint32_t w = this->desc_->window_per_plane ? this->desc_->plane_width : this->desc_->width;
|
|
|
this->plane_bytes_ = this->desc_->packed_2bpp_plane ? (w * this->desc_->height) / 4
|
|
this->plane_bytes_ = this->desc_->packed_2bpp_plane ? (w * this->desc_->height) / 4
|
|
|
: (w * this->desc_->height) / 8;
|
|
: (w * this->desc_->height) / 8;
|
|
|
|
|
+ this->bytes_per_row_ = this->plane_bytes_ / this->desc_->height;
|
|
|
this->cursor_ = 0;
|
|
this->cursor_ = 0;
|
|
|
this->plane_ = 0;
|
|
this->plane_ = 0;
|
|
|
this->cmd_phase_ = CmdPhase::BEFORE_DELAY;
|
|
this->cmd_phase_ = CmdPhase::BEFORE_DELAY;
|
|
@@ -271,7 +272,8 @@ class CycleEngine {
|
|
|
if (end > this->plane_bytes_)
|
|
if (end > this->plane_bytes_)
|
|
|
end = this->plane_bytes_;
|
|
end = this->plane_bytes_;
|
|
|
for (; this->cursor_ < end; this->cursor_++) {
|
|
for (; this->cursor_ < end; this->cursor_++) {
|
|
|
- uint8_t b = buf != nullptr ? buf[this->cursor_] : 0xFF;
|
|
|
|
|
|
|
+ uint32_t src = this->desc_->row_interleave ? this->interleaved_index_(this->cursor_) : this->cursor_;
|
|
|
|
|
+ uint8_t b = buf != nullptr ? buf[src] : 0xFF;
|
|
|
this->write_byte_(invert ? static_cast<uint8_t>(~b) : b, true);
|
|
this->write_byte_(invert ? static_cast<uint8_t>(~b) : b, true);
|
|
|
}
|
|
}
|
|
|
if (this->cursor_ >= this->plane_bytes_) {
|
|
if (this->cursor_ >= this->plane_bytes_) {
|
|
@@ -294,6 +296,20 @@ class CycleEngine {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Maps a wire-transmission-order byte position to the buffer's actual
|
|
|
|
|
+ // (plain top-to-bottom) byte index, for panels whose controller expects
|
|
|
|
|
+ // rows in interleaved top/bottom pairs (row 0, row H-1, row 1, row H-2,
|
|
|
|
|
+ // ...) instead of sequential order - see EpdPanelDescriptor::row_interleave.
|
|
|
|
|
+ // wire_pos counts up linearly (0..plane_bytes_-1) the same way it always
|
|
|
|
|
+ // has; only which buffer byte it reads changes.
|
|
|
|
|
+ uint32_t interleaved_index_(uint32_t wire_pos) const {
|
|
|
|
|
+ uint32_t wire_row = wire_pos / this->bytes_per_row_;
|
|
|
|
|
+ uint32_t byte_in_row = wire_pos % this->bytes_per_row_;
|
|
|
|
|
+ uint32_t pair = wire_row / 2;
|
|
|
|
|
+ uint32_t buf_row = (wire_row % 2 == 0) ? pair : (this->desc_->height - 1 - pair);
|
|
|
|
|
+ return buf_row * this->bytes_per_row_ + byte_in_row;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
void start_delay_(uint16_t delay_ms, State return_to) {
|
|
void start_delay_(uint16_t delay_ms, State return_to) {
|
|
|
this->deadline_ = millis() + delay_ms;
|
|
this->deadline_ = millis() + delay_ms;
|
|
|
this->delay_return_state_ = return_to;
|
|
this->delay_return_state_ = return_to;
|
|
@@ -378,6 +394,7 @@ class CycleEngine {
|
|
|
uint8_t plane_{0};
|
|
uint8_t plane_{0};
|
|
|
const uint8_t *planes_[2]{nullptr, nullptr};
|
|
const uint8_t *planes_[2]{nullptr, nullptr};
|
|
|
uint32_t plane_bytes_{0};
|
|
uint32_t plane_bytes_{0};
|
|
|
|
|
+ uint32_t bytes_per_row_{0};
|
|
|
uint32_t deadline_{0};
|
|
uint32_t deadline_{0};
|
|
|
State delay_return_state_{State::DONE};
|
|
State delay_return_state_{State::DONE};
|
|
|
uint32_t busy_wait_deadline_{0};
|
|
uint32_t busy_wait_deadline_{0};
|