AnsweredAssumed Answered

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

Question asked by jpr.thm on Oct 24, 2016
Latest reply on Jan 13, 2017 by Amel N
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 32.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

Attachments

Outcomes