Skip to content

Commit

Permalink
Add bootloader reset for SMLIGHT SLZB-07 (#63)
Browse files Browse the repository at this point in the history
* Find gpio chip by name

Chip number for USB gpio chips will depend on what other system gpio
chips already exist on the system. Add support to search by chip label
to find chip number.

* Add bootloader reset for SLZB-07

* Add message to avoid other USB devices
  • Loading branch information
tl-sl authored Feb 28, 2024
1 parent eff7dca commit b009196
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Options:
--ezsp-baudrate NUMBERS [default: 115200]
--spinel-baudrate NUMBERS [default: 460800]
--probe-method TEXT [default: bootloader, cpc, ezsp, spinel]
--bootloader-reset [yellow|ihost|sonoff]
--bootloader-reset [yellow|ihost|slzb07|sonoff]
--help Show this message and exit.

Commands:
Expand Down
9 changes: 9 additions & 0 deletions universal_silabs_flasher/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class ApplicationType(enum.Enum):
class ResetTarget(enum.Enum):
YELLOW = "yellow"
IHOST = "ihost"
SLZB07 = "slzb07"
SONOFF = "sonoff"


Expand All @@ -68,4 +69,12 @@ class ResetTarget(enum.Enum):
},
"toggle_delay": 0.1,
},
ResetTarget.SLZB07: {
"chip_name": "cp210x",
"pin_states": {
5: [True, False, False, True],
4: [True, False, True, True],
},
"toggle_delay": 0.1,
},
}
8 changes: 7 additions & 1 deletion universal_silabs_flasher/flasher.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from .emberznet import connect_ezsp
from .firmware import FirmwareImage
from .gecko_bootloader import GeckoBootloaderProtocol, NoFirmwareError
from .gpio import send_gpio_pattern
from .gpio import find_gpiochip_by_label, send_gpio_pattern
from .spinel import SpinelProtocol
from .xmodemcrc import BLOCK_SIZE as XMODEM_BLOCK_SIZE

Expand Down Expand Up @@ -69,6 +69,12 @@ async def enter_bootloader_reset(self, target):
_LOGGER.info(f"Triggering {target.value} bootloader")
if target in GPIO_CONFIGS.keys():
config = GPIO_CONFIGS[target]
if "chip" not in config.keys():
_LOGGER.warning(
f"When using {target.value} bootloader reset "
+ "ensure no other CP2102 USB serial devices are connected."
)
config["chip"] = await find_gpiochip_by_label(config["chip_name"])
await send_gpio_pattern(
config["chip"], config["pin_states"], config["toggle_delay"]
)
Expand Down
39 changes: 38 additions & 1 deletion universal_silabs_flasher/gpio.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from __future__ import annotations

import asyncio
from os import scandir
import time
import typing

try:
import gpiod

is_gpiod_v1 = hasattr(gpiod.chip, "OPEN_BY_PATH")
except ImportError:
gpiod = None

Expand All @@ -15,7 +19,7 @@ def _send_gpio_pattern(
) -> None:
raise NotImplementedError("GPIO not supported on this platform")

elif hasattr(gpiod.chip, "OPEN_BY_PATH"):
elif is_gpiod_v1:
# gpiod <= 1.5.4
def _send_gpio_pattern(
chip: str, pin_states: dict[int, list[bool]], toggle_delay: float
Expand Down Expand Up @@ -82,6 +86,39 @@ def _send_gpio_pattern(
)


def _generate_gpio_chips() -> typing.Iterable[str]:
for entry in scandir("/dev/"):
if is_gpiod_v1:
if entry.name.startswith("gpiochip"):
yield entry.path
else:
if gpiod.is_gpiochip_device(entry.path):
yield entry.path


def _find_gpiochip_by_label(label: str) -> str:
for path in _generate_gpio_chips():
try:
if is_gpiod_v1:
chip = gpiod.chip(path, gpiod.chip.OPEN_BY_PATH)
if chip.label == label:
return path
else:
with gpiod.Chip(path) as chip:
if chip.get_info().label == label:
return path
except PermissionError:
pass
raise RuntimeError("No matching gpiochip device found")


async def find_gpiochip_by_label(label: str) -> str:
result = await asyncio.get_running_loop().run_in_executor(
None, _find_gpiochip_by_label, label
)
return result


async def send_gpio_pattern(
chip: str, pin_states: dict[int, list[bool]], toggle_delay: float
) -> None:
Expand Down

0 comments on commit b009196

Please sign in to comment.