Skip to content

Conversation

@romasku
Copy link
Owner

@romasku romasku commented Oct 25, 2025

This PR adds support for Silabs MCUs, but also includes a major refactoring of the entire codebase:

  • The codebase is now split into platform-agnostic and platform-specific parts.
  • GPIO (and some other components) have been rewritten from a polling-based to a callback-based approach.
  • The Telink SDK has been updated to the latest version (now supporting OTA from stock firmware, though this still needs more testing).
  • Added a stub implementation that runs the platform-agnostic code as a host binary (e.g., directly on your PC).
    • This allows developing and testing new features without real hardware.
    • It supports an interactive REPL mode for triggering fake GPIOs, reading ZCL attributes, and more.
  • Achieved (hopefully) near-complete test coverage of all platform-agnostic logic through the stub target.
  • Improved power management for Telink -- the device now sleeps until woken by GPIO.
  • Numerous smaller changes.

These changes have not been properly tested on real hardware (I did it only on my improvised devboard), so please use with caution. If you can test and report any issues you find, I would greatly appreciate it.

@marazmarci
Copy link
Contributor

Thanks, @romasku, amazing work! I will test your changes on a 3-gang Telink device in the coming days.

However I don't know which Silabs devices can be (easily) used for testing. Do you have any suggestions? This may be a bigger topic, and discussing it in PR comments is probably not the most efficient way, so we can also use the #hal channel on Discord that @andrei-lazarov created.

@clumsy-stefan
Copy link
Contributor

clumsy-stefan commented Oct 26, 2025

Just wanted to try the hal branch (eg. this PR). But when updating my device (TS0004-IHS/knoj8lpk) I always get a

z2m: Update of '0xa4c138d4f6512002' failed (Update failed with reason: INVALID_IMAGE)

Do I miss something?

@romasku
Copy link
Owner Author

romasku commented Oct 26, 2025

I've restored bin/index files from main in this (hal) branch, so that code changes can be viewed.
New binaries + updated index are in hal-build branch.

Also found an issue with OTA, currently testing it.

@clumsy-stefan
Copy link
Contributor

Same isue with the hal-build branch... OTA fails with INVALID_IMAGE...

@clumsy-stefan
Copy link
Contributor

clumsy-stefan commented Oct 26, 2025

Now it seems to work!! Unfortunately I can't tell for sure as the app-versions are still the same as in the main branch!

As written in the chat, I'd suggest to change APP_RELEASE in src/version_cfg.c to 0x03 or so, to be able to identify this branch!

I'll do some functionality tests now..

@clumsy-stefan
Copy link
Contributor

Basic tests failed... No button works anymore (no matter if short or long press). Independent of button config (short, long).

Switching relays from remote (z2m) works though.

@romasku
Copy link
Owner Author

romasku commented Oct 26, 2025

No button works anymore (no matter if short or long press).
Published a potential fix (there was a limit (3) on GPIO IRQ callbacks that can be registered in the Telink SDK).

@marazmarci
Copy link
Contributor

marazmarci commented Oct 26, 2025

I flashed revision 751f281 on my Telink-based Moes 3-gang wall switch (MOES_SWITCHES_TS0013) and lightly tested your changes, both as End Device / Router, and basic functions worked perfectly:

  • ✅ joining network
  • ✅ switching relay from button
  • ✅ switching relay through Zigbee
  • ✅ displaying relay state on LED (w/ default same indicator mode)

However, I found two bugs which are not present on current main:

  1. 🐛 manual indicator mode doesn't work at all. → here's the fix 🔨 ✅
  2. 🐛 The LEDs blink weirdly when the device boots up in network joining mode. However, the blink looks good when entering network joining mode while the device is running (for example by removing the device from Z2M).

@Nerivec
Copy link

Nerivec commented Nov 7, 2025

Any reason not to use simplicity_sdk instead of the now "deprecated" gecko_sdk? Boards are series 2, so they're supported.

PS: feel free to use stuff from https://github.com/Nerivec/silabs-firmware-builder/tree/sisdk-2025.6.2 and/or https://github.com/Nerivec/silabs-firmware-recovery

@romasku
Copy link
Owner Author

romasku commented Nov 9, 2025

Update the code to use simplicity_sdk. This also fixed the sleep behavior, it now seems to work correctly on the silabs devices.

@marazmarci
Copy link
Contributor

marazmarci commented Nov 10, 2025

Because of the new fw file naming scheme (tlc_switch-<version>-<commit>.bin), now when building a different commit, it will result in different .bin and .zigbee filenames in the bin/<device_type>/<device> folders, and these files will start piling up.

I suggest cleaning up old bin files (not belonging to the current commit and version) as part of the build process.

Update: done in 052d5b7

@Nerivec
Copy link

Nerivec commented Nov 11, 2025

If you want to add that to the refactor, it should switch everything over to MJS and be compatible (typed) with https://github.com/Nerivec/z2m-external-converter-dev

  • I didn't fix the endpoint validation errors. I suspect in most cases, the endpoint is expected valid, i.e. ! should suffice.
  • I didn't touch v1, not sure what it's kept for.

https://gist.github.com/Nerivec/6b299f311c442f924b12a925b7265655

@andrei-lazarov
Copy link
Collaborator

andrei-lazarov commented Nov 11, 2025

Thank you @Nerivec for your suggestions and interest in the project!

I can give some info:

  • v1 is kept for Z2M versions older than v2.0.0. But we agreed to drop support for it.
  • The converters are generated with python and jinja templates (helper_scripts/)
    So every time we add a new device in the db, the GitHub action builds the firmware and updates the converters with the new entry.

Romasku did prepare a new version of the converters in #120:

  • they are rewritten as .mjs
  • they generate themselves 'on the spot'
    (the javascript exposes the correct features based on the 'config string' stored on each device)
  • this has multiple benefits including:
    • the end-user no longer needs to re-download them every time we add a new device
    • creating 'custom devices' and changing pinouts easier
  • we didn't deploy them yet, as we need to test and fix compatibility with older Z2M versions

I need to look deeper into your template, but we should apply your changes. 🙂

@andrei-lazarov
Copy link
Collaborator

@romasku when you update the docs, check out my PR - I made some improvements there.

I don't really expect conflicts, just wanted to make sure you don't waste time rewriting something

uses: actions/cache@v3
with:
path: silabs_tools
key: silabs-tools-v4.5.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a leftover from the Gecko SDK. I think we should use the Simplicity SDK's version:

Suggested change
key: silabs-tools-v4.5.0
key: silabs-tools-v2025.6.2

Copy link
Contributor

@marazmarci marazmarci Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is possible that the GitHub build currently only works because of this leftover which causes the build to use a cached Gecko SDK silabs-tools from 2 weeks earlier.

I think this because the build failed in my fork, and the silabs-tools caching step shows a cache miss. The error message at first doesn't seem to be related:

Clear out index files:
Run source .venv/bin/activate
/home/runner/work/_temp/b4363142-edc2-4a48-a05f-c56e38c33320.sh: line 1: .venv/bin/activate: No such file or directory
Error: Process completed with exit code 1.

But there are also errors in the previous step:

Install SDK and Toolchain:
...
Verifying installed tools...
✓ Simplicity SDK: ../../silabs_tools/simplicity_sdk
Version: 2025.6.2
✗ Simplicity Commander: Not installed
make[2]: *** [tools.mk:212: verify] Error 1
make[2]: Leaving directory '/home/runner/work/tuya-zigbee-switch/tuya-zigbee-switch/src/silabs'
make[1]: *** [Makefile:64: tools/all] Error 2
make[1]: Leaving directory '/home/runner/work/tuya-zigbee-switch/tuya-zigbee-switch/src/silabs'
make: *** [Makefile:70: silabs/tools/all] Error 2
...

The builds in your repo show a cache hit for silabs-tools-v4.5.0, while it should already be using Simplicity SDK. Maybe it works because Gecko SDK bundles Simplicity SDK? IDK to be honest.

Maybe my explanation or theory isn't correct, but it surely seems that there is some anomaly around this cache key.

Copy link
Contributor

@marazmarci marazmarci Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correction: I didn't see it correctly at the first time, it's Simplicity Commander which is not installed, not the SDK.

Copy link
Contributor

@marazmarci marazmarci Nov 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the culprit! Silicon Labs changed the name of the commander-cli executable in the zip archive to just simply commander... And the GitHub Actions cache had the old zip which contained the old executable name.

It just has to be replaced everywhere in the project.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: currently, this external change made by Silicon Labs breaks make_install.sh for first-time local dev env setups.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is due to a different problem. A SimplicityCommander-Linux.zip content is:

Commander-cli_linux_aarch32_1v21p0b1946.tar.bz 
Commander-cli_linux_aarch64_1v21p0b1946.tar.bz  
Commander-cli_linux_x86_64_1v21p0b1946.tar.bz   
Commander_linux_aarch32_1v21p0b1946.tar.bz  
Commander_linux_aarch64_1v21p0b1946.tar.bz
Commander_linux_x86_64_1v21p0b1946.tar.bz 
README.txt   
SimplicityCommander-ReleaseNotes.txt

Notice there are different tarballs for -cli and non cli (GUI) versions of commanders.
And here is the part of the makefile that selects the tarball to use:

    @ARCH=$$(uname -m); \
	if [ "$$ARCH" = "x86_64" ]; then \
		COMMANDER_FILE=$$(find $(TOOLS_DIR)/commander_temp -name "*linux_x86_64*.tar.bz" | head -1); \
	elif [ "$$ARCH" = "aarch64" ]; then \
		COMMANDER_FILE=$$(find $(TOOLS_DIR)/commander_temp -name "*linux_aarch64*.tar.bz" | head -1); \
	elif [ "$$ARCH" = "armv7l" ]; then \
		COMMANDER_FILE=$$(find $(TOOLS_DIR)/commander_temp -name "*linux_aarch32*.tar.bz" | head -1); \
	else \
		COMMANDER_FILE=$$(find $(TOOLS_DIR)/commander_temp -name "*linux_x86_64*.tar.bz" | head -1); \
	fi; \

For example, on x86, it selects the first file it encounters with linux_x86_64 as a substring, and if it selects the UI version, then the problem occurs.

I've fixed this issue in 699367a. Please check if it works for you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right. Thanks, the fix worked for me, both locally and in the GitHub build!

@romasku romasku merged commit 052d5b7 into main Nov 15, 2025
2 checks passed
@romasku romasku deleted the hal branch December 19, 2025 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants