#ifndef RTL8019AS_H
#define RTL8019AS_H
#include <avr/io.h>
#include <util/delay.h>
//magistrala adresowa
#define RTL_ADDRESS_PORT PORTB
#define RTL_ADDRESS_DDR DDRB
//magistrala danych
#define RTL_DATA_PORT PORTD
#define RTL_DATA_DDR DDRD
#define RTL_DATA_PIN PIND
//magistrala odczytu/zapisu
#define RTL_CONTROL_PORT PORTC
#define RTL_CONTROL_DDR DDRC
#define RTL_CONTROL_READPIN PC1
#define RTL_CONTROL_WRITEPIN PC0
//zabawa pinami
#define RTL_CLEAR_READ RTL_CONTROL_PORT &= ~(1<<RTL_CONTROL_READPIN)
#define RTL_SET_READ RTL_CONTROL_PORT |= (1<<RTL_CONTROL_READPIN)
#define RTL_CLEAR_WRITE RTL_CONTROL_PORT &= ~(1<<RTL_CONTROL_WRITEPIN)
#define RTL_SET_WRITE RTL_CONTROL_PORT |= (1<<RTL_CONTROL_WRITEPIN)
//reset
#define RTL_RESET_PORT PORTC
#define RTL_RESET_DDR DDRC
#define RTL_RESET_PIN PC2
//rejestry
#define CR 0x00
#define PSTART 0x01
#define PAR0 0x01
#define CR9346 0x01
#define PSTOP 0x02
#define BNRY 0x03
#define TSR 0x04
#define TPSR 0x04
#define TBCR0 0x05
#define NCR 0x05
#define TBCR1 0x06
#define ISR 0x07
#define CURR 0x07
#define RSAR0 0x08
#define CRDA0 0x08
#define RSAR1 0x09
#define CRDA1 0x09
#define RBCR0 0x0A
#define RBCR1 0x0B
#define RSR 0x0C
#define RCR 0x0C
#define TCR 0x0D
#define CNTR0 0x0D
#define DCR 0x0E
#define CNTR1 0x0E
#define IMR 0x0F
#define CNTR2 0x0F
#define RDMAPORT 0x10
#define RSTPORT 0x18
#define ISR_PRX 0
#define ISR_PTX 1
#define ISR_OVW 4
#define ISR_RDC 6
#define ISR_RST 7
//adresy w pamiec
#define TXSTART_INIT 0x40
#define RXSTART_INIT 0x46
#define RXSTOP_INIT 0x60
//romiary pakietu, naglowkow, itd...
#define ETHERNET_MIN_PACKET_LEN 0x3C //60 bajtow
#define ETHERNET_HEADER_LEN 0x0E //14 bajtow
#define IP_TCP_HEADER_LEN 0x28 //40 bajtow
#define TOTAL_HEADER_LEN (IP_TCP_HEADER_LEN | ETHERNET_HEADER_LEN)
unsigned char EthFrame[128];
unsigned int currentRetreiveAddress;
unsigned char currentPacketPtr;
unsigned char nextPacketPtr;
unsigned int PacketSize;
void RTLsetup_ports()
{
RTL_ADDRESS_DDR = 0xFF;
RTL_DATA_PORT = 0xFF;
RTL_CONTROL_DDR |= (1<<RTL_CONTROL_READPIN);
RTL_CONTROL_DDR |= (1<<RTL_CONTROL_WRITEPIN);
RTL_CONTROL_PORT |= (1<<RTL_CONTROL_READPIN);
RTL_CONTROL_PORT |= (1<<RTL_CONTROL_WRITEPIN);
RTL_RESET_DDR |= (1<<RTL_RESET_PIN);
}
void RTLhw_reset()
{
RTL_RESET_PORT |= (1<<RTL_RESET_PIN);
_delay_ms(10);
RTL_RESET_PORT &= ~(1<<RTL_RESET_PIN);
_delay_ms(10);
}
void RTLwrite(unsigned char address, unsigned char data)
{
RTL_ADDRESS_PORT = address;
RTL_DATA_DDR = 0xFF;
RTL_DATA_PORT = data;
RTL_CLEAR_WRITE;
RTL_SET_WRITE;
RTL_DATA_DDR = 0x00;
RTL_DATA_PORT = 0xFF;
}
unsigned char RTLread(unsigned char address)
{
unsigned char byte;
RTL_ADDRESS_PORT = address;
asm volatile("nop\n\t"::);
RTL_CLEAR_READ;
asm volatile("nop\n\t"::);
byte = RTL_DATA_PIN;
RTL_SET_READ;
return byte;
}
void RTLinit(void)
{
RTLsetup_ports();
RTLhw_reset();
RTLwrite(RSTPORT, 0x00);
_delay_ms(30);
RTLwrite(CR, 0x41);
_delay_ms(2);
RTLwrite(CURR, RXSTART_INIT);
RTLwrite(PAR0+0, 0x01);
RTLwrite(PAR0+1, 0x01);
RTLwrite(PAR0+2, 0x01);
RTLwrite(PAR0+3, 0x01);
RTLwrite(PAR0+4, 0x01);
RTLwrite(PAR0+5, 0x01);
RTLwrite(CR, 0x21);
_delay_ms(2);
RTLwrite(DCR, 0x58);
RTLwrite(RCR, 0x04);
RTLwrite(TCR, 0x02);
RTLwrite(RBCR0, 0x00);
RTLwrite(RBCR1, 0x00);
RTLwrite(TPSR, TXSTART_INIT);
RTLwrite(PSTART, RXSTART_INIT);
RTLwrite(BNRY, RXSTART_INIT);
RTLwrite(PSTOP, RXSTOP_INIT);
RTLwrite(ISR, 0xFF);
RTLwrite(IMR, 0x11);
RTLwrite(TCR, 0x00);
RTLwrite(CR, 0x22);
}
void RTLsend_packet()
{
unsigned int i;
RTLwrite(CR,0x22);
while( RTLread(CR) & 0x04 );
RTLwrite(TPSR,TXSTART_INIT);
RTLwrite(RSAR0,0x00);
RTLwrite(RSAR1,TXSTART_INIT);
RTLwrite(ISR,(1<<ISR_PTX));
RTLwrite(RBCR0, 0xEA);
RTLwrite(RBCR1, 0x05);
RTLwrite(CR,0x12);
for(i=0; i<PacketSize; i++)
{
RTLwrite(RDMAPORT, EthFrame[i]);
}
while(PacketSize<60)
{
RTLwrite(RDMAPORT, 0);
PacketSize++;
}
RTLwrite(TBCR0, (unsigned char)(PacketSize));
RTLwrite(TBCR1, (unsigned char)((PacketSize)>>8));
RTLwrite(CR,0x24);
RTLwrite(ISR, (1<<ISR_RDC));
}
unsigned char RTLreceive_empty_check()
{
unsigned char curr;
RTLwrite(CR,0x62);
curr = RTLread(CURR);
RTLwrite(CR,0x22);
return ( curr == RTLread(BNRY) );
}
void RTLend_retreive()
{
unsigned char i = 0x00;
RTLwrite(CR, 0x22);
for(i = 0; i <= 20; i++)
if(RTLread(ISR) & 1<<6)
break;
RTLwrite(ISR, 1<<6);
RTLwrite(BNRY, nextPacketPtr);
}
unsigned char RTLreceive_packet()
{
unsigned int i;
if ( RTLreceive_empty_check() )
return 0;
RTLwrite(CR, 0x22);
currentPacketPtr = RTLread(BNRY);
currentRetreiveAddress = (currentPacketPtr<<8) + 4;
RTLwrite(ISR, (1<<ISR_PRX));
if( (currentPacketPtr >= RXSTOP_INIT) || (currentPacketPtr < RXSTART_INIT) )
{
RTLwrite(BNRY, RXSTART_INIT);
RTLwrite(CR, 0x62);
RTLwrite(CURR, RXSTART_INIT);
RTLwrite(CR, 0x22);
return 0;
}
RTLwrite(RBCR0, 4 + ETHERNET_HEADER_LEN);
RTLwrite(RBCR1, 0);
RTLwrite(RSAR0, 0);
RTLwrite(RSAR1, currentPacketPtr);
RTLwrite(CR, 0x0A);
RTLread(RDMAPORT);
nextPacketPtr = RTLread(RDMAPORT);
if( (nextPacketPtr >= RXSTOP_INIT) || (nextPacketPtr < RXSTART_INIT) )
return 0;
PacketSize = RTLread(RDMAPORT);
PacketSize |= ((unsigned int)RTLread(RDMAPORT)) << 8;
if (PacketSize > 4)
PacketSize -= 4;
else
{
RTLend_retreive();
return 0;
}
if( PacketSize > 128)
{
RTLend_retreive();
return 0;
}
EthFrame[0]=RTLread(RDMAPORT);
EthFrame[1]=RTLread(RDMAPORT);
EthFrame[2]=RTLread(RDMAPORT);
EthFrame[3]=RTLread(RDMAPORT);
EthFrame[4]=RTLread(RDMAPORT);
EthFrame[5]=RTLread(RDMAPORT);
EthFrame[6]=RTLread(RDMAPORT);
EthFrame[7]=RTLread(RDMAPORT);
EthFrame[8]=RTLread(RDMAPORT);
EthFrame[9]=RTLread(RDMAPORT);
EthFrame[10]=RTLread(RDMAPORT);
EthFrame[11]=RTLread(RDMAPORT);
EthFrame[12]=RTLread(RDMAPORT);
EthFrame[13]=RTLread(RDMAPORT);
currentRetreiveAddress += 6+6+2;
RTLwrite(CR, 0x22);
for(i = 0; i <= 20; i++)
if(RTLread(ISR) & 1<<6)
break;
RTLwrite(ISR, 1<<6);
RTLwrite(RBCR0, (unsigned char)PacketSize);
RTLwrite(RBCR1, (unsigned char)(PacketSize>>8));
RTLwrite(RSAR0, (unsigned char)currentRetreiveAddress);
RTLwrite(RSAR1, (unsigned char)(currentRetreiveAddress>>8));
RTLwrite(CR, 0x0A);
for(i=0;i<PacketSize;i++)
EthFrame[14+i] = RTLread(RDMAPORT);
currentRetreiveAddress += PacketSize;
if( currentRetreiveAddress >= 0x6000 )
currentRetreiveAddress = currentRetreiveAddress - (0x6000-0x4600) ;
RTLend_retreive();
return 1;
}
#endif