void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct; if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspInit 0 */ /* USER CODE END SDIO_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDIO_CLK_ENABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 |GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* Peripheral DMA init*/ hdma_sdio.Instance = DMA2_Channel4; hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio.Init.Mode = DMA_NORMAL; hdma_sdio.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_Init(&hdma_sdio); /* Several peripheral DMA handle pointers point to the same DMA handle. Be aware that there is only one channel to perform all the requested DMAs. */ /* Be sure to change transfer direction before calling HAL_SD_ReadBlocks_DMA or HAL_SD_WriteBlocks_DMA. */ __HAL_LINKDMA(hsd,hdmarx,hdma_sdio); __HAL_LINKDMA(hsd,hdmatx,hdma_sdio); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0); HAL_NVIC_EnableIRQ(SDIO_IRQn); /* USER CODE BEGIN SDIO_MspInit 1 */ /* USER CODE END SDIO_MspInit 1 */ } }
void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct; if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspInit 0 */ /* USER CODE END SDIO_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDIO_CLK_ENABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 |GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SDIO_IRQn); /* USER CODE BEGIN SDIO_MspInit 1 */ /* USER CODE END SDIO_MspInit 1 */ } }
/** * @brief Initializes the SD MSP. * @retval None */ static void SD_MspInit(void) { GPIO_InitTypeDef gpioinitstruct = {0}; /* Enable SDIO clock */ __HAL_RCC_SDIO_CLK_ENABLE(); /* Enable DMA2 clocks */ __DMAx_TxRx_CLK_ENABLE(); /* Enable GPIOs clock */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __SD_DETECT_GPIO_CLK_ENABLE(); /* Common GPIO configuration */ gpioinitstruct.Mode = GPIO_MODE_AF_PP; gpioinitstruct.Pull = GPIO_PULLUP; gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; gpioinitstruct.Alternate = GPIO_AF12_SDIO; /* GPIOC configuration */ gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; HAL_GPIO_Init(GPIOC, &gpioinitstruct); /* GPIOD configuration */ gpioinitstruct.Pin = GPIO_PIN_2; HAL_GPIO_Init(GPIOD, &gpioinitstruct); /* SD Card detect pin configuration */ gpioinitstruct.Mode = GPIO_MODE_INPUT; gpioinitstruct.Pull = GPIO_PULLUP; gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; gpioinitstruct.Pin = SD_DETECT_PIN; HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &gpioinitstruct); /* NVIC configuration for SDIO interrupts */ HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0); HAL_NVIC_EnableIRQ(SDIO_IRQn); /* DMA initialization should be done here but , as there is only one channel for RX and TX it is configured and done directly when required*/ }
/** * @brief SD MSP Initialization * This function configures the hardware resources used in this example * @param hsd: SD handle pointer * @retval None */ void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspInit 0 */ /* USER CODE END SDIO_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDIO_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 |GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* USER CODE BEGIN SDIO_MspInit 1 */ /* USER CODE END SDIO_MspInit 1 */ } }
void HAL_SD_MspInit(SD_HandleTypeDef* hsd) { GPIO_InitTypeDef GPIO_InitStruct; if(hsd->Instance==SDIO) { /* USER CODE BEGIN SDIO_MspInit 0 */ /* USER CODE END SDIO_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SDIO_CLK_ENABLE(); /**SDIO GPIO Configuration PC8 ------> SDIO_D0 PC9 ------> SDIO_D1 PC10 ------> SDIO_D2 PC11 ------> SDIO_D3 PC12 ------> SDIO_CK PD2 ------> SDIO_CMD */ GPIO_InitStruct.Pin = SDIO_SD1_D0_Pin|SDIO_SD1_D1_Pin|SDIO_SD1_D2_Pin|SDIO_SD1_D3_Pin |SDIO_SD1_CK_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = SDIO_SD1_CMD_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; HAL_GPIO_Init(SDIO_SD1_CMD_GPIO_Port, &GPIO_InitStruct); /* Peripheral DMA init*/ hdma_sdio_rx.Instance = DMA2_Stream3; hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4; hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio_rx.Init.Mode = DMA_PFCTRL; hdma_sdio_rx.Init.Priority = DMA_PRIORITY_LOW; hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4; hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx); hdma_sdio_tx.Instance = DMA2_Stream6; hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4; hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_sdio_tx.Init.Mode = DMA_PFCTRL; hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4; hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SDIO_IRQn); /* USER CODE BEGIN SDIO_MspInit 1 */ /* USER CODE END SDIO_MspInit 1 */ } }
/** * @brief Initializes the SD MSP. * @param hsd: SD handle * @param Params : pointer on additional configuration parameters, can be NULL. */ __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params) { static DMA_HandleTypeDef dma_rx_handle; static DMA_HandleTypeDef dma_tx_handle; GPIO_InitTypeDef gpio_init_structure; /* Enable SDIO clock */ __HAL_RCC_SDIO_CLK_ENABLE(); /* Enable DMA2 clocks */ __DMAx_TxRx_CLK_ENABLE(); /* Enable GPIOs clock */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /* Common GPIO configuration */ 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_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); /* NVIC configuration for SDIO interrupts */ //HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0); //HAL_NVIC_EnableIRQ(SDIO_IRQn); /* Configure DMA Rx parameters */ dma_rx_handle.Init.Channel = SD_DMAx_Rx_CHANNEL; 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; dma_rx_handle.Instance = SD_DMAx_Rx_STREAM; /* Associate the DMA handle */ __HAL_LINKDMA(hsd, hdmarx, dma_rx_handle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dma_rx_handle); /* Configure the DMA stream */ HAL_DMA_Init(&dma_rx_handle); /* Configure DMA Tx parameters */ dma_tx_handle.Init.Channel = SD_DMAx_Tx_CHANNEL; 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; dma_tx_handle.Instance = SD_DMAx_Tx_STREAM; /* Associate the DMA handle */ __HAL_LINKDMA(hsd, hdmatx, dma_tx_handle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dma_tx_handle); /* Configure the DMA stream */ HAL_DMA_Init(&dma_tx_handle); /* 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 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); }
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; }