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

📄 sdk7a404_fx_cf_driver.c

📁 含t h r e a d x,u c o s 的b s p
💻 C
字号:
/***********************************************************************
 * $Workfile:   sdk7a404_fx_cf_driver.c  $
 * $Revision:   1.1  $
 * $Author:   WellsK  $
 * $Date:   Apr 15 2004 17:16:54  $
 *
 * Project: FileX (ThreadX) SDK7A404 CompactFlash driver
 *
 * Description:
 *     This file contains driver support for the FileX component of
 *     ThreadX when used with the Logic PD SDK7A404 EVB.
 *
 * Notes:
 *     Interrupts are not supported. (The SDK7A404 EVB does not
 *     support interrupts). See the header file for information on
 *     how to improve the performance of this driver.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/bsps/sdk7a404/ports/filex/sdk7a404_fx_cf_driver.c-arc  $
 * 
 *    Rev 1.1   Apr 15 2004 17:16:54   WellsK
 * Incorporated changes due to CF driver changes.
 * 
 *    Rev 1.0   Sep 02 2003 14:44:20   WellsK
 * Initial revision.
 * 
 *
 ***********************************************************************
 * SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
 * OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
 * AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 * SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
 *
 * SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 * FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 * SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
 * FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
 *
 * COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/

#include "sdk7a404_cf_driver.h"
#include "sdk7a404_fx_cf_driver.h"

/***********************************************************************
 * CF driver private data
 **********************************************************************/

/* CF driver handle (used through SDK7A404 CF driver) */
INT_32 cfdev;

/* Offset of CF device in sectors to start of filesystem - this will
   usually be an offset that goes past the partition table, hidden
   sectors, etc. */
UINT sector_offset;

#define CF_SECTOR_SIZE     512   /* Size of a CF sector */
#define PART_TYPE_OFFSET   450   /* Part table offset to part type */
#define PART_TYPE_FAT12    0x01  /* FAT12 partition flag */
#define PART_TYPE_FAT16L   0x04  /* FAT12 < 32M partition flag */
#define PART_TYPE_FAT16G   0x06  /* FAT16 > 32M partition flag */
#define PART_TYPE_FAT32    0x0B  /* FAT32 partition flag */
#define PART_LGSPART_OFF   454   /* Sector offset to first partition */
#define BOOTSEC_BPS_LOW    0x0B  /* Bytes per sector low offset */
#define BOOTSEC_BPS_HIGH   0x0C  /* Bytes per sector high offset */
#define BOOTSEC_EXMKR_LOW  0x1FF /* Executable marker low offset */
#define BOOTSEC_EXMKR_HIGH 0x1FE /* Executable marker high offset */

/***********************************************************************
 *
 * Function: ufx_check_boot_sector
 *
 * Purpose: Determine if the passed sector data is valid
 *
 * Processing:
 *     For the buffer in the passed structure, check the sector size
 *     and the executable end marker value. If they are correct, return
 *     FX_SUCCESS to the caller. Otherwise, return FX_IO_ERROR to the
 *     caller.
 *
 * Parameters:
 *     media_ptr : Pointer to FX_MEDIA structure
 *
 * Outputs: None
 *
 * Returns:
 *     FX_SUCCESS on a successful boot sector detection, or FX_IO_ERROR
 *     if the boot sector was not found.
 *
 * Notes: None
 *
 **********************************************************************/
static UINT ufx_check_boot_sector(FX_MEDIA *media_ptr)
{
    UCHAR_PTR byte_ptr;
    UINT status = FX_IO_ERROR;

    /* Save pointer to buffer area of boot sector */
    byte_ptr = media_ptr->fx_media_driver_buffer;

    /* Before tagging this as the boot sector, perform a sanity check
       on a few values to make sure they are ok */
    if ((byte_ptr[BOOTSEC_BPS_LOW] == 0x00) &&
        (byte_ptr[BOOTSEC_BPS_HIGH] == 0x02) &&
        (byte_ptr[BOOTSEC_EXMKR_LOW] == 0xAA) &&
        (byte_ptr[BOOTSEC_EXMKR_HIGH] == 0x55))
    {
        /* This is valid, so use it */
        status = FX_SUCCESS;
    }
    
    return status;
}

/***********************************************************************
 *
 * Function: ufx_boot_read
 *
 * Purpose: Determine and read the boot sector of first CF partition
 *
 * Processing:
 *     Read sector 0 on the CompactFlash device. Check the sector data
 *     for the correct boot sector information. If the sector is a
 *     boot sector, set the sector offset to 0 and return FX_SUCCESS
 *     to the caller. If the sector is not a boot sector, check the
 *     sector for FAT16 partition tags. If they exist, then the sector
 *     is a partition table sector that points to a FAT16 boot sector.
 *     Locate the FAT16 boot sector and read it. Check the sector data
 *     for the correct boot sector information. If the sector is a
 *     boot sector, set the sector offset to the current sector and
 *     return FX_SUCCESS to the caller. Otherwise, return FX_IO_ERROR
 *     to the caller.
 *
 * Parameters:
 *     media_ptr : Pointer to FX_MEDIA structure
 *
 * Outputs: None
 *
 * Returns:
 *     FX_SUCCESS on a successful boot sector detection, or FX_IO_ERROR
 *     if the boot sector was not found.
 *
 * Notes: None
 *
 **********************************************************************/
static UINT ufx_boot_read(FX_MEDIA *media_ptr)
{
    INT_32 secoff;
    UINT status;
    CF_BLOCKS_T cfb;
    UCHAR_PTR byte_ptr = media_ptr->fx_media_driver_buffer;

    /* Read the first sector on the device */
    cfb.sector = 0;
    cfb.num_blocks = 1;
    cf_ioctl(cfdev, CF_READ_BLOCKS, (INT_32) &cfb);

    /* Sleep until CF device operation is read to receive block */
    while (cf_ioctl(cfdev, CF_GET_STATUS, CF_CARD_BUSY) == 1)
    {
        tx_thread_sleep(1);
    }

    /* Read data from sector */
    cf_read(cfdev, byte_ptr, CF_SECTOR_SIZE);

    /* Assume for now that this is a boot sector and the CF device has
       only one partition and no partition table (and that the
       partition starts at logical sector 0). Perform a sanity check
       of the boot sector by checking a few known values - if they
       match, then this is the boot sector of the CF card */
    status = ufx_check_boot_sector(media_ptr);
    if (status == FX_SUCCESS)
    {
        /* This is the boot sector! */
        sector_offset = 0;
    }
    else
    {
        /* Not the boot sector, this may be a partition table. Check
           the partition flag - if it is a valid partition (FAT12,
           FAT16, or FAT32), then compute the logical sector offset
           to the boot sector of the first partition based on the
           partition CHS (Cylinder/Head/Sector) values */
        switch (byte_ptr[PART_TYPE_OFFSET])
        {
            case PART_TYPE_FAT12:
            case PART_TYPE_FAT16L:
            case PART_TYPE_FAT16G:
            case PART_TYPE_FAT32:
                /* Good partition flag, compute sector offset */
                secoff = (UINT) byte_ptr[PART_LGSPART_OFF] +
                    ((UINT) byte_ptr[PART_LGSPART_OFF + 1] << 8) +
                    ((UINT) byte_ptr[PART_LGSPART_OFF + 2] << 16) +
                    ((UINT) byte_ptr[PART_LGSPART_OFF + 3] << 24);

                /* Read sector pointed to by partition entry */
                cfb.sector = secoff;
                cfb.num_blocks = 1;
                cf_ioctl(cfdev, CF_READ_BLOCKS, (INT_32) &cfb);

                /* Sleep until CF device operation is read to receive
                   block */
                while (cf_ioctl(cfdev, CF_GET_STATUS,
                    CF_CARD_BUSY) == 1)
                {
                    tx_thread_sleep(1);
                }

                /* Read data from sector */
                cf_read(cfdev, byte_ptr, CF_SECTOR_SIZE);

                /* Verify sector */
                status = ufx_check_boot_sector(media_ptr);
                if (status == FX_SUCCESS)
                {
                    /* This is the boot sector! */
                    sector_offset = secoff;
                }
                break;

            default:
                /* Not a valid partition entry or table, so exit */
                break;
        }
    }

    return status;
}

/***********************************************************************
 *
 * Function: _fx_cf_driver
 *
 * Purpose: Main FileX driver entry point
 *
 * Processing:
 *     Based on the FileX driver request case, perform the processing
 *     necessary to read a sector, write a sector, read the boot
 *     sector, flush a sector, abort an operation, or initialize the
 *     driver.
 *
 * Parameters:
 *     media_ptr: Pointer to FX_MEDIA structure
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void _fx_cf_driver(FX_MEDIA *media_ptr)
{
    UINT sector;
    UNS_8 *buffer = (UNS_8 *) media_ptr->fx_media_driver_buffer;
    CF_BLOCKS_T cfb;

    switch (media_ptr->fx_media_driver_request)
    {
        case FX_DRIVER_READ:
            /* Read all sectors */
            for (sector = 0;
                sector < media_ptr->fx_media_driver_sectors;
                sector++)
            {
                /* Sleep until CF device is not busy */
                while (cf_ioctl(cfdev, CF_GET_STATUS,
                    CF_CARD_BUSY) == 1)
                {
                    tx_thread_sleep(1);
                }

                /* Issue read command */
                cfb.sector = media_ptr->fx_media_driver_logical_sector +
                    sector + sector_offset;
                cfb.num_blocks = 1;
                cf_ioctl(cfdev, CF_READ_BLOCKS, (INT_32) &cfb);

                /* Sleep until CF device operation is complete */
                while (cf_ioctl(cfdev, CF_GET_STATUS,
                    CF_CARD_BUSY) == 1)
                {
                    tx_thread_sleep(1);
                }

                /* Read sector into buffer */
                cf_read(cfdev, buffer, CF_SECTOR_SIZE);
                buffer = buffer + CF_SECTOR_SIZE;
            }

            /* Return good status */
            media_ptr->fx_media_driver_status = FX_SUCCESS;
            break;

        case FX_DRIVER_WRITE:
            /* Write all sectors */
            for (sector = 0;
                sector < media_ptr->fx_media_driver_sectors;
                sector++)
            {
                /* Sleep until CF device is not busy */
                while (cf_ioctl(cfdev, CF_GET_STATUS,
                    CF_CARD_BUSY) == 1)
                {
                    tx_thread_sleep(1);
                }

                /* Issue write command */
                cfb.sector = media_ptr->fx_media_driver_logical_sector +
                    sector + sector_offset;
                cfb.num_blocks = 1;
                cf_ioctl(cfdev, CF_WRITE_BLOCKS, (INT_32) &cfb);

                /* Write buffer to sector */
                cf_write(cfdev, buffer, CF_SECTOR_SIZE);
                buffer = buffer + CF_SECTOR_SIZE;
            }

            /* Return good status */
            media_ptr->fx_media_driver_status = FX_SUCCESS;
            break;

        case FX_DRIVER_FLUSH:
            /* CF flush is not used */
            media_ptr->fx_media_driver_status = FX_SUCCESS;
            break;

        case FX_DRIVER_ABORT:
            /* CF abort is not used */
            media_ptr->fx_media_driver_status = FX_SUCCESS;
            break;

        case FX_DRIVER_INIT:
            /* Default status is an error */
            media_ptr->fx_media_driver_status = FX_IO_ERROR;

            /* Open the CF device */
            cfdev = cf_open((INT_32 *) CF_BASE, 0);

            /* Only continue if device opened */
            if (cfdev != 0)
            {
                /* Verify that a card is installed */
                if (cf_ioctl(cfdev, CF_GET_STATUS, CF_CARD_DETECT) == 1)
                {
                    /* Card is installed, set status good */
                    media_ptr->fx_media_driver_status = FX_SUCCESS;
                }
                else
                {
                    /* No card installed, close SDK CF driver */
                    cf_close(cfdev);
                }
            }
            break;

        case FX_DRIVER_BOOT_READ:
            /* Extract data from boot sector */
            media_ptr->fx_media_driver_status =
                ufx_boot_read(media_ptr);
            break;

        default:
            /* Invalid driver request */
            media_ptr->fx_media_driver_status = FX_IO_ERROR;
            break;
    }
}

⌨️ 快捷键说明

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