📄 ata.c
字号:
//* This routine removes a data packet from the receive buffer
//* ring.
//******************************************************************
void get_packet()
{
//execute Send Packet command to retrieve the packet
write_rtl(CR,0x1A);
for(i=0;i<4;++i)
{
read_rtl(RDMAPORT);
pageheader[i] = byte_read;
}
rxlen = make16(pageheader[enetpacketLenH],pageheader[enetpacketLenL]);
for(i=0;i<rxlen;++i)
{
read_rtl(RDMAPORT);
//dump any bytes that will overrun the receive buffer
if(i < packetlen)
packet[i] = byte_read;
}
while(!(byte_read & RDC))
read_rtl(ISR);
write_rtl(ISR,0xFF);
//process an ARP packet
if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x06)
{
if(packet[arp_hwtype+1] == 0x01 &&
packet[arp_prtype] == 0x08 && packet[arp_prtype+1] == 0x00 &&
packet[arp_hwlen] == 0x06 && packet[arp_prlen] == 0x04 &&
packet[arp_op+1] == 0x01 &&
MYIP[0] == packet[arp_tipaddr] &&
MYIP[1] == packet[arp_tipaddr+1] &&
MYIP[2] == packet[arp_tipaddr+2] &&
MYIP[3] == packet[arp_tipaddr+3] )
arp();
}
//process an IP packet
else if(packet[enetpacketType0] == 0x08 && packet[enetpacketType1] == 0x00
&& packet[ip_destaddr] == MYIP[0]
&& packet[ip_destaddr+1] == MYIP[1]
&& packet[ip_destaddr+2] == MYIP[2]
&& packet[ip_destaddr+3] == MYIP[3])
{
if(packet[ip_proto] == PROT_ICMP)
icmp();
else if(packet[ip_proto] == PROT_UDP)
udp();
else if(packet[ip_proto] == PROT_TCP)
tcp();
}
}
//******************************************************************
//* SETIPADDRS
//* This function builds the IP header.
//******************************************************************
void setipaddrs()
{
//move IP source address to destination address
packet[ip_destaddr]=packet[ip_srcaddr];
packet[ip_destaddr+1]=packet[ip_srcaddr+1];
packet[ip_destaddr+2]=packet[ip_srcaddr+2];
packet[ip_destaddr+3]=packet[ip_srcaddr+3];
//make ethernet module IP address source address
packet[ip_srcaddr]=MYIP[0];
packet[ip_srcaddr+1]=MYIP[1];
packet[ip_srcaddr+2]=MYIP[2];
packet[ip_srcaddr+3]=MYIP[3];
//move hardware source address to destinatin address
packet[enetpacketDest0]=packet[enetpacketSrc0];
packet[enetpacketDest1]=packet[enetpacketSrc1];
packet[enetpacketDest2]=packet[enetpacketSrc2];
packet[enetpacketDest3]=packet[enetpacketSrc3];
packet[enetpacketDest4]=packet[enetpacketSrc4];
packet[enetpacketDest5]=packet[enetpacketSrc5];
//make ethernet module mac address the source address
packet[enetpacketSrc0]=MYMAC[0];
packet[enetpacketSrc1]=MYMAC[1];
packet[enetpacketSrc2]=MYMAC[2];
packet[enetpacketSrc3]=MYMAC[3];
packet[enetpacketSrc4]=MYMAC[4];
packet[enetpacketSrc5]=MYMAC[5];
//calculate the IP header checksum
packet[ip_hdr_cksum]=0x00;
packet[ip_hdr_cksum+1]=0x00;
hdr_chksum =0;
hdrlen = (packet[ip_vers_len] & 0x0F) * 4;
addr = &packet[ip_vers_len];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[ip_hdr_cksum] = make8(chksum16,1);
packet[ip_hdr_cksum+1] = make8(chksum16,0);
}
//******************************************************************
//* CHECKSUM CALCULATION ROUTINE
//******************************************************************
void cksum()
{
while(hdrlen > 1)
{
data_H=*addr++;
data_L=*addr++;
chksum16=make16(data_H,data_L);
hdr_chksum = hdr_chksum + chksum16;
hdrlen -=2;
}
if(hdrlen > 0)
{
data_H=*addr;
data_L=0x00;
chksum16=make16(data_H,data_L);
hdr_chksum = hdr_chksum + chksum16;
}
}
//******************************************************************
//* Initialize the RTL8019AS
//******************************************************************
void init_RTL8019AS()
{
fromrtl; // PORTA data lines = input
rtladdr(0x00); // clear address lines
SET_ETH_IOWB; // disable IOW
SET_ETH_IORB; // disable IOR
SET_ETH_RSTDRV; // put NIC in reset
delay_ms(2); // delay at least 1.6ms
CLR_ETH_RSTDRV; // disable reset line
read_rtl(RSTPORT); // read contents of reset port
write_rtl(RSTPORT,byte_read); // do soft reset
delay_ms(10); // give it time
read_rtl(ISR); // check for good soft reset
if(!(byte_read & RST))
{
printf("RTL8019 Init Failed..\r\n");
show_regs();
while(1);
}
write_rtl(CR,0x21); // stop the NIC, abort DMA, page 0
delay_ms(2); // make sure nothing is coming in or going out
write_rtl(DCR,dcrval); // 0x58
write_rtl(RBCR0,0x00);
write_rtl(RBCR1,0x00);
write_rtl(RCR,0x04);
write_rtl(TPSR,txstart);
write_rtl(TCR,0x02);
write_rtl(PSTART,rxstart);
write_rtl(BNRY,rxstart);
write_rtl(PSTOP,rxstop);
write_rtl(CR,0x61);
delay_ms(2);
write_rtl(CURR,rxstart);
for(i=0;i<6;++i)
write_rtl(PAR0+i, MYMAC[i]);
write_rtl(CR,0x21);
write_rtl(DCR,dcrval);
write_rtl(CR,0x22);
write_rtl(ISR,0xFF);
write_rtl(IMR,imrval);
write_rtl(TCR,tcrval);
}
//******************************************************************
//* Perform ARP Response
//* This routine supplies a requesting computer with the
//* Ethernet modules's MAC (hardware) address.
//******************************************************************
void arp()
{
//start the NIC
write_rtl(CR,0x22);
//load beginning page for transmit buffer
write_rtl(TPSR,txstart);
//set start address for remote DMA operation
write_rtl(RSAR0,0x00);
write_rtl(RSAR1,0x40);
//clear the Interrupts
write_rtl(ISR,0xFF);
//load data byte count for remote DMA
write_rtl(RBCR0,0x3C);
write_rtl(RBCR1,0x00);
//do remote write operation
write_rtl(CR,0x12);
//write destination MAC address
for(i=0;i<6;++i)
write_rtl(RDMAPORT,packet[enetpacketSrc0+i]);
//write source MAC address
for(i=0;i<6;++i)
write_rtl(RDMAPORT,MYMAC[i]);
//write typelen hwtype prtype hwlen prlen op:
addr = &packet[enetpacketType0];
packet[arp_op+1] = 0x02;
for(i=0;i<10;++i)
write_rtl(RDMAPORT,*addr++);
//write ethernet module MAC address
for(i=0;i<6;++i)
write_rtl(RDMAPORT,MYMAC[i]);
//write ethernet module IP address
for(i=0;i<4;++i)
write_rtl(RDMAPORT,MYIP[i]);
//write remote MAC address
for(i=0;i<6;++i)
write_rtl(RDMAPORT,packet[enetpacketSrc0+i]);
//write remote IP address
for(i=0;i<4;++i)
write_rtl(RDMAPORT,packet[arp_sipaddr+i]);
//write some pad characters to fill out the packet to
//the minimum length
for(i=0;i<0x12;++i)
write_rtl(RDMAPORT,0x00);
//make sure the DMA operation has successfully completed
byte_read = 0;
while(!(byte_read & RDC))
read_rtl(ISR);
//load number of bytes to be transmitted
write_rtl(TBCR0,0x3C);
write_rtl(TBCR1,0x00);
//send the contents of the transmit buffer onto the network
write_rtl(CR,0x24);
}
//******************************************************************
//* Perform ICMP Function
//* This routine responds to a ping.
//******************************************************************
void icmp()
{
//set echo reply
packet[ICMP_type]=0x00;
packet[ICMP_code]=0x00;
//clear the ICMP checksum
packet[ICMP_cksum ]=0x00;
packet[ICMP_cksum+1]=0x00;
//setup the IP header
setipaddrs();
//calculate the ICMP checksum
hdr_chksum =0;
hdrlen = (make16(packet[ip_pktlen],packet[ip_pktlen+1])) - \
((packet[ip_vers_len] & 0x0F) * 4);
addr = &packet[ICMP_type];
cksum();
chksum16= ~(hdr_chksum + ((hdr_chksum & 0xFFFF0000) >> 16));
packet[ICMP_cksum] = make8(chksum16,1);
packet[ICMP_cksum+1] = make8(chksum16,0);
//send the ICMP packet along on its way
echo_packet();
}
//USART1 initialisation
// desired baud rate:57600
// actual baud rate:57599 (0.0%)
// char size: 8 bit
// parity: Disabled
void init_usart1(void)
{
UCSR1B = 0x00; //disable while setting baud rate
UCSR1A = 0x00;
UCSR1C = 0x06;
UBRR1L = 0x0F; //set baud rate lo
UBRR1H = 0x00; //set baud rate hi
UCSR1B = 0x18;
/* flush receive buffer */
USART_RxTail = 0x00;
USART_RxHead = 0x00;
USART_TxTail = 0x00;
USART_TxHead = 0x00;
}
void USART_RX_interrupt( void )
{
unsigned char data;
unsigned char tmphead;
data = UDR1; /* read the received data */
/* calculate buffer index */
tmphead = ( USART_RxHead + 1 ) & USART_RX_BUFFER_MASK;
USART_RxHead = tmphead; /* store new index */
if ( tmphead == USART_RxTail )
{
/* ERROR! Receive buffer overflow */
}
USART_RxBuf[tmphead] = data; /* store received data in buffer */
}
//interrupt [iv_USART_UDRE]
void USART_TX_interrupt( void )
{
unsigned char tmptail;
/* check if all data is transmitted */
if ( USART_TxHead != USART_TxTail )
{
/* calculate buffer index */
tmptail = ( USART_TxTail + 1 ) & USART_TX_BUFFER_MASK;
USART_TxTail = tmptail; /* store new index */
UDR1 = USART_TxBuf[tmptail]; /* start transmition */
}
else
{
UCSR1B &= ~(1<<UDRIE1); /* disable UDRE interrupt */
}
}
/* Read and write functions */
int recvchar( void )
{
unsigned char tmptail;
/* wait for incomming data */
while ( USART_RxHead == USART_RxTail );
/* calculate buffer index */
tmptail = ( USART_RxTail + 1 ) & USART_RX_BUFFER_MASK;
USART_RxTail = tmptail; /* store new index */
return USART_RxBuf[tmptail]; /* return data */
}
int sendchar( int data )
{
unsigned char tmphead;
/* calculate buffer index */
tmphead = ( USART_TxHead + 1 ) & USART_TX_BUFFER_MASK;
/* wait for free space in buffer */
while ( tmphead == USART_TxTail );
/* store data in buffer */
USART_TxBuf[tmphead] = (unsigned char)data;
USART_TxHead = tmphead; /* store new index */
UCSR1B |= (1<<UDRIE1); /* enable UDRE interrupt */
return data;
}
unsigned char CharInQueue(void)
{
return(USART_RxHead != USART_RxTail);
}
//******************************************************************
//* MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN MAIN
//******************************************************************
// THIS CODE READS AND WRITES EVERY LBA-ADDRESSED SECTOR OF YOUR DRIVE
// AND REPORTS ERRORS WHEN IT ENCOUNTERS THEM.. THIS CAN RUN FOR A DAY OR SO..
// ADAPT IT TO YOUR APPLICATION FOR NOW..
// ARP AND PING ARE FUNCTIONAL WITHOUT CODE MODS.. TCP AND UDP FUNCTIONS ARE
// PRESENT BUT THERE IS NO APPLICATION CODE DRIVING THEM HERE
void C_task main()
{
unsigned int j;
unsigned long bigsector,k;
unsigned char stopcode,result,gotreg;
CLI(); //disable all interrupts
DDRA = 0x00;
PORTA = 0xFF;
DDRB = 0x00;
PORTB = 0xFF;
DDRC = 0x00;
PORTC = 0xFF;
DDRD = 0xFE;
PORTD = 0x01;
DDRE = 0x1F;
PORTE = 0xE0;
DDRF = 0xFF;
PORTF = 0xFF;
DDRG = 0x1F;
PORTG = 0xFB;
init_usart1();
init_RTL8019AS();
clr_synflag;
clr_finflag;
SEI(); //re-enable
delay_ms(20000); // this is for initial spin up
init_ata();
ata_identi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -