HAL_StatusTypeDef HAL_SD_ConfigSpeedBusOperation()

in Drivers/STM32U5xx_HAL/Src/stm32u5xx_hal_sd.c [2513:2757]


HAL_StatusTypeDef HAL_SD_ConfigSpeedBusOperation(SD_HandleTypeDef *hsd, uint32_t SpeedMode)
{
  uint32_t tickstart;
  uint32_t errorstate;
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the parameters */
  assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
  /* Change State */
  hsd->State = HAL_SD_STATE_BUSY;

#if (USE_SD_TRANSCEIVER != 0U)
  if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT)
  {
    switch (SpeedMode)
    {
      case SDMMC_SPEED_MODE_AUTO:
      {
        if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
            (hsd->SdCard.CardType == CARD_SDHC_SDXC))
        {
          hsd->Instance->CLKCR |= SDMMC_CLKCR_BUSSPEED;
          /* Enable Ultra High Speed */
          if (SD_UltraHighSpeed(hsd) != HAL_SD_ERROR_NONE)
          {
            if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
            {
              hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
              status = HAL_ERROR;
            }
          }
        }
        else if (hsd->SdCard.CardSpeed  == CARD_HIGH_SPEED)
        {
          /* Enable High Speed */
          if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
          {
            hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
            status = HAL_ERROR;
          }
        }
        else
        {
          /*Nothing to do, Use defaultSpeed */
        }
        break;
      }
      case SDMMC_SPEED_MODE_ULTRA:
      {
        if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
            (hsd->SdCard.CardType == CARD_SDHC_SDXC))
        {
          /* Enable UltraHigh Speed */
          if (SD_UltraHighSpeed(hsd) != HAL_SD_ERROR_NONE)
          {
            hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
            status = HAL_ERROR;
          }
          hsd->Instance->CLKCR |= SDMMC_CLKCR_BUSSPEED;
        }
        else
        {
          hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
          status = HAL_ERROR;
        }
        break;
      }
      case SDMMC_SPEED_MODE_DDR:
      {
        if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
            (hsd->SdCard.CardType == CARD_SDHC_SDXC))
        {
          /* Enable DDR Mode*/
          if (SD_DDR_Mode(hsd) != HAL_SD_ERROR_NONE)
          {
            hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
            status = HAL_ERROR;
          }
          hsd->Instance->CLKCR |=  SDMMC_CLKCR_BUSSPEED | SDMMC_CLKCR_DDR;
        }
        else
        {
          hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
          status = HAL_ERROR;
        }
        break;
      }
      case SDMMC_SPEED_MODE_HIGH:
      {
        if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
            (hsd->SdCard.CardSpeed  == CARD_HIGH_SPEED) ||
            (hsd->SdCard.CardType == CARD_SDHC_SDXC))
        {
          /* Enable High Speed */
          if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
          {
            hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
            status = HAL_ERROR;
          }
        }
        else
        {
          hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
          status = HAL_ERROR;
        }
        break;
      }
      case SDMMC_SPEED_MODE_DEFAULT:
        break;
      default:
        hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
        status = HAL_ERROR;
        break;
    }
  }
  else
  {
    switch (SpeedMode)
    {
      case SDMMC_SPEED_MODE_AUTO:
      {
        if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
            (hsd->SdCard.CardSpeed  == CARD_HIGH_SPEED) ||
            (hsd->SdCard.CardType == CARD_SDHC_SDXC))
        {
          /* Enable High Speed */
          if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
          {
            hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
            status = HAL_ERROR;
          }
        }
        else
        {
          /*Nothing to do, Use defaultSpeed */
        }
        break;
      }
      case SDMMC_SPEED_MODE_HIGH:
      {
        if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
            (hsd->SdCard.CardSpeed  == CARD_HIGH_SPEED) ||
            (hsd->SdCard.CardType == CARD_SDHC_SDXC))
        {
          /* Enable High Speed */
          if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
          {
            hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
            status = HAL_ERROR;
          }
        }
        else
        {
          hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
          status = HAL_ERROR;
        }
        break;
      }
      case SDMMC_SPEED_MODE_DEFAULT:
        break;
      case SDMMC_SPEED_MODE_ULTRA: /*not valid without transceiver*/
      default:
        hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
        status = HAL_ERROR;
        break;
    }
  }
#else
  switch (SpeedMode)
  {
    case SDMMC_SPEED_MODE_AUTO:
    {
      if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
          (hsd->SdCard.CardSpeed  == CARD_HIGH_SPEED) ||
          (hsd->SdCard.CardType == CARD_SDHC_SDXC))
      {
        /* Enable High Speed */
        if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
        {
          hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
          status = HAL_ERROR;
        }
      }
      else
      {
        /*Nothing to do, Use defaultSpeed */
      }
      break;
    }
    case SDMMC_SPEED_MODE_HIGH:
    {
      if ((hsd->SdCard.CardSpeed  == CARD_ULTRA_HIGH_SPEED) ||
          (hsd->SdCard.CardSpeed  == CARD_HIGH_SPEED) ||
          (hsd->SdCard.CardType == CARD_SDHC_SDXC))
      {
        /* Enable High Speed */
        if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE)
        {
          hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
          status = HAL_ERROR;
        }
      }
      else
      {
        hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE;
        status = HAL_ERROR;
      }
      break;
    }
    case SDMMC_SPEED_MODE_DEFAULT:
      break;
    case SDMMC_SPEED_MODE_ULTRA: /*not valid without transceiver*/
    default:
      hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
      status = HAL_ERROR;
      break;
  }
#endif /* USE_SD_TRANSCEIVER */

  /* Verify that SD card is ready to use after Speed mode switch*/
  tickstart = HAL_GetTick();
  while ((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER))
  {
    if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
    {
      hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT;
      hsd->State = HAL_SD_STATE_READY;
      return HAL_TIMEOUT;
    }
  }

  /* Set Block Size for Card */
  errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
  if (errorstate != HAL_SD_ERROR_NONE)
  {
    /* Clear all the static flags */
    __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);
    hsd->ErrorCode |= errorstate;
    status = HAL_ERROR;
  }

  /* Change State */
  hsd->State = HAL_SD_STATE_READY;
  return status;
}