📄 ata_if.c
字号:
//*****************************************************************
//
// File Name : 'ata_if.c'
// Title : IDE-ATA interface driver
// Author : Pascal Stang
// Date : 11/22/2000
// Version : 0.1
// Target MCU : ATmega103
// Editor Tabs : 4
//
//*****************************************************************
#ifndef WIN32
#include <io.h>
#include <interrupt.h>
#include <signal.h>
#include <progmem.h>
#endif
#include "global.h"
#include "systimer.h"
#include "uart.h"
#include "ata_if.h"
//#define DEBUG_ATA 1
//----------------------------------------------------------------------------
// Select address and CS signals
//
// addressing bits
// 35 DA0 A0 0x01 Address Line 0
// 33 DA1 A1 0x02 Address Line 1
// 36 DA2 A2 0x04 Address Line 2
//
// chip selects
// 37 CS0 A3 0x08 Command Block Select
// 38 CS1 A4 0x10 Control Block Select
//
//
//----------------------------------------------------------------------------
struct
{
u16 cyls;
u08 heads;
u08 sectors;
} ataDiskParam;
void ataInit(void)
{
// initialize disk parameters
ataDiskParam.cyls = ATA_DISKPARM_CLYS;
ataDiskParam.heads = ATA_DISKPARM_HEADS;
ataDiskParam.sectors = ATA_DISKPARM_SECTORS;
}
void ataDiskErr(void)
{
unsigned char b;
b = ataReadByte(ATA_REG_ERROR);
uartPrintStr("ATA Error: ");
uartPrintfu08(b);
uartPrintStr("\r\n");
/*
EOL();
b = ReadBYTE(CMD,1);
PRINT("Error Reg : "); UART_Printfu08(b); EOL();
b = ReadBYTE(CMD,2);
PRINT("Sector Cnt: "); UART_Printfu08(b); EOL();
b = ReadBYTE(CMD,3);
PRINT("Sector Nbr: "); UART_Printfu08(b); EOL();
b = ReadBYTE(CMD,4);
PRINT("Cylindr Lo: "); UART_Printfu08(b); EOL();
b = ReadBYTE(CMD,5);
PRINT("Cylindr Hi: "); UART_Printfu08(b); EOL();
b = ReadBYTE(CMD,6);
PRINT("Device/Hd : "); UART_Printfu08(b); EOL();
b = ReadBYTE(CMD,7);
PRINT("Status : "); UART_Printfu08(b); EOL();
*/
}
void ataPrintSector( u08 *Buffer)
{
u08 i;
u16 j;
u08 *buf;
u08 s;
buf = Buffer;
// print the low order address indicies
uartPrintStr(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF\r\n");
uartPrintStr(" ----------------------------------------------- ---- ASCII -----\r\n");
// print the data
for(j=0; j<0x20; j++)
{
// print the high order address index for this line
uartPrintfu16(j<<4);
uartPrintStr(" ");
// print the hex data
for(i=0; i<0x10; i++)
{
uartPrintfu08(buf[(j<<4)+i]);
uartPrintStr(" ");
}
// leave some space
uartPrintStr(" ");
// print the ascii data
for(i=0; i<0x10; i++)
{
s = buf[(j<<4)+i];
// make sure character is printable
if(s >= 0x20)
{
uartPrintChar(s);
}
else
{
uartPrintChar(0x20);
}
}
uartPrintStr("\r\n");
}
}
void ataReadDataBuffer(u08 *Buffer, u16 numBytes)
{
unsigned int i;
//sbi(MCUCR, SRW); // enable RAM waitstate
// read data from drive
for (i=0; i<(numBytes/16); i++)
{
// optimize by reading 16 bytes in-line before looping
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL);
*Buffer++ = *((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH);
}
//cbi(MCUCR, SRW); // disable RAM waitstate
}
void ataWriteDataBuffer(u08 *Buffer, u16 numBytes)
{
register unsigned char temp;
// unsigned char temp;
unsigned int i;
//sbi(MCUCR, SRW); // enable RAM waitstate
// write data to drive
for (i=0; i<(numBytes/16); i++)
{
// optimize by writing 16 bytes in-line before looping
// keep byte order correct by using temp register
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
temp = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAH) = *Buffer++;
*((volatile unsigned char*) ATA_REG_BASE + ATA_REG_DATAL) = temp;
}
//cbi(MCUCR, SRW); // disable RAM waitstate
}
u08 ataStatusWait(u08 mask, u08 waitStatus)
{
register u08 status;
delay(100);
// wait for desired status
while( ((status = ataReadByte(ATA_REG_CMDSTATUS1)) & mask) == waitStatus );
return status;
}
//----------------------------------------------------------------------------
// Read one sector, identified by drive, head, track and sector
// Returns contents of the Error Register (0x00 is no error detected)
//----------------------------------------------------------------------------
unsigned char ataReadSectors( unsigned char Drive,
unsigned char Head,
unsigned int Track,
unsigned char Sector,
unsigned int numsectors,
unsigned char *Buffer)
{
unsigned char temp;
// Wait for drive to be ready
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
// Prepare parameters...
ataWriteByte(ATA_REG_HDDEVSEL, 0xA0+(Drive ? 0x10:00)+Head); // CHS mode/Drive/Head
ataWriteByte(ATA_REG_CYLHI, Track>>8); // MSB of track
ataWriteByte(ATA_REG_CYLLO, Track); // LSB of track
ataWriteByte(ATA_REG_STARTSEC, Sector); // sector
ataWriteByte(ATA_REG_SECCOUNT, numsectors); // # of sectors
// Issue read sector command...
ataWriteByte(ATA_REG_CMDSTATUS1, 0x21);
// Wait for drive to be ready
temp = ataStatusWait(ATA_SR_BSY, ATA_SR_BSY);
if (temp & ATA_SR_ERR)
{
uartPrintStr("RD ERR\r\n");
return 1;
}
// Wait for drive to request data transfer
ataStatusWait(ATA_SR_DRQ, 0);
// read data from drive
ataReadDataBuffer(Buffer, 512*numsectors);
// Return the error bit from the status register...
temp = ataReadByte(ATA_REG_CMDSTATUS1); // read status register
return (temp & ATA_SR_ERR) ? 1:0;
}
unsigned char ataWriteSectors( unsigned char Drive,
unsigned char Head,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -