# Architecture Documentation ## Overview `pydownloadfwviasrio` implementa un sistema di programmazione flash remota che usa **SRIO-over-TFTP** per comunicare con un target hardware. L'implementazione replica fedelmente il protocollo del software C++ di riferimento (`dwl_fw.cpp`) con workflow identico per garantire compatibilità hardware. ### Componenti principali 1. **Sender (client)**: Applicazione Python con GUI Tkinter che invia comandi flash via TFTP 2. **Receiver (target/emulator)**: Server TFTP che decodifica comandi SRIO, gestisce registri flash controller e scrive su flash memory 3. **SRIO Flash Controller**: Layer che gestisce sequenze registro-flash (MODE_REG, CMD_REG, CTRL_REG, STATUS_REG, FIFO) 4. **Profiles System**: Configurazione multi-target con supporto GlobalConfig → FlashModel → FlashTarget hierarchy ## Protocollo SRIO-over-TFTP ### Architettura Registri Flash Controller Il sistema emula un flash controller SRIO con registri mappati in memoria (da `dwl_fw.h`): ```c // Register addresses (256-byte aligned) #define MODE_REG 0x4700002C // Flash mode: 0x00=primary, 0x08=secondary #define CMD_REG 0x47000030 // Flash command byte #define ADDR_REG 0x47000034 // Flash memory address (32-bit) #define NUM_BYTE_REG 0x47000038 // Number of bytes to transfer #define CTRL_REG 0x47000060 // Control: 0x01=START, 0x00=END, 0x03=WRITE/READ #define TX_FIFO_REG 0x47000400 // TX FIFO (256 bytes for write data) #define STATUS_REG 0x47000864 // Status: bit[11]=busy/ack, bit[12]=tx_empty #define RX_FIFO_REG 0x47000C00 // RX FIFO (256 bytes for read data/status) ``` ### Formato comando TFTP I comandi SRIO vengono codificati nel **filename TFTP** secondo questo schema: ``` $SRIO:/
+ ``` **Esempi:** - `$SRIO:0x13/0x4700002C+256` → Write 256 byte a MODE_REG (registro) - `$SRIO:0x13/0x47000400+256` → Write 256 byte a TX_FIFO_REG (dati flash) - `$SRIO:0x13/0x01000000+256` → Write/Read 256 byte flash address 0x01000000 ### Operazioni Base #### Write Register (TFTP PUT) ```python # Scrive valore 0x06 a MODE_REG data = struct.pack('/
+` - ✅ Stesso chunk size: 256 byte (dwl_fw.cpp DWL_CHUNK_SIZE) - ✅ Stesso comportamento TFTP read/write - ✅ Stessa sequenza registri flash (da dwl_fw.cpp) **Differenze (miglioramenti):** - ✅ **Semplificato**: nessun Qt event loop, nessun layer FpgaFlashEngine/FlashOperation - ✅ **Workflow identico a dwl_fw.cpp**: stesso ordine operazioni, stessi delay (100ms) - ✅ **Dual log**: separazione log applicazione vs protocollo TFTP - ✅ **Testabile**: emulator locale con simulazione completa registri - ✅ **Type-safe**: type hints Python, no casting void* - ✅ **Cross-platform**: nessuna dipendenza Qt, Windows/Linux ready ## Riferimenti Codice Legacy ### dwl_fw.cpp (Linux SRIO nativo) ⭐ REFERENCE - **main()**: Sequenza completa erase→write (line 600-792) - `op_init_qspi()` x2 (line 713-714) - Erase loop con `wait_flash_with_retry()` (line 723-733) - Write loop con delay 100ms + wait + delay 100ms (line 747-767) - **Macro SRIO**: `start_request()`, `end_request()`, `send_request()`, `write_data()`, `read_data()` (line 235-293) - **Flash ops**: `erase_section()`, `write_flash()`, `read_flash()`, `wait_flash()` (line 344-594) - **Constants**: `WRITE_DELAY_US=100000`, `WAITFLASH_DELAY_US=100000`, `MAX_RETRY_READ=1000` (line 18-20) ### fgpaprogrammer.cpp (Qt SRIO-over-TFTP sender) - **rtgWrite()**: TFTP PUT con filename `$SRIO:/0x
+` (line 194-260) - **rtgRead()**: TFTP GET (line 338-410) - **Retry logic**: `NUM_REPEAT_WRITE`, `NUM_REPEAT_READ`, exponential backoff (line 225-240) ### qgtftptargetsim.cpp (Qt TFTP server emulator) - **bsk_tftpd_receive_delegate()**: Decodifica filename SRIO e gestisce operazioni (line 178-279) - **bsk_tftp_mfs_decode_filename()**: Parser filename `$SRIO:` format (line 235) ### fpgaflashengine.cpp / fpgaflashinterface.h (Qt flash abstraction) - Layer troppo complesso per le nostre esigenze - Usavamo solo per riferimento architetturale (simulator pattern) ## Decisioni Architetturali ### Perché TFTP e non TCP/UDP custom? - ✅ TFTP è standard RFC 1350, testabile con tool esterni (`tftp`, Wireshark) - ✅ Target hardware espone già server TFTP funzionante - ✅ Compatibilità con infrastruttura esistente - ✅ Debugging semplice: filename in chiaro nei log ### Perché filename-as-command? - ✅ Evita di implementare protocollo binario custom - ✅ Parsing trivial (regex su stringa) - ✅ Self-documenting (log leggibili) - ✅ Compatibile con vecchia app Qt ### Perché Python e non C++? - ✅ Rapid prototyping e facilità test - ✅ Cross-platform senza ricompilare - ✅ Type hints moderni (meglio di Qt C++ pre-C++11) - ✅ GUI Tkinter nativa (no dipendenze Qt) - ✅ TFTP client custom minimale (no `tftpy` issues con `fcntl` Windows) ### Perché SRIOFlashController separato da FirmwareFlasher? - ✅ **Separation of Concerns**: - `SRIOFlashController`: Low-level register protocol (dwl_fw.cpp lines 100-594) - `FirmwareFlasher`: High-level flash operations (dwl_fw.cpp main loop) - ✅ **Testability**: Posso testare controller SRIO senza file binari - ✅ **Reusability**: Controller riutilizzabile per altre operazioni SRIO ### Perché dual log panels? - ✅ **Debugging**: TFTP trace separato dai messaggi applicazione - ✅ **User Experience**: Utente vede progress in General Log, developer vede protocollo in TFTP Log - ✅ **Protocol Analysis**: Facile confrontare sequenza TFTP con dwl_fw.cpp ## Features Implementate ### Core - ✅ **SRIO Flash Controller**: Gestione completa registri (MODE, CMD, CTRL, STATUS, FIFO) - ✅ **QSPI Init**: `op_init_qspi()` chiamato 2x automaticamente (dwl_fw.cpp line 713-714) - ✅ **Erase**: Sector erase 64KB con `wait_flash_with_retry(MAX_RETRY_READ=1000)` - ✅ **Write**: 256-byte chunks con delay 100ms + wait + delay 100ms (dwl_fw.cpp line 561-564) - ✅ **Verify**: Read back e confronto byte-by-byte - ✅ **Retry Logic**: Exponential backoff su timeout TFTP (max 3 attempts) - ✅ **Timing**: Delay esatti da dwl_fw.cpp (WRITE_DELAY_US, WAITFLASH_DELAY_US) ### GUI - ✅ **Target Selection**: ComboBox con lista da flash_profiles.json - ✅ **Info Panel**: IP, slot, modello, aree memoria, path binari golden/user - ✅ **Dual Logs**: General + TFTP (monospace per trace protocollo) - ✅ **Progress Bar**: Percentuale e barra visuale - ✅ **Memory Area Dialog**: Selezione golden/user con indirizzi visibili - ✅ **Config Manager**: 3 tabs (Global, Models, Targets) con edit inline ### Configuration - ✅ **INI Support**: Caricamento/salvataggio `targets.ini` format - ✅ **JSON Persistence**: `flash_profiles.json` per stato runtime - ✅ **3-Level Hierarchy**: GlobalConfig → FlashModel → FlashTarget - ✅ **Binary Paths**: golden_binary_path + user_binary_path per target - ✅ **Migration**: Tool per convertire vecchi profili (tools/migrate_profiles_json.py) ### Testing - ✅ **TFTP Server Emulator**: Simulazione completa flash controller - Registri SRIO (MODE_REG, CMD_REG, CTRL_REG, STATUS_REG, FIFO) - State machine (START/END request, bit polling) - Flash operations (erase → 0xFF, write → file, read → file) - Logging dettagliato operazioni - ✅ **Local Testing**: Server + client su localhost per test senza hardware ## Prossimi Step Possibili 1. **Logging su File**: Salvare log operazioni in file per audit e debug 2. **Test Hardware Reale**: Validare con target fisico e confrontare timing con dwl_fw.cpp 3. **Checksum Verification**: Aggiungere CRC32/MD5 per verifica integrità file 4. **Batch Operations**: Supporto per programmare multipli target in parallelo 5. **Profile Import/Export**: Esportazione profili tra macchine diverse 6. **Wireshark Dissector**: Plugin per decode pacchetti TFTP con `$SRIO:` format ## Troubleshooting ### TFTP Timeout - **Causa**: Server non raggiungibile o firewall blocca porta 69/6969 - **Soluzione**: Verificare con `ping `, disabilitare firewall per test, controllare porta con `netstat` ### Flash Write Failed - **Causa**: QSPI non inizializzato, flash protetto write, bad sector - **Soluzione**: Verificare log TFTP per sequenza `op_init_qspi()`, controllare STATUS_REG error bits ### Verify Mismatch - **Causa**: Flash non scritta correttamente, read timeout, bit flip - **Soluzione**: Ripetere erase+write, aumentare retry count, controllare checksum file sorgente ### Server Not Responding - **Causa**: Server TFTP emulator non avviato, porta già in uso - **Soluzione**: `python tools/tftp_receiver.py --port 6969`, controllare con `netstat -an | findstr 6969`