# SXXXXXXX_PyDownloadFwViaSRIO

Applicazione Python per la programmazione remota di flash memory via protocollo **SRIO-over-TFTP**.

## Caratteristiche

- ✅ **Protocollo SRIO completo**: Implementazione fedele del protocollo da `dwl_fw.cpp` (Linux) con gestione registri flash controller
- ✅ **GUI intuitiva**: Interfaccia Tkinter con selezione target, dual log panels (General + TFTP), progress bar
- ✅ **Gestione multi-target**: Configurazione basata su `targets.ini` con supporto Golden/User memory areas
- ✅ **TFTP client/server**: Comunicazione TFTP Windows-compatible (no dipendenze esterne)
- ✅ **Flash operations**: Erase (64KB sectors), Write (256-byte chunks), Verify con retry logic
- ✅ **QSPI initialization**: Sequenza `op_init_qspi()` automatica (chiamata 2x come da riferimento C++)
- ✅ **Server di test**: Emulatore TFTP con simulazione completa registri SRIO e flash controller
- ✅ **Abort operations**: Interruzione quasi istantanea (<2ms) di operazioni lunghe tramite pulsante dedicato

## Struttura Progetto

```
SXXXXXXX_PyDownloadFwViaSRIO/
├── pydownloadfwviasrio/          # Package principale
│   ├── core/
│   │   ├── core.py                # FirmwareFlasher (erase/write/verify)
│   │   └── srio_flash.py          # SRIOFlashController (protocollo registri)
│   ├── gui/
│   │   └── gui.py                 # FlasherGUI (interfaccia Tkinter)
│   ├── profiles.py                # GlobalConfig, FlashModel, FlashTarget
│   ├── tftp_client.py             # SRIOTFTPClient (TFTP sender)
│   └── __main__.py                # Entry point
├── _OLD/                          # Riferimenti C++/Qt (protocollo)
│   ├── linux_app/dwl_fw.cpp       # Implementazione Linux SRIO (RIFERIMENTO)
│   └── Vecchia_app/               # Qt app (fpgaflashengine, fpgaflashinterface)
├── tools/
│   └── tftp_receiver.py           # Server TFTP di test con simulazione flash
├── doc/                           # Documentazione
└── flash_profiles.json            # Configurazione target persistente
```

## Installazione

### Requisiti
- Python 3.10+
- Windows / Linux / macOS

### Setup ambiente virtuale

```bash
# Clona repository
git clone <repository_url>
cd SXXXXXXX_PyDownloadFwViaSRIO

# Crea virtual environment
python -m venv .venv

# Attiva venv (Windows)
.venv\Scripts\activate

# Attiva venv (Linux/macOS)
source .venv/bin/activate

# Installa dipendenze
pip install -r requirements.txt
```

## Utilizzo

### Avvio GUI

```bash
python -m pydownloadfwviasrio
```

### Workflow tipico

1. **Seleziona Target**: Scegli dal menu a tendina (es. "EIF_FPGA1")
2. **Verifica configurazione**: Il pannello "Target Information" mostra IP, slot SRIO, modello, aree memoria
3. **Scegli operazione**:
   - **🗑️ Erase**: Cancella settore flash (64KB) → inserisci indirizzo start/end
   - **✍️ Write**: Scrive file binario → seleziona file e indirizzo destinazione
   - **🔍 Verify**: Legge flash e confronta con file
   - **🔄 Full Sequence**: Sequenza completa automatica (Erase + Write + Verify)
   - **🛑 ABORT**: Interrompe operazione in corso (disponibile durante operazioni lunghe)

### Funzione ABORT

Durante operazioni lunghe (Erase, Write, Verify, Full Sequence):
- Il pulsante **"🛑 ABORT"** (rosso) diventa attivo
- Cliccare per **interrompere immediatamente** l'operazione (< 2ms)
- La flash rimane nello stato raggiunto (es. settori parzialmente cancellati/scritti)
- Utile per correggere file/indirizzo sbagliato senza attendere il completamento

**⚠️ Attenzione**: Dopo un abort durante Full Sequence, ripetere l'operazione completa per garantire consistenza della flash.

### Log panels

- **General Log** (sinistra): Messaggi applicazione, progress, errori
- **TFTP Commands** (destra): Trace protocollo TFTP (PUT/GET con indirizzi SRIO)

### Testing con server emulatore

**Terminale 1 - Server:**
```bash
python tools/tftp_receiver.py --port 6969
```

**Terminale 2 - Client:**
```bash
python -m pydownloadfwviasrio
# Configura IP: 127.0.0.1, Port: 6969
```

Il server logga tutte le operazioni SRIO (MODE_REG, CMD_REG, flash erase/write/read) e simula il comportamento hardware.

## Configurazione

### File `targets.ini`

Formato INI con sezioni `[default]`, `[MODEL-x]`, `[TGT-x]`:

```ini
[default]
ip = 192.168.1.100
port = 69
default_target = TGT-DWL_BRD-1

[MODEL-1]
model = MT25QL128
description = Micron 128Mbit NOR Flash
flash_type = NOR
is_4byte_addressing = false
num_sectors = 256
golden_start = 0x00000000
golden_stop = 0x007FFFFF
user_start = 0x00800000
user_stop = 0x00FFFFFF

[TGT-1]
id_target = TGT-DWL_BRD-1
description = Download Board #1
slot_address = 0x13
architecture = PowerPC
model = MODEL-1
golden_binary_path = C:/firmware/golden.bin
user_binary_path = C:/firmware/user.bin
```

### Gestione profili via GUI

1. **Manage Configuration** → apre finestra multi-tab
2. **Tab "Global"**: IP, porta, target di default
3. **Tab "Flash Models"**: Definizione modelli flash (tipo, addressing, settori, aree memoria)
4. **Tab "Targets"**: Configurazione singoli target (slot SRIO, modello, path binari)
5. **Save** → persiste in `flash_profiles.json`

## Protocollo SRIO Flash

### Architettura registri (da `dwl_fw.h`)

```
MODE_REG       0x4700002C  # Flash mode (primary/secondary)
CMD_REG        0x47000030  # Flash command (0x06,0xD8,0x02,0x0B,0x05)
ADDR_REG       0x47000034  # Flash address
NUM_BYTE_REG   0x47000038  # Transfer size
CTRL_REG       0x47000060  # Control (0x01=START, 0x00=END, 0x03=WRITE/READ)
TX_FIFO_REG    0x47000400  # TX FIFO (256 bytes)
STATUS_REG     0x47000864  # Status bits (11=busy, 12=tx_empty)
RX_FIFO_REG    0x47000C00  # RX FIFO (read data/status)
```

### Sequenza operazioni (da `dwl_fw.cpp`)

#### 1. Inizializzazione QSPI (automatica)
```python
# Chiamata automaticamente 2 volte al primo erase/write/verify
init_qspi()  # op_init_qspi() + op_init_qspi()
```

#### 2. Erase sector
```python
# Cancella 64KB sector
erase_section(endpoint, address)
wait_flash_with_retry(MAX_RETRY_READ=1000)
```

#### 3. Write flash
```python
# Scrive 256 byte
write_flash(endpoint, address, data_256bytes)
usleep(WRITE_DELAY_US=100000)       # 100ms
wait_flash_with_retry(MAX_RETRY_READ=1000)
usleep(WAITFLASH_DELAY_US=100000)   # 100ms
```

#### 4. Verify
```python
# Legge 256 byte e confronta
read_flash(endpoint, address, 256)
```

### Comandi flash (CMD_REG values)

- **0x06**: Write Enable
- **0xD8**: Sector Erase (64KB)
- **0x02**: Page Program (256 bytes)
- **0x0B**: Fast Read
- **0x05**: Read Status Register
- **0x61**: Write Volatile Config (QSPI init)
- **0xB7**: Enter 4-byte Address Mode (QSPI init)

## Riferimenti

- **Protocollo Linux**: `_OLD/linux_app/dwl_fw.cpp` (implementazione C++ SRIO)
- **Vecchia GUI Qt**: `_OLD/Vecchia_app/FpgaBeamMeUp/` (fpgaflashengine, fpgaflashinterface)
- **Documentazione**: `doc/architecture.md`, `doc/Italian-manual.md`

## Sviluppo

### Run in modalità sviluppo
```bash
python -m pydownloadfwviasrio
```

### Test protocollo
```bash
# Test TFTP client
python -c "from pydownloadfwviasrio.tftp_client import SRIOTFTPClient; c = SRIOTFTPClient('127.0.0.1', 6969); print(c)"

# Migrazione profili
python tools/migrate_profiles_json.py
```

### Struttura codice

- **Separazione concerns**: `core/` (business logic), `gui/` (UI), `profiles.py` (config)
- **Type hints**: Tutte le funzioni pubbliche annotate
- **Logging**: Dual callbacks (general + TFTP) per separazione log
- **Retry logic**: Timeout e retry automatici su operazioni TFTP

## Licenza

[Specificare licenza]

## Contributi

[Linee guida per contributi]

