/*
*************************************************************
 *@Copyright (C), 2016-2020 smartlinkMicro. Co., Ltd.  All rights reserved.
 *@Filename:
 *@Complier:    IAR msp430 5.30
 *@Target OS:   NONE
 *@Target HW:   SL1523
 *@Author:      rpliu
 *@Version :    V1.0.0
 *@Date:        2018.12.25
 *@Description: LPCD api code header file
 *@History:
 *@    <author>     <time>     <version >   <desc>
 *@    rpliu        20181225   V1.0.0       Initial Version
 *@    rpliu        20190110   V1.0.1       add phase auto calibration
 *@    rpliu        20190115   V2.0.0       new lpcd adjust algorithm
 *@    rpliu        20190116   V3.0.0       rewrite lpcd adjust algorithm again
 *@    rpliu        20190117   V3.0.1       add define for SPI operation
 *@    rpliu        20190117   V3.0.2       replace set_bit_mask and clear_bit_mask
                                            with macro define
 *@    rpliu        20190117   V3.0.3       add timeout for sense adj loop
 *@    rpliu        20190117   V3.0.4       add debug info
 *@    rpliu        20190118   V3.0.5       add a threshold in threshold lut
 *@    rpliu        20190416   V3.0.7       add lpcd_dummy_tr to calib at lpcd_init
                                            remove phase_calib step in lpcd_init
 *@    rpliu        20190416   V3.0.8       add DELAY_1MS macro
 *@    rpliu        20190507   V3.1.0       add status definition

*************************************************************
*/

#ifndef LPCD_H
#define LPCD_H

#include "emv_if.h"

#define THD_ADJ_CNT 5
#define ADJ_TO_TIME 300       // amp_test runs every 16ms, 300 times means about 5 seconds

#define INDEX_NUM   46

#define LPCD_IDX_MAX  (INDEX_NUM-2)
#define LPCD_IDX_MIN  (0)

#define LPCD_CALIB_OK         (0)
#define LPCD_CALIB_TIMEOUT    (-1)
#define LPCD_CALIB_FS_LARGE   (-2)
#define LPCD_CALIB_FS_SMALL   (-3)
#define LPCD_CALIB_UNEXPECTED (-4)


#define AGC_CTRL   0x5f
#define ADC_CTRL   0x81
#define ADC_TIME0  0x82
#define ADC_TIME1  0x83
#define ADC_VALUE0 0x84
#define ADC_VALUE1 0x85

#define LPCD_CTRL0  0x86
#define LPCD_CTRL1  0x87
#define LPCD_CTRL2  0x88
#define LPCD_CTRL3  0x89
#define LPCD_TIME0  0x8a
#define LPCD_TIME1  0x8b
#define LPCD_TIME2  0x8d
#define LPCD_TIME3  0x9d
#define LPCD_PARAM0 0x8e
#define LPCD_PARAM1 0x8f
#define LPCD_PARAM2 0x90
#define LPCD_PARAM3 0x91
#define LPCD_PARAM4 0x92
#define LPCD_PARAM5 0x93
#define LPCD_PARAM6 0x94
#define LPCD_PARAM7 0x95
#define LPCD_STATE  0x96
#define LPCD_STATUS 0x97
#define LPCD_HYS    0x98
#define OSC_SETTLE  0x99

#define LPCD_DETECT_PERIOD (0x08) //0x5 320ms; //0x8 500ms ; //0x10 1s
#define LPCD_DETECT_SENS   (0x02) //0x2 17mv; //0x4 35mv
#define AGC_RX_MAX         (0x80) //-0x80~3.3V; //0x60~3.0V
#define AGC_RX_MIN         (0x20) //-0x80~3.3V; //0x60~3.0V
#define AGC_TARGET         (0x60) //-0x80~3.3V; //0x60~3.0V
#define ADC_TIME0_VAL      (0xff) //time for filed on

typedef struct
{
    unsigned char t1;
    unsigned char phase;
    char phase_offset;
    unsigned char default_amp;
    unsigned char amp;
    unsigned char max_amp;
    unsigned char min_amp;
    unsigned char sense;
    unsigned char idx[8];
} lpcd_cfg_t;

extern lpcd_cfg_t lpcd_cfg;

extern double voltage[];

extern unsigned char lut[];

unsigned char lpcd_amp_test(unsigned char amp);

unsigned char  osc_calib(void);
unsigned char  agc_calib(void);
void adc_init(void);
void test_agc(void);
unsigned char  get_adc_value(void);
unsigned char get_adc_value_mean(unsigned char n);
unsigned char phase_calib(void);

void lpcd_init(unsigned char fst_en,unsigned char adc_value);

void lpcd_entry(void);

uint8_t lpcd_exit(void);

int lpcd_sen_adj(void);

unsigned char lpcd_amp_search_floor(unsigned char lpcd_amp_target, unsigned char amp_low, unsigned char amp_high);
unsigned char lpcd_amp_search_ceil(unsigned char lpcd_amp_target, unsigned char amp_low, unsigned char amp_high);

void lpcd_print(void);

void lpcd_dummy_tr(void);

#define SL_SET_BIT_MASK(reg, mask)  \
    SL_WR_REG(reg, SL_RD_REG(reg) | mask)

#define SL_CLR_BIT_MASK(reg, mask)  \
    SL_WR_REG(reg, SL_RD_REG(reg) & ~mask)

#if 0
#define LPCD_AMP_TEST_INFO(str, amp_info, rlt_info)  \
    printf(str);                                                  \
    printf("\n");                                                 \
    for (i = 0; i < 8; i++)                                       \
    {                                                             \
        printf("idx[%d]: %0.2d\t", i, lpcd_cfg.idx[i]);           \
    }                                                             \
    printf("\namp: %0.2x, phase: %0.2x, lpcd_amp_rlt: %x\n", amp_info, lpcd_cfg.phase, rlt_info);

#define LPCD_ADJ_INFO                                             \
    printf("lpcd_info:\n");                                       \
    if (adj_fail == 1)                                            \
        printf("lpcd_sen_adj: fail\n");                           \
    else                                                          \
        printf("lpcd_sen_adj: succeed\n");                        \
    printf("lpcd_cfg.t1: %x\n", lpcd_cfg.t1);                     \
    printf("lpcd_cfg.phase: %x\n", lpcd_cfg.phase);               \
    printf("lpcd_cfg.amp: %x\n", lpcd_cfg.amp);                   \
    printf("lpcd_cfg.sense: %x\n", lpcd_cfg.sense);               \
    for (i = 0; i < 8; i++)                                       \
    {                                                             \
        printf("lpcd_cfg.idx[%d]: %0.2d\n", i, lpcd_cfg.idx[i]);  \
    }
#else
#define LPCD_AMP_TEST_INFO(str, amp_info, rlt_info)
#define LPCD_ADJ_INFO
#endif

#endif
// endfile
