forked from MarlinFirmware/Marlin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
STM32duino - Use SDIO for onboard SD (MarlinFirmware#16756)
- Loading branch information
1 parent
38a9706
commit 0268c1d
Showing
21 changed files
with
486 additions
and
461 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
/** | ||
* Marlin 3D Printer Firmware | ||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] | ||
* | ||
* Based on Sprinter and grbl. | ||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
#include "../../inc/MarlinConfig.h" | ||
|
||
#if ENABLED(SDIO_SUPPORT) && !defined(STM32GENERIC) | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
//#include "SdMscDriver.h" | ||
|
||
//#include "usbd_msc_bot.h" | ||
//#include "usbd_msc_scsi.h" | ||
//#include "usbd_msc_composite.h" | ||
//#include "usbd_msc_cdc_composite.h" | ||
|
||
//#include "usbd_msc_data.h" | ||
|
||
#if defined(STM32F103xE) || defined(STM32F103xG) | ||
#include <stm32f1xx_hal_rcc_ex.h> | ||
#include <stm32f1xx_hal_sd.h> | ||
#elif defined(STM32F4xx) | ||
#include <stm32f4xx_hal_rcc.h> | ||
#include <stm32f4xx_hal_dma.h> | ||
#include <stm32f4xx_hal_gpio.h> | ||
#include <stm32f4xx_hal_sd.h> | ||
#elif defined(STM32F7xx) | ||
#include <stm32f7xx_hal_rcc.h> | ||
#include <stm32f7xx_hal_dma.h> | ||
#include <stm32f7xx_hal_gpio.h> | ||
#include <stm32f7xx_hal_sd.h> | ||
#else | ||
#error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported" | ||
#endif | ||
|
||
SD_HandleTypeDef hsd; // create SDIO structure | ||
|
||
#define TRANSFER_CLOCK_DIV ((uint8_t)SDIO_INIT_CLK_DIV/40) | ||
|
||
#ifndef USBD_OK | ||
#define USBD_OK 0 | ||
#endif | ||
|
||
void go_to_transfer_speed() { | ||
|
||
SD_InitTypeDef Init; | ||
|
||
/* Default SDIO peripheral configuration for SD card initialization */ | ||
Init.ClockEdge = hsd.Init.ClockEdge; | ||
Init.ClockBypass = hsd.Init.ClockBypass; | ||
Init.ClockPowerSave = hsd.Init.ClockPowerSave; | ||
Init.BusWide = hsd.Init.BusWide; | ||
Init.HardwareFlowControl = hsd.Init.HardwareFlowControl; | ||
Init.ClockDiv = TRANSFER_CLOCK_DIV; | ||
|
||
/* Initialize SDIO peripheral interface with default configuration */ | ||
SDIO_Init(hsd.Instance, Init); | ||
} | ||
|
||
void SD_LowLevel_Init(void) { | ||
|
||
uint32_t tempreg; | ||
|
||
GPIO_InitTypeDef GPIO_InitStruct; | ||
|
||
__HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks | ||
__HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks | ||
|
||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK | ||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; | ||
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; | ||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; | ||
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; | ||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | ||
|
||
#if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // define D1-D3 only if have a four bit wide SDIO bus | ||
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3 | ||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; | ||
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL; | ||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; | ||
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO; | ||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | ||
#endif | ||
|
||
// Configure PD.02 CMD line | ||
GPIO_InitStruct.Pin = GPIO_PIN_2; | ||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); | ||
|
||
RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset | ||
RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock | ||
|
||
// Enable the DMA2 Clock | ||
|
||
//Initialize the SDIO (with initial <400Khz Clock) | ||
tempreg = 0; //Reset value | ||
tempreg |= SDIO_CLKCR_CLKEN; //Clock is enabled | ||
tempreg |= (uint32_t)0x76; //Clock Divider. Clock = 48000/(118+2) = 400Khz | ||
//Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable | ||
SDIO->CLKCR = tempreg; | ||
|
||
//Power up the SDIO | ||
SDIO->POWER = 0x03; | ||
} | ||
|
||
|
||
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init | ||
UNUSED(hsd); /* Prevent unused argument(s) compilation warning */ | ||
__HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock | ||
} | ||
|
||
constexpr uint8_t SD_RETRY_COUNT = (1 | ||
#if ENABLED(SD_CHECK_AND_RETRY) | ||
+ 2 | ||
#endif | ||
); | ||
|
||
bool SDIO_Init() { | ||
//init SDIO and get SD card info | ||
|
||
uint8_t retryCnt = SD_RETRY_COUNT; | ||
|
||
bool status; | ||
hsd.Instance = SDIO; | ||
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET | ||
SD_LowLevel_Init(); | ||
|
||
uint8_t retry_Cnt = retryCnt; | ||
for (;;) { | ||
status = (bool) HAL_SD_Init(&hsd); | ||
if (!status) break; | ||
if (!--retry_Cnt) return false; // return failing status if retries are exhausted | ||
} | ||
|
||
go_to_transfer_speed(); | ||
|
||
#if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // go to 4 bit wide mode if pins are defined | ||
retry_Cnt = retryCnt; | ||
for (;;) { | ||
if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required | ||
if (!--retry_Cnt) break; | ||
} | ||
if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode | ||
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET | ||
SD_LowLevel_Init(); | ||
retry_Cnt = retryCnt; | ||
for (;;) { | ||
status = (bool) HAL_SD_Init(&hsd); | ||
if (!status) break; | ||
if (!--retry_Cnt) return false; // return failing status if retries are exhausted | ||
} | ||
} | ||
#endif | ||
|
||
return true; | ||
} | ||
|
||
void init_SDIO_pins(void) { | ||
GPIO_InitTypeDef GPIO_InitStruct = {0}; | ||
|
||
/**SDIO GPIO Configuration | ||
PC8 ------> SDIO_D0 | ||
PC12 ------> SDIO_CK | ||
PD2 ------> SDIO_CMD | ||
*/ | ||
GPIO_InitStruct.Pin = GPIO_PIN_8; | ||
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_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); | ||
} | ||
|
||
//bool SDIO_init() { return (bool) (SD_SDIO_Init() ? 1 : 0);} | ||
//bool SDIO_Init_C() { return (bool) (SD_SDIO_Init() ? 1 : 0);} | ||
|
||
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) { | ||
bool status; | ||
|
||
hsd.Instance = SDIO; | ||
|
||
uint8_t retryCnt = SD_RETRY_COUNT; | ||
|
||
for (;;) { | ||
bool status = (bool) HAL_SD_ReadBlocks(&hsd, (uint8_t*)dst, block, 1, 1000); // read one 512 byte block with 500mS timeout | ||
status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK | ||
if (!status) return false; // return passing status | ||
if (!--retryCnt) return true; // return failing status if retries are exhausted | ||
} | ||
|
||
/* | ||
return (bool) ((status_read | status_card) ? 1 : 0); | ||
if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false; | ||
if (blockAddress >= SdCard.LogBlockNbr) return false; | ||
if ((0x03 & (uint32_t)data)) return false; // misaligned data | ||
if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; } | ||
if (!SDIO_CmdReadSingleBlock(blockAddress)) { | ||
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS); | ||
dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); | ||
return false; | ||
} | ||
while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {} | ||
dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL); | ||
if (SDIO->STA & SDIO_STA_RXDAVL) { | ||
while (SDIO->STA & SDIO_STA_RXDAVL) (void)SDIO->FIFO; | ||
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); | ||
return false; | ||
} | ||
if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) { | ||
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); | ||
return false; | ||
} | ||
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS); | ||
*/ | ||
|
||
return true; | ||
} | ||
|
||
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) { | ||
bool status; | ||
|
||
hsd.Instance = SDIO; | ||
|
||
uint8_t retryCnt = SD_RETRY_COUNT; | ||
|
||
for (;;) { | ||
status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout | ||
status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK | ||
if (!status) return (bool) status; // return passing status | ||
if (!--retryCnt) return (bool) status; // return failing status if retries are exhausted | ||
} | ||
} | ||
|
||
#endif // SDIO_SUPPORT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.