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

📄 sdk7a404_cf_driver.c

📁 含t h r e a d x,u c o s 的b s p
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $Workfile:   sdk7a404_cf_driver.c  $
 * $Revision:   1.2  $
 * $Author:   WellsK  $
 * $Date:   Apr 15 2004 15:07:10  $
 *
 * Project: SDK7A404 CompactFlash driver
 *
 * Description:
 *     This file contains driver support for the IDE mode CompactFlash
 *     interface on the SDK7A404 EVB.
 *
 * Notes:
 *     This driver provides very basic functions only such as sector
 *     read and write, and data transfer. No error detection is provided
 *     with this driver. A device does not have to be installed in the
 *     EVB to 'open' this driver. BE CAREFUL WRITING TO A CF CARD - YOU
 *     CAN EASILY OVERWRITE IMPORTANT SECTORS AND LOSE INFORMATION ON
 *     THE CARD.
 *
 *     When using the cf_read() and cf_write() operations, the number
 *     of bytes to read or write MUST be at least 512! If it isn't, the
 *     operation will not occur. This is needed because this driver does
 *     not provide buffering to the CF device and data read and write
 *     sector sizes are set at 512 bytes. Note that read and write sizes
 *     should always be a factor of 512, based on the number of sectors
 *     read or written. There is no error checking for this requirement.
 *
 * Important note about accessing CF registers:
 *     The CF interface to the SOC has been configured in such as way
 *     as reads and writes are always 16-bits. Unfortunately, some
 *     registers *must* be written as 8-bit value to the device. This
 *     is not possible in this design - trying to do an 8-bit write to
 *     an 8-bit register will corrupt the other half of the 16-bit
 *     operation. (For example, writing an 8-bit value to address
 *     0x60201000 will corrupt address 0x60201001.) To get around this
 *     minor problem, all write operations must occur as 16-bit
 *     operations, so some CF register values may need to be saved
 *     and written out with another desired register value. When
 *     performing consecutive writes to the CF interface, a read to
 *     another chip select (besides the CF chip select) needs to be
 *     performed in between each write - this is needed to work
 *     around ISA timing issues with the CF interface and the memory
 *     interface timing.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/bsps/sdk7a404/source/sdk7a404_cf_driver.c-arc  $
 * 
 *    Rev 1.2   Apr 15 2004 15:07:10   WellsK
 * Updated CF driver to allow multiple sector reads and writes.
 * 
 *    Rev 1.1   Sep 02 2003 14:21:30   WellsK
 * Added dummy read. Corrected read/write logic. Seperated
 * sector set logic.
 * 
 *    Rev 1.0   Jul 18 2003 11:45:54   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"

/***********************************************************************
 * CompactFlash driver private data and types
 **********************************************************************/

/* CF interface (memory mode) access map */
/* Address    Access     R/W     Notes */
/* 0x60200000 16-bits    R only  Card Information Structure (CIS) */
/* 0x60200200 16-bits    R/W     Attribute memory */
/* 0x60201000 16-bits    R/W     Common memory */

/* Offset to CIS */
#define CF_OFFSET_CSI 0x0

/* Offset to attribute memory */
#define CF_OFFSET_ATTB 0x200

/* Offset to common memory */
#define CF_OFFSET_CM 0x1000

/* CF dummy read address used to force a chip select toggle */
#define CF_DUMMY_RD 0x70000000

/* Organization of attribute memory on the CF device */
typedef struct
{
    volatile UNS_16 config_option;
    volatile UNS_16 card_config_sts;
    volatile UNS_16 pin_replacement;
    volatile UNS_16 socket_copy;
} CF_ATTB_T;

/* CompactFlash Memory mapped mode interface register structure for
   the SDK7A404 (for read accesses only) */
typedef struct
{
    volatile UNS_16 data;           /* CF read data */
    volatile UNS_16 sec_count_no;   /* CF sector count and low 8 bits
                                       of number (LBA mode) */
    volatile UNS_16 sec_mid;        /* CF sector middle 16 bits */
    volatile UNS_16 sec_high_sts;   /* Sector high 8 bits and status
                                       value */
    volatile UNS_16 dup_data;       /* Duplicated data */
    volatile UNS_16 rsvd1;
    volatile UNS_16 dup_error;      /* Duplicated error value */
    volatile UNS_16 dup_sts_da;     /* Duplicated status and drive
                                       address  */
} CF_STATUS_READ_REG_T;

/* CompactFlash Memory mapped mode interface register structure for
   the SDK7A404 (for write accesses) */
typedef struct
{
    volatile UNS_16 data;           /* CF write data */
    volatile UNS_16 sec_count_no;   /* CF sector count and low 8 bits
                                       of number (LBA mode) */
    volatile UNS_16 sec_mid;        /* CF sector middle 16 bits */
    volatile UNS_16 sec_high_cmd;   /* Sector high 8 bits and command
                                       value */
    volatile UNS_16 dup_data;       /* Duplicated data */
    volatile UNS_16 rsvd1;
    volatile UNS_16 dup_features;   /* Duplicated features value */
    volatile UNS_16 device_ctl;     /* Device control */
} CF_STATUS_WRITE_REG_T;

/* CompactFlash status register busy bit */
#define CF_BUSY    _BIT(7)
/* CompactFlash status register command ready bit */
#define CF_RDY     _BIT(6)
/* CompactFlash status register Write fault bit */
#define CF_DWF     _BIT(5)
/* CompactFlash status register card ready bit */
#define CF_DSC     _BIT(4)
/* CompactFlash status register data request bit */
#define CF_DRQ     _BIT(3)
/* CompactFlash status register correctable error bit */
#define CF_CORR    _BIT(2)
/* CompactFlash status register reserved bit, alwats 0 */
#define CF_IDX     _BIT(1)
/* CompactFlash status register noncorrectable error bit */
#define CF_ERR     _BIT(0)

/* CompactFlash error register bad block bit */
#define CF_BBK     _BIT(7)
/* CompactFlash error register bauncorrectable error bit */
#define CF_UNC     _BIT(6)
/* CompactFlash error register bad sector bit */
#define CF_IDNF    _BIT(4)
/* CompactFlash error register abort error bit */
#define CF_ABORT   _BIT(2)
/* CompactFlash error register general error bit */
#define CF_AMNF    _BIT(1)

/* CompactFlash head register LBA mode select bit */
#define CF_LBA     _BIT(4)
/* CompactFlash Device control register reset bit */
#define CF_RST     _BIT(2)
/* CompactFlash Device control register Interrupt enable bit */
#define CF_IEN     _BIT(1)

/* CompactFlash card identification command */
#define CFC_IDENT  0xEC
/* CompactFlash Read sector command */
#define CFC_R_SECT 0x20
/* CompactFlash Read multiple sectors command */
#define CFC_R_MULT 0xC4
/* CompactFlash Write sector command */
#define CFC_W_SECT 0x30
/* CompactFlash Erase sector command */
#define CFC_E_SECT 0xC0
/* CompactFlash Set Multiple command */
#define CFC_S_MULT 0xC6

/* CompactFlash LBA mode enable in the sector register */
#define CF_LBA_MODE 0x40

/* Status word check mask used in detection scheme */
#define CF_DETECT_MASK (CF_BUSY | CF_RDY | CF_DSC | CF_IDX)

/* Expected value from masked status in CF detection scheme */
#define CF_DETECT_VALUE (CF_RDY | CF_DSC)

/* CF device sector size */
#define CF_SECT_SIZE 512

/* CompactFlash configuration structure type */
typedef struct
{
    BOOL_32 init;     /* Driver initialized/open flag */
    CF_STATUS_READ_REG_T *rregptr; /* Read register base pointer */
    CF_STATUS_WRITE_REG_T *wregptr; /* Write register base pointer */
} CF_CFG_T;

/* CompactFlash configuration driver data */
STATIC CF_CFG_T cfcfg;

/***********************************************************************
 * CompactFlash driver private functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: cf_set_seccmd
 *
 * Purpose: Issue the command for the next sector operation
 *
 * Processing:
 *     Set the Logical Block address (LBA) sector value to the passed
 *     sector value and the sector count to 1. Issue the passed
 *     command to the CompactFlash device.
 *
 * Parameters:
 *     sector:  Sector (LBA) to perform operation on
 *     command: CompactFlash command to use with sector
 *     wptr:    Pointer to CompactFlash memory mode register set
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void cf_set_seccmd(UNS_32 sector,
                   UNS_8 command,
                   CF_STATUS_WRITE_REG_T *wptr)
{
    volatile UNS_16 dummy;

    wptr->sec_count_no = (0x01 | (UNS_16) ((sector & 0xFF) << 8));
    dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
    wptr->sec_mid = (UNS_16) (((sector & 0xFF0000) >> 8) |
        (sector & 0xFF00) >> 8);
    dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
    wptr->sec_high_cmd = (UNS_16) ((((sector & 0xFF000000) >> 24) |
        CF_LBA_MODE) | (command << 8));
    dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
}

STATUS cf_start_read(CF_BLOCKS_T *sectorinfo,
                     CF_STATUS_WRITE_REG_T *wptr)
{
    volatile UNS_16 dummy;

    /* Issue command to read a single sector */
    if (sectorinfo->num_blocks == 1)
    {
        cf_set_seccmd((UNS_32) sectorinfo->sector, CFC_R_SECT, wptr);
    }
    else
    {
        wptr->sec_count_no = (sectorinfo->num_blocks & 0xFF);
        wptr->sec_high_cmd = (UNS_16) (CFC_S_MULT << 8);
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        wptr->sec_count_no = (sectorinfo->num_blocks |
            (UNS_16) ((sectorinfo->sector & 0xFF) << 8));
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        wptr->sec_mid = (UNS_16)
            (((sectorinfo->sector & 0xFF0000) >> 8) |
            (sectorinfo->sector & 0xFF00) >> 8);
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
        wptr->sec_high_cmd = (UNS_16)
            ((((sectorinfo->sector & 0xFF000000) >> 24) | CF_LBA_MODE) |
            (CFC_R_MULT << 8));
        dummy = * (volatile UNS_16 *) CF_DUMMY_RD;
    }

    return _NO_ERROR;
}

STATUS cf_start_write(CF_BLOCKS_T *sectorinfo,
                      CF_STATUS_WRITE_REG_T *wptr)
{
    volatile UNS_16 dummy;

    /* Issue command to write a single sector */
    cf_set_seccmd((UNS_32) sectorinfo->sector, CFC_W_SECT, wptr);

    return _NO_ERROR;
}

/***********************************************************************
 * CompactFlash driver public functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: cf_open
 *
 * Purpose: Open the CompactFlash interface
 *
 * Processing:
 *     If init is not FALSE and the passed ipbase does not point to the
 *     CompactFlash register base address, return NULL to the caller.

⌨️ 快捷键说明

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