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

📄 mmc.c

📁 三星公司的ARM44B0的SDC_MMC测试程序
💻 C
字号:
/************************************************************** * ARMSYS-P, LiYuTai elec. * * MMC Card functions ************************************************************/#include "mmc.h"/************************************************************* * MMC Init function * * - flushes card receive buffer * - selects card * - sends the reset command * - sends the initialization command, waits for card ready * - queries card status *************************************************************/int mmc_init(void){  unsigned char c,d;  unsigned int stat;  mcu_io_init_formmc();  mmc_deselect();  /* start off with 80 bits of high data with card deselected */  for(d=0;d<10;d++)    c = spi_byte(0xff);  mmc_select();        /* select card */    /* now send CMD0 - go to idle state, try up to 16 times */  d = 100;  while(c != 1 && d--)  {    mmc_command(0,0,0);  /* software reset command */    c = mmc_get_r1();    Delay(10);  }    if(c != 1)  {    Uart_Printf("MMC is not detected\n");    return(-1);  }  else Uart_Printf("MMC is detected\n");  /* send CMD1 until we get a 0 back, indicating card is done initializing */  d = 255;    /* but only do it up to 16 times */  c = 1;  while(c && d--)  {    mmc_command(1,0,0);    c = mmc_get_r1();    /*    Uart_Printf(PSTR("c = "));    putchar(c);    Uart_Printf(PSTR("\n"));    */    //Uart_Printf("c=%x\n", c);    Delay(10);  }    if(c)  {    Uart_Printf("     init failed\n");    return(-1);  }  else   	Uart_Printf("     card initialized.\n");    /* now we query the card status */  mmc_command(13,0,0);  stat = mmc_get_r2();  Uart_Printf("     card status: ");  if(stat)  {    Uart_Printf("ERROR\n");    return(-1);  }  else   	Uart_Printf("OK\n");  return 0;}/************************************************************ * MMC command  * * - send one byte of 0xff, then issue command + params + (fake) crc * - eat up the one command of nothing after the CRC ************************************************************/int mmc_command(unsigned char command, unsigned int px, unsigned int py){  mmc_select();  spi_byte(0xff);  spi_byte(command | 0x40);  spi_byte((unsigned char)((px >> 8)&0x0ff)); /* high byte of param x */  spi_byte((unsigned char)(px & 0x00ff));     /* low byte of param x */  spi_byte((unsigned char)((py >> 8)&0x0ff)); /* high byte of param y */  spi_byte((unsigned char)(py & 0x00ff));     /* low byte of param y */    spi_byte(0x95);         /* correct CRC for first command in SPI          */                          /* after that CRC is ignored, so no problem with */                          /* always sending 0x95                           */  spi_byte(0xff);  return 0;  }/************************************************************ * MMC get R1  * * - pings the card until it gets a non-0xff value * - returns one byte of read info ************************************************************/unsigned char mmc_get_r1(void){  unsigned char i,c;  for(i=0;i<8;i++)  {                /* response will be after 1-8 0xffs.. */    c = spi_byte(0xff);    if(c != 0xff)                  /* if it isn't 0xff, it is a response */      return(c);  }  return(c);}/************************************************************ * MMC get R2  * * - pings the card until it gets a non-0xff value * - returns one 16 bit word of read info ************************************************************/int mmc_get_r2(void){  unsigned int r;  r = ((mmc_get_r1())<< 8) & 0xff00;  r |= spi_byte(0xff);  return(r);}/************************************************************ * MMC set_sector  * * - write a sector to the card (512 bytes) * - takes sector # as param ************************************************************/int mmc_write_sector(unsigned long int sector_num, unsigned char * s){ // int addr; // char pattern, status=0;	unsigned char c,d;	unsigned int i;	/* sectors are 512 bytes, which is 0x200 or 9 bits                 */	/*   to format properly for mmc_command call, we get the high word */	/*   of the address by shifting sector_num left 9 bits then right 16 bits */	/*   which works out to be a total of 7 right shifts.              */	/*   low address word is reached by just left shifting sector num 9 bits */	mmc_command(24, (sector_num>>7)& 0xffff, (sector_num<<9)& 0xffff);	c = mmc_get_r1();	// d = mmc_get_r1();	i = 0xffff;	while((c !=0) && (i--))	{  				/* wait for data token */		c = mmc_get_r1();	}	if(c != 0x0)	{      			/* data token ? */		Uart_Printf("Can't write\n");		return(-1);	}	spi_byte(0xfe);  	for(i=0;i<512;i++)       /* read the sector */		spi_byte(*s++);  	spi_byte(0xff);          /* checksum -> don't care about it for now */	spi_byte(0xff);	i = 0xffff;	while(i--)	{	  	c=spi_byte(0xff);		d=c;		c&=0x11;		if(c==0x1)		break;  	}	if(c==0x1)	{		while(c!=0xff)		{	     c=spi_byte(0xff);		}	 	d&=0xe;	 	if(d==4) 	    Uart_Printf("Write O.K.\n");	    mmc_deselect();	    return(0);	}	mmc_deselect();	Uart_Printf("Write Failed.\n");	return(-1);}/************************************************************ * MMC get_sector  * * - reads a sector from the card (512 bytes) * - takes sector # as param ************************************************************/int mmc_read_sector(unsigned long int sector_num, unsigned char * s){	unsigned char c,d;	unsigned int i;	unsigned char *buf;	//int addr;	//unsigned char buf[512];	/* sectors are 512 bytes, which is 0x200 or 9 bits                 */	/*   to format properly for mmc_command call, we get the high word */	/*   of the address by shifting sector_num left 9 bits then right 16 bits */	/*   which works out to be a total of 7 right shifts.              */	/*   low address word is reached by just left shifting sector num 9 bits */	mmc_command(17, (sector_num>>7)& 0xffff, (sector_num<<9)& 0xffff);	c = mmc_get_r1();	d = mmc_get_r1();	i = 0xffff;	while(d == 0xff && i--)	{  						/* wait for data token */		d = mmc_get_r1();	}	if(c || d != 0xfe)	{     					/* data token ? */		Uart_Printf("MMC: error during block read\n");		Uart_Printf("     c = %x  d = %x  sector = %x\n",c,d,sector_num);    	return(-1);	}  	buf=s;	for(i=0;i<512;i++)       /* read the sector */    	*s++ = spi_byte(0xff);  	spi_byte(0xff);          /* checksum -> don't care about it for now */	spi_byte(0xff);	mmc_deselect();	//-- Display Rx buffer	s=buf;		for(i=1;i<=512;i++)	{		Uart_Printf("%2x  ",*s++);		if(i==256)		{			Uart_Printf("\nPress ESC key to Exit, other key to continue...");			if(Uart_Getch()==ESC_KEY)			{				Uart_Printf("\n");				return 0;				}				}		if((i%16)==0)			Uart_Printf("\n");	}	  	return(0);}/************************************************************ * MMC print card info * * - gets and prints formatted CID and CSD info from card ************************************************************/int mmc_print_card_info(void){	unsigned char c,d,c_mult;	unsigned int i,bl_len,c_size;	unsigned long int j;	mmc_command(10,0,0);	c = mmc_get_r1();	d = mmc_get_r1();	if(c || d != 0xfe)		Uart_Printf("MMC: error during CID read\n");  	/* get Manufacturer ID in 127:104 (3 bytes) */	//Uart_Printf("\n");	c = spi_byte(0xff);	Uart_Printf(" Manufacturer ID:         0x%x",c);	c = spi_byte(0xff);	Uart_Printf("%x",c);	c = spi_byte(0xff);  	Uart_Printf("%x\n",c);    	/* get Product name in 103:48 (7 byte string) */  	Uart_Printf(" Product name:            ");          	for(i=0;i<7;i++)    	putchar(spi_byte(0xff));  	Uart_Printf("\n");    	c = spi_byte(0xff);              /* get HW and FW revs in 47:44 (1 byte) */  	Uart_Printf(" HW Revision:             %d\n",c>>4);  	Uart_Printf(" FW Revision:             %d\n",c&0x0f);    	/* Serial number is in 39:16 (3 bytes) */  	c = spi_byte(0xff);  	Uart_Printf(" Serial Number:           0x%x",spi_byte(0xff));  	c = spi_byte(0xff);  	Uart_Printf("%x",c);  	c = spi_byte(0xff);  	Uart_Printf("%x\n",c);    	c = spi_byte(0xff);              /* get Month/Year in 15:12 (1 byte) */  	Uart_Printf(" Manufacture Date:        %d/%d\n",c>>4,1997+(c&0x0f));    	spi_byte(0xff);                  /* CRC */  	spi_byte(0xff);  	spi_byte(0xff);    	spi_byte(0xff);  	mmc_command(9,0,0);  	c = mmc_get_r1();  	d = mmc_get_r1();  	if(c || d != 0xfe)   		Uart_Printf("MMC: error during CSD read\n");    	c = spi_byte(0xff);  	/* Uart_Printf("CSD structure:           %d\n",c>>6); */  	Uart_Printf(" MMC spec version:        %d\n",(c>>2)&0x0f);  	c = spi_byte(0xff);  	/* Uart_Printf("TAAC:                    %d\n",c); */  	c = spi_byte(0xff);  	/* Uart_Printf("NSAC:                    %d\n",c); */  	c = spi_byte(0xff);  	/* Uart_Printf("Speed:                   %d\n",c); */  	c = spi_byte(0xff);   /* throwing away CCC */  	c = spi_byte(0xff);  	bl_len = c&0x0f;      /* keep this for calculating device size */  	Uart_Printf(" Read block length :      %d bytes\n",(1<<bl_len));    	/* get C_SIZE, used for calculating device size */  	c = spi_byte(0xff);  	c_size = (c & 0x03)<<10;  	c_size |= (spi_byte(0xff))<<2;  	c = spi_byte(0xff); 	c_size |= c>>6;    	/* get current consumptions */  	Uart_Printf(" Read current  @Vdd_min:  %dma\n",((c>>3)&0x07)*25);  	/* Uart_Printf(PSTR("Read current  @Vdd_max:  %dma\n",(c&0x07)*35); */  	c = spi_byte(0xff);  	/* Uart_Printf(PSTR("Write current @Vdd_min:  %dma\n",((c>>5)&0x07)*35);*/  	Uart_Printf(" Write current @Vdd_max:  %dma\n",((c>>2)&0x07)*45);    	/* get the multiplication factor for device size calculation */  	c_mult = (c & 0x03)<<1;  	c = spi_byte(0xff);  	c_mult |= (c>>7)&0x01;    	/* device size calculation - from the MMC guide */  	/* for some reasone it has to be done in several steps.. */  	j = c_size + 1;   	j *= 1<<(c_mult+2);  	j *= 1<<bl_len;  	Uart_Printf(" Device Size :            %ldk\n",j/1000);    	/* extra stuff we don't care about + CRC */  	for(d=0;d<10;d++)   		spi_byte(0xff);    	mmc_deselect();  	return(0);}void sdmmc_test(void){	int i,blknum;	//unsigned char pattern;	unsigned char buf[512];		Uart_Printf("[SD/MMC single block write & read test]\n");    Uart_Printf("Input number of the block to write\n");    	blknum=Uart_GetIntNum();	//Uart_Printf("\nInput the char pattern to write..\n");	//pattern=(char)Uart_GetIntNum();		for(i=0;i<512;i++)	{		buf[i]=i;//pattern;	}		if(mmc_init()==0)	{		mmc_print_card_info();		mmc_write_sector(blknum,buf);		Uart_Printf("Press ESC key to Exit, other key to continue...\n");		if(Uart_Getch()==ESC_KEY)			return;		mmc_read_sector(blknum,buf);	}}

⌨️ 快捷键说明

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