#include "hod.h"

volatile uint8_t  g_touchIrqFlag = 0;
volatile uint32_t g_touch_state  = 0;
static TouchDrvType touchDrv;

#define HEAT_HIGH_SIDE_INIT()       PinsDrv_SetMuxModeSel(hod_high_side1_pin.port, hod_high_side1_pin.pin, PINSDRV_MUX_AS_GPIO);PinsDrv_SetPinDirection(hod_high_side1_pin.port, hod_high_side1_pin.pin, 1)
#define HEAT_HIGH_SIDE_ON()         PinsDrv_SetPin(hod_high_side1_pin.port, hod_high_side1_pin.pin)
#define HEAT_HIGH_SIDE_OFF()        PinsDrv_ClearPin(hod_high_side1_pin.port, hod_high_side1_pin.pin)

#define HEAT_HIGH_SIDE2_INIT()      PinsDrv_SetMuxModeSel(hod_high_side2_pin.port, hod_high_side2_pin.pin, PINSDRV_MUX_AS_GPIO);PinsDrv_SetPinDirection(hod_high_side2_pin.port, hod_high_side2_pin.pin, 1)
#define HEAT_HIGH_SIDE2_ON()        PinsDrv_SetPin(hod_high_side2_pin.port, hod_high_side2_pin.pin)
#define HEAT_HIGH_SIDE2_OFF()       PinsDrv_ClearPin(hod_high_side2_pin.port, hod_high_side2_pin.pin)

#define HEAT_LOW_SIDE_INIT()        PinsDrv_SetMuxModeSel(hod_low_side_pin.port, hod_low_side_pin.pin, PINSDRV_MUX_AS_GPIO);PinsDrv_SetPinDirection(hod_low_side_pin.port, hod_low_side_pin.pin, 1)
#define HEAT_LOW_SIDE_ON()          PinsDrv_SetPin(hod_low_side_pin.port, hod_low_side_pin.pin)
#define HEAT_LOW_SIDE_OFF()         PinsDrv_ClearPin(hod_low_side_pin.port, hod_low_side_pin.pin)

#define HEAT_SHD_INIT()             PinsDrv_SetMuxModeSel(hod_heat_shd_pin.port, hod_heat_shd_pin.pin, PINSDRV_MUX_AS_GPIO);PinsDrv_SetPinDirection(hod_heat_shd_pin.port, hod_heat_shd_pin.pin, 1)
#define HEAT_SHD_ON()               PinsDrv_ClearPin(hod_heat_shd_pin.port, hod_heat_shd_pin.pin)
#define HEAT_SHD_OFF()              PinsDrv_SetPin(hod_heat_shd_pin.port, hod_heat_shd_pin.pin)

static uint32_t hod_init_ticks = 0;
static uint32_t hod_init_idx   = 0;
bool hod_init(uint32_t ticks)
{
    bool ret = false;

    if (hod_init_ticks != ticks)
    {
        hod_init_ticks = ticks;

        switch (hod_init_idx)
        {
            case 0:
                 HEAT_HIGH_SIDE_INIT();
                 HEAT_HIGH_SIDE2_INIT();
                 HEAT_LOW_SIDE_INIT();
                 HEAT_SHD_INIT();

                 HEAT_HIGH_SIDE_OFF();
                 HEAT_HIGH_SIDE2_OFF();
                 HEAT_LOW_SIDE_OFF();
                 HEAT_SHD_ON();
                 break;
            case 5:
                /* Initialize touch */
                PinsDrv_SetMuxModeSel(hod_sensor_pin.port, hod_sensor_pin.pin, PINSDRV_PIN_DISABLED);
                PinsDrv_SetMuxModeSel(hod_shd_pin.port, hod_shd_pin.pin, PINSDRV_PIN_DISABLED);
                ButtonDrv_Init(NULL, &g_button_cfg);
                TouchDrv_Init(&touchDrv);
                TouchDrv_Configure(&touchDrv, &g_touchCfg);
                TouchDrv_Calibration(&touchDrv, 8192);
                TouchDrv_CleanIrqState(&touchDrv);
                g_touchIrqFlag = 0;
                NVIC_EnableIRQ(TOUCH_IRQn);
                break;
            case 1000:
                ret = true;
                break;
            default:
                break;
        }
        hod_init_idx++;
    }

    if (ret == true)
    {
        hod_init_ticks = 0;
        hod_init_idx   = 0;
    }

    return ret;
}

void TOUCH_Handler(void)
{
    TouchDrv_CleanIrqState(&touchDrv);
    g_touchIrqFlag = 1;
}

volatile static uint32_t hod_task_main_idx   = 0;
volatile static uint32_t hod_task_sub_idx    = 0;
volatile static uint32_t hod_task_last_ticks = 0;
volatile static uint32_t hod_task_heating_idx = 0;
void hod_task(uint32_t ticks)
{
    TouchDrv_InfoType info = {0};
    int16_t raw [TOUCH_SCAN_PHASE_NUM] = {0};
    int16_t base[TOUCH_SCAN_PHASE_NUM] = {0};
    int16_t diff[TOUCH_SCAN_PHASE_NUM] = {0};

    if (hod_task_last_ticks != ticks)
    {
        hod_task_last_ticks = ticks;

        if (hod_task_main_idx == 0)
        {
            hod_task_heating_idx++;
            switch (hod_task_sub_idx)
            {
            case 0:
                TouchDrv_Start(&touchDrv, TOUCHDRV_AUTO_MODE);
                hod_task_sub_idx++;
                break;
            case 1:
                if (g_touchIrqFlag) hod_task_sub_idx++;
                break;
            case 2:
                TouchDrv_Stop(&touchDrv);
                info.irqState = TouchDrv_GetIrqState(&touchDrv);
                info.proxState = TouchDrv_GetProxState(&touchDrv);
                TouchDrv_GetRawdata(&touchDrv, 0, APP_TOUCH_SCAN_PHASE_NUM, raw);
                info.raw = raw;
                info.base = base;
                info.diff = diff;
                ButtonDrv_Process(NULL, &info);

                if (ButtonDrv_GetButtonEvent(NULL, 0) == BUTTON_STATE_ON)
                {
                    if (g_touch_state == 0)
                    {
                        hod_touch_on_cb();
                    }
                    g_touch_state = 1;
                }
                else if (ButtonDrv_GetButtonEvent(NULL, 0) == BUTTON_STATE_OFF)
                {
                    if (g_touch_state == 1)
                    {
                        hod_touch_off_cb();
                    }
                    g_touch_state = 0;
                }

                raw[0]  = ButtonDrv_GetButtonElemRawData(NULL, 0, 0);
                base[0] = ButtonDrv_GetButtonElemBaseData(NULL, 0, 0);
                diff[0] = ButtonDrv_GetButtonElemDiffData(NULL, 0, 0);

                hod_upload_info_cb(raw[0], base[0], diff[0]);
                break;
            default:
                break;
            }
            if (hod_task_heating_idx >= 10 && hod_task_sub_idx == 2)//hod speed	20ms,50hz;10ms==100hz(>=10)
            {
                hod_task_heating_idx = 0;
                hod_task_sub_idx = 0;
                hod_task_main_idx = heating > 0 ? 1 : 0;
            }
        }
        else
        {
            switch (hod_task_sub_idx)
            {
            case 3:
                HEAT_SHD_OFF();
                break;
            case 6:
                HEAT_LOW_SIDE_ON();
                break;
            case 9:
                if (heating > 0)
                {
                    HEAT_HIGH_SIDE2_ON();
                }
                break;
            case 12:
                if (heating > 0)
                {
                    HEAT_HIGH_SIDE_ON();
                }
                break;
            case 100:
                HEAT_HIGH_SIDE_OFF();
                break;
            case 103:
                HEAT_HIGH_SIDE2_OFF();
                break;
            case 106:
                HEAT_LOW_SIDE_OFF();
                break;
            case 109:
                HEAT_SHD_ON();
                break;
            case 112:
                hod_task_sub_idx = 0;
                hod_task_main_idx = 0;
                hod_task_heating_idx = 0;
                break;
            default:
                if (hod_task_sub_idx > 15
                &&  hod_task_sub_idx > hod_heating_duty
                &&  hod_task_sub_idx < 100)
                {
                    hod_task_heating_idx++;
                    if (hod_task_heating_idx == 3)
                    {
                        HEAT_HIGH_SIDE_OFF();
                    }
                    else if (hod_task_heating_idx == 6)
                    {
                        HEAT_HIGH_SIDE2_OFF();
                    }
                }
                break;
            }

            if (hod_task_main_idx == 1) hod_task_sub_idx++;
        }
    }
}