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

📄 lh79524_lpd_cf_driver.c

📁 SHARP_ARM720T_LH79524/5软件开发包_支持TFT_LCD_NAND_FLASH_ETH_USB
💻 C
字号:
/***********************************************************************
 * $Workfile:   lh79524_lpd_cf_driver.c  $
 * $Revision:   1.0  $
 * $Author:   ZhangJ  $
 * $Date:   Oct 20 2004 09:38:42  $
 *
 * Project: CF card memory mode interface driver
 *
 * Description:
 *  This driver is based on the compact flash driver.
 *  This driver supports a CF card and it is on memory mode.
 *
 * Notes:
 *  The LH79520_cf_driver header file is included in the this file, as
 *  some CF specific data is defined there.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh79524/bsps/sdk79524/source/lh79524_lpd_cf_driver.c-arc  $
 * 
 *    Rev 1.0   Oct 20 2004 09:38:42   ZhangJ
 * 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) 2003 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/
#include "abl_types.h"
#include "LH79524_lpd_cf_driver.h"

static void cfmem_get_chs (void);
static void cfmem_dummy_write (void);
static void cfmem_dummy_read (void);
static void cfmem_delay_loop (INT_32 delay);

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

/***********************************************************************
 * Function: cfmem_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 cfmem_get_chs (void)
{
    UNS_16 data [256]; 
	UNS_16 value;
	
    // Issue a read attributes command to the CF device
	value = (CFMEM_STAT->sel_card) & 0xff;
	
	CFMEM_STAT->sel_card = value | (CFC_IDENT<<8);

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

    // Move data into the buffer
    cfmem_read_data (data, sizeof(data));

    // 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: cfmem_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 cfmem_init (void)
{
    INT_32 inserted;

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

/***********************************************************************
 * Function: cfmem_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 cfmem_shutdown (void)
{
    /* Do nothing */
    ;
}

/***********************************************************************
 * Function: cfmem_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 cfmem_is_card_inserted (void)
{
 	UNS_8 value;
	value = (CFMEM_STAT->sel_card)>>8;
    if ((value & CF_DETECT_MASK) == CF_DETECT_VALUE)
        return 1;
    else
    	return 0;
}

/***********************************************************************
 * Function: cfmem_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 cfmem_is_card_ready (void)
{       
	UNS_8 value;
	value = (CFMEM_STAT->sel_card)>>8;
    return ((value & CF_RDY) != 0);
}

/***********************************************************************
 * Function: cfmem_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 cfmem_is_card_busy (void)       
{
	UNS_8 value;
	value = (CFMEM_STAT->sel_card)>>8;
    return ((value & CF_BUSY) != 0);
}

/***********************************************************************
 * Function: cfmem_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 cfmem_set_sector (UNS_32 sectorno)
{
    UNS_16 sector, head, cylinder;
    UNS_32 csector;
    UNS_16 value;

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

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

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

    // Setup the IDE controller with the CHS mappings
    while (cfmem_is_card_busy () == 1);
    // Write cylinder value
    CFMEM_STAT->cyl_low   = cylinder;

    while (cfmem_is_card_busy () == 1);
    //Write head
    CFMEM_STAT->sel_card  = (head|0xa0);
    //CFMEM_STAT->sel_card  = (UNS_8)(head|0xa0);
    // Wait for command to complete
    while (cfmem_is_card_busy () == 1);
    // Write sector count and number (sector count fixed as 1)
	value = 1 | (sector)<<8;
    CFMEM_STAT->sector_count = value;

}

/***********************************************************************
 * Function: cfmem_send_command
 *
 * Purpose:  Send command to CF card
 *
 * Processing:  
 *
 * Parameters:  Command to send to CF card
 *
 * Outputs:  None
 *
 * Returns:  Nothing
 *
 * Notes:  None
 *
 **********************************************************************/
void cfmem_send_command (UNS_32 command)
{
	UNS_16 value;
	
	while(cfmem_is_card_ready() == 0);

    //read the register back
	value = (CFMEM_STAT->sel_card) & 0xff;
	//Write the new command	
	CFMEM_STAT->sel_card = value | (command<<8);

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

/***********************************************************************
 * Function: cfmem_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 cfmem_start_sector_read (void)
{

    //CFMEM_STAT->sector_count = 1;
    cfmem_send_command(CFC_R_SECT);
}

/***********************************************************************
 * Function: cfmem_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 cfmem_start_sector_write (void)
{
    //CFMEM_STAT->sector_count = 1;
    cfmem_send_command(CFC_W_SECT);
}

/***********************************************************************
 * Function: cfmem_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 cfmem_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 = CFMEM_STAT->data_NN;
        cf_data++;
        
        // sma
		//cfmem_dummy_read();
		
        //if (CFMEM_STAT->status_command & CF_DWF)
           //return 0;
    }
    return bytes;
}

/***********************************************************************
 * Function: cfmem_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 cfmem_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
        CFMEM_STAT->data_NN = *cf_data;
        cf_data++;
      
        //if (CFMEM_STAT->status_command & CF_DWF)
          //return 0;
    }
    return bytes;
}

/***********************************************************************
 * Function: cfmem_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 cfmem_erase_sector (INT_32 sectorno)
{
    cfmem_set_sector (sectorno);
    //CFMEM_STAT->sector_count = 1;
    cfmem_send_command (CFC_E_SECT);

    //if (CFMEM_STAT->status_command & CF_DWF)
        //return 1;
    return 0;
}


void cfmem_dummy_write(void)
{
	*(UNS_32 *)(0x40000000) = 0;
}

void cfmem_dummy_read(void)
{
	volatile int i;
	i = *(UNS_32 *)(0x40000000);
}

⌨️ 快捷键说明

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