⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata.c

📁 atmelmega128ATA驱动内含FAT32源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//*   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 + -