#include "bsp_encoder.h"
#if (USING_SOFT_ENCODER == 0)
#include "tim.h"
#else
#include "et_encoder.h"
et_encoder_t gpio_encoder;
void         encoder_exti_callback(void);
#endif // USING_SOFT_ENCODER

volatile int32_t encoder_tim_overflow_count = 0; // 启动后就溢出, 进行++，所以初始化位-1
extern uint32_t  encoder_mode;

void pm_encoder_init(void)
{
#if (USING_SOFT_ENCODER == 0)
    MX_TIM2_Init();
#else
    et_encoder_init(&gpio_encoder);

    ENCODER_GPIO_RCC_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin              = ENCODER_GPIO_PHASE_A_Pin;
    GPIO_InitStruct.Mode             = GPIO_MODE_IT_RISING_FALLING;
    GPIO_InitStruct.Pull             = GPIO_NOPULL;
    HAL_GPIO_Init(ENCODER_GPIO_PHASE_A_Port, &GPIO_InitStruct);

    GPIO_InitStruct.Pin  = ENCODER_GPIO_PHASE_B_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(ENCODER_GPIO_PHASE_B_Port, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
    HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0);
#endif
    encoder_tim_overflow_count = 0;
}
void pm_encoder_start(void)
{
#if (USING_SOFT_ENCODER == 0)
    __HAL_TIM_ENABLE_IT(&ENCODER_TIM, TIM_IT_UPDATE);
    __HAL_TIM_URS_ENABLE(&ENCODER_TIM); // only concern update event
    __HAL_TIM_SET_COUNTER(&ENCODER_TIM, 0);
    HAL_TIM_Encoder_Start(&ENCODER_TIM, TIM_CHANNEL_ALL);
    encoder_tim_overflow_count = 0;
#else
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
    HAL_NVIC_EnableIRQ(EXTI1_IRQn);
#endif
}

void pm_encoder_stop(void)
{
#if (USING_SOFT_ENCODER == 0)
    HAL_TIM_Encoder_Stop(&ENCODER_TIM, TIM_CHANNEL_ALL);
#else
    HAL_NVIC_DisableIRQ(EXTI0_IRQn);
    HAL_NVIC_DisableIRQ(EXTI1_IRQn);
#endif
}


int32_t pm_encoder_get_count(void)
{
#if (USING_SOFT_ENCODER == 0)
    return __HAL_TIM_GET_COUNTER(&ENCODER_TIM);
#else
    return et_encoder_get_position(&gpio_encoder);
#endif
}

bool pm_encoder_counting_down(void)
{
#if (USING_SOFT_ENCODER == 0)
    return __HAL_TIM_IS_TIM_COUNTING_DOWN(&ENCODER_TIM);
#else
    return et_encoder_get_dir(&gpio_encoder) == ET_ENCODER_DIR_REVERSE ? true
                                                                       : false;
#endif
}

#if (USING_SOFT_ENCODER == 1)
void EXTI0_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(ENCODER_GPIO_PHASE_A_Pin);
}

void EXTI1_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(ENCODER_GPIO_PHASE_B_Pin);
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == ENCODER_GPIO_PHASE_A_Pin
        || GPIO_Pin == ENCODER_GPIO_PHASE_B_Pin)
    {
        bool channel_a = HAL_GPIO_ReadPin(ENCODER_GPIO_PHASE_A_Port,
                                          ENCODER_GPIO_PHASE_A_Pin);
        bool channel_b = HAL_GPIO_ReadPin(ENCODER_GPIO_PHASE_B_Port,
                                          ENCODER_GPIO_PHASE_B_Pin);
        if (__HAL_GPIO_EXTI_GET_IT(ENCODER_GPIO_PHASE_A_Pin) != RESET)
        {
            __HAL_GPIO_EXTI_CLEAR_IT(ENCODER_GPIO_PHASE_A_Pin);
            et_encoder_isr(&gpio_encoder, channel_a, channel_b);
        }
    }
}
#endif

uint32_t pm_encoder_get_cpr(void)
{
    uint8_t multi = encoder_mode == TIM_ENCODERMODE_TI12 ? 4 : 2;
    return ENCODER_PPR * multi;
}
