mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-04-18 17:35:05 +00:00
Compare commits
10 Commits
3b9004ffbc
...
281fa5f61e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
281fa5f61e | ||
|
|
1de78a6dc6 | ||
|
|
3b0f2354a0 | ||
|
|
b9c3e5f773 | ||
|
|
3db3fcd8f7 | ||
|
|
5c068974ff | ||
|
|
176f210ced | ||
|
|
e971f01eeb | ||
|
|
1deaf4c426 | ||
|
|
b0408e40ec |
2
.gitignore
vendored
2
.gitignore
vendored
@ -16,3 +16,5 @@ sdkconfig.old
|
|||||||
managed_components/
|
managed_components/
|
||||||
dependencies.lock
|
dependencies.lock
|
||||||
|
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
|||||||
@ -1,22 +1,26 @@
|
|||||||
#include "CYD2432S024C.h"
|
#include "CYD2432S024C.h"
|
||||||
#include "hal/YellowDisplay.h"
|
#include "devices/Display.h"
|
||||||
#include "hal/YellowDisplayConstants.h"
|
#include "devices/SdCard.h"
|
||||||
#include "hal/YellowSdCard.h"
|
|
||||||
|
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
#include <PwmBacklight.h>
|
#include <PwmBacklight.h>
|
||||||
|
|
||||||
#define CYD_SPI_TRANSFER_SIZE_LIMIT (TWODOTFOUR_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
#define CYD_SPI_TRANSFER_SIZE_LIMIT (TWODOTFOUR_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
||||||
|
|
||||||
bool initBoot() {
|
static bool initBoot() {
|
||||||
return driver::pwmbacklight::init(TWODOTFOUR_LCD_PIN_BACKLIGHT);
|
return driver::pwmbacklight::init(TWODOTFOUR_LCD_PIN_BACKLIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tt::hal::DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
createDisplay(),
|
||||||
|
createSdCard()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const tt::hal::Configuration cyd_2432s024c_config = {
|
const tt::hal::Configuration cyd_2432s024c_config = {
|
||||||
.initBoot = initBoot,
|
.initBoot = initBoot,
|
||||||
.createDisplay = createDisplay,
|
.createDevices = createDevices,
|
||||||
.sdcard = createYellowSdCard(),
|
|
||||||
.power = nullptr,
|
|
||||||
.i2c = {
|
.i2c = {
|
||||||
tt::hal::i2c::Configuration {
|
tt::hal::i2c::Configuration {
|
||||||
.name = "First",
|
.name = "First",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
#include "YellowDisplay.h"
|
#include "Display.h"
|
||||||
#include "Cst816Touch.h"
|
#include "Cst816Touch.h"
|
||||||
#include "YellowDisplayConstants.h"
|
|
||||||
|
|
||||||
#include <Ili934xDisplay.h>
|
#include <Ili934xDisplay.h>
|
||||||
#include <PwmBacklight.h>
|
#include <PwmBacklight.h>
|
||||||
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#define TWODOTFOUR_LCD_PIN_BACKLIGHT GPIO_NUM_27
|
#define TWODOTFOUR_LCD_PIN_BACKLIGHT GPIO_NUM_27
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
@ -11,3 +14,4 @@
|
|||||||
#define TWODOTFOUR_LCD_PIN_CS GPIO_NUM_15
|
#define TWODOTFOUR_LCD_PIN_CS GPIO_NUM_15
|
||||||
#define TWODOTFOUR_LCD_PIN_DC GPIO_NUM_2
|
#define TWODOTFOUR_LCD_PIN_DC GPIO_NUM_2
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "YellowSdCard.h"
|
#include "SdCard.h"
|
||||||
|
|
||||||
#define TAG "twodotfour_sdcard"
|
#define TAG "twodotfour_sdcard"
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ constexpr auto SDCARD_PIN_CS = GPIO_NUM_5;
|
|||||||
|
|
||||||
using tt::hal::sdcard::SpiSdCardDevice;
|
using tt::hal::sdcard::SpiSdCardDevice;
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createYellowSdCard() {
|
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||||
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
||||||
SDCARD_PIN_CS,
|
SDCARD_PIN_CS,
|
||||||
GPIO_NUM_NC,
|
GPIO_NUM_NC,
|
||||||
@ -4,5 +4,5 @@
|
|||||||
|
|
||||||
using tt::hal::sdcard::SdCardDevice;
|
using tt::hal::sdcard::SdCardDevice;
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createYellowSdCard();
|
std::shared_ptr<SdCardDevice> createSdCard();
|
||||||
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// Touch
|
|
||||||
#define TWODOTFOUR_TOUCH_I2C_PORT I2C_NUM_0
|
|
||||||
|
|
||||||
@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${SOURCE_FILES}
|
SRCS ${SOURCE_FILES}
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port ILI934x XPT2046 PwmBacklight driver vfs fatfs
|
REQUIRES Tactility esp_lvgl_port ILI934x XPT2046SoftSPI PwmBacklight driver vfs fatfs
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
#include "CYD2432S028R.h"
|
#include "CYD2432S028R.h"
|
||||||
#include "hal/YellowDisplay.h"
|
#include "devices/Display.h"
|
||||||
#include "hal/YellowConstants.h"
|
#include "devices/SdCard.h"
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
#include <PwmBacklight.h>
|
#include <PwmBacklight.h>
|
||||||
#include <Tactility/hal/Configuration.h>
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
|
||||||
|
// SPI Transfer
|
||||||
|
#define CYD_SPI_TRANSFER_SIZE_LIMIT (CYD2432S028R_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
||||||
|
// Display backlight (PWM)
|
||||||
|
#define CYD2432S028R_LCD_PIN_BACKLIGHT GPIO_NUM_21
|
||||||
|
|
||||||
using namespace tt::hal;
|
using namespace tt::hal;
|
||||||
|
|
||||||
bool initBoot() {
|
static bool initBoot() {
|
||||||
//Set the RGB Led Pins to output and turn them off
|
//Set the RGB Led Pins to output and turn them off
|
||||||
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); //Red
|
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT)); //Red
|
||||||
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); //Green
|
ESP_ERROR_CHECK(gpio_set_direction(GPIO_NUM_16, GPIO_MODE_OUTPUT)); //Green
|
||||||
@ -21,16 +26,21 @@ bool initBoot() {
|
|||||||
return driver::pwmbacklight::init(CYD2432S028R_LCD_PIN_BACKLIGHT);
|
return driver::pwmbacklight::init(CYD2432S028R_LCD_PIN_BACKLIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
createDisplay(),
|
||||||
|
createSdCard()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const Configuration cyd_2432s028r_config = {
|
const Configuration cyd_2432s028r_config = {
|
||||||
.initBoot = initBoot,
|
.initBoot = initBoot,
|
||||||
.createDisplay = createDisplay,
|
.createDevices = createDevices,
|
||||||
.sdcard = nullptr,
|
|
||||||
.power = nullptr,
|
|
||||||
.i2c = {},
|
.i2c = {},
|
||||||
.spi {
|
.spi {
|
||||||
//Display
|
//Display
|
||||||
spi::Configuration {
|
spi::Configuration {
|
||||||
.device = CYD2432S028R_LCD_SPI_HOST,
|
.device = SPI2_HOST,
|
||||||
.dma = SPI_DMA_CH_AUTO,
|
.dma = SPI_DMA_CH_AUTO,
|
||||||
.config = {
|
.config = {
|
||||||
.mosi_io_num = GPIO_NUM_13,
|
.mosi_io_num = GPIO_NUM_13,
|
||||||
@ -53,14 +63,14 @@ const Configuration cyd_2432s028r_config = {
|
|||||||
.lock = tt::lvgl::getSyncLock()
|
.lock = tt::lvgl::getSyncLock()
|
||||||
},
|
},
|
||||||
|
|
||||||
// Touch
|
// SDCard
|
||||||
spi::Configuration {
|
spi::Configuration {
|
||||||
.device = CYD2432S028R_TOUCH_SPI_HOST,
|
.device = SPI3_HOST,
|
||||||
.dma = SPI_DMA_CH_AUTO,
|
.dma = SPI_DMA_CH_AUTO,
|
||||||
.config = {
|
.config = {
|
||||||
.mosi_io_num = GPIO_NUM_32,
|
.mosi_io_num = GPIO_NUM_23,
|
||||||
.miso_io_num = GPIO_NUM_39,
|
.miso_io_num = GPIO_NUM_19,
|
||||||
.sclk_io_num = GPIO_NUM_25,
|
.sclk_io_num = GPIO_NUM_18,
|
||||||
.quadwp_io_num = GPIO_NUM_NC,
|
.quadwp_io_num = GPIO_NUM_NC,
|
||||||
.quadhd_io_num = GPIO_NUM_NC,
|
.quadhd_io_num = GPIO_NUM_NC,
|
||||||
.data4_io_num = GPIO_NUM_NC,
|
.data4_io_num = GPIO_NUM_NC,
|
||||||
@ -73,7 +83,7 @@ const Configuration cyd_2432s028r_config = {
|
|||||||
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||||
.intr_flags = 0
|
.intr_flags = 0
|
||||||
},
|
},
|
||||||
.initMode = tt::hal::spi::InitMode::ByTactility,
|
.initMode = spi::InitMode::ByTactility,
|
||||||
.isMutable = false,
|
.isMutable = false,
|
||||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,21 +1,33 @@
|
|||||||
#include "YellowDisplay.h"
|
#include "Display.h"
|
||||||
#include "Xpt2046Touch.h"
|
#include "Xpt2046SoftSpi.h"
|
||||||
#include "YellowConstants.h"
|
|
||||||
#include <Ili934xDisplay.h>
|
#include <Ili934xDisplay.h>
|
||||||
#include <PwmBacklight.h>
|
#include <PwmBacklight.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "CYD";
|
||||||
|
|
||||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||||
auto configuration = std::make_unique<Xpt2046Touch::Configuration>(
|
auto configuration = std::make_unique<Xpt2046SoftSpi::Configuration>(
|
||||||
CYD2432S028R_TOUCH_SPI_HOST,
|
CYD_TOUCH_MOSI_PIN,
|
||||||
CYD2432S028R_TOUCH_PIN_CS,
|
CYD_TOUCH_MISO_PIN,
|
||||||
240,
|
CYD_TOUCH_SCK_PIN,
|
||||||
320,
|
CYD_TOUCH_CS_PIN,
|
||||||
false,
|
CYD2432S028R_LCD_HORIZONTAL_RESOLUTION, // 240
|
||||||
true,
|
CYD2432S028R_LCD_VERTICAL_RESOLUTION, // 320
|
||||||
false
|
false, // swapXY
|
||||||
|
true, // mirrorX
|
||||||
|
false // mirrorY
|
||||||
);
|
);
|
||||||
|
|
||||||
return std::make_shared<Xpt2046Touch>(std::move(configuration));
|
// Allocate the driver
|
||||||
|
auto touch = std::make_shared<Xpt2046SoftSpi>(std::move(configuration));
|
||||||
|
|
||||||
|
// Start the driver
|
||||||
|
if (!touch->start()) {
|
||||||
|
ESP_LOGE(TAG, "Touch driver start failed");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
@ -28,9 +40,9 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
CYD2432S028R_LCD_HORIZONTAL_RESOLUTION,
|
CYD2432S028R_LCD_HORIZONTAL_RESOLUTION,
|
||||||
CYD2432S028R_LCD_VERTICAL_RESOLUTION,
|
CYD2432S028R_LCD_VERTICAL_RESOLUTION,
|
||||||
touch,
|
touch,
|
||||||
false,
|
false, // swapXY
|
||||||
true,
|
true, // mirrorX
|
||||||
false,
|
false, // mirrorY
|
||||||
false,
|
false,
|
||||||
CYD2432S028R_LCD_DRAW_BUFFER_SIZE
|
CYD2432S028R_LCD_DRAW_BUFFER_SIZE
|
||||||
);
|
);
|
||||||
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Display backlight (PWM)
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
#define CYD2432S028R_LCD_PIN_BACKLIGHT GPIO_NUM_21
|
#include <memory>
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define CYD2432S028R_LCD_SPI_HOST SPI2_HOST
|
#define CYD2432S028R_LCD_SPI_HOST SPI2_HOST
|
||||||
@ -12,13 +12,11 @@
|
|||||||
#define CYD2432S028R_LCD_PIN_CS GPIO_NUM_15
|
#define CYD2432S028R_LCD_PIN_CS GPIO_NUM_15
|
||||||
#define CYD2432S028R_LCD_PIN_DC GPIO_NUM_2
|
#define CYD2432S028R_LCD_PIN_DC GPIO_NUM_2
|
||||||
|
|
||||||
// Touch
|
// Touch (Software SPI)
|
||||||
#define CYD2432S028R_TOUCH_SPI_HOST SPI3_HOST
|
#define CYD_TOUCH_MISO_PIN GPIO_NUM_39
|
||||||
#define CYD2432S028R_TOUCH_PIN_CS GPIO_NUM_33
|
#define CYD_TOUCH_MOSI_PIN GPIO_NUM_32
|
||||||
|
#define CYD_TOUCH_SCK_PIN GPIO_NUM_25
|
||||||
|
#define CYD_TOUCH_CS_PIN GPIO_NUM_33
|
||||||
|
#define CYD_TOUCH_IRQ_PIN GPIO_NUM_36
|
||||||
|
|
||||||
// SDCard
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
#define SDCARD_SPI_HOST SPI3_HOST
|
|
||||||
#define SDCARD_PIN_CS GPIO_NUM_5
|
|
||||||
|
|
||||||
// SPI Transfer
|
|
||||||
#define CYD_SPI_TRANSFER_SIZE_LIMIT (CYD2432S028R_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
|
||||||
21
Boards/CYD-2432S028R/Source/devices/SdCard.cpp
Normal file
21
Boards/CYD-2432S028R/Source/devices/SdCard.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "SdCard.h"
|
||||||
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
|
|
||||||
|
using tt::hal::sdcard::SpiSdCardDevice;
|
||||||
|
|
||||||
|
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||||
|
auto config = std::make_unique<SpiSdCardDevice::Config>(
|
||||||
|
GPIO_NUM_5,
|
||||||
|
GPIO_NUM_NC,
|
||||||
|
GPIO_NUM_NC,
|
||||||
|
GPIO_NUM_NC,
|
||||||
|
SdCardDevice::MountBehaviour::AtBoot,
|
||||||
|
std::make_shared<tt::Mutex>(),
|
||||||
|
std::vector<gpio_num_t>(),
|
||||||
|
SPI3_HOST
|
||||||
|
);
|
||||||
|
|
||||||
|
return std::make_shared<SpiSdCardDevice>(std::move(config));
|
||||||
|
}
|
||||||
|
|
||||||
@ -4,5 +4,5 @@
|
|||||||
|
|
||||||
using tt::hal::sdcard::SdCardDevice;
|
using tt::hal::sdcard::SdCardDevice;
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createYellowSdCard();
|
std::shared_ptr<SdCardDevice> createSdCard();
|
||||||
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Tactility/hal/display/DisplayDevice.h"
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
#include "YellowSdCard.h"
|
|
||||||
#include "YellowConstants.h"
|
|
||||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
|
||||||
|
|
||||||
using tt::hal::sdcard::SpiSdCardDevice;
|
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createYellowSdCard() {
|
|
||||||
auto* configuration = new SpiSdCardDevice::Config(
|
|
||||||
SDCARD_PIN_CS,
|
|
||||||
GPIO_NUM_NC,
|
|
||||||
GPIO_NUM_NC,
|
|
||||||
GPIO_NUM_NC,
|
|
||||||
SdCardDevice::MountBehaviour::AtBoot,
|
|
||||||
std::make_shared<tt::Mutex>(),
|
|
||||||
std::vector<gpio_num_t>(),
|
|
||||||
SDCARD_SPI_HOST
|
|
||||||
);
|
|
||||||
|
|
||||||
auto* sdcard = (SdCardDevice*) new SpiSdCardDevice(
|
|
||||||
std::unique_ptr<SpiSdCardDevice::Config>(configuration)
|
|
||||||
);
|
|
||||||
|
|
||||||
return std::shared_ptr<SdCardDevice>(sdcard);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ bool tpagerInit();
|
|||||||
|
|
||||||
using namespace tt::hal;
|
using namespace tt::hal;
|
||||||
|
|
||||||
DeviceVector createDevices() {
|
static DeviceVector createDevices() {
|
||||||
auto bq27220 = std::make_shared<Bq27220>(I2C_NUM_0);
|
auto bq27220 = std::make_shared<Bq27220>(I2C_NUM_0);
|
||||||
auto power = std::make_shared<TpagerPower>(bq27220);
|
auto power = std::make_shared<TpagerPower>(bq27220);
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#include <driver/i2c.h>
|
#include <driver/i2c.h>
|
||||||
#include <driver/spi_master.h>
|
#include <driver/spi_master.h>
|
||||||
|
|
||||||
#define TAG "core2"
|
constexpr auto* TAG = "Core2";
|
||||||
|
|
||||||
axp192_t axpDevice;
|
axp192_t axpDevice;
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#include "M5stackCore2.h"
|
#include "M5stackCore2.h"
|
||||||
#include "InitBoot.h"
|
#include "InitBoot.h"
|
||||||
#include "hal/Core2Display.h"
|
#include "devices/Display.h"
|
||||||
#include "hal/Core2Power.h"
|
#include "devices/Core2Power.h"
|
||||||
#include "hal/Core2SdCard.h"
|
#include "devices/SdCard.h"
|
||||||
|
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
@ -11,16 +11,22 @@
|
|||||||
|
|
||||||
using namespace tt::hal;
|
using namespace tt::hal;
|
||||||
|
|
||||||
extern const tt::hal::Configuration m5stack_core2 = {
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
createPower(),
|
||||||
|
createSdCard(),
|
||||||
|
createDisplay()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration m5stack_core2 = {
|
||||||
.initBoot = initBoot,
|
.initBoot = initBoot,
|
||||||
.createDisplay = createDisplay,
|
.createDevices = createDevices,
|
||||||
.sdcard = createSdCard(),
|
|
||||||
.power = createPower,
|
|
||||||
.i2c = {
|
.i2c = {
|
||||||
tt::hal::i2c::Configuration {
|
i2c::Configuration {
|
||||||
.name = "Internal",
|
.name = "Internal",
|
||||||
.port = I2C_NUM_0,
|
.port = I2C_NUM_0,
|
||||||
.initMode = tt::hal::i2c::InitMode::ByTactility,
|
.initMode = i2c::InitMode::ByTactility,
|
||||||
.isMutable = false,
|
.isMutable = false,
|
||||||
.config = (i2c_config_t) {
|
.config = (i2c_config_t) {
|
||||||
.mode = I2C_MODE_MASTER,
|
.mode = I2C_MODE_MASTER,
|
||||||
@ -34,10 +40,10 @@ extern const tt::hal::Configuration m5stack_core2 = {
|
|||||||
.clk_flags = 0
|
.clk_flags = 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tt::hal::i2c::Configuration {
|
i2c::Configuration {
|
||||||
.name = "External", // (Grove)
|
.name = "External", // (Grove)
|
||||||
.port = I2C_NUM_1,
|
.port = I2C_NUM_1,
|
||||||
.initMode = tt::hal::i2c::InitMode::ByTactility,
|
.initMode = i2c::InitMode::ByTactility,
|
||||||
.isMutable = true,
|
.isMutable = true,
|
||||||
.config = (i2c_config_t) {
|
.config = (i2c_config_t) {
|
||||||
.mode = I2C_MODE_MASTER,
|
.mode = I2C_MODE_MASTER,
|
||||||
@ -53,7 +59,7 @@ extern const tt::hal::Configuration m5stack_core2 = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.spi {
|
.spi {
|
||||||
tt::hal::spi::Configuration {
|
spi::Configuration {
|
||||||
.device = SPI2_HOST,
|
.device = SPI2_HOST,
|
||||||
.dma = SPI_DMA_CH_AUTO,
|
.dma = SPI_DMA_CH_AUTO,
|
||||||
.config = {
|
.config = {
|
||||||
@ -72,7 +78,7 @@ extern const tt::hal::Configuration m5stack_core2 = {
|
|||||||
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
.isr_cpu_id = ESP_INTR_CPU_AFFINITY_AUTO,
|
||||||
.intr_flags = 0
|
.intr_flags = 0
|
||||||
},
|
},
|
||||||
.initMode = tt::hal::spi::InitMode::ByTactility,
|
.initMode = spi::InitMode::ByTactility,
|
||||||
.isMutable = false,
|
.isMutable = false,
|
||||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,6 @@ bool Core2Power::supportsMetric(MetricType type) const {
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // Safety guard for when new enum values are introduced
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core2Power::getMetric(MetricType type, MetricData& data) {
|
bool Core2Power::getMetric(MetricType type, MetricData& data) {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "Core2Display.h"
|
#include "Display.h"
|
||||||
|
|
||||||
#include <Ft6x36Touch.h>
|
#include <Ft6x36Touch.h>
|
||||||
#include <Ili934xDisplay.h>
|
#include <Ili934xDisplay.h>
|
||||||
@ -1,12 +1,10 @@
|
|||||||
#include "Core2SdCard.h"
|
#include "SdCard.h"
|
||||||
|
|
||||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
|
|
||||||
#include <esp_vfs_fat.h>
|
constexpr auto CORE2_SDCARD_PIN_CS = GPIO_NUM_4;
|
||||||
|
constexpr auto CORE2_LCD_PIN_CS = GPIO_NUM_5;
|
||||||
#define CORE2_SDCARD_PIN_CS GPIO_NUM_4
|
|
||||||
#define CORE2_LCD_PIN_CS GPIO_NUM_5
|
|
||||||
|
|
||||||
using tt::hal::sdcard::SpiSdCardDevice;
|
using tt::hal::sdcard::SpiSdCardDevice;
|
||||||
|
|
||||||
@ -1,5 +1,7 @@
|
|||||||
|
file(GLOB_RECURSE SOURCE_FILES Source/*.c*)
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRC_DIRS "Source" "Source/hal"
|
SRCS ${SOURCE_FILES}
|
||||||
INCLUDE_DIRS "Source"
|
INCLUDE_DIRS "Source"
|
||||||
REQUIRES Tactility esp_lvgl_port ILI934x FT5x06 AXP2101 AW9523 driver vfs fatfs
|
REQUIRES Tactility esp_lvgl_port ILI934x FT5x06 AXP2101 AW9523 driver vfs fatfs
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define AXP2101_ADDRESS 0x34
|
|
||||||
#define AW9523_ADDRESS 0x58
|
|
||||||
@ -1,10 +1,9 @@
|
|||||||
#include <Axp2101.h>
|
#include "InitBoot.h"
|
||||||
#include <Aw9523.h>
|
|
||||||
|
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
#include <Tactility/kernel/Kernel.h>
|
#include <Tactility/kernel/Kernel.h>
|
||||||
|
|
||||||
#define TAG "cores3"
|
constexpr auto* TAG = "CoreS3";
|
||||||
|
|
||||||
std::shared_ptr<Axp2101> axp2101;
|
std::shared_ptr<Axp2101> axp2101;
|
||||||
std::shared_ptr<Aw9523> aw9523;
|
std::shared_ptr<Aw9523> aw9523;
|
||||||
@ -148,9 +147,7 @@ bool initBoot() {
|
|||||||
TT_LOG_I(TAG, "initBoot()");
|
TT_LOG_I(TAG, "initBoot()");
|
||||||
|
|
||||||
axp2101 = std::make_shared<Axp2101>(I2C_NUM_0);
|
axp2101 = std::make_shared<Axp2101>(I2C_NUM_0);
|
||||||
tt::hal::registerDevice(axp2101);
|
|
||||||
aw9523 = std::make_shared<Aw9523>(I2C_NUM_0);
|
aw9523 = std::make_shared<Aw9523>(I2C_NUM_0);
|
||||||
tt::hal::registerDevice(aw9523);
|
|
||||||
|
|
||||||
return initPowerControl() && initGpioExpander();
|
return initPowerControl() && initGpioExpander();
|
||||||
}
|
}
|
||||||
@ -1,3 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Axp2101.h>
|
||||||
|
#include <Aw9523.h>
|
||||||
|
|
||||||
|
extern std::shared_ptr<Axp2101> axp2101;
|
||||||
|
extern std::shared_ptr<Aw9523> aw9523;
|
||||||
|
|
||||||
bool initBoot();
|
bool initBoot();
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
#include "M5stackCoreS3.h"
|
#include "M5stackCoreS3.h"
|
||||||
#include "InitBoot.h"
|
#include "InitBoot.h"
|
||||||
#include "hal/CoreS3Display.h"
|
#include "devices/Display.h"
|
||||||
#include "hal/CoreS3DisplayConstants.h"
|
#include "devices/SdCard.h"
|
||||||
#include "hal/CoreS3Power.h"
|
|
||||||
#include "hal/CoreS3SdCard.h"
|
|
||||||
|
|
||||||
|
#include <Axp2101Power.h>
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
#include <Tactility/hal/uart/Uart.h>
|
#include <Tactility/hal/uart/Uart.h>
|
||||||
|
|
||||||
@ -12,11 +11,19 @@
|
|||||||
|
|
||||||
using namespace tt::hal;
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
axp2101,
|
||||||
|
aw9523,
|
||||||
|
std::make_shared<Axp2101Power>(axp2101),
|
||||||
|
createSdCard(),
|
||||||
|
createDisplay()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const Configuration m5stack_cores3 = {
|
const Configuration m5stack_cores3 = {
|
||||||
.initBoot = initBoot,
|
.initBoot = initBoot,
|
||||||
.createDisplay = createDisplay,
|
.createDevices = createDevices,
|
||||||
.sdcard = createSdCard(),
|
|
||||||
.power = createPower,
|
|
||||||
.i2c = {
|
.i2c = {
|
||||||
i2c::Configuration {
|
i2c::Configuration {
|
||||||
.name = "Internal",
|
.name = "Internal",
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
#include "CoreS3Display.h"
|
#include "Display.h"
|
||||||
#include "CoreS3Constants.h"
|
|
||||||
|
|
||||||
|
#include <Axp2101.h>
|
||||||
#include <Ft5x06Touch.h>
|
#include <Ft5x06Touch.h>
|
||||||
#include <Ili934xDisplay.h>
|
#include <Ili934xDisplay.h>
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
#include <Tactility/hal/i2c/I2c.h>
|
#include <Tactility/hal/i2c/I2c.h>
|
||||||
|
|
||||||
constexpr auto TAG = "CoreS3Display";
|
constexpr auto* TAG = "CoreS3Display";
|
||||||
|
|
||||||
static void setBacklightDuty(uint8_t backlightDuty) {
|
static void setBacklightDuty(uint8_t backlightDuty) {
|
||||||
const uint8_t voltage = 20 + ((8 * backlightDuty) / 255); // [0b00000, 0b11100] - under 20 is too dark
|
const uint8_t voltage = 20 + ((8 * backlightDuty) / 255); // [0b00000, 0b11100] - under 20 is too dark
|
||||||
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
#define CORES3_LCD_SPI_HOST SPI3_HOST
|
#define CORES3_LCD_SPI_HOST SPI3_HOST
|
||||||
#define CORES3_LCD_PIN_CS GPIO_NUM_3
|
#define CORES3_LCD_PIN_CS GPIO_NUM_3
|
||||||
@ -8,3 +10,5 @@
|
|||||||
#define CORES3_LCD_VERTICAL_RESOLUTION 240
|
#define CORES3_LCD_VERTICAL_RESOLUTION 240
|
||||||
#define CORES3_LCD_DRAW_BUFFER_HEIGHT (CORES3_LCD_VERTICAL_RESOLUTION / 10)
|
#define CORES3_LCD_DRAW_BUFFER_HEIGHT (CORES3_LCD_VERTICAL_RESOLUTION / 10)
|
||||||
#define CORES3_LCD_DRAW_BUFFER_SIZE (CORES3_LCD_HORIZONTAL_RESOLUTION * CORES3_LCD_DRAW_BUFFER_HEIGHT)
|
#define CORES3_LCD_DRAW_BUFFER_SIZE (CORES3_LCD_HORIZONTAL_RESOLUTION * CORES3_LCD_DRAW_BUFFER_HEIGHT)
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
@ -1,10 +1,8 @@
|
|||||||
#include "CoreS3SdCard.h"
|
#include "SdCard.h"
|
||||||
|
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
|
|
||||||
#include <esp_vfs_fat.h>
|
|
||||||
|
|
||||||
constexpr auto CORES3_SDCARD_PIN_CS = GPIO_NUM_4;
|
constexpr auto CORES3_SDCARD_PIN_CS = GPIO_NUM_4;
|
||||||
constexpr auto CORES3_LCD_PIN_CS = GPIO_NUM_3;
|
constexpr auto CORES3_LCD_PIN_CS = GPIO_NUM_3;
|
||||||
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <Tactility/hal/display/DisplayDevice.h>
|
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
|
||||||
@ -3,7 +3,7 @@
|
|||||||
#include <Tactility/TactilityCore.h>
|
#include <Tactility/TactilityCore.h>
|
||||||
#include <esp_sleep.h>
|
#include <esp_sleep.h>
|
||||||
|
|
||||||
#define TAG "unphone"
|
constexpr auto* TAG = "unPhone";
|
||||||
|
|
||||||
std::shared_ptr<UnPhoneFeatures> unPhoneFeatures;
|
std::shared_ptr<UnPhoneFeatures> unPhoneFeatures;
|
||||||
static std::unique_ptr<tt::Thread> powerThread;
|
static std::unique_ptr<tt::Thread> powerThread;
|
||||||
@ -14,8 +14,6 @@ static const char* powerSleepKey = "power_sleep_key";
|
|||||||
|
|
||||||
class DeviceStats {
|
class DeviceStats {
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
tt::Preferences preferences = tt::Preferences("unphone");
|
tt::Preferences preferences = tt::Preferences("unphone");
|
||||||
|
|
||||||
int32_t getValue(const char* key) {
|
int32_t getValue(const char* key) {
|
||||||
@ -161,7 +159,6 @@ static bool unPhonePowerOn() {
|
|||||||
bootStats.notifyBootStart();
|
bootStats.notifyBootStart();
|
||||||
|
|
||||||
bq24295 = std::make_shared<Bq24295>(I2C_NUM_0);
|
bq24295 = std::make_shared<Bq24295>(I2C_NUM_0);
|
||||||
tt::hal::registerDevice(bq24295);
|
|
||||||
|
|
||||||
unPhoneFeatures = std::make_shared<UnPhoneFeatures>(bq24295);
|
unPhoneFeatures = std::make_shared<UnPhoneFeatures>(bq24295);
|
||||||
|
|
||||||
@ -185,7 +182,7 @@ static bool unPhonePowerOn() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unPhoneInitPower() {
|
bool initBoot() {
|
||||||
ESP_LOGI(TAG, LOG_MESSAGE_POWER_ON_START);
|
ESP_LOGI(TAG, LOG_MESSAGE_POWER_ON_START);
|
||||||
|
|
||||||
if (!unPhonePowerOn()) {
|
if (!unPhonePowerOn()) {
|
||||||
@ -1,20 +1,25 @@
|
|||||||
#include "Tactility/lvgl/LvglSync.h"
|
#include "Tactility/lvgl/LvglSync.h"
|
||||||
#include "UnPhoneFeatures.h"
|
#include "UnPhoneFeatures.h"
|
||||||
#include "Xpt2046Power.h"
|
#include "Xpt2046Power.h"
|
||||||
#include "hal/UnPhoneDisplay.h"
|
#include "devices/Hx8357Display.h"
|
||||||
#include "hal/UnPhoneDisplayConstants.h"
|
#include "devices/SdCard.h"
|
||||||
#include "hal/UnPhoneSdCard.h"
|
|
||||||
#include <Tactility/hal/Configuration.h>
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
|
||||||
#define UNPHONE_SPI_TRANSFER_SIZE_LIMIT (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_SPI_TRANSFER_HEIGHT * LV_COLOR_DEPTH / 8)
|
#define UNPHONE_SPI_TRANSFER_SIZE_LIMIT (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_SPI_TRANSFER_HEIGHT * LV_COLOR_DEPTH / 8)
|
||||||
|
|
||||||
bool unPhoneInitPower();
|
bool initBoot();
|
||||||
|
|
||||||
|
static tt::hal::DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
std::make_shared<Xpt2046Power>(),
|
||||||
|
createDisplay(),
|
||||||
|
createSdCard()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
extern const tt::hal::Configuration unPhone = {
|
extern const tt::hal::Configuration unPhone = {
|
||||||
.initBoot = unPhoneInitPower,
|
.initBoot = initBoot,
|
||||||
.createDisplay = createDisplay,
|
.createDevices = createDevices,
|
||||||
.sdcard = createUnPhoneSdCard(),
|
|
||||||
.power = getOrCreatePower,
|
|
||||||
.i2c = {
|
.i2c = {
|
||||||
tt::hal::i2c::Configuration {
|
tt::hal::i2c::Configuration {
|
||||||
.name = "Internal",
|
.name = "Internal",
|
||||||
|
|||||||
@ -1,20 +1,18 @@
|
|||||||
#include "UnPhoneDisplay.h"
|
#include "Hx8357Display.h"
|
||||||
#include "UnPhoneDisplayConstants.h"
|
#include "Touch.h"
|
||||||
#include "UnPhoneTouch.h"
|
|
||||||
#include "UnPhoneFeatures.h"
|
|
||||||
|
|
||||||
|
#include <UnPhoneFeatures.h>
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
#include <esp_err.h>
|
|
||||||
#include <hx8357/disp_spi.h>
|
#include <hx8357/disp_spi.h>
|
||||||
#include <hx8357/hx8357.h>
|
#include <hx8357/hx8357.h>
|
||||||
|
|
||||||
constexpr auto TAG = "UnPhoneDisplay";
|
constexpr auto TAG = "Hx8357Display";
|
||||||
constexpr auto BUFFER_SIZE = (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_DRAW_BUFFER_HEIGHT * LV_COLOR_DEPTH / 8);
|
constexpr auto BUFFER_SIZE = (UNPHONE_LCD_HORIZONTAL_RESOLUTION * UNPHONE_LCD_DRAW_BUFFER_HEIGHT * LV_COLOR_DEPTH / 8);
|
||||||
|
|
||||||
extern std::shared_ptr<UnPhoneFeatures> unPhoneFeatures;
|
extern std::shared_ptr<UnPhoneFeatures> unPhoneFeatures;
|
||||||
|
|
||||||
bool UnPhoneDisplay::start() {
|
bool Hx8357Display::start() {
|
||||||
TT_LOG_I(TAG, "start");
|
TT_LOG_I(TAG, "start");
|
||||||
|
|
||||||
disp_spi_add_device(SPI2_HOST);
|
disp_spi_add_device(SPI2_HOST);
|
||||||
@ -27,13 +25,13 @@ bool UnPhoneDisplay::start() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneDisplay::stop() {
|
bool Hx8357Display::stop() {
|
||||||
TT_LOG_I(TAG, "stop");
|
TT_LOG_I(TAG, "stop");
|
||||||
disp_spi_remove_device();
|
disp_spi_remove_device();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneDisplay::startLvgl() {
|
bool Hx8357Display::startLvgl() {
|
||||||
TT_LOG_I(TAG, "startLvgl");
|
TT_LOG_I(TAG, "startLvgl");
|
||||||
|
|
||||||
if (lvglDisplay != nullptr) {
|
if (lvglDisplay != nullptr) {
|
||||||
@ -74,7 +72,7 @@ bool UnPhoneDisplay::startLvgl() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneDisplay::stopLvgl() {
|
bool Hx8357Display::stopLvgl() {
|
||||||
TT_LOG_I(TAG, "stopLvgl");
|
TT_LOG_I(TAG, "stopLvgl");
|
||||||
|
|
||||||
if (lvglDisplay == nullptr) {
|
if (lvglDisplay == nullptr) {
|
||||||
@ -100,7 +98,7 @@ bool UnPhoneDisplay::stopLvgl() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable UnPhoneDisplay::getTouchDevice() {
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable Hx8357Display::getTouchDevice() {
|
||||||
if (touchDevice == nullptr) {
|
if (touchDevice == nullptr) {
|
||||||
touchDevice = std::reinterpret_pointer_cast<tt::hal::touch::TouchDevice>(createTouch());
|
touchDevice = std::reinterpret_pointer_cast<tt::hal::touch::TouchDevice>(createTouch());
|
||||||
TT_LOG_I(TAG, "Created touch device");
|
TT_LOG_I(TAG, "Created touch device");
|
||||||
@ -110,10 +108,10 @@ std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable UnPhoneDisplay::getTouchD
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
return std::make_shared<UnPhoneDisplay>();
|
return std::make_shared<Hx8357Display>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneDisplay::UnPhoneDisplayDriver::drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) {
|
bool Hx8357Display::Hx8357Driver::drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) {
|
||||||
lv_area_t area = { xStart, yStart, xEnd, yEnd };
|
lv_area_t area = { xStart, yStart, xEnd, yEnd };
|
||||||
hx8357_flush(nullptr, &area, (uint8_t*)pixelData);
|
hx8357_flush(nullptr, &area, (uint8_t*)pixelData);
|
||||||
return true;
|
return true;
|
||||||
@ -7,18 +7,26 @@
|
|||||||
#include <esp_lcd_types.h>
|
#include <esp_lcd_types.h>
|
||||||
#include <lvgl.h>
|
#include <lvgl.h>
|
||||||
|
|
||||||
#include "UnPhoneDisplayConstants.h"
|
|
||||||
|
|
||||||
#include <Tactility/hal/spi/Spi.h>
|
#include <Tactility/hal/spi/Spi.h>
|
||||||
|
|
||||||
class UnPhoneDisplay : public tt::hal::display::DisplayDevice {
|
#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)
|
||||||
|
|
||||||
|
class Hx8357Display : public tt::hal::display::DisplayDevice {
|
||||||
|
|
||||||
uint8_t* _Nullable buffer = nullptr;
|
uint8_t* _Nullable buffer = nullptr;
|
||||||
lv_display_t* _Nullable lvglDisplay = nullptr;
|
lv_display_t* _Nullable lvglDisplay = nullptr;
|
||||||
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable touchDevice;
|
std::shared_ptr<tt::hal::touch::TouchDevice> _Nullable touchDevice;
|
||||||
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable nativeDisplay;
|
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable nativeDisplay;
|
||||||
|
|
||||||
class UnPhoneDisplayDriver : public tt::hal::display::DisplayDriver {
|
class Hx8357Driver : public tt::hal::display::DisplayDriver {
|
||||||
std::shared_ptr<tt::Lock> lock = tt::hal::spi::getLock(SPI2_HOST);
|
std::shared_ptr<tt::Lock> lock = tt::hal::spi::getLock(SPI2_HOST);
|
||||||
public:
|
public:
|
||||||
tt::hal::display::ColorFormat getColorFormat() const override { return tt::hal::display::ColorFormat::RGB888; }
|
tt::hal::display::ColorFormat getColorFormat() const override { return tt::hal::display::ColorFormat::RGB888; }
|
||||||
@ -52,7 +60,7 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable getDisplayDriver() override {
|
std::shared_ptr<tt::hal::display::DisplayDriver> _Nullable getDisplayDriver() override {
|
||||||
if (nativeDisplay == nullptr) {
|
if (nativeDisplay == nullptr) {
|
||||||
nativeDisplay = std::make_shared<UnPhoneDisplayDriver>();
|
nativeDisplay = std::make_shared<Hx8357Driver>();
|
||||||
}
|
}
|
||||||
assert(nativeDisplay != nullptr);
|
assert(nativeDisplay != nullptr);
|
||||||
return nativeDisplay;
|
return nativeDisplay;
|
||||||
@ -1,10 +1,8 @@
|
|||||||
#include "UnPhoneSdCard.h"
|
#include "SdCard.h"
|
||||||
|
|
||||||
#include <Tactility/lvgl/LvglSync.h>
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
|
|
||||||
#include <esp_vfs_fat.h>
|
|
||||||
|
|
||||||
#define UNPHONE_SDCARD_PIN_CS GPIO_NUM_43
|
#define UNPHONE_SDCARD_PIN_CS GPIO_NUM_43
|
||||||
#define UNPHONE_LCD_PIN_CS GPIO_NUM_48
|
#define UNPHONE_LCD_PIN_CS GPIO_NUM_48
|
||||||
#define UNPHONE_LORA_PIN_CS GPIO_NUM_44
|
#define UNPHONE_LORA_PIN_CS GPIO_NUM_44
|
||||||
@ -12,7 +10,7 @@
|
|||||||
|
|
||||||
using tt::hal::sdcard::SpiSdCardDevice;
|
using tt::hal::sdcard::SpiSdCardDevice;
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createUnPhoneSdCard() {
|
std::shared_ptr<SdCardDevice> createSdCard() {
|
||||||
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
auto configuration = std::make_unique<SpiSdCardDevice::Config>(
|
||||||
UNPHONE_SDCARD_PIN_CS,
|
UNPHONE_SDCARD_PIN_CS,
|
||||||
GPIO_NUM_NC,
|
GPIO_NUM_NC,
|
||||||
@ -1,11 +1,10 @@
|
|||||||
#include "UnPhoneTouch.h"
|
#include "Touch.h"
|
||||||
#include "UnPhoneDisplayConstants.h"
|
|
||||||
|
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
|
|
||||||
std::shared_ptr<Xpt2046Touch> createTouch() {
|
std::shared_ptr<Xpt2046Touch> createTouch() {
|
||||||
auto configuration = std::make_unique<Xpt2046Touch::Configuration>(
|
auto configuration = std::make_unique<Xpt2046Touch::Configuration>(
|
||||||
UNPHONE_LCD_SPI_HOST,
|
SPI2_HOST,
|
||||||
GPIO_NUM_38,
|
GPIO_NUM_38,
|
||||||
320,
|
320,
|
||||||
480
|
480
|
||||||
@ -1,11 +0,0 @@
|
|||||||
#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)
|
|
||||||
@ -1,13 +1,19 @@
|
|||||||
#include "hal/WaveshareDisplay.h"
|
#include "devices/Display.h"
|
||||||
#include "hal/WaveshareSdCard.h"
|
#include "devices/SdCard.h"
|
||||||
|
|
||||||
#include <Tactility/hal/Configuration.h>
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
|
||||||
using namespace tt::hal;
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
createDisplay(),
|
||||||
|
createSdCard()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
extern const Configuration waveshare_s3_touch_43 = {
|
extern const Configuration waveshare_s3_touch_43 = {
|
||||||
.createDisplay = createDisplay,
|
.createDevices = createDevices,
|
||||||
.sdcard = createSdCard(),
|
|
||||||
.i2c = {
|
.i2c = {
|
||||||
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
|
// There is only 1 (internal for touch, and also serves as "I2C-OUT" port)
|
||||||
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
|
// Note: You could repurpose 1 or more UART interfaces as I2C interfaces
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "WaveshareDisplay.h"
|
#include "Display.h"
|
||||||
|
|
||||||
#include <Gt911Touch.h>
|
#include <Gt911Touch.h>
|
||||||
#include <RgbDisplay.h>
|
#include <RgbDisplay.h>
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "WaveshareSdCard.h"
|
#include "SdCard.h"
|
||||||
|
|
||||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||||
|
|
||||||
@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
using tt::hal::sdcard::SdCardDevice;
|
using tt::hal::sdcard::SdCardDevice;
|
||||||
|
|
||||||
std::shared_ptr<SdCardDevice> createUnPhoneSdCard();
|
std::shared_ptr<SdCardDevice> createSdCard();
|
||||||
@ -21,8 +21,8 @@ public:
|
|||||||
|
|
||||||
explicit Axp2101(i2c_port_t port) : I2cDevice(port, AXP2101_ADDRESS) {}
|
explicit Axp2101(i2c_port_t port) : I2cDevice(port, AXP2101_ADDRESS) {}
|
||||||
|
|
||||||
std::string getName() const final { return "AXP2101"; }
|
std::string getName() const override { return "AXP2101"; }
|
||||||
std::string getDescription() const final { return "Power management with I2C interface."; }
|
std::string getDescription() const override { return "Power management with I2C interface."; }
|
||||||
|
|
||||||
bool setRegisters(uint8_t* bytePairs, size_t bytePairsSize) const;
|
bool setRegisters(uint8_t* bytePairs, size_t bytePairsSize) const;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "CoreS3Power.h"
|
#include "Axp2101Power.h"
|
||||||
|
|
||||||
bool CoreS3Power::supportsMetric(MetricType type) const {
|
bool Axp2101Power::supportsMetric(MetricType type) const {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
using enum MetricType;
|
using enum MetricType;
|
||||||
case BatteryVoltage:
|
case BatteryVoltage:
|
||||||
@ -14,7 +14,7 @@ bool CoreS3Power::supportsMetric(MetricType type) const {
|
|||||||
return false; // Safety guard for when new enum values are introduced
|
return false; // Safety guard for when new enum values are introduced
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CoreS3Power::getMetric(MetricType type, MetricData& data) {
|
bool Axp2101Power::getMetric(MetricType type, MetricData& data) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
using enum MetricType;
|
using enum MetricType;
|
||||||
case BatteryVoltage: {
|
case BatteryVoltage: {
|
||||||
@ -57,7 +57,7 @@ bool CoreS3Power::getMetric(MetricType type, MetricData& data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CoreS3Power::isAllowedToCharge() const {
|
bool Axp2101Power::isAllowedToCharge() const {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
if (axpDevice->isChargingEnabled(enabled)) {
|
if (axpDevice->isChargingEnabled(enabled)) {
|
||||||
return enabled;
|
return enabled;
|
||||||
@ -66,17 +66,6 @@ bool CoreS3Power::isAllowedToCharge() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreS3Power::setAllowedToCharge(bool canCharge) {
|
void Axp2101Power::setAllowedToCharge(bool canCharge) {
|
||||||
axpDevice->setChargingEnabled(canCharge);
|
axpDevice->setChargingEnabled(canCharge);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<PowerDevice> power;
|
|
||||||
extern std::shared_ptr<Axp2101> axp2101;
|
|
||||||
|
|
||||||
std::shared_ptr<PowerDevice> createPower() {
|
|
||||||
if (power == nullptr) {
|
|
||||||
power = std::make_shared<CoreS3Power>(axp2101);
|
|
||||||
}
|
|
||||||
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
@ -7,17 +7,17 @@
|
|||||||
|
|
||||||
using tt::hal::power::PowerDevice;
|
using tt::hal::power::PowerDevice;
|
||||||
|
|
||||||
class CoreS3Power final : public PowerDevice {
|
class Axp2101Power final : public PowerDevice {
|
||||||
|
|
||||||
std::shared_ptr<Axp2101> axpDevice;
|
std::shared_ptr<Axp2101> axpDevice;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit CoreS3Power(std::shared_ptr<Axp2101> axp) : axpDevice(std::move(axp)) {}
|
explicit Axp2101Power(std::shared_ptr<Axp2101> axp) : axpDevice(std::move(axp)) {}
|
||||||
~CoreS3Power() override = default;
|
~Axp2101Power() override = default;
|
||||||
|
|
||||||
std::string getName() const final { return "AXP2101 Power"; }
|
std::string getName() const override { return "AXP2101 Power"; }
|
||||||
std::string getDescription() const final { return "Power management via I2C"; }
|
std::string getDescription() const override { return "Power management via AXP2101 over I2C"; }
|
||||||
|
|
||||||
bool supportsMetric(MetricType type) const override;
|
bool supportsMetric(MetricType type) const override;
|
||||||
bool getMetric(MetricType type, MetricData& data) override;
|
bool getMetric(MetricType type, MetricData& data) override;
|
||||||
@ -26,5 +26,3 @@ public:
|
|||||||
bool isAllowedToCharge() const override;
|
bool isAllowedToCharge() const override;
|
||||||
void setAllowedToCharge(bool canCharge) override;
|
void setAllowedToCharge(bool canCharge) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<PowerDevice> createPower();
|
|
||||||
@ -102,13 +102,3 @@ bool Xpt2046Power::readBatteryVoltageSampled(uint32_t& output) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<PowerDevice> power;
|
|
||||||
|
|
||||||
std::shared_ptr<PowerDevice> getOrCreatePower() {
|
|
||||||
if (power == nullptr) {
|
|
||||||
power = std::make_shared<Xpt2046Power>();
|
|
||||||
}
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -18,14 +18,11 @@ class Xpt2046Power : public PowerDevice {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
~Xpt2046Power() = default;
|
~Xpt2046Power() override = default;
|
||||||
|
|
||||||
std::string getName() const final { return "XPT2046 Power Measurement"; }
|
std::string getName() const final { return "XPT2046 Power Measurement"; }
|
||||||
std::string getDescription() const final { return "Power interface via XPT2046 voltage measurement"; }
|
std::string getDescription() const final { return "Power interface via XPT2046 voltage measurement"; }
|
||||||
|
|
||||||
bool supportsMetric(MetricType type) const override;
|
bool supportsMetric(MetricType type) const override;
|
||||||
bool getMetric(MetricType type, MetricData& data) override;
|
bool getMetric(MetricType type, MetricData& data) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<PowerDevice> getOrCreatePower();
|
|
||||||
|
|||||||
@ -5,9 +5,6 @@
|
|||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_lcd_touch_xpt2046.h>
|
#include <esp_lcd_touch_xpt2046.h>
|
||||||
#include <esp_lvgl_port.h>
|
|
||||||
|
|
||||||
Xpt2046Touch* Xpt2046Touch::instance = nullptr;
|
|
||||||
|
|
||||||
bool Xpt2046Touch::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
bool Xpt2046Touch::createIoHandle(esp_lcd_panel_io_handle_t& outHandle) {
|
||||||
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(configuration->spiPinCs);
|
const esp_lcd_panel_io_spi_config_t io_config = ESP_LCD_TOUCH_IO_SPI_XPT2046_CONFIG(configuration->spiPinCs);
|
||||||
|
|||||||
@ -39,8 +39,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static Xpt2046Touch* instance;
|
|
||||||
|
|
||||||
std::unique_ptr<Configuration> configuration;
|
std::unique_ptr<Configuration> configuration;
|
||||||
|
|
||||||
bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override;
|
bool createIoHandle(esp_lcd_panel_io_handle_t& outHandle) override;
|
||||||
|
|||||||
5
Drivers/XPT2046SoftSPI/CMakeLists.txt
Normal file
5
Drivers/XPT2046SoftSPI/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
idf_component_register(
|
||||||
|
SRC_DIRS "Source"
|
||||||
|
INCLUDE_DIRS "Source"
|
||||||
|
REQUIRES Tactility driver esp_lvgl_port
|
||||||
|
)
|
||||||
4
Drivers/XPT2046SoftSPI/README.md
Normal file
4
Drivers/XPT2046SoftSPI/README.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# XPT2046_SoftSPI Driver
|
||||||
|
|
||||||
|
XPT2046_SoftSPI is a driver for the XPT2046 resistive touchscreen controller that uses SoftSPI.
|
||||||
|
Inspiration from: https://github.com/ddxfish/XPT2046_Bitbang_Arduino_Library/
|
||||||
358
Drivers/XPT2046SoftSPI/Source/Xpt2046SoftSpi.cpp
Normal file
358
Drivers/XPT2046SoftSPI/Source/Xpt2046SoftSpi.cpp
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
#include "Xpt2046SoftSpi.h"
|
||||||
|
|
||||||
|
#include <Tactility/Log.h>
|
||||||
|
#include <Tactility/lvgl/LvglSync.h>
|
||||||
|
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_lvgl_port.h>
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <nvs.h>
|
||||||
|
#include <nvs_flash.h>
|
||||||
|
#include <rom/ets_sys.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "Xpt2046SoftSpi";
|
||||||
|
|
||||||
|
constexpr auto RERUN_CALIBRATE = false;
|
||||||
|
constexpr auto CMD_READ_Y = 0x90; // Try different commands if these don't work
|
||||||
|
constexpr auto CMD_READ_X = 0xD0; // Alternative: 0x98 for Y, 0xD8 for X
|
||||||
|
|
||||||
|
struct Calibration {
|
||||||
|
int xMin;
|
||||||
|
int xMax;
|
||||||
|
int yMin;
|
||||||
|
int yMax;
|
||||||
|
};
|
||||||
|
|
||||||
|
Calibration cal = {
|
||||||
|
.xMin = 100,
|
||||||
|
.xMax = 1900,
|
||||||
|
.yMin = 100,
|
||||||
|
.yMax = 1900
|
||||||
|
};
|
||||||
|
|
||||||
|
Xpt2046SoftSpi::Xpt2046SoftSpi(std::unique_ptr<Configuration> inConfiguration)
|
||||||
|
: configuration(std::move(inConfiguration)) {
|
||||||
|
assert(configuration != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defensive check for NVS, put here just in case NVS is init after touch setup.
|
||||||
|
static void ensureNvsInitialized() {
|
||||||
|
static bool initialized = false;
|
||||||
|
if (initialized) return;
|
||||||
|
|
||||||
|
esp_err_t result = nvs_flash_init();
|
||||||
|
if (result == ESP_ERR_NVS_NO_FREE_PAGES || result == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
nvs_flash_erase(); // ignore error for safety
|
||||||
|
result = nvs_flash_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized = (result == ESP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Xpt2046SoftSpi::startLvgl(lv_display_t* display) {
|
||||||
|
|
||||||
|
// Create LVGL input device
|
||||||
|
deviceHandle = lv_indev_create();
|
||||||
|
if (!deviceHandle) {
|
||||||
|
TT_LOG_E(TAG, "Failed to create LVGL input device");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_indev_set_type(deviceHandle, LV_INDEV_TYPE_POINTER);
|
||||||
|
lv_indev_set_read_cb(deviceHandle, touchReadCallback);
|
||||||
|
lv_indev_set_user_data(deviceHandle, this);
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Xpt2046SoftSpi touch driver started successfully");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Xpt2046SoftSpi::stop() {
|
||||||
|
TT_LOG_I(TAG, "Stopping Xpt2046SoftSpi touch driver");
|
||||||
|
|
||||||
|
// Stop LVLG if needed
|
||||||
|
if (deviceHandle != nullptr) {
|
||||||
|
stopLvgl();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Xpt2046SoftSpi::readSPI(uint8_t command) {
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
// Pull CS low for this transaction
|
||||||
|
gpio_set_level(configuration->csPin, 0);
|
||||||
|
ets_delay_us(1);
|
||||||
|
|
||||||
|
// Send 8-bit command
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
gpio_set_level(configuration->mosiPin, command & (1 << i));
|
||||||
|
gpio_set_level(configuration->clkPin, 1);
|
||||||
|
ets_delay_us(1);
|
||||||
|
gpio_set_level(configuration->clkPin, 0);
|
||||||
|
ets_delay_us(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 11; i >= 0; i--) {
|
||||||
|
gpio_set_level(configuration->clkPin, 1);
|
||||||
|
ets_delay_us(1);
|
||||||
|
if (gpio_get_level(configuration->misoPin)) {
|
||||||
|
result |= (1 << i);
|
||||||
|
}
|
||||||
|
gpio_set_level(configuration->clkPin, 0);
|
||||||
|
ets_delay_us(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull CS high for this transaction
|
||||||
|
gpio_set_level(configuration->csPin, 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xpt2046SoftSpi::calibrate() {
|
||||||
|
const int samples = 8; // More samples for better accuracy
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Calibration starting...");
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Touch TOP-LEFT corner");
|
||||||
|
|
||||||
|
while (!isTouched()) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
int sumX = 0, sumY = 0;
|
||||||
|
for (int i = 0; i < samples; i++) {
|
||||||
|
sumX += readSPI(CMD_READ_X);
|
||||||
|
sumY += readSPI(CMD_READ_Y);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
cal.xMin = sumX / samples;
|
||||||
|
cal.yMin = sumY / samples;
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Top-left calibrated: xMin=%d, yMin=%d", cal.xMin, cal.yMin);
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Touch BOTTOM-RIGHT corner");
|
||||||
|
|
||||||
|
while (!isTouched()) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
sumX = sumY = 0;
|
||||||
|
for (int i = 0; i < samples; i++) {
|
||||||
|
sumX += readSPI(CMD_READ_X);
|
||||||
|
sumY += readSPI(CMD_READ_Y);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
}
|
||||||
|
cal.xMax = sumX / samples;
|
||||||
|
cal.yMax = sumY / samples;
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Bottom-right calibrated: xMax=%d, yMax=%d", cal.xMax, cal.yMax);
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Calibration completed! xMin=%d, yMin=%d, xMax=%d, yMax=%d", cal.xMin, cal.yMin, cal.xMax, cal.yMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Xpt2046SoftSpi::loadCalibration() {
|
||||||
|
TT_LOG_W(TAG, "Calibration load disabled (using fresh calibration only).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xpt2046SoftSpi::saveCalibration() {
|
||||||
|
nvs_handle_t handle;
|
||||||
|
esp_err_t err = nvs_open("xpt2046", NVS_READWRITE, &handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "Failed to open NVS for writing (%s)", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nvs_set_blob(handle, "cal", &cal, sizeof(cal));
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
nvs_commit(handle);
|
||||||
|
TT_LOG_I(TAG, "Calibration saved to NVS");
|
||||||
|
} else {
|
||||||
|
TT_LOG_E(TAG, "Failed to write calibration data to NVS (%s)", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
nvs_close(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xpt2046SoftSpi::setCalibration(int xMin, int yMin, int xMax, int yMax) {
|
||||||
|
cal.xMin = xMin;
|
||||||
|
cal.yMin = yMin;
|
||||||
|
cal.xMax = xMax;
|
||||||
|
cal.yMax = yMax;
|
||||||
|
TT_LOG_I(TAG, "Manual calibration set: xMin=%d, yMin=%d, xMax=%d, yMax=%d", xMin, yMin, xMax, yMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point Xpt2046SoftSpi::getTouch() {
|
||||||
|
|
||||||
|
const int samples = 8; // More samples for better accuracy
|
||||||
|
int totalX = 0, totalY = 0;
|
||||||
|
int validSamples = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < samples; i++) {
|
||||||
|
int rawX = readSPI(CMD_READ_X);
|
||||||
|
int rawY = readSPI(CMD_READ_Y);
|
||||||
|
|
||||||
|
// Only use valid readings
|
||||||
|
if (rawX > 100 && rawX < 3900 && rawY > 100 && rawY < 3900) {
|
||||||
|
totalX += rawX;
|
||||||
|
totalY += rawY;
|
||||||
|
validSamples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validSamples == 0) {
|
||||||
|
return Point {0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
int rawX = totalX / validSamples;
|
||||||
|
int rawY = totalY / validSamples;
|
||||||
|
|
||||||
|
const int xRange = cal.xMax - cal.xMin;
|
||||||
|
const int yRange = cal.yMax - cal.yMin;
|
||||||
|
|
||||||
|
if (xRange <= 0 || yRange <= 0) {
|
||||||
|
TT_LOG_W(TAG, "Invalid calibration: xRange=%d, yRange=%d", xRange, yRange);
|
||||||
|
return Point {0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = (rawX - cal.xMin) * configuration->xMax / xRange;
|
||||||
|
int y = (rawY - cal.yMin) * configuration->yMax / yRange;
|
||||||
|
|
||||||
|
if (configuration->swapXy) std::swap(x, y);
|
||||||
|
if (configuration->mirrorX) x = configuration->xMax - x;
|
||||||
|
if (configuration->mirrorY) y = configuration->yMax - y;
|
||||||
|
|
||||||
|
x = std::clamp(x, 0, (int)configuration->xMax);
|
||||||
|
y = std::clamp(y, 0, (int)configuration->yMax);
|
||||||
|
|
||||||
|
return Point {x, y};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Xpt2046SoftSpi::isTouched() {
|
||||||
|
const int samples = 3;
|
||||||
|
int xTotal = 0, yTotal = 0;
|
||||||
|
int validSamples = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < samples; i++) {
|
||||||
|
int x = readSPI(CMD_READ_X);
|
||||||
|
int y = readSPI(CMD_READ_Y);
|
||||||
|
|
||||||
|
// Basic validity check - XPT2046 typically returns values in range 100-3900 when touched
|
||||||
|
if (x > 100 && x < 3900 && y > 100 && y < 3900) {
|
||||||
|
xTotal += x;
|
||||||
|
yTotal += y;
|
||||||
|
validSamples++;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1)); // Small delay between samples
|
||||||
|
}
|
||||||
|
gpio_set_level(configuration->csPin, 1);
|
||||||
|
|
||||||
|
// Consider touched if we got valid readings
|
||||||
|
bool touched = validSamples >= 2;
|
||||||
|
|
||||||
|
// Debug logging (remove this once working)
|
||||||
|
if (touched) {
|
||||||
|
TT_LOG_I(TAG, "Touch detected: validSamples=%d, avgX=%d, avgY=%d", validSamples, xTotal / validSamples, yTotal / validSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
return touched;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Xpt2046SoftSpi::touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
||||||
|
Xpt2046SoftSpi* touch = static_cast<Xpt2046SoftSpi*>(lv_indev_get_user_data(indev));
|
||||||
|
|
||||||
|
if (touch && touch->isTouched()) {
|
||||||
|
Point point = touch->getTouch();
|
||||||
|
data->point.x = point.x;
|
||||||
|
data->point.y = point.y;
|
||||||
|
data->state = LV_INDEV_STATE_PRESSED;
|
||||||
|
} else {
|
||||||
|
data->state = LV_INDEV_STATE_RELEASED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Xpt2046SoftSpi::start() {
|
||||||
|
ensureNvsInitialized();;
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "Starting Xpt2046SoftSpi touch driver");
|
||||||
|
|
||||||
|
// Configure GPIO pins
|
||||||
|
gpio_config_t io_conf = {};
|
||||||
|
|
||||||
|
// Configure MOSI, CLK, CS as outputs
|
||||||
|
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||||
|
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||||
|
io_conf.pin_bit_mask = (1ULL << configuration->mosiPin) |
|
||||||
|
(1ULL << configuration->clkPin) |
|
||||||
|
(1ULL << configuration->csPin);
|
||||||
|
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||||
|
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||||
|
|
||||||
|
if (gpio_config(&io_conf) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "Failed to configure output pins");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure MISO as input
|
||||||
|
io_conf.mode = GPIO_MODE_INPUT;
|
||||||
|
io_conf.pin_bit_mask = (1ULL << configuration->misoPin);
|
||||||
|
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||||
|
|
||||||
|
if (gpio_config(&io_conf) != ESP_OK) {
|
||||||
|
TT_LOG_E(TAG, "Failed to configure input pin");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize pin states
|
||||||
|
gpio_set_level(configuration->csPin, 1); // CS high
|
||||||
|
gpio_set_level(configuration->clkPin, 0); // CLK low
|
||||||
|
gpio_set_level(configuration->mosiPin, 0); // MOSI low
|
||||||
|
|
||||||
|
TT_LOG_I(TAG, "GPIO configured: MOSI=%d, MISO=%d, CLK=%d, CS=%d", configuration->mosiPin, configuration->misoPin, configuration->clkPin, configuration->csPin);
|
||||||
|
|
||||||
|
// Load or perform calibration
|
||||||
|
bool calibrationValid = true; //loadCalibration() && !RERUN_CALIBRATE;
|
||||||
|
if (calibrationValid) {
|
||||||
|
// Check if calibration values are valid (xMin != xMax, yMin != yMax)
|
||||||
|
if (cal.xMin == cal.xMax || cal.yMin == cal.yMax) {
|
||||||
|
TT_LOG_W(TAG, "Invalid calibration detected: xMin=%d, xMax=%d, yMin=%d, yMax=%d", cal.xMin, cal.xMax, cal.yMin, cal.yMax);
|
||||||
|
calibrationValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!calibrationValid) {
|
||||||
|
TT_LOG_W(TAG, "Calibration data not found, invalid, or forced recalibration");
|
||||||
|
calibrate();
|
||||||
|
saveCalibration();
|
||||||
|
} else {
|
||||||
|
TT_LOG_I(TAG, "Loaded calibration: xMin=%d, yMin=%d, xMax=%d, yMax=%d", cal.xMin, cal.yMin, cal.xMax, cal.yMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether this device supports LVGL
|
||||||
|
bool Xpt2046SoftSpi::supportsLvgl() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop LVGL
|
||||||
|
bool Xpt2046SoftSpi::stopLvgl() {
|
||||||
|
if (deviceHandle != nullptr) {
|
||||||
|
lv_indev_delete(deviceHandle);
|
||||||
|
deviceHandle = nullptr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return driver instance if any
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> Xpt2046SoftSpi::getTouchDriver() {
|
||||||
|
return nullptr; // replace with actual driver later
|
||||||
|
}
|
||||||
91
Drivers/XPT2046SoftSPI/Source/Xpt2046SoftSpi.h
Normal file
91
Drivers/XPT2046SoftSPI/Source/Xpt2046SoftSpi.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tactility/hal/touch/TouchDevice.h"
|
||||||
|
#include "Tactility/hal/touch/TouchDriver.h"
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef TFT_WIDTH
|
||||||
|
#define TFT_WIDTH 240
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TFT_HEIGHT
|
||||||
|
#define TFT_HEIGHT 320
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Point {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Xpt2046SoftSpi : public tt::hal::touch::TouchDevice {
|
||||||
|
public:
|
||||||
|
class Configuration {
|
||||||
|
public:
|
||||||
|
Configuration(
|
||||||
|
gpio_num_t mosiPin,
|
||||||
|
gpio_num_t misoPin,
|
||||||
|
gpio_num_t clkPin,
|
||||||
|
gpio_num_t csPin,
|
||||||
|
uint16_t xMax = TFT_WIDTH,
|
||||||
|
uint16_t yMax = TFT_HEIGHT,
|
||||||
|
bool swapXy = false,
|
||||||
|
bool mirrorX = false,
|
||||||
|
bool mirrorY = false
|
||||||
|
) : mosiPin(mosiPin),
|
||||||
|
misoPin(misoPin),
|
||||||
|
clkPin(clkPin),
|
||||||
|
csPin(csPin),
|
||||||
|
xMax(xMax),
|
||||||
|
yMax(yMax),
|
||||||
|
swapXy(swapXy),
|
||||||
|
mirrorX(mirrorX),
|
||||||
|
mirrorY(mirrorY)
|
||||||
|
{}
|
||||||
|
|
||||||
|
gpio_num_t mosiPin;
|
||||||
|
gpio_num_t misoPin;
|
||||||
|
gpio_num_t clkPin;
|
||||||
|
gpio_num_t csPin;
|
||||||
|
uint16_t xMax;
|
||||||
|
uint16_t yMax;
|
||||||
|
bool swapXy;
|
||||||
|
bool mirrorX;
|
||||||
|
bool mirrorY;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Configuration> configuration;
|
||||||
|
lv_indev_t* deviceHandle = nullptr;
|
||||||
|
|
||||||
|
int readSPI(uint8_t command);
|
||||||
|
bool loadCalibration();
|
||||||
|
void saveCalibration();
|
||||||
|
static void touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Xpt2046SoftSpi(std::unique_ptr<Configuration> inConfiguration);
|
||||||
|
|
||||||
|
// TouchDevice interface
|
||||||
|
std::string getName() const final { return "Xpt2046SoftSpi"; }
|
||||||
|
std::string getDescription() const final { return "Xpt2046 Soft SPI touch driver"; }
|
||||||
|
|
||||||
|
bool start() override;
|
||||||
|
bool stop() override;
|
||||||
|
|
||||||
|
bool supportsLvgl() const override;
|
||||||
|
bool startLvgl(lv_display_t* display) override;
|
||||||
|
bool stopLvgl() override;
|
||||||
|
|
||||||
|
bool supportsTouchDriver() override { return true; }
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDriver> getTouchDriver() override;
|
||||||
|
lv_indev_t* getLvglIndev() override { return deviceHandle; }
|
||||||
|
|
||||||
|
// XPT2046-specific methods
|
||||||
|
Point getTouch();
|
||||||
|
void calibrate();
|
||||||
|
void setCalibration(int xMin, int yMin, int xMax, int yMax);
|
||||||
|
bool isTouched();
|
||||||
|
};
|
||||||
@ -7,6 +7,8 @@
|
|||||||
#include "Tactility/hal/spi/SpiInit.h"
|
#include "Tactility/hal/spi/SpiInit.h"
|
||||||
#include "Tactility/hal/uart/UartInit.h"
|
#include "Tactility/hal/uart/UartInit.h"
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
#include <Tactility/hal/touch/TouchDevice.h>
|
||||||
#include <Tactility/kernel/SystemEvents.h>
|
#include <Tactility/kernel/SystemEvents.h>
|
||||||
|
|
||||||
namespace tt::hal {
|
namespace tt::hal {
|
||||||
@ -35,6 +37,16 @@ void registerDevices(const Configuration& configuration) {
|
|||||||
auto devices = configuration.createDevices();
|
auto devices = configuration.createDevices();
|
||||||
for (auto& device : devices) {
|
for (auto& device : devices) {
|
||||||
registerDevice(device);
|
registerDevice(device);
|
||||||
|
|
||||||
|
// Register attached devices
|
||||||
|
if (device->getType() == Device::Type::Display) {
|
||||||
|
const auto display = std::static_pointer_cast<display::DisplayDevice>(device);
|
||||||
|
assert(display != nullptr);
|
||||||
|
const std::shared_ptr<Device> touch = display->getTouchDevice();
|
||||||
|
if (touch != nullptr) {
|
||||||
|
registerDevice(touch);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user