Beispiel #1
0
void sdcard_init(void)
{
    volatile int retry=10;

    /* SDIO initial configuration */
    SDHandle.Instance                 = SDIO;
    SDHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
    SDHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
    SDHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE; //TODO
    SDHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
    SDHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
    SDHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV; //INIT_CLK_DIV will be used first

    /* DeInit in case of reboot */
    HAL_SD_DeInit(&SDHandle);

    /* Init the SD interface */
    HAL_SD_CardInfoTypedef cardinfo;
    while(HAL_SD_Init(&SDHandle, &cardinfo) != SD_OK && --retry) {
        systick_sleep(100);
    }

    if (retry == 0) {
        BREAK();
    }

    /* Configure the SD Card in wide bus mode. */
    if (HAL_SD_WideBusOperation_Config(&SDHandle, SDIO_BUS_WIDE_4B) != SD_OK) {
        BREAK();
    }
}
Beispiel #2
0
bool sdcard_power_on(void) {
    if (!sdcard_is_present()) {
        return false;
    }

    // SD device interface configuration
    sd_handle.Instance = SDIO;
    sd_handle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
    sd_handle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
    sd_handle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
    sd_handle.Init.BusWide             = SDIO_BUS_WIDE_1B;
    sd_handle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
    sd_handle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;

    // init the SD interface
    HAL_SD_CardInfoTypedef cardinfo;
    if (HAL_SD_Init(&sd_handle, &cardinfo) != SD_OK) {
        goto error;
    }

    // configure the SD bus width for wide operation
    if (HAL_SD_WideBusOperation_Config(&sd_handle, SDIO_BUS_WIDE_4B) != SD_OK) {
        HAL_SD_DeInit(&sd_handle);
        goto error;
    }

    return true;

error:
    sd_handle.Instance = NULL;
    return false;
}
void sdcard_init(void)
{
    volatile int retry=10;
    HAL_SD_CardInfoTypedef cardinfo;

    // SDIO configuration
    SDHandle.Instance                 = SDIO;
    SDHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
    SDHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
    SDHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
    SDHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
    SDHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
    SDHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV; //INIT_CLK_DIV will be used first

    // Deinit SD
    HAL_SD_DeInit(&SDHandle);
    // Init SD interface
    while(HAL_SD_Init(&SDHandle, &cardinfo) != SD_OK && retry--) {
        if (retry == 0) {
            __fatal_error("Failed to init sdcard: init timeout");
        }
        systick_sleep(100);
    }

    /* Configure the SD Card in wide bus mode. */
    if (HAL_SD_WideBusOperation_Config(&SDHandle, SDIO_BUS_WIDE_4B) != SD_OK) {
        __fatal_error("Failed to init sensor, sdcard: config wide bus");
    }

    // Configure and enable DMA IRQ Channel
    // SDIO IRQ should have a higher priority than DMA IRQ because it needs to
    // preempt the DMA irq handler to set a flag indicating the end of transfer.
    HAL_NVIC_SetPriority(SDIO_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
    HAL_NVIC_EnableIRQ(SDIO_IRQn);
}
/**
  * @brief  Initializes the SD card device.
  * @retval SD status
  */
uint8_t BSP_SD_Init(void)
{
  uint8_t sd_state = MSD_OK;

  /* PLLSAI is dedicated to LCD periph. Do not use it to get 48MHz*/

  /* uSD device interface configuration */
  uSdHandle.Instance = SDIO;

  uSdHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
  uSdHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
  uSdHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
  uSdHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
  uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
  uSdHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;

  /* Configure IO functionalities for SD detect pin */
  BSP_IO_Init();

  /* Check if the SD card is plugged in the slot */
  BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_INPUT_PU);
  if(BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR_SD_NOT_PRESENT;
  }
  
  /* Msp SD initialization */
  BSP_SD_MspInit(&uSdHandle, NULL);

  /* HAL SD initialization */
  if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK)
  {
    sd_state = MSD_ERROR;
  }

  /* Configure SD Bus width */
  if(sd_state == MSD_OK)
  {
    /* Enable wide operation */
    if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK)
    {
      sd_state = MSD_ERROR;
    }
    else
    {
      sd_state = MSD_OK;
    }
  }
  return  sd_state;
}
Beispiel #5
0
/* SDMMC1 init function */
void MX_SDMMC1_SD_Init(void)
{

  hsd1.Instance = SDMMC1;
  hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
  hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B;
  hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd1.Init.ClockDiv = 0;
  HAL_SD_Init(&hsd1, &SDCardInfo1);

  HAL_SD_WideBusOperation_Config(&hsd1, SDMMC_BUS_WIDE_4B);

}
/**
  * @brief  Initializes the SD card device.
  * @retval SD status
  */
uint8_t BSP_SD_Init(void)
{ 
  uint8_t sd_state = MSD_OK;
  
  /* uSD device interface configuration */
  uSdHandle.Instance = SDIO;

  uSdHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
  uSdHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
  uSdHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
  uSdHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
  uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE;
  uSdHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;
  
  /* Msp SD Detect pin initialization */
  BSP_SD_Detect_MspInit(&uSdHandle, NULL);
  
  /* Check if SD card is present */
  if(BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR_SD_NOT_PRESENT;
  }
  
  /* Msp SD initialization */
  BSP_SD_MspInit(&uSdHandle, NULL);

  /* HAL SD initialization */
  if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK)
  {
    sd_state = MSD_ERROR;
  }
  
  /* Configure SD Bus width */
  if(sd_state == MSD_OK)
  {
    /* Enable wide operation */
    if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK)
    {
      sd_state = MSD_ERROR;
    }
    else
    {
      sd_state = MSD_OK;
    }
  }
  
  return  sd_state;
}
/**
  * @brief  Initializes the SD card device.
  * @param  None
  * @retval SD status.
  */
uint8_t BSP_SD_Init(void)
{ 
  uint8_t SD_state = MSD_OK;
  
  /* uSD device interface configuration */
  uSdHandle.Instance = SDIO;

  uSdHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
  uSdHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
  uSdHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
  uSdHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
  uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  uSdHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;
  
  /* Configure IO functionalities for SD detect pin */
  BSP_IO_Init(); 
  
  /* Check if the SD card is plugged in the slot */
  if(BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR;
  }
  
  /* HAL SD initialization */
  SD_MspInit();
  if(HAL_SD_Init(&uSdHandle, &SD_CardInfo) != SD_OK)
  {
    SD_state = MSD_ERROR;
  }
  
  /* Configure SD Bus width */
  if(SD_state == MSD_OK)
  {
    /* Enable wide operation */
    if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK)
    {
      SD_state = MSD_ERROR;
    }
    else
    {
      SD_state = MSD_OK;
    }
  }
  
  return  SD_state;
}
Beispiel #8
0
/**
  * @brief  Initializes the SD card device.
  * @param  None
  * @retval SD status
  */
uint8_t BSP_SD_Init(void)
{
  uint8_t SD_state = MSD_OK;
  /* Check if the SD card is plugged in the slot */
  if (BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR;
  }
  SD_state = HAL_SD_Init(&hsd, &SDCardInfo);
#ifdef BUS_4BITS
  if (SD_state == MSD_OK)
  {
    if (HAL_SD_WideBusOperation_Config(&hsd, SDIO_BUS_WIDE_4B) != SD_OK)
    {
      SD_state = MSD_ERROR;
    }
    else
    {
      SD_state = MSD_OK;
    }
  }
#endif
  return SD_state;
}
Beispiel #9
0
//{{{
uint8_t SD_Init() {

  //{{{  sdDetect init
  SD_DETECT_GPIO_CLK_ENABLE();

  GPIO_InitTypeDef  gpio_init_structure;
  gpio_init_structure.Pin       = SD_DETECT_PIN;
  gpio_init_structure.Mode      = GPIO_MODE_INPUT;
  gpio_init_structure.Pull      = GPIO_PULLUP;
  gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
  HAL_GPIO_Init (SD_DETECT_GPIO_PORT, &gpio_init_structure);
  //}}}
  uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
  uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
  uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
   uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;
  uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;

   __HAL_RCC_DMA2_CLK_ENABLE();

  // sd interrupt
  #ifdef STM32F746G_DISCO
    uSdHandle.Instance = SDMMC1;
    __HAL_RCC_SDMMC1_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    //{{{  gpio init
    gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
    gpio_init_structure.Pull      = GPIO_PULLUP;
    gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
    gpio_init_structure.Alternate = GPIO_AF12_SDMMC1;

    gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
    HAL_GPIO_Init (GPIOC, &gpio_init_structure);

    gpio_init_structure.Pin = GPIO_PIN_2;
    HAL_GPIO_Init (GPIOD, &gpio_init_structure);
    //}}}
    //{{{  DMA rx parameters
    dma_rx_handle.Instance                 = DMA2_Stream3;
    dma_rx_handle.Init.Channel             = DMA_CHANNEL_4;
    dma_rx_handle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    dma_rx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
    dma_rx_handle.Init.MemInc              = DMA_MINC_ENABLE;
    dma_rx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    dma_rx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    dma_rx_handle.Init.Mode                = DMA_PFCTRL;
    dma_rx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
    dma_rx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
    dma_rx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    dma_rx_handle.Init.MemBurst            = DMA_MBURST_INC4;
    dma_rx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;

    __HAL_LINKDMA (&uSdHandle, hdmarx, dma_rx_handle);
    HAL_DMA_DeInit (&dma_rx_handle);
    HAL_DMA_Init (&dma_rx_handle);
    //}}}
    //{{{  DMA tx parameters
    dma_tx_handle.Instance                 = DMA2_Stream6;
    dma_tx_handle.Init.Channel             = DMA_CHANNEL_4;
    dma_tx_handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    dma_tx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
    dma_tx_handle.Init.MemInc              = DMA_MINC_ENABLE;
    dma_tx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    dma_tx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    dma_tx_handle.Init.Mode                = DMA_PFCTRL;
    dma_tx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
    dma_tx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
    dma_tx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    dma_tx_handle.Init.MemBurst            = DMA_MBURST_INC4;
    dma_tx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;

    __HAL_LINKDMA (&uSdHandle, hdmatx, dma_tx_handle);
    HAL_DMA_DeInit (&dma_tx_handle);
    HAL_DMA_Init (&dma_tx_handle);
    //}}}
    HAL_NVIC_SetPriority (SDMMC1_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ (SDMMC1_IRQn);
    HAL_NVIC_SetPriority (DMA2_Stream3_IRQn, 6, 0);  // f for 769
    HAL_NVIC_EnableIRQ (DMA2_Stream3_IRQn);
    HAL_NVIC_SetPriority (DMA2_Stream6_IRQn, 6, 0);  // f for 769
    HAL_NVIC_EnableIRQ (DMA2_Stream6_IRQn);
  #else
    uSdHandle.Instance = SDMMC2;
    __HAL_RCC_SDMMC2_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOG_CLK_ENABLE();
    //{{{  gpio init
    gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
    gpio_init_structure.Pull      = GPIO_PULLUP;
    gpio_init_structure.Speed     = GPIO_SPEED_HIGH;

    gpio_init_structure.Alternate = GPIO_AF10_SDMMC2;
    gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_4;
    HAL_GPIO_Init (GPIOB, &gpio_init_structure);

    gpio_init_structure.Alternate = GPIO_AF11_SDMMC2;
    gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
    HAL_GPIO_Init (GPIOD, &gpio_init_structure);

    gpio_init_structure.Pin = GPIO_PIN_9 | GPIO_PIN_10;
    HAL_GPIO_Init (GPIOG, &gpio_init_structure);
    //}}}
    //{{{  DMA rx parameters
    dma_rx_handle.Instance                 = DMA2_Stream0;
    dma_rx_handle.Init.Channel             = DMA_CHANNEL_11;
    dma_rx_handle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    dma_rx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
    dma_rx_handle.Init.MemInc              = DMA_MINC_ENABLE;
    dma_rx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    dma_rx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    dma_rx_handle.Init.Mode                = DMA_PFCTRL;
    dma_rx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
    dma_rx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
    dma_rx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    dma_rx_handle.Init.MemBurst            = DMA_MBURST_INC4;
    dma_rx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;

    __HAL_LINKDMA (&uSdHandle, hdmarx, dma_rx_handle);
    HAL_DMA_DeInit (&dma_rx_handle);
    HAL_DMA_Init (&dma_rx_handle);
    //}}}
    //{{{  DMA tx parameters
    dma_tx_handle.Instance                 = DMA2_Stream5;
    dma_tx_handle.Init.Channel             = DMA_CHANNEL_11;
    dma_tx_handle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    dma_tx_handle.Init.PeriphInc           = DMA_PINC_DISABLE;
    dma_tx_handle.Init.MemInc              = DMA_MINC_ENABLE;
    dma_tx_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    dma_tx_handle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    dma_tx_handle.Init.Mode                = DMA_PFCTRL;
    dma_tx_handle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
    dma_tx_handle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
    dma_tx_handle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    dma_tx_handle.Init.MemBurst            = DMA_MBURST_INC4;
    dma_tx_handle.Init.PeriphBurst         = DMA_PBURST_INC4;

    __HAL_LINKDMA (&uSdHandle, hdmatx, dma_tx_handle);
    HAL_DMA_DeInit (&dma_tx_handle);
    HAL_DMA_Init (&dma_tx_handle);
    //}}}
    HAL_NVIC_SetPriority (SDMMC2_IRQn, 0x5, 0);  //e
    HAL_NVIC_EnableIRQ (SDMMC2_IRQn);
    HAL_NVIC_SetPriority (DMA2_Stream0_IRQn, 0x6, 0); //f
    HAL_NVIC_EnableIRQ (DMA2_Stream0_IRQn);
    HAL_NVIC_SetPriority (DMA2_Stream5_IRQn, 0x6, 0);  // f
    HAL_NVIC_EnableIRQ (DMA2_Stream5_IRQn);
  #endif

  // HAL SD initialization
  if (HAL_SD_Init (&uSdHandle, &uSdCardInfo) != SD_OK)
    return MSD_ERROR;
  if (HAL_SD_WideBusOperation_Config (&uSdHandle, SDMMC_BUS_WIDE_4B) != SD_OK)
    return MSD_ERROR;
  if (HAL_SD_HighSpeed (&uSdHandle) != SD_OK)
    return MSD_ERROR;

  //osMutexDef (sdMutex);
  //mSdMutex = osMutexCreate (osMutex (sdMutex));

  mReadCache = (uint8_t*)pvPortMalloc (512 * mReadCacheSize);

  return MSD_OK;
  }
/**
  * @brief  Initializes the SD card device.
  * @param  SdCard: SD card to be used, that should be SD_CARD1 or SD_CARD2 
  * @retval SD status
  */
uint8_t BSP_SD_InitEx(uint32_t SdCard)
{ 
  uint8_t sd_state = MSD_OK;
  
  /* uSD device interface configuration */
  if(SdCard == SD_CARD1)
  {  
    uSdHandle.Instance = SDMMC1;
    uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
    uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
    uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
    uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;
    uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
    uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;
  }
  else
  {
    uSdHandle2.Instance = SDMMC2;
    uSdHandle2.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
    uSdHandle2.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
    uSdHandle2.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
    uSdHandle2.Init.BusWide             = SDMMC_BUS_WIDE_1B;
    uSdHandle2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
    uSdHandle2.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;    
  }
  /* Initialize IO functionalities (MFX) used by SD detect pin */
  BSP_IO_Init(); 
  
  /* Check if the SD card is plugged in the slot */
  if(SdCard == SD_CARD1)
  {
    BSP_IO_ConfigPin(SD1_DETECT_PIN, IO_MODE_INPUT_PU);
    if(BSP_SD_IsDetectedEx(SD_CARD1) != SD_PRESENT)
    {
      return MSD_ERROR_SD_NOT_PRESENT;
    }  
    /* Msp SD initialization */
    BSP_SD_MspInit(&uSdHandle, NULL);
    
    /* HAL SD initialization */
    if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK)
    {
      sd_state = MSD_ERROR;
    }  
  }
  else
  {
    BSP_IO_ConfigPin(SD2_DETECT_PIN, IO_MODE_INPUT_PU);
    
    if(BSP_SD_IsDetectedEx(SD_CARD2) != SD_PRESENT)
    {
      return MSD_ERROR_SD_NOT_PRESENT;
    }
    
    /* Msp SD initialization */
    BSP_SD_MspInit(&uSdHandle2, NULL);
    
    /* HAL SD initialization */
    if(HAL_SD_Init(&uSdHandle2, &uSdCardInfo) != SD_OK)
    {
      sd_state = MSD_ERROR;
    }    
  }
  
  
  /* Configure SD Bus width */
  if(sd_state == MSD_OK)
  {
    if(SdCard == SD_CARD1)
    {    
      /* Enable wide operation */
      sd_state = HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_4B); 
    }
    else
    {
      /* Enable wide operation */    
      sd_state = HAL_SD_WideBusOperation_Config(&uSdHandle2, SDMMC_BUS_WIDE_4B);
    }
    if(sd_state != SD_OK)
    {
      sd_state = MSD_ERROR;
    }
    else
    {
      sd_state = MSD_OK;
    }
  }
  
  return  sd_state;
}
/**
  * @brief  Initializes the SD card device.
  * @param  None
  * @retval SD status
  */
uint8_t BSP_SD_Init(void) { 
	uint8_t SD_state = MSD_OK;

	/* uSD device interface configuration */
#if defined(SDIO)
	uSdHandle.Instance = SDIO;

	uSdHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
	uSdHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
	uSdHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
	uSdHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
	uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
	uSdHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV;
#elif defined(SDMMC1)
	uSdHandle.Instance = SDMMC1;

	uSdHandle.Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
	uSdHandle.Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
	uSdHandle.Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
	uSdHandle.Init.BusWide             = SDMMC_BUS_WIDE_1B;
	uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
	uSdHandle.Init.ClockDiv            = SDMMC_TRANSFER_CLK_DIV;	
#else
#error "NOT SUPPORTED!"
#endif

	/* Init GPIO, DMA and NVIC */
	SD_MspInit();

	/* Check if the SD card is plugged in the slot */
	if (BSP_SD_IsDetected() != SD_PRESENT) {
		return MSD_ERROR;
	}

	/* HAL SD initialization */
	if (HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK) {
		SD_state = MSD_ERROR;
	}

	/* Configure SD Bus width */
	if (SD_state == MSD_OK) {
		/* Enable wide operation */
#if defined(SDIO_BUS_WIDE_4B)
#if FATFS_SDIO_4BIT == 1
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) {
#else
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_1B) != SD_OK) {	
#endif
#else
#if FATFS_SDIO_4BIT == 1
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_4B) != SD_OK) {
#else
		if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_1B) != SD_OK) {	
#endif
#endif
			SD_state = MSD_ERROR;
		} else {
			SD_state = MSD_OK;
		}
	}

	return  SD_state;
}

/**
 * @brief  Detects if SD card is correctly plugged in the memory slot or not.
 * @param  None
 * @retval Returns if SD is detected or not
 */
uint8_t BSP_SD_IsDetected(void) {
	return SDCARD_IsDetected();
}

/**
 * @brief  Detects if SD card is write protected
 * @param  None
 * @retval Returns if SD is write protected or not.
 */
uint8_t BSP_SD_IsWriteProtected(void) {
	return !SDCARD_IsWriteEnabled();
}

/**
  * @brief  Reads block(s) from a specified address in an SD card, in polling mode.
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  ReadAddr: Address from where data is to be read  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to read 
  * @retval SD status
  */
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	if (HAL_SD_ReadBlocks(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) {
		return MSD_ERROR;
	}
	
	return MSD_OK;
}

/**
  * @brief  Writes block(s) to a specified address in an SD card, in polling mode. 
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  WriteAddr: Address from where data is to be written  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to write
  * @retval SD status
  */
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	if (HAL_SD_WriteBlocks(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) {
		return MSD_ERROR;
	}
	
	return MSD_OK;
}

/**
  * @brief  Reads block(s) from a specified address in an SD card, in DMA mode.
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  ReadAddr: Address from where data is to be read  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to read 
  * @retval SD status
  */
uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	uint8_t SD_state = MSD_OK;

	/* Read block(s) in DMA transfer mode */
	if (HAL_SD_ReadBlocks_DMA(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) {
		SD_state = MSD_ERROR;
	}

	/* Wait until transfer is complete */
	if (SD_state == MSD_OK) {
		if (HAL_SD_CheckReadOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK) {
			SD_state = MSD_ERROR;
		} else {
			SD_state = MSD_OK;
		}
	}

	return SD_state; 
}

/**
  * @brief  Writes block(s) to a specified address in an SD card, in DMA mode.
  * @param  pData: Pointer to the buffer that will contain the data to transmit
  * @param  WriteAddr: Address from where data is to be written  
  * @param  BlockSize: SD card data block size, that should be 512
  * @param  NumOfBlocks: Number of SD blocks to write 
  * @retval SD status
  */
uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) {
	uint8_t SD_state = MSD_OK;

	/* Write block(s) in DMA transfer mode */
	if (HAL_SD_WriteBlocks_DMA(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) {
		SD_state = MSD_ERROR;
	}

	/* Wait until transfer is complete */
	if (SD_state == MSD_OK) {
		if(HAL_SD_CheckWriteOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK) {
			SD_state = MSD_ERROR;
		} else {
			SD_state = MSD_OK;
		}
	}

	return SD_state;  
}

/**
  * @brief  Erases the specified memory area of the given SD card. 
  * @param  StartAddr: Start byte address
  * @param  EndAddr: End byte address
  * @retval SD status
  */
uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr) {
	if (HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != SD_OK) {
		return MSD_ERROR;
	}
	
	return MSD_OK;
}

/**
  * @brief  Initializes the SD MSP.
  * @param  None
  * @retval None
  */
static void SD_MspInit(void) {
	static DMA_HandleTypeDef dmaRxHandle;
	static DMA_HandleTypeDef dmaTxHandle;
	SD_HandleTypeDef *hsd = &uSdHandle;
	uint16_t gpio_af;
	
	/* Get GPIO alternate function */
#if defined(GPIO_AF12_SDIO)
	gpio_af = GPIO_AF12_SDIO;
#endif
#if defined(GPIO_AF12_SDMMC1)
	gpio_af = GPIO_AF12_SDMMC1;
#endif
	
	/* Enable SDIO clock */
	__HAL_RCC_SDIO_CLK_ENABLE();

	/* Enable DMA2 clocks */
	__DMAx_TxRx_CLK_ENABLE();

	/* Detect pin, write protect pin */
#if FATFS_USE_DETECT_PIN > 0
	TM_GPIO_Init(FATFS_DETECT_PORT, FATFS_DETECT_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
#endif
#if FATFS_USE_WRITEPROTECT_PIN > 0
	TM_GPIO_Init(FATFS_WRITEPROTECT_PORT, FATFS_WRITEPROTECT_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low);
#endif
	
	/* SDIO/SDMMC pins */
#if FATFS_SDIO_4BIT == 1
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af);
#else
	TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_8 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af);
#endif
	TM_GPIO_InitAlternate(GPIOD, GPIO_PIN_2, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af);

	/* NVIC configuration for SDIO interrupts */
	HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0);
	HAL_NVIC_EnableIRQ(SDIO_IRQn);

	/* Configure DMA Rx parameters */
	dmaRxHandle.Init.Channel             = SD_DMAx_Rx_CHANNEL;
	dmaRxHandle.Init.Direction           = DMA_PERIPH_TO_MEMORY;
	dmaRxHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
	dmaRxHandle.Init.MemInc              = DMA_MINC_ENABLE;
	dmaRxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
	dmaRxHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
	dmaRxHandle.Init.Mode                = DMA_PFCTRL;
	dmaRxHandle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
	dmaRxHandle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
	dmaRxHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
	dmaRxHandle.Init.MemBurst            = DMA_MBURST_INC4;
	dmaRxHandle.Init.PeriphBurst         = DMA_PBURST_INC4;

	dmaRxHandle.Instance = SD_DMAx_Rx_STREAM;

	/* Associate the DMA handle */
	__HAL_LINKDMA(hsd, hdmarx, dmaRxHandle);

	/* Deinitialize the stream for new transfer */
	HAL_DMA_DeInit(&dmaRxHandle);

	/* Configure the DMA stream */
	HAL_DMA_Init(&dmaRxHandle);

	/* Configure DMA Tx parameters */
	dmaTxHandle.Init.Channel             = SD_DMAx_Tx_CHANNEL;
	dmaTxHandle.Init.Direction           = DMA_MEMORY_TO_PERIPH;
	dmaTxHandle.Init.PeriphInc           = DMA_PINC_DISABLE;
	dmaTxHandle.Init.MemInc              = DMA_MINC_ENABLE;
	dmaTxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
	dmaTxHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
	dmaTxHandle.Init.Mode                = DMA_PFCTRL;
	dmaTxHandle.Init.Priority            = DMA_PRIORITY_VERY_HIGH;
	dmaTxHandle.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
	dmaTxHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
	dmaTxHandle.Init.MemBurst            = DMA_MBURST_INC4;
	dmaTxHandle.Init.PeriphBurst         = DMA_PBURST_INC4;

	dmaTxHandle.Instance = SD_DMAx_Tx_STREAM;

	/* Associate the DMA handle */
	__HAL_LINKDMA(hsd, hdmatx, dmaTxHandle);

	/* Deinitialize the stream for new transfer */
	HAL_DMA_DeInit(&dmaTxHandle);

	/* Configure the DMA stream */
	HAL_DMA_Init(&dmaTxHandle); 

	/* NVIC configuration for DMA transfer complete interrupt */
	HAL_NVIC_SetPriority(SD_DMAx_Rx_IRQn, 6, 0);
	HAL_NVIC_EnableIRQ(SD_DMAx_Rx_IRQn);

	/* NVIC configuration for DMA transfer complete interrupt */
	HAL_NVIC_SetPriority(SD_DMAx_Tx_IRQn, 6, 0);
	HAL_NVIC_EnableIRQ(SD_DMAx_Tx_IRQn);
}


/**
  * @brief  Get SD information about specific SD card.
  * @param  CardInfo: Pointer to HAL_SD_CardInfoTypedef structure
  * @retval None 
  */
void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo) {
	/* Get SD card Information */
	HAL_SD_Get_CardInfo(&uSdHandle, CardInfo);
}
Beispiel #12
0
bool sdInit() {
    /* Enable SDIO clock */
    __HAL_RCC_SDIO_CLK_ENABLE();

    /* Enable DMA2 clocks */
    SD_DMAx_TxRx_CLK_ENABLE();

    /* Enable GPIOs clock */
    __GPIOC_CLK_ENABLE(); // sd data lines PC8..PC12
    __GPIOD_CLK_ENABLE(); // cmd line D2
    __GPIOB_CLK_ENABLE(); // pin detect

    /* Common GPIO configuration */
    GPIO_InitTypeDef GPIO_Init_Structure = { 0 };
    GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP;
    GPIO_Init_Structure.Pull = GPIO_PULLUP;
    GPIO_Init_Structure.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_Init_Structure.Alternate = GPIO_AF12_SDIO;

    /* GPIOC configuration */
    GPIO_Init_Structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
    HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure);

    /* GPIOD configuration */
    GPIO_Init_Structure.Pin = GPIO_PIN_2;
    HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure);

    /* SD Card detect pin configuration */
    GPIO_Init_Structure.Mode = GPIO_MODE_INPUT;
    GPIO_Init_Structure.Pull = GPIO_PULLUP;
    GPIO_Init_Structure.Speed = GPIO_SPEED_LOW;
    GPIO_Init_Structure.Pin = 8;
    HAL_GPIO_Init(GPIOB, &GPIO_Init_Structure);

    /* Initialize SD interface
     * Note HW flow control must be disabled on STM32f415 due to hardware glitches on the SDIOCLK
     * line. See errata:
     *
     * "When enabling the HW flow control by setting bit 14 of the SDIO_CLKCR register to ‘1’,
     * glitches can occur on the SDIOCLK output clock resulting in wrong data to be written
     * into the SD/MMC card or into the SDIO device. As a consequence, a CRC error will be
     * reported to the SD/SDIO MMC host interface (DCRCFAIL bit set to ‘1’ in SDIO_STA register)."
     **/
    uSdHandle.Instance = SDIO;
    uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
    uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
    uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
    uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B;
    uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
    uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV;

    HAL_SD_ErrorTypedef status;
    if ((status = HAL_SD_Init(&uSdHandle, &uSdCardInfo)) != SD_OK) {
        error("Failed to init sd: status=%d\n", status);
        return false;
    }

    if ((status = HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B)) != SD_OK) {
        error("Failed to init wide bus mode, status=%d\n", status);
        return false;
    }

    /* NVIC configuration for SDIO interrupts */
    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
    HAL_NVIC_SetPriority(SDIO_IRQn, SD_NVIC_PRIORITY, 0);
    HAL_NVIC_EnableIRQ(SDIO_IRQn);

    // try high speed mode
    if ((status = HAL_SD_HighSpeed(&uSdHandle)) != SD_OK) {
        error("Failed to set high speed mode, status=%d\n", status);
        MatchBox::blinkOfDeath(*led, (MatchBox::BlinkCode) SDIO_HS_MODE);
    }

    return true;
}