// =============================================================================
//  PULCINO — config.h
//  Configurazione dell'utente: Wi-Fi, token, variante hardware, calibrazione.
//  Questo è l'UNICO file che normalmente devi modificare prima di caricare lo sketch.
//  Pin, formati e API seguono SPEC.md (fonte di verità del progetto).
// =============================================================================
#pragma once
#include <Arduino.h>

// ----------------------------------------------------------------------------
//  Rete
// ----------------------------------------------------------------------------
// Rete Wi-Fi di casa. Se lasci WIFI_SSID vuoto (o la connessione fallisce entro
// WIFI_TIMEOUT_MS) il robot apre un Access Point "Pulcino-XXXX" (password
// AP_PASS, IP 192.168.4.1).
#define WIFI_SSID        ""
#define WIFI_PASS        ""
#define WIFI_TIMEOUT_MS  15000
#define AP_PASS          "pulcino123"
#define MDNS_NAME        "pulcino"          // -> http://pulcino.local

// Token opzionale. Se NON è vuoto, i comandi WS e le POST devono avere
// ?token=... nell'URL (la web app lo prende da http://pulcino.local/?token=...
// e lo ricorda). Stringa vuota = nessuna protezione (rete di casa fidata).
#define API_TOKEN        ""

// ----------------------------------------------------------------------------
//  Variante hardware
// ----------------------------------------------------------------------------
// 0 = servo collegati direttamente ai pin D0,D1,D2,D3,D8,D9 (ESP32Servo)
// 1 = servo sui canali 0–5 di una scheda PCA9685 (I²C), con occhi LED su 8/9,
//     lettura batteria su D0 e sensore HC-SR04 su D1/D2 (vedi SPEC.md §2.2)
#ifndef USE_PCA9685
#define USE_PCA9685      0
#endif

// ----------------------------------------------------------------------------
//  Servo: direzione e calibrazione
// ----------------------------------------------------------------------------
// Ordine dei giunti (identico ovunque):
//   0 L_hip_roll, 1 L_hip_pitch, 2 L_ankle_pitch, 3 R_hip_roll, 4 R_hip_pitch, 5 R_ankle_pitch
//
// Formula (SPEC.md §3):  angolo_servo = 90 + SERVO_DIR[i]*gradi(q_i) + CALIB_OFFSET[i]
//
// SERVO_DIR[i] (+1 / -1) traduce la convenzione "semantica" dei segni nel verso
// fisico del servo montato. Come verificarlo: metti il robot "in piedi", poi dalla
// pagina /calib muovi un giunto di +10°: per hip_roll il piede deve andare verso
// l'ESTERNO, per hip_pitch il piede deve andare in AVANTI, per ankle_pitch la
// punta deve salire. Se va al contrario, cambia il segno qui.
static const int8_t SERVO_DIR[6] = { +1, +1, +1, -1, -1, -1 };

// CALIB_OFFSET[i] in gradi: correzione del montaggio (il corno del servo non
// entra mai esattamente a 90°). COME CALIBRARE:
//   1. Carica il firmware con i servo NON ancora avvitati ai corni.
//   2. Apri http://pulcino.local/calib e premi "Tutti a 90°" (comando calib90):
//      ogni servo va a 90° + offset.
//   3. Monta i corni il più dritti possibile (gamba verticale, piede piatto,
//      hip_roll con la gamba parallela al corpo).
//   4. Con gli slider della pagina /calib correggi i gradi residui di ogni servo
//      finché il robot è perfettamente dritto, poi premi "Salva": gli offset
//      vengono salvati in NVS (memoria non volatile) e sopravvivono ai reset.
//   5. (Opzionale) Copia i valori salvati qui sotto, così restano anche se
//      cancelli la flash. I valori in NVS, se presenti, hanno la precedenza.
static const float CALIB_OFFSET[6] = { 0, 0, 0, 0, 0, 0 };

// Limiti meccanici di sicurezza dell'angolo servo (gradi) e impulsi MG90S.
#define SERVO_MIN_DEG    5
#define SERVO_MAX_DEG    175
#define SERVO_MIN_US     500     // impulso a 0°
#define SERVO_MAX_US     2400    // impulso a 180°

// ----------------------------------------------------------------------------
//  Pin (XIAO ESP32S3 Sense) — SPEC.md §2.1, NON cambiarli senza aggiornare SPEC
// ----------------------------------------------------------------------------
static const uint8_t SERVO_PINS[6] = { 1, 2, 3, 4, 7, 8 };  // D0 D1 D2 D3 D8 D9
#define PIN_SDA          5    // D4
#define PIN_SCL          6    // D5
#define PIN_I2S_BCLK     43   // D6 -> MAX98357A BCLK
#define PIN_I2S_LRC      44   // D7 -> MAX98357A LRC
#define PIN_I2S_DOUT     9    // D10 -> MAX98357A DIN
#define PIN_MIC_CLK      42   // microfono PDM interno
#define PIN_MIC_DATA     41
#define PIN_USER_LED     21   // LED arancione della XIAO (attivo basso)

// Variante PCA9685 (SPEC.md §2.2)
#define PCA9685_ADDR     0x40
#define PCA_EYE_L        8
#define PCA_EYE_R        9
#define PIN_VBAT         1    // D0: partitore 200k/100k -> VBAT = adc*3
#define PIN_SONAR_TRIG   2    // D1
#define PIN_SONAR_ECHO   3    // D2 (con partitore 5V -> 3,3V)

// ----------------------------------------------------------------------------
//  IMU (MPU6050 montato al centro sul fondo del torso)
// ----------------------------------------------------------------------------
#define MPU_ADDR         0x68
// Rimappatura assi chip -> frame robot (x avanti, y sinistra, z su).
// Di default si assume il chip montato con la sua X verso l'avanti e la Z in su.
// Se l'hai montato ruotato, scegli qui l'asse del chip (0=x,1=y,2=z) e il segno.
#define IMU_AXIS_X       0
#define IMU_SIGN_X       (+1)
#define IMU_AXIS_Y       1
#define IMU_SIGN_Y       (+1)
#define IMU_AXIS_Z       2
#define IMU_SIGN_Z       (+1)
#define IMU_ALPHA        0.98f   // filtro complementare (peso del giroscopio)

// ----------------------------------------------------------------------------
//  Audio
// ----------------------------------------------------------------------------
#define AUDIO_RATE       16000   // Hz, PCM 16 bit mono (SPEC.md §6)
#define MIC_GAIN         4       // amplificazione software del mic PDM (è molto basso)
#define SPEAKER_VOLUME   0.6f    // 0..1, volume software dello speaker

// ----------------------------------------------------------------------------
//  Movimento
// ----------------------------------------------------------------------------
#define CONTROL_HZ       50      // frequenza del ciclo di controllo (la policy è a 50 Hz)
#define MOVE_WATCHDOG_MS 1000    // senza messaggi per 1 s -> il robot si ferma
#define TELEMETRY_MS     200     // telemetria WS ~5 Hz

#define FW_VERSION       "0.1.0"
