
/* Standard includes. */
#include <stdio.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#include "delay.h"

/* Library includes. */
#include "stm32f10x_it.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_dma.h"									// FW pro praci s DMA radicem
#include "misc.h"

// Include FW knihovny -------------------------------------
#include "stm32f10x_flash.h"	// Kníhovna pro praci s FLASH - pomocne funkce pro knihovnu EEPROM

// Include drivery a vlastni knihovny
#include "PIN_config.h"			// Definice nazvu pinu, portu
#include "LCD_HD44780.h"		// Driver k Alfanumerickemu displayi 2x16 znaku
#include "My_PWM.h"				// Driver pro rizeni PWM vystupu -> ovladani jasu v jednotlivych LED kanalech
#include "My_ADC.h"				// Driver pro rizeni interniho AD prevodniku
#include "My_usart.h"			// Driver pro praci se seriovou linkou
#include "My_rtc.h"				// Driver interniho RTC
#include "eeprom.h"				// Knihovna pro emulaci EEPROM v interni FLASH mikrokontroleru (posledni 2 kb ze 128kb)
#include "DS18B20.h"			// Knihovna pro praci s teplotnimi cidly DS18B20
#include "server.h"				// Knihovna pro Etherentovy server
#include "tcp.h"
#include "www.h"
#include "user_interface.h"		// Knihovna s uzivatelskym rozhranim
#include "menu.h"				// Knihovna menu uzivatelskeho rozhrani
#include "Humidity.h"			// Knihovna pro mereni a vypocet relativni vzdusne vlhkosti mereneho pomoci kapacitniho cidla
#include "planovac.h"			// Knihovna pro operace s naplanovanymi zmenami LED
#include "flash_save.h"			// Knihovna pro nacitani a ukladani nastaveni do FLASH
#include "RS232_komunikace.h"	// Knihovna pro prijem prikazu a odesilani parametru po seriove lince

/* Task priorities. */
#define mainBLINK_TASK_PRIORITY				( tskIDLE_PRIORITY + 5 )
#define mainUSER_INTERFACE_TASK_PRIORITY	( tskIDLE_PRIORITY + 4 )
#define mainSERVER_TASK_PRIORITY			( tskIDLE_PRIORITY + 2 )
#define mainWWW_TASK_PRIORITY				( tskIDLE_PRIORITY + 2 )

/* The check task uses the sprintf function so requires a little more stack. */
#define mainBLINK_TASK_STACK_SIZE			( configMINIMAL_STACK_SIZE )		// jednotka je 32 bite = 4 byte
#define mainUSER_INTERFACE_TASK_STACK_SIZE	( 280 )								// jednotka je 32 bite = 4 byte
#define mainSERVER_TASK_STACK_SIZE			( 340 )//( 350 )					// jednotka je 32 bite = 4 byte
#define mainWWW_TASK_STACK_SIZE				( 300 )//( 320 )					// jednotka je 32 bite = 4 byte

#define TEPLOTA_LED_ID			0
#define TEPLOTA_TRANZ_ID		1
#define TEPLOTA_EXT_ID			2

/* Prototypy funkci -----------------------------------------*/
void DMAChannel1_IRQHandler(void);

/* Globalni promenne ----------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;

extern FLASH_Status FlashStatus;
extern const uint16_t EEPROM_VirtAdd[3] = {0x0000, 0x3000, 0x5000};	/* Virtual address defined by the user: 0xFFFF value is prohibited */

extern volatile u8 PocetCidel = 0;								// Pocet teplotnich cidel nalezenych pomoci funkce find sensors
extern int16_t Teplota[MAXSENSORS] = {DS18X20_INVALID_TEMP,
									  DS18X20_INVALID_TEMP,
									  DS18X20_INVALID_TEMP};	// Teplota ve formatu int -> 25,3 = 253
volatile uint8_t gSensorIDs[MAXSENSORS][DS18X20_SP_SIZE];		// Tabulka ROM kodu jednotlivych cidel nactenych pres funkci find sensor
volatile uint16_t FLASHSensorIDs[MAXSENSORS][DS18X20_SP_SIZE];	// Tabulka ROM kodu jednotlivych cidel nactenych z emulovane EEPROM pameti
																// FLASHSensorIDs[0][] ... Cidlo na chladici 1 - LED
																// FLASHSensorIDs[1][] ... Cidlo na chladici 2 - Tranzistory
																// FLASHSensorIDs[2][] ... Externi cidlo na kabelu
extern int16_t TeplotaHistorie[MAXSENSORS+1][2] = 
									  {{DS18X20_INVALID_TEMP,DS18X20_INVALID_TEMP},
									   {DS18X20_INVALID_TEMP,DS18X20_INVALID_TEMP},
									   {DS18X20_INVALID_TEMP,DS18X20_INVALID_TEMP},
									   {DS18X20_INVALID_TEMP,DS18X20_INVALID_TEMP}};
// Hodiny a datum
extern uint8_t Time_Hodiny = 0;
extern uint8_t Time_Minuty = 0;
extern uint8_t Time_Vteriny = 0;
extern uint8_t Time_Den = 0;
extern uint8_t Time_Mesic = 0;
extern uint16_t Time_Rok = 0;
extern uint8_t Time_DenVTydnu = 0;
volatile uint16_t SummerTimeCorrect;
const uint8_t *JmenaDni2[]={"Po","Ut","St","Ct","Pa","So","Ne"};
extern const uint8_t JmenaDni3[7][9]={{"Pondělí\0"},{"Úterý\0"},{"Středa\0"},{"Čtvrtek\0"},{"Pátek\0"},{"Sobota\0"},{"Neděle\0"}};
extern uint32_t LED_Time[6] = {0,0,0,0,0,0};

extern uint32_t RunTime = 0;									// Delka spusteni ve vterinach

// ADC mereni
extern uint16_t ADC_Hodnoty[6];									// Promenna kam bude DMA ukladat namerene vysledky ADC
extern uint16_t ADC_HodnotyPrumer[6]={0,0,0,0,0,0};				// Jiz zprumerovane hodnoty z ADC (prumer za 1ms->1000vzorku)
uint32_t ADC_Prumer[6]={0,0,0,0,0,0};
uint16_t ADC_PrumerPocet = 0;
// PWM
extern uint16_t PWM_max[5]={48000,48000,48000,48000,48000};
//FAN
extern uint16_t FANtemp[4]={300,350,400,430};
extern uint16_t SHUTDOWNtemp={600};
extern uint16_t FANval[4]={36000,39000,42000,48000};

extern uint8_t	FANmode=0;

// Promenne pro komunikaci mezi procesy
extern uint8_t PovoleniMeritTeplotu = false;
extern uint8_t TeplotaInicializace = true;
extern uint8_t PovoleniRTC_Update = false;

// Promenne planovace nastaveni
extern uint8_t AutomatickyRezim=0xFF;							// Na pozici na ktere je 1 se bude nastaveni ridit podle planovace

extern uint16_t HumidityRAW;
extern uint8_t Humidity;
extern uint8_t HumidityHistorie[2];

// Promenne pro komunikaci TCP stacku v jednom procesu s web serverem v druhem procesu
extern uint8_t TCPEnableGenerateWWW = 0;
extern uint8_t TCPGenerateStatus = GENERATE_OFF;
extern uint8_t RxTx_buffer[TCP_BUFFER_SIZE+1];

// Promenne pro ulozeni nasledujici naplanovane zmeny planovace
extern volatile uint32_t Planovac_Timestamp = 0;			// Format: RRMMDDssss
extern uint8_t PlanovacStav=(1<<PLANOVAC_RESTART);
extern uint8_t Planovac_Kanal[5]={127,127,127,127,127};	// [0-6] ... Kanal 1 (0-100%)
														// [0-6] ... Kanal 2 (0-100%)
														// [0-6] ... Kanal 3 (0-100%)
														// [0-6] ... Kanal 4 (0-100%)
														// [0-6] ... Kanal 5 (0-100%)
														// [7] ..... Kanal 6 (0-OFF/1-ON)

//#define DEBUG
/* ------------------------------------------------------------------------- */
/* Configure the clocks, GPIO and other peripherals as required by the demo. */
static void prvSetupHardware( void );

/* Prototypy spoustenych procesu ----------------------------*/
static void vBlinkTask( void *pvParameters );
static void vUserInterfaceTask( void *pvParameters );
static void vServerTask( void *pvParameters );
static void vWWWTask( void *pvParameters );

/* =========================================================== 
 Hlavni spousteci funkce
 ========================================================== */
int main( void )
{
	uint16_t del;
	prvSetupHardware();							// Inicializace jadra procesoru a hodin
	
	/* Inicializace periferii */
	ALL_PORTS_POWERED();						// Zapnuti napajeni pro vsechny GPIO porty + alternativni funkce portu
  	INFO_LED_Out();								// Nastaveni pinu pro informacni LED jako vystup
	INFO_LED_ON();
  	Backlight_Out();
  	PWM_Init();									// Inicializace PWM vystupu
  	AD_Init();									// Inicializace AD prevodniku s DMA radicem
  	TLACITKA_IN();								// Nakonfigurovani pinu tlacitek jako vstupy
	USART1_Init();								// Inicializace UARTu
	PIEZO_OUT();								// Nastaveni piezo vystupu jako vystup
	PEZO_BEEP_NoTask();							// Pipnuti
	PEZO_BEEP_NoTask();							// Pipnuti
	PEZO_BEEP_NoTask();							// Pipnuti
	PEZO_BEEP_NoTask();							// Pipnuti
	#ifdef DEBUG
		USART1_Send_Clc();						// Odeslani prikazu pro smazani vypisu
		USART1_Send("START", 1);
		USART1_Send("Loading FLASH... ", 1);
	#endif
	FlashSave_LoadConfig();						// Nacteni nastaveni z FLASH
	#ifdef DEBUG		
		USART1_Send("OK", 1);
	#endif
	RTC_Init();									// Inicializace RTC	
	PovoleniRTC_Update=true;					// Povoleni aktualizace casu pomoci RTC
	Humidity_Init();							// Inicializace timeru pro humidity sensor
	#ifdef DEBUG
		USART1_Send("Server init", 1);
	#endif
	/* Inicializace serveru */
	ServerInit();
	#ifdef DEBUG
		USART1_Send("Starting OS", 1);
	#endif
	/* Start the tasks defined within this file */    
	xTaskCreate(vUserInterfaceTask, (signed portCHAR *)"Interface", mainUSER_INTERFACE_TASK_STACK_SIZE, NULL, mainUSER_INTERFACE_TASK_PRIORITY, NULL );	
	xTaskCreate(vServerTask, (signed portCHAR *)"Server", mainSERVER_TASK_STACK_SIZE, NULL, mainSERVER_TASK_PRIORITY, NULL );	
	xTaskCreate(vWWWTask, (signed portCHAR *)"WWW", mainWWW_TASK_STACK_SIZE, NULL, mainWWW_TASK_PRIORITY, NULL );	
	xTaskCreate(vBlinkTask, (signed portCHAR *)"Blink", mainBLINK_TASK_STACK_SIZE, NULL, mainBLINK_TASK_PRIORITY, NULL );		
	
	/* Start the scheduler. */
	vTaskStartScheduler();
	
	/* Will only get here if there was not enough heap space to create the
	idle task. */
	while(1)
	{
		INFO_LED_ON();
		_delay_us(50000);
		INFO_LED_OFF();
		_delay_us(50000);
	}
//	return 0;
}

/* ===========================================================
 Task 1
 - ethernetovy UDP server
 - ethernetovy HTTP server
 - IP, ICMP, ARP, TCP, UDP rutiny
 ========================================================== */
static void vServerTask( void *pvParameters )
{	
    #ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("# Starting Server task", 1);
		USART1_FreeMUTEX();
	#endif
	TCP_Init();
	for( ;; )
	{
		ServerStart();					// Spusti jeden beh serveru - jedno zpracovani prijateho paketu
		Check_RS232();					// Proveri jestli eprisly nejake prikazy po seriove lince
		vTaskDelay(1*portTICK_FOR_1MS);
	}
}

/* ===========================================================
 Task 2
 - zpracovavani HTTP requestu => WWW server 
  (kooperuje se serverem - modul tcp.h)
 ========================================================== */
static void vWWWTask( void *pvParameters )
{	
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("# Starting WWW task", 1);
		USART1_FreeMUTEX();
	#endif
	for( ;; )
	{		
		WWW_ProcessRequest(RxTx_buffer,RxTx_buffer);

		vTaskDelay(1*portTICK_FOR_1MS);
	}
}

/* ===========================================================
 Task 3
 - blikani kontrolni LED								[OK]
 - aktualizace teplotnich cidel							[OK]
 - rizeni otacek ventilatoru							[OK]
 - automaticke vypinani vykonu pri prekroceni 		  	[OK]
   mezni teploty -> ochrana LED pri prehrati
 - aktualizace a vypocty relativni vlhkosti				[OK]
 ========================================================== */
static void vBlinkTask( void *pvParameters )
{	
	uint8_t i;
	uint32_t Hodnota32=0;
	portTickType xLastExecutionTime;

	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("# Starting Blink task", 1);
		USART1_FreeMUTEX();
	#endif

	for( ;; )
	{
		xLastExecutionTime = xTaskGetTickCount();
		INFO_LED_ON();
		vTaskDelay(200*portTICK_FOR_1MS);
		INFO_LED_OFF();

		if (PovoleniMeritTeplotu==true)
		{
			DS18B20_UpdateTemperatue();
			/* Zaznam minimalni a maximalni teploty pro DS cidla */
			if(TeplotaInicializace==false)
			{
				for(i=0;i<MAXSENSORS;i++)								// Zaznamenavani minimalni a maximalni teploty
				{
					if(Teplota[i]!=DS18X20_INVALID_TEMP)
					{
						if (TeplotaHistorie[i][0]==DS18X20_INVALID_TEMP)	// Pokud je pamet minima a maxima prazdna - ulozit bez porovnavani
							TeplotaHistorie[i][0] = Teplota[i];
						else if(Teplota[i]>TeplotaHistorie[i][0])			// Pokud je aktualni teplota vetsi nez maximum - ulozit
							TeplotaHistorie[i][0] = Teplota[i];
						if (TeplotaHistorie[i][1]==DS18X20_INVALID_TEMP)	// Pokud je pamet minima a maxima prazdna - ulozit bez porovnavani
							TeplotaHistorie[i][1] = Teplota[i];
						else if(Teplota[i]<TeplotaHistorie[i][1])			// Pokud je aktualni teplota mensi nez maximum - ulozit
							TeplotaHistorie[i][1] = Teplota[i];												
					}
				}
			}
		}
		if(PovoleniRTC_Update==true)
		{
			RTC_UpdateSec();
		}
		/* Zaznamenavani minimalni a maximalni teploty systemu - teploty mikrokontroléru */
		Hodnota32 = ADC_HodnotyPrumer[ADC_VALUE_TEMP];		// 32°C = 1725	
		Hodnota32 = (((uint32_t)100*((uint32_t)3288-(uint32_t)Hodnota32))/(uint32_t)53)+(uint32_t)250;
		Hodnota32 = Hodnota32/10;
		if(TeplotaHistorie[MAXSENSORS][0]==DS18X20_INVALID_TEMP)
			TeplotaHistorie[MAXSENSORS][0]=Hodnota32;
		else if(Hodnota32>TeplotaHistorie[MAXSENSORS][0])
			TeplotaHistorie[MAXSENSORS][0]=Hodnota32;
		if(TeplotaHistorie[MAXSENSORS][1]==DS18X20_INVALID_TEMP)
			TeplotaHistorie[MAXSENSORS][1]=Hodnota32;
		else if(Hodnota32<TeplotaHistorie[MAXSENSORS][1])
			TeplotaHistorie[MAXSENSORS][1]=Hodnota32;

		/* Automaticka regulace otacek ventilatoru */
		if(FANmode==0)
		{
			if((Teplota[0]!=DS18X20_INVALID_TEMP) & (TeplotaInicializace==false))	// Teplota z cidla LED diod je spravna - cidlo je propojeno
			{
				for(i=0;i<4;i++)
				{
					if((Teplota[0]>=FANtemp[3-i]) | ((Teplota[1]>=FANtemp[3-i]) & (Teplota[1]!=DS18X20_INVALID_TEMP)))
					{
						PWM_Set_FAN(FANval[3-i]);
						break;
					}
				}
				if(Teplota[0]<FANtemp[0])
				{
					PWM_Set_FAN(0);									// Vypnuti ventilatoru
				}
			}
			else													// Cidlo LED diod neni pripojeno - rezim trvale zapnuty ventilator
			{
				if((PWM_Get_LED_1()==0) & (PWM_Get_LED_2()==0) & (PWM_Get_LED_3()==0) & (PWM_Get_LED_4()==0) & (PWM_Get_LED_5()==0))
				{
					PWM_Set_FAN(0);									// Vypnuti ventilatoru
				}
				else
				{
					PWM_Set_FAN(48000);								// Zapnuti velntilatoru naplno
				}	
			}
		}
		/* Nouzove vypnuti LED pri prehrati - pokud funguje cidlo */
		if((Teplota[0]>=SHUTDOWNtemp) & (Teplota[0]!=DS18X20_INVALID_TEMP))
		{
			PWM_Vypnuti();									// Vyrazeni PWM a zhasnuti vsech LED
			PWM_Set_FAN(48000);								// Zapnuti velntilatoru naplno
		}
		else
		{
			PWM_ZnovuZapnuti();								// Znovuaktivovani LED
		}
		Planovac_CheckPlan();								// Overeni a provedeni naplanovanych zmen LED
		vTaskDelayUntil( &xLastExecutionTime, 1000*portTICK_FOR_1MS );
		HumidityZmerit();
	}
}

/* ===========================================================
 Task 4
 - uzivatelske rozhrani mistniho ovladani
 - inicializace teplotnich cidel
 ========================================================== */
static void vUserInterfaceTask( void *pvParameters )
{
	uint8_t i=0;
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("# Starting user interface task", 1);
		USART1_FreeMUTEX();
	#endif
	/* Inicializace LCD */  
	Backlight_ON();
	LCD_HD44780_Init();							// Inicializace LCD displaye
	LCD_HD44780_Cursor(OFF);					// Vypnuti kurzoru LCD displaye
	
	#ifdef DEBUG
		USART1_WaitForMUTEX();
		USART1_SetMUTEX();
		USART1_Send("> LCD init complete", 1);
		USART1_FreeMUTEX();
	#endif
	/* Zobrazeni data a casu kompilace programu */
	LCD_HD44780_Clear();
	LCD_HD44780_PutString("Build date:");
	LCD_HD44780_GoTo(0,1);
	LCD_HD44780_PutString(__TIME__);			// Vypise na display cas kompilace zdrojového kódu
	LCD_HD44780_GoTo(5,1);
	LCD_HD44780_PutChar(' ');
	LCD_HD44780_PutBuildDate();					// Vypise na display datum kompilace zdrojového kódu
	vTaskDelay(2000*portTICK_FOR_1MS);
	LCD_HD44780_Clear();
	
	/* Inicializace teplotnich cidel a jejich oznaceni (co meri) */
	UserInterface_SensorInit();

	LCD_HD44780_Clear();
	LCD_HD44780_PutString("Running");
    
	for( ;; )
	{
		LCD_HD44780_GoTo(0,0);
		LCD_HD44780_TimeToLCD();

		// Zobrazeni teplot
		LCD_HD44780_GoTo(0,1);
		LCD_HD44780_PutString("                ");
		LCD_HD44780_GoTo(0,1);
		if(i<20)
		{
			LCD_HD44780_PutString("Ext.:");
			if(Humidity!=255)
			{
				if(Humidity<100)
				{			
					LCD_HD44780_PutChar(' ');
					LCD_HD44780_PutInt16(Humidity,2);
				}
				else
				{
					LCD_HD44780_PutInt16(Humidity,3);
				}
				LCD_HD44780_PutChar('%');
			}
			if(Teplota[2]!=DS18X20_INVALID_TEMP)
			{
				LCD_HD44780_TeplotaNaLCD(Teplota[2]);
				LCD_HD44780_PutChar(Char_StupenCelsia);
			}					
		}
		else if(i<40)
		{
			LCD_HD44780_PutString("LED: ");
			if(Teplota[0]!=DS18X20_INVALID_TEMP)
			{
				LCD_HD44780_TeplotaNaLCD(Teplota[0]);
				LCD_HD44780_PutChar(Char_StupenCelsia);
			}
			else
			{
				LCD_HD44780_PutString("Err");
			}									
		}
		else if(i<60)
		{
			LCD_HD44780_PutString("Tranz.: ");
			if(Teplota[1]!=DS18X20_INVALID_TEMP)
			{
				LCD_HD44780_TeplotaNaLCD(Teplota[1]);
				LCD_HD44780_PutChar(Char_StupenCelsia);
			}
			else
			{
				LCD_HD44780_PutString("Err");
			}						
		}
		else if(i<80)
		{
			LCD_HD44780_PutString("MCU: ");			
			LCD_HD44780_TeplotaNaLCD(ADC_GetTempMCU());
			LCD_HD44780_PutChar(Char_StupenCelsia);			
		}
		else
		{
			i=0;
		}
		i++;
		vTaskDelay(300*portTICK_FOR_1MS);
		if(TL_MENU_Read_0())										// Obsluha tlacitka NAHORU
		{
			PEZO_BEEP();
			vTaskDelay(30*portTICK_FOR_1MS);
			while(TL_MENU_Read_0()) vTaskDelay(1*portTICK_FOR_1MS);	// Cekani na uvolneni tlacitka
			vTaskDelay(40*portTICK_FOR_1MS);
			
			LCD_HD44780_Clear();			
			UserInterface_Run();									// Vstup do menu
			LCD_HD44780_Clear();
		}
	}
}

/*-----------------------------------------------------------
 Inicializace jadra mikrokontroleru a jeho hodin
 --------------------------------------------------------- */
static void prvSetupHardware( void )
{
	/* Start with the clocks in their expected state. */
	RCC_DeInit();

	/* Enable HSE (high speed external clock). */
	RCC_HSEConfig( RCC_HSE_ON );

	/* Wait till HSE is ready. */
	while( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) == RESET )
	{
	}

	/* 2 wait states required on the flash. */
	*( ( unsigned portLONG * ) 0x40022000 ) = 0x02;

	/* HCLK = SYSCLK */
	RCC_HCLKConfig( RCC_SYSCLK_Div1 );

	/* PCLK2 = HCLK */
	RCC_PCLK2Config( RCC_HCLK_Div1 );

	/* PCLK1 = HCLK/2 */
	RCC_PCLK1Config( RCC_HCLK_Div2 );

	/* PLLCLK = 8MHz * 3 = 24 MHz. */
	RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_3 );

	/* Enable PLL. */
	RCC_PLLCmd( ENABLE );

	/* Wait till PLL is ready. */
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
	{
	}

	/* Select PLL as system clock source. */
	RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );

	/* Wait till PLL is used as system clock source. */
	while( RCC_GetSYSCLKSource() != 0x08 )
	{
	}

	/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
							| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );

	/* Set the Vector Table base address at 0x08000000 */
	NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );

	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
	
	/* Configure HCLK clock as SysTick clock source. */
	SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
	
}

/* Preruseni ================================================================ */
/* ------------------------------------------
 Preruseni od DMA kanalu
 -> prumerovani namerenych hodnot ADC
 po zmereni sady (vsech 5 kanalu proudu
 a jedno kanalu teploty)
 ----------------------------------------- */
void DMAChannel1_IRQHandler(void)
{
	uint8_t i;
	for(i=0;i<6;i++)
	{
		ADC_Prumer[i] += ADC_Hodnoty[i];
	}
	ADC_PrumerPocet++;
	
	if(ADC_PrumerPocet>=200)
	{
		for(i=0;i<6;i++)
		{
			ADC_HodnotyPrumer[i] = ADC_Prumer[i]/(uint32_t)ADC_PrumerPocet;	// Vypocet prumerne hodnoty za poslednich 200 vzorku => 1ms (5us/vzorek)
			ADC_Prumer[i]=0;										// Vynulovani prumerovaci sumy
		}
		ADC_PrumerPocet=0;											// Vynulovani poctu souctu v sume	
	}
	DMA_ClearITPendingBit(DMA1_IT_TC1);								// Vymazani priznaku preruseni DMA1->Channel_1->Full transfer
	DMA_ClearFlag(DMA1_FLAG_TC1);									// Vyresetovani flagu Full-transfer
}

#ifdef  DEBUG										  
/* Keep the linker happy. */

void assert_failed( unsigned portCHAR* pcFile, unsigned portLONG ulLine )
{
	for( ;; )
	{
	}
}
#endif

/* Konec souboru */
