
/*
Конфигурирование контроллера Ethernet и функции для обмена данными по параллельному интерфейсу.
*/

void EthCfg(void);                                  //функция конфигурирования контроллера 5600ВГ1У
																			  
int Write_Tx_Descriptor(unsigned short,_tx_current_descriptor*); //функция записи дескриптора передатчика
unsigned short Read_Tx_Descriptor(_tx_descriptor*); //функция чтения дескриптора передатчика

int Ready_Rx_Descriptor(_rx_descriptor*);           //функция записи дескриптора приемника
unsigned short Read_Rx_Descriptor(_rx_descriptor*); //функция чтения дескриптора приемника

unsigned short Read_Packet_Start_Address(_rx_descriptor*);     //функция чтения стартового адреса принятого пакета
unsigned short Read_Packet_Length(_rx_descriptor*);            //функция чтения длины пакета

//--------------------------------------------------------------------------------------
//Функция для инициализации Ethernet-контроллера 5600ВГ1У
//Параметр:	нет
//Возвращаемых значений нет
//--------------------------------------------------------------------------------------
void EthCfg()
{
	int i;

		Ethernet->GCTRL = 0x8000;	//Reset 5600VG1U        
		for(i=0;i<1000;i++){}		//Little delay
		Ethernet->GCTRL = 0x4382;						   	
		Ethernet->MinFrame = 0x0040;
    	Ethernet->CollConfig = 0;
    	Ethernet->IPGTx = 0x000A;
    	Ethernet->MAC_ADDR_T = 0x1B0A;
    	Ethernet->MAC_ADDR_M = 0x3D2C;
    	Ethernet->MAC_ADDR_H = 0x5F4E;
        Ethernet->PHY_CTRL = 0x31D0;
		Ethernet->MAC_CTRL = 0x0200;  //Receive broadcast packet and packet with my MAC-address, littel endian ON
}

//--------------------------------------------------------------------------------------
//Функция для подготовки дескрипторов передатчика к отправке пакетов
//Параметр:	PacketLen - размер пакета в байтах,
//			TxCurrentDesc - указатель на текущий дескриптор отправляемых пакетов
//Возвращаемых значений нет
//--------------------------------------------------------------------------------------
int Write_Tx_Descriptor(unsigned short PacketLen, _tx_current_descriptor* TxCurrentDesc)
{
	unsigned int* MyDesc;
	MyDesc = (unsigned int*)(TxCurrentDesc->TxCurrentDescriptor->StartAddress);

	*(MyDesc+1) = PacketLen;
	*(MyDesc+3) = (TxCurrentDesc->FirstEmptyWord>>2)&0x0000FFFF;

	if(TxCurrentDesc->TxCurrentDescriptor->LastDesc == 1) *MyDesc = 0xC000;
	else *MyDesc = 0x8000;

	TxCurrentDesc->FirstEmptyWord += (PacketLen/2)<<2;	//адрес первого свободного 16-разрядного слова в буфере
												//сдвг PacketLen на 1 разряд, так как в передаваемом пакете
												//необходимо указывать размер в байтах, а в буфере - 16-разрядные слова!
	if(TxCurrentDesc->FirstEmptyWord > 0x60005FFC)
	{
		TxCurrentDesc->FirstEmptyWord -= 0x00006000;
		TxCurrentDesc->FirstEmptyWord |= 0x60004000;
	}
    return 0;
}

//--------------------------------------------------------------------------------------
//Функция для определения статуса отправляемого пакета
//Параметр:	TxDesc - указатель на дескриптор отправляемых пакетов
//Возвращает:	1 - пакет не отправлен
//				0 - пакет отправлен 
//--------------------------------------------------------------------------------------
unsigned short Read_Tx_Descriptor(_tx_descriptor* TxDesc)
{
		unsigned int* MyDesc;
		MyDesc = (unsigned int*)(TxDesc->StartAddress);
        if((*MyDesc & 0x8000) == 0x8000) return 1;            //пакет не отправлен
        else return 0;                                              //пакет отправлен
}

//--------------------------------------------------------------------------------------
//Функция для установки признака готовности к приему пакета дескриптором принимаемых пакетв
//Параметр:	RxDesc - указатель на дескриптор принимаемых пакетов
//Возвращает:	0
//--------------------------------------------------------------------------------------
int Ready_Rx_Descriptor(_rx_descriptor* RxDesc)
{
		unsigned int* MyDesc;
		MyDesc = (unsigned int*)(RxDesc->StartAddress);
		if(RxDesc->LastDesc == 1) *MyDesc = 0xC000;	//установка готовности дескриптора к приему пакета
		else *MyDesc = 0x8000;						//установка готовности дескриптора к приему пакета
        return 0;
}

//--------------------------------------------------------------------------------------
//Функция для определения наличия принятого пакета
//Параметр:	RxDesc - указатель на дескриптор принимаемых пакетов
//Возвращает:	1 - пакет не принят
//				0 - пакет принят
//--------------------------------------------------------------------------------------
unsigned short Read_Rx_Descriptor(_rx_descriptor* RxDesc)
{
		unsigned int* RDescPointer;
		RDescPointer = (unsigned int*)RxDesc->StartAddress;
        if( (*RDescPointer & 0x8000) == 0x8000) return 1;	
        else return 0;                                      
}

//--------------------------------------------------------------------------------------
//Функция для получения размера приянтого пакета
//Параметр:	RxDesc - указатель на дескриптор принимаемых пакетов
//Возвращает:	размер пакета в байтах
//--------------------------------------------------------------------------------------
unsigned short Read_Packet_Length(_rx_descriptor* RxDesc)
{
		unsigned int* RDescPointer;
		RDescPointer = (unsigned int*)(RxDesc->StartAddress + 4);		//получим адрес длины пакета
        return (unsigned short)(*RDescPointer);       //Temp;
}

//--------------------------------------------------------------------------------------
//Функция для получения адреса, по которому расположен пакета в буфере приемника
//Параметр:	RxDesc - указатель на дескриптор принимаемых пакетов
//Возвращает:	адрес пакета в буфере
//--------------------------------------------------------------------------------------
unsigned short Read_Packet_Start_Address(_rx_descriptor* RxDesc)
{
        unsigned int* RDescPointer;
		RDescPointer = (unsigned int*)(RxDesc->StartAddress + 12);	//получим адрес стартового адреса пакета
        return (unsigned short)(*RDescPointer);
}

