#include "config.h"

#include "System.h"
#include "boot.h"
#include "USART1.h"
#include "RSLink.h"

#include <avr/fuse.h>
FUSES={ .extended=F_Ext, .high = F_High, .low = F_Low };				//	Fuses + Lock programming
LOCKBITS=F_Lock;

int main(void)
{
	//FUSE CHECK
	asm volatile (
		"ldi	R31,	0x00	\n\t"
		"ldi	R30,	0x01	\n\t"
		"ldi	R16,	0x09	\n\t"
		"out	0x37,	R16		\n\t"
		"lpm	R17,	Z		\n\t"
		"cpi	R17,	%0		\n\t"
		"brne	L_LOOP_%=		\n\t"
		//	Fuse Extended
		"ldi	R30,	0x02	\n\t"
		"out	0x37,	R16		\n\t"
		"lpm	R17,	Z		\n\t"
		"cpi	R17,	%1		\n\t"
		"brne	L_LOOP_%=		\n\t"
		//	Fuse Low Byte
		"ldi	R30,	0x00	\n\t"
		"out	0x37,	R16		\n\t"
		"lpm	R17,	Z		\n\t"
		"cpi	R17,	%2		\n\t"
		"brne	L_LOOP_%=		\n\t"
		//	Fuse Hi Byte
		"ldi	R30,	0x03	\n\t"
		"out	0x37,	R16		\n\t"
		"lpm	R17,	Z		\n\t"
		"cpi	R17,	%3		\n\t"
		"breq	L_EXIT_%=		\n\t"
		"L_LOOP_%=:				\n\t"
		"rjmp	L_LOOP_%=		\n\t"
		"L_EXIT_%=:				\n\t"
		: //No output
		: "M" (F_Lock),	
		  "M" (F_Ext),	
		  "M" (F_Low),	
		  "M" (F_High)	
	);	

	wdt_enable(WDTO_2S);
	wdt_reset();

	//Move interrupt table
	uint8_t temp = MCUCR;
	MCUCR=temp|(1<<IVCE);
	MCUCR=temp|(1<<IVSEL);

	USART1_Init();

	RSLink_Init();

	FindBootloaderEnterReason();	//Do checks
	wdt_reset();

	if (BootloaderInfo.Reason == IDIFMW_REASON_NoReason)	LaunchApplication(); 

	BootloaderInfo.BlockNumber = -1;	//Find Better Place!!
	AES_DISABLED = 0;

	sei();

    while (1) 
    {
		RSLink_Handler();
		wdt_reset();
    }
}

