/******************************************************************************
 * @file      drv_adbms1818.c
 * @brief     ads8688 drivers
 * @version   V1.0
 * @author    Gary
 * @copyright
 ******************************************************************************/
#include "drv_ads8688.h"
#include "drv_spi.h"
#include "kit_time.h"

void drv_set_ads8688_cs(GpioStatus state)
{
    drv_gpio_set_pin_status(kGpioType_ADC_Cs, state);
}

void drv_set_ads8688_rst(GpioStatus state)
{
    drv_gpio_set_pin_status(kGpioType_ADC_Reset, state);
}

uint8_t drv_ads8688_spi_send_rev(uint8_t data)
{
    return drv_spi_sync_send_rev(kSpiDev_2, data);
}

// 初始化ADS8688，并且检验读入寄存器数据和写入的是否一样
// 返回TURE则说明初始化正常，否则错误
bool drv_ads8688_Init(void)
{
    uint8_t i = 0;
    drv_spi_init(kSpiDev_2, kSpiFreq_Div256, kSpiMode_C0E1, SpiFrame_MSBFirst, kGpioType_ADC_Clk, kGpioType_ADC_Miso, kGpioType_ADC_Mosi);
	//drv_ads8688_Reset();// hardware reset
	
	drv_enter_pwrdn_mode();
	OSTimeDly(20);	
	drv_enter_standby_mode();
	OSTimeDly(20);	
    drv_reset_ads8688();
	OSTimeDly(20);
	drv_set_ch_range(Channel_0_Input_Range,VREF_25_25);
	drv_set_ch_range(Channel_1_Input_Range,VREF_25_25);
	drv_set_ch_range(Channel_2_Input_Range,VREF_25_25);
	drv_set_ch_range(Channel_3_Input_Range,VREF_25_25);
	drv_set_ch_range(Channel_4_Input_Range,VREF_25_25);
	drv_set_ch_range(Channel_5_Input_Range,VREF_25_25);
	
	drv_set_ch_pwrdn(Channel_6_Input_Range);
	drv_set_ch_pwrdn(Channel_7_Input_Range);
	
    drv_ads8688_write_reg(AUTO_SEQ_EN, 0x3F);
	
    i = drv_ads8688_read_reg(AUTO_SEQ_EN);
	
    if (i != 0x3F)
    {
        return true;
    }
    else
    {
		drv_enter_auto_rst_mode(); // 进入自动扫描模式
		OSTimeDly(20);
        return false;
    }
}

void drv_ads8688_Reset(void) // hardware reset
{
    uint8_t i = 5;
    drv_set_ads8688_rst(kGpioStatus_Low);
	OSTimeDly(10);
    while (i--)
        ;
    drv_set_ads8688_rst(kGpioStatus_High);
}

void drv_ads8688_pwrdn(void) // hardware power-down
{
    uint8_t i = 50;
    drv_set_ads8688_rst(kGpioStatus_Low);
    while (i--)
        ;
}

void drv_ads8688_pwrup(void) // power-down
{
    drv_set_ads8688_rst(kGpioStatus_High);
}


void drv_ads8688_write_cmd_reg(uint16_t command) // 写ADS8688命令寄存器
{
    drv_set_ads8688_cs(kGpioStatus_Low);
    drv_ads8688_spi_send_rev(command >> 8 & 0xFF);
    drv_ads8688_spi_send_rev(command & 0xFF);
    drv_set_ads8688_cs(kGpioStatus_High);
}



void drv_reset_ads8688(void) // 软件复位模式，复位 program registers
{
    drv_ads8688_write_cmd_reg(RST);
}

// 进入STDBY模式，且命令发送后CS立刻置高，不读数据帧；
// 退出此模式需执行AUTO_RST或者MAN_CH_n命令，且需要等待至少20us以保证正常数据的AD转换
void drv_enter_standby_mode(void)
{
    drv_ads8688_write_cmd_reg(STDBY);
}

// 进入PWR_DN模式，且命令发送后CS立刻置高，不读数据帧；
// 退出此模式需执行AUTO_RST或者MAN_CH_n命令，且需要等待至少15ms以保证正常数据的AD转换
void drv_enter_pwrdn_mode(void) // 此为软件方式进入PWR_DN模式，与硬件方式区别是不改变 program registers
{
    drv_ads8688_write_cmd_reg(PWR_DN);
}

void drv_enter_auto_rst_mode(void) // 进入自动扫描模式
{
    drv_ads8688_write_cmd_reg(AUTO_RST);
}

// 读取扫描通道序列的AD转换数据code到变量数组中
void drv_enter_auto_rst_mode_Data(uint16_t *outputdata, uint8_t chnum)
{
    uint8_t i = 0, datal = 0, datah = 0;
    uint16_t data = 0;
    for (i = 0; i < chnum; i++)
    {
        drv_set_ads8688_cs(kGpioStatus_Low);
        drv_ads8688_spi_send_rev(0x00);
        drv_ads8688_spi_send_rev(0x00);
        datah = drv_ads8688_spi_send_rev(0xFF);
        datal = drv_ads8688_spi_send_rev(0xFF);
        drv_set_ads8688_cs(kGpioStatus_High);

        data = datah << 8 | datal; // 高位在前，低位在后
        *(outputdata + i) = data;
    }
}

void drv_manual_chn_mode(uint16_t ch) // 手动模式
{
    drv_ads8688_write_cmd_reg(ch);
}

// 读取手动通道的AD转换数据code
uint16_t drv_manual_chn_mode_Data(void)
{
    uint8_t datah = 0, datal = 0;
    drv_set_ads8688_cs(kGpioStatus_Low);
    drv_ads8688_spi_send_rev(0x00);
    drv_ads8688_spi_send_rev(0x00);
    datah = drv_ads8688_spi_send_rev(0xFF);
    datal = drv_ads8688_spi_send_rev(0xFF);
    drv_set_ads8688_cs(kGpioStatus_High);

    return (datah << 8 | datal);
}

//Gary add function
uint16_t drv_get_ads8688_ch_data(uint16_t ch)
{
	drv_manual_chn_mode(ch);
	return drv_manual_chn_mode_Data();
}

// Program Register写操作
void drv_ads8688_write_reg(uint8_t Addr, uint8_t data)
{
    drv_set_ads8688_cs(kGpioStatus_Low);
    drv_ads8688_spi_send_rev(Addr << 1 | WRITE);
    drv_ads8688_spi_send_rev(data);
    drv_set_ads8688_cs(kGpioStatus_High);
}

// Program Register读操作
uint8_t drv_ads8688_read_reg(uint8_t Addr)
{
    uint8_t data = 0;

    drv_set_ads8688_cs(kGpioStatus_Low);
    drv_ads8688_spi_send_rev(Addr << 1 | READ);
    data = drv_ads8688_spi_send_rev(0xFF);
    data = drv_ads8688_spi_send_rev(0xFF);
    drv_set_ads8688_cs(kGpioStatus_High);

    return data;
}

void drv_set_auto_scan_sequence(uint8_t seq) // 设置自动扫描序列通道
{
    drv_ads8688_write_reg(0x01, seq);
}

void drv_set_ch_pwrdn(uint8_t chn) // 设置通道n为Power Down
{
    drv_ads8688_write_reg(0X02, chn);
}

void drv_set_ch_range(uint8_t ch, uint8_t range) // 设置各个通道的范围
{
    drv_ads8688_write_reg(ch, range);
}

int16_t drv_ads8688_value(uint16_t value)
{
	int32_t ret = 0;
	uint16_t tmp = 0;
	tmp = value & 0x7FFF;
	if(KIT_GET_BIT_VAL(value, 15) == 1)
	{
		return tmp;
	}
	else
	{
		return -tmp;
	}
}


