2016-10-23 06:17 PM
I'm working with STM32L476 trying to get a microSD card to communicate. Initially I'm sure I was getting a response, but now when I send CMD8 the chip does not see a respons from the card (SD_CMD_RSP_TIMEOUT). Even though the signal is present on D0.
Here is clock setup, initially clock runs at ~300kHz for setup./** System Clock Configuration */
void
SystemClock_Config(
void
)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
//Low speed external crystal
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
//Mid speed internal osc
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if
(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
Error_Handler();
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if
(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
Error_Handler();
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_USB | RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_RTC;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
//External 768 crystal
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1;
PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;
PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
PeriphClkInit.PLLSAI1.PLLSAI1N = 24;
PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK | RCC_PLLSAI1_ADC1CLK;
if
(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
Error_Handler();
__HAL_RCC_PWR_CLK_ENABLE();
if
(HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
Error_Handler();
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_RCCEx_EnableMSIPLLMode();
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
Msp init:
void
HAL_SD_MspInit(SD_HandleTypeDef* hsd)
{
GPIO_InitTypeDef GPIO_InitStruct;
if
(hsd->Instance == SDMMC1)
{
/* USER CODE BEGIN SDMMC1_MspInit 0 */
/* USER CODE END SDMMC1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SDMMC1_CLK_ENABLE();
/**SDMMC1 GPIO Configuration
PC8 ------> SDMMC1_D0
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
*/
GPIO_InitStruct.Pin = SD1_D0_Pin | SD1_CLK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SD1_CMD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(SD1_CMD_GPIO_Port, &GPIO_InitStruct);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(SDMMC1_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
/* USER CODE BEGIN SDMMC1_MspInit 1 */
/* USER CODE END SDMMC1_MspInit 1 */
}
}
Clock and CMD pins are correct for sure, as its sending data to the card and the card is responding. However, the code or chip isn't seeing the response come in.
I've tried setting PC8 (SDMMC1_D0) as an output and toggling, and that shows up on the logic analyzer, so its not as if the pin is not connected to the SD card.
Attached is image of logic analyzer output:
If I look at the SDMMC1 registers, the CTIMEOUT register is active. Which will occur after 64 SD clock cyles of no response. But clearly the response is there (about 15 clock cycles), so I am not sure what I am missing.
Checked errata and there is a mention of CRCFAIL and WAITRESP when sending a command without a response. So I don't see those being relevant. Thanks #sdmmcSolved! Go to Solution.
2016-10-29 06:51 PM
Went through all the SDMMC1 registers and they look ok:
- PWRCTRL 11 (on) - WIDBUS 00 (1b wide bus) - PWRSAV/BYPASS 0 - CLKEN 1 (enabled) - CLKDIV (tried various up to 0xFE, no change) - ARG = 0x1AA which is right - CMD -> CPSMEN enabled (I think you can't do anything with SD without the state machine on, but could be wrong) - WAITRESP = 01 = wait for short response - CMDINDEX = 0x08 (send_if_cond, which is right because we get the appropriate R7 response) RESPCMD is always 111111, ie no response received. PC8 has no other connections on the Nucleo board, and no other connections on my own hardware. I did see one thread where someone mentioned L4xx and SD working for them, but no details on code. I tried the sample app and thats not working as well: STMCubeHAL\STM32Cube_FW_L4_V1.5.0\Projects\STM32L476G_EVAL\Applications\FatFs\FatFs_uSD\ Had to edit it to use MSI clock. Edit: very simple mistake by me was cause of problem. I was getting a response on D0 and thinking that everything was setup correctly. But its because I was entering SPI mode which is completely different than SD mode (SD mode the response is on the same CMD pin, SPI mode the response is on D3 pin). See page 14 here: http://users.ece.utexas.edu/~valvano/EE345M/SD_Physical_Layer_Spec.pdf - No response to CMD0 is expected (this is right in HAL). - If SPI mode is accidentally entered, unplug the card to reset it, or it will be stuck in that mode. Just tie/pull that pin high if you are using a microSD module with a ''CS'' pin, as we don't need it in 1-bit SD mode. - Some SD cards will require additional delay after sdmmc clock is started. I believe this is in the spec, HAL does not wait long enough. Add a 1ms delay after __HAL_SD_SDMMC_ENABLE(hsd); - The first R1 response I got to CMD55 was COM_CRC_ERROR. But its gone away now (crc info here http://wiki.seabright.co.nz/wiki/SdCardProtocol.html). If I see it again I will investigate.2016-10-29 06:51 PM
Went through all the SDMMC1 registers and they look ok:
- PWRCTRL 11 (on) - WIDBUS 00 (1b wide bus) - PWRSAV/BYPASS 0 - CLKEN 1 (enabled) - CLKDIV (tried various up to 0xFE, no change) - ARG = 0x1AA which is right - CMD -> CPSMEN enabled (I think you can't do anything with SD without the state machine on, but could be wrong) - WAITRESP = 01 = wait for short response - CMDINDEX = 0x08 (send_if_cond, which is right because we get the appropriate R7 response) RESPCMD is always 111111, ie no response received. PC8 has no other connections on the Nucleo board, and no other connections on my own hardware. I did see one thread where someone mentioned L4xx and SD working for them, but no details on code. I tried the sample app and thats not working as well: STMCubeHAL\STM32Cube_FW_L4_V1.5.0\Projects\STM32L476G_EVAL\Applications\FatFs\FatFs_uSD\ Had to edit it to use MSI clock. Edit: very simple mistake by me was cause of problem. I was getting a response on D0 and thinking that everything was setup correctly. But its because I was entering SPI mode which is completely different than SD mode (SD mode the response is on the same CMD pin, SPI mode the response is on D3 pin). See page 14 here: http://users.ece.utexas.edu/~valvano/EE345M/SD_Physical_Layer_Spec.pdf - No response to CMD0 is expected (this is right in HAL). - If SPI mode is accidentally entered, unplug the card to reset it, or it will be stuck in that mode. Just tie/pull that pin high if you are using a microSD module with a ''CS'' pin, as we don't need it in 1-bit SD mode. - Some SD cards will require additional delay after sdmmc clock is started. I believe this is in the spec, HAL does not wait long enough. Add a 1ms delay after __HAL_SD_SDMMC_ENABLE(hsd); - The first R1 response I got to CMD55 was COM_CRC_ERROR. But its gone away now (crc info here http://wiki.seabright.co.nz/wiki/SdCardProtocol.html). If I see it again I will investigate.2017-01-12 02:31 AM
Hi
‌- Some SD cards will require additional delay after sdmmc clock is started. I believe this is in the spec, HAL does not wait long enough. Add a 1ms delay after __HAL_SD_SDMMC_ENABLE(hsd);
I agree with your conclusion. The HAL driver should be updated to insert correct delay(s) when needed.
Could you please share the model of the SD card where the issue is faced?
Thank you
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2017-01-12 03:24 PM
Sorry I don't recall the models at this time. Mixza 8GB SD card was one and
there were others. If its important I can test it again sometime.
Here is the reference to the SD specification:
The host shall supply power to the card so that the voltage is reached to
VDD min within 250ms and start to supply at least 74 SD clocks to the SD
card with keeping CMD line to high. In case of SPI mode, CS shall be held
to high during 74 clock cycles.
https://www.sdcard.org/downloads/pls/pdf/part1_500.pdf (pg174)
2017-01-13 04:09 AM
Thank you
for the shared details.To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.