1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-15 12:25:20 +03:00

Merge pull request #10776 from mikeller/fix_g4_h7_spi

Fixed SPI access for SD cards for STM32G4 and STM32H7.
This commit is contained in:
J Blackman 2021-06-08 08:14:47 +10:00 committed by GitHub
commit c84170fac3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 18 deletions

View file

@ -88,6 +88,15 @@ typedef enum SPIDevice {
#define SPI_CFG_TO_DEV(x) ((x) - 1)
#define SPI_DEV_TO_CFG(x) ((x) + 1)
// Work around different check routines in the libraries for different MCU types
#if defined(STM32H7)
#define CHECK_SPI_RX_DATA_AVAILABLE(instance) LL_SPI_IsActiveFlag_RXWNE(instance)
#define SPI_RX_DATA_REGISTER(base) ((base)->RXDR)
#else
#define CHECK_SPI_RX_DATA_AVAILABLE(instance) LL_SPI_IsActiveFlag_RXNE(instance)
#define SPI_RX_DATA_REGISTER(base) ((base)->DR)
#endif
void spiPreinit(void);
void spiPreinitRegister(ioTag_t iotag, uint8_t iocfg, uint8_t init);
void spiPreinitByIO(IO_t io);

View file

@ -147,7 +147,7 @@ uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
LL_SPI_TransmitData8(instance, txByte);
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
while (!CHECK_SPI_RX_DATA_AVAILABLE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
@ -188,7 +188,7 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
LL_SPI_TransmitData16(instance, w);
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
while (!CHECK_SPI_RX_DATA_AVAILABLE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
@ -213,7 +213,7 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
LL_SPI_TransmitData8(instance, b);
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
while (!CHECK_SPI_RX_DATA_AVAILABLE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}

View file

@ -157,6 +157,8 @@ typedef enum {
#define DMA_DEVICE_NO(x) ((((x)-1) / 8) + 1)
#define DMA_DEVICE_INDEX(x) ((((x)-1) % 8) + 1)
uint32_t dmaGetChannel(const uint8_t channel);
#else // !STM32G4
typedef enum {

View file

@ -25,12 +25,11 @@
#ifdef USE_SDCARD_SPI
#include "drivers/nvic.h"
#include "drivers/io.h"
#include "drivers/bus_spi.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/bus_spi.h"
#include "drivers/io.h"
#include "drivers/nvic.h"
#include "drivers/time.h"
#include "pg/bus_spi.h"
@ -299,9 +298,9 @@ static bool sdcard_sendDataBlockFinish(void)
{
#ifdef USE_HAL_DRIVER
// Drain anything left in the Rx FIFO (we didn't read it during the write)
//This is necessary here as when using msc there is timing issue
while (LL_SPI_IsActiveFlag_RXNE(sdcard.busdev.busdev_u.spi.instance)) {
sdcard.busdev.busdev_u.spi.instance->DR;
// This is necessary here as when using msc there is timing issue
while (CHECK_SPI_RX_DATA_AVAILABLE(sdcard.busdev.busdev_u.spi.instance)) {
SPI_RX_DATA_REGISTER(sdcard.busdev.busdev_u.spi.instance);
}
#endif
@ -342,11 +341,15 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
LL_DMA_StructInit(&init);
#if defined(STM32G4) || defined(STM32H7)
init.PeriphRequest = dmaGetChannel(sdcard.dmaChannel);
#else
init.Channel = dmaGetChannel(sdcard.dmaChannel);
#endif
init.Mode = LL_DMA_MODE_NORMAL;
init.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
init.PeriphOrM2MSrcAddress = (uint32_t)&sdcard.busdev.busdev_u.spi.instance->DR;
init.PeriphOrM2MSrcAddress = (uint32_t)&SPI_RX_DATA_REGISTER(sdcard.busdev.busdev_u.spi.instance);
init.Priority = LL_DMA_PRIORITY_LOW;
init.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
init.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
@ -360,7 +363,11 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
LL_DMA_DeInit(sdcard.dma->dma, sdcard.dma->stream);
LL_DMA_Init(sdcard.dma->dma, sdcard.dma->stream, &init);
#if defined(STM32G4)
LL_DMA_EnableChannel(sdcard.dma->dma, sdcard.dma->stream);
#else
LL_DMA_EnableStream(sdcard.dma->dma, sdcard.dma->stream);
#endif
LL_SPI_EnableDMAReq_TX(sdcard.busdev.busdev_u.spi.instance);
@ -378,7 +385,7 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
init.DMA_MemoryBaseAddr = (uint32_t) buffer;
init.DMA_DIR = DMA_DIR_PeripheralDST;
#endif
init.DMA_PeripheralBaseAddr = (uint32_t) &sdcard.busdev.busdev_u.spi.instance->DR;
init.DMA_PeripheralBaseAddr = (uint32_t)&SPI_RX_DATA_REGISTER(sdcard.busdev.busdev_u.spi.instance);
init.DMA_Priority = DMA_Priority_Low;
init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
@ -735,8 +742,8 @@ static bool sdcardSpi_poll(void)
DMA_CLEAR_FLAG(sdcard.dma, DMA_IT_TCIF);
DMA_CLEAR_FLAG(sdcard.dma, DMA_IT_HTIF);
// Drain anything left in the Rx FIFO (we didn't read it during the write)
while (LL_SPI_IsActiveFlag_RXNE(sdcard.busdev.busdev_u.spi.instance)) {
sdcard.busdev.busdev_u.spi.instance->DR;
while (CHECK_SPI_RX_DATA_AVAILABLE(sdcard.busdev.busdev_u.spi.instance)) {
SPI_RX_DATA_REGISTER(sdcard.busdev.busdev_u.spi.instance);
}
// Wait for the final bit to be transmitted
@ -760,7 +767,7 @@ static bool sdcardSpi_poll(void)
// Drain anything left in the Rx FIFO (we didn't read it during the write)
while (SPI_I2S_GetFlagStatus(sdcard.busdev.busdev_u.spi.instance, SPI_I2S_FLAG_RXNE) == SET) {
sdcard.busdev.busdev_u.spi.instance->DR;
SPI_RX_DATA_REGISTER(sdcard.busdev.busdev_u.spi.instance);
}
// Wait for the final bit to be transmitted

View file

@ -227,10 +227,10 @@
#define USE_BARO_DPS310
#define USE_BARO_SPI_DPS310
#if !defined(STM32G4)
// G4 support needs fixing
#define USE_SDCARD
#define USE_SDCARD_SPI
#if !defined(STM32G4)
// G4 support needs fixing
#define USE_SDCARD_SDIO
#endif

View file

@ -28,7 +28,7 @@ CUSTOM_DEFAULTS_EXTENDED = yes
endif
ifeq ($(TARGET), STM32G47X)
FEATURES += VCP ONBOARDFLASH
FEATURES += VCP SDCARD_SPI ONBOARDFLASH
else
FEATURES += VCP SDCARD_SPI SDCARD_SDIO ONBOARDFLASH
endif