Metadata-Version: 2.5
Name: sim-bridge
Version: 0.1.0
Summary: Bridge G-code firmware simulation to VCD waveform analysis (AVR + STM32)
Author: grbl-multi contributors
License: MIT
Keywords: cnc,embedded,firmware,grbl,renode,simavr,simulation,vcd
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Embedded Systems
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.12
Requires-Dist: pyvcd>=0.5.0
Requires-Dist: typer>=0.15.0
Requires-Dist: vcdvcd>=2.6.0
Description-Content-Type: text/markdown

# sim-bridge

**Bridge G-code firmware simulation to VCD waveform analysis.**

sim-bridge wraps two open-source MCU simulators — [simavr](https://github.com/buserror/simavr) (AVR) and [Renode](https://renode.io/) (STM32) — and provides a unified CLI for:

1. **Launching a firmware simulation** with UART accessible via socket/PTY and GDB server for debugging.
2. **Recording GPIO signal transitions** to [VCD (Value Change Dump)](https://en.wikipedia.org/wiki/Value_change_dump) files for waveform analysis in GTKWave.

This is useful for embedded firmware developers who want to verify stepper motor timing, UART protocol behavior, or GPIO sequencing without physical hardware.

## How it works

sim-bridge runs two cooperating processes:

```
 ┌─────────────┐         TCP (JSON control)        ┌─────────────┐
 │  *-vcd CLI  │  ◄──────────────────────────►  │  *-host CLI  │
 │  (client)   │                                  │  (server)   │
 └─────────────┘                                  └──────┬──────┘
                                                        │
                                          ┌─────────────┼─────────────┐
                                          ▼             ▼             ▼
                                    ┌──────────┐ ┌──────────┐ ┌──────────┐
                                    │ UART     │ │ GDB      │ │ VCD      │
                                    │ socket/  │ │ server   │ │ hooks    │
                                    │ PTY      │ │          │ │          │
                                    └──────────┘ └──────────┘ └──────────┘
```

- **`*-host`** launches the simulator (simavr or Renode), loads firmware ELF, exposes UART for G-code I/O, opens a GDB server, and registers GPIO state-change hooks.
- **`*-vcd`** is the control client. It discovers the host via a port file in `/tmp/`, then issues `start` / `stop` / `status` / `list` commands to drive VCD recording.

## CLI commands

| Command | Platform | Role | Description |
|---------|----------|------|-------------|
| `simavr-host` | AVR | Host | Launches simavr with UART PTY + GDB + VCD control port |
| `simavr-vcd` | AVR | VCD control | Drives VCD recording on a running `simavr-host` |
| `renode-host` | STM32 | Host | Launches Renode CLI with UART socket + GDB + Robot server |
| `renode-vcd` | STM32 | VCD control | Drives VCD recording on a running `renode-host` |

> **Note:** `simavr-host` / `simavr-vcd` only support Linux (POSIX PTY + socket APIs). `renode-host` / `renode-vcd` work on Linux and macOS.

## Installation

### From PyPI

```bash
pip install sim-bridge
```

For STM32 (Renode) support, also install `renode-run` (not on PyPI):

```bash
uv tool install git+https://github.com/antmicro/renode-run.git
```

### From source

```bash
git clone <repo-url> && cd sim-bridge
uv tool install .          # recommended
# or
pip install .
```

### System dependencies

**For `simavr-host` (AVR simulation):**

```bash
# Debian/Ubuntu
sudo apt install build-essential libsimavr-dev rapidjson-dev
```

- `g++` — compiles the bundled C++ bridge on first run (cached in `/tmp/sim_bridge/`)
- `libsimavr-dev` — provides `libsimavr`, `libsimavrparts`, and headers (compatible with simavr 1.6 and 1.8)
- `rapidjson-dev` — C++ JSON parser for the control protocol

**For `renode-host` (STM32 simulation):**

```bash
uv tool install git+https://github.com/antmicro/renode-run.git
```

`renode-run` manages the Renode binary; sim-bridge calls it automatically.

## Quickstart

### AVR (simavr)

You need an AVR firmware ELF file (e.g. built with `cmake -B build -DMCU=atmega328p . && cmake --build build`).

```bash
# Terminal 1: launch simulation host
simavr-host build/atmega328p_GRBL_Debug.elf --gdbport 1234
# → UART PTY:   /tmp/simavr-uart-pty
# → GDB server: localhost:1234
# → VCD control port: auto (written to /tmp/simavr-bridge.port)

# Terminal 2: record waveforms
simavr-vcd list                        # discover available signals
simavr-vcd start -s timer1 -f out.vcd  # start recording (atomic)
# ... send G-code via PTY ...
simavr-vcd stop                        # stop → out.vcd written

# View waveform
gtkwave out.vcd
```

**Signal names** follow simavr's module convention: `<module>.<signal>` (e.g. `timer1.compa`, `uart0.rxd`, `portb.pb3`).

**Signal groups** (shorthand): use the module name as a group. Common groups on ATmega328P: `portb`, `portc`, `portd`, `timer0`, `timer1`, `timer2`, `uart0`, `adc`, `spi`, `twi`, `all`.

### STM32 (Renode)

You need a firmware ELF file and a Renode `.resc` platform script.

```bash
# Terminal 1: launch simulation host
renode-host \
    --resc platform.resc \
    --firmware build/stm32f103_GRBL_Debug.elf \
    --gdbport 3333
# → UART socket:  localhost:12345 (send G-code here)
# → GDB server:   localhost:3333
# → Robot server: auto (written to /tmp/renode-bridge.port)

# Terminal 2: record waveforms
renode-vcd list                         # discover GPIO pins
renode-vcd start -s PA0 -s PA1 -s PA3   # start recording specific pins
# ... send G-code to localhost:12345 ...
renode-vcd stop -f out.vcd              # stop → out.vcd written

# View waveform
gtkwave out.vcd
```

**Signal names** use STM32 convention: `PA0`, `PB5`, `PC15`, or entire ports `gpioPortA`, `gpioPortB`, etc. Use `all` (default) for all pins.

## Sending G-code

The UART interface accepts raw G-code over TCP (STM32) or PTY (AVR).

**Interactive (PuTTY / gtkterm):** connect to `127.0.0.1:12345` (Raw mode).

**Command line:**
```bash
echo -e '$X\nG1 X100 Y100 F1000\n' | nc -q10 127.0.0.1 12345
```

**Python script:**
```python
import socket, time

s = socket.create_connection(('127.0.0.1', 12345))
time.sleep(2); s.recv(4096)              # wait for boot

s.sendall(b'$X\n'); time.sleep(1); s.recv(4096)    # unlock
s.sendall(b'G1 X100 Y100 F1000\n')                  # move
time.sleep(10); s.recv(4096)

s.close()
```

## VCD recording details

**State machine** (host-authoritative):

```
idle ──start──► recording ──stop──► idle
```

- `start` is atomic: registers hooks + begins simulation in one step. Returns error if already recording.
- `stop` requires `--file`: pauses simulation, drains transitions, writes VCD, returns to idle.
- `status`: query current state and transition count.

**Key differences between AVR and STM32:**

| | AVR (simavr) | STM32 (Renode) |
|---|---|---|
| UART interface | PTY (`/tmp/simavr-uart-pty`) | TCP socket (`127.0.0.1:12345`) |
| VCD writing | Real-time to file during recording | In-memory; written on `stop` |
| Signal discovery | `simavr-vcd list` (module-based) | `renode-vcd list` (GPIO pin-based) |
| Port discovery file | `/tmp/simavr-bridge.port` | `/tmp/renode-bridge.port` |

## Command reference

### `simavr-host`

```
simavr-host FIRMWARE [--gdbport PORT] [--uart INDEX] [--freq HZ] [--mcu NAME]
```

Launches simavr with the given firmware ELF. The bundled C++ bridge (`simavr_uart_bridge.cpp`) is compiled on first run and cached by source hash.

### `simavr-vcd`

```
simavr-vcd list                          # list available signals
simavr-vcd start [-s SIGNAL]... [-f FILE] [--period US]
simavr-vcd status
simavr-vcd stop
```

### `renode-host`

```
renode-host --resc FILE --firmware FILE [--gdbport PORT] [--uartport PORT] [--robot-port PORT]
```

Launches Renode via `renode-run` with the given `.resc` platform script and firmware ELF.

### `renode-vcd`

```
renode-vcd list [-g PORT_LETTER]
renode-vcd start [-s SIGNAL]...
renode-vcd status
renode-vcd stop -f FILE
```

## License

MIT
