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_CFG_TO_DEV(x) ((x) - 1)
#define SPI_DEV_TO_CFG(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 spiPreinit(void);
void spiPreinitRegister(ioTag_t iotag, uint8_t iocfg, uint8_t init); void spiPreinitRegister(ioTag_t iotag, uint8_t iocfg, uint8_t init);
void spiPreinitByIO(IO_t io); 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); LL_SPI_TransmitData8(instance, txByte);
timeoutStartUs = microsISR(); timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) { while (!CHECK_SPI_RX_DATA_AVAILABLE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) { if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance); return spiTimeoutUserCallback(instance);
} }
@ -188,7 +188,7 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
LL_SPI_TransmitData16(instance, w); LL_SPI_TransmitData16(instance, w);
timeoutStartUs = microsISR(); timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) { while (!CHECK_SPI_RX_DATA_AVAILABLE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) { if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance); return spiTimeoutUserCallback(instance);
} }
@ -213,7 +213,7 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
LL_SPI_TransmitData8(instance, b); LL_SPI_TransmitData8(instance, b);
timeoutStartUs = microsISR(); timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) { while (!CHECK_SPI_RX_DATA_AVAILABLE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) { if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance); return spiTimeoutUserCallback(instance);
} }

View file

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

View file

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

View file

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

View file

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