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

📄 cf_ide.c

📁 Analog公司的ADSP_BF532上面实现以太网接口的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    ATA_CMD.DH  = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA

    // read command
    ATA_CMD.CMD = 0x20;

    // 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);
}

/******************************************************************************
 * CF_IDE: ATA_read_fat_sector()
 *
 * Purpose:
 *  expects a cluster number to read and converts it to LBA address for
 *  fetch from CF
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_read_fat_sector(DWORD LBAsec)
{
    int     i, w;

    // skip reserved sectors and add hidden for LBA addressing
    LBAsec += ATA_P.BPB_RsvdSecCnt + 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
    ATA_CMD.DH  = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA

    // read command
    ATA_CMD.CMD = 0x20;

    // Send ATA Command
    ATA_send_command();

    // Wait for IRQ
    ATA_wait_for_it();

    // Collect Buffer
    for(i=0; i<256; i++)
    {
        ATA_CurFATBuffer[i] = _inpw(IDE_RDD);
        
        // wait loop
        for (w=0; w<PIOWAIT; w++)
            _inp(0xffa00000);
    }
}

/******************************************************************************
 * CF_IDE: ATA_read_cluster()
 *
 * Purpose:
 *  expects a cluster number to read and converts it to LBA address for
 *  fetch from CF
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_read_cluster(DWORD Cluster, DWORD* buffer)
{
    int     i, j, w;
    DWORD   LBAsec;
    BYTE    Timeout;
    WORD    *buf = (WORD*) buffer;
    WORD    status;

    // allocation starts with sector 2, add data offset and hidden
    LBAsec = (Cluster-2) * ATA_P.BPB_SecPerClus + ATA_FirstDataSector + ATA_LBAHidden;

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

    // loop for number of sectors per cluster
    for (j = 0; j<ATA_P.BPB_SecPerClus; j++)
    {
        // prepare command buffer
        ATA_CMD.SC  = 1;                                // one cluster
        ATA_CMD.SN  = (LBAsec & 0x000000ff);            // sec number
        ATA_CMD.CL  = (LBAsec & 0x0000ff00)>> 8;        // cyl low
        ATA_CMD.CH  = (LBAsec & 0x00ff0000)>>16;        // cyl high
        ATA_CMD.DH  = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA

        // read command
        ATA_CMD.CMD = 0x20;

        // Send ATA Command
        ATA_send_command();

        // Wait for IRQ
        ATA_wait_for_it();

        // Collect Buffer
        for(i=0; i < 256; i++)
        {
            *buf++ = _inpw(IDE_RDD);
            
            //wait loop
            for (w=0; w<PIOWAIT; w++)
                _inp(0xffa00000);
        }

        // increment sector pointer
        LBAsec += 1;

        // set Timeout to 1 sec        
        Timeout_DISK = 4;
    
        // wait for rdy
        while(Timeout_DISK)
        {
            if (_inpw(IDE_STAT)&0x40) break;
        }
        
        // no ready so we must reset
        if (!Timeout_DISK) ATA_reset();
    }
}


/******************************************************************************
 * CF_IDE: ATA_read_directory()
 *
 * Purpose:
 *  reads the directory and returns a parsed list of entries
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_read_directory(WORD cluster, BYTE ROOTread)
{
    BYTE*   pd = (BYTE*) ATA_buffer;
    BYTE    entry = 0;
    DWORD   LBAsec;
    int     i, j, k;

    // convert cluster to LBA
    if (ROOTread == ROOT)
    {
        LBAsec = cluster + ATA_RootDirSecCnt + ATA_LBAHidden;
    }
    else
    {
        LBAsec = (cluster-2) * ATA_P.BPB_SecPerClus + ATA_FirstDataSector + ATA_LBAHidden;
    }

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

    // prepare command buffer
    ATA_CMD.SC  = 1;                                // one sector
    ATA_CMD.SN  = (LBAsec & 0x000000ff);            // sec number
    ATA_CMD.CL  = (LBAsec & 0x0000ff00)>> 8;        // cyl low
    ATA_CMD.CH  = (LBAsec & 0x00ff0000)>>16;        // cyl high
    ATA_CMD.DH  = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA

    // read command
    ATA_CMD.CMD = 0x20;

    // 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);

    for (i=0; i<16; i++)
    {
        // no further entries
        if (*pd == 0)
        {
            break;
        }
        if (*pd != 0xe5)
        {
            for (j=0; j<8; j++)
            {
                if (*(pd+j) == 0x20) break;
                ATA_D[entry].DIR_Name[j] = *(pd+j);
            }
                    ATA_D[entry].DIR_Name[j] = 0x2e;
            memcpy(&ATA_D[entry].DIR_Name[j+1]     , pd+ 8, 3);
                    ATA_D[entry].DIR_Name[12] = 0x00;

            memcpy(&ATA_D[entry].DIR_Attr          , pd+11, 1);
            memcpy(&ATA_D[entry].DIR_NTRes         , pd+12, 1);
            memcpy(&ATA_D[entry].DIR_CrtTimeTenth  , pd+13, 1);
            memcpy(&ATA_D[entry].DIR_CrtTime       , pd+14, 2);
            memcpy(&ATA_D[entry].DIR_CrtDate       , pd+16, 2);
            memcpy(&ATA_D[entry].DIR_LstAccDate    , pd+18, 2);
            memcpy(&ATA_D[entry].DIR_FstClusHI     , pd+20, 2);
            memcpy(&ATA_D[entry].DIR_WrtTime       , pd+22, 2);
            memcpy(&ATA_D[entry].DIR_WrtDate       , pd+24, 2);
            memcpy(&ATA_D[entry].DIR_FstClusLO     , pd+26, 2);
            memcpy(&ATA_D[entry].DIR_FileSize      , pd+28, 4);

            // proper entry, let's increment
            entry++;
        }
        // move pointer to next possible location
        pd += 32;
    }

    // signal last element if array is not full
    if (entry < 16) memcpy(&ATA_D[entry].DIR_Name, "\0", 1);

#if A_DP
    for (i=0; i< entry; i++)
        printf("%13s, %02x, %08x, %04x, %04x\n", ATA_D[i].DIR_Name, ATA_D[i].DIR_Attr, ATA_D[i].DIR_FileSize, ATA_D[i].DIR_FstClusHI, ATA_D[i].DIR_FstClusLO);
#endif
}


/******************************************************************************
 * CF_IDE: ATA_read_short_dir()
 *
 * Purpose:
 *  reads basic parameters the directory and returns a parsed list of entries
 *
 * Actions:
 *
 *****************************************************************************/
MC void ATA_read_short_dir(WORD cluster, BYTE ROOTread)
{
    BYTE*   pd = (BYTE*) ATA_buffer;
    DWORD   LBAsec;
    int     i, j, k;

    // convert cluster to LBA
    if (ROOTread == ROOT)
        LBAsec = cluster + ATA_RootDirSecCnt + ATA_LBAHidden;
    else
        LBAsec = (cluster-2) * ATA_P.BPB_SecPerClus + ATA_FirstDataSector + ATA_LBAHidden;

    for (k=0; k < MAX_SHORT_DIR; )
    {
        #if A_DP
            printf("LBA: %d\n", LBAsec);
        #endif

        // prepare command buffer
        ATA_CMD.SC  = 1;                                // one sector
        ATA_CMD.SN  = (LBAsec & 0x000000ff);            // sec number
        ATA_CMD.CL  = (LBAsec & 0x0000ff00)>> 8;        // cyl low
        ATA_CMD.CH  = (LBAsec & 0x00ff0000)>>16;        // cyl high
        ATA_CMD.DH  = ((LBAsec & 0x0f000000)>>24)|0xE0; // 0xAx | LBA

        // read command
        ATA_CMD.CMD = 0x20;

        // 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);

        // 16 entries per sector
        for (i=0; i<16; i++)
        {
            // no further entries
            if (*pd == 0)
            {
                // store number of entries
                ATA_CurDirEnt = k;

                // signal last element if array is not full
                if (k < MAX_SHORT_DIR) memcpy(&ATA_DS[k].DIR_Name, "\0", 1);

                #if 1//A_DP
                    for (i=0; i<k; i++)
                        printf("%13s, %02x, %08x, %04x, %04x\n", ATA_DS[i].DIR_Name, ATA_DS[i].DIR_Attr, ATA_DS[i].DIR_FileSize, ATA_DS[i].DIR_FstClusLO);
                #endif

                // exit subfunction
                return;
            }
            if (*pd != 0xe5)
            {
                for (j=0; j<8; j++)
                {
                    if (*(pd+j) == 0x20) break;
                    ATA_DS[k].DIR_Name[j] = *(pd+j);
                }
                        ATA_DS[k].DIR_Name[j+0] = 0x2e;
                memcpy(&ATA_DS[k].DIR_Name[j+1]     , pd+ 8, 3);
                        ATA_DS[k].DIR_Name[j+4] = 0x00;

                memcpy(&ATA_DS[k].DIR_Attr          , pd+11, 1);
                memcpy(&ATA_DS[k].DIR_FstClusLO     , pd+26, 2);
                memcpy(&ATA_DS[k].DIR_FileSize      , pd+28, 4);

                // increment number of entries
                k++;
            }
            // move pointer to next possible location
            pd += 32;
        }

        // increment LBA Sector
        LBAsec += 1;
        
        // reset pointer
        pd = (BYTE*) ATA_buffer;
    }

    // signal last element if array is not full
    if (k < MAX_SHORT_DIR) memcpy(&ATA_DS[k].DIR_Name, "\0", 1);
}


⌨️ 快捷键说明

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