#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