uSD card


Example how ot use uSD cards.

Toolkit:STM Development System

Location:/bipom/devtools/STM32/examples/uSD

Code Example


int main(void) 
{
	delayMs(250);
	
	tprintf("\n\rMini-Max/STM32F1");
	tprintf("\n\ruSD TEST REV 1.01");
	// Configures SDIO IRQ interrupts

	NVIC_Configuration();
	//

	sdtest();
	//

	tprintf("\n\r\n\rEND");
	for(;;);
	return 0;
}

uint8_t Buffer_Block_Tx[BLOCK_SIZE], Buffer_Block_Rx[BLOCK_SIZE];
uint8_t Buffer_MultiBlock_Tx[MULTI_BUFFER_SIZE], Buffer_MultiBlock_Rx[MULTI_BUFFER_SIZE];
volatile TestStatus EraseStatus = FAILED, TransferStatus1 = FAILED, TransferStatus2 = FAILED;
SD_Error Status = SD_OK;
__IO uint32_t SDCardOperation = SD_OPERATION_ERASE;

//********************************************************************************

void sdtest(void)
{
	const char *typeName[8]= 
	{ 
		"STD CAPACITY SD CARD V1.1",
		"STD CAPACITY SD CARD V2.0",
		"HIGH CAPACITY SD CARD",
		"MULTIMEDIA CARD",
		"SECURE DIGITAL IO CARD",
		"HIGH SPEED MULTIMEDIA CARD",
		"SECURE DIGITAL IO COMBO CARD",
		"HIGH CAPACITY MMC CARD"
	};
	//

  	GPIO_InitTypeDef  GPIO_InitStructure;
  	//

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    /*!< Configure SD Card power pin */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_11;
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  	GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOC, GPIO_Pin_5 );
    /*------------------------------ SD Init ---------------------------------- */
	if((Status = SD_Init()) != SD_OK)
	{
    	tprintf("\n\rERROR: can't initialize SD card");
		return;
  	}
	tprintf("\n\r\n\ruSD card info");
  	tprintf("\n\rType      : %d ",SDCardInfo.CardType);
  	(7<SDCardInfo.CardType) ? 
  		tprintf("UNKNOWN CARD"): 
  			tprintf(typeName[SDCardInfo.CardType]);
  	//

	tprintf("\n\rCapacity  :  %u ",SDCardInfo.CardCapacity);
	tprintf("\n\rBlock Size:  %u ",SDCardInfo.CardBlockSize);
	tprintf("\n\r");
	// 

	while((Status == SD_OK) && (SDCardOperation != SD_OPERATION_END) && (SD_Detect()== SD_PRESENT))
	{
    	switch(SDCardOperation)
    	{
      		/*-------------------------- SD Erase Test ---------------------------- */
      		case (SD_OPERATION_ERASE):
      		{
        		SD_EraseTest();
        		SDCardOperation = SD_OPERATION_BLOCK;
        		break;
      		}
      		/*-------------------------- SD Single Block Test --------------------- */
      		case (SD_OPERATION_BLOCK):
      		{
        		SD_SingleBlockTest();
        		SDCardOperation = SD_OPERATION_MULTI_BLOCK;
        	break;
      		}       
      		/*-------------------------- SD Multi Blocks Test --------------------- */
      		case (SD_OPERATION_MULTI_BLOCK):
      		{
        		SD_MultiBlockTest();
        		SDCardOperation = SD_OPERATION_END;
      		  	break;
      		}              
    	}
	}
   // 

  SD_DeInit();
  /*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12);

  /*!< Configure PD.02 CMD line */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOD,GPIO_Pin_2);
  // Disable power to the card

  GPIO_SetBits(GPIOC, GPIO_Pin_5 );
}

//********************************************************************************

void NVIC_Configuration(void)
{
  // Configures SDIO IRQ channel.


  NVIC_InitTypeDef NVIC_InitStructure;
  /* Configure the NVIC Preemption Priority Bits */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  //	

  NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


//********************************************************************************

void SD_EraseTest(void)
{
  // Tests the SD card erase operation

	
  /*------------------- Block Erase ------------------------------------------*/
  if (Status == SD_OK)
  {
    /* Erase NumberOfBlocks Blocks of WRITE_BL_LEN(512 Bytes) */
    Status = SD_Erase(0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));
  }

  if (Status == SD_OK)
  {
    Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);

    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();

    /* Wait until end of DMA transfer */
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  /* Check the correctness of erased blocks */
  if (Status == SD_OK)
  {
    EraseStatus = eBuffercmp(Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);
  }
  
  if(EraseStatus == PASSED)
  {
   tprintf("\n\rSUCCESS: EraseTest passed");
  }
  else
  {
   tprintf("\n\rERROR: EraseTest failed");  
  }
}


//********************************************************************************

void SD_SingleBlockTest(void)
{
  // Tests the SD card Single Blocks operations

  
  /*------------------- Block Read/Write --------------------------*/
  /* Fill the buffer to send */
  Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F);

  if (Status == SD_OK)
  {
    /* Write block of 512 bytes on address 0 */
    Status = SD_WriteBlock(Buffer_Block_Tx, 0x00, BLOCK_SIZE);
    /* Check if the Transfer is finished */
    Status = SD_WaitWriteOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  if (Status == SD_OK)
  {
    /* Read block of 512 bytes from address 0 */
    Status = SD_ReadBlock(Buffer_Block_Rx, 0x00, BLOCK_SIZE);
    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  /* Check the correctness of written data */
  if (Status == SD_OK)
  {
    TransferStatus1 = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE);
  }
  
  if(TransferStatus1 == PASSED)
  {
   tprintf("\n\rSUCCESS: SingleBlockTest passed");
  }
  else
  {
    tprintf("\n\rERROR: SingleBlockTest failed");   
  }
}


//********************************************************************************

void SD_MultiBlockTest(void)
{
  // Tests the SD card Multiple Blocks operations

  
  /*--------------- Multiple Block Read/Write ---------------------*/
  /* Fill the buffer to send */
  Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 0x0);

  if (Status == SD_OK)
  {
    /* Write multiple block of many bytes on address 0 */
    Status = SD_WriteMultiBlocks(Buffer_MultiBlock_Tx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);
    /* Check if the Transfer is finished */
    Status = SD_WaitWriteOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  if (Status == SD_OK)
  {
    /* Read block of many bytes from address 0 */
    Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);
    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  /* Check the correctness of written data */
  if (Status == SD_OK)
  {
    TransferStatus2 = Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);
  }
  
  if(TransferStatus2 == PASSED)
  {
   tprintf("\n\rSUCCESS: MultiBlockTest passed");
  }
  else
  {
   tprintf("\n\rERROR: MultiBlockTest failed"); 
  }
}


//********************************************************************************

TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength)
{
  while (BufferLength--)
  {
    if (*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }

    pBuffer1++;
    pBuffer2++;
  }

  return PASSED;
}


//********************************************************************************

void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)
{
  uint16_t index = 0;

  /* Put in global buffer same values */
  for (index = 0; index < BufferLength; index++)
  {
    pBuffer[index] = index + Offset;
  }
}


//********************************************************************************

TestStatus eBuffercmp(uint8_t* pBuffer, uint32_t BufferLength)
{
  // Checks if a buffer has all its values are equal to zero

  
  while (BufferLength--)
  {
    /* In some SD Cards the erased state is 0xFF, in others it's 0x00 */
    if ((*pBuffer != 0xFF) && (*pBuffer != 0x00))
    {
      return FAILED;
    }

    pBuffer++;
  }

  return PASSED;
}