/* Correction du TP 9 (partie 1, sans OS) -- extraits de Core/Src/main.c.
 *
 * Configuration CubeMX : celle du TP 5 (UART5 115200, printf) ; RCC LSE =
 * Crystal/Ceramic Resonator ; RTC Activate Clock Source (PAS Calendar) ; RTC
 * Clock Mux = LSE ; predivisers 127 / 255. LSE CSS JAMAIS active (errata
 * ES0396, perte de l'heure a chaque coupure). Horloge systeme HSI par defaut.
 */

/* ===== USER CODE BEGIN Includes ============================================= */
#include <stdio.h>
/* USER CODE END Includes */

/* ===== USER CODE BEGIN PD =================================================== */
#define RTC_SIGNATURE   0x52544331u     /* « RTC1 » en ASCII */
/* USER CODE END PD */

/* ===== USER CODE BEGIN 0 ==================================================== */
int __io_putchar(int ch)
{
    uint8_t c = (uint8_t)ch;

    HAL_UART_Transmit(&huart5, &c, 1u, 10u);
    return ch;
}

static void rtc_set(uint16_t year, uint8_t mon, uint8_t day,
                    uint8_t h, uint8_t m, uint8_t s)
{
    RTC_TimeTypeDef t = {0};
    RTC_DateTypeDef d = {0};

    t.Hours = h; t.Minutes = m; t.Seconds = s;
    t.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
    t.StoreOperation = RTC_STOREOPERATION_RESET;
    d.Year = (uint8_t)(year - 2000u); d.Month = mon; d.Date = day;
    d.WeekDay = RTC_WEEKDAY_MONDAY;       /* non utilise ici */
    HAL_RTC_SetTime(&hrtc, &t, RTC_FORMAT_BIN);
    HAL_RTC_SetDate(&hrtc, &d, RTC_FORMAT_BIN);
}

static void rtc_print(void)
{
    RTC_TimeTypeDef t;
    RTC_DateTypeDef d;

    HAL_RTC_GetTime(&hrtc, &t, RTC_FORMAT_BIN);
    HAL_RTC_GetDate(&hrtc, &d, RTC_FORMAT_BIN);   /* obligatoire, juste apres */
    printf("%04u-%02u-%02u %02u:%02u:%02u\r\n",
           2000u + d.Year, d.Month, d.Date, t.Hours, t.Minutes, t.Seconds);
}

/* Etape 3 : ne regle l'heure qu'au premier demarrage. */
static void rtc_init_once(void)
{
    if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != RTC_SIGNATURE)
    {
        rtc_set(2026u, 10u, 28u, 14u, 0u, 0u);
        HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, RTC_SIGNATURE);
        printf("heure reglee (premier demarrage)\r\n");
    }
    else
    {
        printf("heure conservee\r\n");
    }
}
/* USER CODE END 0 */

/* ===== USER CODE BEGIN 2 ====================================================
    rtc_init_once();      (etape 2 : rtc_set(...) seul, sans la signature)
   USER CODE END 2 */

/* ===== Dans while (1), USER CODE BEGIN 3 ==================================== */
#if 1
    rtc_print();
    HAL_Delay(1000);
#endif
/* USER CODE END 3 */

/* Etape 4 (commande « T AAAA-MM-JJ HH:MM:SS ») : lire la ligne comme au TP 5
 * (exercice de l'interpreteur), puis
 *     unsigned y, mo, d, h, mi, s;
 *     if (sscanf(ligne, "T %u-%u-%u %u:%u:%u", &y, &mo, &d, &h, &mi, &s) == 6)
 *         rtc_set(y, mo, d, h, mi, s);
 *
 * Reponses attendues aux questions :
 *  1. 32768 / 128 = 256 ; 256 / 256 = 1 Hz.
 *  2. Le reset ne touche pas au domaine de sauvegarde, alimente par VDD.
 *     Une coupure de VDD l'eteint, sauf si une pile bouton alimente VBAT.
 *  3. Minuit pile est une heure valide : « zero » ne distingue pas une RTC
 *     jamais reglee d'une RTC qui affiche minuit. La signature, si.
 */
