2024-04-27 09:23 AM - last edited on 2024-04-28 12:47 AM by Peter BENSCH
I have a custom board using the STM32L562Q BGA package processor. I have a high speed capable eMMC part with an 8-bit data interface.
The STM Cube generated code seems to be correctly beginning the init and ID process, however after the 3 different settings are attempted the code error exits with return code 4. This is the part of the 1-bit boot sequence where code is trying to identify voltage and high capacity or low capacity card.
Do you have reference code for this specific part or something that complies with the 5.1 eMMC specification? In theory these are all backward compatible, but these newer cards has lots of useful features.
The design also include a Linear Tech triple supply so VCC to this part is independently controlled. It also has a hard reset. So power is applied and we wait for pgood, we toggle and wait the appropriate period on the init signal. Then the normal eMMC init is kicked off.
Any idea on where to resume debugging this?
void
HAL_MMC_MspInit(MMC_HandleTypeDef* mmcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 };
if (mmcHandle->Instance == SDMMC1) {
/* USER CODE BEGIN SDMMC1_MspInit 0 */
bool VCC2_NotReady = true;
// Power ON Device
SetVCC2(ON);
do {
if (GetPGood2() == GPIO_PIN_SET) {
VCC2_NotReady = false;
} else {
// Timeout power good and handle hardware error
// TODO Add time check here for fatal error
}
} while (VCC2_NotReady);
/* USER CODE END SDMMC1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC1;
PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLP;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}
/* SDMMC1 clock enable */
__HAL_RCC_SDMMC1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**SDMMC1 GPIO Configuration
PB9 ------> SDMMC1_D5
PD2 ------> SDMMC1_CMD
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PC10 ------> SDMMC1_D2
PB8 ------> SDMMC1_D4
PC7 ------> SDMMC1_D7
PC9 ------> SDMMC1_D1
PC8 ------> SDMMC1_D0
PC6 ------> SDMMC1_D6
*/
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_10 | GPIO_PIN_7 |
GPIO_PIN_9 | GPIO_PIN_8 | GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* SDMMC1 interrupt Init */
HAL_NVIC_SetPriority(SDMMC1_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
/* USER CODE BEGIN SDMMC1_MspInit 1 */
// Perform Hard Reset
SetEmmcRstN(ON);
// Force a 1 mSec wait for reset
HAL_Delay(1);
// Release Hard Reset
SetEmmcRstN(OFF);
/* USER CODE END SDMMC1_MspInit 1 */
}
}