//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#ifdef F_CPU
#undef F_CPU
#endif
#define F_CPU 16000000UL
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <Arduino.h>
#include "IdiBusSerialLine.h"
#include "IDIBUS_4DC.h"
#include "IDIBUS_4ADC.h"
#include "IDIBUS_4CNT.h"
#include "IDIBUS_1Wire.h"
#include "IDIBUS_3Thermo1HT.h"
#include "IDIBUS_Speedster.h"
#include "IDIBUS_1xGen.h"
#include "MBOARD_POWER.h"
#include <avr/wdt.h>

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//IDIBUS MASTER V0.26 beta
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IdiBusSerialLine Serial_Line0;
IdiBusSerialLine Serial_Line1;
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup()
{
 MBOARD_POWER_OFF_ON();
 delay(50);		//	Power on delay for external periphery
 
 //Arduino Variant
 IDIBUS_SERIAL_INIT_TYPEDEF L0Init;
 L0Init.USART_NUMBER  = IDIBUS_SERIAL_USART2;	//	select USART
 L0Init.TIMER_NUMBER  = IDIBUS_TIMER_1;			//	select timer 
 L0Init.CONFIG        = IDIBUS_SERIAL_8N2;		//	8 bit, 2 stop
 L0Init.RS485_DIR_PIN         = 6;				//	direction pin in-out
 L0Init.BAUDRATE_DIPSW_S0_PIN = 9;				//	speed selector pins
 L0Init.BAUDRATE_DIPSW_S1_PIN = 8;
 L0Init.BAUDRATE_DIPSW_S2_PIN = 7;
 Serial_Line0.Init(&L0Init);					//	Init line with with config above	
 Serial_Line0.UpdateBaudrateFromDipSwitch();	//	speed setup
 Serial_Line0.Start();							//	run!
 
 // Standard pinout variant
 IDIBUS_SERIAL_ALTERNATIVE_INIT_TYPEDEF L1Init;
 L1Init.USART_NUMBER  = IDIBUS_SERIAL_USART1;
 L1Init.TIMER_NUMBER  = IDIBUS_TIMER_3;
 L1Init.CONFIG        = IDIBUS_SERIAL_8N2;
 L1Init.RS485_DIR_GPIO.PORT       = &PORTL;
 L1Init.RS485_DIR_GPIO.PIN_NUM    = 6;
 L1Init.BAUDRATE_DIPSW.S0.PORT    = &PORTD;
 L1Init.BAUDRATE_DIPSW.S0.PIN_NUM = 1;
 L1Init.BAUDRATE_DIPSW.S1.PORT    = &PORTD;
 L1Init.BAUDRATE_DIPSW.S1.PIN_NUM = 0;
 L1Init.BAUDRATE_DIPSW.S2.PORT    = &PORTL;
 L1Init.BAUDRATE_DIPSW.S2.PIN_NUM = 7;
 Serial_Line1.Init(&L1Init);
 Serial_Line1.UpdateBaudrateFromDipSwitch();
 Serial_Line1.Start();
 
 //Serial.begin(115200,SERIAL_8N2);	//	usart0 for debug
 
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 //	Enable power out 24V on main board (to slaves)
 //#define BAUD 16000000UL/16/250000UL-1		// BAUD speed = 250000 bod	
 //UBRR3 = (uint16_t)(BAUD);			//	USART BAUD RATE INIT
 //UCSR3B = (1<<RXEN3)|(1<<TXEN3);	//	USART ENABLE TX RX
 //while (!(UCSR3A & (1<<UDRE3)));	//	wait for send
 //UDR3 = 'R';						//	send 'R'
 //while (!(UCSR3A & (1<<UDRE3)));	//	wait for send
 //UDR3 = '+';						//  send '+'
 //delay(500);						//	Power on delay for external periphery
 
 volatile uint8_t ErrorCode;		//	buffer for error codes
 IdiBusLongOpData LopData;			//	Long operation data (not used in current example)
 Inputs Settings;
 
 IdiBus_1xGen TEMP(&Serial_Line0, 2);
 ErrorCode = TEMP.c_Init();
 delay(1000);
 
 Settings.first_mode_time = 1;
 Settings.first_mode_pwm_value = 40000;
 Settings.first_mode_f = 40;
 Settings.first_mode_invert = 1;  // 0 || 1
 
 Settings.second_mode_time = 1;
 Settings.second_mode_pwm_value = 20000;
 Settings.second_mode_f = 60;
 Settings.second_mode_invert = 1;  // 0 || 1
 
 uint8_t TxData[10] = {Settings.first_mode_time,
	 (uint8_t)((Settings.first_mode_pwm_value >> 8) & 0xFF), (uint8_t)(Settings.first_mode_pwm_value & 0xFF),
	 Settings.first_mode_f, Settings.first_mode_invert,
	 Settings.second_mode_time,
	 (uint8_t)((Settings.second_mode_pwm_value >> 8) & 0xFF), (uint8_t)(Settings.second_mode_pwm_value & 0xFF),
 Settings.second_mode_f, Settings.second_mode_invert};

 TEMP.start_SPI(TxData);
 //TEMP.reset_STM();
 
 Serial_Line1.UpdateBaudrateFromDipSwitch();
 Serial_Line0.UpdateBaudrateFromDipSwitch();
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void loop() {}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint8_t MBOARD_POWER_SET(uint8_t juction, uint8_t set)	//	power channel ON/OFF
{
	Serial3.begin(115200,SERIAL_8N1);	//	usart3 for 328pb on MBoard
	uint8_t string[2];
	if((juction==MBOARD_POWER_J89_05V)&&(set==MBOARD_POWER_ON))
	{
		Serial3.print("5+"); delay(10);
		Serial3.readBytes(string, 2);
		if((string[0]=='O')&&(string[1]=='K')) return MBOARD_POWER_OK;
	}
	else if((juction==MBOARD_POWER_J89_05V)&&(set==MBOARD_POWER_OFF))
	{
		Serial3.print("5-"); delay(10);
		Serial3.readBytes(string, 2);
		if((string[0]=='O')&&(string[1]=='K')) return MBOARD_POWER_OK;
	}
	else if((juction==MBOARD_POWER_J89_24V)&&(set==MBOARD_POWER_ON))
	{
		Serial3.print("J+"); delay(10);
		Serial3.readBytes(string, 2);
		if((string[0]=='O')&&(string[1]=='K')) return MBOARD_POWER_OK;
	}
	else if((juction==MBOARD_POWER_J89_24V)&&(set==MBOARD_POWER_OFF))
	{
		Serial3.print("J-"); delay(10);
		Serial3.readBytes(string, 2);
		if((string[0]=='O')&&(string[1]=='K')) return MBOARD_POWER_OK;
	}
	else if((juction==MBOARD_POWER_J67_24V)&&(set==MBOARD_POWER_ON))
	{
		Serial3.print("R+"); delay(10);
		Serial3.readBytes(string, 2);
		if((string[0]=='O')&&(string[1]=='K')) return MBOARD_POWER_OK;
	}
	else if((juction==MBOARD_POWER_J67_24V)&&(set==MBOARD_POWER_OFF))
	{
		Serial3.print("R-"); delay(10);
		Serial3.readBytes(string, 2);
		if((string[0]=='O')&&(string[1]=='K')) return MBOARD_POWER_OK;
	}
	while(Serial3.available()>0) string[0]=Serial3.read();
	return MBOARD_POWER_ERR;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void MBOARD_POWER_OFF_ON(void)	//	выключение, пауза и последовательное включение всех питаний
{
	MBOARD_POWER_SET(MBOARD_POWER_J89_05V, MBOARD_POWER_OFF);
	MBOARD_POWER_SET(MBOARD_POWER_J89_24V, MBOARD_POWER_OFF);
	MBOARD_POWER_SET(MBOARD_POWER_J67_24V, MBOARD_POWER_OFF);
	delay(1000);wdt_reset();
	MBOARD_POWER_SET(MBOARD_POWER_J89_05V, MBOARD_POWER_ON);
	delay(500);wdt_reset();
	MBOARD_POWER_SET(MBOARD_POWER_J89_24V, MBOARD_POWER_ON);
	delay(500);wdt_reset();
	MBOARD_POWER_SET(MBOARD_POWER_J67_24V, MBOARD_POWER_ON);
	delay(1000);wdt_reset();
	return;
}