summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/display.cpp62
-rw-r--r--src/drivers/display_init.cpp1
-rw-r--r--src/drivers/include/drivers/display.hpp4
-rw-r--r--src/drivers/include/drivers/display_init.hpp1
4 files changed, 52 insertions, 16 deletions
diff --git a/src/drivers/display.cpp b/src/drivers/display.cpp
index 2fcb9dc0..0ae37688 100644
--- a/src/drivers/display.cpp
+++ b/src/drivers/display.cpp
@@ -136,21 +136,35 @@ auto Display::Create(IGpios& expander,
spi_device_handle_t handle;
spi_bus_add_device(VSPI_HOST, &spi_cfg, &handle);
- auto display = std::make_unique<Display>(expander, handle);
+ auto display = std::make_unique<Display>(expander, handle, init_data.pad);
// Now we reset the display into a known state, then configure it
ESP_LOGI(kTag, "Sending init sequences");
+
+ // Hold the SPI bus for the entire init sequence, as otherwise SD init may
+ // grab it and delay showing the boot splash. The total time until boot is
+ // finished may be increased by doing this, but a short boot with no feedback
+ // feels worse than a longer boot that doesn't tell you anything.
+ spi_device_acquire_bus(handle, portMAX_DELAY);
+ expander.SdMuxEnable(false);
+
for (int i = 0; i < init_data.num_sequences; i++) {
display->SendInitialisationSequence(init_data.sequences[i]);
}
+ display->WriteLeftPad(reinterpret_cast<uint8_t*>(kDisplayBuffer));
+
+ expander.SdMuxEnable(true);
+ spi_device_release_bus(handle);
+
// The hardware is now configured correctly. Next, initialise the LVGL display
// driver.
ESP_LOGI(kTag, "Init buffers");
assert(esp_ptr_dma_capable(kDisplayBuffer));
ESP_LOGI(kTag, "Creating display");
- display->display_ = lv_display_create(init_data.width, init_data.height);
+ display->display_ =
+ lv_display_create(init_data.width - init_data.pad, init_data.height);
lv_display_set_buffers(display->display_, kDisplayBuffer, NULL,
sizeof(kDisplayBuffer),
LV_DISPLAY_RENDER_MODE_PARTIAL);
@@ -162,12 +176,13 @@ auto Display::Create(IGpios& expander,
return display.release();
}
-Display::Display(IGpios& gpio, spi_device_handle_t handle)
+Display::Display(IGpios& gpio, spi_device_handle_t handle, uint_fast8_t pad)
: gpio_(gpio),
handle_(handle),
first_flush_finished_(false),
display_on_(false),
- brightness_(0) {}
+ brightness_(0),
+ pad_(pad) {}
Display::~Display() {
ledc_fade_func_uninstall();
@@ -223,13 +238,6 @@ auto Display::SetDutyCycle(uint_fast8_t new_duty, bool fade) -> void {
}
void Display::SendInitialisationSequence(const uint8_t* data) {
- // Hold the SPI bus for the entire init sequence, as otherwise SD init may
- // grab it and delay showing the boot splash. The total time until boot is
- // finished may be increased by doing this, but a short boot with no feedback
- // feels worse than a longer boot that doesn't tell you anything.
- spi_device_acquire_bus(handle_, portMAX_DELAY);
- gpio_.SdMuxEnable(false);
-
// First byte of the data is the number of commands.
for (int i = *(data++); i > 0; i--) {
uint8_t command = *(data++);
@@ -249,9 +257,33 @@ void Display::SendInitialisationSequence(const uint8_t* data) {
vTaskDelay(pdMS_TO_TICKS(sleep_duration_ms));
}
}
+}
- gpio_.SdMuxEnable(true);
- spi_device_release_bus(handle_);
+void Display::WriteLeftPad(uint8_t* buffer) {
+ if (pad_ == 0) {
+ return;
+ }
+
+ uint16_t data1[2] = {0, 0};
+
+ // Select the left pad_ cols
+ data1[0] = SPI_SWAP_DATA_TX(0, 16);
+ data1[1] = SPI_SWAP_DATA_TX(pad_, 16);
+ SendCommandWithData(displays::ST77XX_CASET, reinterpret_cast<uint8_t*>(data1),
+ 4);
+
+ // Select all rows
+ data1[0] = SPI_SWAP_DATA_TX(0, 16);
+ data1[1] = SPI_SWAP_DATA_TX(128, 16);
+ SendCommandWithData(displays::ST77XX_RASET, reinterpret_cast<uint8_t*>(data1),
+ 4);
+
+ // Prep our beautiful zeroes.
+ size_t len = pad_ * 128 * 3;
+ std::memset(buffer, 0, len);
+
+ // Write our beautiful zeroes.
+ SendCommandWithData(displays::ST77XX_RAMWR, buffer, len);
}
IRAM_ATTR
@@ -309,8 +341,8 @@ void Display::OnLvglFlush(const lv_area_t* area, uint8_t* color_map) {
// First we need to specify the rectangle of the display we're writing into.
uint16_t data[2] = {0, 0};
- data[0] = SPI_SWAP_DATA_TX(area->x1, 16);
- data[1] = SPI_SWAP_DATA_TX(area->x2, 16);
+ data[0] = SPI_SWAP_DATA_TX(area->x1 + pad_, 16);
+ data[1] = SPI_SWAP_DATA_TX(area->x2 + pad_, 16);
SendCommandWithData(displays::ST77XX_CASET, reinterpret_cast<uint8_t*>(data),
4);
diff --git a/src/drivers/display_init.cpp b/src/drivers/display_init.cpp
index edd36a8d..62cd18dd 100644
--- a/src/drivers/display_init.cpp
+++ b/src/drivers/display_init.cpp
@@ -103,6 +103,7 @@ static const uint8_t kST7735RCommonFooter[]{
const InitialisationData kST7735R = {
.width = 160,
.height = 128,
+ .pad = 0,
.num_sequences = 3,
.sequences = {kST7735RCommonHeader, kST7735RCommonGreen,
kST7735RCommonFooter}};
diff --git a/src/drivers/include/drivers/display.hpp b/src/drivers/include/drivers/display.hpp
index e5001c48..88bb07c4 100644
--- a/src/drivers/include/drivers/display.hpp
+++ b/src/drivers/include/drivers/display.hpp
@@ -34,7 +34,7 @@ class Display {
static auto Create(IGpios& expander,
const displays::InitialisationData& init_data) -> Display*;
- Display(IGpios& gpio, spi_device_handle_t handle);
+ Display(IGpios& gpio, spi_device_handle_t handle, uint_fast8_t pad);
~Display();
auto SetDisplayOn(bool) -> void;
@@ -54,6 +54,7 @@ class Display {
bool first_flush_finished_;
bool display_on_;
uint_fast8_t brightness_;
+ uint_fast8_t pad_;
lv_display_t* display_ = nullptr;
@@ -63,6 +64,7 @@ class Display {
};
void SendInitialisationSequence(const uint8_t* data);
+ void WriteLeftPad(uint8_t *buffer);
void SendCommandWithData(uint8_t command, const uint8_t* data, size_t length);
diff --git a/src/drivers/include/drivers/display_init.hpp b/src/drivers/include/drivers/display_init.hpp
index 9bf5b3f5..6ccdb417 100644
--- a/src/drivers/include/drivers/display_init.hpp
+++ b/src/drivers/include/drivers/display_init.hpp
@@ -17,6 +17,7 @@ extern const uint8_t kDelayBit;
struct InitialisationData {
uint16_t width;
uint16_t height;
+ uint8_t pad;
uint8_t num_sequences;
const uint8_t* sequences[4];
};