
#include "opora.h"
#include "config.h"

uint32_t temp;
uint32_t ReceiveWord,LastTrueCmd,TempCmd,refresh;

void MIL_STD_1553B1_Handler(void);

int main()
{
	ClkConfig();
	PortConfig();
	MilStd1553Init();
	MilStd1553DataInit();
	NVIC_EnableIRQ(MIL_STD_1553B1_IRQn);
	LastTrueCmd=0;
	while(1);
}

void MIL_STD_1553B1_Handler()
{
	uint16_t Status;
	uint32_t i,j;

	Status = MIL_STD_15531->STATUS;

	if((Status&0x08)==0x08)		//Error
	{
		MIL_STD_15531->CONTROL&=0xFFFBFFFF;	//ошибки сбрасываются автоматически при установке бита IDLE
		MIL_STD_15531->StatusWord1=(MYADDR<<11)|0x400;
		if(refresh==1)
		{
			LastTrueCmd=TempCmd;
			refresh=0;
		}
	}
	else
	{
		if ((Status&0x02)==0x02)	//True word
		{
			ReceiveWord=MIL_STD_15531->CommandWord1;
			if(((ReceiveWord&(0x1F<<5))==(0x1F<<5))||((ReceiveWord&(0x1F<<5))==0))	//если приняли команду управления
			{
				if(((ReceiveWord&(1<<10)==(1<<10))&&((ReceiveWord&0x1F)>0x08)&&((ReceiveWord&0x1F)<0x10))||((ReceiveWord&0x1F)>0x15))	//если необходимо передать КШ данные и код команды является резервным кодом
				{
					if((ReceiveWord&(0x1F<<11))==(0x1F<<11))	MIL_STD_15531->StatusWord1=(MYADDR<<11)|(1<<10)|(1<<4);	//принята групповая командв, ошибка в сообщении, установили адрес устройства
					else										MIL_STD_15531->StatusWord1=(MYADDR<<11)|(1<<10);			//ошибка в сообщении, установили адрес устройства
					LastTrueCmd=MIL_STD_15531->CommandWord1;
					MIL_STD_15531->CONTROL|=0x00040000;
					return;
				}
			}
			if((MIL_STD_15531->MSG==0x2420)&&((MIL_STD_15531->CommandWord1&0x1F)==0x12))	//Команда управления с данными не групповая (Команда передать последнюю команду)
			{
				MIL_STD_15531->StatusWord1=MYADDR<<11;
				MIL_STD_15531->ModeData=LastTrueCmd;	
			}
			else
			{
				refresh=1;
				TempCmd=LastTrueCmd;
				if((MIL_STD_15531->MSG==0x1008)||(MIL_STD_15531->MSG==0x0200))	//Команда обмена данными ОУ-ОУ групповая или не групповая
					LastTrueCmd=MIL_STD_15531->CommandWord2;
				else
					LastTrueCmd=MIL_STD_15531->CommandWord1;
			}
			if(!(((MIL_STD_15531->MSG==0x0410)&&((MIL_STD_15531->CommandWord1&0x1F)==0x02))||((MIL_STD_15531->MSG==0x2420)&&((MIL_STD_15531->CommandWord1&0x1F)==0x12))) )
			//если приняли любую команду кроме команды "Передать ОС" или команды "Передать последнюю команду"
			{
				switch(MIL_STD_15531->MSG)
				{
					case 0x0080:
					case 0x0100:
					case 0x0200:
					case 0x0400:
					case 0x0800:	MIL_STD_15531->StatusWord1=(MYADDR<<11)|(1<<4);	break;	//выставляем адрес ОУ и бит принятия групповой команды
					default:		MIL_STD_15531->StatusWord1=MYADDR<<11; break;			//выставляем адрес ОУ
				}
			}
			if((MIL_STD_15531->MSG==0x0410)||(MIL_STD_15531->MSG==0x0400))	//если приняли команду управления без данных групповую или не групповую
			{
				if((MIL_STD_15531->CommandWord1&0x1F)==0x04)	//если приняли команду блокировать передатчик	
				{
					if((Status&0x30)==0x10) MIL_STD_15531->CONTROL&=0xFFFFFFDF;
					else if((Status&0x30)==0x20) MIL_STD_15531->CONTROL&=0xFFFFFFEF;
				}
				else if((MIL_STD_15531->CommandWord1&0x1F)==0x05)	//если приняли команду разблокировать передатчик
				{
					if((Status&0x30)==0x10)	MIL_STD_15531->CONTROL|=0x20;	
					else if((Status&0x30)==0x20)	MIL_STD_15531->CONTROL|=0x10;
				}
			}
			if((MIL_STD_15531->MSG==0x0040)||(MIL_STD_15531->MSG==0x0800))
			//если принята команда с данными групповая или не групповая
			{
				if((MIL_STD_15531->CommandWord1&0x1F)==0x14)	//приняли команду "Блокировать i-й передатчик"
				{
					if((Status&0x30)==0x10)	MIL_STD_15531->CONTROL&=0xFFFFFFDF;
					else if((Status&0x30)==0x20)	MIL_STD_15531->CONTROL&=0xFFFFFFEF;
				}
				else if((MIL_STD_15531->CommandWord1&0x1F)==0x15)	//приняли команду "Разблокировать i-й передатчик"
				{
					if((Status&0x30)==0x10)	MIL_STD_15531->CONTROL|=0x20;
					else if((Status&0x30)==0x20)	MIL_STD_15531->CONTROL|=0x10;
				}
			}
		}
		if((Status&0x04)==0x04)	//если успешно завершилась транзакция в канале
		{
			if(((MIL_STD_15531->MSG==0x0040)||(MIL_STD_15531->MSG==0x0800))&&((MIL_STD_15531->CommandWord1&0x1F)==0x11))	//если была принята команда групповая или не групповая "Синхронизация (со СД)"
			{
				ReceiveWord=(MIL_STD_15531->CONTROL&0xFFFFF83F)|((MIL_STD_15531->ModeData&0x1F)<<6);	//оставили заполнение только адресных бит ОУ
				MIL_STD_15531->CONTROL=ReceiveWord;
			} 
			refresh=0;
			if(((MIL_STD_15531->CommandWord1|0xFBFF)==0xFBFF)&&((MIL_STD_15531->CommandWord1&0x3E0)!=0x3E0)&&((MIL_STD_15531->CommandWord1|0xFC1F)!=0xFC1F))	//если команда обмена данными и необходимо принять от КШ данные
			{
				if((MIL_STD_15531->CommandWord1&0x20)==0x20)
				{
					for(j=0;j<=0x80;j=j+4)
					{
						i=*((volatile uint32_t *)(MIL_STD_15531_BASE+0x80+j));
						*((volatile uint32_t *)(MIL_STD_15531_BASE+0x80+j))=i;
					}
				}
			}		
		}
	}
	MIL_STD_15531->CONTROL|=0x00040000;	//18 бит установили в 1 (ошибки могут быть сброшены только битом MR)

}

