/* Correction du TP 4 (partie 1, sans OS) -- extraits de Core/Src/main.c.
 *
 * Configuration CubeMX : PB15 = TIM12_CH2, PWM Generation CH2, PSC 0,
 * ARR 2559 (25 kHz a 64 MHz) ; I2C2 sur PB10/PB11 (etape 3) ; SYS Debug =
 * Serial Wire ; horloge HSI par defaut.
 * Mesure de reference (cahier de labo, 2026-09-26) : ventilateur 2 fils qui
 * tourne a 100 %, cale a 95 %, meme apres une montee a pleine vitesse.
 */

/* ===== USER CODE BEGIN PD =================================================== */
#define FAN_PERIOD      2560u           /* ARR + 1 */
#define TMP102_ADDR     (0x48u << 1)
#define FAN_ON_mC       35000
#define FAN_OFF_mC      32000
/* USER CODE END PD */

/* ===== USER CODE BEGIN PV =================================================== */
volatile uint32_t g_fan_pct;     /* palier courant, lu au debogueur */
volatile int32_t  g_temp_mC;
volatile uint32_t g_fan_on;
/* USER CODE END PV */

/* ===== USER CODE BEGIN 0 ==================================================== */
static void fan_set_pct(uint32_t pct)
{
    if (pct > 100u) { pct = 100u; }
    g_fan_pct = pct;
    __HAL_TIM_SET_COMPARE(&htim12, TIM_CHANNEL_2, (FAN_PERIOD * pct) / 100u);
}

static int temp_read_mC(int32_t *out)
{
    uint8_t b[2];
    int32_t raw;

    if (HAL_I2C_Mem_Read(&hi2c2, TMP102_ADDR, 0x00u, I2C_MEMADD_SIZE_8BIT,
                         b, 2u, 5u) != HAL_OK) { return 0; }
    raw = (int32_t)((((uint16_t)b[0] << 8) | b[1]) >> 4);
    if (raw & 0x800) { raw -= 4096; }
    *out = (raw * 625) / 10;
    return 1;
}
/* USER CODE END 0 */

/* ===== USER CODE BEGIN 2 ====================================================
    HAL_TIM_PWM_Start(&htim12, TIM_CHANNEL_2);
   USER CODE END 2 */

/* ===== Dans while (1), USER CODE BEGIN 3 ====================================
 * Une seule des variantes ci-dessous a la fois. */

/* Etape 1 : de 100 % a 0 %, paliers de 5 %, 5 s chacun, puis on recommence. */
#if 0
    for (int32_t p = 100; p >= 0; p -= 5)
    {
        fan_set_pct((uint32_t)p);
        HAL_Delay(5000);
    }
#endif

/* Question 3 : une seconde a 100 %, puis 70 %. */
#if 0
    fan_set_pct(100u);
    HAL_Delay(1000);
    fan_set_pct(70u);
    HAL_Delay(10000);
#endif

/* Etape 3 : thermostat tout ou rien, hysteresis 32 / 35 degC. */
#if 1
    {
        int32_t t;

        if (temp_read_mC(&t))
        {
            g_temp_mC = t;
            if (!g_fan_on && (t >= FAN_ON_mC))     { g_fan_on = 1u; }
            else if (g_fan_on && (t <= FAN_OFF_mC)) { g_fan_on = 0u; }
        }
        fan_set_pct(g_fan_on ? 100u : 0u);
        HAL_Delay(1000);
    }
#endif
/* USER CODE END 3 */

/* Reponses attendues aux questions :
 *  1. 64 MHz / (0 + 1) / (2559 + 1) = 25 000 Hz.
 *  2. Non : il garde sa vitesse puis cale d'un coup, vers 95 % pour le
 *     modele des robots (selon le modele, un peu plus bas).
 *  3. Non (mesure RatBot : meme apres six secondes a pleine vitesse, 70 % ne
 *     le maintient pas) : ce n'est pas un probleme de demarrage.
 *  4. L'electronique interne et sa tolerance aux coupures varient d'un
 *     modele a l'autre (condensateur interne plus ou moins gros).
 *  5. L'alimentation reste permanente ; seule la consigne de vitesse est
 *     decoupee, sur un fil separe, et l'electronique ne decroche plus.
 *  6. Avec un seul seuil, le bruit de mesure ferait demarrer et arreter le
 *     ventilateur sans cesse autour du seuil : deux seuils (hysteresis)
 *     l'evitent.
 */
