//#############################################################################################################################################################################################################
#include "RSLink.h"
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void RSLink_Init(/*USART_INTERFACE_TYPE *USART_INTERFACE, USART_IDIBUS_ROUTINE_TYPE *USART_ID_INTERFACE*/)
{
	//RS_USI=USART_INTERFACE;								//	USART POINTER INIT
	//RS_USIID=USART_ID_INTERFACE;
	RS_NeedSpeedChangeFlag=0;

	//RS_LastMMES_TimeInstance=System_GetTimeInstance();
	FARG.OutData = USART1_getTxBuf();		//set RX addr

	RSLink_StatusLedInit();									//	Init LEDs
	RSLink_DipsInit();										// 
	RSLink_SpeedCheckAndUpdate();							//	Set speed
	USART1_SetIdiBusBoudrate(RS_SpeedCode);		//	Set speed usart
	RSLink_AddressCheckAndUpdate();							//	Set adr
	USART1_RxTransferRestart();						//	Restart RX
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint8_t RSLink_SpeedCheckAndUpdate(void)
{
	uint8_t SpeedDSW_Code = RSLink_SpeedDecode();
	if (RS_SpeedCode != SpeedDSW_Code) { RS_SpeedCode = SpeedDSW_Code; return 1; }
	return 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void RSLink_AddressCheckAndUpdate(void)
{
	RS_Address = RSLink_AddrDecode();
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void RSLink_Handler(void)	
{
	// Address and Speed Change Check Routine =======================================
	if ( (RS_NeedSpeedChangeFlag == 1) || RSLink_SpeedCheckAndUpdate() )
	{
		if ( USART1_IsTxActive() ) { RS_NeedSpeedChangeFlag = 1; }
		else  						     { USART1_SetIdiBusBoudrate(RS_SpeedCode); RS_NeedSpeedChangeFlag = 0; }
	}
	RSLink_AddressCheckAndUpdate();

	IDIBUS_ModuleBackgroundHandler();

	if ( USART1_IsNewRxMessage() == 0 ) { return; }
	
	if ( USART1_IsRxError() == 1) { 
		USART1_RxTransferRestart();
		return;
	}
	
	static uint16_t RxMessageSize;

	// Check normal Message --------------------------------------------------------->

	// Check Message size
	uint8_t RcvAddress;
	RxMessageSize = USART1_getRxBufSize();
	if ( (RxMessageSize < (MODBUS_CRC16_SIZE+1) ) || (RxMessageSize > IDIMMES_MAX_MES_SIZE) ) { USART1_RxTransferRestart(); return; }
	else
	{
		USART1_copyRxBuf( &RxMesageBuf[IDIMMES_ADDR_Pos], IDIMMES_ADDR_Pos, RxMessageSize ); 	// Need for CRC
		USART1_RxTransferRestart();
		RcvAddress = RxMesageBuf[IDIMMES_ADDR_Pos];
	}

	// MMESG(Module) or MMES ------------->
	if ( RcvAddress == RS_Address )
	{
		// Check CRC, copy RxBuf and Restart Transfer
		//USART1_copyRxBuf( &RxMesageBuf[IDIMMES_MMPS_Pos], IDIMMES_MMPS_Pos, (uint16_t)(RxMessageSize-1) );
		uint16_t CalculatedCRC = CRC16( RxMesageBuf, (uint16_t)(RxMessageSize-2) );
		uint16_t ReceivedCRC   = (uint16_t)( ((uint16_t)RxMesageBuf[RxMessageSize-2] << 8) | RxMesageBuf[RxMessageSize-1] );
		if ( CalculatedCRC != ReceivedCRC ) { BootloaderInfo.Status=IDIFMW_STATUS_ErrorPacketCRC; return; }

		FARG.OutDataLength = IDISMES_ERROR_Pos;	//Set length 2 (adr+cmd)

		uint8_t MMPS = RxMesageBuf[IDIMMES_MMPS_Pos];
		
		if ( (MMPS != (IDIMMES_MMPS_MES_TYPE_Msk)) || (RxMessageSize < IDIMMESG_MODULE_MIN_MES_SIZE)) { 
			//IDIBUS_ResponseProtectedWrite(NULL,0,IDIERSLV_NO_FIRMWARE);
			IDIBUS_ResponseProtectedWrite(NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT);
		}
		else 
		{
			FARG.ComFunc =  RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos];
			//FARG.InpData = &RxMesageBuf[IDIMMESG_DATA_COM_FUNC_Pos + 1];
			FARG.InpDataLength = (uint16_t)(RxMessageSize - (IDIMMESG_DATA_COM_FUNC_Pos + 1) - MODBUS_CRC16_SIZE);
			IDIBUS_ModuleCommandHandler();
		}

		RSLink_SendSMES();
	} //if ( (RcvAddress == RS_Address) && (RxMessageSize >= IDIMMES_MIN_MES_SIZE) )


	// MMESG ------------->
	// NO RESPONSE!!!
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void RSLink_SendSMES()
{
	if ( /*(USART1STR->ResponseTimeoutComplete == 0) &&*/ (FARG.OutDataLength > IDISMES_ERROR_Pos) )
	{
		FARG.OutData[IDISMES_ADDR_Pos] = RS_Address;
		FARG.OutData[IDISMES_SMPS_Pos] = FARG.SMPS;
		//if ( FARG.ErrorState   != 0 )    { FARG.OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_ERROR_BIT_Pos); }
		//if ( FARG.OutLongMesState != 0 ) { FARG.OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_LONG_MES_Pos);  }
		//if ( FARG.LongOpState != 0 )     { FARG.OutData[IDISMES_SMPS_Pos] |= (1U << IDISMES_SMPS_LONG_OP_Pos);  }
		uint16_t crc16 = CRC16(&FARG.OutData[0], FARG.OutDataLength);
		FARG.OutData[FARG.OutDataLength++] = (uint8_t)(crc16 >> 8);
		FARG.OutData[FARG.OutDataLength++] = (uint8_t) crc16;
		USART1_SendTxBuf(FARG.OutDataLength);
	}
}
//#############################################################################################################################################################################################################
