#include "IDIBUS_IMPL_Custom.h"

int data_flag = 0;
uint8_t data_to_send[12] = {0};

void IDIBUS_CustomInit(){
	IDIBUS_MODULE.STATUS.STATE.B0S.StError = 0;
	IDIBUS_MODULE.STATUS.STATE.B0S.StState = IDISTATUS_B0S_ST_STATE_StOperate;
	IDIBUS_MODULE.STATUS.STATE.B0S.AesSupported = 0;
	IDIBUS_MODULE.STATUS.STATE.B0S.AesInstalled = 0;
	IDIBUS_MODULE.STATUS.STATE.B0S.SendAlarmL0 = 0;
	IDIBUS_MODULE.STATUS.STATE.B0S.SendAlarmL1 = 0;

	IDIBUS_MODULE.STATUS.STATE.B1S.ModuleType = IDISTATUS_B1S_MODULE_TYPE_Slave;
	IDIBUS_MODULE.STATUS.STATE.B1S.BridgeConnected = 0;
	IDIBUS_MODULE.STATUS.STATE.B1S.SelfInit = 1;
	IDIBUS_MODULE.STATUS.STATE.B1S.TimeoutLed = 0;
	IDIBUS_MODULE.STATUS.STATE.B1S.NoMMESTimeout = 0;
	IDIBUS_MODULE.STATUS.STATE.B1S.CatchAlarmL0 = 0;
	IDIBUS_MODULE.STATUS.STATE.B1S.CatchAlarmL1 = 0;

	IDIBUS_MODULE.Devices = IDIBUS_DEVICES;
	IDIBUS_MODULE.DevicesCount = IDIBUS_DEVICES_NUMBER;
	
	IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels  = &IDIBUS_GEN_CHNLS[0];
	IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].ChannelsCount  = GEN_CHN_COUNT;
	
	for (uint8_t I=0; I < GEN_CHN_COUNT; I++)
	{
		IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].ChNum = I;
		IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].LONG_OP.Type = 0;
		IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].LONG_OP.State = IDILONGOP_STATE_COMPLETE_NO_ERR;
		IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].BcastAddr = IDIBUS_GROUP_0_ADDR;
		IDIBUS_MODULE.Devices[IDIBUS_GEN_DEV].Channels[I].CH_Func = IDIBUS_GEN_ChannelHandler;
	}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void IDIBUS_GEN_ChannelHandler(struct IDIBUS_CHANNEL_STR* CH, IDIBUS_FARG_TYPE *farg){
	if ( IDIBUS_CnannelStaticFunc(CH, farg) != 0) { return; }

	if (CH->ChNum >= GEN_CHN_COUNT) {IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERDEV_INVALID_CHN_NUM); return;}

	switch (farg->ComFunc)
	{
		case (0x01) : {  // Добавить выключение
			if ( farg->InpDataLength == 0 ) { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_INVALID_RX_REQUEST_FORMAT); }
			else
			{
				//DDRE = 2;
				uint8_t ErrorSt = IDIER_NOPE;
				memcpy(data_to_send, farg->InpData, sizeof(data_to_send));

				if (sizeof(data_to_send) / sizeof(data_to_send[0]) != 0) {
					data_flag = 1;
				}
				
				TCCR2A |= (1 << WGM21);  // CTC
				TCCR2B |= (1 << CS21);  // Prescaler
				OCR2A = 1;
				TIMSK2 = (1<<OCIE2A);
				
				IDIBUS_ResponseProtectedWrite(farg, NULL, 0, ErrorSt);
			}
		break; 
		}
		
		case (0x02) : {  // STM Reset
			uint8_t ErrorSt = IDIER_NOPE;
			STMReset();
			IDIBUS_ResponseProtectedWrite(farg, NULL, 1, ErrorSt);
		}

		default : { IDIBUS_ResponseProtectedWrite(farg, NULL, 0, IDIERSLV_UNSUPPORTED_FUNC_NUM); }
	}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ISR(TIMER2_COMPA_vect) {
	TimerStop;
	ResetTimer;
	
	switch (CurrentState) {
		
		case GEN_Wait: {
			_delay_ms(10);
			
			while (data_flag == 0);  // Ждем приема данных из идибаса
			CurrentState = GEN_Send;
			break;
		}
		
		case GEN_Send: {		
			CurrentState = GEN_Wait;
			// А НАДО ЛИ???????????????
			TimerTime = 100; // Ограничение по времени - 150 мс
			
			//_delay_ms(10);
			STMReset();
			//_delay_ms(10);
			
			if ((PINC)&(1<<PORTC3)) {  // STM готов к приему
				_delay_ms(10);
				for (uint8_t i = 0; i < 12; i++) {
					SPI_MasterTransmit(data_to_send[i]);
				}
			}
			
			TimerStartTick;
			break;
		}
	}
}

void STMReset() {
	DDRC |= (1 << PINC4);
	PORTC &= ~(1 << PINC4);
	_delay_ms(100);
	DDRC &= ~(1 << PINC4);
	_delay_ms(100);
}