📄 kev7a400_cf_driver.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 + -