#include "vic.h"
#include "app.h"
#include "uart0_irq.h"
#include "stdio_uc.h"

static void showVicError(int n) {
	irq_Disable();

	static int x;
	if (n>10) n=10;
	while(1) {
		for (x=0;x<n;x++) {
			ledERROR_On();
			#if (useBEEP == pdON)
			buzzer_On();
			#endif
			delay_ms(250);
			ledERROR_Off();
			#if (useBEEP == pdON)
			buzzer_Off();
			#endif
			delay_ms(250);
		}
		delay_ms(1000);
	}
}

// Esta função está sendo chamada a cada 1ms
static void call_System(void) {
//	tpOn();
	control.countTicks++;

	app_Tick();
	led_Tick();

	#if (useSERVOS == pdON)
	servo_Tick();
	#endif

	#if (useBEEP == pdON)
	beep_Tick();
	#endif

	#if (useKEYS == pdON)
	key_Tick();
	#endif

	#if (useRELAYS == pdON)
	relay_Tick();
	#endif

	#if (useDISPLAY7SEG == pdON)
	visor_Tick();
	#endif

	#if (useKEYS == pdON)
	gKey_Tick();
	#endif

	#if (useADC == pdON)
	analogic_Tick();
	#endif

	#if (USES_MODBUS ==	pdON)
	modbus_SlaveTick();
	#endif

//	tpOff();
}

int main(void) {
	nvic_SetIntHandler(showVicError);
	control.countTicks = 0;

	#if (useDISPLAY7SEG == pdON)
	control.visor.type = visorNONE;
	#endif

	// NÃO USAR UART COM INTERRUPÇÃO PARA O LOG, POIS CONSTANTEMENTE A
  	// POSIÇÃO DOS VETORES DE INTERRUPÇÕES COM O USO DO BOOTLOADER

  	// REGISTRANDO AS ENTRADAS E SAÍDAS PADRÃO AOS SEUS RESPECTIVOS DISPOSTIVOS
	// PORTA PARA CLI DEVE SER COM INTERRUPÇÃO
  	lgetchar_RegisterDev(uart0_GetChar);
	lputchar_RegisterDev(uart0_PutChar);
	ldebug_RegisterDev(uart0_BasicPutChar);
	uart0_Init(115200);

//	tpInit();
	led_Init();
	systime_Init();
	systime_SetIntHandler(call_System, 1); // Chamar o a função callsystem a cada 1ms OBS: Levando em consideração o SYSTIME_IRQ_TICK_DIV

	#if (useSSP1 == pdON)
	ssp1_Init(SSP1_MASTER, SSP1_STANDARD); // inicar o barramento SPI a 400Khz
	#endif

	#if (useBEEP == pdON)
	beep_Init();
	#endif

	#if (useKEYS == pdON)
	gKey_Init(&onKeyDown, &onKeyPress, &onKeyUp);	// Anexar os eventos do teclado
	key_Init();
	#endif

	#if (useRELAYS == pdON)
	relay_Init();
	#endif

	#if (useSERVOS == pdON)
	servo_Init();
	#endif

	#if (useADC == pdON)
	analogic_Init();
	#endif

	#if (useACS71X == pdON)
	acx71x_Init(ampMODULE1, 185, 10000, 10000);
		// os resistores de 10K não foi considerado a sua precisão porque estamos usando a fórmula linear de calibração
	#endif

	#if (useDAC == pdON)
	da_Init();
	#endif

	#if (useDISPLAY7SEG == pdON)
	visor_Init(visor7SEGMENTS);
	#endif

	#if (useEEPROM == pdON)
	ee25xx_Init();
	#endif

	#if (USES_MODBUS == pdON)
	// ATENÇÃO: Iniciar ModBUS tem que ser depois das leituras dos parametros na eeprom
	modbus_Init(1, 57600);
	#endif


	irq_Enable(); 	// Habilitar interrupções

	app_Init();
	lprintf(CMD_TERMINATOR);
	lprintf(PROGAM_NAME);
	lprintf("ucLibc version "__VERSION CMD_TERMINATOR);

	visor_7SegMsg("INIT");
	while (1) {
		prompt_Process();
		app_Process();

		#if (useADC == pdON)
		analogic_Process();
		#endif

		#if (useKEYS == pdON)
		gKey_Process(control.keyboard);
		#endif

		#if (USES_MODBUS == pdON)
		modbus_SlaveProcess();
		#endif
	}

	return (0);
}
