Exemple #1
0
/**-----------------------------------------------------------------------------
 * @brief	Initialisation du watchdog Windows.
 *
 * param[in]	Timeout_ms	Duree du timeout watchdog en ms.
 */
void WDG_InitWWDG(uint16_t Timeout_ms){

	RCC_ClocksTypeDef xRCC_Clocks;
	uint32_t ulClock_kHz;

	WWDG_DeInit();

	// Initialisation des variables
	WWDG_Reload = Timeout_ms;
	WWDG_Cnt = Timeout_ms;

	// Activation horloges
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_WWDG, DISABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);

	// Configuration interruption
	WWDG_EnableIT();
	#ifdef configLIBRARY_KERNEL_INTERRUPT_PRIORITY
		NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init( &NVIC_InitStructure );
	#else
		NVIC_EnableIRQ(WWDG_IRQn);
	#endif

	// Configuration timeout
	WWDG_SetPrescaler(WWDG_Prescaler_8);
	WWDG_SetWindowValue(0x7F);

	// Activation
	WWDG_Enable(0x7F);
	WDG_Refresh();
}
//-----------------------------------------------------------------------------
// FUNCTION:    main
// SCOPE:       Bootloader application system function
// DESCRIPTION: bootloader main function             
// RETURNS:     0
//----------------------------------------------------------------------------- 
int main(void)
{	
    volatile unsigned long loop_counter = 0;  // counter of loop without received frame
    
	Byte enableBootMode = 0; 			//  0: enter APP, 1: enter BOOT mode, 2: enter verify mode

	DisableInterrupts;
	//WDG_Disable();				//watchdog can be enable or disabled in kinetis_sysinit.c
	
	INIT_CLOCKS_TO_MODULES;			// init clock module
	Boot_Button_Init();  			// init SW1 button (PTC3 port) on FRDM_KL26 board
	INIT_BOOT_LED;
	
    //condition for entering boot:  
    if(((*(unsigned long*)(RELOCATED_VECTORS + 8)) == 0xffffffff)                          //1. no valid code in APP vector section,
    || Boot_StrCompare(( Byte*)APPOK_START_ADDRESS, str_app_ok, APPOK_LENGTH) == CHECK_FAIL	   //2."APP_OK" is wrong in address APPOK_START_ADDRESS.
    || ((GPIO_PDIR_REG(BOOT_PIN_ENABLE_GPIO_BASE) & (1 << BOOT_PIN_ENABLE_NUM)) == 0)      //3. SW1 is pressed
    || (AppIDC == 0x0000000B))                                                             //4. App request boot
    {
    	 enableBootMode = 1; // enable boot
    	 BOOT_LED_ON;
    	 AppIDC = 0;
    }
    else if (AppIDC == 0x0000000A)   // App request verify
    {
    	 enableBootMode = 2; // enable verify mode
    	 BOOT_LED_ON;
    	 AppIDC = 0;
    }
    
    if(enableBootMode)
    {
    	// if use external clock
#ifdef USE_EXTERNAL_CLOCK
    	Boot_Init_Clock( );
#endif
    	PIN_INIT_AS_UART;   			// set PTA1/UART0_RX and PTA2/UART0_TX pins as UART
    	UART_Initialization();  		// init UART module
    }

	////////////////////////////////////////////////////////////////////////
	//BOOT Model 
	////////////////////////////////////////////////////////////////////////
	while(enableBootMode)  // enter boot or verify mode, execute all command from GUI
	{  
		volatile Byte frame_start_flag  = 0;    // if frame header is received. 1: receive $, start to receive frame;  0: no $ received
		volatile Byte frame_length 	= 0xFF;    // SCI received frame length, initialized as 0xFF
		volatile Byte data_length = 0;
		volatile Byte buff_index = 1;   	   // receive buffer index for sci_buffer[]
		volatile Byte data_checked  = 0; 	   // check frame end 0xAA 0x55. 1: correct frame ; 0: wrong frame
				
		FLASH_Initialization();

		sci_buffer[0] = UART_GetChar();
		if( sci_buffer[0] == '$') 			//check frame header: whether it is '$'
		{
			loop_counter = 0;
			frame_start_flag  = 1;			
		}   
		
		if(frame_start_flag == 1)
		{
			sci_buffer[1] = UART_GetChar();     // sci_buffer[1] is the station number
			UART_GetChar();   					// sci_buffer[2] is reserved
			sci_buffer[3] = UART_GetChar();     // sci_buffer[3] is the Data length
			data_length = sci_buffer[3];
			frame_length = 4 + sci_buffer[3] + 2;  // frame_length = frame head + data + frame end 
			buff_index = 4;
			while(data_length --)
				sci_buffer[buff_index ++] = UART_GetChar();
			sci_buffer[buff_index ++] = UART_GetChar();  // frame end. It should be 0xAA
			sci_buffer[buff_index ++] = UART_GetChar();  // frame end. It should be 0x55
			frame_start_flag = 0;
		}
		
		if((sci_buffer[frame_length-2] == 0xAA) && (sci_buffer[frame_length-1] == 0x55)) //Check if Frame end is correct
		{
			data_checked = 1; //  Correct frame received. 
		}

		// all the data in frame was correctly received (data_checked = 1) above, now perform frame analysis below.
		// sci_buffer[] now is switched to tx buffer
		if(data_checked == 1)
		{ 
			Byte i = 0;  
			Byte j = 0;  	
			Byte s19length = 0;
			Byte s19buffer[WR_BLOCK_BYTE]; //extract app file burning code from received frame, store them to s19buffer[]
			
			WDG_Refresh();
			switch(sci_buffer[4])
			{
				
				case 'I':	// receive 'I' command, send  version information to UART    
							i = 4;
						    while((sci_buffer[i] = Identifier[i-4]) !='\0')	//assign chip part number info to sci_buffer[]
						    {
						    	i++;
						    }
						    sci_buffer[3] = i - 4;   // tx data length in one frame 
						    Boot_Send(sci_buffer);
						    if(enableBootMode == 1)  // if in boot mode
						      FLASH_EraseSector((LWord)APPOK_START_ADDRESS);	//erase APP_OK
						    break;
						    
				case 'E':	// receive 'E' command, erase sector, then send confirm frame to UART
							Boot_ReadAddress();
							if(!( FLASH_EraseSector(address.complete)))
							{
								 sci_buffer[3] = 00;							  
								 Boot_Send(sci_buffer);
							}
							break; 

				case'W':	// receive 'W' command, extract app  burning code,  program flash. then send confirm frame to UART
							Boot_ReadAddress();
							s19length = sci_buffer[8];
				
							for(j=0,i=9;j<s19length;j++,i++) // extract the prepared writing data from sci_buff[] to S19buffer[]
							{
								s19buffer[j] = sci_buffer[i];   
							}
							if(!(FLASH_ProgramSectionByLongs (address.complete, (LWord*)s19buffer, s19length/4))) 
							{            
								 sci_buffer[3] = 00;
								 Boot_Send(sci_buffer);
								 break;
							}

				case'R':	// receive 'R' command, read out the memory data, then send the data in frame to UART
							Boot_ReadAddress();
							s19length = sci_buffer[8];
							for(i=0;i<s19length;i++)
							{ 
								sci_buffer[i + 4] = ((Byte*)(address.complete))[i];
							}
							sci_buffer[3] = s19length;
							Boot_Send(sci_buffer);
							break;

				case'G':	// receive 'G' command, go to app. 
					        if(enableBootMode == 1)
				    		  FLASH_ProgramSectionByLongs ((LWord)APPOK_START_ADDRESS, (LWord*)str_app_ok, APPOK_LENGTH/4);   
					        
							Boot_Cpu_SystemReset( );
							// if we want  to jump to user application, we need to deinitialize used modules and switch MCG back to FEI mode
							break;

				default :
				         	break;
			}// end switch(sci_buffer[4])		
			frame_start_flag  = 0;
			for (buff_index = 0; buff_index<FRAME_BUFF_LENGTH; buff_index++)	// clear sci_buffer[]
				sci_buffer[buff_index] = 0;
			
		}// end if(data_checked == 1)
		loop_counter ++;
		if(loop_counter >= 10 && enableBootMode == 2)                         // 100 * timeout of UART_GetChar();
		{
			Boot_Cpu_SystemReset( );
		}
	}// end while(enableBootMode)
	
	// deinitialization of used modules
	UART_Deinitialization();
	DEINIT_BOOT_LED;
	DEINIT_CLOCKS_TO_MODULES;
	
	// relocate vector table
	SCB_VTOR = RELOCATED_VECTORS;	
	AppIDC = 0;
	// Jump to user application
	JumpToUserApplication(*((unsigned long*)RELOCATED_VECTORS), *((unsigned long*)(RELOCATED_VECTORS+4)));  
	return 0;
} // end main 
//-----------------------------------------------------------------------------
// FUNCTION:    main
// SCOPE:       Bootloader application system function
// DESCRIPTION: bootloader main function             
// RETURNS:     0
//----------------------------------------------------------------------------- 
int main(void)
{	
    volatile unsigned long loop_counter = 0;    // counter of loop without received frame

    Byte enableBootMode = 0; 			//  0: enter APP, 1: enter BOOT mode, 2: enter verify mode
    //Byte s19buffer[WR_BLOCK_BYTE] = {1};        //extract app file burning code from received frame, store them to s19buffer[]

    DisableInterrupts;


    INIT_CLOCKS_TO_MODULES;			// init clock module
    Boot_Button_Init();  			// init SW3 button (PTC3 port) on FRDM_K22 board
    INIT_BOOT_LED;
    //  condition for entering boot:
    if(((*(unsigned long*)(RELOCATED_VECTORS + 8)) == 0xffffffff)                          //1. no valid code in APP vector section,
    || Boot_StrCompare(( Byte*)APPOK_START_ADDRESS, str_app_ok, APPOK_LENGTH) == CHECK_FAIL	   //2."APP_OK" is wrong in address APPOK_START_ADDRESS.
    || ((GPIO_PDIR_REG(BOOT_PIN_ENABLE_GPIO_BASE) & (1 << BOOT_PIN_ENABLE_NUM)) == 0)      //3. SW1 is pressed
    || (AppIDC == 0x0000000B))                                                             //4. App request boot
    {
        enableBootMode = 1; // enable boot
        BOOT_LED_ON;
        AppIDC = 0;
    }
    else if (AppIDC == 0x0000000A)   // App request verify
    {
        enableBootMode = 2; // enable verify mode
        BOOT_LED_ON;
        AppIDC = 0;
    }
    if(enableBootMode)
    {
    // if use external clock
#ifdef USE_EXTERNAL_CLOCK
        Boot_Init_Clock();
#endif
        PIN_INIT_AS_UART;   			// set PTEA1/UART1_RX and PTE0/UART1_TX pins as UART
        UART_Initialization();  		// init UART module
    }   
    ////////////////////////////////////////////////////////////////////////
    //BOOT Model
    ////////////////////////////////////////////////////////////////////////
    while(enableBootMode)  // enter boot or verify mode, execute all command from GUI
    {        
        volatile Byte frame_start_flag  = 0;    // if frame header is received. 1: receive $, start to receive frame;  0: no $ received
        volatile Byte frame_length 	= 0xFF;    // SCI received frame length, initialized as 0xFF
        volatile Byte data_length = 0;
        volatile Byte buff_index = 1;   	   // receive buffer index for sci_buffer[]
        volatile Byte data_checked  = 0; 	   // check frame end 0xAA 0x55. 1: correct frame ; 0: wrong frame
        WDG_Refresh();
        FLASH_Initialization();

        sci_buffer[0] = UART_GetChar();
        if( sci_buffer[0] == '$') 			//check frame header: whether it is '$'
        {
            loop_counter = 0;
            frame_start_flag  = 1;
        }

        if(frame_start_flag == 1)
        {
            sci_buffer[1] = UART_GetChar();     // sci_buffer[1] is the station number
            UART_GetChar();   					// sci_buffer[2] is reserved
            sci_buffer[3] = UART_GetChar();     // sci_buffer[3] is the Data length
            data_length = sci_buffer[3];
            frame_length = 4 + sci_buffer[3] + 2;  // frame_length = frame head + data + frame end
            buff_index = 4;
            while(data_length --)
                      sci_buffer[buff_index ++] = UART_GetChar();
            sci_buffer[buff_index ++] = UART_GetChar();  // frame end. It should be 0xAA
            sci_buffer[buff_index ++] = UART_GetChar();  // frame end. It should be 0x55
            frame_start_flag = 0;
        }

        if((sci_buffer[frame_length-2] == 0xAA) && (sci_buffer[frame_length-1] == 0x55)) //Check if Frame end is correct
        {
            data_checked = 1; //  Correct frame received.
        }

       // all the data in frame was correctly received (data_checked = 1) above, now perform frame analysis below.
       // sci_buffer[] now is switched to tx buffer
        if(data_checked == 1)
        {
            Byte i = 0;
            Byte j = 0;
            Byte burn_data_length = 0;
            Byte s19buffer[WR_BLOCK_BYTE]; //extract app file burning code from received frame, store them to s19buffer[]

            //WDG_Refresh();
            switch(sci_buffer[4])
            {
                case 'I':	// receive 'I' command, send  version information to UART
                            i = 4;
                            while((sci_buffer[i] = MCU_Identification.targ_name[i-4]) !='\0')	//assign chip part number info to sci_buffer[]
                            {
                                    i++;
                            }
                            sci_buffer[i++] = '#';
                            j = i;
                            while((sci_buffer[i] = MCU_Identification.Boot_version[i-j]) !='\0')	//assign bootloader version info to sci_buffer[]
                            {
                                    i++;
                            }
                            sci_buffer[i++] = '#';
                            sci_buffer[i++] = (MCU_Identification.wrblk & 0xFF00)>>8;		//assign write block size
                            sci_buffer[i++] = MCU_Identification.wrblk & 0x00FF;

                            sci_buffer[i++] = (MCU_Identification.erblk & 0xFF00)>>8;		//assign erase block size
                            sci_buffer[i++] = MCU_Identification.erblk & 0x00FF;

                            sci_buffer[i++] = MCU_Identification.addr_limit.Bytes.hl;		 //assign MCU Flash end address
                            sci_buffer[i++] = MCU_Identification.addr_limit.Bytes.lh;
                            sci_buffer[i++] = MCU_Identification.addr_limit.Bytes.ll;

                            sci_buffer[i++] = MCU_Identification.dontcare_addrl.Bytes.hl;		//assign bootloader dont care memory start adddress
                            sci_buffer[i++] = MCU_Identification.dontcare_addrl.Bytes.lh;
                            sci_buffer[i++] = MCU_Identification.dontcare_addrl.Bytes.ll;

                            sci_buffer[i++] = MCU_Identification.dontcare_addrh.Bytes.hl;		//assign bootloader dont care memory end adddress
                            sci_buffer[i++] = MCU_Identification.dontcare_addrh.Bytes.lh;
                            sci_buffer[i++] = MCU_Identification.dontcare_addrh.Bytes.ll;

                            sci_buffer[i++] = MCU_Identification.relocated_vectors.Bytes.hl;		//assign bootloader start adddress
                            sci_buffer[i++] = MCU_Identification.relocated_vectors.Bytes.lh;
                            sci_buffer[i++] = MCU_Identification.relocated_vectors.Bytes.ll;

                            sci_buffer[i++] = MCU_Identification.targ_core; 	// target is M4 core
                            
                            sci_buffer[3] = i - 4;   // tx data length in one frame 
                            Boot_Send(sci_buffer);
                            if(enableBootMode == 1)  // if in boot mode
                                FLASH_EraseSector((LWord)APPOK_START_ADDRESS);	//erase APP_OK
                            WDG_Refresh();
                            break;

                case 'E':	// receive 'E' command, erase sector, then send confirm frame to UART
                            Boot_ReadAddress();
                            if(!( FLASH_EraseSector(address.complete)))
                            {
                                sci_buffer[3] = 00;
                                Boot_Send(sci_buffer);
                            }
                            WDG_Refresh();
                            break;

                case'W':	// receive 'W' command, extract app  burning code,  program flash. then send confirm frame to UART
                            Boot_ReadAddress();
                            burn_data_length = sci_buffer[8];
                            for(j=0,i=9;j<burn_data_length;j++,i++) // extract the prepared writing data from sci_buff[] to S19buffer[]
                            {
                                s19buffer[j] = sci_buffer[i];
                            }
                            if(!(FLASH_ProgramSectionByLongs (address.complete, (LWord*)s19buffer, burn_data_length/4)))
                            {
                                sci_buffer[3] = 00;
                                Boot_Send(sci_buffer);
                                
                            }
                            WDG_Refresh();
                            break;
                case'R':	// receive 'R' command, read out the memory data, then send the data in frame to UART
                            Boot_ReadAddress();
                            burn_data_length = sci_buffer[8];
                            for(i=0;i<burn_data_length;i++)
                            {
                                sci_buffer[i + 4] = ((Byte*)(address.complete))[i];
                            }
                            sci_buffer[3] = burn_data_length;
                            Boot_Send(sci_buffer);
                            WDG_Refresh();
                            break;

                case'G':	// receive 'G' command, go to app.
                            if(enableBootMode == 1)
                            FLASH_ProgramSectionByLongs ((LWord)APPOK_START_ADDRESS, (LWord*)str_app_ok, APPOK_LENGTH/4);
                            //BOOT_LED_OFF;
                            NVIC_SystemReset();
                            break;

                default :
                            break;
            }// end switch(sci_buffer[4])
            frame_start_flag  = 0;
            for (buff_index = 0; buff_index<FRAME_BUFF_LENGTH; buff_index++)	// clear sci_buffer[]
                sci_buffer[buff_index] = 0;

          }// end if(data_checked == 1)
          loop_counter ++;
          if(loop_counter >= 10 && enableBootMode == 2)                         // 100 * timeout of UART_GetChar();
          {
              NVIC_SystemReset();
          }
    }// end while(enableBootMode)
Exemple #4
0
/**-----------------------------------------------------------------------------
 * @brief	Desactivation du watchdog.
 *
 */
void WDG_Disable(){
	WWDG_DeInit();
	WDG_Refresh();
}
Exemple #5
0
/*------------------------------------------------------------------------------------------------*/
int main(void)
{
	Bool_e NouveauMode;
	Horodatage_s Time = {
			.Heure = 0,
			.Minute = 0,
			.Seconde = 0,
	};


	// ------------------------------------------------------------------------
	// --- INIT DU SYSTEME
	// --- Initialisations uC, Peripheriques, Fonctions et Interfaces
	BSP_Init();									// Init carte
	SysTick_Config(SystemCoreClock / 1000);		// Init Tick 1ms
	HAL_Console_Init(115200);
	RTC_StartInit(TRUE);						// Start Init RTC
	I2C1_Init(100 * 1000);						// 100kHz
	ADC1_Init();

	_CONSOLE(0, "\n");
	_CONSOLE(LogId, "--- START - ALJ%s ---\n", VERSION_SW);

	//AM23xx_Test();

	REGLAGE_RTC();

	//----------------------------------
	// FONCTIONNALITES
	MemoireFAT_Init((Diskio_drvTypeDef*) &SdCard_SPI_Driver);
	#if USE_TEMP_HYGRO
		TempHygro_Init(TEMPERATURE_PERIODE_ACQUISITION_ms);
	#endif
	Delay_ms(50);

//	Hygrometre_Init();
	ConfIni_Init();
	Arrosage_Init(USE_CONF_INI_FILE);
	Chauffage_Init(USE_CONF_INI_FILE);
	Ventilation_Init(USE_CONF_INI_FILE);
	Logs_Init();

	PC_Init();
	Terminal_Init();
	Terminal_Cmd_Init();

	//_CONSOLE(LogId, "MODE_FCT_SERVEUR\n");
	ModeFct = MODE_FCT_SERVEUR;
	//MemoireFAT_PrintFileList("httpserver");
	Ethernet_Init(USE_CONF_INI_FILE);

	if (RTC_BkpRegister_Read(0) != 0)
	{
		_CONSOLE(LogId, "MODE_FCT_USB\n");
		ModeFct = MODE_FCT_USB;
		//USB_Init((Diskio_drvTypeDef*) &SdCard_SPI_Driver);
		RTC_BkpRegister_Write(0, 0);
	}

	// Lancement des timers
	TSW_Start(&TmrAffichTempHygro, 3000);


	//Mode_Test();

	WDG_InitWWDG(10000);

	while (RTC_Main() != RTC_ETAPE_READY);
	TSW_Start(&Tmr_RTC, 10000);
	RTC_Lire(&StartTime);
	RTC_Lire(&Time);


	//--------------------------------------------------------------------------------
	_CONSOLE(LogId, "--------------------------\n");
	_CONSOLE(LogId, "StartupTime=%dms\n", TSW_GetTimestamp_ms());
	_CONSOLE(LogId, "--------------------------\n\n");
		while(1)
	{
		WDG_Refresh();

//		if (PC_Read((uint8_t*) BufferIn, NULL) == TRUE)
//		{
//			Terminal_Parser(BufferIn, BufferOut, 1024);
//			if (strlen(BufferOut) > 0)
//				PC_Write(BufferOut, strlen(BufferOut));
//		}

		// Choix du mode de fonctionnement
		// WKUP = ACTIF -> USB  -  WKUP = INACTIF -> WebServer
		//if (GPIO_Get(PORT_WKUP) == Etat_ACTIF)
		//{
		//	RTC_BkpRegister_Write(0, 1);
		//	while (GPIO_Get(PORT_WKUP) == Etat_ACTIF)
		//		TSW_Delay(100);
		//	GOTO(0);
		//}

		//----------------------------------
		// PROCESSUS
		LifeBit_Main();
		MemoireFAT_Main();
		#if USE_TEMP_HYGRO
			TempHygro_Thread();
		#endif

		if (Mode != MODE_DEMARRAGE)
		{
			Arrosage_Management();
			Chauffage_Management();
			Ventilation_Management();
			Hygrometrie_Management();
		}

		if (ModeFct == MODE_FCT_SERVEUR)
		{
			Ethernet_Management();
		}

		Logs_Management();


		//----------------------------------
		// LECTURE TEMPERATURE
		if ((TempHygro_IsValide() == FALSE)
		&&	(Mode != MODE_DEMARRAGE))
		{
			Mode = MODE_DEFAUT;
		}
		else
		{
			Temperature = TempHygro_GetTemperature();
			Hygrometrie = TempHygro_GetHygrometrie();
		}

		//----------------------------------
		// RTC
		if (TSW_IsFinished(&Tmr_RTC))
		{
			RTC_Lire(&Time);
			TSW_ReStart(&Tmr_RTC);

			//_CONSOLE(LogId, "RTC = %d-%02d-%02d %02d:%02d:%02d;%08d;",
			//				Time.Annee, Time.Mois, Time.Jour,
			//				Time.Heure, Time.Minute, Time.Seconde,
			//				TSW_GetTimestamp_ms());
		}


		//----------------------------------
		// AFFICHAGE TEMPERATURE
/*		if (TSW_IsRunning(&TmrAffichTempHygro) == FALSE)
		{
			_CONSOLE(LogId, "TempHygro = ");
			if (TempHygro_IsValide() == FALSE)
				_CONSOLE(LogId, "Non valide\n");
			else
			{
				_CONSOLE(LogId, "%.01f %c\t%.01f %c\n",
						Temperature, '°',
						Hygrometrie, '%');
			}

			TSW_Start(&TmrAffichTempHygro, 2500);
		}
*/


		//----------------------------------
		// GESTION DES MODES
		NouveauMode = FALSE;
		if (LastMode != Mode)
		{
			LastMode = Mode;
			NouveauMode = TRUE;
		}

		switch (Mode)
		{
			//--------------------------------------------------------------
			case MODE_DEMARRAGE :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_DEMARRAGE -----\n");
					Logs_Data();
				}

				if (Mode_Demarrage() == Status_Fini)
				{
					Mode = MODE_SURVEILLANCE;
				}

				break;


			//--------------------------------------------------------------
			case MODE_SURVEILLANCE :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_SURVEILLANCE -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_INACTIF);

					EtatVentillation	= Etat_INACTIF;
					EtatChauffage		= Etat_INACTIF;

					TSW_Start(&Tmr_ATTENTE, 1000 * 30); // On reste au moins 30sec en mode attente
				}

				if (TSW_IsRunning(&Tmr_ATTENTE) == TRUE)
				{
					break;
				}

				// Pas de chauffage dessuite après l'extraction
				if ((TSW_IsRunning(&Tmr_EXT) == FALSE)
				&&	(Temperature < Chauffage_Get()->Cfg_SeuilStart_DegC))
				{
					Mode = MODE_CHAUFFAGE;
				}

				// Pas d'extraction dessuite après le chauffage
				if ((TSW_IsRunning(&Tmr_CH) == FALSE)
				&&	(Temperature >= Ventilation_Get()->Cfg_SeuilStart_DegC))
				{
					Mode = MODE_VENTILLATION;
				}

				break;


			//--------------------------------------------------------------
			case MODE_CHAUFFAGE :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_CHAUFFAGE -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_INACTIF);

					if (Ventilation_Get()->Cfg_ActiverPendantChauffage)
						EtatVentillation = Etat_ACTIF;
					else
						EtatVentillation = Etat_INACTIF;
					EtatChauffage = Etat_ACTIF;
				}

				// Attente franchissement seuil
			if (Temperature >= Chauffage_Get()->Cfg_SeuilStop_DegC)
				{
					EtatChauffage = Etat_INACTIF;

					TSW_Start(&Tmr_CH, 1000 * Chauffage_Get()->Cfg_TempoApresCh_s);
					Mode = MODE_SURVEILLANCE;
				}

				break;

			//--------------------------------------------------------------
			case MODE_VENTILLATION :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_VENTILLATION -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_ACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_INACTIF);

					EtatChauffage = Etat_INACTIF;
					EtatVentillation = Etat_ACTIF;
				}

				if (Temperature < Ventilation_Get()->Cfg_SeuilStop_DegC)
				{
					EtatVentillation = Etat_INACTIF;

					TSW_Start(&Tmr_EXT, 1000 * Ventilation_Get()->Cfg_TempoApresEXT_s);
					Mode = MODE_SURVEILLANCE;
				}

				break;

			//--------------------------------------------------------------
			case MODE_DEFAUT :

				if (NouveauMode)
				{
					_CONSOLE(LogId, "----- MODE_DEFAUT -----\n");
					Logs_Data();

					GPIO_Set(PORT_IHM_LED1, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED2, Etat_INACTIF);
					GPIO_Set(PORT_IHM_LED3, Etat_ACTIF);

					EtatVentillation 	= Etat_INACTIF;
					EtatChauffage		= Etat_INACTIF;
					//Arrosage_Stop();

					TSW_Start(&Tmr_DEFAULT, 60 * 1000);
					TSW_Start(&Tmr_DEFAULT_Max, 600 * 1000);
				}

				if (TempHygro_IsValide() == TRUE)
				{
					Mode = MODE_VENTILLATION;
					break;
				}

				if ((TSW_IsRunning(&Tmr_DEFAULT) == FALSE)
				&&	(REBOOT_ON_DEFAULT_MODE == TRUE)
				&&	(Arrosage_IsActive() == FALSE))
				{
					if ((Telnet_GetNbActiveConnection() == 0)
					||	(TSW_IsRunning(&Tmr_DEFAULT_Max) == FALSE))
					{
						_CONSOLE(LogId, "REBOOT...\n");
						MemoireFAT_DeInit();
						TSW_Delay(5000);
						GOTO(0);
						Mode = MODE_DEMARRAGE;
					}
				}
				break;

		}

		//----------------------------------
		// MAJ DES SORTIES
		if (GPIO_Get(PORT_RELAIS_V_EXT) != EtatVentillation)
		{
			_CONSOLE(LogId, "Ventillation = %d\n", EtatVentillation);
			GPIO_Set(PORT_RELAIS_V_EXT, EtatVentillation);
			Logs_Data();
		}
		if (GPIO_Get(PORT_RELAIS_CH) != EtatChauffage)
		{
			_CONSOLE(LogId, "Chauffage = %d\n", EtatChauffage);
			GPIO_Set(PORT_RELAIS_CH, EtatChauffage);
			Logs_Data();
		}
	}

	return 0;

}


/*------------------------------------------------------------------------------------------------*/
extern void SdCard_SPI_timerproc (void);

void ApplicationTickHook (void) {

	static uint8_t ucTick_10ms=0;
	static uint8_t ucTick_100ms=0;


	/* Gestion du Tick Timer Software */
	TSW_Refresh();

	/* Tick 10ms */
	ucTick_10ms++;
	if (ucTick_10ms >= 10){
		ucTick_10ms = 0;
		ADC1_Tick();
		SdCard_SPI_timerproc();
	}

	/* Tick 100ms */
	ucTick_100ms++;
	if (ucTick_100ms >= 10){
		ucTick_100ms = 0;

	}
}


/*------------------------------------------------------------------------------------------------*/
void Delay(uint32_t nCount)
{
  /* Capture the current local time */
  uint32_t timingdelay = TSW_GetTimestamp_ms() + nCount;

  /* wait until the desired delay finish */
  while(timingdelay > TSW_GetTimestamp_ms())
  {
  }
}