1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-12 19:10:32 +03:00

Merge pull request #10799 from hydra/bf-sdcard-fixes-2

This commit is contained in:
Michael Keller 2021-09-10 03:03:53 +12:00
parent 089cae0af1
commit 0bef24a579
6 changed files with 89 additions and 12 deletions

View file

@ -446,13 +446,13 @@ HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef*
// DC - See errata 2.11.4 - 8 SDMMC clock cycles must elapse before DTEN can be set.
// 32U below is used as a VERY rough guess that the SDMMC clock is 1/4 of the sytem clock, 8 * 4 = 32 and that the
// assembly below only takes 1 CPU cycle to run. All of which will be wrong, but right enough most of the time, especially
// when considering other processing overheads.
// loop code below only takes 2 CPU cycles to run. All of which will likely be wrong, but right enough most of the time.
// It's important that the code isn't optimized-out by the compiler or linker too, see
// https://stackoverflow.com/questions/7083482/how-to-prevent-gcc-from-optimizing-out-a-busy-wait-loop
register uint32_t count = 32U;
do
{
count--;
} while(count > 0);
for (unsigned i = 0; i < count; i++) {
__asm__ volatile("" : "+g" (i) : :);
}
// DC - See errata 2.11.4
/* Write to SDMMC DCTRL */

View file

@ -1654,7 +1654,7 @@ bool SD_GetState(void)
/** -----------------------------------------------------------------------------------------------------------------*/
bool SD_Init(void)
static bool SD_DoInit(void)
{
SD_Error_t ErrorState;
@ -1695,6 +1695,22 @@ bool SD_Init(void)
return ErrorState;
}
bool SD_Init(void)
{
static bool sdInitAttempted = false;
static SD_Error_t result = SD_ERROR;
if (sdInitAttempted) {
return result;
}
sdInitAttempted = true;
result = SD_DoInit();
return result;
}
/** -----------------------------------------------------------------------------------------------------------------*/
/**
* @brief This function handles SD card interrupt request.

View file

@ -1637,7 +1637,7 @@ bool SD_GetState(void)
/** -----------------------------------------------------------------------------------------------------------------*/
bool SD_Init(void)
static bool SD_DoInit(void)
{
SD_Error_t ErrorState;
@ -1674,6 +1674,23 @@ bool SD_Init(void)
return ErrorState;
}
bool SD_Init(void)
{
static bool sdInitAttempted = false;
static SD_Error_t result = SD_ERROR;
if (sdInitAttempted) {
return result;
}
sdInitAttempted = true;
result = SD_DoInit();
return result;
}
/** -----------------------------------------------------------------------------------------------------------------*/
/**
* @brief This function handles SD card interrupt request.

View file

@ -46,6 +46,9 @@ typedef struct SD_Handle_s
uint32_t CID[4]; // SD card identification number table
volatile uint32_t RXCplt; // SD RX Complete is equal 0 when no transfer
volatile uint32_t TXCplt; // SD TX Complete is equal 0 when no transfer
uint32_t RXErrors;
uint32_t TXErrors;
} SD_Handle_t;
SD_HandleTypeDef hsd1;
@ -54,7 +57,7 @@ SD_HandleTypeDef hsd1;
SD_CardInfo_t SD_CardInfo;
SD_CardType_t SD_CardType;
static SD_Handle_t SD_Handle;
SD_Handle_t SD_Handle;
typedef struct sdioPin_s {
ioTag_t pin;
@ -265,7 +268,7 @@ bool SD_GetState(void)
* The F4/F7 code actually returns an SD_Error_t if the card is detected
* SD_OK == 0, SD_* are non-zero and indicate errors. e.g. SD_ERROR = 42
*/
bool SD_Init(void)
static bool SD_DoInit(void)
{
bool failureResult = SD_ERROR; // FIXME fix the calling code, this false for success is bad.
bool successResult = false;
@ -524,6 +527,22 @@ SD_Error_t SD_GetCardInfo(void)
return ErrorState;
}
bool SD_Init(void)
{
static bool sdInitAttempted = false;
static SD_Error_t result = SD_ERROR;
if (sdInitAttempted) {
return result;
}
sdInitAttempted = true;
result = SD_DoInit();
return result;
}
SD_Error_t SD_CheckWrite(void) {
if (SD_Handle.TXCplt != 0) return SD_BUSY;
return SD_OK;
@ -620,6 +639,20 @@ void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, sdReadParameters.NumberOfBlocks * sdReadParameters.BlockSize + ((uint32_t)sdReadParameters.buffer - alignedAddr));
}
void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd)
{
UNUSED(hsd);
if (SD_Handle.RXCplt) {
SD_Handle.RXErrors++;
SD_Handle.RXCplt = 0;
}
if (SD_Handle.TXCplt) {
SD_Handle.TXErrors++;
SD_Handle.TXCplt = 0;
}
}
void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd)
{
UNUSED(hsd);

View file

@ -167,13 +167,17 @@ static int8_t STORAGE_Init (uint8_t lun)
LED0_OFF;
#ifdef USE_DMA_SPEC
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SDIO, 0, sdioConfig()->dmaopt);
#if defined(STM32H7) // H7 uses IDMA
SD_Initialize_LL(0);
#else
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SDIO, 0, sdioConfig()->dmaopt);
if (!dmaChannelSpec) {
return 1;
}
SD_Initialize_LL((DMA_ARCH_TYPE *)dmaChannelSpec->ref);
#endif
#else
SD_Initialize_LL(SDCARD_SDIO_DMA_OPT);
#endif
@ -181,7 +185,7 @@ static int8_t STORAGE_Init (uint8_t lun)
if (!sdcard_isInserted()) {
return 1;
}
if (SD_Init() != 0) {
if (SD_Init() != SD_OK) {
return 1;
}

View file

@ -495,6 +495,11 @@ void SystemClock_Config(void)
#ifdef USE_SDCARD_SDIO
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC;
#if (HSE_VALUE != 8000000)
#error Unsupported external oscillator speed. The calculations below are based on 8Mhz resonators
// if you are seeing this, then calculate the PLL2 settings for your resonator and add support as required.
#else
RCC_PeriphClkInit.PLL2.PLL2M = 5;
RCC_PeriphClkInit.PLL2.PLL2N = 500;
RCC_PeriphClkInit.PLL2.PLL2P = 2; // 500Mhz
@ -505,6 +510,8 @@ void SystemClock_Config(void)
RCC_PeriphClkInit.PLL2.PLL2FRACN = 0;
RCC_PeriphClkInit.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL2;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
#endif // 8Mhz HSE_VALUE
#endif
// Configure MCO clocks for clock test/verification