#include "sync_pulse.h"
#include "timeouts.h"
#include "id.h"
extern TIM_HandleTypeDef htim8;
volatile int watchdog_active = 0;
volatile int watchdog_started = 0;

volatile int request_syncout_activation = 0;

typedef enum {
    SYNC_PULSE_MODE_WATCHDOG = 0,
    SYNC_PULSE_MODE_SYNCOUT  = 1,
} SyncPulseMode_t;

static volatile SyncPulseMode_t s_mode = SYNC_PULSE_MODE_WATCHDOG;
void SYNC_Pulse_RequestSyncout(uint8_t enable)
{
    request_syncout_activation = enable ? 1 : 0;
}
static void SYNC_Pulse_SwitchToSyncout(void)
{
    /* Stop timer + interrupts, remap pin to GPIO output */
    SYNC_PULSE_TIM_STOP();
    SYNC_Pulse_EnableGPIO();

    /* Optional: reset flags/state for syncout mode */
    watchdog_active = 0;

    s_mode = SYNC_PULSE_MODE_SYNCOUT;
}

static void SYNC_Pulse_SwitchToWatchdog(void)
{
    /* Remap pin back to TIM8_CH1 AF, start PWM interrupts */
    SYNC_Pulse_EnableTIM8();
    SYNC_PULSE_TIM_START();

    /* Optional: reset flags/state for watchdog mode */
    watchdog_active = 0;

    s_mode = SYNC_PULSE_MODE_WATCHDOG;
}

/* Call this from main loop / fast task */
void SYNC_Pulse_Poll(void)
{
    uint8_t req = (request_syncout_activation != 0);

    if (req && (s_mode != SYNC_PULSE_MODE_SYNCOUT))
    {
        __disable_irq();
        SYNC_Pulse_SwitchToSyncout();
        __enable_irq();
    }
    else if (!req && (s_mode != SYNC_PULSE_MODE_WATCHDOG))
    {
        __disable_irq();
        SYNC_Pulse_SwitchToWatchdog();
        __enable_irq();
    }
}
uint8_t SYNC_Pulse_IsSyncoutMode(void)
{
    return (s_mode == SYNC_PULSE_MODE_SYNCOUT);
}


/* =========================================================
   Optional user hook: called from HAL callback
   (keep it simple: set this from your app code if you want)
   ========================================================= */
static void (*s_sync_pulse_cb)(void) = 0;

void SYNC_Pulse_SetCallback(void (*cb)(void))
{
    s_sync_pulse_cb = cb;
}

/* =========================================================
   IRQ enable/disable
   ========================================================= */
static void SYNC_Pulse_TIM8_EnableNVIC(void)
{
    /* TIM8 has two common IRQ lines on STM32G4:
       - TIM8_CC_IRQn         : capture/compare interrupts (PWM CC)
       - TIM8_UP_TIM13_IRQn   : update interrupt (period elapsed)
    */
    HAL_NVIC_SetPriority(TIM8_CC_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM8_CC_IRQn);

    HAL_NVIC_SetPriority(TIM8_UP_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);
}

static void SYNC_Pulse_TIM8_DisableNVIC(void)
{
    HAL_NVIC_DisableIRQ(TIM8_CC_IRQn);
    HAL_NVIC_DisableIRQ(TIM8_UP_IRQn);
}

/* =========================================================
   Public API
   ========================================================= */

/**
 * @brief Configure PA15 as TIM8_CH1 PWM output (AF2).
 * NOTE: This only sets the pin muxing. Timer configuration is assumed done elsewhere.
 */
void SYNC_Pulse_EnableTIM8(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* Remove previous GPIO config on PA15 */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);

    /* Configure PA15 alternate function = TIM8_CH1 (AF2) */
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin       = GPIO_PIN_15;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM8;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Enable TIM8 interrupts in NVIC */
    SYNC_Pulse_TIM8_EnableNVIC();
}

/**
 * @brief Start TIM8 PWM on CH1 with interrupt enabled.
 *
 * This enables CC interrupts for the channel and will call:
 *   HAL_TIM_PWM_PulseFinishedCallback()
 * (and/or other HAL callbacks depending on HAL internals)
 */
void SYNC_PULSE_TIM_START(void)
{
    /* Start PWM + interrupt */
    HAL_TIM_PWM_Start_IT(&htim8, TIM_CHANNEL_1);

    /* If you also want update (period elapsed) interrupts, uncomment:
       HAL_TIM_Base_Start_IT(&htim8);
    */
}
void SYNC_PULSE_TIM_STOP(void)
{
    /* Start PWM + interrupt */
    HAL_TIM_PWM_Stop_IT(&htim8, TIM_CHANNEL_1);
    /* If you also want update (period elapsed) interrupts, uncomment:
       HAL_TIM_Base_Start_IT(&htim8);
    */
}
/**
 * @brief Disable TIM8_CH1 PWM and return PA15 to GPIO output mode.
 */
void SYNC_Pulse_EnableGPIO(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* Stop PWM output on TIM8 CH1 (IT-safe stop) */
    HAL_TIM_PWM_Stop_IT(&htim8, TIM_CHANNEL_1);

    /* If you started base update IT, stop it too:
       HAL_TIM_Base_Stop_IT(&htim8);
    */

    /* Disable NVIC lines */
    SYNC_Pulse_TIM8_DisableNVIC();

    /* Remove AF mapping */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);

    /* Reconfigure PA15 as standard push-pull output */
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin   = GPIO_PIN_15;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Optional: set known state */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
}

void SYNC_Pulse_GPIO_set(uint8_t state)
{
    HAL_GPIO_WritePin(SYNC_OUT_GPIO_Port, SYNC_OUT_Pin,
                      state ? GPIO_PIN_SET : GPIO_PIN_RESET);
}

/* =========================================================
   Actual IRQ handlers (DEFINED HERE, not in stm32xx_it.c)
   ========================================================= */

void TIM8_CC_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim8);
}

void TIM8_UP_TIM13_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim8);
}

/* =========================================================
   HAL callbacks (choose whichever you want)
   ========================================================= */

/* Called for Update event if Base_Start_IT (or update IT) is enabled */
/*void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM8)
    {
        // Period elapsed (update)
        if (s_sync_pulse_cb) s_sync_pulse_cb();

    }
}*/
#include "can_port.h"

/* Often triggered when PWM channel finishes a pulse when using PWM_Start_IT */
#if defined(T06301)
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM8)
    {
        if (!watchdog_active){
			watchdog_active = 1;   // ✅ Pulse finished
			watchdog_started = 1;
			FIEONA_Check_Car_Startup();
	    	can_port_send_msg_def(&MSG_ID_EMPF4);
	    	Timeout_StartIfStopped(20, TIM16->CNT);  // deberia mejorarlo bastante esto, en vez de
	    	FIEONA_advance();
        }

        /* PWM CC event */
        if (s_sync_pulse_cb) s_sync_pulse_cb();
    }
}
#elif defined(cfgejemplo)

#endif

