Skip to content

Comments

Integrate Luckfox staging commits and add platform autodetection#298

Open
3rdIteration wants to merge 29 commits intodevfrom
luckfox-staging-portability
Open

Integrate Luckfox staging commits and add platform autodetection#298
3rdIteration wants to merge 29 commits intodevfrom
luckfox-staging-portability

Conversation

@3rdIteration
Copy link
Owner

Summary\n- cherry-pick 10 commits from lightningspore/upstream-luckfox-staging-1 with original authorship preserved\n- migrate hardware paths toward periphery/OpenCV portability\n- auto-detect runtime platform/variant (Raspberry Pi, Luckfox, Desktop)\n- treat hardware config as runtime-detected instead of user-configurable\n- extend Hardware > System Info to show Platform and Variant\n

Copilot AI review requested due to automatic review settings February 16, 2026 02:20
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR integrates Luckfox staging commits and implements platform autodetection to support multiple hardware platforms (Raspberry Pi, Luckfox Pico, Desktop). The major architectural change is migrating from Raspberry Pi-specific libraries (RPi.GPIO, picamera, smbus2) to cross-platform alternatives (python-periphery for GPIO/SPI/I2C, OpenCV for camera). Hardware configuration is now automatically detected at runtime based on device model information, with platform-specific pin mappings defined centrally in settings_definition.py.

Changes:

  • Replaced RPi.GPIO with python-periphery for GPIO, SPI, and I2C operations across all hardware drivers
  • Migrated from picamera to OpenCV-only camera implementation
  • Added runtime platform detection for Raspberry Pi (26/40-pin), Luckfox Pico (22/40-pin), and Desktop
  • Introduced hardware pin configuration system with platform-specific mappings for display, buttons, and camera
  • Extended System Info screen to display detected Platform and Variant

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
src/settings.json Default settings template with FOX_40 hardware config
src/settings.rpi.json Raspberry Pi-specific settings template with RPI_40 config and 270° camera rotation
src/settings.luckfox.json Luckfox Pico-specific settings template with FOX_22 config and 180° camera rotation
src/seedsigner/models/settings.py Platform detection logic and hardware config enforcement
src/seedsigner/models/settings_definition.py Hardware pin configurations for all supported platforms
src/seedsigner/hardware/buttons.py Migrated to periphery GPIO with dynamic pin mapping
src/seedsigner/hardware/camera.py Removed picamera support, OpenCV-only implementation
src/seedsigner/hardware/pivideostream.py Simplified to use only OpenCV VideoCapture
src/seedsigner/hardware/battery_hat.py Migrated from smbus2 to periphery I2C
src/seedsigner/hardware/displays/*.py Migrated all display drivers to periphery GPIO/SPI
src/seedsigner/views/settings_views.py Added platform info detection and display
src/seedsigner/gui/screens/settings_screens.py Extended System Info screen with platform fields
src/seedsigner/views/tools_views.py Updated image entropy capture to use video stream mode
src/seedsigner/gui/screens/scan_screens.py Removed resolution parameter from video stream initialization
src/seedsigner/gui/screens/tools_screens.py Removed resolution parameter from one video stream call
requirements.txt Removed smbus2 dependency
requirements-raspi.txt Replaced multiple Pi-specific libs with python-periphery
docs/dev_device_setup_instructions.md Added Raspberry Pi OS setup instructions

Comment on lines +72 to +99
```
export DISABLE_TIFF=1
export DISABLE_WEBP=1
```
libtiff5-dev


```

sudo apt install libopenblas-dev liblapack3 liblapack-dev
sudo apt install libopenblas-dev liblapack-dev libblas-dev
sudo apt install libatlas3-base libatlas-base-dev


sudo apt install libgtk-3-0 libgdk-pixbuf2.0-0 libglib2.0-0

```

uv pip install --reinstall --no-binary pillow pillow==10.0.1
uv pip install --reinstall --no-binary numpy numpy==1.25.2 -v


uv pip install pytest





Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The documentation contains incomplete or malformed content. Line 76 has a standalone "libtiff5-dev" that appears to be leftover from editing, and the bash code block starting at line 79 is not properly closed. The commands between lines 79-94 appear to be partially commented or incomplete. This makes the setup instructions unclear and potentially unusable.

Copilot uses AI. Check for mistakes.
Comment on lines 175 to 192
@@ -183,16 +179,17 @@
single SPI transaction, with a default of 4096.
"""
# Set DC low for command, high for data.
GPIO.output(self._dc, is_data)
self._dc.write(is_data)
# Convert scalar argument to list so either can be passed as parameter.
if isinstance(data, numbers.Number):
data = [data & 0xFF]
# Write data a chunk at a time.
# for start in range(0, len(data), chunk_size):
# end = min(start+chunk_size, len(data))
# self._spi.writebytes2(data[start:end])

self._spi.writebytes2(data)
# self._spi.transfer(data)
self._chunked_transfer(data)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The send method has a chunk_size parameter that is no longer used since chunked transfer is now handled by _chunked_transfer with a fixed CHUNK_SIZE. The parameter should be removed from the method signature to avoid confusion, or the implementation should be updated to respect the parameter if variable chunk sizes are needed.

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +192
# Write data a chunk at a time.
# for start in range(0, len(data), chunk_size):
# end = min(start+chunk_size, len(data))
# self._spi.writebytes2(data[start:end])

self._spi.writebytes2(data)
# self._spi.transfer(data)
self._chunked_transfer(data)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

Commented-out code on line 191 (self._spi.transfer(data)) should be removed entirely rather than left as a comment. The commented lines 187-189 and 191 appear to be leftover from refactoring and create clutter.

Copilot uses AI. Check for mistakes.
"qr_brightness_tips": "E",
"partner_logos": "E",
"display_config": "st7789_240x240",
"hardware_config": "FOX_40",
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The default settings.json file is configured with hardware_config: "FOX_40" (Luckfox Pico 40-pin), but according to the PR description and platform detection logic, the default should be platform-agnostic or Desktop. This file appears to be intended as the default fallback when no platform-specific settings file exists. Consider using a Desktop or generic configuration as the default, or document that this file is specifically for Luckfox Pico 40-pin platforms.

Suggested change
"hardware_config": "FOX_40",
"hardware_config": "DESKTOP",

Copilot uses AI. Check for mistakes.
Comment on lines 285 to 286
if detected_hardware:
self._data[attr_name] = detected_hardware
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The set_value method for SETTING__HARDWARE_CONFIG returns early without calling save() when save=True. This means user attempts to change this setting won't be persisted to disk. While this may be intentional (since hardware is auto-detected), the early return bypasses the normal save flow. If the setting should truly be read-only, consider logging a warning or removing the setting from user-facing UI entirely rather than silently ignoring save requests.

Suggested change
if detected_hardware:
self._data[attr_name] = detected_hardware
if detected_hardware:
# Hardware configuration is auto-detected and treated as read-only.
logger.warning(
"Attempted to modify read-only setting %s; using auto-detected hardware configuration instead.",
attr_name,
)
self._data[attr_name] = detected_hardware
if save:
self.save()
else:
logger.warning(
"Attempted to modify hardware configuration setting %s, but no hardware could be auto-detected; ignoring change.",
attr_name,
)

Copilot uses AI. Check for mistakes.
def _detect_runtime_profile(hostname: str) -> str:
model = _read_device_model()
if "luckfox" in model or "luckfox" in hostname.lower():
if "mini" in model or "22" in model:
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The detection logic for luckfox_22 checks if "22" appears anywhere in the model string ("22" in model). This could produce false positives if "22" appears in version numbers, dates, or other unrelated text in the device model string. Consider using a more specific pattern match, such as checking for "22-pin" or "mini" specifically, rather than just the number "22".

Suggested change
if "mini" in model or "22" in model:
if "mini" in model or "22-pin" in model or "22 pin" in model:

Copilot uses AI. Check for mistakes.
Comment on lines 353 to 368
# "KEY_UP": ("/dev/gpiochip1", 28),
# "KEY_DOWN": ("/dev/gpiochip1", 21),
# "KEY_LEFT": ("/dev/gpiochip1", 27),
# "KEY_RIGHT": ("/dev/gpiochip1", 22),
# "KEY_PRESS": ("/dev/gpiochip1", 20),
# "KEY1": ("/dev/gpiochip1", 23),
# "KEY2": ("/dev/gpiochip1", 11),
# "KEY3": ("/dev/gpiochip1", 10),
"KEY_UP": (58,),
"KEY_DOWN": (53,),
"KEY_LEFT": (59,),
"KEY_RIGHT": (54,),
"KEY_PRESS": (52,),
"KEY1": (55,),
"KEY2": (43,),
"KEY3": (42,),
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The button pin definitions for FOX_40 use single-element tuples (e.g., (58,)) instead of the two-element tuples used by other configurations (e.g., ("/dev/gpiochip1", 20)). The commented-out code above shows what appears to be the correct format with gpiochip paths. This inconsistency will cause the GPIO(*pin_selector, "in") call in buttons.py line 94 to fail because it expects a device path and pin number, not just a pin number. The active configuration needs to match the periphery GPIO API signature.

Suggested change
# "KEY_UP": ("/dev/gpiochip1", 28),
# "KEY_DOWN": ("/dev/gpiochip1", 21),
# "KEY_LEFT": ("/dev/gpiochip1", 27),
# "KEY_RIGHT": ("/dev/gpiochip1", 22),
# "KEY_PRESS": ("/dev/gpiochip1", 20),
# "KEY1": ("/dev/gpiochip1", 23),
# "KEY2": ("/dev/gpiochip1", 11),
# "KEY3": ("/dev/gpiochip1", 10),
"KEY_UP": (58,),
"KEY_DOWN": (53,),
"KEY_LEFT": (59,),
"KEY_RIGHT": (54,),
"KEY_PRESS": (52,),
"KEY1": (55,),
"KEY2": (43,),
"KEY3": (42,),
"KEY_UP": ("/dev/gpiochip1", 28),
"KEY_DOWN": ("/dev/gpiochip1", 21),
"KEY_LEFT": ("/dev/gpiochip1", 27),
"KEY_RIGHT": ("/dev/gpiochip1", 22),
"KEY_PRESS": ("/dev/gpiochip1", 20),
"KEY1": ("/dev/gpiochip1", 23),
"KEY2": ("/dev/gpiochip1", 11),
"KEY3": ("/dev/gpiochip1", 10),

Copilot uses AI. Check for mistakes.
Comment on lines 235 to 257
@@ -253,7 +253,8 @@ def _run(self):
component.render()
self.renderer.show_image()
finally:
camera.stop_single_frame_mode()
# camera.stop_single_frame_mode()
camera.stop_video_stream_mode()
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The commented-out lines for camera.start_single_frame_mode() and camera.stop_single_frame_mode() should be removed entirely if they're no longer needed, rather than left as comments. Keeping dead code as comments can cause confusion during maintenance.

Copilot uses AI. Check for mistakes.
Comment on lines 32 to 33
if "model b rev 1" in model or ("model a" in model and "zero" not in model):
return "rpi_26"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The platform detection logic for Raspberry Pi Model A is incomplete. The condition checks for "model a" but excludes "zero" to avoid matching "Zero W" variants. However, this doesn't account for "Model A Plus" or other Model A variants. Consider using a more explicit pattern like checking for "model a" followed by a space or end of string, or explicitly listing the Model A variants that should map to 26-pin GPIO.

Copilot uses AI. Check for mistakes.
Comment on lines 298 to 305
"up": ("/dev/gpiochip0", 17),
"down": ("/dev/gpiochip0", 27),
"left": ("/dev/gpiochip0", 22),
"right": ("/dev/gpiochip0", 23),
"press": ("/dev/gpiochip0", 4),
"key1": ("/dev/gpiochip0", 21),
"key2": ("/dev/gpiochip0", 20),
"key3": ("/dev/gpiochip0", 16),
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The button pin names for RPI_26 configuration use lowercase names ("up", "down", "left", "right", "press") while all other configurations use uppercase names ("KEY_UP", "KEY_DOWN", etc.). This inconsistency will cause the lookup in buttons.py line 91 (pin_mapping.get(name) or pin_mapping.get(name.lower())) to fail for the RPI_26 configuration since it tries the uppercase version first and doesn't fall back correctly. Standardize all button pin names to use the same case convention.

Suggested change
"up": ("/dev/gpiochip0", 17),
"down": ("/dev/gpiochip0", 27),
"left": ("/dev/gpiochip0", 22),
"right": ("/dev/gpiochip0", 23),
"press": ("/dev/gpiochip0", 4),
"key1": ("/dev/gpiochip0", 21),
"key2": ("/dev/gpiochip0", 20),
"key3": ("/dev/gpiochip0", 16),
"KEY_UP": ("/dev/gpiochip0", 17),
"KEY_DOWN": ("/dev/gpiochip0", 27),
"KEY_LEFT": ("/dev/gpiochip0", 22),
"KEY_RIGHT": ("/dev/gpiochip0", 23),
"KEY_PRESS": ("/dev/gpiochip0", 4),
"KEY1": ("/dev/gpiochip0", 21),
"KEY2": ("/dev/gpiochip0", 20),
"KEY3": ("/dev/gpiochip0", 16),

Copilot uses AI. Check for mistakes.
@3rdIteration 3rdIteration force-pushed the luckfox-staging-portability branch 2 times, most recently from 03e48de to 99a22ce Compare February 16, 2026 19:40
@3rdIteration 3rdIteration force-pushed the luckfox-staging-portability branch from 99a22ce to 211d2f3 Compare February 16, 2026 19:40
3rdIteration and others added 5 commits February 22, 2026 17:02
Add IO config consistency guidance to AGENTS.md
…-io_config-pin-mismatch

Correct Luckfox Pico Pi (FOX_PI) display/button mapping to blue GPIO labels
…tion-and-key2-busy

Fix Luckfox GPIO chip resolution and button init races
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.

2 participants