/*
* Copyright 2005 by Spectrum Digital Incorporated.
* All rights reserved. Property of Spectrum Digital Incorporated.
*
* Not for distribution.
*/
/*
* ATA Implementation
*
*/
/*
* Note: With the PLL set to 459 MHz and the default timing settings used
* the period in ULTRA DMA mode is about 60%-80% above spec.
* The Ultra DMA mode does work properly, but the throughput on writing
* to the harddrive will be much slower.
*/
#include "stdio.h"
#include "ata.h"
/* ------------------------------------------------------------------------ *
* *
* ATA_init( ) *
* *
* ------------------------------------------------------------------------ */
Int16 ATA_init( )
{
DAVINCIEVM_PMX_set( 0x00030000, 0 ); // Enable ATA pinmux
/*
* Configure ATA Controller for default mode ( PIO mode )
*/
ATA_IDETIMP = 0x8000; // Primary PIO mode
ATA_IDETIMS = 0x0000; // Secondary off
ATA_SIDETIM = 0x00; // Secondary IDE timing
ATA_SLEWCTL_L = 0x00; // Slew rate is 0
ATA_SLEWCTL_H = 0x00; // Slew rate is 0
ATA_IDESTATUS = 0x03; // IDE Status
ATA_UDMACTL = 0x0000; // Ultra DMA OFF
ATA_UDMATIM = 0x0000; // Ultra DMA timing
ATA_MISCCTL = 0x00000200; // Release ATA from reset
ATA_IDETIMP = 0x8000; // Primary PIO mode
PINMUX0&=0xffffffe0;
/* DAVINCIEVM_GPIO_setDirection(26,0);
DAVINCIEVM_GPIO_setOutput(26,0);
DAVINCIEVM_waitusec( 1000 );
DAVINCIEVM_GPIO_setOutput(26,1);
DAVINCIEVM_waitusec( 1000 );
DAVINCIEVM_waitusec( 1000 );
DAVINCIEVM_waitusec( 1000 );*/
DAVINCIEVM_GPIO_setDirection(40,0);
DAVINCIEVM_GPIO_setOutput(40,0);
DAVINCIEVM_GPIO_setDirection(16,0);
DAVINCIEVM_GPIO_setOutput(16,0);
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* ATA_changeMode( ata_mode ) *
* *
* ------------------------------------------------------------------------ */
Int16 ATA_changeMode( Uint8 ata_mode )
{
Uint8 transfer_number = ata_mode & 0x07;
Uint8 transfer_mode = ata_mode & 0xF8;
if ( transfer_mode == ULTRA_DMA_MODE )
{
/* DMA Engine */
ATA_BMICP_PRI = 0x0000; // Primary DMA control
ATA_BMISP_PRI = 0x000E; // Primary DMA status
ATA_BMIDTP_PRI = ATA_PRD_TABLE; // Primary DMA PRD
ATA_BMICS_SEC = 0x0000; // Secondary DMA control
ATA_BMISS_SEC = 0x000E; // Secondary DMA status
ATA_BMIDTP_SEC = 0x0000; // Secondary DMA PRD
ATA_UDMACTL = 0x0003; // Ultra DMA ON
ATA_UDMATIM = 0 // Ultra DMA timing
| ( transfer_number << 4 )
| ( transfer_number << 0 )
;
}
if ( transfer_mode == MULTIWORD_DMA_MODE )
{
/* DMA Engine */
ATA_BMICP_PRI = 0x0000; // Primary DMA control
ATA_BMISP_PRI = 0x000E; // Primary DMA status
ATA_BMIDTP_PRI = ATA_PRD_TABLE; // Primary DMA PRD
ATA_BMICS_SEC = 0x0000; // Secondary DMA control
ATA_BMISS_SEC = 0x000E; // Secondary DMA status
ATA_BMIDTP_SEC = 0x0000; // Secondary DMA PRD
ATA_UDMACTL = 0x0000; // Ultra DMA OFF
ATA_UDMATIM = 0x0000; // Ultra DMA timing
}
if ( transfer_mode == PIO_MODE )
{
ATA_UDMACTL = 0x0000; // Ultra DMA OFF
ATA_UDMATIM = 0x0000; // Ultra DMA timing
}
ATA_setfeature( 0x03, ata_mode ); // Set transfer mode on harddrive
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* waitWhileBSYHigh( timeout ) *
* *
* timeout: in cycles *
* *
* ------------------------------------------------------------------------ */
Int16 waitWhileBSYHigh( Uint32 timeout )
{
Uint32 timecount = 0;
while ( ( PRI_ATA_STATUS & 0x80 ) == 0x80 ) // Wait for signal to change
{
if ( ++timecount >= timeout )
{
printf( " ****BSY TIMEOUT occured****\n" );
return 1;
}
}
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* waitWhileDRDYLow( timeout ) *
* *
* timeout: in cycles *
* *
* ------------------------------------------------------------------------ */
Int16 waitWhileDRDYLow( Uint32 timeout )
{
Uint32 timecount = 0;
while ( ( PRI_ATA_STATUS & 0x40 ) == 0x00 ) // Wait for signal to change
{
if ( ++timecount >= timeout )
{
printf( " ****DRDY TIMEOUT occured****\n" );
return 1;
}
}
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* waitWhileIntrqLow( timeout ) *
* *
* timeout: in cycles *
* *
* ------------------------------------------------------------------------ */
Int16 waitWhileIntrqLow( Uint32 timeout )
{
Uint32 timecount = 0;
while ( ( ATA_IDESTATUS & 0x20 ) == 0x00 ) // Wait for signal to change
{
if ( ++timecount >= timeout )
{
printf( " ****Intrq TIMEOUT occured****\n" );
return 1;
}
}
return 0;
}
/* ------------------------------------------------------------------------ *
* *
* ATA_issueCommand( command, sector ) *
* *
* command: command code *
* sector: sector *
* *
* ------------------------------------------------------------------------ */
Int16 ATA_issueCommand( Uint8 command, Uint32 sector )
{
waitWhileDRDYLow( (Uint32)(-1
ata.rar_ata_visual c
版权申诉
193 浏览量
2022-09-14
17:23:46
上传
评论
收藏 122KB RAR 举报
钱亚锋
- 粉丝: 89
- 资源: 1万+