402 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			402 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/**********************************************************************
							 | 
						||
| 
								 | 
							
								* $Id$		lpc43xx_sdif.c		2012-Aug-15
							 | 
						||
| 
								 | 
							
								*//**
							 | 
						||
| 
								 | 
							
								* @file		lpc43xx_sdif.c
							 | 
						||
| 
								 | 
							
								* @brief	LPC43xx SD interface driver
							 | 
						||
| 
								 | 
							
								* @version	1.0
							 | 
						||
| 
								 | 
							
								* @date		15. Aug. 2012
							 | 
						||
| 
								 | 
							
								* @author	NXP MCU SW Application Team
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								* Copyright(C) 2011, NXP Semiconductor
							 | 
						||
| 
								 | 
							
								* All rights reserved.
							 | 
						||
| 
								 | 
							
								*
							 | 
						||
| 
								 | 
							
								***********************************************************************
							 | 
						||
| 
								 | 
							
								* Software that is described herein is for illustrative purposes only
							 | 
						||
| 
								 | 
							
								* which provides customers with programming information regarding the
							 | 
						||
| 
								 | 
							
								* products. This software is supplied "AS IS" without any warranties.
							 | 
						||
| 
								 | 
							
								* NXP Semiconductors assumes no responsibility or liability for the
							 | 
						||
| 
								 | 
							
								* use of the software, conveys no license or title under any patent,
							 | 
						||
| 
								 | 
							
								* copyright, or mask work right to the product. NXP Semiconductors
							 | 
						||
| 
								 | 
							
								* reserves the right to make changes in the software without
							 | 
						||
| 
								 | 
							
								* notification. NXP Semiconductors also make no representation or
							 | 
						||
| 
								 | 
							
								* warranty that such application will be suitable for the specified
							 | 
						||
| 
								 | 
							
								* use without further testing or modification.
							 | 
						||
| 
								 | 
							
								* Permission to use, copy, modify, and distribute this software and its
							 | 
						||
| 
								 | 
							
								* documentation is hereby granted, under NXP Semiconductors'
							 | 
						||
| 
								 | 
							
								* relevant copyright in the software, without fee, provided that it
							 | 
						||
| 
								 | 
							
								* is used in conjunction with NXP Semiconductors microcontrollers.  This
							 | 
						||
| 
								 | 
							
								* copyright, permission, and disclaimer notice must appear in all copies of
							 | 
						||
| 
								 | 
							
								* this code.
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Peripheral group ----------------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								/** @addtogroup SDIF
							 | 
						||
| 
								 | 
							
								 * @{
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Includes ------------------------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								#include "LPC43xx.h"                    /* LPC43xx definitions                */
							 | 
						||
| 
								 | 
							
								#include "system_LPC43xx.h"
							 | 
						||
| 
								 | 
							
								#include "lpc_sdmmc.h"
							 | 
						||
| 
								 | 
							
								#include "lpc43xx_sdif.h"
							 | 
						||
| 
								 | 
							
								#include "lpc43xx_cgu.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* If this source file built with example, the lpc43xx FW library configuration
							 | 
						||
| 
								 | 
							
								 * file in each example directory ("lpc43xx_libcfg.h") must be included,
							 | 
						||
| 
								 | 
							
								 * otherwise the default FW library configuration file must be included instead
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#ifdef __BUILD_WITH_EXAMPLE__
							 | 
						||
| 
								 | 
							
								#include "lpc43xx_libcfg.h"
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#include "lpc43xx_libcfg_default.h"
							 | 
						||
| 
								 | 
							
								#endif /* __BUILD_WITH_EXAMPLE__ */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef _SDIF
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Local data structure for the SDIF driver */
							 | 
						||
| 
								 | 
							
								struct _sdif_device {
							 | 
						||
| 
								 | 
							
								    MCI_IRQ_CB_FUNC_T irq_cb;
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC_DMA_Type mci_dma_dd[1 + (0x10000 / MCI_DMADES1_MAXTR)];
							 | 
						||
| 
								 | 
							
								    uint32_t sdio_clk_rate;
							 | 
						||
| 
								 | 
							
								    uint32_t sdif_slot_clk_rate;
							 | 
						||
| 
								 | 
							
								    int32_t clock_enabled;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								static struct _sdif_device sdif_dev;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Enables the SDIO controller clock
							 | 
						||
| 
								 | 
							
								* @param[in]	None
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								static void sdif_enable_clock(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!sdif_dev.clock_enabled)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /* Enable SD MMC clock */
							 | 
						||
| 
								 | 
							
								        CGU_ConfigPWR(CGU_PERIPHERAL_SDIO, ENABLE);
							 | 
						||
| 
								 | 
							
								        sdif_dev.clock_enabled = 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Disables the SDIO controller clock
							 | 
						||
| 
								 | 
							
								* @param[in]	None
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								static void sdif_disable_clock(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (!sdif_dev.clock_enabled)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /* Disable SD MMC clock */
							 | 
						||
| 
								 | 
							
								        CGU_ConfigPWR(CGU_PERIPHERAL_SDIO, (FunctionalState)FALSE);
							 | 
						||
| 
								 | 
							
								        sdif_dev.clock_enabled = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Public Functions ----------------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								/** @defgroup SDIF_Public_Functions
							 | 
						||
| 
								 | 
							
								 * @ingroup SDIF
							 | 
						||
| 
								 | 
							
								 * @{
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Setup DMA descriptors
							 | 
						||
| 
								 | 
							
								* @param[in]	addr Address of buffer (source or destination)
							 | 
						||
| 
								 | 
							
								* @param[in]	size size of buffer in bytes (64K max)
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_dma_setup(uint32_t addr, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int i = 0;
							 | 
						||
| 
								 | 
							
									uint32_t ctrl, maxs;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Reset DMA */
							 | 
						||
| 
								 | 
							
									LPC_SDMMC->CTRL |= MCI_CTRL_DMA_RESET | MCI_CTRL_FIFO_RESET;
							 | 
						||
| 
								 | 
							
								 	while (LPC_SDMMC->CTRL & MCI_CTRL_DMA_RESET);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Build a descriptor list using the chained DMA method */
							 | 
						||
| 
								 | 
							
									while (size > 0)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
										/* Limit size of the transfer to maximum buffer size */
							 | 
						||
| 
								 | 
							
										maxs = size;
							 | 
						||
| 
								 | 
							
										if (maxs > MCI_DMADES1_MAXTR)
							 | 
						||
| 
								 | 
							
											maxs = MCI_DMADES1_MAXTR;
							 | 
						||
| 
								 | 
							
										size -= maxs;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Set buffer size */
							 | 
						||
| 
								 | 
							
										sdif_dev.mci_dma_dd[i].des1 = MCI_DMADES1_BS1(maxs);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Setup buffer address (chained) */
							 | 
						||
| 
								 | 
							
										sdif_dev.mci_dma_dd[i].des2 = addr + (i * MCI_DMADES1_MAXTR);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Setup basic control */
							 | 
						||
| 
								 | 
							
										ctrl = MCI_DMADES0_OWN | MCI_DMADES0_CH;
							 | 
						||
| 
								 | 
							
										if (i == 0)
							 | 
						||
| 
								 | 
							
											ctrl |= MCI_DMADES0_FS; /* First DMA buffer */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* No more data? Then this is the last descriptor */
							 | 
						||
| 
								 | 
							
										if (!size)
							 | 
						||
| 
								 | 
							
											ctrl |= MCI_DMADES0_LD;
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											ctrl |= MCI_DMADES0_DIC;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										/* Another descriptor is needed */
							 | 
						||
| 
								 | 
							
										sdif_dev.mci_dma_dd[i].des3 = (uint32_t) &sdif_dev.mci_dma_dd[i + 1];
							 | 
						||
| 
								 | 
							
										sdif_dev.mci_dma_dd[i].des0 = ctrl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										i++;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Set DMA derscriptor base address */
							 | 
						||
| 
								 | 
							
									LPC_SDMMC->DBADDR = (uint32_t) &sdif_dev.mci_dma_dd[0];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Function to send command to Card interface unit (CIU)
							 | 
						||
| 
								 | 
							
								* @param[in]	cmd Command with all flags set
							 | 
						||
| 
								 | 
							
								* @param[in]	arg Argument for the command
							 | 
						||
| 
								 | 
							
								* @return 		TRUE on times-out, otherwise FALSE
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								int32_t sdif_send_cmd(uint32_t cmd, uint32_t arg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    volatile int32_t tmo = 50;
							 | 
						||
| 
								 | 
							
								    volatile int delay;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* set command arg reg*/
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CMDARG = arg;
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CMD = MCI_CMD_START | cmd;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* poll untill command is accepted by the CIU */
							 | 
						||
| 
								 | 
							
								    while (--tmo && (LPC_SDMMC->CMD & MCI_CMD_START))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (tmo & 1)
							 | 
						||
| 
								 | 
							
								            delay = 50;
							 | 
						||
| 
								 | 
							
								        else
							 | 
						||
| 
								 | 
							
								            delay = 18000;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        while (--delay > 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (tmo < 1) ? 1 : 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Function to retrieve command response
							 | 
						||
| 
								 | 
							
								* @param[in]	pdev Pointer to card info structure
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_get_response(uint32_t *resp)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  /* on this chip response is not a fifo so read all 4 regs */
							 | 
						||
| 
								 | 
							
								  resp[0] = LPC_SDMMC->RESP0;
							 | 
						||
| 
								 | 
							
								  resp[1] = LPC_SDMMC->RESP1;
							 | 
						||
| 
								 | 
							
								  resp[2] = LPC_SDMMC->RESP2;
							 | 
						||
| 
								 | 
							
								  resp[3] = LPC_SDMMC->RESP3;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Function to set speed of the clock going to card
							 | 
						||
| 
								 | 
							
								* @param[in]	speed Desired clock speed to the card
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_set_clock(uint32_t speed)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* compute SD/MMC clock dividers */
							 | 
						||
| 
								 | 
							
								    uint32_t div;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Exit if the clock is already set at the passed speed */
							 | 
						||
| 
								 | 
							
								    if (sdif_dev.sdif_slot_clk_rate == speed)
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    div = ((sdif_dev.sdio_clk_rate / speed) + 2) >> 1;
							 | 
						||
| 
								 | 
							
								    sdif_dev.sdif_slot_clk_rate = speed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((div == LPC_SDMMC->CLKDIV) && LPC_SDMMC->CLKENA)
							 | 
						||
| 
								 | 
							
								        return; /* Closest speed is already set */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable clock */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CLKENA = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* User divider 0 */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CLKSRC = MCI_CLKSRC_CLKDIV0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* inform CIU */
							 | 
						||
| 
								 | 
							
								    sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* set divider 0 to desired value */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CLKDIV = MCI_CLOCK_DIVIDER(0, div);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* inform CIU */
							 | 
						||
| 
								 | 
							
								    sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable clock */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CLKENA = MCI_CLKEN_ENABLE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* inform CIU */
							 | 
						||
| 
								 | 
							
								    sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Detect if an SD card is inserted
							 | 
						||
| 
								 | 
							
								* @param[in]	None
							 | 
						||
| 
								 | 
							
								* @return 		Returns 0 if a card is detected, otherwise 1
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								int32_t sdif_card_ndetect(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* No card = high state in regsiter */
							 | 
						||
| 
								 | 
							
									if (LPC_SDMMC->CDETECT & 1)
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return 1;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Detect if write protect is enabled
							 | 
						||
| 
								 | 
							
								* @param[in]	None
							 | 
						||
| 
								 | 
							
								* @return 		Returns 1 if card is write protected, otherwise 0
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								int32_t sdif_card_wp_on(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (LPC_SDMMC->WRTPRT & 1)
							 | 
						||
| 
								 | 
							
										return 1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Enable or disable slot power
							 | 
						||
| 
								 | 
							
								* @param[in]	enable !0 to enable, or 0 to disable
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_power_onoff(int32_t enable)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (enable)
							 | 
						||
| 
								 | 
							
										LPC_SDMMC->PWREN = 1;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										LPC_SDMMC->PWREN = 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Reset card in slot
							 | 
						||
| 
								 | 
							
								* @param[in]	reset Sets SD_RST to passed state
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_reset(int32_t reset)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (reset)
							 | 
						||
| 
								 | 
							
										LPC_SDMMC->RST_N = 1;
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										LPC_SDMMC->RST_N = 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Set block size for transfer
							 | 
						||
| 
								 | 
							
								* @param[in]	bytes Lock size in bytes
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_set_blksize(uint32_t bytes)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								      LPC_SDMMC->BLKSIZ = bytes;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Enter or exit low power mode (disables clocking)
							 | 
						||
| 
								 | 
							
								* @param[in]	lpmode !0 to enable low power mode, 0 = exit
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_set_lowpower_mode(int32_t lpmode)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/* Once in low power mode, no SDIF functions should ever be
							 | 
						||
| 
								 | 
							
									   called, as it can hang the chip. Always exit low power mode
							 | 
						||
| 
								 | 
							
									   prior to resuming SDIF functions */
							 | 
						||
| 
								 | 
							
								    if (lpmode)
							 | 
						||
| 
								 | 
							
								        sdif_disable_clock();
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								        sdif_enable_clock();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Initializes the MCI card controller
							 | 
						||
| 
								 | 
							
								* @param[in]	waitfunc Pointer to wait function to be used during for poll command status
							 | 
						||
| 
								 | 
							
								* @param[in]	irq_callback Pointer to IRQ callback function
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_init(uint32_t sdio_clock, MCI_IRQ_CB_FUNC_T irq_callback)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    volatile uint32_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sdif_dev.sdio_clk_rate = sdio_clock;
							 | 
						||
| 
								 | 
							
								    sdif_dev.irq_cb = irq_callback;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* enable SD/MMC clock */
							 | 
						||
| 
								 | 
							
								    sdif_enable_clock();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Software reset */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->BMOD = MCI_BMOD_SWR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* reset all blocks */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CTRL = MCI_CTRL_RESET | MCI_CTRL_FIFO_RESET |
							 | 
						||
| 
								 | 
							
								        MCI_CTRL_DMA_RESET;
							 | 
						||
| 
								 | 
							
								    while (LPC_SDMMC->CTRL &
							 | 
						||
| 
								 | 
							
								        (MCI_CTRL_RESET | MCI_CTRL_FIFO_RESET | MCI_CTRL_DMA_RESET));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Internal DMA setup for control register */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CTRL = MCI_CTRL_USE_INT_DMAC | MCI_CTRL_INT_ENABLE;
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->INTMASK = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Clear the interrupts for the host controller */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->RINTSTS = 0xFFFFFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Put in max timeout */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->TMOUT = 0xFFFFFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* FIFO threshold settings for DMA, DMA burst of 4,
							 | 
						||
| 
								 | 
							
								       FIFO watermark at 16 */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->FIFOTH = MCI_FIFOTH_DMA_MTS_4 |
							 | 
						||
| 
								 | 
							
								        MCI_FIFOTH_RX_WM((SD_FIFO_SZ / 2) - 1) |
							 | 
						||
| 
								 | 
							
								        MCI_FIFOTH_TX_WM(SD_FIFO_SZ / 2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Enable internal DMA, burst size of 4, fixed burst */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->BMOD = MCI_BMOD_DE | MCI_BMOD_PBL4 | MCI_BMOD_DSL(4);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable clock to CIU (needs latch) */
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CLKENA = 0;
							 | 
						||
| 
								 | 
							
								    LPC_SDMMC->CLKSRC = 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		Close the MCI
							 | 
						||
| 
								 | 
							
								* @param[in]	None
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void sdif_deinit(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* clear mmc structure*/
							 | 
						||
| 
								 | 
							
								    sdif_disable_clock();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*********************************************************************//**
							 | 
						||
| 
								 | 
							
								* @brief 		SDIO controller interrupt handler
							 | 
						||
| 
								 | 
							
								* @param[in]	None
							 | 
						||
| 
								 | 
							
								* @return 		None
							 | 
						||
| 
								 | 
							
								**********************************************************************/
							 | 
						||
| 
								 | 
							
								void SDIO_IRQHandler(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /* All SD based register handling is done in the callback
							 | 
						||
| 
								 | 
							
									   function. The SDIO interrupt is not enabled as part of this
							 | 
						||
| 
								 | 
							
									   driver and needs to be enabled/disabled in the callbacks or
							 | 
						||
| 
								 | 
							
									   application as needed. This is to allow flexibility with IRQ
							 | 
						||
| 
								 | 
							
									   handling for applicaitons and RTOSes. */
							 | 
						||
| 
								 | 
							
								    sdif_dev.irq_cb(LPC_SDMMC->RINTSTS);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @}
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* _SDIF */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @}
							 | 
						||
| 
								 | 
							
								 */
							 |