/****************************************************************************
 Title	:	TERMINAL FOR VISUALIZATION AND CONTROL CONDITIONS IN HOUSE
 Author	:	Patrik Szalay <xszala01@stud.feec.vutbr.cz>
 File	:	serial.c
 Software:	CodeWarrior Development Studio Version: 10.6 Build Id:140329
 Target	:	MC9S08LH64

 DESCRIPTION
       Code for the serial interface

 USAGE
       
*****************************************************************************/
#include "serial.h"

unsigned int SCIdataTransfering, SCIbytesToSend, SCIbytesSent, SCIbytesReceiving = 0, SCI_BytesReceived = 0, lastMessageBytesCount = 0;
byte *SCIdatabuffer;
byte SCIMessage[SCI_BUFFER_LENGHT];
byte SCI_RxDataBuffer[SCI_BUFFER_LENGHT], lastMessage[SCI_BUFFER_LENGHT];
SCISSTR volatile SCIS;
ADDRESS ANSAddress, connectedAddress[2], ACKAddress;
SCIRegAddress ACKRegAddress;
byte SCIACKRQ_TOut = 0;


void InitSCI(void) {

	/*SCI1BD = baud;*/
	/* SCI1C1: LOOPS=0,SCISWAI=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */
	SCI1C1 = 0x04;               /* Configure the SCI */
	/* SCI1C3: R8=0,T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */
	SCI1C3 = 0x00;               /* Disable error interrupts */
	/* SCI1S2: LBKDIF=0,RXEDGIF=0,??=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */
	SCI1S2 = 0x00;
	/* SCI1C2: TIE=0,TCIE=0,RIE=0,ILIE=0,TE=0,RE=0,RWU=0,SBK=0 */
	SCI1C2 = 0x00;               /* Disable all interrupts */
	//SCI1S2_BRK13 = 1;
	//SCI1S2_LBKDE = 1;
	SCI1BDH = 0x00;              /* Set high divisor register (enable device) */
	SCI1BDL = SCIBD_BD_14400;   /* Set low divisor register (enable device) */
	//SCI1C2_TE = 0x01;            /* Enable transmitter */
	SCI1C2_RE = 0x01;            /* Enable receiver */
	SCI1C2_RIE = 0x01;

}

void SCITransmit(unsigned int bytes, char* ptr){
	SCIbytesToSend = bytes;
	SCIbytesSent = 0;
	SCIS_SCISDTX = true;
	SCIdatabuffer = ptr;
	SCI1C2_RIE = 0;
	if (SCIbytesSent < SCIbytesToSend){
		SCI1C2_TE = 1;
		SCI1D = *SCIdatabuffer;
		SCI1C2_TIE = 1;
		SCIbytesSent++;
	}

	while (SCIS_SCISDTX) __RESET_WATCHDOG();
	SCI1C2_TIE = 0;
	SCI1C2_RIE = 1;

}

void SCIRead(void)
{
	byte headerBuffer[6], dataBytes, registerAddress, task, dataBuffer[SCI_BUFFER_LENGHT - 6];
	ADDRESS srcAddress;
	bool useData = false;
	__RESET_WATCHDOG();
	(void)memcpy(headerBuffer, &SCI_RxDataBuffer, 6 * sizeof(*SCI_RxDataBuffer));
	if (headerBuffer[0] == LOCAL_TERM_ADDR)
	{
		if (CRC(headerBuffer, 5) == headerBuffer[5])
		{
			srcAddress = headerBuffer[1];
			task = headerBuffer[2];
			registerAddress = headerBuffer[3] - nullvalue;
			dataBytes = headerBuffer[4] - nullvalue;
			switch (task)
			{
			case NA: break;
			case RING: SCIRingACK(srcAddress); break;
			case ACK: SCIACKCheck(srcAddress, registerAddress); break;
			case NACK: SCIRetransmit(); break;
			case RTX: SCIRetransmit(); break;
			case ERR: break;
			case GET: SCISendMeas(srcAddress, registerAddress); break;
			case SET: useData = true; break;
			case ANS: useData = true; break;
			case RST: SCIResetSyst(srcAddress); break;
			case LOCK: SCIDisconnect(srcAddress); break;
			case DISCONN: break;
			case SERGET: useData = true; break;
			case SERANS: useData = true; break;
			case SERSET: useData = true; break;
			default: SCISendERR(srcAddress, registerAddress); break;
			}
			if (dataBytes != 0 && useData)
			{
				(void)memcpy(dataBuffer, &SCI_RxDataBuffer[6], (SCI_BUFFER_LENGHT - 6) * sizeof(*SCI_RxDataBuffer));
				if (CRC(dataBuffer, dataBytes) == dataBuffer[dataBytes])
				{
					switch (task)
					{
					case SET: SCISet(srcAddress, registerAddress, dataBuffer); break;
					case ANS: break;
					case SERGET: SCISerGet(srcAddress, dataBytes, dataBuffer); break;
					case SERANS: break;
					case SERSET: SCISerSet(srcAddress, dataBytes, dataBuffer); break;
					default: break;
					}
				}
				else
				{
					SCIRTX(srcAddress, registerAddress);
				}
			}
		}
	}
	SCIS_SCISDRX = 0;
}

void SCISendMessage(ADDRESS address, byte task, SCIRegAddress regAddress, byte bytes, byte *data)
{
	int i = 0;
	SCIMessage[0] = address;
	SCIMessage[1] = LOCAL_TERM_ADDR;
	SCIMessage[2] = task;
	SCIMessage[3] = (byte)regAddress;
	SCIMessage[4] = bytes;
	SCIMessage[5] = CRC(SCIMessage, 5);
	for (i = 0; i < bytes; i++)
	{
		SCIMessage[6 + i] = data[i];
	}
	if (bytes > 0)
	{
		SCIMessage[6 + i] = CRC(data, bytes);
		bytes++;
	}

	(void)memcpy(lastMessage, &SCIMessage[0], SCI_BUFFER_LENGHT * sizeof(*SCIMessage));
	lastMessageBytesCount = 6 + bytes;
	//Num_aux(lastMessageBytesCount);
	SCITransmit(6 + bytes, SCIMessage);

}

byte CRC(byte* message, byte length){
	byte ans = message[0];
	int i;
	for (i = 1; i < length; i++)
	{
		ans ^= message[i];
	}
	return ans;


}

void SCIRingACK(ADDRESS srcAddress)
{
	SCIS_SCISACKRQ = false;
	SCISendMessage(srcAddress, ACK, 0, 0, NULL);
	if (connectedAddress[0] != srcAddress && connectedAddress[1] != srcAddress)
	{
		if (connectedAddress[0] == 0x00)
		{
			if (connectedAddress[0] != srcAddress) connectedAddress[0] = srcAddress;
		}
		else
		{
			if (connectedAddress[1] != srcAddress) connectedAddress[1] = srcAddress;
		}
	}
	SCIS_SCISCONN = 1;
	lcd_Bcklght_on();
	//Write_string("CON",1); 
	SCIS_SCISACK = 1;

}

void SCIACK(ADDRESS srcAddress, SCIRegAddress reg)
{
	SCISendMessage(srcAddress, ACK, reg, 0, NULL);
	SCIS_SCISACK = 1;
	SCIS_SCISACKRQ = false;
}

void ConvertValueToMessage(char *res, decimal value)
{
	res[0] = (char)((value > -100) ? ((int)value / 100) : (256 - abs((int)value / 100)));
	res[1] = (char)(value >= 0) ? (labs((int)value % 100)) : (256 - labs((int)value % 100));
}

void SCISendMeas(ADDRESS dstAddress, SCIRegAddress device)
{
	byte SCIMessage[SCI_BUFFER_LENGHT];
	decimal value;
	if (SCIConnCheck(dstAddress))
	{
		if (device >= LM75_1 && device <= HTU21D_HUM)
		{
			value = measure(device);
			if (value != IIC_INVALID_DATA && value != CRC_ERR && value != MEAS_ERROR)
			{
				ConvertValueToMessage(SCIMessage, value);
				SCISendMessage(dstAddress, ANS, device, 2, SCIMessage);
			}
			else
			{
				SCISendERR(dstAddress, device);
			}
		}
		else if (device >= SYST_TYPE && device <= PUMP_DELAY_TIME)
		{
			switch (device)
			{
			case SYST_TYPE: SCIMessage[0] = (byte)getSystType(); break;
			case HEATER: SCIMessage[0] = (byte)getHeater_State(); break;
			case PUMP: SCIMessage[0] = (byte)getPump_State(); break;
			case AUTOSW: SCIMessage[0] = (byte)getAutoSwitchingState(); break;
			case DAY_START_TIME: SCIMessage[0] = (byte)getDayTempStart(); break;
			case DAY_END_TIME: SCIMessage[0] = (byte)getDayTempEnd(); break;
			case PUMP_DELAY_TIME: SCIMessage[0] = (byte)getPumpDelayTime(); break;
			default: break;
			}
			SCISendMessage(dstAddress, ANS, device, 1, SCIMessage);
		}
		else if (device >= ROOM_TEMP && device <= OFF_AVG_TEMP)
		{
			switch (device)
			{
			case ROOM_TEMP: ConvertValueToMessage(SCIMessage, getRoom_Temp()); break;
			case WATER_OUT_TEMP: ConvertValueToMessage(SCIMessage, getWater_Out_Temp()); break;
			case WATER_RETURN_TEMP: ConvertValueToMessage(SCIMessage, getWater_Return_Temp()); break;
			case AVG_TEMP: ConvertValueToMessage(SCIMessage, getAverageTemp()); break;
			case OUTDOOR_TEMP: ConvertValueToMessage(SCIMessage, getOutDoor_Temp()); break;
			case OUTDOOR_HUM: ConvertValueToMessage(SCIMessage, getOutDoor_Hum()); break;
			case REGULATE_DAY_TEMP: ConvertValueToMessage(SCIMessage, getRegulateToDayTemp()); break;
			case REGULATE_NIGHT_TEMP: ConvertValueToMessage(SCIMessage, getRegulateToNightTemp()); break;
			case REGULATE_TEMP_HYST: ConvertValueToMessage(SCIMessage, getRegulationHyst()); break;
			case REGULATE_WATER_MAX_TEMP: ConvertValueToMessage(SCIMessage, getRegulateToMaxWaterTemp()); break;
			case REGULATE_WATER_DIFF: ConvertValueToMessage(SCIMessage, getWaterDiff()); break;
			case ON_AVG_TEMP: ConvertValueToMessage(SCIMessage, getOnAverageTemp()); break;
			case OFF_AVG_TEMP: ConvertValueToMessage(SCIMessage, getOffAverageTemp()); break;
			default: break;
			}
			SCISendMessage(dstAddress, ANS, device, 2, SCIMessage);
		}
		else
		{
			SCISendERR(dstAddress, device);
		}
		//Write_string("MEA",1);
		SCIACKRQ(dstAddress, device);
	}
	else
	{
		SCIForbidden(dstAddress, device);
	}


}

void SCISerGet(ADDRESS dstAddress, byte regCount, byte *dataBuffer)
{
	byte SCIMessage[SCI_BUFFER_LENGHT], valueMessage[2];
	decimal value;
	byte device;
	bool error = false;
	byte i, pos = 0;
	if (SCIConnCheck(dstAddress))
	{
		for (i = 0; i < regCount; i++)
		{
			device = dataBuffer[i];
			SCIMessage[pos++] = device;
			if (device >= LM75_1 && device <= HTU21D_HUM)
			{
				value = measure(device);
				if (value != IIC_INVALID_DATA && value != CRC_ERR && value != MEAS_ERROR)
				{
					ConvertValueToMessage(valueMessage, value);
					SCIMessage[pos++] = valueMessage[0];
					SCIMessage[pos++] = valueMessage[1];
				}
				else
				{
					SCISendERR(dstAddress, device);
					error = true;
					break;
				}
			}
			else if (device >= SYST_TYPE && device <= PUMP_DELAY_TIME)
			{
				switch (device)
				{
				case SYST_TYPE: SCIMessage[pos++] = (byte)getSystType(); break;
				case HEATER: SCIMessage[pos++] = (byte)getHeater_State(); break;
				case PUMP: SCIMessage[pos++] = (byte)getPump_State(); break;
				case AUTOSW: SCIMessage[pos++] = (byte)getAutoSwitchingState(); break;
				case DAY_START_TIME: SCIMessage[pos++] = (byte)getDayTempStart(); break;
				case DAY_END_TIME: SCIMessage[pos++] = (byte)getDayTempEnd(); break;
				case PUMP_DELAY_TIME: SCIMessage[pos++] = (byte)getPumpDelayTime(); break;
				default: break;
				}
			}
			else if (device >= ROOM_TEMP && device <= OFF_AVG_TEMP)
			{
				switch (device)
				{
				case ROOM_TEMP: ConvertValueToMessage(valueMessage, getRoom_Temp()); break;
				case WATER_OUT_TEMP: ConvertValueToMessage(valueMessage, getWater_Out_Temp()); break;
				case WATER_RETURN_TEMP: ConvertValueToMessage(valueMessage, getWater_Return_Temp()); break;
				case AVG_TEMP: ConvertValueToMessage(valueMessage, getAverageTemp()); break;
				case OUTDOOR_TEMP: ConvertValueToMessage(valueMessage, getOutDoor_Temp()); break;
				case OUTDOOR_HUM: ConvertValueToMessage(valueMessage, getOutDoor_Hum()); break;
				case REGULATE_DAY_TEMP: ConvertValueToMessage(valueMessage, getRegulateToDayTemp()); break;
				case REGULATE_NIGHT_TEMP: ConvertValueToMessage(valueMessage, getRegulateToNightTemp()); break;
				case REGULATE_TEMP_HYST: ConvertValueToMessage(valueMessage, getRegulationHyst()); break;
				case REGULATE_WATER_MAX_TEMP: ConvertValueToMessage(valueMessage, getRegulateToMaxWaterTemp()); break;
				case REGULATE_WATER_DIFF: ConvertValueToMessage(valueMessage, getWaterDiff()); break;
				case ON_AVG_TEMP: ConvertValueToMessage(valueMessage, getOnAverageTemp()); break;
				case OFF_AVG_TEMP: ConvertValueToMessage(valueMessage, getOffAverageTemp()); break;
				default: break;
				}
				SCIMessage[pos++] = valueMessage[0];
				SCIMessage[pos++] = valueMessage[1];
			}
			else
			{
				SCISendERR(dstAddress, device);
				error = true;
				break;
			}

		}
		if (!error)
		{
			SCISendMessage(dstAddress, SERANS, SERIALIZED, pos, SCIMessage);
			SCIACKRQ(dstAddress, SERIALIZED);
		}
	}
}

void SCISerSet(ADDRESS dstAddress, byte bytesCount, byte *dataBuffer)
{
	byte valueMessage[2], timeMessage[7];
	decimal value;
	byte device;
	bool error = false;
	byte pos = 0;
	if (SCIConnCheck(dstAddress))
	{
		while (pos < bytesCount)
		{
			device = dataBuffer[pos++];
			if (device >= LM75_1 && device <= HTU21D_HUM)
			{
				SCISendERR(dstAddress, device);
				error = true;
				break;
			}
			else if (device >= SYST_TYPE && device <= PUMP_DELAY_TIME)
			{
				switch (device)
				{
				case SYST_TYPE: setSystType((bool)dataBuffer[pos++]); break;
				case HEATER: setHeater_State((bool)dataBuffer[pos++]); break;
				case PUMP: setPump_State((bool)dataBuffer[pos++]); break;
				case AUTOSW: setAutoSwitchingState((bool)dataBuffer[pos++]); break;
				case DAY_START_TIME: setDayTempStart((int)dataBuffer[pos++]); break;
				case DAY_END_TIME: setDayTempEnd((int)dataBuffer[pos++]); break;
				case PUMP_DELAY_TIME: setPumpDelayTime((int)dataBuffer[pos++]); break;
				default: break;
				}
			}
			else if (device >= ROOM_TEMP && device <= OFF_AVG_TEMP)
			{
				valueMessage[0] = dataBuffer[pos++];
				valueMessage[1] = dataBuffer[pos++];
				value = ConvertDataToDecimalValue(valueMessage);
				switch (device)
				{
				case ROOM_TEMP: setRoom_Temp(value); break;
				case WATER_OUT_TEMP: setWater_Out_Temp(value); break;
				case WATER_RETURN_TEMP: setWater_Return_Temp(value); break;
				case AVG_TEMP: setAVGTemp(value); break;
				case OUTDOOR_TEMP: setOutDoor_Temp(value); break;
				case OUTDOOR_HUM: setOutDoor_Hum(value); break;
				case REGULATE_DAY_TEMP: setRegulateToDayTemp(value); break;
				case REGULATE_NIGHT_TEMP: setRegulateToNightTemp(value); break;
				case REGULATE_TEMP_HYST: setRegulationHyst(value); break;
				case REGULATE_WATER_MAX_TEMP: setRegulateToMaxWaterTemp(value); break;
				case REGULATE_WATER_DIFF: setWaterDiff(value); break;
				case ON_AVG_TEMP: setOnAverageTemp(value); break;
				case OFF_AVG_TEMP: setOffAverageTemp(value); break;
				default: break;
				}

			}
			else if (device == CLOCK)
			{
				timeMessage[0] = dataBuffer[pos++];
				timeMessage[1] = dataBuffer[pos++];
				timeMessage[2] = dataBuffer[pos++];
				timeMessage[3] = dataBuffer[pos++];
				timeMessage[4] = dataBuffer[pos++];
				timeMessage[5] = dataBuffer[pos++];
				timeMessage[6] = dataBuffer[pos++];
				setClock(timeMessage);
			}
			else
			{
				SCISendERR(dstAddress, device);
				error = true;
				break;
			}

		}
		if (!error)
		{
			SCIACK(dstAddress, SERIALIZED);
		}
	}
}

void SCISendERR(ADDRESS dstAddress, SCIRegAddress reg)
{
	//Write_string("ERR",1);
	SCISendMessage(dstAddress, ERR, reg, 0, NULL);
	SCIACKRQ(dstAddress, reg);
}

void SCIForbidden(ADDRESS dstAddress, SCIRegAddress reg)
{
	//Write_string("AUTH",1);
	SCISendMessage(dstAddress, FORBIDDEN, reg, 0, NULL);
}

void SCIRetransmit(void)
{

	//Write_string("RTX",1);
	SCITransmit(lastMessageBytesCount, lastMessage);
	SCIACKRQ(lastMessage[0], lastMessage[3]);
}

void SCIRTX(ADDRESS srcAddress, SCIRegAddress reg)
{
	SCIResetTimeOut();
	SCISendMessage(srcAddress, RTX, reg, 0, NULL);

}

void SCIResetTimeOut(void)
{
	SCIACKRQ_TOut = 0;
}
void SCIDisconnect(ADDRESS srcAddress)
{
	if (connectedAddress[0] != srcAddress && connectedAddress[1] != srcAddress)
	{
		SCISendMessage(srcAddress, FORBIDDEN, 0, 0, NULL);
	}
	else
	{
		if (connectedAddress[0] == srcAddress) connectedAddress[0] = 0x00;
		if (connectedAddress[1] == srcAddress) connectedAddress[1] = 0x00;
		SCISendMessage(srcAddress, DISCONN, 0, 0, NULL);
		SCIS_SCISCONN = false;
		SCIS_SCISACKRQ = false; 
	}

}

void SCIResetSyst(ADDRESS srcAddress)
{
	if (SCIConnCheck(srcAddress))
	{
		SCIDisconnect(srcAddress);
		if (!SCIS_SCISCONN)
		{
			lcd_Bcklght_on();
			restart();
		}
	}
}

bool SCIConnCheck(ADDRESS srcAddress)
{
	if (connectedAddress[0] == srcAddress || connectedAddress[1] == srcAddress) return true;
	else return false;
}

bool SCIACKCheck(ADDRESS srcAddress, SCIRegAddress reg)
{
	if (ACKAddress == srcAddress && reg == ACKRegAddress && SCIS_SCISACKRQ)
	{
		SCIS_SCISACKRQ = false;
		return true;
	}
	else return false;
}

void SCIACKRQ(ADDRESS address, SCIRegAddress reg)
{
	ACKAddress = address;
	ACKRegAddress = reg;
	SCIS_SCISACKRQ = true;
}

ADDRESS SCIGetACKAddress(void)
{
	return ACKAddress;
}

void SCISet(ADDRESS srcAddress, SCIRegAddress reg, byte *data)
{
	if (SCIConnCheck(srcAddress))
	{
		switch (reg) {
		case ROOM_TEMP: setRoom_Temp(ConvertDataToDecimalValue(data)); break;
		case WATER_OUT_TEMP: setWater_Out_Temp(ConvertDataToDecimalValue(data)); break;
		case WATER_RETURN_TEMP: setWater_Return_Temp(ConvertDataToDecimalValue(data)); break;
		case AVG_TEMP: setAVGTemp(ConvertDataToDecimalValue(data)); break;
		case OUTDOOR_TEMP: setOutDoor_Temp(ConvertDataToDecimalValue(data)); break;
		case OUTDOOR_HUM: setOutDoor_Hum(ConvertDataToDecimalValue(data)); break;
		case REGULATE_DAY_TEMP: setRegulateToDayTemp(ConvertDataToDecimalValue(data)); break;
		case REGULATE_NIGHT_TEMP: setRegulateToNightTemp(ConvertDataToDecimalValue(data)); break;
		case REGULATE_TEMP_HYST: setRegulationHyst(ConvertDataToDecimalValue(data)); break;
		case REGULATE_WATER_MAX_TEMP: setRegulateToMaxWaterTemp(ConvertDataToDecimalValue(data)); break;
		case REGULATE_WATER_DIFF: setWaterDiff(ConvertDataToDecimalValue(data)); break;
		case ON_AVG_TEMP: setOnAverageTemp(ConvertDataToDecimalValue(data)); break;
		case OFF_AVG_TEMP: setOffAverageTemp(ConvertDataToDecimalValue(data)); break;
		case SYST_TYPE: setSystType((bool)data[0]); break;
		case HEATER: setHeater_State((bool)data[0]); break;
		case PUMP: setPump_State((bool)data[0]); break;
		case AUTOSW: setAutoSwitchingState((bool)data[0]); break;
		case DAY_START_TIME: setDayTempStart((int)data[0]); break;
		case DAY_END_TIME: setDayTempEnd((int)data[0]); break;
		case PUMP_DELAY_TIME: setPumpDelayTime((int)data[0]); break;
		case CLOCK: setClock(data); break;
		default:
			break;
		}
		SCIACK(srcAddress, reg);
	}
	else
	{
		SCIForbidden(srcAddress, reg);
	}

}

void setClock(byte *data)
{
	clockSetYear((int)data[0] + 2000);
	clockSetMonth(data[1]);
	clockSetDay(data[2]);
	clockSetDayOfWeek(data[3]);
	clockSetHours(data[4]);
	clockSetMinutes(data[5]);
	clockSetSeconds(data[6]);
	clockSetRTC();
}
decimal ConvertDataToDecimalValue(byte *data)
{
	return ((data[0] < 128) ? ((decimal)(data[0] * 100)) : ((decimal)((int)data[0] - 256) * 100))  + ((data[1] < 128) ? ((decimal)data[1]) : ((decimal)((int)data[1] - 256)));
}

unsigned char crc_check(unsigned long long int message, unsigned char check_value_from_sensor)
{
	unsigned long long int remainder = (unsigned long long int)message << 8; /* Pad with 8 bits because we have to add in the check value */
	unsigned long long int divsor = (unsigned long long int)SCI_SHIFTED_DIVISOR;
	int i = 0;

	remainder |= check_value_from_sensor; /* Add on the check value */

	for (i = 0; i < 16; i++) /* Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done. */
	{

		if (remainder & (unsigned long int)1 << (unsigned char)(23 - i)) /* Check if there is a one in the left position */
			remainder ^= divsor;

		divsor >>= 1; /* Rotate the divisor max 16 times so that we have 8 bits left of a remainder */
	}

	return (unsigned char)remainder;
}

interrupt VectorNumber_Vsci1tx void ISR_SCI_TX(void) {
	if (SCI1S1_TDRE){

		if (SCIS_SCISDTX){
			if (SCIbytesSent < SCIbytesToSend){
				SCI1D = *(SCIdatabuffer + SCIbytesSent);	/* Send 1 byte */
				SCIbytesSent++;
				return;
			}
			else{	/* All bytes sent */
				SCIS_SCISDTX = false;
				SCI1C2_TE = 0;
				SCI1C2_TIE = 0;
				return;
			}
		}
	}
}

interrupt VectorNumber_Vsci1rx void ISR_SCI_RX(void) {
	if (SCI1S1_RDRF){
		SCI1C2_ILIE = 1;
		SCIS_SCISDRX = false;
		SCIbytesReceiving %= SCI_BUFFER_LENGHT;
		SCI_RxDataBuffer[SCIbytesReceiving++] = (byte)SCI1D;
	}
	else if (SCI1S1_IDLE){
		SCI1C2_ILIE = 0;
		SCI_BytesReceived = SCIbytesReceiving - 1;
		SCIbytesReceiving = 0;
		SCIS_SCISDRX = true;
	}
}




