#include "hdl_cs5552.h"

static stc_cs5552_t cs5552;

//uint32_t hdl_cs5552_reg_read(uint8_t cmd)
//{
//	uint32_t data = 0;
//	uint8_t buf[4] = {0};
//	
//	CLR_CS5552_CS();
//	
//	hdl_cs5552_write_read_byte(cmd);
//	
//	for(int i=0;i<4;i++)
//	{
//		buf[i] = hdl_cs5552_write_read_byte(0x00);
//	}
//	
//	SET_CS5552_CS();
//	
//	data = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
//	
//	return data;
//}

void hdl_cs5552_soft_spi_init(void)
{
	stc_gpio_init_t stcGpioInit;
	
	LL_PERIPH_WE(LL_PERIPH_GPIO);
	
	(void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinDir = PIN_DIR_OUT;
	stcGpioInit.u16PinDrv = PIN_HIGH_DRV;
	(void)GPIO_Init(CS5552_MOSI_PORT, CS5552_MOSI_PIN, &stcGpioInit);
	(void)GPIO_Init(CS5552_SCLK_PORT, CS5552_SCLK_PIN, &stcGpioInit);
	(void)GPIO_Init(CS5552_CS_PORT, CS5552_CS_PIN, &stcGpioInit);
	
	(void)GPIO_StructInit(&stcGpioInit);
	stcGpioInit.u16PinDir = PIN_DIR_IN;
	stcGpioInit.u16PullUp = PIN_PU_ON;
	(void)GPIO_Init(CS5552_MISO_PORT, CS5552_MISO_PIN, &stcGpioInit);
	
	LL_PERIPH_WP(LL_PERIPH_GPIO);
	
	CLR_CS5552_SCLK();
}

uint8_t hdl_cs5552_write_read_byte(uint8_t w_data)
{
	uint8_t r_data = 0;
	uint16_t retry = 0;
	
	for(int i=0;i<8;i++)
	{
		if((w_data&0x80) == 0)
		{
			CLR_CS5552_DIN();
		}else{
			SET_CS5552_DIN();
		}
		
		hdl_delay_us(1);
		
		SET_CS5552_SCLK();
		
		r_data<<=1;
		if(SET == GET_CS5552_DOUT())
		{
			r_data++;
		}
		
		CLR_CS5552_SCLK();
		
		w_data<<=1;
		
		hdl_delay_us(1);
	}
		
    return r_data;
}

void hdl_cs5552_reg_write(uint8_t cmd, uint8_t dat_h, uint8_t dat_m, uint8_t dat_l, uint8_t dat_s)
{
	CLR_CS5552_CS();
	
	hdl_cs5552_write_read_byte(cmd);
	hdl_cs5552_write_read_byte(dat_h);
	hdl_cs5552_write_read_byte(dat_m);
	hdl_cs5552_write_read_byte(dat_l);
	hdl_cs5552_write_read_byte(dat_s);
	
	SET_CS5552_CS();
}

uint32_t hdl_cs5552_reg_read(uint8_t cmd)
{
	uint32_t data = 0;
	uint8_t buf[4] = {0};
	
	CLR_CS5552_CS();
	
	hdl_cs5552_write_read_byte(cmd);
	
	for(int i=0;i<4;i++)
	{
		buf[i] = hdl_cs5552_write_read_byte(0x00);
	}
	
	SET_CS5552_CS();
	
	data = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
	
	return data;
}

void hdl_cs5552_value_get(int32_t *buf)
{
	memcpy(buf, cs5552.buf, sizeof(cs5552.buf));
}

void hdl_cs5552_init(void)
{
	uint32_t data = 0;
	
	hdl_cs5552_soft_spi_init();
	
	SET_CS5552_CS();
	
	/* 配置CS5552 */
	CLR_CS5552_CS();
	hdl_cs5552_write_read_byte(0x00);
	hdl_cs5552_write_read_byte(0xA5);
	hdl_cs5552_write_read_byte(0xFF);
	hdl_cs5552_write_read_byte(0x5A);
	SET_CS5552_CS();
	hdl_delay_us(100);
	
	hdl_cs5552_reg_write(SYS_CONF0_W, 0x80, 0x00, 0x00, 0x00);	//RESET
	hdl_delay_us(100);
	
	hdl_cs5552_reg_write(OS_CH0_W, 0x00, 0x00, 0x00, 0x00);	//OS_CH0
	hdl_cs5552_reg_write(GAIN_CH0_W, 0x02, 0x00, 0x00, 0x00);	//GAIN_CH0
	hdl_cs5552_reg_write(OS_CH1_W, 0x00, 0x00, 0x00, 0x00);	//OS_CH1
	hdl_cs5552_reg_write(GAIN_CH1_W, 0x02, 0x00, 0x00, 0x00);	//GAIN_CH1
	hdl_cs5552_reg_write(CONV_CONF0_W, 0x30, 0x80, 0x00, 0x80);	//CONV_CONF0 滤波-256CLK	速率-200Hz PGA-128
	hdl_cs5552_reg_write(CONV_CONF1_W, 0x00, 0x00, 0x00, 0x00);	//CONV_CONF1
	hdl_cs5552_reg_write(SYS_CONF0_W, 0x02, 0x01, 0x00, 0x00);	//SYS_CONF0
	hdl_cs5552_reg_write(SYS_CONF1_W, 0x08, 0x11, 0x02, 0x10);	//SYS_CONF1	内部时钟 内部基准源 
	hdl_cs5552_reg_write(SYS_CONF2_W, 0x00, 0x52, 0x10, 0x00);	//SYS_CONF2

#ifdef	HC32_DEBUG
	/* 读取通道0设置 */
	data = hdl_cs5552_reg_read(OS_CH0_R);
	printf("OS_CH0 = %d\r\n", data);
	data = hdl_cs5552_reg_read(GAIN_CH0_R);
	printf("GAIN_CH0 = %d\r\n", data);
	
	/* 读取通道1设置 */
	data = hdl_cs5552_reg_read(OS_CH1_R);
	printf("OS_CH1 = %d\r\n", data);
	data = hdl_cs5552_reg_read(GAIN_CH1_R);
	printf("GAIN_CH1 = %d\r\n", data);
	
	/* 配置CONV */
	data = hdl_cs5552_reg_read(CONV_CONF0_R);
	printf("CONV_CONF0 = %d\r\n", data);
	data = hdl_cs5552_reg_read(CONV_CONF1_R);
	printf("CONV_CONF1 = %d\r\n", data);
	
	/* 配置SYS */
	data = hdl_cs5552_reg_read(SYS_CONF0_R);
	printf("SYS_CONF0 = %d\r\n", data);
	data = hdl_cs5552_reg_read(SYS_CONF1_R);
	printf("SYS_CONF1 = %d\r\n", data);
	data = hdl_cs5552_reg_read(SYS_CONF2_R);
	printf("SYS_CONF2 = %d\r\n", data);
#endif
}

void hdl_cs5552_conv_start(void)
{
	cs5552.step = CS5552_OFFSET;
}

void hdl_cs5552_proc(void)
{
	static uint16_t offset_cnt = 0;
	uint32_t ad_value = 0;
	switch(cs5552.step)
	{
		case CS5552_IDLE:
			break;
		case CS5552_OFFSET:
			CLR_CS5552_CS();
		
			if(cs5552.channel_sta == CS5552_CH0)
				hdl_cs5552_write_read_byte(SYS_OFFSET_CH0);
			if(cs5552.channel_sta == CS5552_CH1)
				hdl_cs5552_write_read_byte(SYS_OFFSET_CH1);
			cs5552.step = CS5552_OFFSET_READ;
			if(offset_cnt > OFFSET_CNT)
			{
				offset_cnt = 0;
				cs5552.step = CS5552_START;
			}
			break;
		case CS5552_OFFSET_READ:
			if(RESET == GET_CS5552_DOUT())
			{
				ad_value = hdl_cs5552_reg_read(0xFF);	//获取数据
				
				if((ad_value & 0x1) == 0)
				{
					cs5552.offset_ch0[offset_cnt] = (ad_value & 0xFFFFFFFE) | 0x0;
				}
					
				if((ad_value & 0x1) == 1)
				{
					cs5552.offset_ch1[offset_cnt] = (ad_value & 0xFFFFFFFE) | 0x0;
				}
				offset_cnt++;
				cs5552.channel_sta = 1-cs5552.channel_sta;		//切换通道

				cs5552.step = CS5552_OFFSET;
			}
			break;
		case CS5552_START:
			CLR_CS5552_CS();
			
			if(cs5552.channel_sta == CS5552_CH0)
				hdl_cs5552_write_read_byte(CONV_CH0);
			if(cs5552.channel_sta == CS5552_CH1)
				hdl_cs5552_write_read_byte(0x90);
			cs5552.step = CS5552_READ;
			break;
		case CS5552_READ:

			if(RESET == GET_CS5552_DOUT())
			{
				ad_value = hdl_cs5552_reg_read(0xFF);	//获取数据
				
				if((ad_value & 0x1) == 0)
				{
					if((ad_value>>22) < 0x3F)	//+
						cs5552.buf[0] = (ad_value & 0x3FFFFFFE) >> 13;
					if((ad_value>>22) > 0xC0)	//-
						cs5552.buf[0] = ~(0x7FFFF - ((ad_value & 0xFFFFFFFE) >> 13));
				}
					
				if((ad_value & 0x1) == 1)
				{
					if((ad_value>>22) < 0x3F)	//+
						cs5552.buf[1] = (ad_value & 0x3FFFFFFE) >> 13;
					if((ad_value>>22) > 0xC0)	//-
						cs5552.buf[1] = ~(0x7FFFF - ((ad_value & 0xFFFFFFFE) >> 13));
				}
				
				cs5552.channel_sta = 1-cs5552.channel_sta;		//切换通道

				cs5552.step = CS5552_START;
			}
			break;
	}
}


