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:
commit
c84170fac3
6 changed files with 36 additions and 18 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue