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

📄 ata.c

📁 atmelmega128ATA驱动内含FAT32源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//AVR ATA DRIVE CONTROLLER
//VERSION 1.0
//EDTP ELECTRONICS
//09/23/02002
//*******************************************
// THIS IS "LIVING" CODE AND WILL EVOLVE OVER TIME.
//*******************************************
//NOTES:
//		06/20/2002  First code release PING IS IMPLEMENTED ONLY
//		07/01/2002	corrected endian-ness in read sector routine
//		08/06/2002  upped packet len to 1518 bytes
//      09/23/2002  cleaned up core routines

#include <iom128v.h>
#include <macros.h>
#include <string.h>
#include "mega128stdio.h"  // allows printf to work on USART1

#pragma interrupt_handler USART_RX_interrupt:iv_USART1_RX    
#pragma interrupt_handler USART_TX_interrupt:iv_USART1_UDRE  

//******************************************************************
//*	FUNCTION PROTOTYPES
//******************************************************************
unsigned char ata_read_sector(unsigned char device, unsigned long lbasector \
                               ,unsigned int page);
unsigned char ata_write_sector(unsigned char device, unsigned long lbasector  \
                               ,unsigned int page);
void ata_select_device(unsigned char device);
unsigned int ata_write_word(unsigned int wordout);
void ram_fill_page(unsigned int page,unsigned int dataword);
void ram_read_page(unsigned int page);
void init_ata(void);
void ata_identify(void);
unsigned int ata_read_word(void);
void ata_write_byte(unsigned char atabyte);
void ata_set_io_addr(unsigned char ataaddr);
void ata_send_cmd(unsigned char atacmd);
unsigned char ata_get_status_byte(void);
void ata_hard_reset(void);
unsigned int ata_rdy(void);
unsigned int ata_bsy(void);
unsigned int ata_drq(void);
unsigned int ata_err(void);
int recvchar( void );
int putchar(int);
int sendchar( int );
unsigned char CharInQueue(void);
void init_usart1(void);
void delay_ms(unsigned int delay);
void delay_us(unsigned int delay);
void show_aux_packet(void);
void dump_header(void);
void readwrite(void);
void bin2hex(unsigned char binchar);
void show_regs(void);
void show_packet(void);
void cls(void);
void application_code(void);
void tcp(void);
void assemble_ack(void);
void write_rtl(unsigned int regaddr, unsigned int regdata);
void read_rtl(unsigned int regaddr);
void get_packet(void);
void setipaddrs(void);
void cksum(void);
void echo_packet(void);
void send_tcp_packet(void);
void arp(void);
void icmp(void);
void udp(void);
void rtladdr(unsigned char val);

#include "putchar.c"

//#define debug

#define USART_RX_BUFFER_SIZE  16       /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
//#if ( USART_RX_BUFFER_SIZE & USART_RX_BUFFER_MASK )
//#error RX buffer size is not a power of 2
//#endif
#define USART_TX_BUFFER_SIZE  128      /* 1,2,4,8,16,32,64,128 or 256 bytes */
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )
//#if ( USART_TX_BUFFER_SIZE & USART_TX_BUFFER_MASK )
//#error TX buffer size is not a power of 2
//#endif
//******************************************************************
//*	AVR RAM Definitions
//******************************************************************
unsigned char USART_RxBuf[USART_RX_BUFFER_SIZE],USART_TxBuf[USART_TX_BUFFER_SIZE];
unsigned char USART_TxHead,USART_TxTail,USART_RxHead,USART_RxTail;

unsigned char aux_data[512];            //tcp received data area
unsigned char ram_page_buffer[512];
unsigned char *addr,flags,last_line;
unsigned char byte_read,data_H,data_L;
unsigned char high_nibble, low_nibble, high_char, low_char,resend;
unsigned int i,txlen,rxlen,chksum16,hdrlen,tcplen,tcpdatalen_in,word_read;
unsigned int tcpdatalen_out,ISN,portaddr,ip_packet_len;
unsigned long hdr_chksum,my_seqnum,client_seqnum,incoming_ack,expected_ack;

#define nop		   NOP()
#define esc   	   0x1B

// CB_ERR ERROR REGISTER BITS 
#define ATA_ER_BBK  0x80    // ATA bad block
#define ATA_ER_UNC  0x40    // ATA uncorrected error
#define ATA_ER_MC   0x20    // ATA media change
#define ATA_ER_IDNF 0x10    // ATA id not found
#define ATA_ER_MCR  0x08    // ATA media change request
#define ATA_ER_ABRT 0x04    // ATA command aborted
#define ATA_ER_NTK0 0x02    // ATA track 0 not found
#define ATA_ER_NDAM 0x01    // ATA address mark not found
// CB_DH bits 7-4 OF THE DEVICE/HEAD REGISTER
#define ATA_DH_DEV0 0xE0    // select device 0 LBA MODE
#define ATA_DH_DEV1 0xF0    // select device 1 LBA MODE
// CB_STAT REGISTER BITS
#define ATA_STAT_BSY  0x80  // ATA busy
#define ATA_STAT_RDY  0x40  // ATA ready
#define ATA_STAT_DF   0x20  // ATA device fault
#define ATA_STAT_SKC  0x10  // ATA seek complete
#define ATA_STAT_DRQ  0x08  // ATA data request
#define ATA_STAT_CORR 0x04  // ATA corrected
#define ATA_STAT_IDX  0x02  // ATA index
#define ATA_STAT_ERR  0x01  // ATA error 
// CB_DC REGISTER BITS
#define ATA_DC_HD15   0x08  // bit should always be set to one
#define ATA_DC_SRST   0x04  // soft reset
#define ATA_DC_NIEN   0x02  // disable interrupts
//ATA commands (from ATA-3),
#define CMD_CFA_ERASE_SECTORS            0xC0
#define CMD_CFA_REQUEST_EXT_ERR_CODE     0x03
#define CMD_CFA_TRANSLATE_SECTOR         0x87
#define CMD_CFA_WRITE_MULTIPLE_WO_ERASE  0xCD
#define CMD_CFA_WRITE_SECTORS_WO_ERASE   0x38
#define CMD_CHECK_POWER_MODE1            0xE5
#define CMD_CHECK_POWER_MODE2            0x98
#define CMD_DEVICE_RESET                 0x08
#define CMD_EXECUTE_DEVICE_DIAGNOSTIC    0x90
#define CMD_FLUSH_CACHE                  0xE7
#define CMD_FORMAT_TRACK                 0x50
#define CMD_IDENTIFY_DEVICE              0xEC
#define CMD_IDENTIFY_DEVICE_PACKET       0xA1
#define CMD_IDENTIFY_PACKET_DEVICE       0xA1
#define CMD_IDLE1                        0xE3
#define CMD_IDLE2                        0x97
#define CMD_IDLE_IMMEDIATE1              0xE1
#define CMD_IDLE_IMMEDIATE2              0x95
#define CMD_INITIALIZE_DRIVE_PARAMETERS  0x91
#define CMD_INITIALIZE_DEVICE_PARAMETERS 0x91
#define CMD_NOP                          0x00
#define CMD_PACKET                       0xA0
#define CMD_READ_BUFFER                  0xE4
#define CMD_READ_DMA                     0xC8
#define CMD_READ_DMA_QUEUED              0xC7
#define CMD_READ_MULTIPLE                0xC4
#define CMD_READ_SECTORS                 0x20
#define CMD_READ_VERIFY_SECTORS          0x40
#define CMD_RECALIBRATE                  0x10
#define CMD_SEEK                         0x70
#define CMD_SET_FEATURES                 0xEF
#define CMD_SET_MULTIPLE_MODE            0xC6
#define CMD_SLEEP1                       0xE6
#define CMD_SLEEP2                       0x99
#define CMD_STANDBY1                     0xE2
#define CMD_STANDBY2                     0x96
#define CMD_STANDBY_IMMEDIATE1           0xE0
#define CMD_STANDBY_IMMEDIATE2           0x94
#define CMD_WRITE_BUFFER                 0xE8
#define CMD_WRITE_DMA                    0xCA
#define CMD_WRITE_DMA_QUEUED             0xCC
#define CMD_WRITE_MULTIPLE               0xC5
#define CMD_WRITE_SECTORS                0x30
#define CMD_WRITE_VERIFY                 0x3C
//ATA I/O PORT FUNCTIONS AND ADDRESS DEFINITIONS
//*CONTROL BLOCK REGISTERS
//		   		 		  	 		 	   RESET
//										   |DIOW
//										   ||DIOR
//										   |||DA0
//										   ||||DA1
//										   |||||DA2
//										   ||||||CS0
//										   |||||||CS1
//										   ||||||||	
#define ATA_IO_HIZ		 	 		     0b11111111
#define ATA_IO_ASTAT					 0b11101110
#define ATA_IO_DEVICECNTL				 0b11101110
//*COMMAND BLOCK REGISTER ADDRESSES
#define ATA_IO_DATA						 0b11100001
#define ATA_IO_ERROR					 0b11110001
#define ATA_IO_FEATURES					 0b11110001
#define ATA_IO_SECTORCNT				 0b11101001
#define ATA_IO_SECTORNUM				 0b11111001
#define ATA_IO_CYL_L					 0b11100101
#define ATA_IO_CYL_H					 0b11110101
#define ATA_IO_DEVICE_HEAD				 0b11101101
#define ATA_IO_STATUS					 0b11111101
#define ATA_IO_CMD					 	 0b11111101
//ATMega128 PIN DEFINITIONS
//ATA Drive
#define PORT_RAM_CNTRL_DDR 				 DDRG
#define PORT_RAM_CNTL	   				 PORTG
#define PORT_ATA_DATA_L_DDR				 DDRA
#define PORT_ATA_DATA_H_DDR				 DDRC
#define PORT_ATA_DATA_L_OUT  		 	 PORTA
#define PORT_ATA_DATA_H_OUT				 PORTC
#define PORT_ATA_DATA_L_IN  		 	 PINA
#define PORT_ATA_DATA_H_IN				 PINC
#define PORT_ATA_IO_CNTL_DDR			 DDRF
#define PORT_ATA_IO_CNTL			 	 PORTF
#define	ATA_INTRQ					 	 0x01
#define ATA_CS1						 	 0x01
#define ATA_CS0						 	 0x02
#define ATA_DA2						 	 0x04
#define ATA_DA1						 	 0x08
#define ATA_DA0						 	 0x10
#define ATA_DIOR					 	 0x20
#define ATA_DIOW					 	 0x40
#define ATA_RESET					 	 0x80
//RS-232
#define RS232_CTS						 0x10
//External Buffer SRAM
#define RAM_WE	  	  				 	 0x01
#define RAM_CS						 	 0x02
#define RAM_LE	  	  				 	 0x04
#define ram_on 							 PORT_RAM_CNTL &= ~RAM_CS;
#define ram_off							 PORT_RAM_CNTL |= RAM_CS;
#define ram_write_pulse					 PORT_RAM_CNTL &= ~RAM_WE;  \
										 nop;		   	  			\
										 PORT_RAM_CNTL |= RAM_WE;
#define latch_ram_addr					 PORT_RAM_CNTL |= RAM_LE;  \
										 nop;		   	  		   \
										 PORT_RAM_CNTL &= ~RAM_LE;
#define avr_databus_in					 PORT_ATA_DATA_L_DDR = 0x00;  \
										 PORT_ATA_DATA_H_DDR = 0x00;
#define avr_databus_out					 PORT_ATA_DATA_L_DDR = 0xFF;  \
										 PORT_ATA_DATA_H_DDR = 0xFF;	
#define ata_write_pulse					 PORT_ATA_IO_CNTL &= ~ATA_DIOW;  \
										 delay_us(1);   	  			 \
										 PORT_ATA_IO_CNTL |= ATA_DIOW;
//#define ata_read_pulse										 
#define busy							 ata_bsy()
#define drq								 ata_drq()
#define error							 ata_err()
#define ready							 ata_rdy()	
#define hard_reset						 ata_hard_reset()	
#define select_device_0					 ata_select_device(0x00)
#define select_device_1					 ata_select_device(0x01)	
#define recalibrate						 ata_send_cmd(CMD_RECALIBRATE)
#define identify_device					 ata_send_cmd(CMD_IDENTIFY_DEVICE)						 
							 
//******************************************************************
//*	INITIALIZE DRIVE
//*   This routine assumes Drive 0 is the only drive attached.
//*   
//******************************************************************
void init_ata(void)
{
 #ifdef debug
 do{
 	ata_get_status_byte();
   }
 #endif   
 while(!ready & busy);
 hard_reset;
 delay_ms(10);
 #ifdef debug
 do{
 	ata_get_status_byte();
   }
  #endif  
 while(!ready & busy);
 select_device_0;
 #ifdef debug
 do{
 	ata_get_status_byte();
   }
  #endif 
  while(!ready & busy);
  recalibrate;

 #ifdef debug
 do{
 	ata_get_status_byte();
   }
 #endif 

 while(busy);
#ifdef debug   
  ata_set_io_addr(ATA_IO_SECTORCNT);
  ata_write_byte(0x3F);
  while(busy);
  ata_set_io_addr(ATA_IO_DEVICE_HEAD);
  ata_write_byte(0xAF); 
  while(busy);
  ata_send_cmd(CMD_INITIALIZE_DEVICE_PARAMETERS);
  while(busy);
 #endif
 if(error)
      printf("ERROR!");

  printf("\r\nDrive is READY!\r\n");
 
}
//******************************************************************
//*	SELECT ATA DEVICE
//*   This routine defaults to Drive 0 as the target drive.
//*   
//******************************************************************
void ata_select_device(unsigned char device)
{
  PORT_ATA_IO_CNTL = ATA_IO_DEVICE_HEAD;
  switch (device)
  {
   		 case 0x00:
		 	  ata_write_byte(ATA_DH_DEV0);
			  break;
  		 case 0x01:
		 	  ata_write_byte(ATA_DH_DEV1);
			  break;
		 default:
		 	  ata_write_byte(ATA_DH_DEV0);
		 	  break;
  }
}
//******************************************************************
//*	IDENTIFY ATA DEVICE
//*   This routine assumes Drive 0 is the target drive.
//*   
//******************************************************************										 									 									 
void ata_identify(void)
{
   ata_send_cmd(CMD_IDENTIFY_DEVICE);
   delay_us(1);
   while(busy);			 
   cls();
   while(!drq);
   word_read = ata_read_word();
   if(word_read & 0x8000)
    printf("\r\nATAPI Device Detected\r\n");
   else
    printf("\r\nATA Device Detected\r\n");
   if(word_read & 0x0080)
    printf("Removable Media Device Detected\r\n");
   if(word_read & 0x0040)
    printf("Nonremovable Media Device Detected\r\n");
   word_read = ata_read_word();
   printf("Number of Cylinders = %u\r\n",word_read);
   for(i=0;i<2;++i)
    word_read = ata_read_word();
   printf("Number of Logical Heads = %u\r\n",word_read);
   for(i=0;i<3;++i)
    word_read = ata_read_word();   
   printf("Number of Logical Sectors per Track = %u\r\n",word_read);
   for(i=0;i<3;++i)
    word_read = ata_read_word();   
   printf("Serial Number = ");
   for(i=0;i<10;++i)
   {
   	word_read = ata_read_word();
  	data_H = word_read >> 8;
	data_L = word_read & 0x00FF;
	printf("%c%c",data_H,data_L);
	}	
	printf("\r\n");
   for(i=0;i<7;++i)
      word_read = ata_read_word();
   printf("Model Number = ");
   for(i=0;i<20;++i)
   {
   	word_read = ata_read_word();
  	data_H = word_read >> 8;
	data_L = word_read & 0x00FF;
	printf("%c%c",data_H,data_L);
   }	
   for(i=0;i<209;++i)
   {
    word_read = ata_read_word();
	#ifdef debug
   	data_H = word_read >> 8;
	data_L = word_read & 0x00FF;
	printf("Word %X - %X\r\n",i,word_read);
	#endif
	}
}										 
//******************************************************************
//*	SET ATA I/O ADDRESS
//*   This routine sets the ATA I/O address.
//*   
//******************************************************************										 									 									 
void ata_set_io_addr(unsigned char ataaddr)
 {
  PORT_ATA_IO_CNTL = ataaddr; 
 }
//******************************************************************
//*	READ WORD FROM ATA DEVICE
//*   This routine does not use SRAM as a buffer.
//*   
//******************************************************************										 									 									 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -