What changed, and why it matters
This commit adds support for a new hardware device called the TZT CanMV. It is a routine feature addition: the code now recognizes the new device type, includes it in build/flash scripts, sets the correct display and touchscreen flags, and assigns a USB product ID. There is no security fix or security-relevant behavior change.
No security action required. Treat as a normal hardware-support feature commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff extends Krux’s device support matrix to include ‘maixpy_tzt’. Changes are limited to: adding the device to build/flash/release lists in the krux shell script, setting its USB vendor/product ID (1a86:55d3) and board type (‘dan’), adding an is_tzt flag in kboard.py, including it in the has_touchscreen group, and adding it to the display initialization branch shared with yahboom/wonder_mv. A minor refactor in touch.py replaces a chained hasattr/attribute access with getattr(…, False), which is functionally equivalent and not security-relevant.
Changed components
CHANGELOG.mdkrux build/flash/release scriptsrc/krux/display.pysrc/krux/kboard.pysrc/krux/touch.pyInspect captured patch +24 / −12
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76b3429..f82c25f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# Changelog 25.XX.X - XXX 2025
+
+### New Device Support: TZT
+The TZT CanMV is similar to the WonderMV, but adds five buttons and a premium, fully enclosed aluminum housing that completely wraps the device.
+
# Changelog 25.09.0 - September 2025
### Extended Encryption Options
diff --git a/krux b/krux
index 82801bf..353e43a 100755
--- a/krux
+++ b/krux
@@ -67,6 +67,7 @@ if [ "$1" == "build" ]; then
[ "$device" == "maixpy_yahboom" ]||
[ "$device" == "maixpy_cube" ]||
[ "$device" == "maixpy_wonder_mv" ]||
+ [ "$device" == "maixpy_tzt" ]||
[ "$allow_unsupported" ]; then
declare $(grep -m 1 version pyproject.toml | sed 's/ *= */=/g' | sed 's/"//g' | sed 's/\r//g')
sed -i -- 's/VERSION = ".*"/VERSION = "'"$version"'"/g' src/krux/metadata.py
@@ -90,7 +91,7 @@ elif [ "$1" == "flash" -o "$1" == "boot" -o "$1" == "erase" ]; then
if [ "$1" == "flash" ]; then
CMD_SUFFIX="kboot.kfpkg"
elif [ "$1" == "boot" ]; then
- CMD_SUFFIX="-s firmware.bin"
+ CMD_SUFFIX="-s firmware.bin -t"
else
CMD_SUFFIX="-E"
fi
@@ -114,6 +115,9 @@ elif [ "$1" == "flash" -o "$1" == "boot" -o "$1" == "erase" ]; then
[ "$device" == "maixpy_wonder_mv" ]; then
# https://devicehunt.com/view/type/usb/vendor/1a86/device/7523
device_vendor_product_id="1a86:7523"
+ elif [ "$device" == "maixpy_tzt" ]; then
+ # https://devicehunt.com/view/type/usb/vendor/1a86/device/55d3
+ device_vendor_product_id="1a86:55d3"
fi
if [ -z "$device_vendor_product_id" ]; then
panic "Unknown device"
@@ -125,7 +129,9 @@ elif [ "$1" == "flash" -o "$1" == "boot" -o "$1" == "erase" ]; then
panic "Failed to find device via USB. Is it connected and powered on?"
fi
- if [ "$device" == "maixpy_dock" ]||[ "$device" == "maixpy_wonder_mv" ]; then
+ if [ "$device" == "maixpy_dock" ]||
+ [ "$device" == "maixpy_wonder_mv" ]||
+ [ "$device" == "maixpy_tzt" ]; then
BOARD="dan"
else
BOARD="goE"
@@ -270,7 +276,7 @@ elif [ "$1" == "build-release" ]; then
cp -f ktool-win.exe ../$release_dir/ktool-win.exe
cd ..
- devices=("maixpy_m5stickv" "maixpy_amigo" "maixpy_bit" "maixpy_dock" "maixpy_yahboom" "maixpy_cube" "maixpy_wonder_mv")
+ devices=("maixpy_m5stickv" "maixpy_amigo" "maixpy_bit" "maixpy_dock" "maixpy_yahboom" "maixpy_cube" "maixpy_wonder_mv" "maixpy_tzt")
for device in ${devices[@]}; do
./krux build $device
mkdir -p $release_dir/$device
diff --git a/src/krux/display.py b/src/krux/display.py
index 140923d..1f5fd92 100644
--- a/src/krux/display.py
+++ b/src/krux/display.py
@@ -138,7 +138,7 @@ class Display:
],
)
self.set_pmu_backlight(Settings().hardware.display.brightness)
- elif kboard.is_yahboom or kboard.is_wonder_mv:
+ elif kboard.is_yahboom or kboard.is_wonder_mv or kboard.is_tzt:
lcd.init(
invert=True,
rst=board.config["lcd"]["rst"],
diff --git a/src/krux/kboard.py b/src/krux/kboard.py
index d3a7311..68ed99b 100644
--- a/src/krux/kboard.py
+++ b/src/krux/kboard.py
@@ -32,8 +32,11 @@ class KBoard:
self.is_cube = board.config["type"] == "cube"
self.is_yahboom = board.config["type"] == "yahboom"
self.is_wonder_mv = board.config["type"] == "wonder_mv"
+ self.is_tzt = board.config["type"] == "tzt"
self.is_m5stickv = board.config["type"] == "m5stickv"
- self.has_touchscreen = self.is_yahboom or self.is_wonder_mv or self.is_amigo
+ self.has_touchscreen = (
+ self.is_yahboom or self.is_wonder_mv or self.is_tzt or self.is_amigo
+ )
self.has_minimal_display = self.is_m5stickv or self.is_cube
self.can_control_brightness = (
self.is_cube or self.is_m5stickv or self.is_wonder_mv
diff --git a/src/krux/touch.py b/src/krux/touch.py
index 0fdb485..5dfa181 100644
--- a/src/krux/touch.py
+++ b/src/krux/touch.py
@@ -79,9 +79,8 @@ class Touch:
def valid_position(self, data):
"""Checks if touch position is within buttons area"""
- if (
- hasattr(Settings().hardware.display, "flipped_orientation")
- and Settings().hardware.display.flipped_orientation
+ if hasattr(Settings().hardware, "display") and getattr(
+ Settings().hardware.display, "flipped_orientation", False
):
data = (self.height - data[0], self.width - data[1])
@@ -176,9 +175,8 @@ class Touch:
def _store_points(self, data):
"""Store pressed points and calculare an average pressed point"""
- if (
- hasattr(Settings().hardware.display, "flipped_orientation")
- and Settings().hardware.display.flipped_orientation
+ if hasattr(Settings().hardware, "display") and getattr(
+ Settings().hardware.display, "flipped_orientation", False
):
new_y = max(0, self.height - data[0])
new_y = min(new_y, self.height - 1)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.