📄 sdk7a404_cf_driver.c
字号:
/***********************************************************************
* $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 + -