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

📄 lh7a400_mmc_driver.c

📁 sharp触摸屏测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    INT_32 index;

    response = (UNS_16 *) buf;

    // Wait for response
    while ((mmc_regs->mmc_status & MMC_END_CMD_RESP) == 0);

    // Read the necessary number of response words from the response
    // FIFO
    for (index = 0; index < (resp_size / 2); index++)
    {
//        response [index] = swap (mmc_regs->result_fifo);
        response [index] = mmc_regs->result_fifo;
    }
}

/***********************************************************************
 *
 * Function: mmcif_init
 *
 * Purpose:
 *  Initialize the MMC interface.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  '1' if a MMC card has been detected, '0' otherwise.
 *
 * Notes:
 *  None
 *
 **********************************************************************/
INT_32 mmcif_init (void)
{
    INT_32 card_inserted;
    mmc_status_type cstatus;
    INT_32 try_count, successful_init, ocr_attempts;

    // Set register address for CPLD interface
    cpld_boot_mmc_status = (UNS_32 *) CPLD_BOOTMMC_ST;

    // Set mmc base address to point to MMC register set
    mmc_regs = (MMCREGS *) MMC_BASE_ADDR;

    // Check to see if card is inserted
    card_inserted = mmcif_is_card_inserted ();

    // Continue if a card is available
    if (card_inserted == 1)
    {
        try_count = 1;
        successful_init = 0;
        while ((try_count > 0) && (successful_init == 0))
        {
            // Disable controller
            mmc_regs->mmc_prediv = 0;

            // Disable SPI mode control functions
            mmc_regs->spi_mode = 0;

            // Disable interrupts, polling mode only
            mmc_regs->int_mask = -1;

            // Enable the PCLK to the MMC, enable FIFO reads via APB,
            // and set predivider to HCLK / 4
            mmc_regs->mmc_prediv =
                (MMC_EN | MMC_APB_RD_EN | MMC_PREDIV (6));

            // Set the clock divider to the initialization clock value
            // (With a prediv of HCLK / 4 and and clkdiv of 6
            // (1/64 divider), the maximum bit speed (at 100MHz HCLK)
            // will be 390KBps
            mmc_regs->mmc_clk_rate = 6;

            // Set timeout values for data and response
            mmc_regs->response_to = 0xFF;
            mmc_regs->read_to = 0x01FF;

            // Disable the MMC clock
            mmc_clock_stop ();

            // Place card in idle mode
            mmc_command (MMC_IDLE, 0);

            // Poll card until it has completed the power-up sequence
            ocr_attempts = 80;
            ocr [0] = 0;
            while (((ocr [0] & 0x80) == 0) && (ocr_attempts > 0))
            {
                mmc_command (MMC_SOP_COND, VRANGE_OCR);
                mmc_get_response (&ocr, sizeof (ocr));
                ocr_attempts--;
            }


            try_count--;
            successful_init = (INT_32) ((ocr [0] & 0x80) != 0);
        }

        // Request the CID from the MMC card(s)
        mmc_command (MMC_ALL_SEND_CID, 0);
        mmc_get_response (&acid, sizeof (acid));

        // Set the relative address of this card (only 1 card is
        // presently supported)
        rca = 0x00010000;
        mmc_command (MMC_SRA, rca);
        mmc_get_response (&cstatus, sizeof (cstatus));

        // Use faster response timeout after init
        mmc_regs->response_to = 0x10;

        mmc_regs->mmc_prediv = (MMC_EN | MMC_APB_RD_EN | MMC_PREDIV (3));
        mmc_regs->mmc_clk_rate = 1; // (100 / 6) Mbps max

        // Select card 'rca' as the active card
        mmc_command (MMC_DES_CARD, rca);
        mmc_get_response (&cstatus, sizeof (cstatus));

        // The CID and CSD are read (but never used)
        mmc_command (MMC_SEND_CID, rca);
        mmc_get_response (&cid, sizeof (cid));
        mmc_command (MMC_SEND_CSD, rca);
        mmc_get_response (&csd, sizeof (csd));

        // Deselect card
        mmc_command (MMC_DES_CARD, 0);
        mmc_get_response (&cstatus, sizeof (cstatus));

        // Leave the clock disabled until needed
        mmc_clock_stop ();
    }

    return card_inserted;
}

/***********************************************************************
 *
 * Function: mmcif_shutdown
 *
 * Purpose:
 *  Shutdown the MMC interface.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void mmcif_shutdown (void)
{
    mmc_status_type cstatus;

    // Put the card in inactive state - normally this is not
    // needed, but if this init sequence is called more than once,
    // the second time will fail withou this sequence
    mmc_command (MMC_INACTIVE, 0);
    mmc_get_response (&cstatus, sizeof (cstatus));

    // Disable the MMC clock
    mmc_regs->str_stp_clk = MMC_STOP_CLK;

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

    // Disable PCLK to the device
    mmc_regs->mmc_prediv = mmc_regs->mmc_prediv & ~MMC_EN;
}

/***********************************************************************
 *
 * Function: mmcif_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 mmcif_is_card_inserted (void)
{
    return ((*cpld_boot_mmc_status & CPLD_MMC_DETECT) != 0);
}

/***********************************************************************
 *
 * Function: mmcif_set_sector
 *
 * Purpose:
 *  Set the sector number for the next operation.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  '1' if a card is inserted, '0' otherwise.
 *
 * Notes:
 *  The convention is Cylinder/Head/Sector (CHS). The function will
 *  convert the CHS values to a value that works with the MMC card.
 *
 **********************************************************************/
void mmcif_set_sector (UNS_32 sectorno)
{
    next_sector = (UNS_32) sectorno * MMC_BLK_SIZE;
}

/***********************************************************************
 *
 * Function: mmcif_is_card_ready
 *
 * Purpose:
 *  Determines if the card is ready for a new command.
 *
 * Processing:
 *  Use the busy status function as the card ready indicator.
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  '1' if the card is ready for a new command, '0' otherwise.
 *
 * Notes:
 *  None
 *
 **********************************************************************/
INT_32 mmcif_is_card_ready (void)
{
    return (1 - mmcif_is_card_busy ());
}

/***********************************************************************
 *
 * Function: mmcif_is_card_busy
 *
 * Purpose:
 *  Determine if a card is busy (processing a command).
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  '1' if the card is busy, '0' otherwise.
 *
 * Notes:
 *  This function is not used. (Specific waits are performed in other
 *  placeds in the driver.)
 *
 **********************************************************************/
INT_32 mmcif_is_card_busy (void)
{
    return 0;
}

/***********************************************************************
 *
 * Function: mmcif_start_sector_read
 *
 * Purpose:
 *  Starts the read of a sector.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void mmcif_start_sector_read (void)
{
    mmc_status_type cstatus;
    UNS_16 dummy;

    // Select card 'rca' as the active card
    mmc_command (MMC_DES_CARD, rca);
    mmc_get_response (&cstatus, sizeof (cstatus));

    // Send block length command to card
    mmc_command (MMC_SET_BLEN, MMC_BLK_SIZE);
    mmc_get_response (&cstatus, sizeof (cstatus));

    // Pre-empty the data FIFO
    while ((mmc_regs->mmc_status & MMC_FIFO_EMPTY) == 0)
    {
        dummy = mmc_regs->data_fifo;
    }

    // Issue the read block command
    mmc_command (MMC_READ_SINGLE, next_sector);
    mmc_get_response (&cstatus, sizeof (cstatus));
}

/***********************************************************************
 *
 * Function: mmcif_start_sector_write
 *
 * Purpose:
 *  Starts the write of a sector.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void mmcif_start_sector_write (void)
{
    mmc_status_type cstatus;
    UNS_16 dummy;

#if 0
    // Select card 'rca' as the active card
    mmc_command (MMC_DES_CARD, rca);
    mmc_get_response (&cstatus, MMC_DES_CARD);

    // Send block length command to card
    mmc_command (MMC_SET_BLEN, MMC_BLK_SIZE);
    mmc_get_response (&cstatus, MMC_SET_BLEN);

    // Pre-empty the data FIFO
    while ((mmc_regs->mmc_status & MMC_FIFO_EMPTY) == 0)
    {
        dummy = mmc_regs->data_fifo;
    }

    // Issue the read block command
    mmc_command (MMC_WRITE_SINGLE, next_sector);
    mmc_get_response (&cstatus, MMC_WRITE_SINGLE);
#endif
}

/***********************************************************************
 *
 * Function: mmcif_read_data
 *
 * Purpose:
 *  Read a block of data from the MMC card.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  data  : Pointer to where to put read data from the MMC 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:
 *  None
 *
 **********************************************************************/
INT_32 mmcif_read_data (void *data, INT_32 bytes)
{
    INT_32 i = 0;
    mmc_status_type cstatus;
    UNS_16 *buf = (UNS_16 *) data;

    // Wait until transfer is complete
    while ((mmc_regs->mmc_status & MMC_DATA_TRAN_DONE) == 0);

    // Continue reading data until FIFO is empty
    while (((mmc_regs->mmc_status & MMC_FIFO_EMPTY) == 0) &&
        (i < (bytes / 2)))
    {
        // Any data in the FIFO
        if ((mmc_regs->mmc_status & MMC_FIFO_EMPTY) == 0)
        {
            buf [i] = swap (mmc_regs->data_fifo);            
            i++;
        }
    }

	// Stop the MMC clock
    mmc_clock_stop ();

    // Set card 'rca' as an inactive card
    mmc_command (MMC_DES_CARD, 0);
    mmc_get_response (&cstatus, sizeof (cstatus));

    return bytes;
}

/***********************************************************************
 *
 * Function: mmcif_write_data
 *
 * Purpose:
 *  Write a block of data to the MMC card.
 *
 * Processing:
 *  TBD
 *
 * Parameters:
 *  data  : Pointer to where to get data to write to the MMC card
 *  bytes : Number of bytes to write
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  The number of bytes written from the card.
 *
 * Notes:
 *  None
 *
 **********************************************************************/
INT_32 mmcif_write_data (void *data, INT_32 bytes)
{
    INT_32 i = 0;
    mmc_status_type cstatus;
    UNS_16 *buf = (UNS_16 *) data;

    ;

	// Stop the MMC clock
    mmc_clock_stop ();

    // Set card 'rca' as an inactive card
    mmc_command (MMC_DES_CARD, 0);
    mmc_get_response (&cstatus, sizeof (cstatus));

    return bytes;
}

⌨️ 快捷键说明

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