#ifndef TARGET_IS_BLIZZARD_RA1
#define TARGET_IS_BLIZZARD_RA1
#endif

#ifndef PART_TM4C123GH6PM
#define PART_TM4C123GH6PM
#endif

/*
 * Resistor Measure Application
 * Copyright (c) 2013-2014 China JiLiang University
 * All Rights Reserved.
 */

/*!
 * @file        main.c
 * @version     1.0
 * @author      Kai Zhang
 * @date        2013-08-22
 * @brief       Դŵ·ԭֵģ
 *
 * 		________
 *				|
 *			 PA6|<--SCL		I2CЭʱź
 *		M4	 PA7|<--SDA		I2CЭź
 *			 PB4|<--ADC0	ģתźԴ
 *		________|
 */

#include "stdint.h"
#include "stdbool.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_i2c.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/i2c.h"
#include "driverlib/adc.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "LCDDriver.h"

/************************************************************************
 * 궨
 *************************************************************************/
#define MIN_BRIDGE_ADC_VALUE		1984		// ŲADCʾֵ
#define MAX_BRIDGE_ADC_VALUE		4095		// ŲADCʾֵ
#define MAX_RESISTOR_VALUE			203500		// ֵλ m
#define SLAVE_ADDRESS 				0x48 		// ADS1100ݼĴַ

#define SOURCE_OFFSET				32768

/************************************************************************
 * ʼADCȡֵѹֵ,ڵŵ·
 * 		|
//				|
//		M4	 PB4|<--ADC0		ģתźԴ
//		________|
 *
 ***********************************************************************/
#define ADC_BASE		ADC0_BASE			// ʹADC0
#define SequenceNum 	3					// ʹ3
void Init_ADC_Detect(){

	// ʹ ADC0
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

	// ʹPort B˿
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

	// ѡPB4ΪģװADCĹܽ
	ROM_GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);

	// òеĴԴȼ
	ROM_ADCSequenceConfigure(ADC_BASE, SequenceNum, ADC_TRIGGER_PROCESSOR, 0);

	// òзĲ
	ROM_ADCSequenceStepConfigure(ADC_BASE, SequenceNum, 0, ADC_CTL_CH10 | ADC_CTL_IE |
							 ADC_CTL_END);

	// ʹһ
	ROM_ADCSequenceEnable(ADC_BASE, SequenceNum);

	// жԴ
	ROM_ADCIntClear(ADC_BASE, SequenceNum);
}

/************************************************************************
 * ʼAI2CȡADS1100ϵADCѹ,ںԴ
 * 		|
//				|
//		M4	 PA6|<--SCL		I2CЭʱź
//			 PA7|<--SDA		I2CЭź
//		________|
 *
 ***********************************************************************/
void Init_I2C_Comm()
{
	// ʹI2C1
	SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

	// ʹPortA˿
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

	// PA6PA7Ϊ˿
	GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

	// PA6ΪI2CЭʱźš PA7ΪI2CЭź
	GPIOPinConfigure(GPIO_PA6_I2C1SCL);
	GPIOPinConfigure(GPIO_PA7_I2C1SDA);
	GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
	GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);

	// ʼI2Cģ顣ٶȺʹģ
	I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);

	// ʹI2Cģ
	I2CMasterEnable(I2C1_BASE);
}

/************************************************************************
 * ADS1100üĴ
 *	ST/BSY		0		0		SC		DR1		DR0		PGA1	PGA0
 *		1		0		0		1		1		1		0		0
 *
 *************************************************************************/
void Configure_I2C()
{
	I2CMasterSlaveAddrSet(I2C1_BASE, SLAVE_ADDRESS, false);

	I2CMasterDataPut(I2C1_BASE,0x8C);

	I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);

	while(I2CMasterBusBusy(I2C1_BASE));
}


/********************************************************************
 * ȡADS1100ϲɼADC
 * ͨЭ飺  1öȡI2CӻַADS1100
 * 		  2ȡ16Bit ADCѹеĸ8Bit
 * 		  3ȡ16Bit ADCѹеĵ8Bit
 * 		  4õADS1100Ϣ
 ********************************************************************/
uint32_t I2C_ADC_OpReg_MSB_i;			// ͨI2CȡADS110016λADĸֽ
uint32_t I2C_ADC_OpReg_LSB_i;			// ͨI2CȡADS110016λADĸֽ
uint32_t I2C_ADC_ConfigReg_i;
#define DELAY_6MS		(SysCtlClockGet() / 3) / 150000
void CatchI2C()
{
	// Դ
	I2CMasterSlaveAddrSet(I2C1_BASE, SLAVE_ADDRESS, true);

	//###############################################
	I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
	while(I2CMasterBusy(I2C1_BASE));
	I2C_ADC_OpReg_MSB_i = I2CMasterDataGet(I2C1_BASE);

	//###############################################
	I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
	while(I2CMasterBusy(I2C1_BASE));
	I2C_ADC_OpReg_LSB_i = I2CMasterDataGet(I2C1_BASE);


	//###############################################
	I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
	while(I2CMasterBusy(I2C1_BASE));
	I2C_ADC_ConfigReg_i = I2CMasterDataGet(I2C1_BASE);

	//###############################################
}

#define SAMPLE_NUM									8
int16_t sample_Source[SAMPLE_NUM];                     	// ԴADCֵ
unsigned int sample_Bridge[SAMPLE_NUM];                     	// ŲADCֵ
int16_t sample_Source_Average;
uint32_t sample_Bridge_Average;
int	sample_Index;
/************************************************************************
 *
 * 
 *
 *************************************************************************/

uint32_t temp1, temp2;
char bit;
uint16_t average;
int16_t temp3;
int main(void)
{
	bool bRefresh = false;
	uint32_t pui32ADC0Value[1];					// ADCֵ
	unsigned char number = '0';

	SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
									SYSCTL_XTAL_8MHZ);
	// ʹLCD
	LCD_Enable();

	// ʼLCD
	LCD_Init();

	// ʼLCD
	LCD_ScreenClr();

	// ʼ
	Init_ADC_Detect();

	//LCDĵһк͵зֱʾ裺    ڹ۲ֵ
	LCD_Draw_Char('I', LINE_ONE, 0 * 8);
	LCD_Draw_Char('N', LINE_ONE, 1 * 8);
	LCD_Draw_Char('A', LINE_ONE, 2 * 8);
	LCD_Draw_Char('3', LINE_ONE, 3 * 8);
	LCD_Draw_Char('3', LINE_ONE, 4 * 8);
	LCD_Draw_Char('3', LINE_ONE, 5 * 8);

	LCD_Draw_Char('M', LINE_ONE, 7 * 8);
	LCD_Draw_Char('e', LINE_ONE, 8 * 8);
	LCD_Draw_Char('a', LINE_ONE, 9 * 8);
	LCD_Draw_Char('s', LINE_ONE, 10 * 8);
	LCD_Draw_Char('u', LINE_ONE, 11 * 8);
	LCD_Draw_Char('r', LINE_ONE, 12 * 8);
	LCD_Draw_Char('e', LINE_ONE, 13 * 8);
	LCD_Draw_Char(':', LINE_ONE, 14 * 8);
	LCD_Draw_Char('V', LINE_TWO, 127-8);			// V

	LCD_Draw_Char('A', LINE_THREE, 0 * 8);
	LCD_Draw_Char('D', LINE_THREE, 1 * 8);
	LCD_Draw_Char('S', LINE_THREE, 2 * 8);
	LCD_Draw_Char('1', LINE_THREE, 3 * 8);
	LCD_Draw_Char('1', LINE_THREE, 4 * 8);
	LCD_Draw_Char('0', LINE_THREE, 5 * 8);
	LCD_Draw_Char('0', LINE_THREE, 6 * 8);

	LCD_Draw_Char('M', LINE_THREE, 8 * 8);
	LCD_Draw_Char('e', LINE_THREE, 9 * 8);
	LCD_Draw_Char('a', LINE_THREE, 10 * 8);
	LCD_Draw_Char('s', LINE_THREE, 11 * 8);
	LCD_Draw_Char('u', LINE_THREE, 12 * 8);
	LCD_Draw_Char('r', LINE_THREE, 13 * 8);
	LCD_Draw_Char('e', LINE_THREE, 14 * 8);
	LCD_Draw_Char(':', LINE_THREE, 15 * 8-1);
	LCD_Draw_Char('V', LINE_FOUR, 127-8);			// V

	// ڼIICĶȡ״
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
	GPIOPinWrite(GPIO_PORTF_BASE,  GPIO_PIN_1,  GPIO_PIN_1);

	//ʼI2CͨЭ飬ADS1100ȡADCֵ
	Init_I2C_Comm();//

	// ADS1100
	Configure_I2C();

	while(1)
	{

		// while125msʱÿˢƵΪ8Hz
		ROM_SysCtlDelay(SysCtlClockGet() / 3 / 30);

		//##################################################
		//Ų
		ADCProcessorTrigger(ADC_BASE, SequenceNum);

		// ȴADת
		while(!ADCIntStatus(ADC_BASE, SequenceNum, false))
		{
		}

		// ADCжϱ־λ
		ADCIntClear(ADC_BASE, SequenceNum);

		// ȡADCֵ
		ADCSequenceDataGet(ADC_BASE, SequenceNum, pui32ADC0Value);

		/////sample_Bridge_Average = pui32ADC0Value[0];

		sample_Bridge_Average = (pui32ADC0Value[0] * 3300) / 4096;

		//##############################################//
		// Դ
		CatchI2C();

		// 8λݷø8λ
		temp1 = (I2C_ADC_OpReg_MSB_i & 0x000000FF) << 8 ;
		// 8λݷõ8λ
		temp2 = (I2C_ADC_OpReg_LSB_i & 0x000000FF);
		// ϲߵλΪĲ
		temp3 = (int16_t)(temp1 + temp2);

		sample_Source[sample_Index] = temp3;

		if(sample_Index >= SAMPLE_NUM)
		{
			bRefresh = true;
			sample_Index = 0;

			uint32_t total_Bridge = 0;
			int32_t total_Source = 0;
			int i = 0;
			for(i = 0 ; i<SAMPLE_NUM; i++)
			{
				total_Bridge += sample_Bridge[i];
				total_Source += (int32_t)sample_Source[i];
			}
			//sample_Bridge_Average = total_Bridge >> 3;
			sample_Source_Average = total_Source >> 3;
			total_Bridge = 0;
			total_Source = 0;
		}else
		{
			sample_Index ++;
		}

		if(bRefresh)
		{
			//תʽ
		//	float ResValue = (sample_Bridge_Average - MIN_BRIDGE_ADC_VALUE) * (MAX_RESISTOR_VALUE / (MAX_BRIDGE_ADC_VALUE - MIN_BRIDGE_ADC_VALUE));
			//##################################
			uint32_t temp = (int) sample_Bridge_Average;
			int i = 0 ;
			unsigned char data[4] = {0};
			data[0] = (temp / 1000);
			data[1] = (temp / 100) % 10;
			data[2] = (temp / 10) % 10;
			data[3] = (temp / 1) % 10;

			// ADCֵ仯ʾ
			for(i = 0; i < 4; ++i)
			{
				LCD_Draw_Char('.', LINE_FOUR, 60 + 10 * 1);
				if(i < 1)
					LCD_Draw_Char(number + data[i], LINE_TWO, 60 + 10 * i);
				else
					LCD_Draw_Char(number + data[i], LINE_TWO, 60 + 10 * (i + 1));
			}

			//################################# ˢʾԴֵ
//			uint32_t temp1  = 0;

			uint32_t ADC_temp = 0;

//			uint32_t Risistor = 0;
//			if(sample_Source_Average & 0x8000 != 0x8000)
//			{
//				temp1 = (SOURCE_OFFSET + (uint16_t)sample_Source_Average);
////				Risistor = (temp1 * 3300) / 65536;
//			}else
//			{
//				temp1 = ((uint32_t)SOURCE_OFFSET + (uint32_t)sample_Source_Average);
//				//Risistor = ((SOURCE_OFFSET - temp1) * 3300) / 65536;
//			}

			bit = (sample_Source_Average & 0x8000) >> 15;

			average = ~sample_Source_Average + 1 ;

			// жǷǸ
//			if(bit)
//			{
//				ADC_temp = ~sample_Source_Average + 1;
//			}else{
				ADC_temp = (uint32_t)(sample_Source_Average);
//			}

				uint32_t Vol_ads = (ADC_temp * 3300) / (16384 * 2);

			data[0] = (Vol_ads / 1000);
			data[1] = (Vol_ads / 100) % 10;
			data[2] = (Vol_ads / 10) % 10;
			data[3] = (Vol_ads / 1) % 10;

			// ADCֵ仯ʾ
			for( i = 0; i < 4; ++i)
			{
				LCD_Draw_Char('.', LINE_TWO, 60 + 10 * 1);
				if(i < 1)
					LCD_Draw_Char(number + data[i], LINE_FOUR, 60 + 10 * i);
				else
					LCD_Draw_Char(number + data[i], LINE_FOUR, 60 + 10 * (i + 1));
			}
			//##################################
			bRefresh = false;
		}

		// ADCֵ仯ʾ
//		if(sample_Source_old != sample_Source)
//		{
//			uint32_t sample = sample_Source * 250;		// (v / i) =    1.044mA
//		}
	}

}

