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

📄 nand.c

📁 基于EP7312的MP3播放器源代码,包括MCU和PC端代码.
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************//// NAND.C - File system driver for the on-board NAND FLASH.//// Copyright (c) 2000,2001 Cirrus Logic, Inc.////****************************************************************************#include "globals.h"#include "../hwport.h"#include "../hwdefs.h"#include "fat/fat.h"#include "ftl/ftl.h"//****************************************************************************//// The name of this drive.////****************************************************************************static const unsigned short pusDriveName[] ={    'I', 'n', 't', 'e', 'r', 'n', 'a', 'l', ' ', 'N', 'A', 'N', 'D', '\0'};//****************************************************************************//// The persistent state of the NAND driver.////****************************************************************************static struct{    //    // The persistent state of the FTL layer used for the on-board NAND.    //    tFTL sFTL;    //    // The persistent state of the FAT layer used for the on-board NAND.    //    tFAT sFAT;    //    // Flags indicating the state of the NAND FLASH driver.    //    unsigned long ulFlags;} sNAND;//****************************************************************************//// The set of flags that indicate the state of the NAND FLASH driver.////****************************************************************************#define FLAG_ID_MASK                            0x000000ff#define FLAG_IS_BUSY1                           0x40000000#define FLAG_IS_BUSY2                           0x80000000//****************************************************************************//// The FLASH driver IOCTL entry point for the on-board NAND.////****************************************************************************static unsigned longNANDFLASHIoctl(unsigned long ulIoctl, unsigned long ulParam1,               unsigned long ulParam2, unsigned long ulParam3,               unsigned long ulParam4){    volatile unsigned long *pulGPIO = (unsigned long *)HwBaseAddress;    unsigned long ulCS, ulBusyFlag;    //    // If the first on-board NAND could be busy, then wait until it is not.    //    if(sNAND.ulFlags & FLAG_IS_BUSY1)    {        //        // Select the first on-board NAND.        //        pulGPIO[HwPortABCD >> 2] &= ~HwPortABCD_NAND1_CS;        //        // Wait until the first on-board NAND is not busy.        //        NANDWaitTilNotBusy(HwNANDAddress);        //        // Indicate that the first on-board NAND is not busy.        //        sNAND.ulFlags &= ~FLAG_IS_BUSY1;        //        // Deselect the first on-board NAND.        //        pulGPIO[HwPortABCD >> 2] |= HwPortABCD_NAND1_CS;    }    //    // If the second on-board NAND could be busy, then wait until it is not.    //#ifdef HwPortABCD_NAND2_CS    if(sNAND.ulFlags & FLAG_IS_BUSY2)    {        //        // Select the second on-board NAND.        //        pulGPIO[HwPortABCD >> 2] &= ~HwPortABCD_NAND2_CS;        //        // Wait until the second on-board NAND is not busy.        //        NANDWaitTilNotBusy(HwNANDAddress);        //        // Indicate that the second on-board NAND is not busy.        //        sNAND.ulFlags &= ~FLAG_IS_BUSY2;        //        // Deselect the second on-board NAND.        //        pulGPIO[HwPortABCD >> 2] |= HwPortABCD_NAND2_CS;    }#endif    //    // Determine which of the on-board NAND FLASH devices to select.    //#ifdef HwPortABCD_NAND2_CS    if(sNAND.ulFlags & FLAG_ID_MASK)    {        //        // The on-board NAND FLASH device to select is dependent upon the        // IOCTL being executed.        //        switch(ulIoctl)        {            //            // Handle the IOCTLs which work on a page basis.            //            case IOCTL_FLASH_READ:            case IOCTL_FLASH_WRITE:            case IOCTL_FLASH_READ_REDT:            case IOCTL_FLASH_WRITE_REDT:            {                unsigned long ulNumPages = 0;                //                // Determine the number of pages in each of the NAND FLASH                // devices.                //                switch(sNAND.ulFlags & FLAG_ID_MASK)                {                    //                    // A pair of 16MB NAND FLASH devices have 32768 pages in                    // each device.                    //                    case 0x75:                    {                        ulNumPages = 32768;                        break;                    }                    //                    // A pair of 32MB NAND FLASH devices have 65536 pages in                    // each device.  Also, each individual device is accessed                    // with only three address cycles.                    //                    case 0x76:                    {                        ulNumPages = 65536;                        ulParam4 &= ~FLASH_ADDR_4_CYCLE;                        break;                    }                    //                    // A pair of 64MB NAND FLASH devices have 131072 pages in                    // each device.                    //                    case 0x79:                    {                        ulNumPages = 131072;                        break;                    }                }                //                // Determine the NAND FLASH device to select based on the page                // number being accessed.                //                if(ulParam1 < ulNumPages)                {                    ulCS = HwPortABCD_NAND1_CS;                    ulBusyFlag = FLAG_IS_BUSY1;                }                else                {                    ulParam1 -= ulNumPages;                    ulCS = HwPortABCD_NAND2_CS;                    ulBusyFlag = FLAG_IS_BUSY2;                }                //                // We've determined the correct device.                //                break;            }            //            // Handle the IOCTLs which work on a block basis.            //            case IOCTL_FLASH_ERASE:            {                unsigned long ulNumBlocks = 0;                //                // Determine the number of blocks in each of the NAND FLASH                // devices.                //                switch(sNAND.ulFlags & FLAG_ID_MASK)                {                    //                    // A pair of 16MB NAND FLASH devices have 1024 blocks in                    // each device.                    //                    case 0x75:                    {                        ulNumBlocks = 1024;                        break;                    }                    //                    // A pair of 32MB NAND FLASH devices have 2048 blocks in                    // each device.  Also, each individual device is accessed                    // with only three address cycles.                    //                    case 0x76:                    {                        ulNumBlocks = 2048;                        ulParam4 &= ~FLASH_ADDR_4_CYCLE;                        break;                    }                    //                    // A pair of 64MB NAND FLASH devices have 4096 blocks in                    // each device.                    //                    case 0x79:                    {                        ulNumBlocks = 4096;                        break;                    }                }                //                // Determine the NAND FLASH device to select based on the block                // number being accessed.                //                if(ulParam1 < ulNumBlocks)                {                    ulCS = HwPortABCD_NAND1_CS;                    ulBusyFlag = FLAG_IS_BUSY1;                }                else                {                    ulParam1 -= ulNumBlocks;                    ulCS = HwPortABCD_NAND2_CS;                    ulBusyFlag = FLAG_IS_BUSY2;                }                //                // We've determined the correct device.                //                break;            }            //            // Handle all other IOCTLs.            //            default:            {                //                // Do not assert a chip select for all other IOCTLs.                //                ulCS = 0;                //                // Not not set a busy flag for all other IOCTLs.                //                ulBusyFlag = 0;                //                // We've determined the correct device.                //                break;            }        }    }    else#endif    {        //        // Get the chip select for the first on-board NAND.        //        ulCS = HwPortABCD_NAND1_CS;        //        // Get the busy flag for the first on-board NAND.        //        ulBusyFlag = FLAG_IS_BUSY1;    }    //    // Select the on-board NAND.    //    pulGPIO[HwPortABCD >> 2] &= ~ulCS;    //    // Determine what to do based on the requested IOCTL.    //    switch(ulIoctl)    {        //        // Get the ID of the on-board NAND.        //        case IOCTL_FLASH_GETID:        {            unsigned long *pulDeviceID = (unsigned long *)ulParam1;            //            // If we are faking a larger NAND FLASH, then return the faked ID.            //            if(sNAND.ulFlags & FLAG_ID_MASK)            {                //                // Return the faked ID.                //                *pulDeviceID = sNAND.ulFlags & FLAG_ID_MASK;            }            else            {                //                // Read the device ID from the on-board NAND.                //                *pulDeviceID = NANDGetID(HwNANDAddress);            }            //            // We're done with this request.            //            break;        }        //        // Read a page of data from the on-board NAND.        //        case IOCTL_FLASH_READ:        {            //            // Read the page of data from the on-board NAND.            //#ifdef SUPPORT_TINY_MEDIA            if(ulParam4 & FLASH_PS256)            {                //                // This NAND device has 256 bytes per page.                //                NANDRead_256(HwNANDAddress, ulParam1 << 1,                             (unsigned char *)ulParam2,                             (unsigned char *)ulParam3);            }            else#endif            if(ulParam4 & FLASH_ADDR_4_CYCLE)            {                //                // This NAND device has 512 bytes per page and requires 4                // address cycles.                //                NANDRead_512_4(HwNANDAddress, ulParam1,                               (unsigned char *)ulParam2,                               (unsigned char *)ulParam3);            }            else            {                //                // This NAND device has 512 bytes per page and requires 3                // address cycles.                //                NANDRead_512_3(HwNANDAddress, ulParam1,                               (unsigned char *)ulParam2,                               (unsigned char *)ulParam3);            }            //            // We're done with this request.            //            break;        }        //        // Write a page of data to the on-board NAND.        //        case IOCTL_FLASH_WRITE:        {            //            // Write the page of data to the on-board NAND.            //#ifdef SUPPORT_TINY_MEDIA            if(ulParam4 & FLASH_PS256)

⌨️ 快捷键说明

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