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

📄 ata.c

📁 TI的DM6446的硬件平台搭建的相关例子
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  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( -1 );                         // Wait until drive is ready

    PRI_ATA_SECCNT      = 0x01;                     // Issue command
    PRI_ATA_LBA7_0      = ( sector & 0x000000ff );
    PRI_ATA_LBA15_8     = ( sector & 0x0000ff00 ) >> 8;
    PRI_ATA_LBA23_16    = ( sector & 0x00ff0000 ) >> 16;
    PRI_ATA_LBA27_24    = ( ( sector & 0x0f000000 ) >> 24 ) | 0xe0;
    PRI_ATA_CMD         = command;

    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  ATA_setfeature( command, options )                                      *
 *                                                                          *
 *      command: Set Feature command                                        *
 *      options: Set Feature options                                        *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 ATA_setfeature( Uint8 command, Uint8 options )
{
    waitWhileDRDYLow( -1 );                         // Wait until drive is ready

    PRI_ATA_FEATURE     = command;
    PRI_ATA_SECCNT      = options;
    PRI_ATA_LBA7_0      = options;
    PRI_ATA_LBA15_8     = options;
    PRI_ATA_LBA23_16    = options;
    PRI_ATA_LBA27_24    = 0;
    PRI_ATA_CMD         = ATA_SET_FEATURE;

    waitWhileBSYHigh( -1 );                         // Wait until complete

    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  ATA_readId( dst )                                                       *
 *      Read the Harddrive ID sector                                        *
 *                                                                          *
 *      dst: address of buffer                                              *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 ATA_readId( Uint32 dst )
{
    Int16 i;
    Uint16 *dst16 = ( Uint16* )dst;

    for ( i = 0 ; i < ATA_SECTOR_SIZE ; i += 2 )    // Clear buffer
        *dst16++ = 0;

    dst16 = ( Uint16* )dst;

    ATA_issueCommand( ATA_IDENTIFY_DEVICE, 0 );     // Issue ID command
    waitWhileBSYHigh( -1 );                         // Wait for BSY to drop low

    for ( i = 0 ; i < ATA_SECTOR_SIZE ; i += 2 )    // Read data
        *dst16++ = PRI_ATA_DATA16;

    return 0;
}

static Int16 firstbit( Uint32 mask )
{
    Int16 shiftamt;
    Uint32 bit;

    /* Find offset of first bit in mask */
    for ( bit = 0x80000000, shiftamt = 32 ; shiftamt >= 0 ; shiftamt--, bit >>= 1 )
        if ( bit & mask )
            break;

    /* Return location of first bit */
    return shiftamt;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  ATA_identify( )                                                         *
 *                                                                          *
 *                                                                          *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 ATA_identify( Uint8* buffer )

⌨️ 快捷键说明

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