#include "UnPhoneDisplay.h" #include "UnPhoneDisplayConstants.h" #include "UnPhoneTouch.h" #include "UnPhoneFeatures.h" #include #include #include #include constexpr auto TAG = "UnPhoneDisplay"; constexpr auto BUFFER_SIZE = (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_DRAW_BUFFER_HEIGHT * LV_COLOR_DEPTH / 8); extern std::shared_ptr unPhoneFeatures; bool UnPhoneDisplay::start() { TT_LOG_I(TAG, "start"); disp_spi_add_device(SPI2_HOST); hx8357_reset(GPIO_NUM_46); hx8357_init(UNPHONE_LCD_PIN_DC); uint8_t madctl = (1U << MADCTL_BIT_INDEX_COLUMN_ADDRESS_ORDER); hx8357_set_madctl(madctl); return true; } bool UnPhoneDisplay::stop() { TT_LOG_I(TAG, "stop"); disp_spi_remove_device(); return true; } bool UnPhoneDisplay::startLvgl() { TT_LOG_I(TAG, "startLvgl"); if (lvglDisplay != nullptr) { TT_LOG_W(TAG, "LVGL was already started"); return false; } lvglDisplay = lv_display_create(UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION); lv_display_set_physical_resolution(lvglDisplay, UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION); lv_display_set_color_format(lvglDisplay, LV_COLOR_FORMAT_NATIVE); // TODO malloc to use SPIRAM buffer = static_cast(heap_caps_malloc(BUFFER_SIZE, MALLOC_CAP_DMA)); assert(buffer != nullptr); lv_display_set_buffers( lvglDisplay, buffer, nullptr, BUFFER_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL ); lv_display_set_flush_cb(lvglDisplay, hx8357_flush); if (lvglDisplay == nullptr) { TT_LOG_I(TAG, "Failed"); return false; } unPhoneFeatures->setBacklightPower(true); auto touch_device = getTouchDevice(); if (touch_device != nullptr) { touch_device->startLvgl(lvglDisplay); } return true; } bool UnPhoneDisplay::stopLvgl() { TT_LOG_I(TAG, "stopLvgl"); if (lvglDisplay == nullptr) { TT_LOG_W(TAG, "LVGL was already stopped"); return false; } // Just in case disp_wait_for_pending_transactions(); auto touch_device = getTouchDevice(); if (touch_device != nullptr && touch_device->getLvglIndev() != nullptr) { TT_LOG_I(TAG, "Stopping touch device"); touch_device->stopLvgl(); } lv_display_delete(lvglDisplay); lvglDisplay = nullptr; heap_caps_free(buffer); buffer = nullptr; return true; } std::shared_ptr _Nullable UnPhoneDisplay::getTouchDevice() { if (touchDevice == nullptr) { touchDevice = std::reinterpret_pointer_cast(createTouch()); TT_LOG_I(TAG, "Created touch device"); } return touchDevice; } std::shared_ptr createDisplay() { return std::make_shared(); } bool UnPhoneDisplay::UnPhoneDisplayDriver::drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) { lv_area_t area = { xStart, yStart, xEnd, yEnd }; hx8357_flush(nullptr, &area, (uint8_t*)pixelData); return true; }