#include "includes.h"

// DAC7311输出范围：0~4095对应0~2.5v，转成成0~25mA

// 延迟大约10us
void DAC7311_delay()
{
	uint32_t loop = 250;
	
	while(loop--) 
		__NOP();
}

// 通讯定义
#define   DAC7311_CHANNEL_1_LATCH_LOW() \
	{ \
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_8); \
		DAC7311_delay(); \
	}
	
#define   DAC7311_CHANNEL_1_LATCH_HIGH() \
	{ \
		LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_8); \
		DAC7311_delay(); \
	}

#define   DAC7311_CHANNEL_2_LATCH_LOW() \
	{ \
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_7); \
		DAC7311_delay(); \
	}
	
#define   DAC7311_CHANNEL_2_LATCH_HIGH() \
	{ \
		LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7); \
		DAC7311_delay(); \
	}
    
#define   DAC7311_CHANNEL_3_LATCH_LOW() \
	{ \
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_9); \
		DAC7311_delay(); \
	}
	
#define   DAC7311_CHANNEL_3_LATCH_HIGH() \
	{ \
		LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_9); \
		DAC7311_delay(); \
	}
    
#define   DAC7311_CLK_LOW() \
	{ \
		LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6); \
		DAC7311_delay(); \
	}	

#define   DAC7311_CLK_HIGH() \
	{ \
		LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6); \
		DAC7311_delay(); \
	}	
	
#define   DAC7311_DATA_1() \
	{ \
		LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_15); \
		DAC7311_delay(); \
	}	
	
#define   DAC7311_DATA_0() \
	{ \
		LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_15); \
		DAC7311_delay(); \
	}	

// 写 1 bit
void DAC7311_Bit(uint32_t b1)
{
	DAC7311_CLK_HIGH();
	if(b1)
	{
		DAC7311_DATA_1();
	}
	else
	{
		DAC7311_DATA_0();
	}
	DAC7311_CLK_LOW();
}

// 写多个bits
void DAC7311_Bits(uint32_t bytes, uint8_t num)
{
	uint32_t mask = (1ul << (num - 1));
	while(num--)
	{
		DAC7311_Bit(bytes & mask);
		bytes <<= 1;
	}		
}

void DAC7311_Write(uint8_t channel, uint32_t data)
{
	if(channel == 0)
	{
		DAC7311_CHANNEL_1_LATCH_LOW();
	}
	else if(channel == 1)
	{
		DAC7311_CHANNEL_2_LATCH_LOW();
	}
	else
	{
		DAC7311_CHANNEL_3_LATCH_LOW();
	}

	DAC7311_Bits(data, 16);
	if(channel == 0)
	{
		DAC7311_CHANNEL_1_LATCH_HIGH();
	}
	else if(channel == 1)
	{
		DAC7311_CHANNEL_2_LATCH_HIGH();
	}
	else
	{
		DAC7311_CHANNEL_3_LATCH_HIGH();
	}
	DAC7311_CLK_HIGH();
}

// 初始化
void DAC7311_Init()
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	/* GPIO Ports Clock Enable */
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD);

	/**/
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7|LL_GPIO_PIN_8|LL_GPIO_PIN_9);

	/**/
	LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_15);

	/**/
	LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6);

	/**/
	GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	LL_GPIO_Init(GPIOD, &GPIO_InitStruct);

	/**/
	GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7|LL_GPIO_PIN_8|LL_GPIO_PIN_9;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void DAC7311_Open()
{
	// 刷新电流输出
	DAC7311_Refresh();
}

// 输出正常电流, 将液位百分比转换为4~20mA电流
void DAC7311_Out(uint8_t channel, float	percent)
{
	uint32_t dac = (percent * 0.16 + 4) / 25 * 4095 + 0.5;
	DAC7311_Write(channel, dac << 2);
}

// 输出报警电流：3.5mA
void DAC7311_OutAlarm(uint8_t channel)
{
	uint32_t dac = 3.5 / 25 * 4095 + 0.5;
	DAC7311_Write(channel, dac << 2);
}

// 输出零电流：0mA
void DAC7311_OutZero(uint8_t channel)
{
	uint32_t dac = 0;
	DAC7311_Write(channel, dac << 2);
}

// 刷新电流输出
void DAC7311_Refresh()
{
	uint8_t on = IS_VCC_MA_ON();
	
	VCC_MA_ON();
	
#if 0
	DAC7311_OutAlarm(0); // 3.5mA
	DAC7311_Out(1, 0);	 // 4mA
	DAC7311_Out(2, 100); // 20mA
#else	
	if(dcBuff.sampleData.staDPress.notConnect)
		DAC7311_OutZero(0);
	else if(dcBuff.sampleData.staDPress.underFlow || dcBuff.sampleData.staDPress.overFlow)
		DAC7311_OutAlarm(0);
	else if(dcBuff.configDisplay.op_HARDWARE_VER_MAJOR == 229 // 巴西罐箱
		|| dcBuff.configDisplay.op_USE_CAPACITY_SENSOR		  // 电容测量
		|| dcBuff.configSensor.levelOutMMWC > 0)			  // 按最高液位的mmWC输出液位百分比
	{
		DAC7311_Out(0, dcBuff.sampleData.volumePct * 0.01); // volumePct放大了100倍的
	}
	else	// 其它差压客户
	{
		// 差压传感器的量程
		DAC7311_Out(0, (dcBuff.sampleData.diff - dcBuff.configSensor.sensorDPress.lowRange) * 100.0 
				/ (dcBuff.configSensor.sensorDPress.highRange - dcBuff.configSensor.sensorDPress.lowRange));
	}
	
	if(!dcBuff.configDisplay.op_2ND_420MA_OUT_LEVEL)
	{
		if(dcBuff.sampleData.staPress.notConnect)
			DAC7311_OutZero(1);
		else if(dcBuff.sampleData.staPress.underFlow || dcBuff.sampleData.staPress.overFlow)
			DAC7311_OutAlarm(1);
		else if(dcBuff.sampleData.staPress.full)
			DAC7311_Out(1, 100);
		else
		{
			// 压力传感器的量程
			DAC7311_Out(1, (dcBuff.sampleData.pressure - dcBuff.configSensor.sensorPress.lowRange) * 100.0 
					/ (dcBuff.configSensor.sensorPress.highRange - dcBuff.configSensor.sensorPress.lowRange));
		}
	}
	else
	{
		if(dcBuff.sampleData.staDPress.notConnect)
			DAC7311_OutZero(1);
		else if(dcBuff.sampleData.staDPress.underFlow || dcBuff.sampleData.staDPress.overFlow)
			DAC7311_OutAlarm(1);
		else if(dcBuff.configDisplay.op_HARDWARE_VER_MAJOR == 229 // 巴西罐箱
			|| dcBuff.configDisplay.op_USE_CAPACITY_SENSOR		  // 电容测量
			|| dcBuff.configSensor.levelOutMMWC > 0)			  // 按最高液位的mmWC输出液位百分比
		{
			DAC7311_Out(1, dcBuff.sampleData.volumePct * 0.01); // volumePct放大了100倍的
		}
		else	// 其它差压客户
		{
			// 差压传感器的量程
			DAC7311_Out(1, (dcBuff.sampleData.diff - dcBuff.configSensor.sensorDPress.lowRange) * 100.0 
					/ (dcBuff.configSensor.sensorDPress.highRange - dcBuff.configSensor.sensorDPress.lowRange));
		}
	}

	if(dcBuff.sampleData.staExtTempr[0].notConnect)
		DAC7311_OutZero(2);
	else if(dcBuff.sampleData.staExtTempr[0].underFlow || dcBuff.sampleData.staExtTempr[0].overFlow)
		DAC7311_OutAlarm(2);
	else if(dcBuff.sampleData.staExtTempr[0].full)
		DAC7311_Out(2, 100);
	else if(dcBuff.configDisplay.op_USE_PT100_SENSOR)
	{
		// PT100温度传感器的量程: -200~80
		DAC7311_Out(2, (dcBuff.sampleData.extTempr[0] - (-200)) * 100.0 
				/ (80 - (-200)));
	}
	else
	{
		// 4~20mA温度传感器的量程
		DAC7311_Out(2, (dcBuff.sampleData.extTempr[0] - dcBuff.configSensor.sensorMTempr[0].lowRange) * 100.0 
				/ (dcBuff.configSensor.sensorMTempr[0].highRange - dcBuff.configSensor.sensorMTempr[0].lowRange));
	}
#endif
	
	if(!on)
		VCC_MA_OFF();
}

