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

📄 lh7a400_mmc_driver.c

📁 sharp触摸屏测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $Workfile:   LH7A400_mmc_driver.c  $
 * $Revision:   1.3  $
 * $Author:   WellsK  $
 * $Date:   Sep 22 2002 14:21:40  $
 *
 * Project: Multimedia controller interface driver
 *
 * Description:
 *  This driver reads and writes raw 'sectors' in the MMC 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 MMC interface must be performed
 *  at a higher driver level. Multitasking in the MMC interface is not
 *  supported. If a read operation is performed, the data should be
 *  read from the card before another operation is performed.
 *
 * Known issues:
 *  Write operations are not yet supported in this driver. Byte
 *  swapping code has been temporarily added.
 *
 * Notes:
 *  The MMC card detection logic can be performed via the function
 *  supplied in the CPLD driver. To reduce dependency on that driver,
 *  the function has been added in this driver.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/MMC/Drivers/LH7A400_mmc_driver.c-arc  $
 * 
 *    Rev 1.3   Sep 22 2002 14:21:40   WellsK
 * Remove call to shutdown if MMC card was not detected.
 * 
 *    Rev 1.2   Sep 14 2002 08:52:34   WellsK
 * Corrected OCR check logic
 * Corrected card select/deselect logic
 * Used types and defines from MMC structure header file
 * Other minor tweaks
 * 
 *    Rev 1.1   Sep 07 2002 12:05:40   WellsK
 * Changed HCLK rate retrieve function. Added code to perform
 * init with 4 retries before driver init fails.
 * 
 *    Rev 1.0   Aug 28 2002 13:51:08   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) 2002 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/
#include "SMA_types.h"
#include "LH7A400_mmc.h"
#include "LH7A400_mmc_driver.h"
#include "LH7A400_CSC_driver.h"

//**********************************************************************
// Local defines
//**********************************************************************
// CPLD register bits and addresses
#define CPLD_BOOTMMC_ST 0x20000006 // Boot/MMC status register address
#define CPLD_MMC_DETECT 0x0001     // CPLD MMC card detect

// Other defines
#define MMC_BPS_CLK     20000000   // Best MMC bit/second rate
#define MMC_BASE_ADDR   0x80000100 // MMC register set base
#define VRANGE_OCR      0x001C0000 // MMC cards allowed at 3.0 to 3.3v
#define MMC_BLK_SIZE    512        // MMC sector size

//**********************************************************************
// MMC structures
//**********************************************************************
// Possible commands (send operations are 'sent' from the card to the
// MultiMedia Controller (MMC)
typedef enum
{
    MMC_IDLE,              // Put card in idle mode
    MMC_SOP_COND,          // Send operating condition (OCR)
    MMC_ALL_SEND_CID,      // All send CID data
    MMC_SRA,               // Set relative address
    MMC_DES_CARD,          // Delselect card
    MMC_SEND_CSD,          // Send CSD data
    MMC_SEND_CID,          // Send CID register data (with rel. addr)
    MMC_READ_UNTIL_STOP,   // Read data until stop command
    MMC_STOP_TRAN,         // Stop data transfer
    MMC_SSTAT,             // Send status
    MMC_INACTIVE,          // Put card in inactive state
    MMC_SET_BLEN,          // Set block transfer length
    MMC_READ_SINGLE,       // Read a single block
    MMC_READ_MULTIPLE,     // Read multiple blocks
    MMC_WRITE_SINGLE,      // Write a single block
    MMC_WRITE_MULTIPLE,    // Write multiple blocks
    MMC_INVALID_CMD        // Invalid command
} mmc_command_type;

// Each command enumeration has a MMC command number (used by the card)
// and a MMC command/control word (used by the controller). This
// structure defines this word pair.
typedef struct
{
    UNS_32 cmd;
    UNS_32 cmdctl;
} cmd_ctrl_type;

//**********************************************************************
// MMC structured data returned from card commands (responses)
// These structures are not used in the code, but are placed here for
// informational purposes only.
//**********************************************************************
// OCR register data (response R1)
typedef struct
{
    UNS_32 end_bit         : 1;
    UNS_32 crc7            : 7;
    UNS_32 rsv1            : 8;
    UNS_32 volts_20__21    : 1;
    UNS_32 volts_21__22    : 1;
    UNS_32 volts_22__23    : 1;
    UNS_32 volts_23__24    : 1;
    UNS_32 volts_24__25    : 1;
    UNS_32 volts_25__26    : 1;
    UNS_32 volts_26__27    : 1;
    UNS_32 volts_27__28    : 1;
    UNS_32 volts_28__29    : 1;
    UNS_32 volts_29__30    : 1;
    UNS_32 volts_30__31    : 1;
    UNS_32 volts_31__32    : 1;
    UNS_32 volts_32__33    : 1;
    UNS_32 volts_33__34    : 1;
    UNS_32 volts_34__35    : 1;
    UNS_32 volts_35__36    : 1;
    UNS_32 rsv2            : 7;
    UNS_32 card_not_busy   : 1;
    UNS_32 cmd_index       : 6;
    UNS_32 start_tran_bits : 2;
} ocr_register_type;

// CID register data (not used, information only), 128 bits
typedef struct
{
    UNS_32 rsv             : 1;
    UNS_32 crc             : 7;
    UNS_32 date            : 8;
    UNS_32 serial_number   : 32;
    UNS_32 product_rev     : 8;
    UNS_32 product_name_b  : 32;
    UNS_32 product_name_a  : 16;
    UNS_32 oem_id          : 16;
    UNS_32 manufacturer_id : 8;
} mmc_cid_type;

// CSD register data (not used, information only)
typedef struct
{
    UNS_32 end_bit         : 1;
    UNS_32 crc7            : 7;
    UNS_32 rsv1            : 1;
    UNS_32 crc             : 7;
    UNS_32 ecc             : 2;
    UNS_32 rsv2            : 2;
    UNS_32 wr_protect_tmp  : 1;
    UNS_32 wr_protect_perm : 1;
    UNS_32 copy            : 1;
    UNS_32 rsv3            : 6;
    UNS_32 wr_blk_partial  : 1;
    UNS_32 wr_blk_len      : 4;
    UNS_32 r2w_factor      : 3;
    UNS_32 default_ecc     : 2;
    UNS_32 wp_grp_enable   : 1;
    UNS_32 wp_grp_size     : 5;
    UNS_32 erase_grp_size  : 5;
    UNS_32 sector_size     : 5;
    UNS_32 c_size_mult     : 3;
    UNS_32 wr_curr_max     : 3;
    UNS_32 wr_curr_min     : 3;
    UNS_32 rd_curr_max     : 3;
    UNS_32 rd_curr_min     : 3;
    UNS_32 c_size_h        : 2;
    UNS_32 c_size_l        : 10;
    UNS_32 rsv4            : 2;
    UNS_32 dsr_imp         : 1;
    UNS_32 rd_blk_misalgn  : 1;
    UNS_32 wr_blk_misalgn  : 1;
    UNS_32 rd_blk_partial  : 1;
    UNS_32 rd_blk_len      : 4;
    UNS_32 ccc             : 12;
    UNS_32 tran_speed      : 8;
    UNS_32 nsac            : 8;
    UNS_32 taac            : 8;
    UNS_32 rsv5            : 2;
    UNS_32 mmc_prot        : 4;
    UNS_32 csd_struct      : 2;
    UNS_32 cmd_index       : 6;
    UNS_32 start_tran_bits : 2;
} mmc_csd_type;

// Status register data
typedef struct
{
    UNS_32 rsv1            : 5;
    UNS_32 app_cmd         : 1;
    UNS_32 rsv2            : 2;
    UNS_32 buff_empty      : 1;
    UNS_32 card_state      : 4;
    UNS_32 erase_reset     : 1;
    UNS_32 card_ecc_dis    : 1;
    UNS_32 wp_erase_skip   : 1;
    UNS_32 csd_overwrite   : 1;
    UNS_32 int_error       : 1;
    UNS_32 overrun         : 1;
    UNS_32 underrun        : 1;
    UNS_32 general_error   : 1;
    UNS_32 cc_error        : 1;
    UNS_32 card_ecc_failed : 1;
    UNS_32 illegal_cmd     : 1;
    UNS_32 crc_error       : 1;
    UNS_32 lock_ulock_fail : 1;
    UNS_32 card_locked     : 1;
    UNS_32 wr_volation     : 1;
    UNS_32 erase_sel_error : 1;
    UNS_32 erase_seq_error : 1;
    UNS_32 invalid_blk_len : 1;
    UNS_32 misalgn_addr    : 1;
    UNS_32 cmd_out_of_rnge : 1;
} mmc_status_type;

//**********************************************************************
// Package data
//**********************************************************************
// MMC register set base addresses
MMCREGS *mmc_regs;

// CPLD MMC status register
volatile UNS_32 *cpld_boot_mmc_status;

// Card identifier number (128 bits)
UNS_32 cid [5], acid [5];

// Card-specific data register (128 bits)
UNS_32 csd [5];

// Relative card address
UNS_32 rca;

// OCR register status
//ocr_register_type ocr;
UNS_16 ocr [3];

// Next sector operation pointer
UNS_32 next_sector;

// The following list maps a command enumeration to a MMC command
// number and command/control word
cmd_ctrl_type const cmd_data [MMC_INVALID_CMD] =
{
    {0,  (MMC_INITIALIZE | MMC_REPONSE_FORMAT (0))},    // MMC_IDLE
    {1,  (MMC_REPONSE_FORMAT (3))},               // MMC_SOP
    {2,  (MMC_REPONSE_FORMAT (2))},               // MMC_ALL_SEND_CID
    {3,  (MMC_REPONSE_FORMAT (1))},               // MMC_SRA
    {7,  (MMC_REPONSE_FORMAT (1))},               // MMC_DES_CARD
    {9,  (MMC_REPONSE_FORMAT (2))},               // MMC_SCSD
    {10, (MMC_REPONSE_FORMAT (2))},               // MMC_SCID
    {11, (MMC_REPONSE_FORMAT (1))},               // MMC_READ_UNTIL_STOP
    {12, (MMC_BUSY | MMC_REPONSE_FORMAT (1))},    // MMC_STOP_TRAN
    {13, (MMC_REPONSE_FORMAT (1))},               // MMC_SSTAT
    {15, (MMC_REPONSE_FORMAT (1))},               // MMC_INACTIVE
    {16, (MMC_REPONSE_FORMAT (1))},               // MMC_SET_BLEN
    {17, (MMC_DATA_EN | MMC_REPONSE_FORMAT (1))}, // MMC_READ_SINGLE
    {18, (MMC_DATA_EN | MMC_REPONSE_FORMAT (1))}, // MMC_READ_MULTIPLE
    {24, (MMC_DATA_EN | MMC_REPONSE_FORMAT (1))}, // MMC_WRITE_SINGLE
    {25, (MMC_DATA_EN | MMC_REPONSE_FORMAT (1))}  // MMC_WRITE_MULTIPLE
};

/***********************************************************************
 *
 * Function: mmc_determine_div
 *
 * Purpose:
 *  xxx
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  xxx
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  xxx
 *
 * Notes:
 *  This function is private to this module.
 *
 **********************************************************************/
int mmc_determine_div (UNS_32 nom_freq)
{
    UNS_32 lcd_clock, lcd_diff1, lcd_diff2, ahb_speed;
    UNS_32 div = 1;

    // Get AHB bus speed
    ahb_speed = LH7A400_get_hclk ();
    lcd_clock = ahb_speed / div;

    // Try to get the best divider just under the nominal frequency
    while (lcd_clock > nom_freq)
    {
        div++;
        lcd_clock = ahb_speed / div;
    }

    if (div > 1)
    {
        // Determine if 'div' or 'div - 1' is closer to nominal frequency
        if (lcd_clock > nom_freq)
        {
            lcd_diff1 = lcd_clock - nom_freq;
        }
        else
        {
            lcd_diff1 = nom_freq - lcd_clock;
        }

        lcd_clock = ahb_speed / (div - 1);
        if (lcd_clock > nom_freq)
        {
            lcd_diff2 = lcd_clock - nom_freq;
        }
        else
        {
            lcd_diff2 = nom_freq - lcd_clock;
        }

        // If diff1 is greater than diff2, then 'div + 1' is the
        // closest divider.
        if ((lcd_diff1 > lcd_diff2) && (div > 1))
        {
            div--;
        }
    }

    return div;
}

/***********************************************************************
 *
 * Function: mmc_clock_stop
 *
 * Purpose:
 *  Stops the MMC clock.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  This function is private to this module.
 *
 **********************************************************************/
void mmc_clock_stop (void)
{
    // Stop the clock
    mmc_regs->str_stp_clk = MMC_STOP_CLK;

    // Wait for MMC clock to stop
    while ((mmc_regs->mmc_status & MMC_CLK_ENABLE) == 0);
}

/***********************************************************************
 *
 * Function: mmc_clock_start
 *
 * Purpose:
 *  Starts the MMC clock.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  This function is private to this module.
 *
 **********************************************************************/
void mmc_clock_start (void)
{
    // Stop the clock
    mmc_regs->str_stp_clk = MMC_START_CLK;

    // Wait for MMC clock to stop
    while ((mmc_regs->mmc_status & MMC_CLK_ENABLE) != 0);
}

/***********************************************************************
 *
 * Function: mmc_command
 *
 * Purpose:
 *  TBD
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  cmd : Command enumeration
 *  arg : Command argument
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  This function is private to this module.
 *
 **********************************************************************/
void mmc_command (UNS_32 cmd, UNS_32 arg)
{
    // Stop the clock
    mmc_clock_stop ();

    // Place the command and argument in the command number and
    // argument registers
    mmc_regs->cmd_num = cmd_data [cmd].cmd;
    mmc_regs->argument = arg;

    // Update controller command/control word
    mmc_regs->cmd_data_cont = cmd_data [cmd].cmdctl;

    // Restart clock
    mmc_clock_start ();
}

UNS_16 swap (UNS_32 val)
{
    UNS_16 hi, lo;
    hi = ((UNS_16) val & 0x00FF) << 8;
    lo = ((UNS_16) val & 0xFF00) >> 8;
    return (lo + hi);
}

/***********************************************************************
 *
 * Function: mmc_get_response
 *
 * Purpose:
 *  TBD
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  buf   : Address of where to place response
 *  bytes : Number of response bytes to copy
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  This function is private to this module.
 *
 **********************************************************************/
void mmc_get_response (void *buf, INT_32 resp_size)
{
    UNS_16 *response;

⌨️ 快捷键说明

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