#ifndef __ETHFUNC_C
#define __ETHFUNC_C
#include "config.h"
#include "ethfunc.h"
#include "opora.h"
extern const uint16_t MyMAC[3];
extern const uint16_t MyIPAddress[2];
/*-----------------------------------------------------
*------------------------------------------------------
*------------------------------------------------------
*--------------- ╘єэъЎшш ъюэЄЁюыыЁр PHY ---------------
*------------------------------------------------------
*------------------------------------------------------
------------------------------------------------------*/
//*** ╘єэъЎш фы ъюэЇшуєЁшЁютрэш PHY ьюфєы ўхЁхч MDIO шэЄхЁЇхщё ***
//Addr - рфЁхё ьюфєы PHY
//Mode - Ёхцшь ЁрсюЄ√ ъюэЄЁюыыхЁр PHY
void PHYInit(uint8_t Addr, uint8_t Mode)
{
uint32_t tmp;
tmp = ETHERNET->PHY_CTRL;
tmp &= 0x0770; //ёсЁюёшыш яюы рфЁхёр PHY, Ёхцшьр ЁрсюЄ√ яю єьюыўрэш■, Ёхцшь FiberOptic
tmp |= (Addr<<11)|(Mode<<1)|1;
ETHERNET->PHY_CTRL=tmp;
while((ETHERNET->PHY_STATUS&0x10)==0); //цфхь яюър ьюфєы№ т ёюёЄю эшш ёсЁюёр
}
//*** ╘єэъЎш фы чряшёш ЁхушёЄЁют PHY ьюфєы ўхЁхч MDIO шэЄхЁЇхщё ***
//Addr - рфЁхё ьюфєы PHY
//Num - эюьхЁ ЁхушёЄЁр, ъєфр сєфхь чряшё√трЄ№ фрээ√х
//Data - фрээ√х фы чряшёш
void SetPHYReg(uint8_t Addr, uint8_t Num, uint16_t Data)
{
uint32_t i;
ETHERNET->MDIO_DATA=Data;
i=0xC000|((Addr&0x1F)<<8)|(Num&0x1F)|(0x01<<5);
ETHERNET->MDIO_CTRL=(uint16_t)i;
while((ETHERNET->MDIO_CTRL&0x8000)==0);
}
//*** ╘єэъЎш фы ўЄхэш ЁхушёЄЁют PHY ьюфєы ўхЁхч MDIO шэЄхЁЇхщё ***
//Addr - рфЁхё ьюфєы PHY
//Num - эюьхЁ ЁхушёЄЁр, ъюЄюЁ√щ эхюсїюфшью яЁюўшЄрЄ№
//тючтЁр∙рхЄ чэрўхэшх ЁхушёЄЁр яю рфЁхёє Num т Addr ьюфєых PHY.
uint16_t GetPHYReg(uint8_t Addr, uint8_t Num)
{
uint32_t i;
i=0xE000|((Addr&0x1F)<<8)|(0x1<<5)|(Num&0x1F);
ETHERNET->MDIO_CTRL=(uint16_t)i;
while((ETHERNET->MDIO_CTRL&0x8000)==0);
return ETHERNET->MDIO_DATA;
}
/*-----------------------------------------------------
*------------------------------------------------------
*------------------------------------------------------
*--------------- ╘єэъЎшш ъюэЄЁюыыЁр MAC ---------------
*------------------------------------------------------
*------------------------------------------------------
-----------------------------------------------------*/
//*** ╘єэъЎш фы ъюэЇшуєЁшЁютрэш MAC ьюфєы ***
void EthernetConfig()
{
PHYInit(0x1C,3); //PHY address 0x1C, Mode 100BaseT_Full_Duplex
ETHERNET->MAC_T=MyMAC[0];
ETHERNET->MAC_M=MyMAC[1];
ETHERNET->MAC_H=MyMAC[2];
MACReset();
ETHERNET->IMR=0x0101; //ЁрчЁх°хэшх яЁхЁ√трэшщ яЁш єёях°эюь яЁшхьх яръхЄр
}
//*** ╘єэъЎш фы ъюэЇшуєЁшЁютрэш MAC ьюфєы ё шёїюфэ√ьш чэрўхэш ьш ЁхушёЄЁют ***
void MACReset()
{
ETHERNET->G_CFG|=0x00030000; //RRST=1, XRST=1 ёсЁюё яЁшхьэшър ш яхЁхфрЄўшър
ClearMemory();
ETHERNET->Delimiter=0x1000; //4096 срщЄ сєЇхЁ яхЁхфрЄўшър, 4096 срщЄ сєЇхЁ яЁшхьэшър
ETHERNET->HASH0=0;
ETHERNET->HASH1=0;
ETHERNET->HASH2=0;
ETHERNET->HASH3=0x8000;
ETHERNET->IPG=0x0060;
ETHERNET->PSC=0x0050;
ETHERNET->BAG=0x0200;
ETHERNET->JitterWnd=0x0005;
ETHERNET->R_CFG=0x8406;
ETHERNET->X_CFG=0x81FA;
ETHERNET->G_CFG=0x30030080; //ышэхщэ√щ Ёхцшь ЁрсюЄ√ сєЇхЁют.
ETHERNET->IMR=0;
ETHERNET->IFR=0xFFFF;
ETHERNET->R_Head=0x0000;
ETHERNET->X_Tail=0x1000;
ETHERNET->G_CFG&=0xFFFCBFFF; //RRST=0, XRST=0 °ЄрЄэ√щ Ёхцшь ЁрсюЄ√
}
//*** ╘єэъЎш фы юўшёЄъш сєЇхЁют яЁшхьэшър ш яхЁхфрЄўшър MAC ьюфєы ***
//┴єЇхЁ яЁшхьэшър 4096 срщЄ
//┴єЇхЁ яхЁхфрЄўшър 4096 срщЄ
void ClearMemory()
{
uint32_t Temp;
uint32_t *ptr;
ptr=(uint32_t*)0x38000000;
for(Temp=0;Temp<2048;Temp++) *ptr++=0;
}
/*---------------------------------------------------------------------------------------------------
*--------------- ╘єэъЎшш фы ЁрсюЄ√ ё сєЇхЁрьш яЁшхьэшър ш яхЁхфрЄўшър ъюэЄЁюыыЁр MAC ---------------
---------------------------------------------------------------------------------------------------*/
//*** ╘єэъЎш фы ёўшЄ√трэш яръхЄр шч сєЇхЁр яЁшхьэшър ***
//*** *Frame - єърчЄхы№ эр ёЄЁєъЄєЁє яръхЄр
uint32_t ReadPacket(_Rec_Frame* Frame)
{
uint16_t space_start=0;
uint16_t space_end=0;
uint16_t tail;
uint16_t head;
uint32_t *src, *dst;
uint32_t size, i;
uint16_t tmp[2];
tail=ETHERNET->R_Tail;
head=ETHERNET->R_Head;
if(tail>head)
{
space_end=tail-head;
space_start=0;
}
else
{
space_end=0x1000-head;
space_start=tail;
}
src=(uint32_t*)(0x38000000+head);
dst=(uint32_t*)(Frame->Data);
*((uint32_t*)tmp)=*src++; //яЁюўшЄрыш ъюы-тю срщЄ т яюыєўхээюь яръхЄх
space_end-=4;
if((uint16_t)src>0xFFF) src=(uint32_t*)0x38000000;
size=(tmp[0]+3)/4;
if(tmp[0]<=space_end)
{
for(i=0;i<size;i++)
*dst++ = *src++;
}
else
{
size=size-space_end/4;
for(i=0; i<(space_end/4); i++)
*dst++ = *src++;
src=(uint32_t*)0x38000000;
for(i=0; i<size; i++)
*dst++ = *src++;
}
if((uint16_t)src>0xFFF) src=(uint32_t*)0x38000000;
ETHERNET->R_Head=(uint16_t)src;
ETHERNET->STAT-=0x20;
return tmp[0];
}
//*** ╘єэъЎш фы чряшёш яръхЄр т сєЇхЁ яхЁхфрЄўшър ***
//*** *buffer - єърчЄхы№ эр сєЇхЁ фрээ√ї
//*** size - ъюы-тю юЄяЁрты хь√ї срщЄ
int SendPacket(void* buffer, int size)
{
uint16_t i;
uint32_t tmp, head, tail;
uint32_t *src, *dst;
uint16_t space[2];
head = ETHERNET->X_Head;
tail = ETHERNET->X_Tail;
//т√ўшёы хь ъюы-тю ётюсюфэюую ьхёЄр т сєЇхЁх яхЁхфрЄўшър
if(head>tail)
{
space[0]=head-tail;
space[1]=0;
} else
{
space[0]=0x2000-tail;
space[1]=head-0x1000;
}
//т√ўшёышыш ъюы-тю ётюсюфэюую ьхёЄр т сєЇхЁх яхЁхфрЄўшър
if(size>(space[0]+space[1]-8)) return 0; //-8, Єръ ъръ 4 срщЄр чрэшьрхЄ яюых фышэ√ фрээ√ї ш 4 срщЄр чрэшьрхЄ яюых ёЄрЄєёр яръхЄр
tmp=size;
src=buffer;
dst=(uint32_t*)(0x38000000+tail);
*dst++ =tmp;
space[0]-=4;
if((uint16_t)dst>0x1FFC) dst=(uint32_t*)0x38001000;
tmp=(size+3)/4;
if(size<=space[0])
{
for(i=0; i<tmp; i++)
*dst++ = *src++;
}
else
{
tmp-=space[0]/4;
for(i=0;i<(space[0]/4);i++)
*dst++ = *src++;
dst=(uint32_t*)0x38001000;
for(i=0;i<tmp;i++)
*dst++ = *src++;
}
if((uint16_t)dst>0x1FFC) dst=(uint32_t*)0x38001000;
tmp=0;
*dst++ =tmp;
if((uint16_t)dst>0x1FFC) dst=(uint32_t*)0x38001000;
ETHERNET->X_Tail=(uint16_t)dst;
return size;
}
#endif //__ETHFUNC_C