diff --git a/README.md b/README.md index e7ced65..c518d61 100644 --- a/README.md +++ b/README.md @@ -43,17 +43,21 @@ To bypass the memory and protocol constraints of the microcontroller, we use a h * **[boot.py](boot.py)**: Automatically connects to Wi-Fi using credentials in `wifi_config.py` and renders connection logs on the screen. * **[main.py](main.py)**: Background execution loop. Handlers for buttons (manual dashboard refresh, LED state cycle), NeoPixel animation loop, and non-blocking MCP server requests. * **[mcp_server.py](mcp_server.py)**: The lightweight JSON-RPC server implementing the MCP tools list and call handlers. -* **[audio_util.py](audio_util.py)**: Audio drivers for the ES7210 microphone array and the ES8311 speaker DAC. Implements sine-wave tone generation (`play_tone`), voice recording (`record_audio`), and file-based audio playing (`play_wav`). -* **[rlcd.py](rlcd.py)**: Low-level FrameBuffer driver for the 4.2" Reflective LCD, including PBM loaders and screenshot exporters. -* **[sd_util.py](sd_util.py)**: Mounting and filesystem management utility for the onboard microSD card slot. -* **Hardware Drivers**: - * [shtc3_util.py](shtc3_util.py) (Temperature & Humidity) - * [rtc_util.py](rtc_util.py) (Hardware Real-Time Clock) - * [battery_util.py](battery_util.py) (Voltage & Capacity reader) - * [rgb_led_util.py](rgb_led_util.py) (WS2812 NeoPixel animations) - * [button_util.py](button_util.py) (Key & Boot button debouncer) - * [ble_util.py](ble_util.py) (Passive BLE scanning & UART) * **[wifi_config.py](wifi_config.py)**: Wi-Fi credentials. **(Do not commit real credentials to Git)**. +* **`lib/`**: Hardware drivers and utility modules automatically searched by MicroPython: + * **[audio_util.py](lib/audio_util.py)**: Audio drivers for the ES7210 microphone array and the ES8311 speaker DAC. Implements sine-wave tone generation (`play_tone`), voice recording (`record_audio`), and file-based audio playing (`play_wav`). + * **[rlcd.py](lib/rlcd.py)**: Low-level FrameBuffer driver for the 4.2" Reflective LCD, including PBM loaders and screenshot exporters. + * **[sd_util.py](lib/sd_util.py)**: Mounting and filesystem management utility for the onboard microSD card slot. + * **[shtc3_util.py](lib/shtc3_util.py)**: Temperature & Humidity sensor utility. + * **[rtc_util.py](lib/rtc_util.py)**: PCF85063 Hardware Real-Time Clock driver. + * **[battery_util.py](lib/battery_util.py)**: Battery voltage and capacity reader. + * **[rgb_led_util.py](lib/rgb_led_util.py)**: WS2812 NeoPixel animation manager. + * **[button_util.py](lib/button_util.py)**: Boot/Key button debouncer utility. + * **[ble_util.py](lib/ble_util.py)**: Passive BLE scanning and BLE UART interface. + * **[ft6336u.py](lib/ft6336u.py)**: I2C Capacitive touchscreen controller driver. + * **[ili9341.py](lib/ili9341.py)**: ILI9341 LCD driver. + * **[st7796.py](lib/st7796.py)**: ST7796 LCD driver. + * **[download_util.py](lib/download_util.py)**: Helper for streaming downloads to the local filesystem. ### Host-Side files * **[mcp_bridge.py](mcp_bridge.py)**: The stdio-to-HTTP LAN bridge connecting the LLM client to the board. Handles image resizing, dithering, and formatting. diff --git a/audio_util.py b/lib/audio_util.py similarity index 100% rename from audio_util.py rename to lib/audio_util.py diff --git a/battery_util.py b/lib/battery_util.py similarity index 100% rename from battery_util.py rename to lib/battery_util.py diff --git a/ble_util.py b/lib/ble_util.py similarity index 100% rename from ble_util.py rename to lib/ble_util.py diff --git a/button_util.py b/lib/button_util.py similarity index 100% rename from button_util.py rename to lib/button_util.py diff --git a/download_util.py b/lib/download_util.py similarity index 100% rename from download_util.py rename to lib/download_util.py diff --git a/ft6336u.py b/lib/ft6336u.py similarity index 100% rename from ft6336u.py rename to lib/ft6336u.py diff --git a/ili9341.py b/lib/ili9341.py similarity index 100% rename from ili9341.py rename to lib/ili9341.py diff --git a/rgb_led_util.py b/lib/rgb_led_util.py similarity index 100% rename from rgb_led_util.py rename to lib/rgb_led_util.py diff --git a/rlcd.py b/lib/rlcd.py similarity index 100% rename from rlcd.py rename to lib/rlcd.py diff --git a/rtc_util.py b/lib/rtc_util.py similarity index 100% rename from rtc_util.py rename to lib/rtc_util.py diff --git a/sd_util.py b/lib/sd_util.py similarity index 100% rename from sd_util.py rename to lib/sd_util.py diff --git a/shtc3_util.py b/lib/shtc3_util.py similarity index 100% rename from shtc3_util.py rename to lib/shtc3_util.py diff --git a/st7796.py b/lib/st7796.py similarity index 100% rename from st7796.py rename to lib/st7796.py diff --git a/mcp_server.py b/mcp_server.py index 22c03d1..6973601 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -510,6 +510,18 @@ class MCPServer: elif name == "write_file": path = str(args.get("path")) content = str(args.get("content")) + # Auto-create parent directories on the device if present in the path + import os + parts = path.split('/') + if len(parts) > 1: + dir_path = "" + for part in parts[:-1]: + if part: + dir_path = dir_path + "/" + part if dir_path else part + try: + os.mkdir(dir_path) + except OSError: + pass # Directory likely already exists with open(path, 'w') as f: f.write(content) return f"Successfully wrote {len(content)} characters to '{path}'." diff --git a/upload_files.py b/upload_files.py index 5254f64..a9c1da4 100644 --- a/upload_files.py +++ b/upload_files.py @@ -54,10 +54,11 @@ def main(): # Upload new drivers, utilities, and updated scripts files_to_upload = [ - ("st7796.py", "st7796.py"), - ("ft6336u.py", "ft6336u.py"), - ("battery_util.py", "battery_util.py"), - ("rgb_led_util.py", "rgb_led_util.py"), + ("lib/st7796.py", "lib/st7796.py"), + ("lib/ft6336u.py", "lib/ft6336u.py"), + ("lib/battery_util.py", "lib/battery_util.py"), + ("lib/rgb_led_util.py", "lib/rgb_led_util.py"), + ("lib/audio_util.py", "lib/audio_util.py"), ("video_stream.py", "video_stream.py"), ("mcp_server.py", "mcp_server.py"), ("boot.py", "boot.py"),