📄 xsmmc.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: XsMmc.c
**
** PURPOSE: A driver for the MMC controller.
**
** $Modtime: 12/17/03 1:57p $
**
******************************************************************************/
/*
*******************************************************************************
* HEADER FILES
*******************************************************************************
*/
#include <stdio.h>
#include "systypes.h"
#include "dm_errors.h"
#include "timedelays.h"
#include "XsClkMgr.h"
#include "boardcontrol.h"
#include "xllp_mmc.h"
#include "xllp_bcr.h"
#include "xllp_gpio.h"
#include "xllp_clkmgr.h"
#include "XsIntCtrlApi.h"
#include "mallocx.h"
#define XSMMC_GLOBALS 1
#include "MmcSd.h"
/*
*******************************************************************************
* LOCAL CONSTANTS
*******************************************************************************
*/
// MMC Controller registers base address
#define MMCBASETP ((XsMMCregsT *)0x41100000)
#define XS_GPIO_REGISTER_BASE 0x40E00000
/*
*******************************************************************************
* LOCAL DATA TYPES
*******************************************************************************
*/
typedef struct {
VUINT32 strpcl; // Control to start and stop MMC clock
VUINT32 stat; // MMC status register (read only)
VUINT32 clkrt; // MMC clock rate
VUINT32 spi; // SPI mode control bits
VUINT32 cmdat; // Command/response/data sequence control
VUINT32 resto; // Expected response time out
VUINT32 rdto; // Expected data read time out
VUINT32 blklen; // Block length of data transaction
VUINT32 nob; // Number of blocks, for block mode
VUINT32 prtbuf; // Partial MMC_TXFIFO FIFO written
VUINT32 imask; // Interrupt Mask
VUINT32 ireg; // Interrupt Register (read only)
VUINT32 cmd; // Index of current command
VUINT32 argh; // MSW part of the current command argument
VUINT32 argl; // LSW part of the current command argument
VUINT32 res; // Response FIFO (read only)
VUINT32 rxfifo; // Receive FIFO (read only)
VUINT32 txfifo; // Transmit FIFO (write only)
VUINT32 RESERVED1[50]; /* reserved for different fifo */
VUINT32 SD_CMDAT; /* SD CMDAT register */
VUINT32 RESERVED2[11]; /* reserved for different fifo */
VUINT32 fb_rxfifo; /* receive fifo for 1,2 or 4 bytes */
VUINT32 fb_txfifo; /* transmit fifo for 1,2 or 4 bytes */
} XsMMCregsT;
/*
*******************************************************************************
* LOCAL VARIABLES
*******************************************************************************
*/
XsMMCregsT * regs;
UINT16 rxRead, txWritten;
UINT32 *putBuf, *getBuf;
P_XLLP_CLKMGR_T ClckReg;
P_XLLP_BCR_T BcrReg;
P_XLLP_GPIO_T GpioReg;
P_XLLP_MMC_T MmcReg;
UINT32 pState=0;
UINT32 lState=0;
UINT32 dState=0;
UINT32 sState=0;
UINT32 expectedInterrupt=0;
XLLP_BOOL_T powerUp = XLLP_FALSE;
/*
*******************************************************************************
*
* FUNCTION: XsMMCSWInit
*
* DESCRIPTION: Init the MMC driver internal variables.
*
* INPUT PARAMETERS: None.
*
* RETURNS: Nothing.
*
* GLOBAL EFFECTS: None.
*
* ASSUMPTIONS: None.
*
* CALLS: None.
*
* CALLED BY: System.
*
* PROTOTYPE: void XsMMCSWInit(void)
*
*******************************************************************************
*/
void displayCSDInfo(SDCSD *sd_csd){
printf("\t\tTMP_WRITE_PROTECT:\t%x\r\n",sd_csd->TMP_WRITE_PROTECT );
printf("\t\tPERM_WRITE_PROTECT:\t%x\r\n",sd_csd->PERM_WRITE_PROTECT );
printf("\t\tCOPY:\t\t\t%x\r\n",sd_csd->COPY );
printf("\t\tCOPY_FORMAT_GROUP:\t%x\r\n",sd_csd->FILE_FORMAT_GRP );
printf("\t\tWRITE_BL_PARTIAL:\t%x\r\n",sd_csd->WRITE_BL_PARTIAL );
printf("\t\tWRITE_BL_LEN:\t\t%x\r\n",sd_csd->WRITE_BL_LEN);
printf("\t\tR2W_FACTOR:\t %x\r\n",sd_csd->R2W_FACTOR );
printf("\t\tWP_GRP_ENABLE:\t\t%x\r\n",sd_csd->WP_GRP_ENABLE );
printf("\t\tWP_GRP_SIZE:\t\t%x\r\n",sd_csd->WP_GRP_SIZE );
printf("\t\tSECTOR_SIZE:\t\t%x\r\n",sd_csd->SECTOR_SIZE );
printf("\t\tERASE_BLK_EN:\t\t%x\r\n",sd_csd->ERASE_BLK_EN );
printf("\t\tC_SIZE_MULT:\t\t%x\r\n",sd_csd->C_SIZE_MULT );
printf("\t\tVDD_W_CURR_MAX:\t\t%x\r\n",sd_csd->VDD_W_CURR_MAX );
printf("\t\tVDD_W_CURR_MIN:\t\t%x\r\n",sd_csd->VDD_W_CURR_MIN );
printf("\t\tVDD_R_CURR_MAX:\t\t%x\r\n",sd_csd->VDD_R_CURR_MAX);
printf("\t\tVDD_R_CURR_MIN:\t\t%x\r\n",sd_csd->VDD_R_CURR_MIN );
printf("\t\tC_SIZE:\t\t\t%x\r\n",sd_csd->C_SIZE );
printf("\t\tC_SIZEx:\t\t%x\r\n",sd_csd->C_SIZEx );
printf("\t\tDSR_IMP:\t\t%x\r\n",sd_csd->DSR_IMP );
printf("\t\tREAD_BLK_MISALIGN:\t%x\r\n",sd_csd->READ_BLK_MISALIGN );
printf("\t\tWRITE_BLK_MISALIGN:\t%x\r\n",sd_csd->WRITE_BLK_MISALIGN );
printf("\t\tREAD_BL_PARTIAL:\t%x\r\n",sd_csd->READ_BL_PARTIAL );
printf("\t\tREAD_BL_LEN:\t\t%x\r\n",sd_csd->READ_BL_LEN );
printf("\t\tCCC:\t\t\t%x\r\n",sd_csd->CCC );
printf("\t\tTRAN_SPEED:\t\t%x\r\n",sd_csd->TRAN_SPEED );
printf("\t\tNSAC:\t\t\t%x\r\n",sd_csd->NSAC );
printf("\t\tTAAC:\t\t\t%x\r\n",sd_csd->TAAC );
printf("\t\tCSD_STRUCTURE:\t\t%x\r\n",sd_csd->CSD_STRUCTURE );
}
void displayCIDinfo(SDCID *sd_cid )
{
printf("\t\tMDT:\t\t\t%x\r\n",sd_cid->MDT );
printf("\t\tPSN:\t\t\t%x\r\n",sd_cid->PSN );
printf("\t\tPSNx:\t\t\t%x\r\n",sd_cid->PSNx );
printf("\t\tPRV:\t\t\t%x\r\n",sd_cid->PRV );
printf("\t\tPNM:\t\t\t%x\r\n",sd_cid->PNM );
printf("\t\tPNMx:\t\t\t%x\r\n",sd_cid->PNMx );
printf("\t\tOID:\t\t\t%x\r\n",sd_cid->OID );
printf("\t\tMID:\t\t\t%x\r\n",sd_cid->MID );
}
void rxFifoFullInt(void) {
UINT16 y;
// volatile unsigned int *pHexDisp= (volatile unsigned int *) 0x41100140;
//printf("+rxFifoFullInt\r\n");
for (y=0; y<8; y++)
{
getBuf[rxRead++] = MmcReg->MB_RXFIFO;
// tempBuf[rxRead++] = regs->rxfifo;
// printf("getBuf %x\r\n",getBuf[rxRead-1]);
}
// if (regs->stat & XLLP_STAT_DATATRANDONE) regs->imask |= XLLP_MMC_I_MASK_RXFIFORDREQ;
}
void txFifoEmptyInt(void) {
UINT16 y;
// MmcReg = (P_XLLP_MMC_T)0x41100000;
// volatile unsigned int *pHexDisp= (volatile unsigned int *) 0x41100144;
//printf("+txFifoEmptyInt \r\n");
for (y=0; y<8; y++)
{
MmcReg->MB_TXFIFO = putBuf[txWritten++];
// printf("putBuf %x\r\n", putBuf[txWritten-1]);
}
// if (regs->stat & XLLP_STAT_DATATRANDONE) regs->imask |= XLLP_MMC_I_MASK_TXFIFOWRREQ;
}
void mmcInterruptServiceRoutine(void)
{
// UINT32 state;
//printf("ISR: I_REG %x(STAT %x), expected Interrupt(%x)\r\n", MmcReg->MMC_I_REG, MmcReg->MMC_STAT,(~MmcReg->MMC_I_MASK & 0xff));
if ( (MmcReg->MMC_I_REG & 0x1fff) & (~MmcReg->MMC_I_MASK & 0x1fff) )
{
if((MmcReg->MMC_I_REG & XLLP_MMC_I_REG_RXFIFORDREQ) == XLLP_MMC_I_REG_RXFIFORDREQ)
// if(MmcReg->MMC_I_REG == XLLP_MMC_I_REG_RXFIFORDREQ)
{
//printf("+RXFifoEmptyInt \r\n");
rxFifoFullInt();
// if (rxRead == MMCSTK.BSIZE)
// XsMMCFollowupRead();
}
else
if((MmcReg->MMC_I_REG & XLLP_MMC_I_REG_TXFIFOWRREQ) == XLLP_MMC_I_REG_TXFIFOWRREQ)
// if(MmcReg->MMC_I_REG == XLLP_MMC_I_REG_TXFIFOWRREQ)
{
//printf("+TXFifoEmptyInt \r\n");
txFifoEmptyInt();
// if (rxRead == MMCSTK.BSIZE)
// XsMMCFollowupRead();
}
else
MmcReg->MMC_I_MASK = 0x1fff;
//printf("ISR: MMC_I_MASK %x\r\n", MmcReg->MMC_I_MASK);
}
}
void XsMMCSWInit(void)
{
regs = MMCBASETP;
MmcReg = (P_XLLP_MMC_T)0x41100000;
ClckReg = (P_XLLP_CLKMGR_T)CKEN_REGISTER_BASE;
BcrReg = (P_XLLP_BCR_T)BOARD_REG_BASE;
GpioReg = (P_XLLP_GPIO_T)XS_GPIO_REGISTER_BASE;
}
UINT32 parseResponse( UINT16 * response, BOOL wrap)
{
UINT32 tempResponse=0;
// printf("Response2 %x\r\n",response[2]);
// printf("Response1 %x\r\n",response[1]);
// printf("Response0 %x\r\n",response[0]);
if(wrap)
tempResponse = ((((UINT32)response[2] & 0xff)<< 24) |
((UINT32)response[1] << 8) | (response[0] & 0xff00) >> 8 );
else
tempResponse = ((((UINT32)response[1] & 0xff)<< 24) |
((UINT32)response[0] << 8) | (response[2] & 0xff00) >> 8 );
//("tempResponse %x\r\n",tempResponse);
return(tempResponse);
}
UINT32 checkStatus(P_XLLP_MMC_T mmcReg, UINT32 response)
{
UINT32 StatusReceived=0;
//putting it in the 32 bit register format from card
//printf("Resp %x\r\n", response);
// tempStatus = parseResponse(response);
// StatusReceived |= ( ((tempStatus >> 9) & 0xf )<<28);
StatusReceived |= ( (response & MMCSD_CARD_STATUS_CS)<<19);
if(mmcReg->MMC_STAT & XLLP_STAT_TORD)
StatusReceived |= MMCSD_STAT_TOR;
if(mmcReg->MMC_STAT & XLLP_STAT_TORSPNS)
StatusReceived |= MMCSD_STAT_TORSPN;
if(mmcReg->MMC_STAT & XLLP_STAT_CRCWRERR)
StatusReceived |= MMCSD_STAT_CRCWRER;
if(mmcReg->MMC_STAT & XLLP_STAT_CRCRDERR)
StatusReceived |= MMCSD_STAT_CRCRDERR;
if(mmcReg->MMC_STAT & XLLP_STAT_DATAERRTKN)
StatusReceived |= MMCSD_STAT_DATAERRTKN;
if(mmcReg->MMC_STAT & XLLP_STAT_FLASHERR)
StatusReceived |= MMCSD_STAT_FLASHERR;
if(response & MMCSD_CARD_STATUS_OOR)
StatusReceived |= MMCSD_STAT_OUT_OF_RANGE;
if(response & MMCSD_CARD_STATUS_AE)
StatusReceived |= MMCSD_STAT_ADDRESS_ERR;
if(response & MMCSD_CARD_STATUS_EP )
StatusReceived |= MMCSD_STAT_ERASE_PARAM;
if(response & MMCSD_CARD_STATUS_WPV)
StatusReceived |= MMCSD_CARD_STATUS_WPV;
if(response & MMCSD_CARD_STATUS_CL)
StatusReceived |= MMCSD_STAT_CARD_LOCKED;
if(response & MMCSD_CARD_STATUS_ERR)
StatusReceived |= MMCSD_STAT_ADDRESS_ERR;
// printf("Status Received %x- response %x\r\n", StatusReceived, response);
return(StatusReceived);
}
STATRES mmcProcessCmd(P_XLLP_MMC_T mmcReg, mmcStack *MMC)
{
// int i=0;
STATRES statusRes;
UINT16 res[8];
// UINT32 status[4];
//printf("+mmcProcessCmd\r\n");
//StopClk:
//printf("+StopClk\r\n");
// XllpMmcSdInts(mmcReg,XLLP_MMC_I_MASK_CLKISOFF);
// mmcReg->MMC_STRPCL = XLLP_STRPCL_STPCLK; // Stop the MMC clock
// osStatus = OSAFlagWait(_keypadFlagRef, KEYPAD_FLAG_MASK, OSA_FLAG_OR_CLEAR, &keypadFlags, OSA_SUSPEND);
// ASSERT(osStatus == OS_SUCCESS);
// while (MmcReg->MMC_STAT & XLLP_STAT_CLKEN); // Wait for the clock to stop
goto SetupCommand;
SetupCommand:
//printf("+SetupCommand\r\n");
XllpMmcSdInts(mmcReg,XLLP_MMC_I_MASK_ENDCMDRES);
if (MMC->DATATRANS)
{
// XllpMmcSdSetupCmd(MmcReg, MMC->CMD, MMC->ADDR, 64,0);
goto ExpectedDataTrans;
}else
{
XllpMmcSdSetupCmd(MmcReg, MMC->CMD, MMC->ADDR, 64,0, XLLP_FALSE);
// osStatus = OSAFlagWait(_keypadFlagRef, KEYPAD_FLAG_MASK, OSA_FLAG_OR_CLEAR, &keypadFlags, OSA_SUSPEND);
// ASSERT(osStatus == OS_SUCCESS);
while (!(MmcReg->MMC_STAT & XLLP_STAT_ENDCMDRES));
// printf("MmcReg->MMC_STAT %x\r\n", MmcReg->MMC_STAT);
if(mmcReg->MMC_CMDAT & XLLP_MMC_CMDAT_RESTYPE)
goto ExtractResponse;
else
goto end;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -