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

📄 cf_ide.c

📁 Analog公司的ADSP_BF532上面实现以太网接口的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//##############################################################
//#
//# CF_IDE.C
//#
//# ADSP-21535 Embedded Web Server Project
//#
//# (c) ANALOG DEVICES 2002
//#     eDSP Division
//#     Stefan Hacker
//#     23-DEC-2002
//#
//# History
//#     04-APR-2003     last fixes
//#     16-APR-2003 HS  release 1.0
//#

#include "cf_ide.h"
#include "stdio.h"
#include "ez_lan_types.h"
#include "io_sprt.h"
#include "globals.h"
#include "string.h"

#define MC section("L1_code")

/******************************************************************************
 * CF_IDE: ATA_reset()
 *
 * Purpose:
 *  performs a soft reset on the drive
 *
 * Actions:
 *
 *****************************************************************************/
void ATA_reset()
{
    int i;

    _outpw(IDE_CTRL, 0x04);

    // set timeout 1 sec.
    Timeout_DISK = 4;
    // wait for occurence of IRQ
    while(Timeout_DISK);

    _outpw(IDE_CTRL, 0x00);
}

/******************************************************************************
 * CF_IDE: ATA_wait_for_it()
 *
 * Purpose:
 *  waits for the IRQ or Timeout
 *
 * Actions:
 *
 *****************************************************************************/
int ATA_wait_for_it()
{
    int status;

    // set timeout to 3 sec.
    Timeout_DISK = 12;

    while(Timeout_DISK)
    {
        if (IRQ_DISK)
        {
            // media active, clear IRQ occurred
            IRQ_DISK = 0;
            return 1;
        }
    }
    return -1;
}


/******************************************************************************
 * CF_IDE: ATA_send_command()
 *
 * Purpose:
 *  send ATA Command Block to the drive
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_send_command()
{
    // write command to CF
    _outpw(IDE_SCNT, ATA_CMD.SC);   // Sector Count
    _outpw(IDE_SNUM, ATA_CMD.SN);   // Sector Number
    _outpw(IDE_CYLL, ATA_CMD.CL);   // Cylinder low
    _outpw(IDE_CYLH, ATA_CMD.CH);   // Cylinder High
    _outpw(IDE_CDH, ATA_CMD.DH);    // Drive Head
    _outpw(IDE_CMD, ATA_CMD.CMD);   // Command Register

    // prepare waiting for IRQ
    IRQ_DISK = 0;
}


/******************************************************************************
 * CF_IDE: ATA_identify()
 *
 * Purpose:
 *  gets the first information from drive
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_identify()
{
    int     i;
    WORD    stmp;
    BYTE    bytes[40];
    BYTE*   pd = (BYTE*) ATA_buffer;

    // Identify drive
    ATA_CMD.DH = 0xA0;
    ATA_CMD.CMD = 0xEC;

    // Send ATA Command
    ATA_send_command();

    // Wait for IRQ
    // check media inserted and ready
    if (ATA_wait_for_it())
    {
        // good - our media is responding
        ATA_media_present = 1;
    }
    else
    {
        // bad - no response
        ATA_media_present = 0;

        // flag error
        ATA_ERROR = 1;

        // stop function
        return;
    }

    // Collect Buffer
    for(i=0; i<256; i++)
       ATA_buffer[i] = _inpw(IDE_RDD);

#if 1//A_DP
    for (i=0; i<4; i++)
    {
       stmp = ATA_buffer[23+i];
       bytes[2*i] = stmp>>8;
       bytes[2*i+1] = stmp&0xff;
    }
    printf("\n");
    for (i=0; i<8; i++)
       printf("%c", bytes[i]);

    for (i=0; i<20; i++)
    {
       stmp = ATA_buffer[27+i];
       bytes[2*i] = stmp>>8;
       bytes[2*i+1] = stmp&0xff;
    }
    printf("\n");
    for (i=0; i<40; i++)
       if (bytes[i] == 0) bytes[i] = 0x20;

    for (i=0; i<40; i++)
       printf("%c", bytes[i]);
    printf("\n");
#endif //A_DP

    // extract drive parameters
    memcpy(&ATA_N_Cyl   , pd+  2, 2);
    memcpy(&ATA_N_Head  , pd+  6, 2);
    memcpy(&ATA_N_Sec   , pd+ 12, 2);
    memcpy(&ATA_N_LBA   , pd+114, 4);

    return;
}

/******************************************************************************
 * CF_IDE: ATA_get_boot_block()
 *
 * Purpose:
 *  parses the boot block of the drive and sets parameters accordingly
 *
 * Actions:
 *
 *****************************************************************************/
MC int ATA_get_boot_block()
{
    int     i;
    WORD    stmp;
    BYTE*   pd = (BYTE*) ATA_buffer;

    // read sectors command
    // 1 sector, sector 1
    ATA_CMD.SC  = 1;        // one 512 byte sector
    ATA_CMD.SN  = 1;        // sec number
    ATA_CMD.CL  = 0;        // cyl low
    ATA_CMD.CH  = 0;        // cyl high
    ATA_CMD.DH  = 0xA1;     // head 1
    ATA_CMD.CMD = 0x20;     // read command

    // Send ATA Command
    ATA_send_command();

    // Wait for IRQ
    ATA_wait_for_it();

    // Collect Buffer
    for(i=0; i<256; i++)
       ATA_buffer[i] = _inpw(IDE_RDD);

    // first signature should be 0x3ceb
    memcpy(&ATA_P.BPB_id1          , pd+  0, 2);
    // second signature should be 0xaa55
    memcpy(&ATA_P.BPB_id2          , pd+510, 2);

    // check for formatted drive
    if (ATA_P.BPB_id2 != 0xaa55)
    {
#if 1//A_DP
        printf("ERROR: Drive is not formatted - ABORT! \n");
#endif // A_DP
        // if not, so flag error condition
        return -1;
    }

    // parse Boot Sector Information
    memcpy(&ATA_P.BS_jmpBoot       , pd+ 0,  3);
    memcpy(&ATA_P.BS_OEMName       , pd+ 3,  8);
    memcpy(&ATA_P.BPB_BytsPerSec   , pd+11,  2);
    memcpy(&ATA_P.BPB_SecPerClus   , pd+13,  1);
    memcpy(&ATA_P.BPB_RsvdSecCnt   , pd+14,  2);
    memcpy(&ATA_P.BPB_NumFATs      , pd+16,  1);
    memcpy(&ATA_P.BPB_RootEntCnt   , pd+17,  2);
    memcpy(&ATA_P.BPB_TotSec16     , pd+19,  2);
    memcpy(&ATA_P.BPB_Media        , pd+21,  1);
    memcpy(&ATA_P.BPB_FATSz16      , pd+22,  2);
    memcpy(&ATA_P.BPB_SecPerTrk    , pd+24,  2);
    memcpy(&ATA_P.BPB_NumHeads     , pd+26,  2);
    memcpy(&ATA_P.BPB_HiddSec      , pd+28,  4);
    memcpy(&ATA_P.BPB_TotSec32     , pd+32,  4);
    memcpy(&ATA_P.BS_DrvNum        , pd+36,  1);
    memcpy(&ATA_P.BS_Reserved1     , pd+37,  1);
    memcpy(&ATA_P.BS_BootSig       , pd+38,  1);
    memcpy(&ATA_P.BS_VolID         , pd+39,  4);
    memcpy(&ATA_P.BS_VolLab        , pd+43, 11);
    memcpy(&ATA_P.BS_FileSysType   , pd+54,  8);

    // we support only FAT16
    if (ATA_P.BPB_FATSz16)
        ATA_FATSz = ATA_P.BPB_FATSz16;
    else
    {
#if 1//A_DP
        printf("ERROR: Drive is not FAT16 - ABORT! \n");
#endif // A_DP
        // flag error condition
        return -1;
    }

    // calculate Root Dir sectors
    ATA_RootDirSectors = ((ATA_P.BPB_RootEntCnt<<5) + (ATA_P.BPB_BytsPerSec - 1)) / ATA_P.BPB_BytsPerSec;

    // calculate Data Region Start and Root Sector Number
    ATA_RootDirSecCnt = ATA_P.BPB_RsvdSecCnt + (ATA_P.BPB_NumFATs * ATA_FATSz);
    ATA_FirstDataSector = ATA_RootDirSecCnt + ATA_RootDirSectors;

    // ATA LBA Offset
    ATA_LBAHidden = ATA_P.BPB_HiddSec;


    // get Total Sector Count
    if (ATA_P.BPB_TotSec16)
        ATA_TotSec = ATA_P.BPB_TotSec16;
    else
        ATA_TotSec = ATA_P.BPB_TotSec32;

    // calculate Data Sectors
    ATA_DataSec = ATA_TotSec - (ATA_P.BPB_RsvdSecCnt + (ATA_P.BPB_NumFATs * ATA_FATSz) + ATA_RootDirSectors);

    // calculate Cluster Count
    ATA_CountOfClusters = ATA_DataSec / ATA_P.BPB_SecPerClus;

    // Detect File System
    if (ATA_CountOfClusters < 65525)
    {
#if 1//A_DP
        printf("\nInfo : FAT 16 Drive detected\n");
#endif // A_DP
        ATA_FAT16_detected = 1;
    }
    else
    {
#if 1//A_DP
        printf("\nERROR: FAT32 filesystem detected - ABORT!\n");
#endif // A_DP
        ATA_FAT16_detected = 0;
        return -1;
    }

    return 1;
}


/******************************************************************************
 * CF_IDE: ATA_read_sector()
 *
 * Purpose:
 *  expects a LBA sector number to read and fetch from CF
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_read_sector(DWORD LBAsec)
{
    int     i;
    BYTE    asn, acl, ach, adh;

    // add offset to data area and add hidden sectors for LBA
    LBAsec += ATA_FirstDataSector + ATA_LBAHidden;

#if 1//A_DP
    printf("LBA: %d\n", LBAsec);
#endif

    // prepare command buffer
    ATA_CMD.SC  = 1;                                // one 512 byte sector
    ATA_CMD.SN  = (LBAsec & 0x000000ff);            // sec number
    ATA_CMD.CL  = (LBAsec & 0x0000ff00)>> 8;        // cyl low
    ATA_CMD.CH  = (LBAsec & 0x00ff0000)>>16;        // cyl high

⌨️ 快捷键说明

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