📄 mmcoem.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*****************************************************************************
* FileName: MMCOEM.C
*
* SanDisk Host Developer's Toolkit
*
* Copyright (c) 1997 - 2000 SanDisk Corporation
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*
* Description:
*
* MMC platform specific routines.
*
******************************************************************************/
#include "sdapi.h"
#if (USE_MMC || USE_MMC_EMULATION)
#define DATA_TOKEN 0xFE
#if (WORD_ACCESS_ONLY)
#define DUMMY_DATA 0xFFFF
#else
#define DUMMY_DATA 0xFF
#endif
#if (WORD_ACCESS_ONLY)
#define DUMMY_DATA 0xFFFF
#define BUS_SIZE 16
#else
#define DUMMY_DATA 0xFF
#define BUS_SIZE 8
#endif
SDLOCAL MMC_CC MMCExchangeData(UCHAR odata, UCHAR *idata);
#if (USE_MMC)
#if (USE_MEMMODE) /* Memory mapped mode */
INT16 driveSave = 0;
/****************************************************************************
* Name: mmc_hw_init - Initialize MMC hardware
*
* Description:
*
* Input:
* controller_no Controller number
*
* Output:
* None
*
* Return:
* None
*
* Function: MMC controller intialization
*
****************************************************************************/
SDVOID mmc_hw_init(INT16 controllerno) /*__fn__*/
{
FPTR32 portIO;
/* Check for MMC controller */
if ( controllerno )
{
/* Second MMC controller */
portIO = (FPTR32)PERIPHERAL_BASE;
}
else
{
/* First MMC controller */
portIO = (FPTR32)PERIPHERAL_BASE;
}
/* Enable clock in OPEN-DRAIN mode */
MMCClockEnable();
/* Enable MMC controller */
SDWRITE_DATA32((portIO+MMCCT), MMCCT_EN);
/* Disable MMC interrupts */
SDWRITE_DATA32((portIO+MMCIM), 0L);
}
#else /* I/O mode */
#include <stdio.h>
#include "plx9054.h"
#define SSTOP_TRANSMISSION 0x4C
UINT32 portAddress = 0;
INT16 driveSave = 0;
/************************************************************************/
/* PCI Internal variables */
/************************************************************************/
SDLOCAL INT16 noController = 0;
SDLOCAL ADAPTER myAdapters[N_CONTROLLERS];
/* Function prototypes */
SDBOOL mmcAdapterInfo(INT16 controller, UINT32 *pPort, INT16 *pIntr);
/**************************** MMC Controller ********************************/
/****************************************************************************/
SDVOID MMCSelectController(INT16 ctrlNo, INT16 phys_drive)
{
UINT32 mmcPort;
INT16 mmcIntr;
driveSave = phys_drive;
/* Get the IO base */
if ( !mmcAdapterInfo(ctrlNo, &mmcPort, &mmcIntr) )
{
portAddress = 0;
return;
}
portAddress = mmcPort;
}
/****************************************************************************
* Name: mmc_hw_init - Initialize MMC hardware
*
* Description:
* MMC controller intialization
*
* Input:
* controller_no Controller number
*
* Output:
* None
*
* Return:
* None
*
****************************************************************************/
SDVOID mmc_hw_init(INT16 ctrlno) /*__fn__*/
{
INT16 portIntr;
/* Get the IO base */
if ( !mmcAdapterInfo(ctrlno, &portAddress, &portIntr) )
{
portAddress = 0L;
}
return;
}
/**************************************************************************
* Name: stopMMCClock - Stop the MMC Host controller clock
*
* Description:
* The clocks of the MMC Host controller is stopped.
*
* Input:
* portAddress Controller base address
*
* Output:
* Stopping the MMC Host clock.
*
* Return:
* None
*
**************************************************************************/
SDBOOL stopMMCClock(SDVOID)
{
UINT16 dTime;
UINT16 dStatus;
/* Disable MMC clock. */
SDWRITE_DATA16((portAddress+STR_STP_CLK_REG), STOP_CLOCK);
dTime = 0x200;
dStatus = 0;
/* Check status register */
while ( dTime )
{
dStatus = SDREAD_DATA16(portAddress+STATUS_REG);
dTime--;
if ( dStatus & CLOCK_DISABLE )
return YES;
}
return NO;
}
/**************************************************************************
* Name: startMMCClock - Start the MMC Host Controller clock
*
* Description:
* The MMC clock is started by the.
*
* Input:
* portAddress Controller bas address
*
* Output:
* Starting the clock.
*
* Return:
* None
*
**************************************************************************/
SDVOID startMMCClock(SDVOID)
{
/* Start the MMC clock. */
SDWRITE_DATA16((portAddress+STR_STP_CLK_REG), START_CLOCK);
}
/**************************************************************************
* Name: setMMCClockRate - Set the MMC clock rate
*
* Description:
* Stop the MMC clock and set the new clock rate
* then start the clock again.
*
* Input:
* ClockRate Clock rate
*
* Output:
* Set new clock rate.
*
* Return:
* YES if successful
* NO if failure
*
**************************************************************************/
SDBOOL setMMCClockRate(UINT16 ClockRate)
{
/* The clock needs to be stopped if currently active */
if ( !stopMMCClock() ) /* STOP MMC CLOCK */
return NO;
/* Set the clock rate */
SDWRITE_DATA16((portAddress+CLK_RATE_REG), ClockRate);
SDWRITE_DATA16((portAddress+RESPONSE_TOUT_REG), 0xFFFF);
SDWRITE_DATA16((portAddress+READ_TOUT_REG), 0xFFFF);
/* Start the clock again */
startMMCClock(); /* START MMC CLOCK */
return YES;
}
/**************************************************************************
* Name: startMMC80Clocks - Start the MMC devices
*
* Description:
* The 80 clocks is required to start initializing the
* devices.
*
* Input:
* ctrlNo Controller number
*
* Output:
* Sending out 80 clocks.
*
* Return:
* None
*
**************************************************************************/
SDVOID startMMC80Clocks(INT16 ctrlNo)
{
UINT16 ij, dStatus;
ij = (UINT16)ctrlNo; /* Make compiler happy! */
/* Send the 80 clocks to start all devices */
SDWRITE_DATA16((portAddress+CMD_DAT_CONT_REG), SEND_80_CLOCKS);
for (ij = 0; ij < 0x200; ij++ )
{
dStatus = SDREAD_DATA16(portAddress+STATUS_REG);
if ( dStatus & END_CMD_RES )
{
break;
}
}
/* Ramp-up time */
OS_WAIT(55);
}
/**************************************************************************
* Name: resetMMCController - Reset MMC host controller
*
* Description:
* Writing to the port with any value will reset the
* MMC Host controller
*
* Input:
* ctrlNo Controller number
*
* Output:
* Reset the controller
*
* Return:
* None
*
**************************************************************************/
SDVOID resetMMCController(UINT16 ctrlNo)
{
UINT16 dRev;
MMCSelectController(ctrlNo, 0);
/* Get the current information. */
dRev = SDREAD_DATA16(portAddress+REVISION_REG);
/* Reset the MMC controller. */
SDWRITE_DATA16((portAddress+REVISION_REG), dRev);
/* Give it some times for hardware to settle down */
dRev = 0x200;
while (dRev)
{
dRev--;
}
}
/**************************************************************************
* Name: setupMMCSetupInterrupt - Enable MMC interrupt setting
*
* Description:
*
* Input:
* bitMask set the bis to 1's which need to be enabled
*
* Output:
*
* Return:
*
* Function: mmc interrupt enable subroutine
*
*************************************************************************/
SDVOID SetupMMCInterrupt(UINT16 bitMask)
{
UINT16 dtmp;
/* Set interrupt mask value */
dtmp = SDREAD_DATA16(portAddress+INT_MASK_REG);
#if (USE_INTERRUPTS)
dtmp &= 0x0F;
dtmp |= bitMask;
#else
dtmp = bitMask;
dtmp &= 0;
#endif
SDWRITE_DATA16((portAddress+INT_MASK_REG), dtmp);
}
/**************************************************************************
* Name: disableMMCInterrupt - Disable MMC interrupt setting
*
* Description:
*
* Input:
* unMaskBit set the bis to 1's which need to be disabled
*
* Output:
*
* Return:
*
* Function: mmc interrupt disable subroutine
**************************************************************************/
SDVOID disableMMCInterrupt(UINT16 unMaskBit)
{
UINT16 dtmp;
/* Get Interrupt Mask value */
dtmp = SDREAD_DATA16(portAddress+INT_MASK_REG);
/* Mask off unwanted interrupts. */
dtmp &= (~unMaskBit);
SDWRITE_DATA16(portAddress+INT_MASK_REG, dtmp);
}
/*********************** MMC command and response ***************************/
/****************************************************************************/
/***************************************************************************
* Name: MMCSendCommand
*
* Description:
*
* Input:
* portAddress Base Address
* cmd Command index
* arg Argument
*
* Output:
* 6-byte command is sent to the card
*
* Return:
* Complete code
*
* Function: send the command to MMC card. CRC is not needed for
* the FPGA controller.
*
***************************************************************************/
SDVOID MMCSendCommand( UINT32 Arg, UINT16 Cmd, UINT16 crcDATA)
{
UINT16 dtmp;
dtmp = (UINT16)crcDATA;
/* Set up the argument. */
dtmp = (UINT16)(Arg >> 16);
SDWRITE_DATA16((portAddress+ARGUMENT_HI_REG), dtmp);
dtmp = (UINT16)(Arg & 0xFFFF);
SDWRITE_DATA16((portAddress+ARGUMENT_LO_REG), dtmp);
/* Set up the command. */
dtmp = (Cmd & 0x7F);
SDWRITE_DATA16((portAddress+CMD_REG), dtmp);
}
/***************************************************************************
* Name: getMMCResponseInfo - Get the response from MMC card
*
* Description:
* Get the response from MMC card
*
* Input:
* RespBuff Response buffer
* RespLength Length of the response
*
* Output:
* Response information
*
* Return:
* MMC Error code
*
***************************************************************************/
MMC_CC getMMCResponseInfo(UCHAR *respBuff, UINT16 respLength, UINT16 respType)
{
UINT16 dtmp, dtimer;
UINT16 i;
i = respType; /* Make compiler happy! */
/* Timer count for an MMC response */
dtimer = 0x0FFF;
/* Clear the FIFO buffer */
dtmp = SDREAD_DATA16(portAddress+FIFO_RD_WR_REG);
while ( dtimer )
{
/* Read status and wait for proper response */
dtmp = SDREAD_DATA16(portAddress+STATUS_REG);
dtimer--;
/* Check for TIME OUT on response */
if ( dtmp & TIME_OUT_RESPONSE )
{
return MMC_CARD_IS_NOT_RESPONDING;
}
/* Check for CRC on response */
else if ( dtmp & RESP_CRC_ERR)
{
return (MMC_CMD_CRC_ERROR );
}
else if ( dtmp & CRC_WR_ERR )
{
return MMC_DATA_STATUS_CRC_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -