Merge branch 'main' into usbhost-refactored

This commit is contained in:
Ken Van Hoeylandt 2026-10-10 01:00:08 +02:00
commit 321ced744f
130 changed files with 1612 additions and 499 deletions

0
Buildscripts/Flashing/merge.sh Normal file → Executable file
View File

View File

@ -124,10 +124,8 @@ else ()
add_compile_definitions(CONFIG_TT_DEVICE_NAME="Simulator")
add_compile_definitions(CONFIG_TT_DEVICE_VENDOR="")
add_compile_definitions(CONFIG_TT_DEVICE_NAME_SIMPLE="Simulator")
add_compile_definitions(CONFIG_TT_LAUNCHER_APP_ID="tactility.launcher")
add_compile_definitions(CONFIG_TT_AUTO_START_APP_ID="")
add_compile_definitions(CONFIG_TT_USER_DATA_LOCATION_INTERNAL)
add_compile_definitions(CONFIG_TT_LVGL_STATUSBAR_COLORS_INVERTED=false)
endif ()

View File

@ -1,8 +1,6 @@
general.vendor=BigTreeTech
general.name=Panda Touch,K Touch
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -26,9 +26,9 @@
};
// Top Stemma/Qwiic port 1 shares this bus with the RTC (SDA: pin 1 <-> SCL: pin 2). External
// I2C devices on that port are reachable via i2c0. The tca8418 keyboard (revision 2 hardware)
// and power-supply chip (revision 3 hardware) are mutually exclusive on this bus and are
// created dynamically based on hardware detection - see cl32_detect.cpp.
// I2C devices on that port are reachable via i2c0. The tca8418 keyboard has a different layout
// on revision 2 and 3 hardware and is created dynamically based on hardware detection, see
// cl32_detect.cpp.
i2c0 {
compatible = "espressif,esp32-i2c-master";
port = <I2C_NUM_0>;

View File

@ -1,10 +1,8 @@
general.vendor=CL-32
general.name=CL-32
apps.launcherAppId=tactility.launcher
general.name=CL-32 v0.2 v0.3
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.flashSize=16MB
hardware.spiRam=true
hardware.spiRamMode=QUAD
hardware.spiRamSpeed=80M
@ -20,6 +18,5 @@ display.dpi=139
lvgl.colorDepth=8
lvgl.theme=Mono
lvgl.uiDensity=compact
lvgl.statusbarColorsInverted=true
cdn.warningMessage=Only hardware revision 0.2 and 0.3 are supported for now!
cdn.infoMessage=This variant supports hardware revision v0.2 and v0.3.

View File

@ -3,4 +3,4 @@ dependencies:
- Drivers/tca8418-module
- Drivers/esp-epaper-module
- Drivers/bm8563-module
dts: cl32.dts
dts: cl32-v02-v03.dts

View File

@ -0,0 +1,78 @@
// SPDX-License-Identifier: Apache-2.0
#include "cl32_detect.h"
#include "cl32_v2_keyboard.h"
#include "cl32_v3_keyboard.h"
#include "cl32_v3.h"
#include <tactility/device.h>
#include <tactility/device_listener.h>
#include <tactility/drivers/i2c_controller.h>
#include <tactility/log.h>
#include <cstring>
constexpr auto* TAG = "cl32-detect";
// Revision 2 and 3 boards are both plain tca8418 keyboards with different physical key layouts.
// Revision 3 boards also have a fuel gauge.
static Cl32HardwareRevision cl32_revision = Cl32HardwareRevision::Unknown;
// The probe-once latch for on_i2c0_started(). File-scope (not function-local) so
// cl32_teardown_devices() can reset it for a later start/probe cycle.
static bool did_probe = false;
static Cl32HardwareRevision cl32_detect(Device* i2c0) {
if (i2c_controller_has_device_at_address(i2c0, CL32_V3_FUEL_GAUGE_I2C_ADDRESS, CL32_V3_TIMEOUT) == ERROR_NONE) {
LOG_I(TAG, "Detected V3 hardware by MAX17048G fuel gauge presence");
return Cl32HardwareRevision::Revision3;
}
LOG_I(TAG, "No fuel gauge detected, assuming revision 2 hardware");
return Cl32HardwareRevision::Revision2;
}
// Fires for every device's start/stop in the system.
static void on_i2c0_started(Device* device, DeviceEvent event, void* context) {
(void)context;
if (did_probe || event != DEVICE_EVENT_STARTED || strcmp(device->name, "i2c0") != 0) {
return;
}
did_probe = true;
cl32_revision = cl32_detect(device);
switch (cl32_revision) {
case Cl32HardwareRevision::Revision2:
cl32_create_keyboard(device);
break;
case Cl32HardwareRevision::Revision3:
cl32_v3_create_keyboard(device);
break;
default:
LOG_W(TAG, "Unknown/unsupported hardware revision");
break;
}
}
Cl32HardwareRevision cl32_hardware_revision() {
return cl32_revision;
}
void cl32_teardown_devices() {
// The keyboards bind the shared ti,tca8418 driver (owned by tca8418-module), so they don't block
// this module's driver destruction. They are torn down so a later start can recreate them.
cl32_destroy_keyboard();
cl32_v3_destroy_keyboard();
did_probe = false;
}
void cl32_power_detect_start() {
device_listener_add(on_i2c0_started, nullptr);
}
void cl32_power_detect_stop() {
device_listener_remove(on_i2c0_started, nullptr);
}

View File

@ -4,7 +4,6 @@ enum class Cl32HardwareRevision {
Unknown,
Revision2,
Revision3,
Revision4,
};
Cl32HardwareRevision cl32_hardware_revision();

View File

@ -1,8 +1,6 @@
#include <tactility/module.h>
#include "cl32_detect.h"
#include "cl32_v4_keyboard.h"
#include "cl32_v4_power.h"
extern "C" {
@ -18,13 +16,10 @@ static error_t stop() {
}
static Driver* const cl32_drivers[] = {
&cl32_v4_power_driver,
&cl32_v4_power_supply_driver,
&cl32_v4_keyboard_driver,
nullptr
};
Module cl32_module = {
Module cl32_v02_v03_module = {
.name = "cl32",
.start = start,
.stop = stop,

View File

@ -0,0 +1,7 @@
file(GLOB_RECURSE SOURCE_FILES source/*.c*)
idf_component_register(
SRCS ${SOURCE_FILES}
INCLUDE_DIRS "source"
REQUIRES TactilityKernel
)

View File

@ -0,0 +1,195 @@
Apache License
==============
_Version 2.0, January 2004_
_&lt;<http://www.apache.org/licenses/>&gt;_
### Terms and Conditions for use, reproduction, and distribution
#### 1. Definitions
“License” shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, “control” means **(i)** the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
outstanding shares, or **(iii)** beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising
permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
“Object” form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
“submitted” means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
#### 2. Grant of Copyright License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
#### 3. Grant of Patent License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
#### 4. Redistribution
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
this License; and
* **(b)** You must cause any modified files to carry prominent notices stating that You
changed the files; and
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
#### 5. Submission of Contributions
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
#### 6. Trademarks
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
#### 7. Disclaimer of Warranty
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
#### 8. Limitation of Liability
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
#### 9. Accepting Warranty or Additional Liability
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
_END OF TERMS AND CONDITIONS_
### APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets `[]` replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same “printed page” as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,7 @@
description: CL-32 v0.4 keyboard, provided by the core chip
include: ["i2c-device.yaml"]
compatible: "cl32-v4-keyboard"
bus: i2c

View File

@ -0,0 +1,23 @@
description: CL-32 v0.4 display light, provided by the core chip
include: ["i2c-device.yaml"]
compatible: "cl32-v4-light"
bus: i2c
properties:
brightness-register:
type: int
description: Register that holds the brightness level (0-255)
timeout-register:
type: int
description: Register that holds the timeout in seconds
brightness-default:
type: int
default: 255
description: Default brightness level (0-255), applied by set_brightness_default()
timeout-seconds:
type: int
default: 10
description: Seconds of inactivity after which the core chip turns the light off. 0 keeps the chip's own setting.

View File

@ -0,0 +1,7 @@
description: CL-32 v0.4 battery voltage and power off, provided by the core chip
include: ["i2c-device.yaml"]
compatible: "cl32-v4-power"
bus: i2c

View File

@ -0,0 +1,107 @@
/dts-v1/;
#include <tactility/bindings/root.h>
#include <tactility/bindings/esp32_gpio.h>
#include <tactility/bindings/esp32_grove.h>
#include <tactility/bindings/esp32_i2c_master.h>
#include <tactility/bindings/esp32_spi.h>
#include <tactility/bindings/esp32_sdspi.h>
#include <tactility/bindings/esp32_wifi.h>
#include <bindings/bm8563.h>
#include <bindings/cl32_v4_light.h>
#include <bindings/cl32_v4_keyboard.h>
#include <bindings/cl32_v4_power.h>
#include <bindings/st7305.h>
/ {
compatible = "root";
model = "CL-32";
gpio0 {
compatible = "espressif,esp32-gpio";
gpio-count = <49>;
};
wifi0 {
compatible = "espressif,esp32-wifi";
status = "disabled";
};
// Top Stemma/Qwiic port 1 shares this bus with the RTC (SDA: pin 1 <-> SCL: pin 2). External
// I2C devices on that port are reachable via i2c0.
i2c0 {
compatible = "espressif,esp32-i2c-master";
port = <I2C_NUM_0>;
clock-frequency = <100000>;
pin-sda = <&gpio0 1 GPIO_FLAG_PULL_UP>;
pin-scl = <&gpio0 2 GPIO_FLAG_PULL_UP>;
rtc: bm8563 {
compatible = "belling,bm8563";
reg = <0x51>;
};
// The core chip provides both the keyboard and the power functions
keyboard {
compatible = "cl32-v4-keyboard";
reg = <0x08>;
};
power {
compatible = "cl32-v4-power";
reg = <0x08>;
};
back_light {
compatible = "cl32-v4-light";
reg = <0x08>;
brightness-register = <0x0F>;
timeout-register = <0x10>;
};
front_light {
compatible = "cl32-v4-light";
status = "disabled"; // Will be in future hardware
reg = <0x08>;
brightness-register = <0x11>;
timeout-register = <0x12>;
};
};
port_b: grove1 {
compatible = "espressif,esp32-grove";
defaultMode = <GROVE_MODE_I2C>;
pinSdaTx = <&gpio0 47 GPIO_FLAG_NONE>;
pinSclRx = <&gpio0 48 GPIO_FLAG_NONE>;
uartPort = <UART_NUM_1>;
i2cPort = <I2C_NUM_1>;
i2cClockFrequency = <100000>;
};
spi1 {
compatible = "espressif,esp32-spi";
host = <SPI2_HOST>;
cs-gpios = <&gpio0 7 GPIO_FLAG_NONE>,
<&gpio0 6 GPIO_FLAG_NONE>;
pin-mosi = <&gpio0 10 GPIO_FLAG_NONE>;
pin-miso = <&gpio0 11 GPIO_FLAG_NONE>;
pin-sclk = <&gpio0 9 GPIO_FLAG_NONE>;
max-transfer-size = <4096>;
sdcard@0 {
compatible = "espressif,esp32-sdspi";
frequency-khz = <20000>;
};
display@1 {
compatible = "sitronix,st7305";
pin-dc = <&gpio0 13 GPIO_FLAG_NONE>;
pin-reset = <&gpio0 12 GPIO_FLAG_NONE>;
pixel-clock-hz = <80000000>;
mirror-x;
mirror-y;
backlight = <&back_light>;
};
};
};

View File

@ -0,0 +1,22 @@
general.vendor=CL-32
general.name=CL-32 v0.4
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.spiRam=true
hardware.spiRamMode=OCT
hardware.spiRamSpeed=80M
hardware.spiRamXipDisabled=true
hardware.esptoolFlashFreq=80M
hardware.bluetooth=true
storage.userDataLocation=SD
display.size=2.9"
display.dpi=139
lvgl.colorDepth=8
lvgl.theme=Mono
lvgl.uiDensity=compact
cdn.infoMessage=This variant supports hardware revision v0.4 with the reflective LCD.

View File

@ -0,0 +1,6 @@
dependencies:
- Platforms/platform-esp32
- Drivers/bm8563-module
- Drivers/st7305-module
bindings: bindings
dts: cl32-v04.dts

View File

@ -0,0 +1,6 @@
#pragma once
#include <tactility/bindings/bindings.h>
#include <cl32_v4_keyboard.h>
DEFINE_DEVICETREE(cl32_v4_keyboard, struct Cl32V4KeyboardConfig)

View File

@ -0,0 +1,6 @@
#pragma once
#include <tactility/bindings/bindings.h>
#include <cl32_v4_light.h>
DEFINE_DEVICETREE(cl32_v4_light, struct Cl32V4LightConfig)

View File

@ -0,0 +1,6 @@
#pragma once
#include <tactility/bindings/bindings.h>
#include <cl32_v4_power.h>
DEFINE_DEVICETREE(cl32_v4_power, struct Cl32V4PowerConfig)

View File

@ -4,6 +4,4 @@
#include <cstdint>
constexpr uint8_t CL32_V4_KEYBOARD_PROBE_REGISTER = 0x02;
constexpr uint8_t CL32_V4_CORE_I2C_ADDRESS = 0x08;
constexpr TickType_t CL32_V4_CORE_TIMEOUT = pdMS_TO_TICKS(50);

View File

@ -9,10 +9,12 @@
#include <new>
extern Module cl32_module;
extern Module cl32_v04_module;
constexpr auto* TAG = "cl32-v4-keyboard";
#define GET_CONFIG(device) (static_cast<const Cl32V4KeyboardConfig*>((device)->config))
// v4's core chip reports keyboard events on the same I2C address as the power-supply function
// (see cl32_v4_power.h) - CL-32/CL-32's CL32_core class talks to both over one address.
// Registers below come from that project's regMap.h (CL32_INTERRUPT/EVENT_COUNT/EVENT1).
@ -27,12 +29,13 @@ constexpr uint8_t MAX_EVENTS_PER_DRAIN = 16;
// HID Keyboard/Keypad usage codes (USB HID Usage Tables page 0x07) this chip's matrix produces,
// named after CL-32/CL-32's CL32_core::_matrix keymap (CL32_core.cpp).
constexpr uint8_t KEY_FN = 0x3A; // repurposed F1 position
constexpr uint8_t KEY_FILE = 0x43; // repurposed F10 position
constexpr uint8_t KEY_MENU = 0x44; // repurposed F11 position
constexpr uint8_t KEY_FN = 0x65;
constexpr uint8_t KEY_FILE = 0x76;
constexpr uint8_t KEY_MENU = 0x74;
constexpr uint8_t KEY_ENTER = 0x28;
constexpr uint8_t KEY_ESCAPE = 0x29;
constexpr uint8_t KEY_BACKSPACE = 0x2A;
constexpr uint8_t KEY_TAB = 0x2B;
constexpr uint8_t KEY_SPACE = 0x2C;
constexpr uint8_t KEY_EQUALS = 0x2E;
constexpr uint8_t KEY_PERIOD = 0x37;
@ -40,6 +43,8 @@ constexpr uint8_t KEY_ARROW_RIGHT = 0x4F;
constexpr uint8_t KEY_ARROW_LEFT = 0x50;
constexpr uint8_t KEY_ARROW_DOWN = 0x51;
constexpr uint8_t KEY_ARROW_UP = 0x52;
constexpr uint8_t KEY_YES = 0x77;
constexpr uint8_t KEY_NO = 0x78;
constexpr uint8_t KEYPAD_SLASH = 0x54;
constexpr uint8_t KEYPAD_ASTERISK = 0x55;
constexpr uint8_t KEYPAD_MINUS = 0x56;
@ -49,7 +54,7 @@ constexpr uint8_t KEYPAD_1 = 0x59;
constexpr uint8_t KEYPAD_9 = 0x61;
constexpr uint8_t KEYPAD_0 = 0x62;
constexpr uint8_t KEYPAD_PERIOD = 0x63;
constexpr uint8_t KEY_SHIFT = 0xE1;
constexpr uint8_t KEY_SHIFT = 0x7F;
enum class ToggleState { Unpressed, OnePress, Locked };
@ -143,6 +148,7 @@ static bool translate_key(uint8_t code, bool shift, bool fn, uint32_t* out_key)
switch (code) {
case KEY_ENTER: *out_key = CODEPOINT_ENTER; return true;
case KEY_TAB: *out_key = CODEPOINT_TAB; return true;
case KEY_ESCAPE: *out_key = CODEPOINT_ESCAPE; return true;
case KEY_BACKSPACE: *out_key = CODEPOINT_BACKSPACE; return true;
case KEY_SPACE: *out_key = ' '; return true;
@ -152,6 +158,8 @@ static bool translate_key(uint8_t code, bool shift, bool fn, uint32_t* out_key)
case KEY_ARROW_LEFT: *out_key = CODEPOINT_ARROW_LEFT; return true;
case KEY_ARROW_DOWN: *out_key = CODEPOINT_ARROW_DOWN; return true;
case KEY_ARROW_UP: *out_key = CODEPOINT_ARROW_UP; return true;
case KEY_YES: *out_key = CODEPOINT_YES; return true;
case KEY_NO: *out_key = CODEPOINT_NO; return true;
case KEYPAD_SLASH: *out_key = '/'; return true;
case KEYPAD_ASTERISK: *out_key = '*'; return true;
case KEYPAD_MINUS: *out_key = '-'; return true;
@ -171,12 +179,12 @@ static bool translate_key(uint8_t code, bool shift, bool fn, uint32_t* out_key)
static void handle_key_down(Cl32V4KeyboardInternal* internal, uint8_t code) {
if (code == KEY_SHIFT) {
internal->shift_state = next_toggle_state(internal->shift_state);
LOG_I(TAG, "code=0x%02X shift -> %s", code, toggle_state_name(internal->shift_state));
LOG_D(TAG, "code=0x%02X shift -> %s", code, toggle_state_name(internal->shift_state));
return;
}
if (code == KEY_FN) {
internal->fn_state = next_toggle_state(internal->fn_state);
LOG_I(TAG, "code=0x%02X fn -> %s", code, toggle_state_name(internal->fn_state));
LOG_D(TAG, "code=0x%02X fn -> %s", code, toggle_state_name(internal->fn_state));
return;
}
@ -186,7 +194,7 @@ static void handle_key_down(Cl32V4KeyboardInternal* internal, uint8_t code) {
// No app-level menu system at the driver layer - surface the raw HID code only, same as
// tab5_keyboard.cpp's F1-F12 handling.
if (code == KEY_MENU || code == KEY_FILE) {
LOG_I(TAG, "code=0x%02X (menu/file) shift=%s fn=%s hid_modifier=0x%02X",
LOG_D(TAG, "code=0x%02X (menu/file) shift=%s fn=%s hid_modifier=0x%02X",
code, toggle_state_name(internal->shift_state), toggle_state_name(internal->fn_state), hid_modifier);
push_pending(internal, 0, true, code, hid_modifier);
push_pending(internal, 0, false, code, hid_modifier);
@ -198,7 +206,7 @@ static void handle_key_down(Cl32V4KeyboardInternal* internal, uint8_t code) {
const bool has_key = translate_key(code, shift, fn, &key);
const char printable = (has_key && key >= 0x20 && key < 0x7F) ? static_cast<char>(key) : '.';
LOG_I(TAG, "code=0x%02X key='%c' key_hex=0x%04X shift=%s fn=%s hid_modifier=0x%02X",
LOG_D(TAG, "code=0x%02X key='%c' key_hex=0x%04X shift=%s fn=%s hid_modifier=0x%02X",
code, printable, static_cast<unsigned int>(has_key ? key : 0),
toggle_state_name(internal->shift_state), toggle_state_name(internal->fn_state), hid_modifier);
@ -216,9 +224,9 @@ static void handle_key_down(Cl32V4KeyboardInternal* internal, uint8_t code) {
}
}
static void drain_events(Device* i2c0, Cl32V4KeyboardInternal* internal) {
static void drain_events(Device* i2c0, uint8_t address, Cl32V4KeyboardInternal* internal) {
uint8_t interrupt_status = 0;
if (i2c_controller_register8_get(i2c0, CL32_V4_CORE_I2C_ADDRESS, REG_INTERRUPT, &interrupt_status, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
if (i2c_controller_register8_get(i2c0, address, REG_INTERRUPT, &interrupt_status, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
return;
}
if ((interrupt_status & INTERRUPT_BIT_KEYBOARD) == 0) {
@ -226,38 +234,38 @@ static void drain_events(Device* i2c0, Cl32V4KeyboardInternal* internal) {
}
uint8_t count = 0;
if (i2c_controller_register8_get(i2c0, CL32_V4_CORE_I2C_ADDRESS, REG_EVENT_COUNT, &count, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
if (i2c_controller_register8_get(i2c0, address, REG_EVENT_COUNT, &count, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
return;
}
for (uint8_t drained = 0; drained < MAX_EVENTS_PER_DRAIN && count > 0; drained++) {
uint8_t raw = 0;
if (i2c_controller_register8_get(i2c0, CL32_V4_CORE_I2C_ADDRESS, REG_EVENT1, &raw, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
if (i2c_controller_register8_get(i2c0, address, REG_EVENT1, &raw, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
break;
}
LOG_I(TAG, "raw event=0x%02X (%s)", raw, (raw & 0x80) != 0 ? "down" : "up");
LOG_D(TAG, "raw event=0x%02X (%s)", raw, (raw & 0x80) != 0 ? "down" : "up");
if ((raw & 0x80) != 0) {
handle_key_down(internal, static_cast<uint8_t>(raw & 0x7F));
}
if (i2c_controller_register8_get(i2c0, CL32_V4_CORE_I2C_ADDRESS, REG_EVENT_COUNT, &count, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
if (i2c_controller_register8_get(i2c0, address, REG_EVENT_COUNT, &count, CL32_V4_CORE_TIMEOUT) != ERROR_NONE) {
break;
}
}
// Only the keyboard bit is ours to clear - the power-supply function on this same chip owns
// the other status bits in this register.
i2c_controller_register8_reset_bits(i2c0, CL32_V4_CORE_I2C_ADDRESS, REG_INTERRUPT, INTERRUPT_BIT_KEYBOARD, CL32_V4_CORE_TIMEOUT);
i2c_controller_register8_reset_bits(i2c0, address, REG_INTERRUPT, INTERRUPT_BIT_KEYBOARD, CL32_V4_CORE_TIMEOUT);
}
static error_t v3_read_key(Device* device, KeyboardKeyData* data) {
static error_t v4_read_key(Device* device, KeyboardKeyData* data) {
auto* internal = static_cast<Cl32V4KeyboardInternal*>(device_get_driver_data(device));
Cl32V4KeyEvent event;
if (internal->pending_count == 0) {
drain_events(device_get_parent(device), internal);
drain_events(device_get_parent(device), GET_CONFIG(device)->address, internal);
}
if (pop_pending(internal, &event)) {
@ -282,7 +290,7 @@ static error_t v3_read_key(Device* device, KeyboardKeyData* data) {
}
static constexpr KeyboardApi cl32_v4_keyboard_api = {
.read_key = v3_read_key,
.read_key = v4_read_key,
.get_backlight = nullptr,
.is_present = nullptr,
};
@ -313,52 +321,9 @@ Driver cl32_v4_keyboard_driver = {
.compatible = (const char*[]) { "cl32-v4-keyboard", nullptr },
.start_device = start,
.stop_device = stop,
.probe = nullptr,
.api = &cl32_v4_keyboard_api,
.device_type = &KEYBOARD_TYPE,
.owner = &cl32_module,
.internal = nullptr
.owner = &cl32_v04_module,
.internal = nullptr,
};
static Device cl32_v4_keyboard_device {};
static bool cl32_v4_keyboard_created = false;
bool cl32_v4_create_keyboard(Device* i2c0) {
cl32_v4_keyboard_device = Device { .address = 0, .name = "cl32-v4-keyboard", .config = nullptr, .parent = nullptr, .flags = 0, .internal = nullptr };
error_t error = device_construct(&cl32_v4_keyboard_device);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to construct keyboard: %s", error_to_string(error));
return false;
}
device_set_parent(&cl32_v4_keyboard_device, i2c0);
device_set_driver(&cl32_v4_keyboard_device, &cl32_v4_keyboard_driver);
error = device_add(&cl32_v4_keyboard_device);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to add keyboard: %s", error_to_string(error));
device_destruct(&cl32_v4_keyboard_device);
return false;
}
error = device_start(&cl32_v4_keyboard_device);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to start keyboard: %s", error_to_string(error));
device_remove(&cl32_v4_keyboard_device);
device_destruct(&cl32_v4_keyboard_device);
return false;
}
cl32_v4_keyboard_created = true;
return true;
}
void cl32_v4_destroy_keyboard() {
if (!cl32_v4_keyboard_created) {
return;
}
device_stop(&cl32_v4_keyboard_device);
device_remove(&cl32_v4_keyboard_device);
device_destruct(&cl32_v4_keyboard_device);
cl32_v4_keyboard_created = false;
}

View File

@ -0,0 +1,19 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <tactility/driver.h>
struct Cl32V4KeyboardConfig {
uint8_t address;
};
extern struct Driver cl32_v4_keyboard_driver;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,75 @@
// SPDX-License-Identifier: Apache-2.0
#include "cl32_v4_light.h"
#include "cl32_v4.h"
#include <tactility/device.h>
#include <tactility/drivers/backlight.h>
#include <tactility/drivers/i2c_controller.h>
#include <tactility/log.h>
#include <tactility/module.h>
extern Module cl32_v04_module;
constexpr auto* TAG = "cl32-v4-light";
#define GET_CONFIG(device) (static_cast<const Cl32V4LightConfig*>((device)->config))
static error_t set_brightness(Device* device, uint8_t brightness) {
return i2c_controller_register8_set(device_get_parent(device), GET_CONFIG(device)->address, GET_CONFIG(device)->brightness_register, brightness, CL32_V4_CORE_TIMEOUT);
}
static error_t set_brightness_default(Device* device) {
return set_brightness(device, GET_CONFIG(device)->brightness_default);
}
static error_t get_brightness(Device* device, uint8_t* out_brightness) {
return i2c_controller_register8_get(device_get_parent(device), GET_CONFIG(device)->address, GET_CONFIG(device)->brightness_register, out_brightness, CL32_V4_CORE_TIMEOUT);
}
static constexpr BacklightApi CL32_V4_LIGHT_API = {
.set_brightness = set_brightness,
.set_brightness_default = set_brightness_default,
.get_brightness = get_brightness,
.get_min_brightness = nullptr,
.get_max_brightness = nullptr,
};
static error_t start(Device* device) {
auto* i2c0 = device_get_parent(device);
if (device_get_type(i2c0) != &I2C_CONTROLLER_TYPE) {
LOG_E(TAG, "Parent is not an I2C controller");
return ERROR_RESOURCE;
}
const auto* config = GET_CONFIG(device);
if (config->timeout_seconds > 0) {
auto timeout_value = config->timeout_seconds * 15;
if (timeout_value > 255) {
timeout_value = 255;
}
error_t error = i2c_controller_register8_set(i2c0, config->address, config->timeout_register, static_cast<uint8_t>(timeout_value), CL32_V4_CORE_TIMEOUT);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to set timeout");
return error;
}
}
return ERROR_NONE;
}
static error_t stop(Device*) {
return ERROR_NONE;
}
Driver cl32_v4_light_driver = {
.name = "cl32-v4-light",
.compatible = (const char*[]) { "cl32-v4-light", nullptr },
.start_device = start,
.stop_device = stop,
.probe = nullptr,
.api = &CL32_V4_LIGHT_API,
.device_type = &BACKLIGHT_TYPE,
.owner = &cl32_v04_module,
.internal = nullptr,
};

View File

@ -0,0 +1,23 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <tactility/driver.h>
struct Cl32V4LightConfig {
uint8_t address;
uint8_t brightness_register;
uint8_t timeout_register;
uint8_t brightness_default;
uint8_t timeout_seconds;
};
extern struct Driver cl32_v4_light_driver;
#ifdef __cplusplus
}
#endif

View File

@ -11,10 +11,15 @@
#include <new>
extern Module cl32_module;
extern Module cl32_v04_module;
constexpr auto* TAG = "cl32-v4-power";
#define GET_CONFIG(device) (static_cast<const Cl32V4PowerConfig*>((device)->config))
constexpr uint8_t REG_POWER_CONTROL = 0x01;
constexpr uint8_t POWER_CONTROL_CUT_POWER = 0x80;
constexpr uint8_t BAT_VOLTAGE = 0x13;
constexpr uint8_t REG_VOLTAGE = 0x14;
constexpr int MV_PER_LSB = 25;
constexpr int MIN_MV = 3200;
@ -31,7 +36,7 @@ static bool ps_supports_property(Device*, PowerSupplyProperty property) {
static error_t read_battery_mv(Device* chip_device, int* out_mv) {
auto* i2c0 = device_get_parent(chip_device);
uint8_t raw = 0;
error_t error = i2c_controller_register8_get(i2c0, CL32_V4_CORE_I2C_ADDRESS, REG_VOLTAGE, &raw, CL32_V4_CORE_TIMEOUT);
error_t error = i2c_controller_register8_get(i2c0, GET_CONFIG(chip_device)->address, BAT_VOLTAGE, &raw, CL32_V4_CORE_TIMEOUT);
if (error != ERROR_NONE) {
return error;
}
@ -66,8 +71,13 @@ static error_t ps_set_allowed_to_charge(Device*, bool) { return ERROR_NOT_SUPPOR
static bool ps_supports_quick_charge(Device*) { return false; }
static bool ps_is_quick_charge_enabled(Device*) { return false; }
static error_t ps_set_quick_charge_enabled(Device*, bool) { return ERROR_NOT_SUPPORTED; }
static bool ps_supports_power_off(Device*) { return false; }
static error_t ps_power_off(Device*) { return ERROR_NOT_SUPPORTED; }
static bool ps_supports_power_off(Device*) { return true; }
static error_t ps_power_off(Device* device) {
auto* chip_device = device_get_parent(device);
auto* i2c0 = device_get_parent(chip_device);
return i2c_controller_register8_set_bits(i2c0, GET_CONFIG(chip_device)->address, REG_POWER_CONTROL, POWER_CONTROL_CUT_POWER, CL32_V4_CORE_TIMEOUT);
}
static constexpr PowerSupplyApi CL32_V4_POWER_SUPPLY_API = {
.supports_property = ps_supports_property,
@ -82,7 +92,7 @@ static constexpr PowerSupplyApi CL32_V4_POWER_SUPPLY_API = {
.power_off = ps_power_off,
};
// Registered in cl32_module's driver list so driver_bind() has a valid ->internal, but never
// Registered in cl32_v04_module's driver list so driver_bind() has a valid ->internal, but never
// matched against a devicetree node: wired up directly by pointer from cl32_v4_power_driver's start().
Driver cl32_v4_power_supply_driver = {
.name = "cl32-v4-power-supply",
@ -91,7 +101,7 @@ Driver cl32_v4_power_supply_driver = {
.stop_device = nullptr,
.api = &CL32_V4_POWER_SUPPLY_API,
.device_type = &POWER_SUPPLY_TYPE,
.owner = &cl32_module,
.owner = &cl32_v04_module,
.internal = nullptr
};
@ -179,8 +189,9 @@ Driver cl32_v4_power_driver = {
.compatible = (const char*[]) { "cl32-v4-power", nullptr },
.start_device = start,
.stop_device = stop,
.probe = nullptr,
.api = nullptr,
.device_type = nullptr,
.owner = &cl32_module,
.internal = nullptr
.owner = &cl32_v04_module,
.internal = nullptr,
};

View File

@ -0,0 +1,20 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <tactility/driver.h>
struct Cl32V4PowerConfig {
uint8_t address;
};
extern struct Driver cl32_v4_power_driver;
extern struct Driver cl32_v4_power_supply_driver;
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,26 @@
#include <tactility/module.h>
#include "cl32_v4_light.h"
#include "cl32_v4_keyboard.h"
#include "cl32_v4_power.h"
extern "C" {
static Driver* const cl32_drivers[] = {
&cl32_v4_power_driver,
&cl32_v4_power_supply_driver,
&cl32_v4_keyboard_driver,
&cl32_v4_light_driver,
nullptr
};
Module cl32_v04_module = {
.name = "cl32",
.start = nullptr,
.stop = nullptr,
.drivers = cl32_drivers,
.symbols = nullptr,
.internal = nullptr
};
}

View File

@ -1,156 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
#include "cl32_detect.h"
#include "cl32_v2_keyboard.h"
#include "cl32_v3_keyboard.h"
#include "cl32_v2.h"
#include "cl32_v3.h"
#include "cl32_v4.h"
#include "cl32_v4_keyboard.h"
#include "cl32_v4_power.h"
#include <tactility/device.h>
#include <tactility/device_listener.h>
#include <tactility/drivers/i2c_controller.h>
#include <tactility/log.h>
#include <cstring>
constexpr auto* TAG = "cl32-detect";
// Revision 2 and 3 boards are both plain tca8418 keyboards (different physical key layouts) with
// no core chip. Revision 4 boards have the core chip (power + keyboard) at CL32_V4_CORE_I2C_ADDRESS.
static Cl32HardwareRevision cl32_revision = Cl32HardwareRevision::Unknown;
static Device cl32_v4_power_device {};
static bool cl32_v4_power_created = false;
// The probe-once latch for on_i2c0_started(). File-scope (not function-local) so
// cl32_teardown_devices() can reset it for a later start/probe cycle.
static bool did_probe = false;
static void create_v2_devices(Device* i2c0) {
cl32_create_keyboard(i2c0);
}
static void create_v3_devices(Device* i2c0) {
cl32_v3_create_keyboard(i2c0);
}
static bool create_v4_power_device(Device* i2c0) {
cl32_v4_power_device = Device { .address = 0, .name = "cl32-v4-power", .config = nullptr, .parent = nullptr, .flags = 0, .internal = nullptr };
error_t error = device_construct(&cl32_v4_power_device);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to construct cl32-v4-power: %s", error_to_string(error));
return false;
}
device_set_parent(&cl32_v4_power_device, i2c0);
device_set_driver(&cl32_v4_power_device, &cl32_v4_power_driver);
error = device_add(&cl32_v4_power_device);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to add cl32-v4-power: %s", error_to_string(error));
device_destruct(&cl32_v4_power_device);
return false;
}
error = device_start(&cl32_v4_power_device);
if (error != ERROR_NONE) {
LOG_E(TAG, "Failed to start cl32-v4-power: %s", error_to_string(error));
device_remove(&cl32_v4_power_device);
device_destruct(&cl32_v4_power_device);
return false;
}
return true;
}
static void create_v4_devices(Device* i2c0) {
cl32_v4_create_keyboard(i2c0);
cl32_v4_power_created = create_v4_power_device(i2c0);
}
// Stops, removes and destructs cl32_v4_power_device if it was successfully created.
// cl32_v4_power_driver's own stop() tears down its power-supply child device.
static void destroy_v4_power_device() {
if (!cl32_v4_power_created) {
return;
}
device_stop(&cl32_v4_power_device);
device_remove(&cl32_v4_power_device);
device_destruct(&cl32_v4_power_device);
cl32_v4_power_created = false;
}
static Cl32HardwareRevision cl32_detect(Device* i2c0) {
uint8_t probe_value = 0;
if (i2c_controller_register8_get(i2c0, CL32_V4_CORE_I2C_ADDRESS, CL32_V4_KEYBOARD_PROBE_REGISTER, &probe_value, CL32_V4_CORE_TIMEOUT) == ERROR_NONE) {
LOG_I(TAG, "Detected V4 hardware by V4 keyboard presence");
return Cl32HardwareRevision::Revision4;
}
if (i2c_controller_has_device_at_address(i2c0, CL32_V3_FUEL_GAUGE_I2C_ADDRESS, CL32_V3_TIMEOUT) == ERROR_NONE) {
LOG_I(TAG, "Detected V3 hardware by MAX17048G fuel gauge presence");
return Cl32HardwareRevision::Revision3;
}
LOG_I(TAG, "No core chip or fuel gauge detected, assuming revision 2 hardware");
return Cl32HardwareRevision::Revision2;
}
// Fires for every device's start/stop in the system.
static void on_i2c0_started(Device* device, DeviceEvent event, void* context) {
(void)context;
if (did_probe || event != DEVICE_EVENT_STARTED || strcmp(device->name, "i2c0") != 0) {
return;
}
did_probe = true;
cl32_revision = cl32_detect(device);
switch (cl32_revision) {
case Cl32HardwareRevision::Revision2:
create_v2_devices(device);
break;
case Cl32HardwareRevision::Revision3:
create_v3_devices(device);
break;
case Cl32HardwareRevision::Revision4:
create_v4_devices(device);
break;
default:
LOG_W(TAG, "Unknown/unsupported hardware revision");
break;
}
}
Cl32HardwareRevision cl32_hardware_revision() {
return cl32_revision;
}
void cl32_teardown_devices() {
// Revision 2/3 keyboards bind the shared ti,tca8418 driver (owned by tca8418-module), so they
// don't block cl32_module's own driver destruction - torn down anyway for symmetry and so a
// later start can recreate them cleanly.
cl32_destroy_keyboard();
cl32_v3_destroy_keyboard();
// Revision 4 devices bind cl32-owned drivers (cl32_v4_keyboard_driver, cl32_v4_power_driver).
// Must be torn down before cl32_module's driver-removal loop runs, or driver_destruct() finds
// a started device still using the driver and fails.
cl32_v4_destroy_keyboard();
destroy_v4_power_device();
did_probe = false;
}
void cl32_power_detect_start() {
device_listener_add(on_i2c0_started, nullptr);
}
void cl32_power_detect_stop() {
device_listener_remove(on_i2c0_started, nullptr);
}

View File

@ -1,11 +0,0 @@
#pragma once
#include <tactility/device.h>
#include <tactility/driver.h>
extern struct Driver cl32_v4_keyboard_driver;
/** @return true if the device was successfully constructed, added and started. */
bool cl32_v4_create_keyboard(struct Device* i2c0);
void cl32_v4_destroy_keyboard();

View File

@ -1,6 +0,0 @@
#pragma once
#include <tactility/driver.h>
extern struct Driver cl32_v4_power_driver;
extern struct Driver cl32_v4_power_supply_driver;

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=2432S022C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=2432S024C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=2432S024R
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=2432S028R
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=2432S028R v3
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=2432S032C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=3248S035C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=4848S040C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -2,8 +2,6 @@ general.vendor=CYD
general.name=8048S043C
general.incubating=false
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=E32R28T
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=E32R32P
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Elecrow
general.name=CrowPanel Advance 2.8"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Elecrow
general.name=CrowPanel Advance 3.5"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Elecrow
general.name=CrowPanel Advance 5.0"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Elecrow
general.name=CrowPanel Basic 2.8"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Elecrow
general.name=CrowPanel Basic 3.5"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Elecrow
general.name=CrowPanel Basic 5.0"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=4MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=CYD
general.name=ES3C28P
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Generic
general.name=ESP32
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=8MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Generic
general.name=ESP32-C6
apps.launcherAppId=tactility.launcher
hardware.target=ESP32C6
hardware.flashSize=8MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Generic
general.name=ESP32-P4
apps.launcherAppId=tactility.launcher
hardware.target=ESP32P4
hardware.flashSize=8MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Generic
general.name=ESP32-S3
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Guition
general.name=JC1060P470C-I-W-Y
apps.launcherAppId=tactility.launcher
hardware.target=ESP32P4
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Guition
general.name=JC2432W328C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=4MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=Guition
general.name=JC8048W550C
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Heltec
general.name=WiFi LoRa 32 v3
general.incubating=true
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32S3

View File

@ -2,8 +2,6 @@ general.vendor=LilyGO
general.name=T5 4.7 Inch E-Paper S3
general.incubating=true
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true
@ -20,4 +18,3 @@ display.dpi=235
lvgl.colorDepth=8
lvgl.fontSize=24
lvgl.theme=Mono
lvgl.statusbarColorsInverted=true

View File

@ -3,8 +3,6 @@ general.name=T-Deck Max
# SD card support is not yet working, display driver is untested since refactoring; remove once it is functional.
general.incubating=true
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.flashMode=DIO
@ -23,6 +21,5 @@ display.dpi=128
lvgl.colorDepth=8
lvgl.theme=Mono
lvgl.statusbarColorsInverted=true
cdn.warningMessage=Display not reliably working. Use at your own risk.

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-Deck Plus
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -3,8 +3,6 @@ general.name=T-Deck Pro
# The display driver is not reliable yet
general.incubating=true
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.flashMode=DIO
@ -22,6 +20,5 @@ display.dpi=128
lvgl.colorDepth=8
lvgl.theme=Mono
lvgl.statusbarColorsInverted=true
cdn.warningMessage=Only for hardware revision 1.0! Display not reliably working. Use at your own risk.

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-Deck
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,7 +1,5 @@
general.vendor=LilyGO
general.name=T-Display S3
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32S3

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-Display
general.incubating=true
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-Dongle S3
general.incubating=true
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32S3

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-Embed CC1101 Plus
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-HMI
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=LilyGO
general.name=T-Lora Pager
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.flashMode=DIO

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=Cardputer Adv
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=Cardputer,Cardputer v1.1
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.spiRam=false

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=Core2
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=CoreS3
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -2,8 +2,6 @@ general.vendor=M5Stack
general.name=PaperS3
general.incubating=true
apps.launcherAppId=tactility.launcher
hardware.target=esp32s3
hardware.flashSize=16MB
hardware.spiRam=true
@ -21,6 +19,5 @@ display.dpi=235
lvgl.colorDepth=8
lvgl.fontSize=24
lvgl.theme=Mono
lvgl.statusbarColorsInverted=true
sdkconfig.CONFIG_EPD_DISPLAY_TYPE_ED047TC2=y

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=StackChan
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=StickC Plus2
apps.launcherAppId=tactility.launcher
hardware.target=ESP32
hardware.flashSize=8MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=StickS3
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=M5Stack
general.name=Tab5
apps.launcherAppId=tactility.launcher
hardware.target=ESP32P4
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Seeed Studio
general.name=Wio Tracker L2 Pro
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Simulator
general.name=Tab5Simulator
apps.launcherAppId=tactility.launcher
hardware.target=POSIX
storage.userDataLocation=Internal

View File

@ -1,8 +1,6 @@
general.vendor=Tulip
general.name=Tulip Creative Computer (4r11)
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=32MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=unPhone
general.name=unPhone
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=8MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=Waveshare
general.name=ESP32 S3 GEEK
general.incubating=true
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32S3

View File

@ -1,8 +1,6 @@
general.vendor=WaveShare
general.name=S3 LCD 1.3"
general.incubating=true
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32S3

View File

@ -1,8 +1,6 @@
general.vendor=WaveShare
general.name=S3 Touch LCD 1.28"
general.incubating=true
apps.launcherAppId=tactility.launcher
apps.autoStartAppId=tactility.apwebserver
hardware.target=ESP32S3

View File

@ -2,8 +2,6 @@ general.vendor=WaveShare
general.name=S3 Touch LCD 1.47"
general.incubating=true
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -1,8 +1,6 @@
general.vendor=WaveShare
general.name=S3 Touch LCD 4.3"
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
# Some models have 16MB flash, but some have 8MB. We only support the latter to avoid making more builds.
hardware.flashSize=8MB

View File

@ -1,8 +1,6 @@
general.vendor=Wireless Tag
general.name=WT32 SC01 Plus
apps.launcherAppId=tactility.launcher
hardware.target=ESP32S3
hardware.flashSize=16MB
hardware.spiRam=true

View File

@ -63,22 +63,14 @@ static error_t axp192_backlight_get_brightness(Device* device, uint8_t* out_brig
return ERROR_NONE;
}
static uint8_t axp192_backlight_get_min_brightness(Device*) {
return 0;
}
static uint8_t axp192_backlight_get_max_brightness(Device*) {
return 255;
}
// endregion
static constexpr BacklightApi AXP192_BACKLIGHT_API = {
.set_brightness = axp192_backlight_set_brightness,
.set_brightness_default = axp192_backlight_set_brightness_default,
.get_brightness = axp192_backlight_get_brightness,
.get_min_brightness = axp192_backlight_get_min_brightness,
.get_max_brightness = axp192_backlight_get_max_brightness,
.get_min_brightness = nullptr,
.get_max_brightness = nullptr,
};
// region Driver lifecycle
@ -123,6 +115,7 @@ Driver axp192_backlight_driver = {
.compatible = (const char*[]) { "axp192-backlight", nullptr },
.start_device = start,
.stop_device = stop,
.probe = nullptr,
.api = &AXP192_BACKLIGHT_API,
.device_type = &BACKLIGHT_TYPE,
.owner = &axp192_module,

View File

@ -76,22 +76,14 @@ static error_t axp2101_backlight_get_brightness(Device* device, uint8_t* out_bri
return ERROR_NONE;
}
static uint8_t axp2101_backlight_get_min_brightness(Device*) {
return 0;
}
static uint8_t axp2101_backlight_get_max_brightness(Device*) {
return 255;
}
// endregion
static constexpr BacklightApi AXP2101_BACKLIGHT_API = {
.set_brightness = axp2101_backlight_set_brightness,
.set_brightness_default = axp2101_backlight_set_brightness_default,
.get_brightness = axp2101_backlight_get_brightness,
.get_min_brightness = axp2101_backlight_get_min_brightness,
.get_max_brightness = axp2101_backlight_get_max_brightness,
.get_min_brightness = nullptr,
.get_max_brightness = nullptr,
};
// region Driver lifecycle
@ -131,10 +123,11 @@ Driver axp2101_backlight_driver = {
.compatible = (const char*[]) { "axp2101-backlight", nullptr },
.start_device = start,
.stop_device = stop,
.probe = nullptr,
.api = &AXP2101_BACKLIGHT_API,
.device_type = &BACKLIGHT_TYPE,
.owner = &axp2101_module,
.internal = nullptr
.internal = nullptr,
};
}

View File

@ -88,22 +88,14 @@ static error_t tdeck_keyboard_backlight_get_brightness(Device* device, uint8_t*
return ERROR_NONE;
}
static uint8_t tdeck_keyboard_backlight_get_min_brightness(Device*) {
return 0;
}
static uint8_t tdeck_keyboard_backlight_get_max_brightness(Device*) {
return 255;
}
// endregion
static const BacklightApi tdeck_keyboard_backlight_api = {
.set_brightness = tdeck_keyboard_backlight_set_brightness,
.set_brightness_default = tdeck_keyboard_backlight_set_brightness_default,
.get_brightness = tdeck_keyboard_backlight_get_brightness,
.get_min_brightness = tdeck_keyboard_backlight_get_min_brightness,
.get_max_brightness = tdeck_keyboard_backlight_get_max_brightness,
.get_min_brightness = nullptr,
.get_max_brightness = nullptr,
};
extern struct Module lilygo_module;
@ -113,6 +105,7 @@ Driver tdeck_keyboard_backlight_driver = {
.compatible = (const char*[]) { "lilygo,tdeck-keyboard-backlight", nullptr },
.start_device = start,
.stop_device = stop,
.probe = nullptr,
.api = &tdeck_keyboard_backlight_api,
.device_type = &BACKLIGHT_TYPE,
.owner = &lilygo_module,

View File

@ -93,22 +93,14 @@ static error_t lp5814_get_brightness(Device* device, uint8_t* out_brightness) {
return ERROR_NONE;
}
static uint8_t lp5814_get_min_brightness(Device*) {
return 0;
}
static uint8_t lp5814_get_max_brightness(Device*) {
return 255;
}
// endregion
static constexpr BacklightApi LP5814_BACKLIGHT_API = {
.set_brightness = lp5814_set_brightness,
.set_brightness_default = lp5814_set_brightness_default,
.get_brightness = lp5814_get_brightness,
.get_min_brightness = lp5814_get_min_brightness,
.get_max_brightness = lp5814_get_max_brightness,
.get_min_brightness = nullptr,
.get_max_brightness = nullptr,
};
// region Driver lifecycle
@ -159,7 +151,7 @@ Driver lp5814_driver = {
.api = &LP5814_BACKLIGHT_API,
.device_type = &BACKLIGHT_TYPE,
.owner = &lp5814_module,
.internal = nullptr
.internal = nullptr,
};
}

View File

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.20)
include("${CMAKE_CURRENT_LIST_DIR}/../../Buildscripts/module.cmake")
file(GLOB_RECURSE SOURCE_FILES "source/*.c*")
tactility_add_module(st7305-module
SRCS ${SOURCE_FILES}
INCLUDE_DIRS include/
REQUIRES TactilityKernel platform-esp32 esp_lcd driver
)

Some files were not shown because too many files have changed in this diff Show More