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

📄 mmc.c

📁 IAR-2148.rar 这是IAR上做的2148所有的例程
💻 C
📖 第 1 页 / 共 2 页
字号:
{
  unsigned long i = 0;
  char rvalue = MMC_RESPONSE_ERROR;	// MMC_SUCCESS;
  //char c = 0x00;

  // Set the block length to read
  if (mmcSetBlockLength (512) == MMC_SUCCESS)	// block length could be set
    {

      // SS = LOW (on)
      CS_LOW ();
      // send write command
      mmcSendCmd (24,address, 0xFF);

      // check if the MMC acknowledged the write block command
      // it will do this by sending an affirmative response
      // in the R1 format (0x00 is no errors)
     // UART_PutString(UART0,"set write block length\n");//add by chang
      if (mmcGetXXResponse(MMC_R1_RESPONSE) == MMC_R1_RESPONSE)
	{
	
         // UART_PutString(UART0,"write signal block\n");//add by chang
          spiSendByte(0xff);
	  // send the data token to signify the start of the data
	  spiSendByte(0xfe);
	  // clock the actual data transfer and transmitt the bytes
	  for (i = 0; i < 512; i++)
	    spiSendByte(mmc_buffer[i]);	// mmc_buffer[i];       Test: i & 0xff
	  // put CRC bytes (not really needed by us, but required by MMC)
	  spiSendByte(0xff);
	  spiSendByte(0xff);
	  // read the data response xxx0<status>1 : status 010: Data accected, status 101: Data
	  //   rejected due to a crc error, status 110: Data rejected due to a Write error.
          mmcCheckBusy();
	}
      else
	{
	  // the MMC never acknowledge the write command
	  rvalue = MMC_RESPONSE_ERROR;	// 2
	}
      rvalue=MMC_SUCCESS;
    }
  else
    {
      rvalue = MMC_BLOCK_SET_ERROR;	// 1
    }
  //give the MMC the required clocks to finish up what ever it needs to do
  //for (i = 0; i < 9; ++i)
  //spiSendByte(0xff);

  CS_HIGH ();
 // Uart_Printf("rvalue=%d\n",rvalue);
  // Send 8 Clock pulses of delay.
  spiSendByte(0xff);
  return rvalue;
}// mmc_write_block


//---------------------------------------------------------------------
void mmcSendCmd (const char cmd, unsigned long data, const char crc)
{
  char frame[6];
  char temp;
  int i;

  frame[0]=(cmd|0x40);
  for(i=3;i>=0;i--){
    temp=(char)(data>>(8*i));
    frame[4-i]=(temp);
  }
  frame[5]=(crc);
  for(i=0;i<6;i++)
    spiSendByte(frame[i]);
}


//--------------- set blocklength 2^n ------------------------------------------------------
// Ti Modification: long int-> long
char mmcSetBlockLength (const unsigned long blocklength)
{
  //char rValue = MMC_TIMEOUT_ERROR;
  //char i = 0;

  // SS = LOW (on)
  CS_LOW ();

  // Set the block length to read
  //MMC_SET_BLOCKLEN =CMD16
  mmcSendCmd(16, blocklength, 0xFF);

  // get response from MMC - make sure that its 0x00 (R1 ok response format)
  if(mmcGetResponse()!=0x00)
  {
    //UART_PutString(UART0,"not set \n");
    return 0xff;
  }
  CS_HIGH ();

  // Send 8 Clock pulses of delay.
  spiSendByte(0xff);
  spiSendByte(0xff);

  return MMC_SUCCESS;
}				


unsigned char spiSendByte(const unsigned char data)
{
    /*
    unsigned char spib;

    //while(SSIOST_bit.BUSY != 0);    // Wait until the character can be sent
    SSIOINT_bit.TXCMP = 1;            //clear interrupt register
    SSIOBUF = data;                   // Send the data

    while((SSIOINT & 0x02) != 0x02);   // Wait for the transfer to complete
    spib = SSIOBUF;                   // Get the data received
    SSIOINT_bit.RXCMP = 1;            //clear interrupt register
    return spib;                      //return transmited character
    */

    //NOTE!!! This function send character to SPI bus when mode is MASTER
    //NOTE!!! This function receive character from SPI when mode is SLAVE
    unsigned int spib;

    //while(SSPSR_bit.BSY);      // Wait until the character can be sent
    while(SSPSR_bit.TNF == 0);
    SSPDR = data;              // Send the data

    //while(!SPSR0_bit.SPIF);     // Wait for the transfer to complete
    while(SSPSR_bit.RNE == 0);    // Wait until the character can be sent
    spib = SSPDR;                 // Get the data received
    return spib;
    //return 0;
}

void spiWriteByte(const unsigned char data)
{
  //while(SSIOST_bit.BUSY != 0);      // Wait until the character can be sent
  //SSIOINT_bit.TXCMP = 1;            // clear interrupt register
  //SSIOBUF = data;
}

unsigned char spiReadByte()
{
  //unsigned char spib;
  //while(SSIOINT_bit.RXCMP == 0);
  //spib = SSIOBUF;                   // Get the data received
  //SSIOINT_bit.RXCMP = 1;            //clear interrupt register
  //return spib;
  return 0;
}

// Reading the contents of the CSD and CID registers in SPI mode is a simple
// read-block transaction.

char mmcReadRegister (const char cmd_register, const unsigned char length)
{
  char uc = 0;
  char rvalue = MMC_TIMEOUT_ERROR;
//  char i = 0;

  if (mmcSetBlockLength(length) == MMC_SUCCESS)
    {

      CS_LOW ();
      // CRC not used: 0xff as last byte
      mmcSendCmd(cmd_register, 0x000000, 0xff);

      // wait for response
      // in the R1 format (0x00 is no errors)
      if (mmcGetResponse() == 0x00)
	{
	 //UART_PutString(UART0,"set MMC BlockLength ok\n");
          if (mmcGetXXResponse(0xfe)== 0xfe)
          {
	    UART_PutString(UART0,"read register\n");//add by chang
            for (uc = 0; uc < length; uc++)
	      mmc_buffer[uc] = spiSendByte(0xff);
          }
            // get CRC bytes (not really needed by us, but required by MMC)
	  //add chang guo feng
          rvalue = 0x00;
          spiSendByte(0xff);
	  spiSendByte(0xff);
	}
      else
	rvalue = MMC_RESPONSE_ERROR;
      // CS = HIGH (off)
    //  CS_HIGH ();

      // Send 8 Clock pulses of delay.
      spiSendByte(0xff);
     // CS_HIGH ();

    }
  CS_HIGH ();
  return rvalue;
}// mmc_read_register


/************************************************************************************
**Function:MMC_Test
**autor:chang guofeng
*************************************************************************************/
void MMC_Test(void)
{
  int err;
  int i;//,j;
  int block_len,block_num,tmp;
  unsigned char ret;//,csdbuf[16];
  err=initMMC();
  if(err==0)UART_PutString(UART0,"Init MMC OK\n");
  else UART_PutString(UART0,"Init MMC error\n");
 // Uart_Printf("MMC Test\n");
  ret=mmcReadRegister (MMC_READ_CSD, 16);
  if(ret !=0)
  {
    UART_PutString(UART0,"Get Card info error\n");
    return;
  }
  IO0CLR = IO0CLR | 0x1<<4; //Clear P0.4,0
  ///* 计算块的最大长度  */														/* calculate the size of a sector */
  block_len = 1 << (mmc_buffer[READ_BL_LEN_POS] & READ_BL_LEN_MSK);  			///* (2 ^ READ_BL_LEN) */

	///* 计算卡中块的个数 */														/* calculate the sector numbers of the SD Card */
  block_num = ((mmc_buffer[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +
	      			 (mmc_buffer[C_SIZE_POS2] << 2) +
	 	 			((mmc_buffer[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1;				/* (C_SIZE + 1)*/
		 	  															
 tmp = ((mmc_buffer[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +
	      ((mmc_buffer[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2;				/* (C_SIZE_MULT + 2) */
    	
  /* 获得卡中块的数量 */														/* get the block numbers in card */
 block_num = block_num * (1 << tmp);									/* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
																			
/* 计算擦除的单位(单位: 块) */	
 tmp  = ((mmc_buffer[ERASE_GRP_SIZE_POS] & ERASE_GRP_SIZE_MSK) >> 2) + 1;  	/* (ERASE_GRP_SIZE + 1)  */
		
		/* (ERASE_GRP_SIZE + 1) * (ERASE_GRP_MULTI + 1) */
 tmp *= ((mmc_buffer[ERASE_GRP_MULTI_POS1] & ERASE_GRP_MULTI_MSK1) << 3) +
		       ((mmc_buffer[ERASE_GRP_MULTI_POS2] & ERASE_GRP_MULTI_MSK2) >> 5) + 1;	
			/* MMC: SECTOR_SIZE */
  UART_PutString(UART0,"MMC Card Info:\n");
  Uart_Printf("Max Bock Length :%dbyte\n",block_len);
  Uart_Printf("Bock Number:%d\n",block_num);
  Uart_Printf("Size:%dM\n",tmp);

  for(i=0;i<512;i++)mmc_buffer[i]=5;

 // for(i=0;i<=4;i++)
  //{
   // for(j=0;j<16;j++)
    //  Uart_Printf(" %02u ",mmc_buffer[i*16+j]);
 //  Uart_Printf("\n");
 // }
  UART_PutString(UART0,"Write a block\n");	
  if(mmcWriteBlock (0x0)!=0)
  {
     UART_PutString(UART0,"Write error\n");
     return;
  }
  UART_PutString(UART0,"Write OK\n");

  for(i=0;i<512;i++)mmc_buffer[i]=0;  //clear mmc_buffer

   UART_PutString(UART0,"Read a Block\n");	
   if(mmcReadBlock(0x0,512)!=0)
   {
     UART_PutString(UART0,"Read error\n");
     return;
  }
  UART_PutString(UART0,"Read OK\n");
  // UART_PutString(UART0,"compare data\n");
  for(i=0;i<512;i++)
  { if(mmc_buffer[i]!=5)
   {
     UART_PutString(UART0,"Compare error\n");	
     return ;
   }
  //else
  }

  UART_PutString(UART0,"Read and write is OK\n");	

}
//---------------------------------------------------------------------
#endif /* _MMCLIB_C */

⌨️ 快捷键说明

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