unPhone implementation and more (#169)
- Implemented [unPhone](https://unphone.net/) v9 board - Updated `.clang-format` to better reflect the intended code style - Fix SD card compatibility issues for all boards (frequency wasn't set well) - Moved `I2cDevice` class from CoreS3 board project to TactilityHeadless project - Tactility configuration now has default empty lists for apps and services fields - Fix for Launcher app: we don't need padding when showing it vertically - Fix for I2cDevice read/write calls that checked for `esp_err_t` instead of `bool` - Fix for TinyUSB init that checked for `esp_err_t` instead of `bool`
This commit is contained in:
committed by
GitHub
parent
3ea02d912f
commit
72230129bb
@@ -0,0 +1,73 @@
|
||||
#include "UnPhoneDisplay.h"
|
||||
#include "UnPhoneDisplayConstants.h"
|
||||
#include "UnPhoneTouch.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <TactilityCore.h>
|
||||
|
||||
#include "UnPhoneFeatures.h"
|
||||
#include "esp_err.h"
|
||||
#include "hx8357/disp_spi.h"
|
||||
#include "hx8357/hx8357.h"
|
||||
|
||||
#define TAG "unphone_display"
|
||||
#define BUFFER_SIZE (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_DRAW_BUFFER_HEIGHT * LV_COLOR_DEPTH / 8)
|
||||
|
||||
extern UnPhoneFeatures unPhoneFeatures;
|
||||
|
||||
bool UnPhoneDisplay::start() {
|
||||
TT_LOG_I(TAG, "Starting");
|
||||
|
||||
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);
|
||||
|
||||
displayHandle = lv_display_create(UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION);
|
||||
lv_display_set_physical_resolution(displayHandle, UNPHONE_LCD_HORIZONTAL_RESOLUTION, UNPHONE_LCD_VERTICAL_RESOLUTION);
|
||||
lv_display_set_color_format(displayHandle, LV_COLOR_FORMAT_NATIVE);
|
||||
|
||||
// TODO malloc to use SPIRAM
|
||||
static auto* buffer1 = (uint8_t*)heap_caps_malloc(BUFFER_SIZE, MALLOC_CAP_SPIRAM);
|
||||
static auto* buffer2 = (uint8_t*)heap_caps_malloc(BUFFER_SIZE, MALLOC_CAP_SPIRAM);
|
||||
assert(buffer1 != nullptr);
|
||||
assert(buffer2 != nullptr);
|
||||
|
||||
lv_display_set_buffers(
|
||||
displayHandle,
|
||||
buffer1,
|
||||
buffer2,
|
||||
BUFFER_SIZE,
|
||||
LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||
);
|
||||
|
||||
lv_display_set_flush_cb(displayHandle, hx8357_flush);
|
||||
|
||||
if (displayHandle != nullptr) {
|
||||
TT_LOG_I(TAG, "Finished");
|
||||
unPhoneFeatures.setBacklightPower(true);
|
||||
return true;
|
||||
} else {
|
||||
TT_LOG_I(TAG, "Failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool UnPhoneDisplay::stop() {
|
||||
tt_assert(displayHandle != nullptr);
|
||||
|
||||
lv_display_delete(displayHandle);
|
||||
displayHandle = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
tt::hal::Touch* _Nullable UnPhoneDisplay::createTouch() {
|
||||
return static_cast<tt::hal::Touch*>(new UnPhoneTouch());
|
||||
}
|
||||
|
||||
tt::hal::Display* createDisplay() {
|
||||
return static_cast<tt::hal::Display*>(new UnPhoneDisplay());
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <esp_lcd_types.h>
|
||||
#include "lvgl.h"
|
||||
#include "hal/Display.h"
|
||||
|
||||
extern lv_disp_t* displayHandle;
|
||||
|
||||
class UnPhoneDisplay : public tt::hal::Display {
|
||||
|
||||
private:
|
||||
|
||||
lv_display_t* displayHandle = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
bool start() override;
|
||||
|
||||
bool stop() override;
|
||||
|
||||
tt::hal::Touch* _Nullable createTouch() override;
|
||||
|
||||
lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; }
|
||||
};
|
||||
|
||||
tt::hal::Display* createDisplay();
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#define UNPHONE_LCD_SPI_HOST SPI2_HOST
|
||||
#define UNPHONE_LCD_PIN_CS GPIO_NUM_48
|
||||
#define UNPHONE_LCD_PIN_DC GPIO_NUM_47
|
||||
#define UNPHONE_LCD_PIN_RESET GPIO_NUM_46
|
||||
#define UNPHONE_LCD_SPI_FREQUENCY 27000000
|
||||
#define UNPHONE_LCD_HORIZONTAL_RESOLUTION 320
|
||||
#define UNPHONE_LCD_VERTICAL_RESOLUTION 480
|
||||
#define UNPHONE_LCD_DRAW_BUFFER_HEIGHT (UNPHONE_LCD_VERTICAL_RESOLUTION / 15)
|
||||
#define UNPHONE_LCD_SPI_TRANSFER_HEIGHT (UNPHONE_LCD_VERTICAL_RESOLUTION / 15)
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "UnPhoneSdCard.h"
|
||||
|
||||
#include "lvgl/LvglSync.h"
|
||||
#include "hal/SpiSdCard.h"
|
||||
|
||||
#include <esp_vfs_fat.h>
|
||||
|
||||
#define UNPHONE_SDCARD_SPI_FREQUENCY 20000000U
|
||||
#define UNPHONE_SDCARD_PIN_CS GPIO_NUM_43
|
||||
#define UNPHONE_LCD_PIN_CS GPIO_NUM_48
|
||||
#define UNPHONE_LORA_PIN_CS GPIO_NUM_44
|
||||
#define UNPHONE_TOUCH_PIN_CS GPIO_NUM_38
|
||||
|
||||
std::shared_ptr<SdCard> createUnPhoneSdCard() {
|
||||
auto* configuration = new tt::hal::SpiSdCard::Config(
|
||||
UNPHONE_SDCARD_SPI_FREQUENCY,
|
||||
UNPHONE_SDCARD_PIN_CS,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
GPIO_NUM_NC,
|
||||
SdCard::MountBehaviour::AtBoot,
|
||||
tt::lvgl::getLvglSyncLockable(),
|
||||
{
|
||||
UNPHONE_LORA_PIN_CS,
|
||||
UNPHONE_LCD_PIN_CS,
|
||||
UNPHONE_TOUCH_PIN_CS
|
||||
}
|
||||
);
|
||||
|
||||
auto* sdcard = (SdCard*) new SpiSdCard(
|
||||
std::unique_ptr<SpiSdCard::Config>(configuration)
|
||||
);
|
||||
|
||||
return std::shared_ptr<SdCard>(sdcard);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/SdCard.h"
|
||||
|
||||
using namespace tt::hal;
|
||||
|
||||
std::shared_ptr<SdCard> createUnPhoneSdCard();
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "UnPhoneTouch.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "Log.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
#include "esp_lcd_touch_xpt2046.h"
|
||||
|
||||
#define TAG "unphone_touch"
|
||||
|
||||
#define UNPHONE_TOUCH_X_MAX 320
|
||||
#define UNPHONE_TOUCH_Y_MAX 480
|
||||
|
||||
bool UnPhoneTouch::start(lv_display_t* display) {
|
||||
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(GPIO_NUM_38);
|
||||
|
||||
if (esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &ioHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Touch IO SPI creation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_lcd_touch_config_t config = {
|
||||
.x_max = UNPHONE_TOUCH_X_MAX,
|
||||
.y_max = UNPHONE_TOUCH_Y_MAX,
|
||||
.rst_gpio_num = GPIO_NUM_NC,
|
||||
.int_gpio_num = GPIO_NUM_NC,
|
||||
.levels = {
|
||||
.reset = 0,
|
||||
.interrupt = 0,
|
||||
},
|
||||
.flags = {
|
||||
.swap_xy = 0,
|
||||
.mirror_x = 0,
|
||||
.mirror_y = 0,
|
||||
},
|
||||
.process_coordinates = nullptr,
|
||||
.interrupt_callback = nullptr,
|
||||
.user_data = nullptr,
|
||||
.driver_data = nullptr
|
||||
};
|
||||
|
||||
if (esp_lcd_touch_new_spi_xpt2046(ioHandle, &config, &touchHandle) != ESP_OK) {
|
||||
TT_LOG_E(TAG, "XPT2046 driver init failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
const lvgl_port_touch_cfg_t touch_cfg = {
|
||||
.disp = display,
|
||||
.handle = touchHandle,
|
||||
};
|
||||
|
||||
TT_LOG_I(TAG, "Adding touch to LVGL");
|
||||
deviceHandle = lvgl_port_add_touch(&touch_cfg);
|
||||
if (deviceHandle == nullptr) {
|
||||
TT_LOG_E(TAG, "Adding touch failed");
|
||||
cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnPhoneTouch::stop() {
|
||||
cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
void UnPhoneTouch::cleanup() {
|
||||
if (deviceHandle != nullptr) {
|
||||
lv_indev_delete(deviceHandle);
|
||||
deviceHandle = nullptr;
|
||||
}
|
||||
|
||||
if (touchHandle != nullptr) {
|
||||
esp_lcd_touch_del(touchHandle);
|
||||
touchHandle = nullptr;
|
||||
}
|
||||
|
||||
if (ioHandle != nullptr) {
|
||||
esp_lcd_panel_io_del(ioHandle);
|
||||
ioHandle = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "hal/Touch.h"
|
||||
#include "TactilityCore.h"
|
||||
#include "esp_lcd_panel_io_interface.h"
|
||||
#include "esp_lcd_touch.h"
|
||||
|
||||
class UnPhoneTouch : public tt::hal::Touch {
|
||||
private:
|
||||
esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr;
|
||||
esp_lcd_touch_handle_t _Nullable touchHandle = nullptr;
|
||||
lv_indev_t* _Nullable deviceHandle = nullptr;
|
||||
void cleanup();
|
||||
public:
|
||||
bool start(lv_display_t* display) override;
|
||||
bool stop() override;
|
||||
lv_indev_t* _Nullable getLvglIndev() override { return deviceHandle; }
|
||||
};
|
||||
Reference in New Issue
Block a user