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

📄 kev7a400_cf_driver.c

📁 CF读写驱动
💻 C
字号:
/***********************************************************************
 * $Workfile:   KEV7A400_cf_driver.c  $
 * $Revision:   1.1  $
 * $Author:   WellsK  $
 * $Date:   Sep 02 2002 16:24:34  $
 *
 * Project: Compact Flash interface driver
 *
 * Description:
 *  This driver reads and writes raw 'sectors' in the CF card via
 *  the Cylinder/Head/Sector (CHS) mechanism. Support functions for
 *  initializing and locating the card are available. All bookkeeping
 *  functions related to supporting the CF interface must be performed
 *  at a higher driver level. Multitasking in the CF interface is not
 *  supported. If a read operation is performed, the data should be
 *  read from the card before another operation is performed.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/Compact Flash/Drivers/KEV7A400_cf_driver.c-arc  $
 * 
 *    Rev 1.1   Sep 02 2002 16:24:34   WellsK
 * Read and write functions return number of bytes that have
 * been read or written instead of PASS/FAIL (1/0).
 * 
 *    Rev 1.0   Aug 22 2002 15:59:42   MaysR
 * 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) 2002 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/
#include "SMA_types.h"
#include "KEV7A400_cf_driver.h"

static void cfif_get_chs (void);

// CHS mapping values
static UNS_16 max_cyl, max_heads, max_sectors_track;

/***********************************************************************
 * Function: cfif_get_chs
 *
 * Purpose:  Sets up the device specific CHS values.
 *
 * Processing:  Issues the CF identification command and reads the CF 
 *              status. The CHS sizing from the CF card is used by the
 *              driver.
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  None
 *
 **********************************************************************/
static void cfif_get_chs (void)
{
    UNS_16 data [256];

    // Issue a read attributes command to the CF device
    CF_STAT->status_command = CFC_IDENT;

    // Wait for command to complete
    while (cfif_is_card_busy () == 1);

    // Move data into the buffer
    cfif_read_data (data, 512);

    // Save the 3 needed values
    max_cyl = (UNS_16) data [54];
    max_heads = (UNS_16) data [55];
    max_sectors_track = (UNS_16) data [56];
}

/***********************************************************************
 * Function: cfif_init
 *
 * Purpose:  Initialize the CF interface and return the card detection 
 *           status.
 *
 * Processing:  The pointers used in this driver are initialized.
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  '1' if a CF card has been detected, '0' otherwise.
 *
 * Notes:  None
 *
 **********************************************************************/
INT_32 cfif_init (void)
{
    INT_32 inserted;

    inserted = cfif_is_card_inserted ();
    if (inserted == 1)
    {
        // Get CHS mappings (used for absolute sector conversion)
        cfif_get_chs ();
    }
    return inserted;
}

/***********************************************************************
 * Function: cfif_shutdown
 *
 * Purpose:  Shutdown the CF interface driver.
 *
 * Processing:  This function does nothing and is a placeholder.
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  None
 *
 **********************************************************************/
void cfif_shutdown (void)
{
    // Do nothing
    ;
}

/***********************************************************************
 * Function: cfif_is_card_inserted
 *
 * Purpose:  Determine if a card is inserted
 *
 * Processing:  TBD
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  '1' if a card is inserted, '0' otherwise.
 *
 * Notes:  None
 *
 **********************************************************************/
INT_32 cfif_is_card_inserted (void)
{
    if ((CF_STAT->status_command & CF_DETECT_MASK) == CF_DETECT_VALUE)
        return 1;
    return 0;
}

/***********************************************************************
 * Function: cfif_is_card_ready
 *
 * Purpose:  Determines if the card is ready for a new command.
 *
 * Processing:  If the CF_RDY bit in the CF status register is set, 
 *              return '1', else return a '0'.
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  '1' if the card is ready for a new command, otherwise '0'.
 *
 * Notes:  None
 *
 **********************************************************************/
INT_32 cfif_is_card_ready (void)
{
    return ((CF_STAT->status_command & CF_RDY) != 0);
}

/***********************************************************************
 * Function: cfif_is_card_busy
 *
 * Purpose:  Determine if a card is busy (processing a command).
 *
 * Processing:  If the CF_BUSY bit in the CF status register is set, 
 *              return '1', else return a '0'.
 * 
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  '1' if the card is busy, '0' otherwise.
 *
 * Notes:  None
 *
 **********************************************************************/
INT_32 cfif_is_card_busy (void)
{
    if (CF_STAT->status_command & CF_BUSY)
        return 1;
    return 0;
}

/***********************************************************************
 * Function: cfif_set_sector
 *
 * Purpose:  Set the cylinder, head, and sector for the next operation 
 *           (using the absolute sector number).
 *
 * Processing:  The sector passed from the caller update the CHS 
 *              device pointers that will be used for the next 
 *              operation.
 *
 * Parameters:  sectorno : Sector number
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  The convention is Cylinder/Head/Sector (CHS). The function 
 *         will convert the CHS values to a value that works with the 
 *         CF card.
 *
 **********************************************************************/
void cfif_set_sector (UNS_32 sectorno)
{
    UNS_16 sector, head, cylinder;
    UNS_32 csector;

    // Compute real sector number
    csector = sectorno / (UNS_32) max_sectors_track;
    csector = (UNS_32) max_sectors_track * csector;
    sector = (UNS_16) (sectorno - csector + 1);

    // Compute cylinder
    cylinder = (UNS_16) (sectorno /
        ((UNS_32) max_sectors_track * (UNS_32) max_heads));

    // Compute head
    head = (UNS_16) (sectorno / (UNS_32) max_sectors_track -
        ((UNS_32) cylinder * (UNS_32) max_heads));

    // Setup the IDE controller with the CHS mappings
    CF_STAT->cyl_low = (UNS_16)(cylinder & 0xFF);
    CF_STAT->cyl_hi = (UNS_16)((cylinder & 0xFF00) >> 8);
    CF_STAT->sel_card = head;
    CF_STAT->sector_no = sector;
}

/***********************************************************************
 * Function: cfif_send_command
 *
 * Purpose:  Send command to CF card
 *
 * Processing:  
 *
 * Parameters:  Command to send to CF card
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  None
 *
 **********************************************************************/
void cfif_send_command (UNS_32 command)
{
    CF_STAT->status_command = (UNS_16)command;
}

/***********************************************************************
 * Function: cfif_start_sector_read
 *
 * Purpose:  Starts the read of a sector.
 *
 * Processing:  Set the sector size to '1' and issue the sector read command.
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  None
 *
 **********************************************************************/
void cfif_start_sector_read (void)
{
    CF_STAT->sector_count = 1;
    CF_STAT->status_command = CFC_R_SECT;
}

/***********************************************************************
 * Function: cfif_start_sector_write
 *
 * Purpose:  Starts the write of a sector.
 *
 * Processing:  Set the sector size to '1' and issue the sector write command.
 *
 * Parameters:  None
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  None
 *
 **********************************************************************/
void cfif_start_sector_write (void)
{
    CF_STAT->sector_count = 1;
    CF_STAT->status_command = CFC_W_SECT;
}

/***********************************************************************
 * Function: cfif_read_data
 *
 * Purpose:  Read a block of data from the CF card.
 *
 * Processing:  Copy a block of data of from the CF card buffer to the 
 *              destination address.
 *
 * Parameters: 
 *          data  : Pointer to where to put read data from the CF card
 *          bytes : Number of bytes to read
 *
 * Outputs:  The data pointed to by data will be updated.
 *
 * Returns:  The number of bytes read from the card.
 *
 * Notes:  Data is read AFTER a read command.
 *
 **********************************************************************/
INT_32 cfif_read_data (void *data, INT_32 bytes)
{
    INT_32 i;
    UNS_16 *cf_data = (UNS_16 *) data;

    for (i = 0; i < (bytes / 2); i++)
    {
        *cf_data = CF_STAT->data;
        cf_data++;
    if (CF_STAT->status_command & CF_DWF)
        return 0;
    }
    return bytes;
}

/***********************************************************************
 * Function: cfif_write_data
 *
 * Purpose:  Write data to the CF card.
 *
 * Processing:  Copy a block of data of from the source address to the 
 *              CF card buffer.
 *
 * Parameters:
 *          data  : Pointer to where to get data to write to the CF card
 *          bytes : Number of bytes to write
 *
 * Outputs:  None
 *
 * Returns:  The number of bytes written to the card.
 *
 * Notes:  Data is written after a write command.
 *
 **********************************************************************/
INT_32 cfif_write_data (void *data, INT_32 bytes)
{
    INT_32 i;
    UNS_16 *cf_data = (UNS_16 *) data;

    for (i = 0; i < (bytes / 2); i++)
    {
        // Fill write buffer
        CF_STAT->data = *cf_data;
        cf_data++;
    }
    if (CF_STAT->status_command & CF_DWF)
        return 0;
    return bytes;
}

/***********************************************************************
 * Function: cfif_erase_sector
 *
 * Purpose:  Erase CF card sectors.
 *
 * Processing:  Erase requested number of card sectors starting with
 *              specified sector number
 *
 * Parameters:
 *          start: Starting sector number
 *          bytes : Number of sectors to erase
 *
 * Outputs:  None
 *
 * Returns:  Success or fail
 *
 * Notes:  None
 *
 **********************************************************************/
INT_32 cfif_erase_sector (INT_32 sectorno)
{
    cfif_set_sector(sectorno);
    CF_STAT->sector_count = (1);
    cfif_send_command(CFC_E_SECT);
    if (CF_STAT->status_command & CF_DWF)
        return 1;
    return 0;
}


⌨️ 快捷键说明

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