cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 + emmc write & read speed is so slow...

Jlee.5
Associate II

@Hi all!

Thank you for your hard work.

Device : STM32L496 (Nucleo board)

eMMC : Hardkernel emmc reader + eMMC (sandisk 16GB / SDIN9DW4-16G)​

env : stm32cudeide

I can read eMMC infomation and other CSD info.

Write and read function are works well. but it is very slow to our application.

​HAL_MMC_ReadBlocks_DMA function is very fast(microsecond). but when i added HAL_MMC_GetCardState(&hmmc1) function, it almost stop. (millisecond dimension)

​i searched in google and stm32 forum . In spite of these try, I don't have any solution about this problem.

this is my main code.

I'm very glad to any help.

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint32_t dataSize = 512;    // byte
  uint32_t blockSize = 512;
  uint32_t numberOfBlocks = 1;
  uint32_t errorState = 0;
  uint32_t timeout = 1000000;
  uint32_t blockAdd = 0;
  uint8_t *wData = (uint8_t *) malloc(dataSize);
  uint8_t *rData = (uint8_t *) malloc(dataSize);
  uint32_t kB = 0;
  uint32_t capacity = 32*1024*1024;
  uint32_t iterations = capacity / dataSize;
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
  HAL_Delay(3000);
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
  DWT_Delay_Init();
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SDMMC1_MMC_Init();
  MX_LPUART1_UART_Init();
  /* USER CODE BEGIN 2 */
  printf("All init done \r\n ");
#if 1
{
  if( HAL_MMC_GetCardInfo(&hmmc1, &CardInfo) != HAL_OK )
  {
      printf("HAL_MMC_GetCardInfo Err\n");
  }
 
  HAL_MMC_GetCardCSD(&hmmc1, &csd);
  printf("ECC = %d \r\n", csd.ECC);
 
  printf("\r\n BlockNbr = %d", CardInfo.BlockNbr);
  printf("\r\n BlockSize = %d", CardInfo.BlockSize);
  printf("\r\n CardType = %d", CardInfo.CardType);
  printf("\r\n Class = %d", CardInfo.Class);
  printf("\r\n LogBlockNbr = %d", CardInfo.LogBlockNbr);
  printf("\r\n LogBlockSize = %d", CardInfo.LogBlockSize);
}
#endif
	HAL_Delay(1000);
	int status = 0;
 
 
 
#if 1
	{
 
	  status = HAL_MMC_Erase(&hmmc1, 0, 4096);
 
	  if( status != HAL_OK )
	  {
		printf("\r\n Single HAL_MMC_Erase Fail \r\n");
	  }
	  else
	  {
		while( HAL_MMC_GetCardState(&hmmc1) != HAL_MMC_CARD_TRANSFER);
		printf("\r\n Single HAL_MMC_Erase OK \n");
	  }
	}
#endif
 
	printf("\r\n Start write / read data \r\n");
 
	int cmp_fail_cnt = 0;
 
	for (int iteration = 0; iteration < 4096; iteration++) {
	  blockAdd += numberOfBlocks; //  + 2097152 HAL_MMC_ERROR_CMD_CRC_FAIL
	  kB = blockAdd / 2;
 
//	       Write
	      for (int i = 0; i < dataSize; i++) {
	          wData[i] = (i + iteration) & 0xff;
	      }
 
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
		  errorState = HAL_MMC_WriteBlocks(&hmmc1, wData, blockAdd, numberOfBlocks, timeout);
//		  errorState = HAL_MMC_WriteBlocks_DMA(&hmmc1, wData, blockAdd, numberOfBlocks);
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
			  while (HAL_MMC_GetCardState(&hmmc1) != HAL_MMC_CARD_TRANSFER) {
//				  Error_Handler();
//				  HAL_Delay(1);
	      }
 
//		  printf("Wr ");
//			for (int j = 0; j < numberOfBlocks; j++) {
//			  for (int i = 0; i < 16; i++) {
//				  printf("%02X ", wData[i+ j*16]);
//			  }
//			  printf("\n");
//	      }
 
	//       Read
	      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
//	      errorState = HAL_MMC_ReadBlocks(&hmmc1, rData, blockAdd, numberOfBlocks, timeout);
	      errorState = HAL_MMC_ReadBlocks_DMA(&hmmc1, rData, blockAdd, numberOfBlocks);
 
		  while (HAL_MMC_GetCardState(&hmmc1) != HAL_MMC_CARD_TRANSFER){
//			  Error_Handler();
//			  HAL_Delay(1);
	      }
	      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
//	      printf("Rd ");
//	          for (int j = 0; j < numberOfBlocks; j++) {
//	              for (int i = 0; i < 16; i++) {
//	                  printf("%02X ", rData[i+ j*16]);
//	              }
//	              printf("\n");
//	          }
 
 
	      if (memcmp(wData, rData, dataSize) == 0) {
//	          printf("Compare Passed. (BA: %8ld, %8ld kB) %d \r\n", blockAdd, kB, status);
	      }
	      else {
	          status = 1;
	          cmp_fail_cnt += 1;
//	          printf("Compare FAILED! (BA: %8ld, %8ld kB) %d \r\n", blockAdd, kB, status);
	      }
	} /* End of write & read data */
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	  HAL_Delay(5000);
	  printf("\r\n cmp_fail_cnt = %d", cmp_fail_cnt);
  }
  /* USER CODE END 3 */
}

static void MX_SDMMC1_MMC_Init(void)
{
 
  /* USER CODE BEGIN SDMMC1_Init 0 */
 
  /* USER CODE END SDMMC1_Init 0 */
 
  /* USER CODE BEGIN SDMMC1_Init 1 */
 
  /* USER CODE END SDMMC1_Init 1 */
  hmmc1.Instance = SDMMC1;
  hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hmmc1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
  hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hmmc1.Init.BusWide = SDMMC_BUS_WIDE_1B;
  hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
  hmmc1.Init.ClockDiv = 15;
  if (HAL_MMC_Init(&hmmc1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_MMC_ConfigWideBusOperation(&hmmc1, SDMMC_BUS_WIDE_4B) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SDMMC1_Init 2 */
 
  /* USER CODE END SDMMC1_Init 2 */
 
}
 
/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Channel4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn);
 
}

7 REPLIES 7
Jlee.5
Associate II

anyone..? :(

I'm stuck in this problem..

hello, just i have the same problem. can you fix it?

Don't know.

Define your HW, and specifically a UART you can use for diagnostic output.

hmmc1.Init.ClockDiv = 15; // yeah, that's going to be a sloth..

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

hello, what's mean ?

thanks a lot.

>> can you fix it?

Yes, probably, got a couple of L4 and eMMC platforms functioning. I'm using HAL + Keil, not CubeMX/WTF

What I can't fix are "Me Too" problems, or spend hours debugging output from a code generator.

"Define your HW, and specifically a UART you can use for diagnostic output."

Describe your hardware, use a schematic if that's easier, one showing clocking, eMMC wiring, and a UART connection that can be used by a demo application. This way I can form an opinion about if you have a hardware or software issue.

"hmmc1.Init.ClockDiv = 15; // yeah, that's going to be a sloth.."

If you clock it slowly it will perform like a tortoise / snail / slow moving korean mammal

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

@Community member​ 

Hello clive1!

I stay a way from this problem for a long time cause difference work.

finally i faced again this work and happened same problem

You mentioned about "hmmc1.Init.ClockDiv = 15; // yeah, that's going to be a sloth.."

but i already changed ClockDiv by this description .

    (#) Initialize the SDMMC peripheral interface with defaullt configuration.
        The initialization process is done at 400KHz. You can change or adapt 
        this frequency by adjusting the "ClockDiv" field. 
        The MMC Card frequency (SDMMC_CK) is computed as follows:
  
           SDMMC_CK = SDMMCCLK / (ClockDiv + 2)

I follow this description.

but ClockDiv = 15 is fastest value according to my experimental test.

My ultimate goal is that replaced my SD card storage to eMMC storage in my wearable device.

Because i knew that eMMC storage R/W speed faster than SD card.

Please let me know everything you might consider.

(+ I give you cup of coffee using paypal 🙂 )​

Gbaqd.1
Associate

Can someone fix this solution i never find its solution facing the same problem in my device i searched for it from youtube and other sites but cant find the sloution need help from you guys.