Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a96307de2 |
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module btt_panda_touch_module = {
|
static error_t start() {
|
||||||
.name = "btt-panda-touch"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module btt_panda_touch_module = {
|
||||||
|
.name = "btt-panda-touch",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Module cyd_2432s024c_module = {
|
Module cyd_2432s024c_module = {
|
||||||
.name = "cyd-2432s024c",
|
.name = "cyd-2432s024c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_2432s024r_module = {
|
static error_t start() {
|
||||||
.name = "cyd-2432s024r"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_2432s024r_module = {
|
||||||
|
.name = "cyd-2432s024r",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_2432s028r_module = {
|
static error_t start() {
|
||||||
.name = "cyd-2432s028r"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_2432s028r_module = {
|
||||||
|
.name = "cyd-2432s028r",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_2432s028rv3_module = {
|
static error_t start() {
|
||||||
.name = "cyd-2432s028rv3"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_2432s028rv3_module = {
|
||||||
|
.name = "cyd-2432s028rv3",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_2432s032c_module = {
|
static error_t start() {
|
||||||
.name = "cyd-2432s032c"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_2432s032c_module = {
|
||||||
|
.name = "cyd-2432s032c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_3248s035c_module = {
|
static error_t start() {
|
||||||
.name = "cyd-3248s035c"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_3248s035c_module = {
|
||||||
|
.name = "cyd-3248s035c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_4848s040c_module = {
|
static error_t start() {
|
||||||
.name = "cyd-4848s040c"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_4848s040c_module = {
|
||||||
|
.name = "cyd-4848s040c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_8048s043c_module = {
|
static error_t start() {
|
||||||
.name = "cyd-8048s043c"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_8048s043c_module = {
|
||||||
|
.name = "cyd-8048s043c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_e32r28t_module = {
|
static error_t start() {
|
||||||
.name = "cyd-e32r28t"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_e32r28t_module = {
|
||||||
|
.name = "cyd-e32r28t",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module cyd_e32r32p_module = {
|
static error_t start() {
|
||||||
.name = "cyd-e32r32p"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module cyd_e32r32p_module = {
|
||||||
|
.name = "cyd-e32r32p",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,19 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module elecrow_crowpanel_advance_28_module = {
|
static error_t start() {
|
||||||
.name = "elecrow-crowpanel-advance-28"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module elecrow_crowpanel_advance_28_module = {
|
||||||
|
.name = "elecrow-crowpanel-advance-28",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Module elecrow_crowpanel_advance_35_module = {
|
Module elecrow_crowpanel_advance_35_module = {
|
||||||
.name = "elecrow-crowpanel-advance-35"
|
.name = "elecrow-crowpanel-advance-35",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,9 @@
|
|||||||
vsync-back-porch = <8>;
|
vsync-back-porch = <8>;
|
||||||
vsync-front-porch = <8>;
|
vsync-front-porch = <8>;
|
||||||
pclk-active-neg;
|
pclk-active-neg;
|
||||||
bounce-buffer-size-px = <4000>;
|
num-fbs = <2>;
|
||||||
|
double-fb;
|
||||||
|
bounce-buffer-size-px = <8000>;
|
||||||
pin-hsync = <&gpio0 40 GPIO_FLAG_NONE>;
|
pin-hsync = <&gpio0 40 GPIO_FLAG_NONE>;
|
||||||
pin-vsync = <&gpio0 41 GPIO_FLAG_NONE>;
|
pin-vsync = <&gpio0 41 GPIO_FLAG_NONE>;
|
||||||
pin-de = <&gpio0 42 GPIO_FLAG_NONE>;
|
pin-de = <&gpio0 42 GPIO_FLAG_NONE>;
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module elecrow_crowpanel_advance_50_module = {
|
static error_t start() {
|
||||||
.name = "elecrow-crowpanel-advance-50"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module elecrow_crowpanel_advance_50_module = {
|
||||||
|
.name = "elecrow-crowpanel-advance-50",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module elecrow_crowpanel_basic_28_module = {
|
static error_t start() {
|
||||||
.name = "elecrow-crowpanel-basic-28"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module elecrow_crowpanel_basic_28_module = {
|
||||||
|
.name = "elecrow-crowpanel-basic-28",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Module elecrow_crowpanel_basic_35_module = {
|
Module elecrow_crowpanel_basic_35_module = {
|
||||||
.name = "elecrow-crowpanel-basic-35"
|
.name = "elecrow-crowpanel-basic-35",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,9 @@
|
|||||||
vsync-back-porch = <12>;
|
vsync-back-porch = <12>;
|
||||||
vsync-front-porch = <8>;
|
vsync-front-porch = <8>;
|
||||||
pclk-active-neg;
|
pclk-active-neg;
|
||||||
bounce-buffer-size-px = <4000>;
|
num-fbs = <2>;
|
||||||
|
double-fb;
|
||||||
|
bounce-buffer-size-px = <8000>;
|
||||||
pin-hsync = <&gpio0 39 GPIO_FLAG_NONE>;
|
pin-hsync = <&gpio0 39 GPIO_FLAG_NONE>;
|
||||||
pin-vsync = <&gpio0 41 GPIO_FLAG_NONE>;
|
pin-vsync = <&gpio0 41 GPIO_FLAG_NONE>;
|
||||||
pin-de = <&gpio0 40 GPIO_FLAG_NONE>;
|
pin-de = <&gpio0 40 GPIO_FLAG_NONE>;
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module elecrow_crowpanel_basic_50_module = {
|
static error_t start() {
|
||||||
.name = "elecrow-crowpanel-basic-50"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module elecrow_crowpanel_basic_50_module = {
|
||||||
|
.name = "elecrow-crowpanel-basic-50",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
idf_component_register(
|
|
||||||
SRCS "source/module.cpp"
|
|
||||||
REQUIRES TactilityKernel
|
|
||||||
)
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- Platforms/platform-esp32
|
|
||||||
- Drivers/ili9341-module
|
|
||||||
- Drivers/ft5x06-module
|
|
||||||
- Drivers/es8311-module
|
|
||||||
- Drivers/audio-stream-module
|
|
||||||
dts: es3c28p.dts
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
/dts-v1/;
|
|
||||||
|
|
||||||
#include <tactility/bindings/root.h>
|
|
||||||
#include <tactility/bindings/esp32_adc_oneshot.h>
|
|
||||||
#include <tactility/bindings/esp32_ble.h>
|
|
||||||
#include <tactility/bindings/esp32_gpio.h>
|
|
||||||
#include <tactility/bindings/esp32_i2c.h>
|
|
||||||
#include <tactility/bindings/esp32_i2s.h>
|
|
||||||
#include <tactility/bindings/esp32_pwm_ledc.h>
|
|
||||||
#include <tactility/bindings/esp32_sdmmc.h>
|
|
||||||
#include <tactility/bindings/esp32_spi.h>
|
|
||||||
#include <tactility/bindings/esp32_wifi_pinned.h>
|
|
||||||
#include <tactility/bindings/battery_sense.h>
|
|
||||||
#include <tactility/bindings/gpio_hog.h>
|
|
||||||
#include <tactility/bindings/pwm_backlight.h>
|
|
||||||
#include <bindings/ili9341.h>
|
|
||||||
#include <bindings/ft5x06.h>
|
|
||||||
#include <bindings/es8311.h>
|
|
||||||
|
|
||||||
/ {
|
|
||||||
compatible = "root";
|
|
||||||
model = "LCDWIKI ES3C28P";
|
|
||||||
|
|
||||||
wifi0 {
|
|
||||||
compatible = "espressif,esp32-wifi-pinned";
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
|
|
||||||
ble0 {
|
|
||||||
compatible = "espressif,esp32-ble";
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio0 {
|
|
||||||
compatible = "espressif,esp32-gpio";
|
|
||||||
gpio-count = <49>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* FM8002E speaker amp enable, active-low on GPIO1 */
|
|
||||||
amp_enable {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&gpio0 1 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_OUTPUT_LOW>;
|
|
||||||
};
|
|
||||||
|
|
||||||
adc0 {
|
|
||||||
compatible = "espressif,esp32-adc-oneshot";
|
|
||||||
unit-id = <ADC_UNIT_1>;
|
|
||||||
clk-src = <ADC_RTC_CLK_SRC_DEFAULT>;
|
|
||||||
channels = <ADC_CHANNEL_8 ADC_ATTEN_DB_12 ADC_BITWIDTH_DEFAULT>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* BAT+ through 200K/200K divider into GPIO9 ADC1_CH8 */
|
|
||||||
battery-sense {
|
|
||||||
compatible = "battery-sense";
|
|
||||||
io-channel = <&adc0 0>;
|
|
||||||
reference-voltage-mv = <3300>;
|
|
||||||
multiplier = <2000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* i2s0 must be before i2c0 so codec can reference it */
|
|
||||||
i2s0 {
|
|
||||||
compatible = "espressif,esp32-i2s";
|
|
||||||
port = <I2S_NUM_0>;
|
|
||||||
pin-bclk = <&gpio0 5 GPIO_FLAG_NONE>;
|
|
||||||
pin-ws = <&gpio0 7 GPIO_FLAG_NONE>;
|
|
||||||
pin-data-out = <&gpio0 8 GPIO_FLAG_NONE>;
|
|
||||||
pin-data-in = <&gpio0 6 GPIO_FLAG_NONE>;
|
|
||||||
pin-mclk = <&gpio0 4 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c0 {
|
|
||||||
compatible = "espressif,esp32-i2c";
|
|
||||||
port = <I2C_NUM_0>;
|
|
||||||
clock-frequency = <100000>;
|
|
||||||
pin-sda = <&gpio0 16 GPIO_FLAG_NONE>;
|
|
||||||
pin-scl = <&gpio0 15 GPIO_FLAG_NONE>;
|
|
||||||
|
|
||||||
ft5x06@38 {
|
|
||||||
compatible = "focaltech,ft5x06";
|
|
||||||
reg = <0x38>;
|
|
||||||
x-max = <240>;
|
|
||||||
y-max = <320>;
|
|
||||||
swap-xy;
|
|
||||||
mirror-x;
|
|
||||||
pin-reset = <&gpio0 18 GPIO_FLAG_NONE>;
|
|
||||||
pin-interrupt = <&gpio0 17 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
es8311: es8311@18 {
|
|
||||||
compatible = "everest,es8311";
|
|
||||||
reg = <0x18>;
|
|
||||||
i2s = <&i2s0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
display_backlight_pwm {
|
|
||||||
compatible = "espressif,esp32-pwm-ledc";
|
|
||||||
pin = <&gpio0 45 GPIO_FLAG_NONE>;
|
|
||||||
period-ns = <500000>;
|
|
||||||
ledc-timer = <0>;
|
|
||||||
ledc-channel = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
display_backlight {
|
|
||||||
compatible = "pwm-backlight";
|
|
||||||
status = "disabled";
|
|
||||||
pwm = <&display_backlight_pwm>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spi0 {
|
|
||||||
compatible = "espressif,esp32-spi";
|
|
||||||
host = <SPI2_HOST>;
|
|
||||||
pin-mosi = <&gpio0 11 GPIO_FLAG_NONE>;
|
|
||||||
pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>;
|
|
||||||
cs-gpios = <&gpio0 10 GPIO_FLAG_NONE>;
|
|
||||||
|
|
||||||
display@0 {
|
|
||||||
compatible = "ilitek,ili9341";
|
|
||||||
horizontal-resolution = <320>;
|
|
||||||
vertical-resolution = <240>;
|
|
||||||
swap-xy;
|
|
||||||
invert-color;
|
|
||||||
bgr-order;
|
|
||||||
pixel-clock-hz = <40000000>;
|
|
||||||
pin-dc = <&gpio0 46 GPIO_FLAG_NONE>;
|
|
||||||
backlight = <&display_backlight>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sdmmc0 {
|
|
||||||
compatible = "espressif,esp32-sdmmc";
|
|
||||||
pin-clk = <&gpio0 38 GPIO_FLAG_NONE>;
|
|
||||||
pin-cmd = <&gpio0 40 GPIO_FLAG_NONE>;
|
|
||||||
pin-d0 = <&gpio0 39 GPIO_FLAG_NONE>;
|
|
||||||
pin-d1 = <&gpio0 41 GPIO_FLAG_NONE>;
|
|
||||||
pin-d2 = <&gpio0 48 GPIO_FLAG_NONE>;
|
|
||||||
pin-d3 = <&gpio0 47 GPIO_FLAG_NONE>;
|
|
||||||
slot = <SDMMC_HOST_SLOT_1>;
|
|
||||||
bus-width = <4>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#include <tactility/module.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
Module es3c28p_module = {
|
|
||||||
.name = "es3c28p"
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
idf_component_register(
|
|
||||||
SRCS "source/module.cpp"
|
|
||||||
REQUIRES TactilityKernel
|
|
||||||
)
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
general.vendor=LCDWIKI/Hosyond
|
|
||||||
general.name=ES3C35P
|
|
||||||
|
|
||||||
apps.launcherAppId=Launcher
|
|
||||||
|
|
||||||
hardware.target=ESP32S3
|
|
||||||
hardware.flashSize=16MB
|
|
||||||
hardware.spiRam=true
|
|
||||||
hardware.spiRamMode=OCT
|
|
||||||
hardware.spiRamSpeed=80M
|
|
||||||
hardware.esptoolFlashFreq=80M
|
|
||||||
hardware.tinyUsb=true
|
|
||||||
hardware.bluetooth=true
|
|
||||||
|
|
||||||
display.size=3.5"
|
|
||||||
display.shape=rectangle
|
|
||||||
display.dpi=165
|
|
||||||
|
|
||||||
lvgl.colorDepth=16
|
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- Platforms/platform-esp32
|
|
||||||
- Drivers/st77922-module
|
|
||||||
- Drivers/es8311-module
|
|
||||||
- Drivers/audio-stream-module
|
|
||||||
dts: es3c35p.dts
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
/dts-v1/;
|
|
||||||
|
|
||||||
#include <tactility/bindings/root.h>
|
|
||||||
#include <tactility/bindings/esp32_adc_oneshot.h>
|
|
||||||
#include <tactility/bindings/esp32_ble.h>
|
|
||||||
#include <tactility/bindings/esp32_gpio.h>
|
|
||||||
#include <tactility/bindings/esp32_i2c.h>
|
|
||||||
#include <tactility/bindings/esp32_i2s.h>
|
|
||||||
#include <tactility/bindings/esp32_pwm_ledc.h>
|
|
||||||
#include <tactility/bindings/esp32_sdmmc.h>
|
|
||||||
#include <tactility/bindings/esp32_spi.h>
|
|
||||||
#include <tactility/bindings/esp32_wifi_pinned.h>
|
|
||||||
#include <tactility/bindings/battery_sense.h>
|
|
||||||
#include <tactility/bindings/gpio_hog.h>
|
|
||||||
#include <tactility/bindings/pwm_backlight.h>
|
|
||||||
#include <bindings/st77922.h>
|
|
||||||
#include <bindings/st77922_touch.h>
|
|
||||||
#include <bindings/es8311.h>
|
|
||||||
|
|
||||||
/ {
|
|
||||||
compatible = "root";
|
|
||||||
model = "LCDWIKI/Hosyond ES3C35P";
|
|
||||||
|
|
||||||
wifi0 {
|
|
||||||
compatible = "espressif,esp32-wifi-pinned";
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
|
|
||||||
ble0 {
|
|
||||||
compatible = "espressif,esp32-ble";
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio0 {
|
|
||||||
compatible = "espressif,esp32-gpio";
|
|
||||||
gpio-count = <49>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* FM8002E speaker amplifier enable, active-low on GPIO1. */
|
|
||||||
amp_enable {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&gpio0 1 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_OUTPUT_LOW>;
|
|
||||||
};
|
|
||||||
|
|
||||||
adc0 {
|
|
||||||
compatible = "espressif,esp32-adc-oneshot";
|
|
||||||
unit-id = <ADC_UNIT_1>;
|
|
||||||
clk-src = <ADC_RTC_CLK_SRC_DEFAULT>;
|
|
||||||
channels = <ADC_CHANNEL_7 ADC_ATTEN_DB_12 ADC_BITWIDTH_DEFAULT>;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* BAT+ through a 200K/200K divider into GPIO8 / ADC1_CH7. */
|
|
||||||
battery-sense {
|
|
||||||
compatible = "battery-sense";
|
|
||||||
io-channel = <&adc0 0>;
|
|
||||||
reference-voltage-mv = <3300>;
|
|
||||||
multiplier = <2000>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2s0 {
|
|
||||||
compatible = "espressif,esp32-i2s";
|
|
||||||
port = <I2S_NUM_0>;
|
|
||||||
pin-bclk = <&gpio0 18 GPIO_FLAG_NONE>;
|
|
||||||
pin-ws = <&gpio0 21 GPIO_FLAG_NONE>;
|
|
||||||
pin-data-out = <&gpio0 15 GPIO_FLAG_NONE>;
|
|
||||||
pin-data-in = <&gpio0 16 GPIO_FLAG_NONE>;
|
|
||||||
pin-mclk = <&gpio0 17 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c0 {
|
|
||||||
compatible = "espressif,esp32-i2c";
|
|
||||||
port = <I2C_NUM_0>;
|
|
||||||
clock-frequency = <400000>;
|
|
||||||
pin-sda = <&gpio0 38 GPIO_FLAG_NONE>;
|
|
||||||
pin-scl = <&gpio0 39 GPIO_FLAG_NONE>;
|
|
||||||
|
|
||||||
touch@55 {
|
|
||||||
compatible = "sitronix,st77922-touch";
|
|
||||||
reg = <0x55>;
|
|
||||||
x-max = <320>;
|
|
||||||
y-max = <480>;
|
|
||||||
pin-reset = <&gpio0 48 GPIO_FLAG_NONE>;
|
|
||||||
pin-interrupt = <&gpio0 47 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
es8311: es8311@18 {
|
|
||||||
compatible = "everest,es8311";
|
|
||||||
reg = <0x18>;
|
|
||||||
i2s = <&i2s0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
display_backlight_pwm {
|
|
||||||
compatible = "espressif,esp32-pwm-ledc";
|
|
||||||
pin = <&gpio0 41 GPIO_FLAG_NONE>;
|
|
||||||
period-ns = <200000>;
|
|
||||||
ledc-timer = <0>;
|
|
||||||
ledc-channel = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
display_backlight {
|
|
||||||
compatible = "pwm-backlight";
|
|
||||||
status = "disabled";
|
|
||||||
pwm = <&display_backlight_pwm>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spi0 {
|
|
||||||
compatible = "espressif,esp32-spi";
|
|
||||||
host = <SPI2_HOST>;
|
|
||||||
pin-sclk = <&gpio0 12 GPIO_FLAG_NONE>;
|
|
||||||
pin-mosi = <&gpio0 11 GPIO_FLAG_NONE>;
|
|
||||||
pin-miso = <&gpio0 13 GPIO_FLAG_NONE>;
|
|
||||||
pin-wp = <&gpio0 14 GPIO_FLAG_NONE>;
|
|
||||||
pin-hd = <&gpio0 9 GPIO_FLAG_NONE>;
|
|
||||||
cs-gpios = <&gpio0 10 GPIO_FLAG_NONE>;
|
|
||||||
/* Accommodate the driver's 1/10-frame DMA staging transfers, matching
|
|
||||||
* the vendor LVGL port's full-frame refresh path. */
|
|
||||||
max-transfer-size = <65536>;
|
|
||||||
|
|
||||||
display@0 {
|
|
||||||
compatible = "sitronix,st77922";
|
|
||||||
horizontal-resolution = <320>;
|
|
||||||
vertical-resolution = <480>;
|
|
||||||
/* 80 MHz works in the vendor demo, but produces visible QSPI corruption on
|
|
||||||
* some modules/cables. The component's 40 MHz default is reliably clean. */
|
|
||||||
pixel-clock-hz = <40000000>;
|
|
||||||
backlight = <&display_backlight>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
sdmmc0 {
|
|
||||||
compatible = "espressif,esp32-sdmmc";
|
|
||||||
pin-clk = <&gpio0 5 GPIO_FLAG_NONE>;
|
|
||||||
pin-cmd = <&gpio0 4 GPIO_FLAG_NONE>;
|
|
||||||
pin-d0 = <&gpio0 6 GPIO_FLAG_NONE>;
|
|
||||||
pin-d1 = <&gpio0 7 GPIO_FLAG_NONE>;
|
|
||||||
pin-d2 = <&gpio0 2 GPIO_FLAG_NONE>;
|
|
||||||
pin-d3 = <&gpio0 3 GPIO_FLAG_NONE>;
|
|
||||||
slot = <SDMMC_HOST_SLOT_1>;
|
|
||||||
bus-width = <4>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#include <tactility/module.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
Module es3c35p_module = {
|
|
||||||
.name = "es3c35p"
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module generic_esp32_module = {
|
static error_t start() {
|
||||||
.name = "generic-esp32"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module generic_esp32_module = {
|
||||||
|
.name = "generic-esp32",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module generic_esp32c6_module = {
|
static error_t start() {
|
||||||
.name = "generic-esp32c6"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module generic_esp32c6_module = {
|
||||||
|
.name = "generic-esp32c6",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module generic_esp32p4_module = {
|
static error_t start() {
|
||||||
.name = "generic-esp32p4"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module generic_esp32p4_module = {
|
||||||
|
.name = "generic-esp32p4",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module generic_esp32s3_module = {
|
static error_t start() {
|
||||||
.name = "generic-esp32s3"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module generic_esp32s3_module = {
|
||||||
|
.name = "generic-esp32s3",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Module guition_jc1060p470ciwy_module = {
|
Module guition_jc1060p470ciwy_module = {
|
||||||
.name = "guition-jc1060p470ciwy"
|
.name = "guition-jc1060p470ciwy",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module guition_jc2432w328c_module = {
|
static error_t start() {
|
||||||
.name = "guition-jc2432w328c"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module guition_jc2432w328c_module = {
|
||||||
|
.name = "guition-jc2432w328c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module guition_jc8048w550c_module = {
|
static error_t start() {
|
||||||
.name = "guition-jc8048w550c"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module guition_jc8048w550c_module = {
|
||||||
|
.name = "guition-jc8048w550c",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,20 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module heltec_wifi_lora_32_v3_module = {
|
static error_t start() {
|
||||||
.name = "heltec-wifi-lora-32-v3"
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module heltec_wifi_lora_32_v3_module = {
|
||||||
|
.name = "heltec-wifi-lora-32-v3",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 TactilityKernel
|
REQUIRES Tactility GDEQ031T10 driver
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
general.vendor=LilyGO
|
general.vendor=LilyGO
|
||||||
general.name=T-Deck Max
|
general.name=T-Deck Max
|
||||||
# SD card support is not yet working, display driver is untested since refactoring; remove once it is functional.
|
# SD card support is not yet working; remove once it is functional.
|
||||||
general.incubating=true
|
general.incubating=true
|
||||||
|
|
||||||
apps.launcherAppId=Launcher
|
apps.launcherAppId=Launcher
|
||||||
@@ -18,17 +18,14 @@ hardware.bluetooth=true
|
|||||||
# Internal until the SD card is verified working on this board; switch to SD then.
|
# Internal until the SD card is verified working on this board; switch to SD then.
|
||||||
storage.userDataLocation=Internal
|
storage.userDataLocation=Internal
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
display.size=3.1"
|
display.size=3.1"
|
||||||
display.shape=rectangle
|
display.shape=rectangle
|
||||||
display.dpi=128
|
display.dpi=128
|
||||||
|
|
||||||
lvgl.colorDepth=8
|
# The GDEQ031T10 e-paper is monochrome, but its driver renders via
|
||||||
|
# LV_COLOR_FORMAT_I1 on its own display. The global LVGL color depth must stay
|
||||||
|
# at 16: esp_lvgl_port refuses to compile with LV_COLOR_DEPTH_1 set.
|
||||||
|
lvgl.colorDepth=16
|
||||||
# Monochrome theme: the default colour theme renders accent-coloured UI that
|
# Monochrome theme: the default colour theme renders accent-coloured UI that
|
||||||
# thresholds to invisible on a 1bpp panel (enables CONFIG_LV_USE_THEME_MONO).
|
# thresholds to invisible on a 1bpp panel (enables CONFIG_LV_USE_THEME_MONO).
|
||||||
lvgl.theme=Mono
|
lvgl.theme=Mono
|
||||||
|
|
||||||
cdn.warningMessage=Display not reliably working. Use at your own risk.
|
|
||||||
|
|
||||||
sdkconfig.CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME=0
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ dependencies:
|
|||||||
- Platforms/platform-esp32
|
- Platforms/platform-esp32
|
||||||
- Drivers/xl9555-module
|
- Drivers/xl9555-module
|
||||||
- Drivers/cst66xx-module
|
- Drivers/cst66xx-module
|
||||||
- Drivers/gdeq031t10-module
|
|
||||||
- Drivers/tca8418-module
|
- Drivers/tca8418-module
|
||||||
- Drivers/sy6970-module
|
- Drivers/sy6970-module
|
||||||
- Drivers/bq27220-module
|
- Drivers/bq27220-module
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include <tactility/bindings/pwm_backlight.h>
|
#include <tactility/bindings/pwm_backlight.h>
|
||||||
#include <bindings/xl9555.h>
|
#include <bindings/xl9555.h>
|
||||||
#include <bindings/cst66xx.h>
|
#include <bindings/cst66xx.h>
|
||||||
#include <bindings/gdeq031t10.h>
|
|
||||||
#include <bindings/tca8418.h>
|
#include <bindings/tca8418.h>
|
||||||
#include <bindings/sy6970.h>
|
#include <bindings/sy6970.h>
|
||||||
#include <bindings/bq27220.h>
|
#include <bindings/bq27220.h>
|
||||||
@@ -144,17 +143,6 @@
|
|||||||
// exceeds the default ~4 KB transfer limit. Raise the bus limit to fit it.
|
// exceeds the default ~4 KB transfer limit. Raise the bus limit to fit it.
|
||||||
max-transfer-size = <65536>;
|
max-transfer-size = <65536>;
|
||||||
|
|
||||||
display@0 {
|
|
||||||
compatible = "gooddisplay,gdeq031t10";
|
|
||||||
pin-dc = <&gpio0 35 GPIO_FLAG_NONE>;
|
|
||||||
pin-reset = <&gpio0 9 GPIO_FLAG_NONE>;
|
|
||||||
pin-busy = <&gpio0 37 GPIO_FLAG_NONE>;
|
|
||||||
clock-speed-hz = <10000000>;
|
|
||||||
// Default to a fast (~1s) refresh for the automatic ghost-clears so the
|
|
||||||
// full-screen flash they cause is as short as possible.
|
|
||||||
refresh-mode = <GDEQ031T10_REFRESH_FAST>;
|
|
||||||
};
|
|
||||||
|
|
||||||
sdcard@1 {
|
sdcard@1 {
|
||||||
compatible = "espressif,esp32-sdspi";
|
compatible = "espressif,esp32-sdspi";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include "devices/Display.h"
|
||||||
|
|
||||||
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
#include <tactility/check.h>
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/drivers/esp32_spi.h>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static bool initBoot() {
|
||||||
|
// The LoRa and SD chip-selects share the EPD's SPI bus but aren't wired up
|
||||||
|
// yet. spi0's start() already drives every cs-gpio high during kernel init;
|
||||||
|
// re-assert deselection before the EPD driver first transacts, as a cheap
|
||||||
|
// guard against either chip latching stray EPD command bytes (same pattern
|
||||||
|
// as the esp32_sdspi mount path).
|
||||||
|
auto* spi0 = device_find_by_name("spi0");
|
||||||
|
check(spi0 != nullptr);
|
||||||
|
esp32_spi_deselect_all_cs(spi0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
// Touch, keyboard and battery/charging are kernel drivers (cst66xx, tca8418, sy6970,
|
||||||
|
// bq27220 - see the .dts), started independently of this HAL layer. Only the EPD
|
||||||
|
// display remains on the deprecated HAL.
|
||||||
|
return DeviceVector {
|
||||||
|
createDisplay()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration hardwareConfiguration = {
|
||||||
|
.initBoot = initBoot,
|
||||||
|
.createDevices = createDevices
|
||||||
|
};
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include <Gdeq031t10Display.h>
|
||||||
|
|
||||||
|
// Pins from Xinyuan-LilyGO/T-Deck-MAX's lib/TDeckMaxBoard/src/TDeckMaxBoard.h and docs/pinmap.md.
|
||||||
|
constexpr auto EPD_SPI_HOST = SPI2_HOST;
|
||||||
|
constexpr auto EPD_PIN_CS = GPIO_NUM_34;
|
||||||
|
constexpr auto EPD_PIN_DC = GPIO_NUM_35;
|
||||||
|
constexpr auto EPD_PIN_RST = GPIO_NUM_9;
|
||||||
|
constexpr auto EPD_PIN_BUSY = GPIO_NUM_37;
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
|
// Touch is a kernel driver (hynitron,cst66xx - see the .dts), discovered and fed to LVGL
|
||||||
|
// independently of this display, so no touch device is passed into the configuration here.
|
||||||
|
auto configuration = std::make_unique<Gdeq031t10Display::Configuration>(
|
||||||
|
EPD_SPI_HOST,
|
||||||
|
EPD_PIN_CS,
|
||||||
|
EPD_PIN_DC,
|
||||||
|
EPD_PIN_RST,
|
||||||
|
EPD_PIN_BUSY,
|
||||||
|
nullptr,
|
||||||
|
10'000'000,
|
||||||
|
// Default to a fast (~1s) refresh for the automatic ghost-clears so the
|
||||||
|
// full-screen flash they cause is as short as possible.
|
||||||
|
Gdeq031t10Display::RefreshMode::Fast
|
||||||
|
);
|
||||||
|
|
||||||
|
return std::make_shared<Gdeq031t10Display>(std::move(configuration));
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
@@ -2,8 +2,22 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module lilygo_tdeck_max_module = {
|
static error_t start() {
|
||||||
.name = "lilygo-tdeck-max"
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module lilygo_tdeck_max_module = {
|
||||||
|
.name = "lilygo-tdeck-max",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ hardware.tinyUsb=true
|
|||||||
hardware.esptoolFlashFreq=120M
|
hardware.esptoolFlashFreq=120M
|
||||||
hardware.bluetooth=true
|
hardware.bluetooth=true
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
storage.userDataLocation=SD
|
||||||
|
|
||||||
display.size=2.8"
|
display.size=2.8"
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
constexpr auto* TAG = "tdeck-plus";
|
constexpr auto* TAG = "tdeck-plus";
|
||||||
|
|
||||||
|
// Legacy placeholder (required until legacy HAL is cleaned up everywhere)
|
||||||
|
extern const tt::hal::Configuration hardwareConfiguration = {};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void subscribe_events() {
|
void subscribe_events() {
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
file(GLOB_RECURSE SOURCE_FILES source/*.c*)
|
|
||||||
|
|
||||||
idf_component_register(
|
|
||||||
SRCS ${SOURCE_FILES}
|
|
||||||
INCLUDE_DIRS "source"
|
|
||||||
REQUIRES TactilityKernel
|
|
||||||
)
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
general.vendor=LilyGO
|
|
||||||
general.name=T-Deck Pro
|
|
||||||
# The display driver is not reliable yet
|
|
||||||
general.incubating=true
|
|
||||||
|
|
||||||
apps.launcherAppId=Launcher
|
|
||||||
|
|
||||||
hardware.target=ESP32S3
|
|
||||||
hardware.flashSize=16MB
|
|
||||||
hardware.flashMode=DIO
|
|
||||||
hardware.spiRam=true
|
|
||||||
hardware.spiRamMode=AUTO
|
|
||||||
hardware.spiRamSpeed=80M
|
|
||||||
hardware.tinyUsb=true
|
|
||||||
hardware.esptoolFlashFreq=80M
|
|
||||||
hardware.bluetooth=true
|
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
display.size=3.1"
|
|
||||||
display.shape=rectangle
|
|
||||||
display.dpi=128
|
|
||||||
|
|
||||||
lvgl.colorDepth=8
|
|
||||||
# Monochrome theme: the default colour theme renders accent-coloured UI that
|
|
||||||
# thresholds to invisible on a 1bpp panel (enables CONFIG_LV_USE_THEME_MONO).
|
|
||||||
lvgl.theme=Mono
|
|
||||||
|
|
||||||
cdn.warningMessage=Only for hardware revision 1.0! Display not reliably working. Use at your own risk.
|
|
||||||
|
|
||||||
sdkconfig.CONFIG_LV_THEME_DEFAULT_TRANSITION_TIME=0
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- Platforms/platform-esp32
|
|
||||||
- Drivers/cst328-module
|
|
||||||
- Drivers/gdeq031t10-module
|
|
||||||
- Drivers/tca8418-module
|
|
||||||
- Drivers/sy6970-module
|
|
||||||
- Drivers/bq25896-module
|
|
||||||
dts: lilygo,tdeck-pro.dts
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/dts-v1/;
|
|
||||||
|
|
||||||
#include <tactility/bindings/root.h>
|
|
||||||
#include <tactility/bindings/esp32_ble.h>
|
|
||||||
#include <tactility/bindings/esp32_wifi_pinned.h>
|
|
||||||
#include <tactility/bindings/esp32_gpio.h>
|
|
||||||
#include <tactility/bindings/esp32_i2c_master.h>
|
|
||||||
#include <tactility/bindings/esp32_spi.h>
|
|
||||||
#include <tactility/bindings/esp32_sdspi.h>
|
|
||||||
#include <tactility/bindings/esp32_pwm_ledc.h>
|
|
||||||
#include <tactility/bindings/pwm_backlight.h>
|
|
||||||
#include <bindings/cst328.h>
|
|
||||||
#include <bindings/gdeq031t10.h>
|
|
||||||
#include <bindings/tca8418.h>
|
|
||||||
#include <bindings/bq25896.h>
|
|
||||||
|
|
||||||
// Reference for V1.0 (not V1.1!): https://github.com/Xinyuan-LilyGO/T-Deck-Pro/tree/HD-V1-250326
|
|
||||||
// lib/TDeckMaxBoard/src/TDeckMaxBoard.h, docs/pinmap.md
|
|
||||||
/ {
|
|
||||||
compatible = "root";
|
|
||||||
model = "LilyGO T-Deck Pro";
|
|
||||||
|
|
||||||
wifi0 {
|
|
||||||
compatible = "espressif,esp32-wifi-pinned";
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
|
|
||||||
ble0 {
|
|
||||||
compatible = "espressif,esp32-ble";
|
|
||||||
};
|
|
||||||
|
|
||||||
gpio0 {
|
|
||||||
compatible = "espressif,esp32-gpio";
|
|
||||||
gpio-count = <49>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c0 {
|
|
||||||
compatible = "espressif,esp32-i2c-master";
|
|
||||||
port = <I2C_NUM_0>;
|
|
||||||
clock-frequency = <100000>;
|
|
||||||
pin-sda = <&gpio0 13 GPIO_FLAG_NONE>;
|
|
||||||
pin-scl = <&gpio0 14 GPIO_FLAG_NONE>;
|
|
||||||
|
|
||||||
touch {
|
|
||||||
compatible = "hynitron,cst328";
|
|
||||||
reg = <0x1A>;
|
|
||||||
pin-reset = <&gpio0 45 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TCA8418 4x10 matrix scanner. Keymaps are written in the vendor's row/column
|
|
||||||
// orientation (Xinyuan-LilyGO/T-Deck-MAX examples/factory/peri_keypad.cpp); the
|
|
||||||
// TCA8418 columns are wired in reverse of that order, hence reverse-columns.
|
|
||||||
// ALT (shift/uppercase) is row 2 col 0; SYM (symbol layer) is row 3 col 8.
|
|
||||||
keyboard {
|
|
||||||
compatible = "ti,tca8418";
|
|
||||||
reg = <0x34>;
|
|
||||||
rows = <4>;
|
|
||||||
columns = <10>;
|
|
||||||
reverse-columns;
|
|
||||||
keymap-lc = [
|
|
||||||
113 119 101 114 116 121 117 105 111 112 // q w e r t y u i o p
|
|
||||||
97 115 100 102 103 104 106 107 108 8 // a s d f g h j k l BACKSPACE
|
|
||||||
0 122 120 99 118 98 110 109 36 10 // z x c v b n m $ ENTER
|
|
||||||
0 0 0 0 0 11 48 32 0 9 // PREV 0 SPC NEXT
|
|
||||||
];
|
|
||||||
keymap-uc = [
|
|
||||||
81 87 69 82 84 89 85 73 79 80 // Q W E R T Y U I O P
|
|
||||||
65 83 68 70 71 72 74 75 76 8 // A S D F G H J K L BACKSPACE
|
|
||||||
0 90 88 67 86 66 78 77 36 10 // Z X C V B N M $ ENTER
|
|
||||||
0 0 0 0 0 11 48 32 0 9 // PREV 0 SPC NEXT
|
|
||||||
];
|
|
||||||
keymap-sy = [
|
|
||||||
49 50 51 52 53 54 55 56 57 48 // 1 2 3 4 5 6 7 8 9 0
|
|
||||||
64 35 43 45 42 47 40 41 95 8 // @ # + - * / ( ) _ BACKSPACE
|
|
||||||
0 33 63 59 58 39 34 44 46 10 // ! ? ; : ' " , . ENTER
|
|
||||||
0 0 0 0 0 11 48 32 0 9 // PREV 0 SPC NEXT
|
|
||||||
];
|
|
||||||
shift-row = <2>;
|
|
||||||
shift-col = <0>;
|
|
||||||
sym-row = <3>;
|
|
||||||
sym-col = <8>;
|
|
||||||
};
|
|
||||||
|
|
||||||
bq27220 {
|
|
||||||
compatible = "ti,bq25896";
|
|
||||||
reg = <0x6B>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Keyboard backlight (LED_PWM), GPIO42. The keypress-triggered flash/decay effect
|
|
||||||
// from the pre-migration driver isn't reproduced here - kernel drivers don't have a
|
|
||||||
// home for that kind of UI policy (same reasoning as the touch driver's dropped bezel
|
|
||||||
// keys). Off by default; app code can drive brightness via the generic pwm-backlight
|
|
||||||
// API if desired.
|
|
||||||
keyboard_backlight_pwm {
|
|
||||||
compatible = "espressif,esp32-pwm-ledc";
|
|
||||||
pin = <&gpio0 42 GPIO_FLAG_NONE>;
|
|
||||||
period-ns = <33333>;
|
|
||||||
ledc-timer = <0>;
|
|
||||||
ledc-channel = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
keyboard_backlight {
|
|
||||||
compatible = "pwm-backlight";
|
|
||||||
status = "disabled";
|
|
||||||
pwm = <&keyboard_backlight_pwm>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spi0 {
|
|
||||||
compatible = "espressif,esp32-spi";
|
|
||||||
host = <SPI2_HOST>;
|
|
||||||
cs-gpios = <&gpio0 34 GPIO_FLAG_NONE>, // 0: EPD display
|
|
||||||
<&gpio0 48 GPIO_FLAG_NONE>, // 1: SD card
|
|
||||||
<&gpio0 3 GPIO_FLAG_NONE>; // 2: LoRa radio (SX1262, not wired up yet)
|
|
||||||
pin-mosi = <&gpio0 33 GPIO_FLAG_NONE>;
|
|
||||||
pin-miso = <&gpio0 47 GPIO_FLAG_NONE>;
|
|
||||||
pin-sclk = <&gpio0 36 GPIO_FLAG_NONE>;
|
|
||||||
// The EPD pushes its whole 9600-byte framebuffer in one SPI write, which
|
|
||||||
// exceeds the default ~4 KB transfer limit. Raise the bus limit to fit it.
|
|
||||||
max-transfer-size = <65536>;
|
|
||||||
|
|
||||||
display@0 {
|
|
||||||
compatible = "gooddisplay,gdeq031t10";
|
|
||||||
pin-dc = <&gpio0 35 GPIO_FLAG_NONE>;
|
|
||||||
pin-busy = <&gpio0 37 GPIO_FLAG_NONE>;
|
|
||||||
clock-speed-hz = <10000000>;
|
|
||||||
// Default to a fast (~1s) refresh for the automatic ghost-clears so the
|
|
||||||
// full-screen flash they cause is as short as possible.
|
|
||||||
refresh-mode = <GDEQ031T10_REFRESH_FAST>;
|
|
||||||
};
|
|
||||||
|
|
||||||
sdcard@1 {
|
|
||||||
compatible = "espressif,esp32-sdspi";
|
|
||||||
status = "disabled";
|
|
||||||
frequency-khz = <20000>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#include <tactility/module.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
struct Module lilygo_tdeck_pro_module = {
|
|
||||||
.name = "lilygo-tdeck-pro"
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -12,8 +12,6 @@ hardware.tinyUsb=true
|
|||||||
hardware.esptoolFlashFreq=120M
|
hardware.esptoolFlashFreq=120M
|
||||||
hardware.bluetooth=true
|
hardware.bluetooth=true
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
storage.userDataLocation=SD
|
||||||
|
|
||||||
display.size=2.8"
|
display.size=2.8"
|
||||||
|
|||||||
@@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
constexpr auto* TAG = "tdeck";
|
constexpr auto* TAG = "tdeck";
|
||||||
|
|
||||||
|
// Legacy placeholder (required until legacy HAL is cleaned up everywhere)
|
||||||
|
extern const tt::hal::Configuration hardwareConfiguration = {};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void subscribe_events() {
|
void subscribe_events() {
|
||||||
@@ -60,7 +63,9 @@ static error_t stop() {
|
|||||||
Module lilygo_tdeck_module = {
|
Module lilygo_tdeck_module = {
|
||||||
.name = "lilygo-tdeck",
|
.name = "lilygo-tdeck",
|
||||||
.start = start,
|
.start = start,
|
||||||
.stop = stop
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,17 +30,16 @@ static error_t start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static error_t stop() {
|
static error_t stop() {
|
||||||
if (gpio_set_level(POWER_ON_PIN, 0) != ESP_OK) {
|
// Empty for now
|
||||||
return ERROR_RESOURCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Module lilygo_tdisplay_s3_module = {
|
struct Module lilygo_tdisplay_s3_module = {
|
||||||
.name = "lilygo-tdisplay-s3",
|
.name = "lilygo-tdisplay-s3",
|
||||||
.start = start,
|
.start = start,
|
||||||
.stop = stop
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,22 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module lilygo_tdisplay_module = {
|
static error_t start() {
|
||||||
.name = "lilygo-tdisplay"
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module lilygo_tdisplay_module = {
|
||||||
|
.name = "lilygo-tdisplay",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,22 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module lilygo_tdongle_s3_module = {
|
static error_t start() {
|
||||||
.name = "lilygo-tdongle-s3"
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module lilygo_tdongle_s3_module = {
|
||||||
|
.name = "lilygo-tdongle-s3",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,22 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module lilygo_thmi_module = {
|
static error_t start() {
|
||||||
.name = "lilygo-thmi"
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module lilygo_thmi_module = {
|
||||||
|
.name = "lilygo-thmi",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ hardware.tinyUsb=true
|
|||||||
hardware.esptoolFlashFreq=40M
|
hardware.esptoolFlashFreq=40M
|
||||||
hardware.bluetooth=true
|
hardware.bluetooth=true
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
storage.userDataLocation=SD
|
||||||
|
|
||||||
display.size=2.33"
|
display.size=2.33"
|
||||||
|
|||||||
@@ -15,15 +15,18 @@
|
|||||||
|
|
||||||
constexpr auto* TAG = "T-Lora Pager";
|
constexpr auto* TAG = "T-Lora Pager";
|
||||||
|
|
||||||
|
// Legacy placeholder (required until legacy HAL is cleaned up everywhere). All board
|
||||||
|
// peripherals are kernel drivers now (see the .dts): display (st7796), battery (bq27220),
|
||||||
|
// charger power-off (bq25896), haptics (drv2605), keyboard (tca8418) and the encoder wheel
|
||||||
|
// (lilygo,tpager-encoder, bound to LVGL below).
|
||||||
|
extern const tt::hal::Configuration hardwareConfiguration = {};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
tt::kernel::SystemEventSubscription event_subscription;
|
static void subscribe_events() {
|
||||||
|
|
||||||
static error_t start() {
|
|
||||||
|
|
||||||
LOG_I(TAG, LOG_MESSAGE_POWER_ON_START);
|
LOG_I(TAG, LOG_MESSAGE_POWER_ON_START);
|
||||||
|
|
||||||
event_subscription = tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](tt::kernel::SystemEvent) {
|
tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootSplash, [](tt::kernel::SystemEvent) {
|
||||||
// The kernel tpager_encoder device is already started by kernel_init(); this just
|
// The kernel tpager_encoder device is already started by kernel_init(); this just
|
||||||
// registers it as an LVGL input device, which requires LVGL to be up first.
|
// registers it as an LVGL input device, which requires LVGL to be up first.
|
||||||
lvgl_lock();
|
lvgl_lock();
|
||||||
@@ -47,18 +50,23 @@ static error_t start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
subscribe_events();
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static error_t stop() {
|
static error_t stop() {
|
||||||
tt::kernel::unsubscribeSystemEvent(event_subscription);
|
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Module lilygo_tlora_pager_module = {
|
struct Module lilygo_tlora_pager_module = {
|
||||||
.name = "lilygo-tlora-pager",
|
.name = "lilygo-tlora-pager",
|
||||||
.start = start,
|
.start = start,
|
||||||
.stop = stop
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,22 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module m5stack_cardputer_adv_module = {
|
static error_t start() {
|
||||||
.name = "m5stack-cardputer-adv"
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module m5stack_cardputer_adv_module = {
|
||||||
|
.name = "m5stack-cardputer-adv",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,22 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Module m5stack_cardputer_module = {
|
Module m5stack_cardputer_module = {
|
||||||
.name = "m5stack-cardputer"
|
.name = "m5stack-cardputer",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ file(GLOB_RECURSE SOURCE_FILES source/*.c*)
|
|||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS ${SOURCE_FILES}
|
SRCS ${SOURCE_FILES}
|
||||||
REQUIRES TactilityKernel
|
REQUIRES TactilityKernel axp192-module
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,5 +21,3 @@ display.dpi=200
|
|||||||
cdn.warningMessage=This board implementation concerns the original Core2 hardware and **not** the v1.1 variant
|
cdn.warningMessage=This board implementation concerns the original Core2 hardware and **not** the v1.1 variant
|
||||||
|
|
||||||
lvgl.colorDepth=16
|
lvgl.colorDepth=16
|
||||||
|
|
||||||
sdkconfig.CONFIG_CODEC_DUMMY_SUPPORT=y
|
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
- Platforms/platform-esp32
|
- Platforms/platform-esp32
|
||||||
- Drivers/audio-stream-module
|
|
||||||
- Drivers/pdm-mic-module
|
|
||||||
- Drivers/dummy-i2s-amp-module
|
|
||||||
- Drivers/mpu6886-module
|
- Drivers/mpu6886-module
|
||||||
- Drivers/bm8563-module
|
- Drivers/bm8563-module
|
||||||
- Drivers/axp192-module
|
- Drivers/axp192-module
|
||||||
- Drivers/ft5x06-module
|
- Drivers/ft6x36-module
|
||||||
- Drivers/ili9341-module
|
- Drivers/ili9341-module
|
||||||
dts: m5stack,core2.dts
|
dts: m5stack,core2.dts
|
||||||
|
|||||||
@@ -6,16 +6,14 @@
|
|||||||
#include <tactility/bindings/esp32_grove.h>
|
#include <tactility/bindings/esp32_grove.h>
|
||||||
#include <tactility/bindings/esp32_i2c.h>
|
#include <tactility/bindings/esp32_i2c.h>
|
||||||
#include <tactility/bindings/esp32_i2s.h>
|
#include <tactility/bindings/esp32_i2s.h>
|
||||||
#include <tactility/bindings/esp32_sdspi.h>
|
|
||||||
#include <tactility/bindings/esp32_spi.h>
|
#include <tactility/bindings/esp32_spi.h>
|
||||||
#include <tactility/bindings/esp32_uart.h>
|
#include <tactility/bindings/esp32_uart.h>
|
||||||
#include <bindings/mpu6886.h>
|
#include <bindings/mpu6886.h>
|
||||||
#include <bindings/bm8563.h>
|
#include <bindings/bm8563.h>
|
||||||
#include <bindings/axp192.h>
|
#include <bindings/axp192.h>
|
||||||
#include <bindings/ft5x06.h>
|
#include <bindings/ft6x36.h>
|
||||||
#include <bindings/ili9341.h>
|
#include <bindings/ili9341.h>
|
||||||
#include <bindings/dummy_i2s_amp.h>
|
#include <tactility/bindings/esp32_sdspi.h>
|
||||||
#include <bindings/pdm_mic.h>
|
|
||||||
|
|
||||||
// Reference: https://docs.m5stack.com/en/core/Core2
|
// Reference: https://docs.m5stack.com/en/core/Core2
|
||||||
/ {
|
/ {
|
||||||
@@ -52,23 +50,10 @@
|
|||||||
axp192 {
|
axp192 {
|
||||||
compatible = "x-powers,axp192";
|
compatible = "x-powers,axp192";
|
||||||
reg = <0x34>;
|
reg = <0x34>;
|
||||||
dcdc1-enable; // ESP32 + peripherals main 3V3 rail - must stay on
|
|
||||||
dcdc1-voltage = <3300>;
|
|
||||||
dcdc3-enable; // LCD backlight
|
|
||||||
dcdc3-voltage = <3300>;
|
|
||||||
ldo2-enable; // LCD logic + SD card
|
|
||||||
ldo2-voltage = <3300>;
|
|
||||||
// ldo3 (vibration motor) intentionally left disabled
|
|
||||||
exten-enable; // 5V boost (speaker amp etc.)
|
|
||||||
gpio1-pwm; // GPIO1 as PWM1 output, drives the notification LED
|
|
||||||
gpio1-pwm1-duty-cycle = <255>; // 255 = LED off
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// FT6x36 driver doesn't reliably work when power cycling,
|
|
||||||
// or when the driver was powering on with its own power supply (not USB-C).
|
|
||||||
// The driver would not find the device and init would fail.
|
|
||||||
touch {
|
touch {
|
||||||
compatible = "focaltech,ft5x06";
|
compatible = "focaltech,ft6x36";
|
||||||
reg = <0x38>;
|
reg = <0x38>;
|
||||||
x-max = <320>;
|
x-max = <320>;
|
||||||
y-max = <240>;
|
y-max = <240>;
|
||||||
@@ -111,6 +96,8 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NS4168: Speaker and microphone
|
||||||
|
// TODO: Init microphone via I2C: https://github.com/m5stack/M5Unified/blob/a6256725481f1bc366655fa48cf03b6095e30ad1/src/M5Unified.cpp#L391C19-L391C44
|
||||||
i2s0 {
|
i2s0 {
|
||||||
compatible = "espressif,esp32-i2s";
|
compatible = "espressif,esp32-i2s";
|
||||||
port = <I2S_NUM_0>;
|
port = <I2S_NUM_0>;
|
||||||
@@ -119,15 +106,4 @@
|
|||||||
pin-data-out = <&gpio0 2 GPIO_FLAG_NONE>;
|
pin-data-out = <&gpio0 2 GPIO_FLAG_NONE>;
|
||||||
pin-data-in = <&gpio0 34 GPIO_FLAG_NONE>;
|
pin-data-in = <&gpio0 34 GPIO_FLAG_NONE>;
|
||||||
};
|
};
|
||||||
|
|
||||||
speaker0 {
|
|
||||||
compatible = "nsiway,ns4168";
|
|
||||||
i2s = <&i2s0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
mic0 {
|
|
||||||
compatible = "generic,spm1423";
|
|
||||||
i2s = <&i2s0>;
|
|
||||||
channels = <1>;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,49 @@
|
|||||||
|
#include <drivers/axp192.h>
|
||||||
|
|
||||||
|
#include <tactility/check.h>
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/device_listener.h>
|
||||||
#include <tactility/module.h>
|
#include <tactility/module.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
// AXP192 rail/GPIO1 bring-up is now devicetree-configured (see m5stack,core2.dts's axp192 node
|
static void configure_axp192(Device* axp192) {
|
||||||
// and axp192-module's start()), replacing what used to be done by hand here via a
|
check(axp192_set_rail_voltage(axp192, AXP192_RAIL_LDO2, 3300) == ERROR_NONE); // LCD + SD
|
||||||
// DEVICE_EVENT_STARTED device_listener.
|
check(axp192_set_rail_voltage(axp192, AXP192_RAIL_DCDC3, 3300) == ERROR_NONE); // LCD backlight
|
||||||
Module m5stack_core2_module = {
|
|
||||||
.name = "m5stack-core2"
|
check(axp192_set_rail_enabled(axp192, AXP192_RAIL_LDO2, true) == ERROR_NONE);
|
||||||
|
check(axp192_set_rail_enabled(axp192, AXP192_RAIL_LDO3, false) == ERROR_NONE); // VIB_MOTOR stop
|
||||||
|
check(axp192_set_rail_enabled(axp192, AXP192_RAIL_DCDC3, true) == ERROR_NONE);
|
||||||
|
|
||||||
|
check(axp192_set_pwm1_duty_cycle(axp192, 255) == ERROR_NONE); // PWM 255 (LED off)
|
||||||
|
check(axp192_set_gpio1_pwm1_output(axp192) == ERROR_NONE); // GPIO1: PWM
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_device_event(Device* device, DeviceEvent event, void* context) {
|
||||||
|
(void)context;
|
||||||
|
if (event == DEVICE_EVENT_STARTED && strcmp(device->name, "axp192") == 0) {
|
||||||
|
configure_axp192(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
device_listener_add(on_device_event, nullptr);
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
device_listener_remove(on_device_event);
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module m5stack_core2_module = {
|
||||||
|
.name = "m5stack-core2",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
- Platforms/platform-esp32
|
- Platforms/platform-esp32
|
||||||
- Drivers/audio-stream-module
|
|
||||||
- Drivers/aw88298-module
|
|
||||||
- Drivers/aw9523b-module
|
|
||||||
- Drivers/axp2101-module
|
|
||||||
- Drivers/bm8563-module
|
|
||||||
- Drivers/bmi270-module
|
- Drivers/bmi270-module
|
||||||
- Drivers/es7210-module
|
- Drivers/bm8563-module
|
||||||
|
- Drivers/axp2101-module
|
||||||
|
- Drivers/aw9523b-module
|
||||||
- Drivers/ft5x06-module
|
- Drivers/ft5x06-module
|
||||||
- Drivers/ili9341-module
|
- Drivers/ili9341-module
|
||||||
dts: m5stack,cores3.dts
|
dts: m5stack,cores3.dts
|
||||||
|
|||||||
@@ -9,16 +9,15 @@
|
|||||||
#include <tactility/bindings/esp32_i2s.h>
|
#include <tactility/bindings/esp32_i2s.h>
|
||||||
#include <tactility/bindings/esp32_spi.h>
|
#include <tactility/bindings/esp32_spi.h>
|
||||||
#include <tactility/bindings/esp32_uart.h>
|
#include <tactility/bindings/esp32_uart.h>
|
||||||
#include <tactility/bindings/gpio_hog.h>
|
|
||||||
#include <bindings/aw88298.h>
|
|
||||||
#include <bindings/aw9523b.h>
|
|
||||||
#include <bindings/axp2101.h>
|
|
||||||
#include <bindings/axp2101_backlight.h>
|
|
||||||
#include <bindings/bmi270.h>
|
#include <bindings/bmi270.h>
|
||||||
#include <bindings/bm8563.h>
|
#include <bindings/bm8563.h>
|
||||||
#include <bindings/es7210.h>
|
#include <bindings/axp2101.h>
|
||||||
|
#include <bindings/axp2101_backlight.h>
|
||||||
|
#include <bindings/aw9523b.h>
|
||||||
#include <bindings/ft5x06.h>
|
#include <bindings/ft5x06.h>
|
||||||
#include <bindings/ili9341.h>
|
#include <bindings/ili9341.h>
|
||||||
|
#include <tactility/bindings/esp32_sdspi.h>
|
||||||
|
#include <tactility/bindings/gpio_hog.h>
|
||||||
|
|
||||||
// SD card is not supported because of a hardware problem:
|
// SD card is not supported because of a hardware problem:
|
||||||
// The display uses pin 35 as input (MISO), but the SPI bus (and SD card) uses the same pin as DC (output).
|
// The display uses pin 35 as input (MISO), but the SPI bus (and SD card) uses the same pin as DC (output).
|
||||||
@@ -43,18 +42,6 @@
|
|||||||
gpio-count = <49>;
|
gpio-count = <49>;
|
||||||
};
|
};
|
||||||
|
|
||||||
i2s0 {
|
|
||||||
// Note: M5Unified sets the following for speaker: magnification = 2, oversampling = 1
|
|
||||||
// Note: M5Unified sets the following for microphone: magnification = 4
|
|
||||||
compatible = "espressif,esp32-i2s";
|
|
||||||
port = <I2S_NUM_0>;
|
|
||||||
pin-bclk = <&gpio0 34 GPIO_FLAG_NONE>;
|
|
||||||
pin-ws = <&gpio0 33 GPIO_FLAG_NONE>;
|
|
||||||
pin-data-out = <&gpio0 13 GPIO_FLAG_NONE>;
|
|
||||||
pin-data-in = <&gpio0 14 GPIO_FLAG_NONE>;
|
|
||||||
pin-mclk = <&gpio0 0 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
i2c_internal {
|
i2c_internal {
|
||||||
compatible = "espressif,esp32-i2c";
|
compatible = "espressif,esp32-i2c";
|
||||||
port = <I2C_NUM_0>;
|
port = <I2C_NUM_0>;
|
||||||
@@ -74,55 +61,18 @@
|
|||||||
|
|
||||||
// P0_0 = touch reset, P0_1 = bus-out enable, P0_2 = AW88298 reset,
|
// P0_0 = touch reset, P0_1 = bus-out enable, P0_2 = AW88298 reset,
|
||||||
// P0_4 = SD card switch, P1_1 = LCD reset, P1_7 = boost enable (SY7088)
|
// P0_4 = SD card switch, P1_1 = LCD reset, P1_7 = boost enable (SY7088)
|
||||||
aw9523b {
|
aw9523b: aw9523b {
|
||||||
compatible = "awinic,aw9523b";
|
compatible = "awinic,aw9523b";
|
||||||
reg = <0x58>;
|
reg = <0x58>;
|
||||||
|
|
||||||
// Bus-out enable, AW88298 (audio amp) reset, SD card power switch and boost enable
|
|
||||||
// (SY7088) are AW9523B pins with no owning peripheral driver yet.
|
|
||||||
aw9523_bus_out_enable {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&aw9523b 1 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
|
||||||
};
|
|
||||||
|
|
||||||
aw9523_sdcard_switch {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&aw9523b 4 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_INPUT>;
|
|
||||||
};
|
|
||||||
|
|
||||||
aw9523_boost_enable {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&aw9523b 15 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
aw88298 {
|
|
||||||
compatible = "awinic,aw88298";
|
|
||||||
reg = <0x36>;
|
|
||||||
i2s = <&i2s0>;
|
|
||||||
pin-reset = <&aw9523b 2 GPIO_FLAG_NONE>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
axp2101: axp2101 {
|
axp2101: axp2101 {
|
||||||
compatible = "x-powers,axp2101";
|
compatible = "x-powers,axp2101";
|
||||||
reg = <0x34>;
|
reg = <0x34>;
|
||||||
aldo1-millivolt = <1800>;
|
|
||||||
aldo1-enabled;
|
|
||||||
aldo2-millivolt = <3300>;
|
|
||||||
aldo2-enabled;
|
|
||||||
aldo3-millivolt = <3300>;
|
|
||||||
aldo3-enabled;
|
|
||||||
aldo4-millivolt = <3300>;
|
|
||||||
aldo4-enabled;
|
|
||||||
bldo1-enabled;
|
|
||||||
bldo2-enabled;
|
|
||||||
|
|
||||||
// LCD backlight (DLDO1). Raw register codes [20,28] map to [2500,3300]mV;
|
// LCD backlight (DLDO1). Raw register codes [20,28] map to [2500,3300]mV;
|
||||||
// below 2500mV the backlight was considered "too dark" to be useful.
|
// below 2500mV the backlight was considered "too dark" to be useful.
|
||||||
display_backlight {
|
backlight {
|
||||||
compatible = "axp2101-backlight";
|
compatible = "axp2101-backlight";
|
||||||
ldo = <AXP2101_DLDO1>;
|
ldo = <AXP2101_DLDO1>;
|
||||||
min-millivolt = <2500>;
|
min-millivolt = <2500>;
|
||||||
@@ -137,21 +87,32 @@
|
|||||||
y-max = <240>;
|
y-max = <240>;
|
||||||
pin-reset = <&aw9523b 0 GPIO_FLAG_NONE>;
|
pin-reset = <&aw9523b 0 GPIO_FLAG_NONE>;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
es7210 {
|
// Bus-out enable, AW88298 (audio amp) reset, SD card power switch and boost enable
|
||||||
compatible = "everest,es7210";
|
// (SY7088) are AW9523B pins with no owning peripheral driver yet.
|
||||||
reg = <0x40>;
|
aw9523_bus_out_enable {
|
||||||
i2s = <&i2s0>;
|
compatible = "gpio-hog";
|
||||||
// Only MIC1/MIC2 are wired to real capsules (see schematic); MIC3/MIC4
|
pin = <&aw9523b 1 GPIO_FLAG_NONE>;
|
||||||
// slots carry AEC_P/AEC_N reference signal, not microphone audio.
|
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
||||||
mic-mask = <3>;
|
};
|
||||||
// M5Unified applies a 4x post-gain "magnification" for this exact mic
|
|
||||||
// wiring (see M5Unified.cpp _mic_data_cb_cores3): the ES7210's own
|
aw9523_aw88298_reset {
|
||||||
// hardware ADC gain (already near-max via the default 90% input volume
|
compatible = "gpio-hog";
|
||||||
// setting, ~34dB of its 0-37.5dB range) still isn't enough for these
|
pin = <&aw9523b 2 GPIO_FLAG_NONE>;
|
||||||
// capsules on their own.
|
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
||||||
input-gain-percent = <400>;
|
};
|
||||||
};
|
|
||||||
|
aw9523_sdcard_switch {
|
||||||
|
compatible = "gpio-hog";
|
||||||
|
pin = <&aw9523b 4 GPIO_FLAG_NONE>;
|
||||||
|
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
||||||
|
};
|
||||||
|
|
||||||
|
aw9523_boost_enable {
|
||||||
|
compatible = "gpio-hog";
|
||||||
|
pin = <&aw9523b 15 GPIO_FLAG_NONE>;
|
||||||
|
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
||||||
port_a: grove0 {
|
port_a: grove0 {
|
||||||
@@ -202,7 +163,20 @@
|
|||||||
pixel-clock-hz = <40000000>;
|
pixel-clock-hz = <40000000>;
|
||||||
pin-dc = <&gpio0 35 GPIO_FLAG_NONE>;
|
pin-dc = <&gpio0 35 GPIO_FLAG_NONE>;
|
||||||
pin-reset = <&aw9523b 9 GPIO_FLAG_NONE>;
|
pin-reset = <&aw9523b 9 GPIO_FLAG_NONE>;
|
||||||
backlight = <&display_backlight>;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Enable speaker via ES7210 I2C: https://github.com/m5stack/M5Unified/blob/a6256725481f1bc366655fa48cf03b6095e30ad1/src/M5Unified.cpp#L417
|
||||||
|
// TODO: Enable microphone via ES7210 I2C: https://github.com/m5stack/M5Unified/blob/a6256725481f1bc366655fa48cf03b6095e30ad1/src/M5Unified.cpp#L616
|
||||||
|
i2s0 {
|
||||||
|
// Note: M5Unified sets the following for speaker: magnification = 2, oversampling = 1
|
||||||
|
// Note: M5Unified sets the following for microphone: magnification = 4
|
||||||
|
compatible = "espressif,esp32-i2s";
|
||||||
|
port = <I2S_NUM_0>;
|
||||||
|
pin-bclk = <&gpio0 34 GPIO_FLAG_NONE>;
|
||||||
|
pin-ws = <&gpio0 33 GPIO_FLAG_NONE>;
|
||||||
|
pin-data-out = <&gpio0 13 GPIO_FLAG_NONE>;
|
||||||
|
pin-data-in = <&gpio0 14 GPIO_FLAG_NONE>;
|
||||||
|
pin-mclk = <&gpio0 0 GPIO_FLAG_NONE>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,55 @@
|
|||||||
|
#include <drivers/axp2101.h>
|
||||||
|
|
||||||
|
#include <tactility/check.h>
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/device_listener.h>
|
||||||
#include <tactility/module.h>
|
#include <tactility/module.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
Module m5stack_cores3_module = {
|
// M5Stack CoreS3 AXP2101 rail setup, ported from the board's old deprecated-HAL
|
||||||
.name = "m5stack-cores3"
|
// initPowerControl() (source: M5Unified's Power_Class.cpp). ALDO1 powers the AW88298 audio
|
||||||
|
// amp, ALDO2 the ES7210 microphone ADC, ALDO3 the GC0308 camera, ALDO4 the TF/SD card slot.
|
||||||
|
// DLDO1 (LCD backlight) is left to the axp2101-backlight child device.
|
||||||
|
static void configure_axp2101(Device* axp2101) {
|
||||||
|
check(axp2101_set_ldo_voltage(axp2101, AXP2101_ALDO1, 1800) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_voltage(axp2101, AXP2101_ALDO2, 3300) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_voltage(axp2101, AXP2101_ALDO3, 3300) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_voltage(axp2101, AXP2101_ALDO4, 3300) == ERROR_NONE);
|
||||||
|
|
||||||
|
check(axp2101_set_ldo_enabled(axp2101, AXP2101_ALDO1, true) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_enabled(axp2101, AXP2101_ALDO2, true) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_enabled(axp2101, AXP2101_ALDO3, true) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_enabled(axp2101, AXP2101_ALDO4, true) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_enabled(axp2101, AXP2101_BLDO1, true) == ERROR_NONE);
|
||||||
|
check(axp2101_set_ldo_enabled(axp2101, AXP2101_BLDO2, true) == ERROR_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_device_event(Device* device, DeviceEvent event, void* context) {
|
||||||
|
(void)context;
|
||||||
|
if (event == DEVICE_EVENT_STARTED && strcmp(device->name, "axp2101") == 0) {
|
||||||
|
configure_axp2101(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
device_listener_add(on_device_event, nullptr);
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
device_listener_remove(on_device_event);
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module m5stack_cores3_module = {
|
||||||
|
.name = "m5stack-cores3",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
#include "papers3_power.h"
|
#include "papers3_power.h"
|
||||||
|
|
||||||
|
|
||||||
#include <tactility/check.h>
|
#include <tactility/check.h>
|
||||||
#include <tactility/driver.h>
|
#include <tactility/driver.h>
|
||||||
#include <tactility/drivers/gpio.h>
|
|
||||||
#include <tactility/drivers/gpio_controller.h>
|
#include <tactility/drivers/gpio_controller.h>
|
||||||
#include <tactility/drivers/power_supply.h>
|
#include <tactility/drivers/power_supply.h>
|
||||||
#include <tactility/drivers/pwm.h>
|
#include <tactility/drivers/pwm.h>
|
||||||
@@ -15,7 +13,7 @@
|
|||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
constexpr auto* TAG = "Papers3Power";
|
#define TAG "Papers3Power"
|
||||||
#define GET_CONFIG(device) (static_cast<const Papers3PowerConfig*>((device)->config))
|
#define GET_CONFIG(device) (static_cast<const Papers3PowerConfig*>((device)->config))
|
||||||
|
|
||||||
// Power-off signal timing, ported from the old deprecated-HAL PaperS3Power::powerOff().
|
// Power-off signal timing, ported from the old deprecated-HAL PaperS3Power::powerOff().
|
||||||
@@ -194,8 +192,17 @@ static void destroy_power_supply_child(Device* child) {
|
|||||||
// region Driver lifecycle
|
// region Driver lifecycle
|
||||||
|
|
||||||
static error_t acquire_input(const GpioPinSpec& pin, GpioDescriptor** out_descriptor) {
|
static error_t acquire_input(const GpioPinSpec& pin, GpioDescriptor** out_descriptor) {
|
||||||
*out_descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, pin.flags | GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO);
|
auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, GPIO_OWNER_GPIO);
|
||||||
return (*out_descriptor != nullptr) ? ERROR_NONE : ERROR_RESOURCE;
|
if (descriptor == nullptr) {
|
||||||
|
return ERROR_RESOURCE;
|
||||||
|
}
|
||||||
|
error_t error = gpio_descriptor_set_flags(descriptor, pin.flags | GPIO_FLAG_DIRECTION_INPUT);
|
||||||
|
if (error != ERROR_NONE) {
|
||||||
|
gpio_descriptor_release(descriptor);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
*out_descriptor = descriptor;
|
||||||
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static error_t start(Device* device) {
|
static error_t start(Device* device) {
|
||||||
@@ -219,8 +226,13 @@ static error_t start(Device* device) {
|
|||||||
return ERROR_RESOURCE;
|
return ERROR_RESOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal->power_off_descriptor = gpio_descriptor_acquire(config->pin_power_off.gpio_controller, config->pin_power_off.pin, config->pin_power_off.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO);
|
internal->power_off_descriptor = gpio_descriptor_acquire(config->pin_power_off.gpio_controller, config->pin_power_off.pin, GPIO_OWNER_GPIO);
|
||||||
if (internal->power_off_descriptor == nullptr) {
|
if (internal->power_off_descriptor == nullptr ||
|
||||||
|
gpio_descriptor_set_flags(internal->power_off_descriptor, config->pin_power_off.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "Failed to configure power-off pin");
|
||||||
|
if (internal->power_off_descriptor != nullptr) {
|
||||||
|
gpio_descriptor_release(internal->power_off_descriptor);
|
||||||
|
}
|
||||||
gpio_descriptor_release(internal->usb_detect_descriptor);
|
gpio_descriptor_release(internal->usb_detect_descriptor);
|
||||||
gpio_descriptor_release(internal->charge_status_descriptor);
|
gpio_descriptor_release(internal->charge_status_descriptor);
|
||||||
delete internal;
|
delete internal;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
#include <tactility/check.h>
|
||||||
#include <tactility/driver.h>
|
#include <tactility/driver.h>
|
||||||
|
#include <tactility/error.h>
|
||||||
#include <tactility/module.h>
|
#include <tactility/module.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -7,16 +9,26 @@ extern Driver papers3_power_driver;
|
|||||||
extern Driver papers3_power_supply_driver;
|
extern Driver papers3_power_supply_driver;
|
||||||
extern Driver papers3_display_driver;
|
extern Driver papers3_display_driver;
|
||||||
|
|
||||||
static Driver* const papers3_drivers[] = {
|
static error_t start() {
|
||||||
&papers3_display_driver,
|
check(driver_construct_add(&papers3_power_supply_driver) == ERROR_NONE);
|
||||||
&papers3_power_driver,
|
check(driver_construct_add(&papers3_power_driver) == ERROR_NONE);
|
||||||
&papers3_power_supply_driver,
|
check(driver_construct_add(&papers3_display_driver) == ERROR_NONE);
|
||||||
nullptr
|
return ERROR_NONE;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
check(driver_remove_destruct(&papers3_display_driver) == ERROR_NONE);
|
||||||
|
check(driver_remove_destruct(&papers3_power_driver) == ERROR_NONE);
|
||||||
|
check(driver_remove_destruct(&papers3_power_supply_driver) == ERROR_NONE);
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Module m5stack_papers3_module = {
|
Module m5stack_papers3_module = {
|
||||||
.name = "m5stack-papers3",
|
.name = "m5stack-papers3",
|
||||||
.drivers = papers3_drivers
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
file(GLOB_RECURSE SOURCE_FILES source/*.c*)
|
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 TactilityKernel py32ioexpander-module
|
REQUIRES Tactility esp_lvgl_port ILI934x FT6x36 AXP2101 driver vfs fatfs ina226-module py32ioexpander-module
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
#include "devices/Display.h"
|
||||||
|
#include "devices/Power.h"
|
||||||
|
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/drivers/gpio_controller.h>
|
||||||
|
#include <tactility/drivers/i2c_controller.h>
|
||||||
|
#include <tactility/log.h>
|
||||||
|
#include <drivers/py32ioexpander.h>
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
|
||||||
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
#include <Axp2101Power.h>
|
||||||
|
#include <Axp2101.h>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static const auto* TAG = "StackChan";
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// I2C addresses
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
static constexpr uint8_t AXP2101_ADDR = 0x34;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// AW9523B GPIO expander pin map — same wiring as CoreS3.
|
||||||
|
// AW88298 reset (P0_2) is driven directly by the aw88298-module driver itself
|
||||||
|
// (see m5stack,stackchan.dts pin-reset property), not from here.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
constexpr auto AW9523B_PIN_TOUCH_RESET = 0; // P0_0
|
||||||
|
constexpr auto AW9523B_PIN_BUS_OUT_ENABLE = 1; // P0_1
|
||||||
|
constexpr auto AW9523B_PIN_SD_CARD_SWITCH = 4; // P0_4
|
||||||
|
constexpr auto AW9523B_PIN_LCD_RESET = 8 + 1; // P1_1
|
||||||
|
constexpr auto AW9523B_PIN_BOOST_ENABLE = 8 + 7; // P1_7 (SY7088)
|
||||||
|
|
||||||
|
static bool initGpioExpander(::Device* aw9523b) {
|
||||||
|
struct PinInit { uint8_t pin; bool level; };
|
||||||
|
static constexpr PinInit pins[] = {
|
||||||
|
{ AW9523B_PIN_TOUCH_RESET, true },
|
||||||
|
{ AW9523B_PIN_BUS_OUT_ENABLE, true },
|
||||||
|
{ AW9523B_PIN_SD_CARD_SWITCH, true },
|
||||||
|
{ AW9523B_PIN_LCD_RESET, true },
|
||||||
|
{ AW9523B_PIN_BOOST_ENABLE, true },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& pinInit : pins) {
|
||||||
|
auto* descriptor = gpio_descriptor_acquire(aw9523b, pinInit.pin, GPIO_OWNER_GPIO);
|
||||||
|
if (descriptor == nullptr) {
|
||||||
|
LOG_E(TAG, "AW9523B: Failed to acquire pin %u", pinInit.pin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
error_t error = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
if (error == ERROR_NONE) {
|
||||||
|
error = gpio_descriptor_set_level(descriptor, pinInit.level);
|
||||||
|
}
|
||||||
|
gpio_descriptor_release(descriptor);
|
||||||
|
if (error != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "AW9523B: Failed to configure pin %u", pinInit.pin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// AXP2101 power management — same voltage rails as CoreS3
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
static bool initPowerControl(::Device* i2c) {
|
||||||
|
// Source: https://github.com/m5stack/M5Unified/blob/b8cfec7fed046242da7f7b8024a4e92004a51ff7/src/utility/Power_Class.cpp#L64
|
||||||
|
static constexpr uint8_t reg_data[] = {
|
||||||
|
0x90U, 0xBFU, // LDOS ON/OFF control 0 (backlight)
|
||||||
|
0x92U, 18U - 5U, // ALDO1 = 1.8V (AW88298)
|
||||||
|
0x93U, 33U - 5U, // ALDO2 = 3.3V (ES7210)
|
||||||
|
0x94U, 33U - 5U, // ALDO3 = 3.3V (camera)
|
||||||
|
0x95U, 33U - 5U, // ALDO4 = 3.3V (TF card)
|
||||||
|
0x27U, 0x00U, // PowerKey Hold=1sec / PowerOff=4sec
|
||||||
|
0x69U, 0x11U, // CHGLED setting
|
||||||
|
0x10U, 0x30U, // PMU common config
|
||||||
|
0x30U, 0x0FU, // ADC enabled
|
||||||
|
};
|
||||||
|
|
||||||
|
if (i2c_controller_write_register_array(i2c, AXP2101_ADDR, reg_data, sizeof(reg_data), pdMS_TO_TICKS(1000)) != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "AXP2101: Failed to set registers");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// initBoot — called after devicetree devices are constructed/started
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
static std::shared_ptr<Axp2101> axp2101;
|
||||||
|
|
||||||
|
bool initBoot() {
|
||||||
|
auto* i2c = device_find_by_name("i2c_internal");
|
||||||
|
if (i2c == nullptr) {
|
||||||
|
LOG_E(TAG, "i2c_internal not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boost enable via AXP2101 before GPIO expander init (same as CoreS3)
|
||||||
|
if (!initPowerControl(i2c)) {
|
||||||
|
LOG_E(TAG, "AXP2101 init failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* aw9523b = device_find_by_name("aw9523b");
|
||||||
|
if (aw9523b == nullptr) {
|
||||||
|
LOG_E(TAG, "aw9523b not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!initGpioExpander(aw9523b)) {
|
||||||
|
LOG_E(TAG, "AW9523B init failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boot LED pattern — confirms PY32IOExpander is working.
|
||||||
|
// PY32 pin 0 = servo VM_EN (output), pin 13 = WS2812C data line.
|
||||||
|
auto* py32 = device_find_by_name("py32");
|
||||||
|
if (py32 != nullptr) {
|
||||||
|
static constexpr uint8_t LED_COUNT = 12;
|
||||||
|
static constexpr uint8_t COLORS[][3] = {
|
||||||
|
{ 255, 0, 0 }, // red
|
||||||
|
{ 0, 255, 0 }, // green
|
||||||
|
{ 0, 0, 255 }, // blue
|
||||||
|
};
|
||||||
|
py32_led_set_count(py32, LED_COUNT);
|
||||||
|
for (auto& c : COLORS) {
|
||||||
|
for (uint8_t i = 0; i < LED_COUNT; i++) {
|
||||||
|
py32_led_set_color(py32, i, c[0], c[1], c[2]);
|
||||||
|
}
|
||||||
|
py32_led_refresh(py32);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(150));
|
||||||
|
}
|
||||||
|
py32_led_disable(py32);
|
||||||
|
} else {
|
||||||
|
LOG_W(TAG, "py32 not found — LED boot pattern skipped");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep Axp2101 C++ wrapper alive for Axp2101Power (backlight + battery)
|
||||||
|
axp2101 = std::make_shared<Axp2101>(i2c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Device list
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
axp2101,
|
||||||
|
std::make_shared<Axp2101Power>(axp2101),
|
||||||
|
createPower(),
|
||||||
|
createDisplay(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration hardwareConfiguration = {
|
||||||
|
.initBoot = initBoot,
|
||||||
|
.createDevices = createDevices
|
||||||
|
};
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include <Axp2101.h>
|
||||||
|
#include <Ft6x36Touch.h>
|
||||||
|
#include <Ili934xDisplay.h>
|
||||||
|
|
||||||
|
#include <tactility/check.h>
|
||||||
|
#include <tactility/log.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "StackChanDisplay";
|
||||||
|
|
||||||
|
static void setBacklightDuty(uint8_t backlightDuty) {
|
||||||
|
const uint8_t voltage = 20 + ((8 * backlightDuty) / 255); // [0b00000, 0b11100]
|
||||||
|
auto controller = device_find_by_name("i2c_internal");
|
||||||
|
check(controller);
|
||||||
|
if (i2c_controller_write_register(controller, AXP2101_ADDRESS, 0x99, &voltage, 1, 1000) != ERROR_NONE) { // Sets DLD01
|
||||||
|
LOG_E(TAG, "Failed to set display backlight voltage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<tt::hal::touch::TouchDevice> createTouch() {
|
||||||
|
auto configuration = std::make_unique<Ft6x36Touch::Configuration>(
|
||||||
|
I2C_NUM_0,
|
||||||
|
319,//LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
239,//LCD_VERTICAL_RESOLUTION,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
return std::make_shared<Ft6x36Touch>(std::move(configuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
|
Ili934xDisplay::Configuration panel_configuration = {
|
||||||
|
.horizontalResolution = LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
.verticalResolution = LCD_VERTICAL_RESOLUTION,
|
||||||
|
.gapX = 0,
|
||||||
|
.gapY = 0,
|
||||||
|
.swapXY = false,
|
||||||
|
.mirrorX = false,
|
||||||
|
.mirrorY = false,
|
||||||
|
.invertColor = true,
|
||||||
|
.swapBytes = true,
|
||||||
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
|
.touch = createTouch(),
|
||||||
|
.backlightDutyFunction = ::setBacklightDuty,
|
||||||
|
.resetPin = GPIO_NUM_NC,
|
||||||
|
.rgbElementOrder = LCD_RGB_ELEMENT_ORDER_BGR
|
||||||
|
};
|
||||||
|
|
||||||
|
auto spi_configuration = std::make_shared<Ili934xDisplay::SpiConfiguration>(Ili934xDisplay::SpiConfiguration {
|
||||||
|
.spiHostDevice = LCD_SPI_HOST,
|
||||||
|
.csPin = LCD_PIN_CS,
|
||||||
|
.dcPin = LCD_PIN_DC,
|
||||||
|
.pixelClockFrequency = 40'000'000,
|
||||||
|
.transactionQueueDepth = 10
|
||||||
|
});
|
||||||
|
|
||||||
|
return std::make_shared<Ili934xDisplay>(panel_configuration, spi_configuration, true);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <driver/spi_common.h>
|
||||||
|
|
||||||
|
// Display
|
||||||
|
constexpr auto LCD_SPI_HOST = SPI2_HOST;
|
||||||
|
constexpr auto LCD_PIN_CS = GPIO_NUM_3;
|
||||||
|
constexpr auto LCD_PIN_DC = GPIO_NUM_35;
|
||||||
|
constexpr auto LCD_HORIZONTAL_RESOLUTION = 320;
|
||||||
|
constexpr auto LCD_VERTICAL_RESOLUTION = 240;
|
||||||
|
constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 10;
|
||||||
|
constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT;
|
||||||
|
constexpr auto LCD_SPI_TRANSFER_SIZE_LIMIT = LCD_BUFFER_SIZE * LV_COLOR_DEPTH / 8;
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#include "Power.h"
|
||||||
|
|
||||||
|
#include <Tactility/hal/power/PowerDevice.h>
|
||||||
|
#include <drivers/ina226.h>
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/log.h>
|
||||||
|
|
||||||
|
using namespace tt::hal::power;
|
||||||
|
|
||||||
|
static constexpr auto* TAG = "StackChanPower";
|
||||||
|
|
||||||
|
// 1S Li-ion cell (550 mAh): 3.2V (empty) – 4.2V (full)
|
||||||
|
static constexpr float MIN_BATTERY_VOLTAGE_MV = 3200.0f;
|
||||||
|
static constexpr float MAX_BATTERY_VOLTAGE_MV = 4200.0f;
|
||||||
|
|
||||||
|
class StackChanPower final : public PowerDevice {
|
||||||
|
public:
|
||||||
|
explicit StackChanPower(::Device* ina226Device) : ina226(ina226Device) {}
|
||||||
|
|
||||||
|
std::string getName() const override { return "M5Stack StackChan Power"; }
|
||||||
|
std::string getDescription() const override { return "Battery monitoring via INA226 over I2C"; }
|
||||||
|
|
||||||
|
bool supportsMetric(MetricType type) const override {
|
||||||
|
switch (type) {
|
||||||
|
using enum MetricType;
|
||||||
|
case BatteryVoltage:
|
||||||
|
case ChargeLevel:
|
||||||
|
case Current:
|
||||||
|
return ina226 != nullptr;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getMetric(MetricType type, MetricData& data) override {
|
||||||
|
switch (type) {
|
||||||
|
using enum MetricType;
|
||||||
|
|
||||||
|
case BatteryVoltage: {
|
||||||
|
if (ina226 == nullptr) return false;
|
||||||
|
float volts = 0.0f;
|
||||||
|
if (ina226_read_bus_voltage(ina226, &volts) != ERROR_NONE) return false;
|
||||||
|
data.valueAsUint32 = static_cast<uint32_t>(volts * 1000.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ChargeLevel: {
|
||||||
|
if (ina226 == nullptr) return false;
|
||||||
|
float volts = 0.0f;
|
||||||
|
if (ina226_read_bus_voltage(ina226, &volts) != ERROR_NONE) return false;
|
||||||
|
float voltage_mv = volts * 1000.0f;
|
||||||
|
if (voltage_mv >= MAX_BATTERY_VOLTAGE_MV) {
|
||||||
|
data.valueAsUint8 = 100;
|
||||||
|
} else if (voltage_mv <= MIN_BATTERY_VOLTAGE_MV) {
|
||||||
|
data.valueAsUint8 = 0;
|
||||||
|
} else {
|
||||||
|
float factor = (voltage_mv - MIN_BATTERY_VOLTAGE_MV) / (MAX_BATTERY_VOLTAGE_MV - MIN_BATTERY_VOLTAGE_MV);
|
||||||
|
data.valueAsUint8 = static_cast<uint8_t>(factor * 100.0f);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Current: {
|
||||||
|
if (ina226 == nullptr) return false;
|
||||||
|
float amps = 0.0f;
|
||||||
|
if (ina226_read_shunt_current(ina226, &s) != ERROR_NONE) return false;
|
||||||
|
data.valueAsInt32 = static_cast<int32_t>(amps * 1000.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
::Device* ina226;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<PowerDevice> createPower() {
|
||||||
|
auto* ina226 = device_find_by_name("ina226");
|
||||||
|
if (ina226 == nullptr) {
|
||||||
|
LOG_E(TAG, "ina226 device not found");
|
||||||
|
}
|
||||||
|
return std::make_shared<StackChanPower>(ina226);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <Tactility/hal/power/PowerDevice.h>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::power::PowerDevice> createPower();
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#include <tactility/module.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module m5stack_stackchan_module = {
|
||||||
|
.name = "m5stack-stackchan",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,8 +12,6 @@ hardware.tinyUsb=true
|
|||||||
hardware.esptoolFlashFreq=120M
|
hardware.esptoolFlashFreq=120M
|
||||||
hardware.bluetooth=true
|
hardware.bluetooth=true
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
storage.userDataLocation=SD
|
storage.userDataLocation=SD
|
||||||
|
|
||||||
display.size=2"
|
display.size=2"
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
- Platforms/platform-esp32
|
- Platforms/platform-esp32
|
||||||
- Drivers/audio-stream-module
|
|
||||||
- Drivers/aw88298-module
|
|
||||||
- Drivers/aw9523b-module
|
|
||||||
- Drivers/axp2101-module
|
|
||||||
- Drivers/bm8563-module
|
|
||||||
- Drivers/bmi270-module
|
- Drivers/bmi270-module
|
||||||
- Drivers/es7210-module
|
- Drivers/bm8563-module
|
||||||
- Drivers/ft6x36-module
|
|
||||||
- Drivers/ili9341-module
|
|
||||||
- Drivers/ina226-module
|
- Drivers/ina226-module
|
||||||
- Drivers/py32ioexpander-module
|
- Drivers/py32ioexpander-module
|
||||||
|
- Drivers/aw9523b-module
|
||||||
|
- Drivers/aw88298-module
|
||||||
|
- Drivers/es7210-module
|
||||||
|
- Drivers/audio-stream-module
|
||||||
dts: m5stack,stackchan.dts
|
dts: m5stack,stackchan.dts
|
||||||
|
|||||||
@@ -7,21 +7,17 @@
|
|||||||
#include <tactility/bindings/esp32_grove.h>
|
#include <tactility/bindings/esp32_grove.h>
|
||||||
#include <tactility/bindings/esp32_i2c.h>
|
#include <tactility/bindings/esp32_i2c.h>
|
||||||
#include <tactility/bindings/esp32_i2s.h>
|
#include <tactility/bindings/esp32_i2s.h>
|
||||||
#include <tactility/bindings/esp32_sdspi.h>
|
|
||||||
#include <tactility/bindings/esp32_spi.h>
|
#include <tactility/bindings/esp32_spi.h>
|
||||||
#include <tactility/bindings/esp32_uart.h>
|
#include <tactility/bindings/esp32_uart.h>
|
||||||
#include <tactility/bindings/gpio_hog.h>
|
|
||||||
#include <bindings/aw88298.h>
|
|
||||||
#include <bindings/aw9523b.h>
|
|
||||||
#include <bindings/axp2101.h>
|
|
||||||
#include <bindings/axp2101_backlight.h>
|
|
||||||
#include <bindings/bm8563.h>
|
|
||||||
#include <bindings/bmi270.h>
|
#include <bindings/bmi270.h>
|
||||||
#include <bindings/es7210.h>
|
#include <bindings/bm8563.h>
|
||||||
#include <bindings/ft6x36.h>
|
|
||||||
#include <bindings/ili9341.h>
|
|
||||||
#include <bindings/ina226.h>
|
#include <bindings/ina226.h>
|
||||||
#include <bindings/py32ioexpander.h>
|
#include <bindings/py32ioexpander.h>
|
||||||
|
#include <bindings/aw9523b.h>
|
||||||
|
#include <bindings/aw88298.h>
|
||||||
|
#include <bindings/es7210.h>
|
||||||
|
#include <tactility/bindings/esp32_sdspi.h>
|
||||||
|
#include <tactility/bindings/display_placeholder.h>
|
||||||
|
|
||||||
// Reference: https://docs.m5stack.com/en/StackChan
|
// Reference: https://docs.m5stack.com/en/StackChan
|
||||||
/ {
|
/ {
|
||||||
@@ -44,7 +40,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// AW88298 speaker + ES7210 microphone
|
// AW88298 speaker + ES7210 microphone
|
||||||
i2s0 {
|
i2s0: i2s0 {
|
||||||
compatible = "espressif,esp32-i2s";
|
compatible = "espressif,esp32-i2s";
|
||||||
port = <I2S_NUM_0>;
|
port = <I2S_NUM_0>;
|
||||||
pin-bclk = <&gpio0 34 GPIO_FLAG_NONE>;
|
pin-bclk = <&gpio0 34 GPIO_FLAG_NONE>;
|
||||||
@@ -81,34 +77,14 @@
|
|||||||
compatible = "ti,ina226";
|
compatible = "ti,ina226";
|
||||||
reg = <0x41>;
|
reg = <0x41>;
|
||||||
shunt-milliohms = <10>;
|
shunt-milliohms = <10>;
|
||||||
power-supply;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// AW9523B pin map (same wiring as CoreS3):
|
||||||
// P0_0 = touch reset, P0_1 = bus-out enable, P0_2 = AW88298 reset,
|
// P0_0 = touch reset, P0_1 = bus-out enable, P0_2 = AW88298 reset,
|
||||||
// P0_4 = SD card switch, P1_1 = LCD reset, P1_7 = boost enable (SY7088)
|
// P0_4 = SD card switch, P1_1 = LCD reset, P1_7 = boost enable (SY7088)
|
||||||
aw9523b {
|
aw9523b: aw9523b {
|
||||||
compatible = "awinic,aw9523b";
|
compatible = "awinic,aw9523b";
|
||||||
reg = <0x58>;
|
reg = <0x58>;
|
||||||
|
|
||||||
// Bus-out enable, AW88298 (audio amp) reset, SD card power switch and boost enable
|
|
||||||
// (SY7088) are AW9523B pins with no owning peripheral driver yet.
|
|
||||||
aw9523_bus_out_enable {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&aw9523b 1 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
|
||||||
};
|
|
||||||
|
|
||||||
aw9523_sdcard_switch {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&aw9523b 4 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_INPUT>;
|
|
||||||
};
|
|
||||||
|
|
||||||
aw9523_boost_enable {
|
|
||||||
compatible = "gpio-hog";
|
|
||||||
pin = <&aw9523b 15 GPIO_FLAG_NONE>;
|
|
||||||
mode = <GPIO_HOG_MODE_OUTPUT_HIGH>;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
aw88298 {
|
aw88298 {
|
||||||
@@ -118,39 +94,6 @@
|
|||||||
pin-reset = <&aw9523b 2 GPIO_FLAG_NONE>;
|
pin-reset = <&aw9523b 2 GPIO_FLAG_NONE>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Same rail assignment as CoreS3: ALDO1=AW88298, ALDO2=ES7210, ALDO3=camera
|
|
||||||
// (not yet implemented, but harmless to power), ALDO4=TF/SD card. BLDO1/BLDO2 are
|
|
||||||
// enabled with no specific voltage requirement.
|
|
||||||
axp2101 {
|
|
||||||
compatible = "x-powers,axp2101";
|
|
||||||
reg = <0x34>;
|
|
||||||
aldo1-millivolt = <1800>;
|
|
||||||
aldo1-enabled;
|
|
||||||
aldo2-millivolt = <3300>;
|
|
||||||
aldo2-enabled;
|
|
||||||
aldo3-millivolt = <3300>;
|
|
||||||
aldo3-enabled;
|
|
||||||
aldo4-millivolt = <3300>;
|
|
||||||
aldo4-enabled;
|
|
||||||
bldo1-enabled;
|
|
||||||
bldo2-enabled;
|
|
||||||
|
|
||||||
display_backlight {
|
|
||||||
compatible = "axp2101-backlight";
|
|
||||||
ldo = <AXP2101_DLDO1>;
|
|
||||||
min-millivolt = <2500>;
|
|
||||||
max-millivolt = <3300>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
touch {
|
|
||||||
compatible = "focaltech,ft6x36";
|
|
||||||
reg = <0x38>;
|
|
||||||
x-max = <319>;
|
|
||||||
y-max = <239>;
|
|
||||||
pin-reset = <&aw9523b 0 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
es7210 {
|
es7210 {
|
||||||
compatible = "everest,es7210";
|
compatible = "everest,es7210";
|
||||||
reg = <0x40>;
|
reg = <0x40>;
|
||||||
@@ -166,6 +109,9 @@
|
|||||||
input-gain-percent = <400>;
|
input-gain-percent = <400>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// AXP2101 PMIC @ 0x34 — initialized manually in initBoot()
|
||||||
|
// FT6336U capacitive touch @ 0x38 — used by Display driver (FT6x36 library)
|
||||||
|
|
||||||
// TODO: Si12T 3-zone head touch @ 0x68 — INT active-low, 10kΩ pull-up to 3.3V; driver not yet implemented
|
// TODO: Si12T 3-zone head touch @ 0x68 — INT active-low, 10kΩ pull-up to 3.3V; driver not yet implemented
|
||||||
// TODO: GC0308 camera @ 0x21 — requires i2c_master driver, not yet available
|
// TODO: GC0308 camera @ 0x21 — requires i2c_master driver, not yet available
|
||||||
// TODO: LTR-553ALS-WA proximity/light @ 0x23 — no driver yet
|
// TODO: LTR-553ALS-WA proximity/light @ 0x23 — no driver yet
|
||||||
@@ -221,15 +167,7 @@
|
|||||||
pin-sclk = <&gpio0 36 GPIO_FLAG_NONE>;
|
pin-sclk = <&gpio0 36 GPIO_FLAG_NONE>;
|
||||||
|
|
||||||
display@0 {
|
display@0 {
|
||||||
compatible = "ilitek,ili9341";
|
compatible = "display-placeholder";
|
||||||
horizontal-resolution = <320>;
|
|
||||||
vertical-resolution = <240>;
|
|
||||||
invert-color;
|
|
||||||
bgr-order;
|
|
||||||
pixel-clock-hz = <40000000>;
|
|
||||||
pin-dc = <&gpio0 35 GPIO_FLAG_NONE>;
|
|
||||||
pin-reset = <&aw9523b 9 GPIO_FLAG_NONE>;
|
|
||||||
backlight = <&display_backlight>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
sdcard@1 {
|
sdcard@1 {
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
#include <drivers/py32ioexpander.h>
|
|
||||||
|
|
||||||
#include <tactility/check.h>
|
|
||||||
#include <tactility/device.h>
|
|
||||||
#include <tactility/device_listener.h>
|
|
||||||
#include <tactility/module.h>
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <freertos/FreeRTOS.h>
|
|
||||||
#include <freertos/task.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
// Boot LED pattern (red/green/blue sweep across the 12-LED WS2812C ring).
|
|
||||||
// Confirms the PY32L020 body IO expander is working.
|
|
||||||
static void run_led_boot_pattern(Device* py32) {
|
|
||||||
static constexpr uint8_t LED_COUNT = 12;
|
|
||||||
static constexpr uint8_t COLORS[][3] = {
|
|
||||||
{ 255, 0, 0 }, // red
|
|
||||||
{ 0, 255, 0 }, // green
|
|
||||||
{ 0, 0, 255 }, // blue
|
|
||||||
};
|
|
||||||
|
|
||||||
py32_led_set_count(py32, LED_COUNT);
|
|
||||||
for (const auto& color : COLORS) {
|
|
||||||
for (uint8_t i = 0; i < LED_COUNT; i++) {
|
|
||||||
py32_led_set_color(py32, i, color[0], color[1], color[2]);
|
|
||||||
}
|
|
||||||
py32_led_refresh(py32);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(150));
|
|
||||||
}
|
|
||||||
py32_led_disable(py32);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void on_device_event(Device* device, DeviceEvent event, void* context) {
|
|
||||||
(void)context;
|
|
||||||
if (event != DEVICE_EVENT_STARTED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (strcmp(device->name, "py32") == 0) {
|
|
||||||
run_led_boot_pattern(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static error_t start() {
|
|
||||||
device_listener_add(on_device_event, nullptr);
|
|
||||||
return ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static error_t stop() {
|
|
||||||
device_listener_remove(on_device_event);
|
|
||||||
return ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Module m5stack_stackchan_module = {
|
|
||||||
.name = "m5stack-stackchan",
|
|
||||||
.start = start,
|
|
||||||
.stop = stop
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ constexpr auto* TAG = "StickCPlus2";
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
static error_t init_power() {
|
static bool init_power() {
|
||||||
// CH552 applies 4 V to GPIO 0, which reduces Wi-Fi sensitivity.
|
// CH552 applies 4 V to GPIO 0, which reduces Wi-Fi sensitivity.
|
||||||
// Setting output to high adds a bias of 3.3 V and suppresses over-voltage:
|
// Setting output to high adds a bias of 3.3 V and suppresses over-voltage:
|
||||||
gpio_set_direction(GPIO_NUM_0, GPIO_MODE_OUTPUT);
|
gpio_set_direction(GPIO_NUM_0, GPIO_MODE_OUTPUT);
|
||||||
@@ -17,12 +17,25 @@ static error_t init_power() {
|
|||||||
gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
|
gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
|
||||||
gpio_set_level(GPIO_NUM_4, 1);
|
gpio_set_level(GPIO_NUM_4, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
init_power();
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Module m5stack_stickc_plus2_module = {
|
Module m5stack_stickc_plus2_module = {
|
||||||
.name = "m5stack-stickc-plus2",
|
.name = "m5stack-stickc-plus2",
|
||||||
.start = init_power
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
file(GLOB_RECURSE SOURCE_FILES source/*.c*)
|
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 TactilityKernel
|
REQUIRES Tactility esp_lvgl_port esp_lcd ST7789 PwmBacklight ButtonControl vfs fatfs m5pm1-module
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#include "devices/Display.h"
|
||||||
|
#include "devices/Power.h"
|
||||||
|
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <drivers/m5pm1.h>
|
||||||
|
|
||||||
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
#include <ButtonControl.h>
|
||||||
|
#include <PwmBacklight.h>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static constexpr auto* TAG = "StickS3";
|
||||||
|
|
||||||
|
// Audio codec register programming is owned by the es8311-module driver (registered as an
|
||||||
|
// AUDIO_CODEC_TYPE device, see m5stack,sticks3.dts). This board still needs to drive the
|
||||||
|
// AW8737 speaker amplifier's enable line via m5pm1 (PM1_G3), which is board wiring glue
|
||||||
|
// rather than codec configuration, so it stays here.
|
||||||
|
static void enableSpeakerAmplifier() {
|
||||||
|
auto* m5pm1 = device_find_by_name("m5pm1");
|
||||||
|
if (m5pm1 == nullptr) {
|
||||||
|
LOG_W(TAG, "m5pm1 not found -- speaker amp not enabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_t error = m5pm1_set_speaker_enable(m5pm1, true);
|
||||||
|
if (error != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "Failed to enable speaker amplifier: %s", error_to_string(error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initBoot() {
|
||||||
|
enableSpeakerAmplifier();
|
||||||
|
return driver::pwmbacklight::init(GPIO_NUM_38, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
return {
|
||||||
|
createPower(),
|
||||||
|
ButtonControl::createTwoButtonControl(11, 12), // top button, side button
|
||||||
|
createDisplay(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration hardwareConfiguration = {
|
||||||
|
.initBoot = initBoot,
|
||||||
|
.createDevices = createDevices
|
||||||
|
};
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
#include <PwmBacklight.h>
|
||||||
|
#include <St7789Display.h>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
|
St7789Display::Configuration panel_configuration = {
|
||||||
|
.horizontalResolution = LCD_HORIZONTAL_RESOLUTION,
|
||||||
|
.verticalResolution = LCD_VERTICAL_RESOLUTION,
|
||||||
|
.gapX = 52,
|
||||||
|
.gapY = 40,
|
||||||
|
.swapXY = false,
|
||||||
|
.mirrorX = false,
|
||||||
|
.mirrorY = false,
|
||||||
|
.invertColor = true,
|
||||||
|
.bufferSize = LCD_BUFFER_SIZE,
|
||||||
|
.touch = nullptr,
|
||||||
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
|
.resetPin = LCD_PIN_RESET,
|
||||||
|
.lvglSwapBytes = false
|
||||||
|
};
|
||||||
|
|
||||||
|
auto spi_configuration = std::make_shared<St7789Display::SpiConfiguration>(St7789Display::SpiConfiguration {
|
||||||
|
.spiHostDevice = LCD_SPI_HOST,
|
||||||
|
.csPin = LCD_PIN_CS,
|
||||||
|
.dcPin = LCD_PIN_DC,
|
||||||
|
.pixelClockFrequency = 40'000'000,
|
||||||
|
.transactionQueueDepth = 10
|
||||||
|
});
|
||||||
|
|
||||||
|
return std::make_shared<St7789Display>(panel_configuration, spi_configuration);
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Tactility/hal/display/DisplayDevice.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <driver/spi_common.h>
|
||||||
|
|
||||||
|
constexpr auto LCD_SPI_HOST = SPI2_HOST;
|
||||||
|
constexpr auto LCD_PIN_CS = GPIO_NUM_41;
|
||||||
|
constexpr auto LCD_PIN_DC = GPIO_NUM_45;
|
||||||
|
constexpr auto LCD_PIN_RESET = GPIO_NUM_21;
|
||||||
|
constexpr auto LCD_HORIZONTAL_RESOLUTION = 135;
|
||||||
|
constexpr auto LCD_VERTICAL_RESOLUTION = 240;
|
||||||
|
constexpr auto LCD_BUFFER_HEIGHT = LCD_VERTICAL_RESOLUTION / 3;
|
||||||
|
constexpr auto LCD_BUFFER_SIZE = LCD_HORIZONTAL_RESOLUTION * LCD_BUFFER_HEIGHT;
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#include "Power.h"
|
||||||
|
|
||||||
|
#include <Tactility/hal/power/PowerDevice.h>
|
||||||
|
#include <drivers/m5pm1.h>
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/log.h>
|
||||||
|
|
||||||
|
using namespace tt::hal::power;
|
||||||
|
|
||||||
|
static constexpr auto* TAG = "StickS3Power";
|
||||||
|
|
||||||
|
static constexpr float MIN_BATTERY_VOLTAGE_MV = 3300.0f;
|
||||||
|
static constexpr float MAX_BATTERY_VOLTAGE_MV = 4200.0f;
|
||||||
|
|
||||||
|
class StickS3Power final : public PowerDevice {
|
||||||
|
public:
|
||||||
|
explicit StickS3Power(::Device* m5pm1Device) : m5pm1(m5pm1Device) {}
|
||||||
|
|
||||||
|
std::string getName() const override { return "M5Stack StickS3 Power"; }
|
||||||
|
std::string getDescription() const override { return "Battery monitoring via M5PM1 over I2C"; }
|
||||||
|
|
||||||
|
bool supportsMetric(MetricType type) const override {
|
||||||
|
switch (type) {
|
||||||
|
using enum MetricType;
|
||||||
|
case BatteryVoltage:
|
||||||
|
case ChargeLevel:
|
||||||
|
case IsCharging:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getMetric(MetricType type, MetricData& data) override {
|
||||||
|
switch (type) {
|
||||||
|
using enum MetricType;
|
||||||
|
|
||||||
|
case BatteryVoltage: {
|
||||||
|
uint16_t mv = 0;
|
||||||
|
if (m5pm1_get_battery_voltage(m5pm1, &mv) != ERROR_NONE) return false;
|
||||||
|
data.valueAsUint32 = mv;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ChargeLevel: {
|
||||||
|
uint16_t mv = 0;
|
||||||
|
if (m5pm1_get_battery_voltage(m5pm1, &mv) != ERROR_NONE) return false;
|
||||||
|
float voltage = static_cast<float>(mv);
|
||||||
|
if (voltage >= MAX_BATTERY_VOLTAGE_MV) {
|
||||||
|
data.valueAsUint8 = 100;
|
||||||
|
} else if (voltage <= MIN_BATTERY_VOLTAGE_MV) {
|
||||||
|
data.valueAsUint8 = 0;
|
||||||
|
} else {
|
||||||
|
float factor = (voltage - MIN_BATTERY_VOLTAGE_MV) / (MAX_BATTERY_VOLTAGE_MV - MIN_BATTERY_VOLTAGE_MV);
|
||||||
|
data.valueAsUint8 = static_cast<uint8_t>(factor * 100.0f);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IsCharging: {
|
||||||
|
bool charging = false;
|
||||||
|
if (m5pm1_is_charging(m5pm1, &charging) != ERROR_NONE) {
|
||||||
|
LOG_W(TAG, "Failed to read charging status");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data.valueAsBool = charging;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool supportsPowerOff() const override { return true; }
|
||||||
|
|
||||||
|
void powerOff() override {
|
||||||
|
LOG_W(TAG, "Powering off via M5PM1");
|
||||||
|
if (m5pm1_shutdown(m5pm1) != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "Failed to send power-off command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
::Device* m5pm1;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<PowerDevice> createPower() {
|
||||||
|
auto* m5pm1 = device_find_by_name("m5pm1");
|
||||||
|
if (m5pm1 == nullptr) {
|
||||||
|
LOG_E(TAG, "m5pm1 device not found");
|
||||||
|
}
|
||||||
|
return std::make_shared<StickS3Power>(m5pm1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <Tactility/hal/power/PowerDevice.h>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::power::PowerDevice> createPower();
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#include <tactility/module.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
static error_t start() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static error_t stop() {
|
||||||
|
// Empty for now
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Module m5stack_sticks3_module = {
|
||||||
|
.name = "m5stack-sticks3",
|
||||||
|
.start = start,
|
||||||
|
.stop = stop,
|
||||||
|
.symbols = nullptr,
|
||||||
|
.internal = nullptr
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,8 +12,6 @@ hardware.esptoolFlashFreq=80M
|
|||||||
hardware.tinyUsb=true
|
hardware.tinyUsb=true
|
||||||
hardware.bluetooth=true
|
hardware.bluetooth=true
|
||||||
|
|
||||||
dependencies.useDeprecatedHal=false
|
|
||||||
|
|
||||||
storage.userDataLocation=Internal
|
storage.userDataLocation=Internal
|
||||||
|
|
||||||
display.size=1.14"
|
display.size=1.14"
|
||||||
|
|||||||
@@ -4,6 +4,4 @@ dependencies:
|
|||||||
- Drivers/m5pm1-module
|
- Drivers/m5pm1-module
|
||||||
- Drivers/es8311-module
|
- Drivers/es8311-module
|
||||||
- Drivers/audio-stream-module
|
- Drivers/audio-stream-module
|
||||||
- Drivers/st7789-module
|
|
||||||
- Drivers/button-control-module
|
|
||||||
dts: m5stack,sticks3.dts
|
dts: m5stack,sticks3.dts
|
||||||
|
|||||||
@@ -11,11 +11,7 @@
|
|||||||
#include <bindings/m5pm1.h>
|
#include <bindings/m5pm1.h>
|
||||||
#include <bindings/es8311.h>
|
#include <bindings/es8311.h>
|
||||||
#include <tactility/bindings/esp32_sdspi.h>
|
#include <tactility/bindings/esp32_sdspi.h>
|
||||||
#include <tactility/bindings/esp32_pwm_ledc.h>
|
#include <tactility/bindings/display_placeholder.h>
|
||||||
#include <tactility/bindings/pwm_backlight.h>
|
|
||||||
|
|
||||||
#include <bindings/st7789.h>
|
|
||||||
#include <bindings/button_control.h>
|
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
compatible = "root";
|
compatible = "root";
|
||||||
@@ -57,8 +53,6 @@
|
|||||||
m5pm1 {
|
m5pm1 {
|
||||||
compatible = "m5stack,m5pm1";
|
compatible = "m5stack,m5pm1";
|
||||||
reg = <0x6E>;
|
reg = <0x6E>;
|
||||||
power-supply-reference-voltage-mv = <4200>;
|
|
||||||
speaker-amp-enable-at-boot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bmi270 {
|
bmi270 {
|
||||||
@@ -81,49 +75,18 @@
|
|||||||
pin-scl = <&gpio0 10 GPIO_FLAG_NONE>;
|
pin-scl = <&gpio0 10 GPIO_FLAG_NONE>;
|
||||||
};
|
};
|
||||||
|
|
||||||
display_backlight_pwm {
|
|
||||||
compatible = "espressif,esp32-pwm-ledc";
|
|
||||||
pin = <&gpio0 38 GPIO_FLAG_NONE>;
|
|
||||||
period-ns = <1953125>;
|
|
||||||
ledc-timer = <0>;
|
|
||||||
ledc-channel = <0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
display_backlight {
|
|
||||||
compatible = "pwm-backlight";
|
|
||||||
// Off by default so display power-on won't show the screen from before the last power loss.
|
|
||||||
// The display backlight is turned on during the boot process.
|
|
||||||
status = "disabled";
|
|
||||||
pwm = <&display_backlight_pwm>;
|
|
||||||
};
|
|
||||||
|
|
||||||
spi0 {
|
spi0 {
|
||||||
compatible = "espressif,esp32-spi";
|
compatible = "espressif,esp32-spi";
|
||||||
host = <SPI2_HOST>;
|
host = <SPI2_HOST>;
|
||||||
cs-gpios = <&gpio0 41 GPIO_FLAG_NONE>;
|
cs-gpios = <&gpio0 41 GPIO_FLAG_NONE>;
|
||||||
pin-mosi = <&gpio0 39 GPIO_FLAG_NONE>;
|
pin-mosi = <&gpio0 39 GPIO_FLAG_NONE>;
|
||||||
pin-sclk = <&gpio0 40 GPIO_FLAG_NONE>;
|
pin-sclk = <&gpio0 40 GPIO_FLAG_NONE>;
|
||||||
|
|
||||||
display@0 {
|
display {
|
||||||
compatible = "sitronix,st7789";
|
compatible = "display-placeholder";
|
||||||
horizontal-resolution = <135>;
|
|
||||||
vertical-resolution = <240>;
|
|
||||||
gap-x = <52>;
|
|
||||||
gap-y = <40>;
|
|
||||||
invert-color;
|
|
||||||
pixel-clock-hz = <40000000>;
|
|
||||||
pin-dc = <&gpio0 45 GPIO_FLAG_NONE>;
|
|
||||||
pin-reset = <&gpio0 21 GPIO_FLAG_NONE>;
|
|
||||||
backlight = <&display_backlight>;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
buttons {
|
|
||||||
compatible = "tactility,button-control";
|
|
||||||
pin-primary = <&gpio0 11 GPIO_FLAG_NONE>;
|
|
||||||
pin-secondary = <&gpio0 12 GPIO_FLAG_NONE>;
|
|
||||||
};
|
|
||||||
|
|
||||||
uart_grove: uart1 {
|
uart_grove: uart1 {
|
||||||
compatible = "espressif,esp32-uart";
|
compatible = "espressif,esp32-uart";
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
#include <tactility/module.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
Module m5stack_sticks3_module = {
|
|
||||||
.name = "m5stack-sticks3"
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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 esp_lcd esp_lcd_ili9881c esp_lcd_st7123 esp_lcd_touch_st7123 esp_lcd_touch_gt911 driver esp_driver_i2c vfs fatfs ina226-module ili9881c-module st7123-module gt911-module
|
REQUIRES Tactility esp_lvgl_port esp_lcd EspLcdCompat esp_lcd_ili9881c esp_lcd_st7123 esp_lcd_touch_st7123 GT911 PwmBacklight driver esp_driver_i2c vfs fatfs ina226-module
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,205 @@
|
|||||||
|
#include "devices/Display.h"
|
||||||
|
#include "devices/Power.h"
|
||||||
|
#include "devices/Tab5Keyboard.h"
|
||||||
|
|
||||||
|
#include <tactility/drivers/gpio_controller.h>
|
||||||
|
#include <tactility/drivers/i2c_controller.h>
|
||||||
|
|
||||||
|
#include <Tactility/hal/Configuration.h>
|
||||||
|
|
||||||
|
#include <esp_clock_output.h>
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
|
static constexpr auto* TAG = "Tab5";
|
||||||
|
|
||||||
|
static DeviceVector createDevices() {
|
||||||
|
auto* i2c2 = device_find_by_name("i2c2");
|
||||||
|
check(i2c2, "i2c2 not found");
|
||||||
|
return {
|
||||||
|
createPower(),
|
||||||
|
createDisplay(),
|
||||||
|
std::make_shared<Tab5Keyboard>(i2c2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
PI4IOE5V6408-0 (0x43)
|
||||||
|
- Bit 0: RF internal/external switch
|
||||||
|
- Bit 1: Speaker enable
|
||||||
|
- Bit 2: External 5V bus enable
|
||||||
|
- Bit 3: /
|
||||||
|
- Bit 4: LCD reset
|
||||||
|
- Bit 5: Touch reset
|
||||||
|
- Bit 6: Camera reset
|
||||||
|
- Bit 7: Headphone detect
|
||||||
|
*/
|
||||||
|
constexpr auto GPIO_EXP0_PIN_RF_INTERNAL_EXTERNAL = 0;
|
||||||
|
constexpr auto GPIO_EXP0_PIN_SPEAKER_ENABLE = 1;
|
||||||
|
constexpr auto GPIO_EXP0_PIN_EXTERNAL_5V_BUS_ENABLE = 2;
|
||||||
|
constexpr auto GPIO_EXP0_PIN_LCD_RESET = 4;
|
||||||
|
constexpr auto GPIO_EXP0_PIN_TOUCH_RESET = 5;
|
||||||
|
constexpr auto GPIO_EXP0_PIN_CAMERA_RESET = 6;
|
||||||
|
constexpr auto GPIO_EXP0_PIN_HEADPHONE_DETECT = 7;
|
||||||
|
|
||||||
|
/*
|
||||||
|
PI4IOE5V6408-1 (0x44)
|
||||||
|
- Bit 0: C6 WLAN enable
|
||||||
|
- Bit 1: /
|
||||||
|
- Bit 2: /
|
||||||
|
- Bit 3: USB-A 5V enable
|
||||||
|
- Bit 4: Device power: PWROFF_PLUSE
|
||||||
|
- Bit 5: IP2326: nCHG_QC_EN
|
||||||
|
- Bit 6: IP2326: CHG_STAT_LED
|
||||||
|
- Bit 7: IP2326: CHG_EN
|
||||||
|
*/
|
||||||
|
constexpr auto GPIO_EXP1_PIN_C6_WLAN_ENABLE = 0;
|
||||||
|
constexpr auto GPIO_EXP1_PIN_USB_A_5V_ENABLE = 3;
|
||||||
|
constexpr auto GPIO_EXP1_PIN_DEVICE_POWER = 4;
|
||||||
|
constexpr auto GPIO_EXP1_PIN_IP2326_NCHG_QC_EN = 5;
|
||||||
|
constexpr auto GPIO_EXP1_PIN_IP2326_CHG_STAT_LED = 6;
|
||||||
|
constexpr auto GPIO_EXP1_PIN_IP2326_CHG_EN = 7;
|
||||||
|
|
||||||
|
static void initExpander0(::Device* io_expander0) {
|
||||||
|
auto* rf_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_RF_INTERNAL_EXTERNAL, GPIO_OWNER_GPIO);
|
||||||
|
check(rf_pin);
|
||||||
|
auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_OWNER_GPIO);
|
||||||
|
check(speaker_enable_pin);
|
||||||
|
auto* external_5v_bus_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_EXTERNAL_5V_BUS_ENABLE, GPIO_OWNER_GPIO);
|
||||||
|
check(external_5v_bus_enable_pin);
|
||||||
|
auto* lcd_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_LCD_RESET, GPIO_OWNER_GPIO);
|
||||||
|
check(lcd_reset_pin);
|
||||||
|
auto* touch_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_TOUCH_RESET, GPIO_OWNER_GPIO);
|
||||||
|
check(touch_reset_pin);
|
||||||
|
auto* camera_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_CAMERA_RESET, GPIO_OWNER_GPIO);
|
||||||
|
check(camera_reset_pin);
|
||||||
|
auto* headphone_detect_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_HEADPHONE_DETECT, GPIO_OWNER_GPIO);
|
||||||
|
check(headphone_detect_pin);
|
||||||
|
|
||||||
|
gpio_descriptor_set_flags(rf_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(speaker_enable_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(external_5v_bus_enable_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(lcd_reset_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(touch_reset_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(camera_reset_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(headphone_detect_pin, GPIO_FLAG_DIRECTION_INPUT);
|
||||||
|
|
||||||
|
gpio_descriptor_set_level(rf_pin, false);
|
||||||
|
gpio_descriptor_set_level(speaker_enable_pin, false);
|
||||||
|
gpio_descriptor_set_level(external_5v_bus_enable_pin, true);
|
||||||
|
gpio_descriptor_set_level(lcd_reset_pin, false);
|
||||||
|
gpio_descriptor_set_level(touch_reset_pin, false);
|
||||||
|
gpio_descriptor_set_level(camera_reset_pin, true);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
// Enable touch and lcd, but not the camera
|
||||||
|
gpio_descriptor_set_level(lcd_reset_pin, true);
|
||||||
|
gpio_descriptor_set_level(touch_reset_pin, true);
|
||||||
|
|
||||||
|
gpio_descriptor_release(rf_pin);
|
||||||
|
gpio_descriptor_release(speaker_enable_pin);
|
||||||
|
gpio_descriptor_release(external_5v_bus_enable_pin);
|
||||||
|
gpio_descriptor_release(lcd_reset_pin);
|
||||||
|
gpio_descriptor_release(touch_reset_pin);
|
||||||
|
gpio_descriptor_release(camera_reset_pin);
|
||||||
|
gpio_descriptor_release(headphone_detect_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initExpander1(::Device* io_expander1) {
|
||||||
|
|
||||||
|
auto* c6_wlan_enable_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_C6_WLAN_ENABLE, GPIO_OWNER_GPIO);
|
||||||
|
check(c6_wlan_enable_pin);
|
||||||
|
auto* usb_a_5v_enable_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_USB_A_5V_ENABLE, GPIO_OWNER_GPIO);
|
||||||
|
check(usb_a_5v_enable_pin);
|
||||||
|
auto* device_power_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_DEVICE_POWER, GPIO_OWNER_GPIO);
|
||||||
|
check(device_power_pin);
|
||||||
|
auto* ip2326_ncharge_qc_enable_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_NCHG_QC_EN, GPIO_OWNER_GPIO);
|
||||||
|
check(ip2326_ncharge_qc_enable_pin);
|
||||||
|
auto* ip2326_charge_state_led_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_CHG_STAT_LED, GPIO_OWNER_GPIO);
|
||||||
|
check(ip2326_charge_state_led_pin);
|
||||||
|
auto* ip2326_charge_enable_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_CHG_EN, GPIO_OWNER_GPIO);
|
||||||
|
check(ip2326_charge_enable_pin);
|
||||||
|
|
||||||
|
gpio_descriptor_set_flags(c6_wlan_enable_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(usb_a_5v_enable_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(device_power_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(ip2326_ncharge_qc_enable_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(ip2326_charge_state_led_pin, GPIO_FLAG_DIRECTION_OUTPUT);
|
||||||
|
gpio_descriptor_set_flags(ip2326_charge_enable_pin, GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP);
|
||||||
|
|
||||||
|
gpio_descriptor_set_level(c6_wlan_enable_pin, true);
|
||||||
|
gpio_descriptor_set_level(usb_a_5v_enable_pin, true);
|
||||||
|
gpio_descriptor_set_level(device_power_pin, false);
|
||||||
|
gpio_descriptor_set_level(ip2326_ncharge_qc_enable_pin, false);
|
||||||
|
gpio_descriptor_set_level(ip2326_charge_state_led_pin, false);
|
||||||
|
|
||||||
|
gpio_descriptor_release(c6_wlan_enable_pin);
|
||||||
|
gpio_descriptor_release(usb_a_5v_enable_pin);
|
||||||
|
gpio_descriptor_release(device_power_pin);
|
||||||
|
gpio_descriptor_release(ip2326_ncharge_qc_enable_pin);
|
||||||
|
gpio_descriptor_release(ip2326_charge_state_led_pin);
|
||||||
|
gpio_descriptor_release(ip2326_charge_enable_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio codec register programming is owned by the es8388-module/es7210-module drivers
|
||||||
|
// (registered as AUDIO_CODEC_TYPE devices, see m5stack,tab5.dts). This board still needs
|
||||||
|
// to drive the external speaker amplifier's enable line via io_expander0, which is board
|
||||||
|
// wiring glue rather than codec configuration, so it stays here.
|
||||||
|
static error_t enableSpeakerAmplifier(::Device* io_expander0) {
|
||||||
|
auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_OWNER_GPIO);
|
||||||
|
check(speaker_enable_pin, "Failed to acquire speaker enable pin");
|
||||||
|
error_t error = gpio_descriptor_set_level(speaker_enable_pin, true);
|
||||||
|
gpio_descriptor_release(speaker_enable_pin);
|
||||||
|
if (error != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "Failed to enable amplifier: %s", error_to_string(error));
|
||||||
|
return ERROR_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static esp_clock_output_mapping_handle_t camera_osc_handle = nullptr;
|
||||||
|
|
||||||
|
static void initCameraOsc() {
|
||||||
|
if (camera_osc_handle != nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 24 MHz clock on GPIO 36 for the SC2356 MIPI CSI sensor, required before esp_video_init.
|
||||||
|
// Uses SPLL (480 MHz) via esp_clock_output with divider 20 = 24 MHz exactly.
|
||||||
|
// This avoids any LEDC clock source conflict with the display backlight.
|
||||||
|
if (esp_clock_output_start(CLKOUT_SIG_SPLL, GPIO_NUM_36, &camera_osc_handle) != ESP_OK) {
|
||||||
|
LOG_E(TAG, "Camera OSC clock output start failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (esp_clock_output_set_divider(camera_osc_handle, 20) != ESP_OK) {
|
||||||
|
LOG_E(TAG, "Camera OSC clock divider set failed");
|
||||||
|
esp_clock_output_stop(camera_osc_handle);
|
||||||
|
camera_osc_handle = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG_I(TAG, "Camera OSC 24MHz started on GPIO 36 (SPLL/20)");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool initBoot() {
|
||||||
|
auto* io_expander0 = device_find_by_name("io_expander0");
|
||||||
|
check(io_expander0, "io_expander0 not found");
|
||||||
|
auto* io_expander1 = device_find_by_name("io_expander1");
|
||||||
|
check(io_expander1, "io_expander1 not found");
|
||||||
|
|
||||||
|
initCameraOsc();
|
||||||
|
initExpander0(io_expander0);
|
||||||
|
initExpander1(io_expander1);
|
||||||
|
|
||||||
|
error_t error = enableSpeakerAmplifier(io_expander0);
|
||||||
|
if (error != ERROR_NONE) {
|
||||||
|
LOG_E(TAG, "Failed to enable speaker amplifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Configuration hardwareConfiguration = {
|
||||||
|
.initBoot = initBoot,
|
||||||
|
.createDevices = createDevices
|
||||||
|
};
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#include "Detect.h"
|
||||||
|
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/drivers/i2c_controller.h>
|
||||||
|
#include <tactility/log.h>
|
||||||
|
#include <esp_lcd_touch_gt911.h>
|
||||||
|
#include <esp_lcd_touch_st7123.h>
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "Tab5Detect";
|
||||||
|
|
||||||
|
Tab5Variant detectVariant() {
|
||||||
|
// Allow time for touch IC to fully boot after expander reset in initBoot().
|
||||||
|
// 100ms is enough for I2C ACK (probe) but cold power-on needs ~300ms before
|
||||||
|
// register reads (read_fw_info) succeed reliably.
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
|
|
||||||
|
auto* i2c0 = device_find_by_name("i2c0");
|
||||||
|
check(i2c0);
|
||||||
|
|
||||||
|
constexpr auto PROBE_TIMEOUT = pdMS_TO_TICKS(50);
|
||||||
|
|
||||||
|
for (int attempt = 0; attempt < 3; ++attempt) {
|
||||||
|
// GT911 address depends on INT pin state during reset:
|
||||||
|
// GPIO 23 has a pull-up resistor to 3V3, so INT is high at reset → GT911 uses 0x5D (primary)
|
||||||
|
// It may also appear at 0x14 (backup) if the pin happened to be driven low
|
||||||
|
if (i2c_controller_has_device_at_address(i2c0, ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS, PROBE_TIMEOUT) == ERROR_NONE ||
|
||||||
|
i2c_controller_has_device_at_address(i2c0, ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP, PROBE_TIMEOUT) == ERROR_NONE) {
|
||||||
|
LOG_I(TAG, "Detected GT911 touch — using ILI9881C display");
|
||||||
|
return Tab5Variant::Ili9881c_Gt911;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probe for ST7123 touch (new variant)
|
||||||
|
if (i2c_controller_has_device_at_address(i2c0, ESP_LCD_TOUCH_IO_I2C_ST7123_ADDRESS, PROBE_TIMEOUT) == ERROR_NONE) {
|
||||||
|
LOG_I(TAG, "Detected ST7123 touch — using ST7123 display");
|
||||||
|
return Tab5Variant::St7123;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_W(TAG, "No known touch controller detected, defaulting to ST7123");
|
||||||
|
return Tab5Variant::St7123;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum class Tab5Variant {
|
||||||
|
Ili9881c_Gt911, // Older variant
|
||||||
|
St7123, // Newer variant (default)
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] Tab5Variant detectVariant();
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#include "Detect.h"
|
||||||
|
#include "Display.h"
|
||||||
|
#include "Ili9881cDisplay.h"
|
||||||
|
#include "St7123Display.h"
|
||||||
|
#include "St7123Touch.h"
|
||||||
|
|
||||||
|
#include <Gt911Touch.h>
|
||||||
|
#include <PwmBacklight.h>
|
||||||
|
#include <Tactility/hal/gpio/Gpio.h>
|
||||||
|
#include <tactility/check.h>
|
||||||
|
#include <tactility/device.h>
|
||||||
|
#include <tactility/log.h>
|
||||||
|
#include <freertos/FreeRTOS.h>
|
||||||
|
#include <freertos/task.h>
|
||||||
|
|
||||||
|
constexpr auto* TAG = "Tab5Display";
|
||||||
|
|
||||||
|
// LCD reset is wired to the PI4IOE5V6408 IO expander (io_expander0, bit 4), pulsed in
|
||||||
|
// Configuration.cpp's initExpander0() before display creation - not a direct SoC GPIO.
|
||||||
|
constexpr auto LCD_PIN_RESET = GPIO_NUM_NC;
|
||||||
|
constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_22;
|
||||||
|
|
||||||
|
static std::shared_ptr<tt::hal::touch::TouchDevice> createGt911Touch() {
|
||||||
|
auto* i2c = device_find_by_name("i2c0");
|
||||||
|
check(i2c);
|
||||||
|
auto configuration = std::make_unique<Gt911Touch::Configuration>(
|
||||||
|
i2c,
|
||||||
|
720,
|
||||||
|
1280,
|
||||||
|
false, // swapXY
|
||||||
|
false, // mirrorX
|
||||||
|
false, // mirrorY
|
||||||
|
GPIO_NUM_NC, // reset pin
|
||||||
|
GPIO_NUM_NC // "GPIO_NUM_23 cannot be used due to resistor to 3V3"
|
||||||
|
// https://github.com/espressif/esp-bsp/blob/ad668c765cbad177495a122181df0a70ff9f8f61/bsp/m5stack_tab5/src/m5stack_tab5.c#L76234
|
||||||
|
);
|
||||||
|
return std::make_shared<Gt911Touch>(std::move(configuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<tt::hal::touch::TouchDevice> createSt7123Touch() {
|
||||||
|
auto* i2c = device_find_by_name("i2c0");
|
||||||
|
check(i2c, "i2c0 not found");
|
||||||
|
auto configuration = std::make_unique<St7123Touch::Configuration>(
|
||||||
|
i2c,
|
||||||
|
720,
|
||||||
|
1280,
|
||||||
|
false, // swapXY
|
||||||
|
false, // mirrorX
|
||||||
|
false, // mirrorY
|
||||||
|
GPIO_NUM_23 // interrupt pin
|
||||||
|
);
|
||||||
|
return std::make_shared<St7123Touch>(std::move(configuration));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
||||||
|
// Initialize PWM backlight
|
||||||
|
if (!driver::pwmbacklight::init(LCD_PIN_BACKLIGHT, 5000, LEDC_TIMER_1, LEDC_CHANNEL_0)) {
|
||||||
|
LOG_W(TAG, "Failed to initialize backlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab5Variant variant = detectVariant();
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::touch::TouchDevice> touch;
|
||||||
|
|
||||||
|
if (variant == Tab5Variant::St7123) {
|
||||||
|
touch = createSt7123Touch();
|
||||||
|
} else {
|
||||||
|
touch = createGt911Touch();
|
||||||
|
|
||||||
|
// Work-around to init GT911 touch: interrupt pin must be set to low
|
||||||
|
// Note: There is a resistor to 3V3 on interrupt pin which is blocking GT911 touch
|
||||||
|
// See https://github.com/espressif/esp-bsp/blob/ad668c765cbad177495a122181df0a70ff9f8f61/bsp/m5stack_tab5/src/m5stack_tab5.c#L777
|
||||||
|
tt::hal::gpio::configure(23, tt::hal::gpio::Mode::Output, true, false);
|
||||||
|
tt::hal::gpio::setLevel(23, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto configuration = std::make_shared<EspLcdConfiguration>(EspLcdConfiguration {
|
||||||
|
.horizontalResolution = 720,
|
||||||
|
.verticalResolution = 1280,
|
||||||
|
.gapX = 0,
|
||||||
|
.gapY = 0,
|
||||||
|
.monochrome = false,
|
||||||
|
.swapXY = false,
|
||||||
|
.mirrorX = false,
|
||||||
|
.mirrorY = false,
|
||||||
|
.invertColor = false,
|
||||||
|
.bufferSize = 0, // 0 = default (1/10 of screen)
|
||||||
|
.swRotate = true,
|
||||||
|
.buffSpiram = true,
|
||||||
|
.touch = touch,
|
||||||
|
.backlightDutyFunction = driver::pwmbacklight::setBacklightDuty,
|
||||||
|
.resetPin = LCD_PIN_RESET,
|
||||||
|
.lvglColorFormat = LV_COLOR_FORMAT_RGB565,
|
||||||
|
.lvglSwapBytes = false,
|
||||||
|
.rgbElementOrder = LCD_RGB_ELEMENT_ORDER_RGB,
|
||||||
|
.bitsPerPixel = 16
|
||||||
|
});
|
||||||
|
|
||||||
|
if (variant == Tab5Variant::St7123) {
|
||||||
|
return std::static_pointer_cast<tt::hal::display::DisplayDevice>(
|
||||||
|
std::make_shared<St7123Display>(configuration)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return std::static_pointer_cast<tt::hal::display::DisplayDevice>(
|
||||||
|
std::make_shared<Ili9881cDisplay>(configuration)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Tactility/hal/display/DisplayDevice.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay();
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user