/*
 * Copyright (c) 2010 仪星电子
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

/*
 * 著作权所有(C) 2010 仪星电子
 *
 * 本程序为自由软件；您可依据自由软件基金会所发表的GNU通用公共授权条款规定，
 * 就本程序再为发布与／或修改；无论您依据的是本授权的第二版或（您自行选择的）
 * 任一日后发行的版本。

 * 本程序是基于使用目的而加以发布，然而不负任何担保责任；亦无对适售性或特定
 * 目的适用性所为的默示性担保。详情请参照GNU通用公共授权。

 * 您应已收到附随于本程序的GNU通用公共授权的副本；如果没有，请写信至自由软件
 * 基金会：59 Temple Place - Suite 330, Boston, Ma 02111-1307, USA。

 * Email yixingdianzi@126.com
 * Email/MSN yixingdianzi@hotmail.com
 * QQ 648887464
 */

#include "qdmx_adc.h"

#define MAX(x,y)  (x)>(y)?(1):(0)

extern uint8_t Controla_a;
extern uint8_t Controla_b;


extern uint8_t ADCConvertedValue[16384];

void m_adc_clk_config(void)
{
    /* ADCCLK = PCLK2/6 */
  	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    
    /* Enable DMA1 clock */
  	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  	/* Enable ADC1 clock */
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	
}														   

void m_adc_gpio_config(void)
{
  	GPIO_InitTypeDef GPIO_InitStructure;

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);			// | RCC_APB2Periph_AFIO
 
  	/* Configure PA.00 (ADC Channel 0) as analog input -------------------------*/
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void m_adc_init(void)
{
  	ADC_InitTypeDef ADC_InitStructure;
  	DMA_InitTypeDef DMA_InitStructure;
  
  	/* DMA1 channel1 configuration ---------------------------------------------*/
  	DMA_DeInit(DMA1_Channel1);
  	DMA_InitStructure.DMA_PeripheralBaseAddr = (ADC1_DR_Address+1);
  	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
  	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  	DMA_InitStructure.DMA_BufferSize =16384;//1024;
  	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  	DMA_InitStructure.DMA_MemoryInc =DMA_MemoryInc_Enable;
  	DMA_InitStructure.DMA_PeripheralDataSize =  DMA_PeripheralDataSize_Byte;	  
  	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	  
  	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
  	/* Enable the DMA1 Channel1 Transfer complete interrupt */
  	DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);

  	/* Enable DMA1 channel1 */
  	DMA_Cmd(DMA1_Channel1, ENABLE);

   
  	/* ADC1 configuration ------------------------------------------------------*/
  	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;	  //ADC_DataAlign_Right; 
  	ADC_InitStructure.ADC_NbrOfChannel = 2;
  	ADC_Init(ADC1, &ADC_InitStructure);

  	/* ADC1 regular channel 0 configuration */ 
  	ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_1Cycles5);	  //ADC_SampleTime_239Cycles5
  	ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_1Cycles5);

  	/* Enable ADC1 DMA */
  	ADC_DMACmd(ADC1, ENABLE);
  
  	/* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);

  	/* Enable ADC1 reset calibaration register */   
  	ADC_ResetCalibration(ADC1);
  	/* Check the end of ADC1 reset calibration register */
  	while(ADC_GetResetCalibrationStatus(ADC1));

  	/* Start ADC1 calibaration */
  	ADC_StartCalibration(ADC1);
  	/* Check the end of ADC1 calibration */
  	while(ADC_GetCalibrationStatus(ADC1));

	ADC_Cmd(ADC1, DISABLE);
}

void m_adc_Interrupts_Config(void)
{
  	NVIC_InitTypeDef NVIC_InitStructure; 
    /* Enable the DMA1 Channel1 Interrupt */
  	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);
}

uint8_t Control_a(u8 Max,u8 Min)
{
	vu8 Max_B,Min_B;
	vu8 Max_All;

	uint8_t Vd;

	if((Max==0xe6)|(Min==0x00))
	{
		Controla_a=1;
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);GPIO_ResetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14);
	}
	else
	{
		if((Max==Min)&&(Max==0x73))	
			return 0;
		
		if(Min>=0x73)
			Max_All=Max-0x73;
		else 
		{
			if(Max<=0x73)
				Max_All=0x73-Min;
			else
			{
				Max_B=Max-0x73;
				Min_B=0x73-Min;						
				Max_All=Max_B>Min_B? Max_B:Min_B;
			}		
		}
		Vd=Max_All/Controla_a;

		if(Vd>=55)
			Controla_a=1;
		if((Vd>=22)&&(Vd<52))
			Controla_a=2;
		if((Vd>=11)&&(Vd<20))
			Controla_a=5;
		if((Vd>=5)&&(Vd<10))
			Controla_a=10;
		if(Vd<5)
			Controla_a=20;
		
		if((Vd>=52)&&(Vd<55))
		{
			if(Controla_a==1)	 Controla_a=1;
			else				 Controla_a=2;
		}
		if((Vd>=20)&&(Vd<22))
		{
			if(Controla_a==2)	 Controla_a=2;
			else				 Controla_a=5;
		}
		if((Vd>=10)&&(Vd<11))
		{
			if(Controla_a==5)	 Controla_a=5;
			else				 Controla_a=10;
		}
		switch(Controla_a)
		{
			case 1 :  
				GPIO_ResetBits(GPIOB,GPIO_Pin_12);GPIO_ResetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14);
				break;
			case 2 :  
				GPIO_SetBits(GPIOB,GPIO_Pin_12);GPIO_ResetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14);
				break;
			case 5 :  
				GPIO_ResetBits(GPIOB,GPIO_Pin_12);GPIO_SetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14);
				break;
			case 10  :  
				GPIO_SetBits(GPIOB,GPIO_Pin_12);GPIO_SetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_14); 
				break;
			case 20 :  
				GPIO_SetBits(GPIOB,GPIO_Pin_12);GPIO_SetBits(GPIOB,GPIO_Pin_13);GPIO_SetBits(GPIOB,GPIO_Pin_14);
				break;
			default : break;
		}
	}
	return 1;
}


uint8_t Control_b(u8 Max,u8 Min)
{
	vu8 Max_B,Min_B;
	vu8 Max_All;

	uint8_t Vd;

	if((Max==0xe6)|(Min==0x00))
	{
		Controla_b=1;
		GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_ResetBits(GPIOA,GPIO_Pin_1);GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	}
	else
	{
		if((Max==Min)&&(Max==0x73))	
			return 0;
		
		if(Min>=0x73)
			Max_All=Max-0x73;
		else 
		{
			if(Max<=0x73)
				Max_All=0x73-Min;
			else
			{
				Max_B=Max-0x73;
				Min_B=0x73-Min;						
				Max_All=Max_B>Min_B? Max_B:Min_B;
			}		
		}
		Vd=Max_All/Controla_b;

		if(Vd>=55)
			Controla_b=1;
		if((Vd>=22)&&(Vd<52))
			Controla_b=2;
		if((Vd>=11)&&(Vd<20))
			Controla_b=5;
		if((Vd>=5)&&(Vd<10))
			Controla_b=10;
		if(Vd<5)
			Controla_b=20;
		
		if((Vd>=52)&&(Vd<55))
		{
			if(Controla_b==1)	 Controla_b=1;
			else				 Controla_b=2;
		}
		if((Vd>=20)&&(Vd<22))
		{
			if(Controla_b==2)	 Controla_b=2;
			else				 Controla_b=5;
		}
		if((Vd>=10)&&(Vd<11))
		{
			if(Controla_b==5)	 Controla_b=5;
			else				 Controla_b=10;
		}
		switch(Controla_b)
		{
			case 1 :  
				GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_ResetBits(GPIOA,GPIO_Pin_1);GPIO_ResetBits(GPIOA,GPIO_Pin_2);
				break;
			case 2 :  
				GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_ResetBits(GPIOA,GPIO_Pin_1);GPIO_SetBits(GPIOA,GPIO_Pin_2);
				break;
			case 5 :  
				GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOA,GPIO_Pin_1);GPIO_ResetBits(GPIOA,GPIO_Pin_2);
				break;
			case 10  :  
				GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOA,GPIO_Pin_1);GPIO_SetBits(GPIOA,GPIO_Pin_2);
				break;
			case 20 :  
				GPIO_SetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOA,GPIO_Pin_1);GPIO_SetBits(GPIOA,GPIO_Pin_2);
				break;
			default : break;
		}
	}
	return 1;
}






















