cancel
Showing results for 
Search instead for 
Did you mean: 

Sdmmc incoming data not being seen, STM32L476, HAL - SOLVED

thmjpr
Associate II
Posted on October 24, 2016 at 03:17

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:
  • CMD8 is sent
  • Reply looks correct to me (R7, voltage and check pattern 101010 is there)
  • However, SD_CmdResp7Error thinks it times out

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 #sdmmc
1 ACCEPTED SOLUTION

Accepted Solutions
thmjpr
Associate II
Posted on October 30, 2016 at 02:51

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.

View solution in original post

4 REPLIES 4
thmjpr
Associate II
Posted on October 30, 2016 at 02:51

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.

Amel NASRI
ST Employee
Posted on January 12, 2017 at 11:31

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.

Posted on January 12, 2017 at 23:24

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)

Posted on January 13, 2017 at 12:09

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.