#include "driver_qdec.h"
#include "driver_clk.h"

volatile unsigned int pending_count = 0;
volatile unsigned char symbol_state = 0;
volatile int step_count = 0;
volatile unsigned char state = 0;

bool qdec_isr_flag_x = false;
bool qdec_isr_flag_y = false;
bool qdec_isr_flag_z = false;

static void qdecx_init(void)
{
    QDECXCON |= BIT(2) | BIT(1);          //qdecx reserve and forward enable
    QDECX_FILTER(40);                     //qdecx filter
    QDECX_WKUP_ENABLE();                  //qdecx wakeup sleep enable
    QDECX_ENABLB();                       //qdecx enable
}

static void qdecy_init(void)
{
    QDECYCON |= BIT(2) | BIT(1);        //qdecy reserve and forward enable
    QDECY_FILTER(6);                    //qdecy filter
    QDECY_WKUP_ENABLE();                //qdecy wakeup sleep enable
    QDECY_ENABLB();                     //qdecy enable
}

static void qdecz_init(void)
{
    QDECZCON |= BIT(2) | BIT(1);       //qdecz reserve and forward enable
    QDECZ_FILTER(54);                  //qdecz filter
    QDECZ_WKUP_ENABLE();               //qdecz wakeup sleep enable
    QDECZ_ENABLB();                    //qdecz enable
}

AT(.com_periph.qdec.isr)
void qdec_isr(void)
{
if(qdec_isr_flag_x == true)
{
    if(QDECX_FORWARD_PENDING_GET)
    {
        QDECX_FORWARD_PENDING_CLEAR();
        QDECXDATA_VALUE_GET(step_count);
        QDECXDATA_SYMBOL_GET(symbol_state);
        step_count <<= 20;
        step_count >>= 20;
        pending_count++;
    }
    else if(QDECX_REVERSE_PENDING_GET)
    {
        QDECX_REVERSE_PENDING_CLEAR();
        QDECXDATA_VALUE_GET(step_count);
        QDECXDATA_SYMBOL_GET(symbol_state);
        step_count <<= 20;
        step_count >>= 20;
        pending_count++;
    }
    else if(QDECX_ERROR_PENDING_GET)
    {
        QDECX_ERROR_PENDING_CLEAR();
        QDECXDATA_VALUE_GET(step_count);
    }
    else if(QDECX_OV_PNDING_GET)
    {
        QDECX_OV_PNDING_CLEAR();
    }
}

if(qdec_isr_flag_y == true)
{
    if(QDECY_FORWARD_PENDING_GET)
    {
        QDECY_FORWARD_PENDING_CLEAR();
        QDECYDATA_VALUE_GET(step_count);
        QDECYDATA_SYMBOL_GET(symbol_state);
        step_count <<= 20;
        step_count >>= 20;
        pending_count++;
    }
    else if(QDECY_REVERSE_PENDING_GET)
    {
        QDECY_REVERSE_PENDING_CLEAR();
        QDECYDATA_VALUE_GET(step_count);
        QDECYDATA_SYMBOL_GET(symbol_state);
        step_count <<= 20;
        step_count >>= 20;
        pending_count++;
    }
    else if(QDECY_ERROR_PENDING_GET)
    {
        QDECY_ERROR_PENDING_CLEAR();
        QDECYDATA_VALUE_GET(step_count);

    }
    else if(QDECY_OV_PNDING_GET)
    {
        QDECY_OV_PNDING_CLEAR();
    }
}

if(qdec_isr_flag_z == true)
{
    if(QDECZ_FORWARD_PENDING_GET)
    {
        QDECZ_FORWARD_PENDING_CLEAR();
        QDECZDATA_VALUE_GET(step_count);
        QDECZDATA_SYMBOL_GET(symbol_state);
        step_count <<= 20;
        step_count >>= 20;
        pending_count++;
    }
    else if(QDECZ_REVERSE_PENDING_GET)
    {
        QDECZ_REVERSE_PENDING_CLEAR();
        QDECZDATA_VALUE_GET(step_count);
        QDECZDATA_SYMBOL_GET(symbol_state);
        step_count <<= 20;
        step_count >>= 20;
        pending_count++;
    }
    else if(QDECZ_ERROR_PENDING_GET)
    {
        QDECZ_ERROR_PENDING_CLEAR();
        QDECZDATA_VALUE_GET(step_count);

    }
    else if(QDECZ_OV_PNDING_GET)
    {
        QDECZ_OV_PNDING_CLEAR();
    }
}

}

void qdec_init(qdec_init_typedef *qdec_cfg)
{
    printf("enter to test_qdec\n");

    qdec_init_typedef *config = qdec_cfg;

    if(config){

        CLKCON1 |= BIT(8);    //xosc or rtc

        if(qdec_cfg->qdec_asis_sel == QDEC_X_AXIS)                                 // sel qdec_x_axis
        {
            clk_gate1_cmd(CLK_GATE1_QDECX, CLK_EN);                                //qdecx_clken
            QDECXCON |= ((qdec_cfg->qdec_cm_sel) << 12);
            QDECXCON |= ((qdec_cfg->number_samples_sel) << 16);
            qdec_isr_flag_x = true;

            qdecx_init();
        }
        else if(qdec_cfg->qdec_asis_sel == QDEC_Y_AXIS)                            //sel qdec_y_axis
        {
            clk_gate1_cmd(CLK_GATE1_QDECY, CLK_EN);                                //qdecy_clken
            QDECYCON |= ((qdec_cfg->qdec_cm_sel) << 12);
            QDECYCON |= ((qdec_cfg->number_samples_sel) << 16);
            qdec_isr_flag_y = true;

            qdecy_init();
        }
        else if(qdec_cfg->qdec_asis_sel == QDEC_Z_AXIS)                            ////sel qdec_z_axis
        {
            clk_gate1_cmd(CLK_GATE1_QDEC, CLK_EN);                                 //qdecz_clken
            QDECZCON |= ((qdec_cfg->qdec_cm_sel) << 12);
            QDECZCON |= ((qdec_cfg->number_samples_sel) << 16);
            qdec_isr_flag_z = true;

            qdecz_init();
        }
        sys_irq_init(IRQn_IR_QDEC_LEDC, 0, qdec_isr);
    }
}
