/**
 * \file    drv_gpio_capture.c
 * \brief   DPM GPIO interface capture mode definition
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-04-05
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-04-05  Original Creation
 * 
 */

#include "libc.h"
#include "drv_gpio_capture.h"



#define GPIO_CAPTURE_CTRL_REG                               (0x40000014)

/**
IN_CAPTURE1_CHN_SEL, RW, reset value(0x0)
Input capture GPIO channel selection
*/
#ifndef IN_CAPTURE1_CHN_SEL
#define IN_CAPTURE1_CHN_SEL
#endif
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_CHN_SEL           (0x0B)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_CHN_SEL_WTH       (0x05)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_CHN_SEL_FLDSET    (0x0000F800)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_CHN_SEL_FLDMSK    (0xFFFF07FF)

/**
IN_CAPTURE1_EN, RW, reset value(0x0)
1: Input Capture enable 
*/
#ifndef IN_CAPTURE1_EN
#define IN_CAPTURE1_EN
#endif
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_EN                (0x0A)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_EN_WTH            (0x01)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_EN_FLDSET         (0x00000400)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_EN_FLDMSK         (0xFFFFFBFF)

/**
IN_CAPTURE1_MODE, RW, reset value(0x0)
2'b00:  Capture the width between rising edges of input signal, the capture result will be latched into CAPTURE1_CNT registers
2'b01:  Capture the width between falling edges of input signal 
2'b10:  Capture the width from rising edge to falling edge of input signal 
2'b11:  Capture the width from falling edge to rising edge of input signal 
*/
#ifndef IN_CAPTURE1_MODE
#define IN_CAPTURE1_MODE
#endif
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_MODE              (0x08)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_MODE_WTH          (0x02)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_MODE_FLDSET       (0x00000300)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE1_MODE_FLDMSK       (0xFFFFFCFF)

/**
IN_CAPTURE0_CHN_SEL, RW, reset value(0x0)
Input capture GPIO channel selection
*/
#ifndef IN_CAPTURE0_CHN_SEL
#define IN_CAPTURE0_CHN_SEL
#endif
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_CHN_SEL           (0x03)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_CHN_SEL_WTH       (0x05)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_CHN_SEL_FLDSET    (0x000000F8)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_CHN_SEL_FLDMSK    (0xFFFFFF07)

/**
IN_CAPTURE0_EN, RW, reset value(0x0)
1: Input Capture enable 
*/
#ifndef IN_CAPTURE0_EN
#define IN_CAPTURE0_EN
#endif
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_EN                (0x02)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_EN_WTH            (0x01)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_EN_FLDSET         (0x00000004)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_EN_FLDMSK         (0xFFFFFFFB)

/**
IN_CAPTURE0_MODE, RW, reset value(0x0)
2'b00:  Capture the width between rising edges of input signal, the capture result will be latched into CAPTURE0_CNT registers 
2'b01:  Capture the width between falling edges of input signal 
2'b10:  Capture the width from rising edge to falling edge of input signal 
2'b11:  Capture the width from falling edge to rising edge of input signal 
*/
#ifndef IN_CAPTURE0_MODE
#define IN_CAPTURE0_MODE
#endif
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_MODE              (0x00)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_MODE_WTH          (0x02)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_MODE_FLDSET       (0x00000003)
#define GPIO_CAPTURE_CTRL_REG_IN_CAPTURE0_MODE_FLDMSK       (0xFFFFFFFC)


#define GPIO_CAPTURE0_CNT_REG                               (0x40000018)

/**
CAPTURE0_CNT, RW, reset value(0x0)
Input capture0 result, this register is read only      
*/
#ifndef CAPTURE0_CNT
#define CAPTURE0_CNT
#endif
#define GPIO_CAPTURE0_CNT_REG_CAPTURE0_CNT                  (0x00)
#define GPIO_CAPTURE0_CNT_REG_CAPTURE0_CNT_WTH              (0x20)
#define GPIO_CAPTURE0_CNT_REG_CAPTURE0_CNT_FLDSET           (0xFFFFFFFF)
#define GPIO_CAPTURE0_CNT_REG_CAPTURE0_CNT_FLDMSK           (0x00000000)


#define GPIO_CAPTURE1_CNT_REG                               (0x4000001C)

/**
CAPTURE1_CNT, RW, reset value(0x0)
input capture1 result, this register is read only                
*/
#ifndef CAPTURE1_CNT
#define CAPTURE1_CNT
#endif
#define GPIO_CAPTURE1_CNT_REG_CAPTURE1_CNT                  (0x00)
#define GPIO_CAPTURE1_CNT_REG_CAPTURE1_CNT_WTH              (0x20)
#define GPIO_CAPTURE1_CNT_REG_CAPTURE1_CNT_FLDSET           (0xFFFFFFFF)
#define GPIO_CAPTURE1_CNT_REG_CAPTURE1_CNT_FLDMSK           (0x00000000)



u32_t drv_cap_en_gpio_get(DRV_CAPTURE_ID_t id)
{
    switch (id)
    {
        case DRV_CAPTURE_ID_1:
            if (DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_EN))
            {
                return DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_CHN_SEL);
            }
            break;
        case DRV_CAPTURE_ID_0:
            if (DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_EN))
            {
                return DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_CHN_SEL);
            }
            break;
        default:
            break;
    }
    return DRV_GPIO_MAX;
}


bool_t drv_gpio_cap_en_get(DRV_CAPTURE_ID_t id)
{
    switch (id)
    {
        case DRV_CAPTURE_ID_1:
            return DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_EN);

        case DRV_CAPTURE_ID_0:
            return DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_EN);

        default:
            break;
    }
    return FALSE;
}

void drv_gpio_cap_en_set(DRV_CAPTURE_ID_t id, u32_t gpio_id, bool_t flg)
{
    drv_gpio_en_set(gpio_id,TRUE);
    drv_gpio_oe_set(gpio_id,FALSE);
    switch (id)
    {
        case DRV_CAPTURE_ID_1:
            DRV_REG_FIELD_SET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_CHN_SEL,gpio_id);
            DRV_REG_FIELD_SET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_EN,flg);
            break;
        case DRV_CAPTURE_ID_0:
            DRV_REG_FIELD_SET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_CHN_SEL,gpio_id);
            DRV_REG_FIELD_SET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_EN,flg);
            break;
        default:
            break;
    }
}

void drv_gpio_cap_mode_set(DRV_CAPTURE_ID_t id, int mode)
{
    switch (id)
    {
        case DRV_CAPTURE_ID_1:
            DRV_REG_FIELD_SET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_MODE,mode);
            break;
        case DRV_CAPTURE_ID_0:
            DRV_REG_FIELD_SET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_MODE,mode);
            break;
        default:
            break;
    }
}

int drv_gpio_cap_mode_get(DRV_CAPTURE_ID_t id)
{
    switch (id)
    {
        case DRV_CAPTURE_ID_1:
            return DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE1_MODE);
        case DRV_CAPTURE_ID_0:
            return DRV_REG_FIELD_GET(GPIO_CAPTURE_CTRL_REG,IN_CAPTURE0_MODE);
        default:
            break;
    }
    return 0;
}

u32_t drv_gpio_cap_count_get(DRV_CAPTURE_ID_t id)
{
    switch (id)
    {
        case DRV_CAPTURE_ID_1:
            return DRV_REG_GET(GPIO_CAPTURE1_CNT_REG);
        case DRV_CAPTURE_ID_0:
            return DRV_REG_GET(GPIO_CAPTURE0_CNT_REG);
        default:
            break;
    }
    return 0;
}

