# GrifoScope Startup Sequence Analysis

## Obiettivo
Identificare la sequenza di inizializzazione che GrifoScope esegue per preparare il radar all'operatività, da replicare in PyBusMonitor1553.

## Analisi Codice C++

### 1. Inizializzazione Messaggi A1/A2 (Startup Protection)

**File**: `cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/g346_a1a2.cpp`

#### A1 - Radar Settings (`GrifoMsg_A1B6::startProtection()` - linea 10-12)
```cpp
void GrifoMsg_A1B6::startProtection()
{
    dSymbInt.setFromUser(127);  // Symbol Intensity = MAX
}
```

#### A1 - Valori di Default (linee 162-163)
```cpp
dSymbInt.setFromUser(127);      // Symbol Intensity = 127 (massimo)
dIfGain.setFromUser(127);       // IF Gain = 127 (massimo)
dAltBlock.setFromUser(McsG346AltBlock::NORMAL);  // Altitude Block = NORMAL
```

#### A2 - Radar Operation Command (`GrifoMsg_A2B7::startProtection()` - linee 414-416)
```cpp
void GrifoMsg_A2B7::startProtection()
{
    dSilence.setFromUser(1);    // Silence = ON (1)
    dStby.setFromUser(1);       // Standby = ON (1)
}
```

#### A2 - Valori di Default (linee 697-698)
```cpp
dSilence.setFromUser(1);   // Silence = ON (1) - Trasmettitore disabilitato
dStby.setFromUser(1);      // Standby = ON (1) - Radar in standby
```

### 2. Campi 1553 ICD

**File**: `cpp/GrifoScope/GrifoSdkEif/pub/TH/th_b1553_icd.h`

#### Standby Selection (linee 417-424)
```cpp
enum stby_selection_t
{
  STBY_OFF,  // 0 = Radar operativo
  STBY_ON    // 1 = Radar in standby
};

typedef idd_boolfield_u16_t<IDD_REVBIT16(8), stby_selection_t> stby_field_t;
```

**Posizione**: Word A2-01, bit 8 (reversed: bit 7 in Python 0-based)

#### Silence Selection (linee 428, 443, 457)
```cpp
typedef bool silence_selection_t;

typedef idd_bitfield_u16_t<IDD_REVBIT16(12), 1, silence_selection_t> silence_field_t;

union rdr_mode_command_word_t {
    ...
    silence_field_t silence;  // reserved
    ...
};
```

**Posizione**: Word A2-01, bit 12 (reversed: bit 3 in Python 0-based)

**Valori**:
- `0` = Silence OFF → Trasmettitore abilitato
- `1` = Silence ON → Trasmettitore disabilitato (modalità sicura)

### 3. Controlli GUI

**File**: `cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/mcs_g346.cpp` (linee 1199-1204)

```cpp
QAction* qStby=new QAction(&wb.mainWindow());
qStby->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_F1));  // CTRL+F1
qStby->setStatusTip("STBY!");
qStby->setText("STBY");
AdsWidgetsManager::mapAction(theMsg->A2B7.actSTBY, *qStby);
```

**Shortcut**: `CTRL+F1` per toggle STBY

**File**: `cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/grifocmddock.cpp` (linee 32-33)

```cpp
//ui->tb_ads_silence->setVisible(false);
ui->tb_ads_silence->setEnabled(false);  // Silence button DISABILITATO
```

**Nota**: Il pulsante Silence è disabilitato nell'interfaccia GUI. Questo suggerisce che il controllo Silence potrebbe essere gestito automaticamente o non utilizzato nel sistema G346.

### 4. Azioni Toggle (linee 514-516)

```cpp
actSTBY.setObjectName("act_STBY");
actSTBY.attachTo(&dStby);
actSTBY.setActionValue(0, 1);  // 0=OFF, 1=ON
```

## Sequenza di Startup Radar

### Fase 1: Inizializzazione Sicura (Power-On)

Al primo avvio, GrifoScope imposta:

**Messaggio A1 (Radar Settings)**:
- `symbol_intensity` = 127 (massimo)
- `if_gain` = 127 (massimo)
- `altitude_block` = NORMAL
- Tutti gli altri campi ai valori di default (tipicamente 0)

**Messaggio A2 (Radar Operation)**:
- `stby` = 1 (STBY_ON) → Radar in standby
- `silence` = 1 (ON) → Trasmettitore disabilitato
- `master_mode` = 0 o valore precedente
- `designation_control` = NOT_VALID (7 per 3 bit)

### Fase 2: Attivazione ("Run" → Rimozione Standby/Silence)

Quando l'operatore preme "Run" e rimuove Standby/Silence:

**Messaggio A2 modificato**:
- `stby` = 0 (STBY_OFF) → Radar operativo
- `silence` = 0 (OFF) → Trasmettitore abilitato
- `master_mode` = RWS (o altro modo selezionato)
- Altri parametri operativi come range, scan, etc.

**Messaggio A1** (può essere aggiornato con valori operativi):
- `target_history` = valore desiderato (es. 3)
- `symbol_intensity` = valore desiderato
- Frequency channel, gains, etc.

## Campi Python Mapping

### Messaggio A1 (`msg_a1.py`)

**Già implementati**:
- ✅ `symbol_intensity` - BitField(0, 0, 7)
- ✅ `if_gain` - BitField(1, 0, 7) 
- ✅ `target_history` - BitField(0, 8, 3)
- ✅ `ground_reject_vel_high` - BitField(0, 15, 1)
- ✅ `frequency_channel` - BitField(1, 8, 6)

**Mancante**:
- ❌ `altitude_block` - BitField (word 0, bits da verificare)

### Messaggio A2 (`msg_a2.py`)

**Già implementati**:
- ✅ `master_mode` - EnumField(0, 0, 4, MasterMode)
- ✅ `designation_control` - EnumField(0, 4, 3, DesignationControl) 
- ✅ `priority_target_number` - BitField(2, 0, 6)
- ✅ `range_scale` - EnumField(1, 0, 4, RangeScale)
- ✅ `scan_width` - EnumField(1, 4, 3, ScanWidth)
- ✅ `velocity_scale` - EnumField(1, 7, 2, VelocityScale)

**Mancanti (CRITICI per startup)**:
- ❌ `stby` - BitField(0, 7, 1)  # IDD_REVBIT16(8) = bit 7
- ❌ `silence` - BitField(0, 3, 1)  # IDD_REVBIT16(12) = bit 3
- ❌ `freeze` - BitField(0, 6, 1)  # IDD_REVBIT16(9) = bit 6
- ❌ `ibit_request` - BitField(0, 8, 1)  # IDD_REVBIT16(7) = bit 8

## Implementazione Python Raccomandata

### 1. Completare msg_a2.py

```python
# In pybusmonitor1553/lib1553/messages/msg_a2.py

# Word 0 - Radar Mode Command (rdr_mode_command_word_t)
master_mode = EnumField(0, 0, 4, MasterMode)
designation_control = EnumField(0, 4, 3, DesignationControl)
stby = BitField(0, 7, 1)          # NUOVO - Standby control
ibit_request = BitField(0, 8, 1)   # NUOVO - IBIT request
freeze = BitField(0, 6, 1)         # NUOVO - Freeze selection
stop_powerup = BitField(0, 5, 1)   # NUOVO - Reserved
reserved_11 = BitField(0, 11, 1)   # NUOVO - Emergency/reserved
silence = BitField(0, 3, 1)        # NUOVO - Silence control (trasmettitore)
sar_exec = BitField(0, 13, 1)      # NUOVO - SAR execution type
```

### 2. Creare Funzione Startup

```python
# In pybusmonitor1553/core/radar_startup.py

def initialize_radar_safe_state() -> tuple[MsgA1, MsgA2]:
    """
    Crea messaggi A1/A2 con valori di startup sicuri (Standby + Silence ON).
    
    Questa è la configurazione iniziale che GrifoScope usa al power-on
    per proteggere il radar.
    
    Returns:
        (msg_a1, msg_a2): Messaggi pronti per l'invio
    """
    # A1: Radar Settings - valori di default sicuri
    msg_a1 = MsgA1()
    msg_a1.symbol_intensity = 127          # Massimo (startup protection)
    msg_a1.if_gain = 127                   # Massimo
    msg_a1.target_history = 0              # Default
    msg_a1.ground_reject_vel_high = 0      # Default
    msg_a1.frequency_channel = 0           # Default
    # ... altri campi a 0
    
    # A2: Radar Operation - SAFE MODE
    msg_a2 = MsgA2()
    msg_a2.master_mode = MasterMode.NO_OPERATION  # 0
    msg_a2.designation_control = DesignationControl.NOT_VALID  # 7
    msg_a2.stby = 1                        # STANDBY ON
    msg_a2.silence = 1                     # SILENCE ON (TX disabilitato)
    msg_a2.freeze = 0                      # No freeze
    msg_a2.ibit_request = 0                # No IBIT
    # ... altri campi a valori di default
    
    return msg_a1, msg_a2


def activate_radar_operational() -> MsgA2:
    """
    Crea messaggio A2 per attivare il radar (rimuove Standby e Silence).
    
    Questa è l'operazione che l'utente fa in GrifoScope premendo "Run" 
    e disattivando Standby/Silence.
    
    Returns:
        msg_a2: Messaggio A2 con radar pronto all'operatività
    """
    msg_a2 = MsgA2()
    msg_a2.stby = 0                        # STANDBY OFF
    msg_a2.silence = 0                     # SILENCE OFF (TX abilitato)
    msg_a2.master_mode = MasterMode.RWS    # Modo operativo (es. RWS)
    msg_a2.designation_control = DesignationControl.TWS  # Modo designation
    msg_a2.freeze = 0
    msg_a2.ibit_request = 0
    # ... configurare altri parametri operativi
    
    return msg_a2


def radar_startup_sequence(bc: BusController):
    """
    Esegue la sequenza completa di startup del radar.
    
    Replicata da GrifoScope:
    1. Invia A1/A2 con valori sicuri (Standby + Silence ON)
    2. Attende conferma dal radar (B6/B7)
    3. Rimuove Standby e Silence
    4. Configura modo operativo
    
    Args:
        bc: BusController connesso al radar
    """
    import time
    
    # Step 1: Invia configurazione sicura
    print("Step 1: Inizializzazione radar (SAFE MODE)")
    msg_a1, msg_a2 = initialize_radar_safe_state()
    bc.send_command(1, msg_a1)
    time.sleep(0.1)
    bc.send_command(2, msg_a2)
    time.sleep(0.5)  # Attendi stabilizzazione
    
    # Step 2: Verifica stato radar
    print("Step 2: Verifica stato radar")
    msg_b7 = bc.request_data(7, MsgB7, timeout=1.0)
    if msg_b7:
        print(f"  Radar status: mode={msg_b7.master_mode}, stby={msg_b7.standby_status}")
    else:
        print("  WARNING: Nessuna risposta da B7")
    
    # Step 3: Attiva radar (rimuovi Standby/Silence)
    print("Step 3: Attivazione radar (Standby/Silence OFF)")
    msg_a2_active = activate_radar_operational()
    bc.send_command(2, msg_a2_active)
    time.sleep(0.5)
    
    # Step 4: Verifica attivazione
    print("Step 4: Verifica attivazione")
    msg_b7 = bc.request_data(7, MsgB7, timeout=1.0)
    if msg_b7:
        print(f"  Radar active: mode={msg_b7.master_mode}, RF={msg_b7.rf_radiation}")
        if msg_b7.standby_status == 0 and msg_b7.rf_radiation:
            print("  ✓ Radar OPERATIVO")
        else:
            print("  ⚠ Radar non completamente attivo")
    
    print("Startup sequence completata")
```

### 3. Esempio Utilizzo

```python
from pybusmonitor1553.core.bus_controller import BusController
from pybusmonitor1553.core.radar_startup import radar_startup_sequence

# Connetti al radar
bc = BusController(rt_ip="192.168.1.100")
bc.connect()

# Esegui sequenza startup
radar_startup_sequence(bc)

# Ora il radar è pronto per comandi operativi
# ... invio comandi A2 per cambiare modo, range, etc.

bc.disconnect()
```

## Note Implementative

### Bit Position Conversion (IDD_REVBIT16)

**Formula C++**: `IDD_REVBIT16(pos) = 15 - pos`

**Esempi**:
- `IDD_REVBIT16(8)` → bit 7 in Python (stby)
- `IDD_REVBIT16(12)` → bit 3 in Python (silence)
- `IDD_REVBIT16(9)` → bit 6 in Python (freeze)
- `IDD_REVBIT16(7)` → bit 8 in Python (ibit_request)

### Verificare con B7 (Radar Status Tellback)

**Campi B7 da controllare**:
- `standby_status` → deve essere 0 quando operativo
- `rf_radiation` → deve essere 1 quando TX attivo
- `master_mode` → deve corrispondere al comando A2
- `designation_mode` → deve corrispondere al comando A2

## Riferimenti

- **ICD Header**: `cpp/GrifoScope/GrifoSdkEif/pub/TH/th_b1553_icd.h`
- **Implementazione A1/A2**: `cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/g346_a1a2.cpp`
- **GUI Controls**: `cpp/GrifoScope/GrifoMCS/GADS/MCS/MCS_G346/g346/mcs_g346.cpp`
- **Python Messages**: `pybusmonitor1553/lib1553/messages/msg_a2.py`
