2020-07-07 12:47 AM
@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);
}
2020-07-13 01:38 AM
anyone..? :(
I'm stuck in this problem..
2020-09-28 05:27 PM
hello, just i have the same problem. can you fix it?
2020-09-28 05:52 PM
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..
2020-09-28 06:31 PM
hello, what's mean ?
thanks a lot.
2020-09-28 06:59 PM
>> 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
2020-11-05 06:21 PM
@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 :) )
2020-11-16 10:49 PM
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.