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

📄 mmctest.c

📁 有关于USB的一些主机端驱动
💻 C
字号:

#include "mmc_base.h"

#define MMCTX	1
#define MMCRX	2

static struct MMC_Card *card;


unsigned long mmc_total_size = 0;

void MMC_config (struct MMC_Cfg *cfg) //czm
{
	Uint16 resetMask = 0xF7FF;

	// Perform Initialization 
	// Place controller in reset before changing other values resetie: make the pwr down
	MMC_RSET_H (MMC_REG_CON, MMC_MMCCON_DEFAULT);

	// enable callback functions based on the MMCIE value
	MMC_RSET_H (MMC_REG_CMD, cfg->mmccmd);
	MMC_RSET_H (MMC_REG_IE, cfg->mmcie);
	MMC_RSET_H (MMC_REG_CTO, cfg->mmccto);
	MMC_RSET_H (MMC_REG_DTO, cfg->mmcdto);
	MMC_RSET_H (MMC_REG_BLEN, cfg->mmcblen);
	MMC_RSET_H (MMC_REG_NBLK, cfg->mmcnblk);
	MMC_RSET_H (MMC_REG_BUF, cfg->mmcbuf);
	MMC_RSET_H (MMC_REG_CON, (cfg->mmccon & resetMask));
	MMC_RSET_H (MMC_REG_CON, (cfg->mmccon | 0x0800));	// Take MMC out of reset //
	MMC_RSET_H (MMC_REG_SDIO, 0x2000);	// Take MMC out of reset //
};

Uint16
MMC_waitForFlag (Uint16 mask)
{
	Uint16 done = 0;
	Uint16 status;

	do
	  {
		  status = MMC_RGET_H (MMC_REG_STAT);
		  if ((status & mask) != 0)
			  done = 1;
	  }
	while (done == 0);

	return done;

}

Uint16
MMC_sendCmd (Uint16 cmd, Uint16 argh, Uint16 argl, Uint16 waitForRsp)
{


	//clear the MMCSTAT register of its previous value
	MMC_RSET_H (MMC_REG_STAT, 0xFFFF);

	// Format and send command
	MMC_RSET_H (MMC_REG_ARGH, argh);
	MMC_RSET_H (MMC_REG_ARGL, argl);
	MMC_RSET_H (MMC_REG_CMD, cmd);

	// Wait for response done
	if (waitForRsp)
	  {
		  MMC_waitForFlag (MMC_MMCSTAT_EOC | MMC_MMCSTAT_CMD_TO);
		  if (((MMC_RGET_H (MMC_REG_STAT)) & MMC_MMCSTAT_CMD_TO) != 0)
			  return 0;	// command time-out
	  }

	return 1;
}

void
MMC_sendGoIdle (void)
{
	//send the initializing sequence to card
	MMC_RSET_H (MMC_REG_CMD, MMC_RGET_H (MMC_REG_CMD) | MMC_INIT);
	//clear the controller status register
	MMC_RSET_H (MMC_REG_STAT, 0xFFFF);
}

Uint16
MMC_sendOpCond (Uint32 hVddMask)
{
	Uint16 bootup = 0;
    
	do{
	if (card->cardtype == CARD_TYPE_SD) {
		MMC_sendCmd (SD_APP_CMD, MMC_STUFF_BITS, MMC_STUFF_BITS, 1);	//0x2137
		MMC_sendCmd (MMC_SEND_OP_COND, (Uint16) ((hVddMask >> 16) & 0xFFFFu), ((Uint16) (hVddMask & 0xFFFFu)), 1);	//0x1329
		}

    if (card->cardtype == CARD_TYPE_MMC)
	    MMC_sendCmd (MMC_SEND_OP_COND,(Uint16) ((hVddMask >> 16) & 0xFFFFu),((Uint16) (hVddMask & 0xFFFFu)), 1);


		  bootup = MMC_RGET_H (MMC_REG_RSP7);
		  bootup = bootup >> 15;
		  bootup &= 1;
	  }
	while (bootup == 0);

	return 1;

}

void
MMC_getResponse (Uint16 * regs)
{
	// Set all response registers //
	regs[0] = MMC_RGET_H (MMC_REG_RSP0);
	regs[1] = MMC_RGET_H (MMC_REG_RSP1);
	regs[2] = MMC_RGET_H (MMC_REG_RSP2);
	regs[3] = MMC_RGET_H (MMC_REG_RSP3);
	regs[4] = MMC_RGET_H (MMC_REG_RSP4);
	regs[5] = MMC_RGET_H (MMC_REG_RSP5);
	regs[6] = MMC_RGET_H (MMC_REG_RSP6);
	regs[7] = MMC_RGET_H (MMC_REG_RSP7);

}

void
MMC_getCID (struct MMC_CardId *cid)
{
	Uint16 regs[8];

	MMC_getResponse (regs);

	//CRC
	cid->CRC = regs[0] & 0xFE;	//7:1

	//MDT fields
	cid->yearCode = (regs[0] >> 8) & 0xF;	// 11:8
	cid->monthCode = (regs[0] >> 12) & 0xF;	// 12:15
	//cid->dayCode         =  regs[1] & 0xF;//19:16

	//PSN
	cid->MMCv3uniqueID = (Uint32) ((regs[2] << 16) | regs[1]);	//47:16
	cid->SDuniqueID = (Uint32) (((regs[3] & 0xFF) << 16) | ((regs[2] << 8) & 0xFFFF) | ((regs[1] >> 8) & 0xFF));	//55:24

	cid->serialNumber[3] = regs[1] & 0xFF;
	cid->serialNumber[2] = (regs[1] >> 8) & 0xFF;
	cid->serialNumber[1] = regs[2] & 0xFF;
	cid->serialNumber[0] = (regs[2] >> 8) & 0xFF;

	//PRV
	cid->fwRev = regs[3] & 0xF;	// 51:48
	cid->hwRev = (regs[3] >> 4) & 0xF;	// 55:52

	//PNM 103:56
	cid->productName[5] = ((regs[3]) >> 8) & 0xFF;
	cid->productName[4] = ((regs[4]) & 0xFF);
	cid->productName[3] = ((regs[4]) >> 8) & 0xFF;
	cid->productName[2] = ((regs[5]) & 0xFF);
	cid->productName[1] = ((regs[5]) >> 8) & 0xFF;
	cid->productName[0] = ((regs[6]) & 0xFF);


	//OID 119:104
	cid->AppID = ((regs[7] & 0xFF) << 8) | ((regs[6] >> 8) & 0xFF);	//119:104;

	//MID
	cid->mfgId = (regs[7] >> 8) & 0xFF;

};

void
MMC_getCSD (struct MMC_CardCsd *csd)
{
	Uint16 lo;
	Uint16 regs[8];

	MMC_getResponse (regs);

	csd->crc = regs[0] & 0xFE;	//7:1
	//csd->ecc              = (regs[0] >>  8  ) & 3;         // 9:8
	csd->tmpWriteProtect = (regs[0] >> 12) & 1;	// 12
	csd->permWriteProtect = (regs[0] >> 13) & 1;	// 13
	csd->copy = (regs[0] >> 14) & 1;	// 14

	csd->writeBlPartial = (regs[1] >> 5) & 1;	// 21
	csd->writeBlLen = (regs[1] >> 6) & 0xF;	// 25:22
	csd->r2wFactor = (regs[1] >> 10) & 0x7;	// 28:26
	csd->defaultEcc = (regs[1] >> 13) & 0x3;	// 30:29
	csd->wpGrpEnable = (regs[1] >> 15) & 1;	// 31

	csd->wpGrpSize = (regs[2] & 0x1F);	// 36:32
	csd->eraseGrpMult = (regs[2] >> 5) & 0x1f;	// 41:37
	csd->eraseGrpSize = (regs[2] >> 10) & 0x1f;	// 46:42
	lo = (regs[2] >> 15) & 1;	// 49:47
	csd->cSizeMult = ((regs[3] & 3) << 1) | lo;

	csd->vddWCurrMax = (regs[3] >> 2) & 0x7;	// 52:50
	csd->vddWCurrMin = (regs[3] >> 5) & 0x7;	// 55:53
	csd->vddRCurrMax = (regs[3] >> 8) & 0x7;	// 58:56
	csd->vddRCurrMin = (regs[3] >> 11) & 0x7;	// 61:59
	lo = (regs[3] >> 14) & 0x3;	// 73:62
	csd->cSize = ((regs[4] & 0x3FF) << 2) | lo;

	mmc_total_size = (1+csd->cSize)*(1 << (csd->cSizeMult+2))*512;	

	csd->dsrImp = (regs[4] >> 12) & 1;	// 76
	csd->readBlkMisalign = (regs[4] >> 13) & 1;	// 77
	csd->writeBlkMisalign = (regs[4] >> 14) & 1;	// 78
	csd->readBlPartial = (regs[4] >> 15) & 1;	// 79
	csd->readBlLen = (regs[5]) & 0xf;	// 83:80
	csd->ccc = (regs[5] >> 4) & 0xfff;	// 95:84
	csd->tranSpeed = (regs[6]) & 0xff;	// 103:96
	csd->nsac = (regs[6] >> 8) & 0xff;	// 111:104

	csd->taac = (regs[7]) & 0xff;	// 119:112
	csd->mmcProt = (regs[7] >> 10) & 0xf;	// 125:122
	csd->csdStructure = (regs[7] >> 14) & 0x3;	// 127:126


	// extra fields for SD card,make no sense for MMC card
	csd->eraseBlkLen = (regs[2] >> 14) & 0x1;	//46
	csd->eraseSectorSize = (regs[2] >> 7) & 0x7F;	//39:45
};

void
SD_getCID (struct MMC_CardId *cid)
{
	Uint16 regs[8];

	MMC_getResponse (regs);

	cid->CRC = regs[0] & 0xFE;	//7:1

	//MDT fields
	cid->yearCode = (regs[0] >> 8) & 0xF;	// 11:8
	cid->monthCode = (regs[0] >> 12) & 0xF;	// 15:12
	cid->dayCode = regs[1] & 0xF;	//19:16
	//reserved         = //23:20

	//PSN
	cid->serialNumber[3] = (regs[1] >> 8) & 0xFF;
	cid->serialNumber[2] = regs[2] & 0xFF;
	cid->serialNumber[1] = (regs[2] >> 8) & 0xFF;
	cid->serialNumber[0] = regs[3] & 0xFF;

	//PRV
	cid->fwRev = (regs[3] >> 8) & 0xF;	// 59:56
	cid->hwRev = (regs[3] >> 12) & 0xF;	// 63:60

	//PNM 103:64
	cid->productName[5] = ((regs[4]) & 0xFF);
	cid->productName[4] = ((regs[4]) >> 8) & 0xFF;
	cid->productName[3] = ((regs[5]) & 0xFF);
	cid->productName[2] = ((regs[5]) >> 8) & 0xFF;
	cid->productName[1] = ((regs[6]) & 0xFF);
	cid->productName[0] = '0';

	//OID
	cid->AppID = ((regs[7] & 0xFF) << 8) | ((regs[6] >> 8) & 0xFF);	//119:104;

	//MID
	cid->mfgId = (regs[7] >> 8) & 0xFF;
};

Uint16
MMC_initNative (void)
{
	volatile int j;
	Uint32 RCA = 4;

	MMC_RSET_H (MMC_REG_STAT, 0xFFFF);	//clear controller status register
	MMC_RSET_H (MMC_REG_CMD, 0x10);	//send  the card init sequence
	for (j = 0; j < 2000; j++);	//Gsyal investegate the optimal time for waits
	//OCR validation
	MMC_sendOpCond (0x000f0000);	//0x007FC000);
	for (j = 0; j < 2000; j++);	//Gsyal investegate the optimal time for waits
	//CID
	MMC_sendCmd (MMC_ALL_SEND_CID, MMC_STUFF_BITS, MMC_STUFF_BITS, 1);	//cid0x1242
	MMC_getCID (&(card->cidptr));
	//RCA
	MMC_sendCmd (MMC_SET_RELATIVE_ADDR, (RCA & 0xFFFF), MMC_STUFF_BITS, 0);	//rca0x2143
	card->cardRCA = RCA;
	//CSD
	MMC_sendCmd (MMC_SEND_CSD, (RCA & 0xFFFF), MMC_STUFF_BITS, 1);	//csd0x2209
	for (j = 0; j < 8000; j++);	//Gsyal investegate the optimal time for waits
	MMC_getCSD (&(card->csdptr));
	//select card
	MMC_sendCmd (MMC_SELECT_CARD, (RCA & 0xFFFF), MMC_STUFF_BITS, 1);	//select card 0x2907

	return 1;

};

Uint16
SD_initNative (void)
{
    int j;
	//OCR
	MMC_sendOpCond (0x00ff8000);
	//CID
	MMC_sendCmd (SD_ALL_SEND_CID, MMC_STUFF_BITS, MMC_STUFF_BITS, 1);	// CMD2 R2 (0x1202)
    for (j = 0; j < 8000; j++);	//Gsyal investegate the optimal time for waits		
	SD_getCID (&(card->cidptr));
	//RCA
	MMC_sendCmd (SD_SEND_RELATIVE_ADDR, MMC_STUFF_BITS, MMC_STUFF_BITS, 1);	// CMD3 R6 (0x1603)
	card->cardRCA = MMC_RGET_H (MMC_REG_RSP7);
	//CSD
	MMC_sendCmd (MMC_SEND_CSD, card->cardRCA & 0xFFFF, MMC_STUFF_BITS, 1);	// CMD9 R2 (0x2209)
    for (j = 0; j < 8000; j++);	//Gsyal investegate the optimal time for waits	
	MMC_getCSD (&(card->csdptr));
	//select card
	MMC_sendCmd (MMC_SELECT_CARD, card->cardRCA & 0xFFFF, MMC_STUFF_BITS, 1);	// CMD7 R1b (0x2907)
	// Set Data Width
	MMC_sendCmd (SD_APP_CMD, card->cardRCA & 0xFFFF, MMC_STUFF_BITS, 1);	// CMD55 R1 (0x2137)

	// Now the Innovator DK don't support 4-bits bus width, wangjun, 2003-05-07
//      MMC_sendCmd (SD_SET_BUS_WIDTH, MMC_STUFF_BITS, 0x2, 1); // ACMD6 R1 (0x2106)
//      MMC_FSET_H (MMCCON, DBW, 1);    //set bus width to 4-bits in controller

	return 1;
};


void MMC_module_init (void)
{
	struct MMC_Cfg MyCfg;
	int i, j, temp;

	card =   (struct MMC_Card *) malloc (sizeof (struct MMC_Card));

	MyCfg.mmccmd = 0x0000;
	MyCfg.mmccon = MMCCON_CLK_400K | MMCCON_NATIVE | MMCCON_DW1;
	MyCfg.mmcie = 0x0;	//MMC_MMCIE_EOCIE |MMC_MMCIE_ENTR_BSYIE|MMC_MMCIE_BLK_RSIE
	//|MMC_MMCIE_EXT_BSYIE| MMC_MMCIE_DAT_TOIE |MMC_MMCIE_DATCRC_ERRIE |
	// MMC_MMCIE_CMD_TOIE |MMC_MMCIE_CMDCRC_ERRIE |MMC_MMCIE_BUF_AFIE
	// |MMC_MMCIE_BUF_AEIE| MMC_MMCIE_OCR_BSYIE;
	MyCfg.mmcdto = MMC_MMCDTO_DIS;
	MyCfg.mmccto = MMC_MMCCTO_MAX;
	MyCfg.mmcblen = MMC_BLEN_512;
	MyCfg.mmcnblk = MMC_MMCNBLK_ONE;

	MyCfg.mmcbuf = 0x1f00;	// AF_level 0x1F=32 16-bit word(64bytes) AE_level =0

	MMC_config (&MyCfg);

	MMC_sendGoIdle ();
	for (i = 0; i < 1000; i++)
		for (j = 0; j < 1000; j++)
		  {
			  if (temp == 200)
				  temp = 100;
		  }

	MMC_sendCmd (SD_APP_CMD, MMC_STUFF_BITS, MMC_STUFF_BITS, 1);	//ACMD 55  0x2137
	if ((MMC_RGET_H (MMC_REG_RSP6)) == 0x0120)
	  {			//SD Card is present
		  card->cardtype = CARD_TYPE_SD;
		  SD_initNative ();
	  }
	else
	  {			//MMC Card is present
		  card->cardtype = CARD_TYPE_MMC;
		  MMC_initNative ();
	  }



	/*transfer state */
	if (card->cardtype == CARD_TYPE_MMC)
	  {			//set the freq to 16Mhz
		  temp = MMC_RGET_H (MMC_REG_CON);
		  temp &= 0xFF00;
		  temp |= MMCCON_CLK_16M;
		  MMC_RSET_H (MMC_REG_CON, temp);
	  }
	else if (card->cardtype == CARD_TYPE_SD)
	  {			//set the freq to 24Mhz
		  temp = MMC_RGET_H (MMC_REG_CON);
		  temp &= 0xFF00;
		  temp |= MMCCON_CLK_24M;
		  MMC_RSET_H (MMC_REG_CON, temp);
	  }


	MMC_RSET_H (MMC_REG_NBLK, 0x0000);	// 1 blk (= single mode)
	MMC_RSET_H (MMC_REG_BLEN, (512 - 1));
	MMC_sendCmd (MMC_SET_BLOCKLEN, MMC_STUFF_BITS, (512), 0);	// CMD16 (SET_BLOCKLEN) R1

       printf("MMC: total size is %dM(read out by MMC command)\n",mmc_total_size/(1024*1024));
       return;
};


#define OMAP_MOD_CONF_CTRL_0		0xfffe1080	/* module configuration control 0 */
#define OMAP_PULL_DWN_CTRL_2		0xfffe1048	/* pulldown control 2 */
#define OMAP_VOLTAGE_CTRL_0		0xfffe1060	/* voltage control 0 */
void MMC_hw_init (void)
{
	(*(unsigned int *) (OMAP_VOLTAGE_CTRL_0)) = 0x0007;
	(*(unsigned int *) (OMAP_PULL_DWN_CTRL_2)) |= 0x0001F000;
	//The spec sheet says this bit is reserved, but this setting is used in WCSSOFT2 for requiring
	(*(unsigned int *) (OMAP_MOD_CONF_CTRL_0)) |= 0x00800000;
	//(*(unsigned int *) (OMAP_COMP_MODE_CTRL_0)) = 0x0000EAEF;

       *(volatile Uint32*)0xFFFE100C = 0x0000EAEF;   //1510 mode
	*(volatile Uint8*)0x08000005 |= 0x08; //MMC_EN
	*(volatile Uint8*)0x08000210 |= 0x22; //IMR2 mmc CD and ext_FPGA int enabled

}

void MMCtest(void)
{
	MMC_hw_init();
	MMC_module_init();
};

⌨️ 快捷键说明

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