|
/*********************************************************************************** * File : ide_access.C * Processor : ADSP-BF533 * IDDE : VisualDSP++3.5 * Description : define bunch of IDE driver interface functions to FAT including: * * fnIDE_SectorByte(); * funIDE_WriteSectorByte(); * fnIDE_SectorWord(); * fnIDE_SectorDWORD(); * fnIDE_SectorData(); * fnIDE_WriteSectorData(); * fnIDE_BufferSector(); * fnIDE_WriteBufferSector(); * fnIDE_InitDrive(); * ***********************************************************************************/
#include "ide_base.h" #include "ide_access.h" #include "type.h"
IDE_BUFFER buffers;
IDE_DRIVER IDE_current;
/********************************************************************************** * Function : nIDE_SectorByte * Description : Read one byte from a specified address of current sector * Input : WORD Sublocation * Return : one byte value ***********************************************************************************/
BYTE fnIDE_SectorByte(WORD sublocation) { BYTE data=0; data=buffers.currentsector.u8data[sublocation]; // Read Data from specified pos return (data); }
/********************************************************************************** * Function : fnIDE_WriteSectorByte * Description : write one byte to a specified address of current sector * Input : WORD Sublocation * Return : one byte written value ***********************************************************************************/
BYTE fnIDE_WriteSectorByte(WORD sublocation, BYTE value) { buffers.currentsector.u8data[sublocation]=value; return (value); }
/********************************************************************************** * Function : fnIDE_SectorWord * Description : read one word from a specified address of current sector * Input : WORD Sublocation * Return : one word read value ***********************************************************************************/
WORD fnIDE_SectorWord(WORD sublocation) // Return Word at position specified { WORD data=0; data =buffers.currentsector.u8data[sublocation]; // Read Data from specified pos data +=buffers.currentsector.u8data[sublocation+1]<<8; return (data); // Return value }
/********************************************************************************** * Function : fnIDE_SectorDWord * Description : read double word from a specified address of current sector * Input : WORD Sublocation * Return : double word read value ***********************************************************************************/
DWORD fnIDE_SectorDWORD(WORD sublocation) // Return Word at position specified { DWORD data=0; data =buffers.currentsector.u8data[sublocation]; // Read Data from specified pos data +=buffers.currentsector.u8data[sublocation+1]<<8; data +=buffers.currentsector.u8data[sublocation+2]<<16; data +=buffers.currentsector.u8data[sublocation+3]<<24; return (data); // Return value }
/********************************************************************************** * Function : fnIDE_SectorData * Description : read a section of data from a specified starting address of current sector * Input : WORD Sublocation - starting address * BYTE *buffer - reading data buffer * WORD size - size of reading data section ***********************************************************************************/
void fnIDE_SectorData(WORD sublocation, BYTE *buffer, WORD size) { WORD i; for(i=0;i<size;i++) { buffer[i]=buffers.currentsector.u8data[sublocation+i]; } }
/********************************************************************************** * Function : fnIDE_WriteSectorData * Description : write a section of data from a specified starting address of current sector * Input : WORD Sublocation - starting address * BYTE *buffer - writing data buffer * WORD size - size of writing data section * Return : double word read value ***********************************************************************************/
void fnIDE_WriteSectorData(WORD sublocation, BYTE *buffer, WORD size) { WORD i; for(i=0;i<size;i++) { buffers.currentsector.u8data[sublocation+i]=buffer[i]; } }
/********************************************************************************** * Function : fnIDE_BufferSector * Description : read a specified logic sector * Input : BYTE *buffer - reading data buffer * DWORD LBALocation - address of logic sector * BYTE count - counts of reading sectors(up to 256), count=0 means read 256 sectors * Return : 0-normal; 1-error ***********************************************************************************/
int fnIDE_BufferSector(WORD *buf,DWORD LBALocation,BYTE count) { WORD i,temp; BYTE j; BYTE errorcode;
Wait_ReadyBusy(); buffers.SectorCurrentlyLoaded=LBALocation; // update current sector loaded *pDriveHead =((LBALocation >> 24) & 0xFF) | 0xE0; *pCylinderHigh =(LBALocation >> 16) & 0xFF; *pCylinderLow =(LBALocation >> 8) & 0xFF; *pSectorNumber =LBALocation & 0xFF; *pSectorCount = count; *pCommand = 0x21;//IDE_CMD_READSECTOR; // Read sector Wait_DRQ(); j=count; temp=0; do { Wait_DRQ(); for(i=0; i < SECTORWORDSIZE; i++) { buf[temp+i]=*pDataPort; } j--; temp += SECTORWORDSIZE ; }while(j!=0); errorcode = CheckforError(); if (errorcode!=0) return 1; return 0; }
/********************************************************************************** * Function : fnIDE_WriteBufferSector * Description : write a specified logic sector * Input : BYTE *buffer - writing data buffer * DWORD LBALocation - address of logic sector * BYTE count - counts of writing sectors(up to 256), count=0 means write 256 sectors * Return : 0-normal; 1-error ***********************************************************************************/
int fnIDE_WriteBufferSector(WORD *buf,DWORD LBALocation,BYTE count) { WORD i,temp; BYTE j; BYTE errorcode; if (LBALocation>=IDE_current.maxLBA) { printf("\r\nIDE_BufferSector: Out of Range Disc Read of 0x%lx", LBALocation); return 1; } Wait_ReadyBusy(); //if (buffers.SectorCurrentlyLoaded!=LBALocation) // Dont reload if already loaded //{ buffers.SectorCurrentlyLoaded=LBALocation; // update current sector loaded *pDriveHead =((LBALocation >> 24) & 0xFF) | 0xE0;//bit6=1:LBA mode bit6=0:CHS mode *pCylinderHigh =(LBALocation >> 16) & 0xFF; *pCylinderLow =(LBALocation >> 8) & 0xFF; *pSectorNumber =LBALocation & 0xFF; //} /*temp= (LBALocation/IDE_current.head_num)/IDE_current.one_cylinder_sector; *pDriveHead= (LBALocation/IDE_current.one_cylinder_sector)%IDE_current.head_num; *pCylinderHigh =(temp>>8)&0xFF; *pCylinderLow =temp&0xFF; *pSectorNumber =(LBALocation%IDE_current.one_cylinder_sector)+1;*/ *pSectorCount = count; // 1 Sector to be read only *pCommand = 0x31;//IDE_CMD_READSECTOR; // Read sector /*errorcode = CheckforError(); if (errorcode!=0) return 1; // Were there any Errors ? */ Wait_DRQ(); // Wait till Data is available in IDE buffer j=count; temp=0; // Reading Status Register reset INT too do { Wait_DRQ(); for(i=0; i < SECTORWORDSIZE; i++) { *pDataPort=buf[temp+i]; } j--; temp += SECTORWORDSIZE ; }while(j!=0); errorcode = CheckforError(); if (errorcode!=0) return 1; // Were there any Errors ? //} return 0; } /********************************************************************************** * Function : fnIDE_InitDrive * Description : get HD information * Input : none * Return : none ***********************************************************************************/
void fnIDE_InitDrive(void) { WORD i,cnt; BYTE chardata; DWORD TotalLBAs=0; IdeIdle(); // Wait till not busy and RDY? Wait_ReadyBusy();
// Send Command for drive identification *pCommand = IDE_CMD_IDENTIFY; // Wait for DRQ Wait_DRQ();
// Read in first 62 bytes of the drive identification for (i=0; i<256; i++) { // Read data words from drives buffer buffers.currentsector.u16data[i] = *pDataPort; } buffers.SectorCurrentlyLoaded=0xFFFFFFFF;
// Assuming drive supports LBA find max LBA sector TotalLBAs = buffers.currentsector.u16data[61]; TotalLBAs = TotalLBAs << 16; IDE_current.maxLBA = TotalLBAs + buffers.currentsector.u16data[60]; IDE_current.head_num = buffers.currentsector.u16data[3]; IDE_current.cylinder_num = buffers.currentsector.u16data[1]; IDE_current.one_cylinder_sector = buffers.currentsector.u16data[6]; i=0; for (cnt=10; cnt<19; cnt++) { chardata = buffers.currentsector.u16data[cnt]>>8; IDE_current.serialnum[i] = chardata; i++; chardata = buffers.currentsector.u16data[cnt]; IDE_current.serialnum[i] = chardata; i++; } IDE_current.serialnum[i]='\0'; i=0; for (cnt=27; cnt<46; cnt++) { chardata = buffers.currentsector.u16data[cnt]>>8; IDE_current.modelnum[i] = chardata; i++; chardata = buffers.currentsector.u16data[cnt]; IDE_current.modelnum[i] = chardata; i++; } IDE_current.modelnum[i] = '\0' ; #ifdef DEBUG printf("\r\nHard Disc Auto Detect Parameters"); printf("\r\n--------------------------------\r\n"); // Detect HDD or CDROM printf("\r\nType of device: "); if (buffers.currentsector.u16data[0]&0x8000) printf("ATA Device "); else printf("ATAPI Device "); // Detect removable media if (buffers.currentsector.u16data[i]&0x0080) printf("which has removable media");
// Heads printf("\r\nThe number of heads is = %d",IDE_current.head_num); // Cylinders printf("\r\nThe number of Cylinders is = %d",IDE_current.cylinder_num);
// Sectors Per Track printf("\r\nThe number of Sectors per track is = %d", IDE_current.one_cylinder_sector);
// Serial Number printf("\r\nThe number of Serial Number of the device is = %s",IDE_current.serialnum); // Model Number printf("\r\nThe number of Model Number of the device is = %s",IDE_current.modelnum); // CHS or LBA if(!((buffers.currentsector.u16data[49] >> 8) & 0x1)) printf("\r\nCHS Mode Only (NO LBA)"); else printf("\r\nLBA Supported"); // Report max lba address printf("\r\nLBA sectors is 0x%lx\n", TotalLBAs); #endif }
|