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

Support SPI MOSI/MISO DMA stream assignment

Add SPI_TX/SPI_RX aliases for SPI_MOSI/SPI_MISO for dma command
Only assign SPI DMA before motors on F4/F7
This commit is contained in:
Steve Evans 2021-10-07 19:34:30 +01:00
parent adcc36888b
commit 246a02dcc1
6 changed files with 107 additions and 51 deletions

View file

@ -5393,8 +5393,11 @@ typedef struct dmaoptEntry_s {
{ device, peripheral, pgn, sizeof(type), offsetof(type, member), max, mask }
dmaoptEntry_t dmaoptEntryTable[] = {
DEFW("SPI_TX", DMA_PERIPH_SPI_TX, PG_SPI_PIN_CONFIG, spiPinConfig_t, txDmaopt, SPIDEV_COUNT, MASK_IGNORED),
DEFW("SPI_RX", DMA_PERIPH_SPI_RX, PG_SPI_PIN_CONFIG, spiPinConfig_t, rxDmaopt, SPIDEV_COUNT, MASK_IGNORED),
DEFW("SPI_MOSI", DMA_PERIPH_SPI_MOSI, PG_SPI_PIN_CONFIG, spiPinConfig_t, txDmaopt, SPIDEV_COUNT, MASK_IGNORED),
DEFW("SPI_MISO", DMA_PERIPH_SPI_MISO, PG_SPI_PIN_CONFIG, spiPinConfig_t, rxDmaopt, SPIDEV_COUNT, MASK_IGNORED),
// SPI_TX/SPI_RX for backwards compatibility with unified configs defined for 4.2.x
DEFW("SPI_TX", DMA_PERIPH_SPI_MOSI, PG_SPI_PIN_CONFIG, spiPinConfig_t, txDmaopt, SPIDEV_COUNT, MASK_IGNORED),
DEFW("SPI_RX", DMA_PERIPH_SPI_MISO, PG_SPI_PIN_CONFIG, spiPinConfig_t, rxDmaopt, SPIDEV_COUNT, MASK_IGNORED),
DEFA("ADC", DMA_PERIPH_ADC, PG_ADC_CONFIG, adcConfig_t, dmaopt, ADCDEV_COUNT, MASK_IGNORED),
DEFS("SDIO", DMA_PERIPH_SDIO, PG_SDIO_CONFIG, sdioConfig_t, dmaopt),
DEFW("UART_TX", DMA_PERIPH_UART_TX, PG_SERIAL_UART_CONFIG, serialUartConfig_t, txDmaopt, UARTDEV_CONFIG_MAX, MASK_IGNORED),

View file

@ -37,6 +37,7 @@
#include "drivers/motor.h"
#include "drivers/rcc.h"
#include "nvic.h"
#include "pg/bus_spi.h"
static uint8_t spiRegisteredDeviceCount = 0;
@ -540,8 +541,17 @@ void spiInitBusDMA()
dmaIdentifier_e dmaTxIdentifier = DMA_NONE;
dmaIdentifier_e dmaRxIdentifier = DMA_NONE;
for (uint8_t opt = 0; opt < MAX_PERIPHERAL_DMA_OPTIONS; opt++) {
const dmaChannelSpec_t *dmaTxChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SPI_TX, device, opt);
int8_t txDmaopt = spiPinConfig(device)->txDmaopt;
uint8_t txDmaoptMin = 0;
uint8_t txDmaoptMax = MAX_PERIPHERAL_DMA_OPTIONS - 1;
if (txDmaopt != -1) {
txDmaoptMin = txDmaopt;
txDmaoptMax = txDmaopt;
}
for (uint8_t opt = txDmaoptMin; opt <= txDmaoptMax; opt++) {
const dmaChannelSpec_t *dmaTxChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SPI_MOSI, device, opt);
if (dmaTxChannelSpec) {
dmaTxIdentifier = dmaGetIdentifier(dmaTxChannelSpec->ref);
@ -565,8 +575,17 @@ void spiInitBusDMA()
}
}
for (uint8_t opt = 0; opt < MAX_PERIPHERAL_DMA_OPTIONS; opt++) {
const dmaChannelSpec_t *dmaRxChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SPI_RX, device, opt);
int8_t rxDmaopt = spiPinConfig(device)->rxDmaopt;
uint8_t rxDmaoptMin = 0;
uint8_t rxDmaoptMax = MAX_PERIPHERAL_DMA_OPTIONS - 1;
if (rxDmaopt != -1) {
rxDmaoptMin = rxDmaopt;
rxDmaoptMax = rxDmaopt;
}
for (uint8_t opt = rxDmaoptMin; opt <= rxDmaoptMax; opt++) {
const dmaChannelSpec_t *dmaRxChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SPI_MISO, device, opt);
if (dmaRxChannelSpec) {
dmaRxIdentifier = dmaGetIdentifier(dmaRxChannelSpec->ref);

View file

@ -71,16 +71,26 @@ typedef struct dmaTimerMapping_s {
#define DMA_REQUEST_UART9_RX DMA_REQUEST_LPUART1_RX
#define DMA_REQUEST_UART9_TX DMA_REQUEST_LPUART1_TX
// Resolve our preference for MOSI/MISO rather than TX/RX
#define DMA_REQUEST_SPI1_MOSI DMA_REQUEST_SPI1_TX
#define DMA_REQUEST_SPI1_MISO DMA_REQUEST_SPI1_RX
#define DMA_REQUEST_SPI2_MOSI DMA_REQUEST_SPI2_TX
#define DMA_REQUEST_SPI2_MISO DMA_REQUEST_SPI2_RX
#define DMA_REQUEST_SPI3_MOSI DMA_REQUEST_SPI3_TX
#define DMA_REQUEST_SPI3_MISO DMA_REQUEST_SPI3_RX
#define DMA_REQUEST_SPI4_MOSI DMA_REQUEST_SPI4_TX
#define DMA_REQUEST_SPI4_MISO DMA_REQUEST_SPI4_RX
static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
#ifdef USE_SPI
REQMAP_DIR(SPI, 1, TX),
REQMAP_DIR(SPI, 1, RX),
REQMAP_DIR(SPI, 2, TX),
REQMAP_DIR(SPI, 2, RX),
REQMAP_DIR(SPI, 3, TX),
REQMAP_DIR(SPI, 3, RX),
REQMAP_DIR(SPI, 4, TX),
REQMAP_DIR(SPI, 4, RX),
REQMAP_DIR(SPI, 1, MOSI),
REQMAP_DIR(SPI, 1, MISO),
REQMAP_DIR(SPI, 2, MOSI),
REQMAP_DIR(SPI, 2, MISO),
REQMAP_DIR(SPI, 3, MOSI),
REQMAP_DIR(SPI, 3, MISO),
REQMAP_DIR(SPI, 4, MOSI),
REQMAP_DIR(SPI, 4, MISO),
#endif // USE_SPI
#ifdef USE_ADC
@ -209,20 +219,32 @@ static dmaChannelSpec_t dmaChannelSpec[MAX_PERIPHERAL_DMA_OPTIONS] = {
#define DMA_REQUEST_UART6_RX DMA_REQUEST_USART6_RX
#define DMA_REQUEST_UART6_TX DMA_REQUEST_USART6_TX
// Resolve our preference for MOSI/MISO rather than TX/RX
#define DMA_REQUEST_SPI1_MOSI DMA_REQUEST_SPI1_TX
#define DMA_REQUEST_SPI1_MISO DMA_REQUEST_SPI1_RX
#define DMA_REQUEST_SPI2_MOSI DMA_REQUEST_SPI2_TX
#define DMA_REQUEST_SPI2_MISO DMA_REQUEST_SPI2_RX
#define DMA_REQUEST_SPI3_MOSI DMA_REQUEST_SPI3_TX
#define DMA_REQUEST_SPI3_MISO DMA_REQUEST_SPI3_RX
#define DMA_REQUEST_SPI4_MOSI DMA_REQUEST_SPI4_TX
#define DMA_REQUEST_SPI4_MISO DMA_REQUEST_SPI4_RX
#define DMA_REQUEST_SPI5_MOSI DMA_REQUEST_SPI5_TX
#define DMA_REQUEST_SPI5_MISO DMA_REQUEST_SPI5_RX
static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
#ifdef USE_SPI
REQMAP_DIR(SPI, 1, TX),
REQMAP_DIR(SPI, 1, RX),
REQMAP_DIR(SPI, 2, TX),
REQMAP_DIR(SPI, 2, RX),
REQMAP_DIR(SPI, 3, TX),
REQMAP_DIR(SPI, 3, RX),
REQMAP_DIR(SPI, 4, TX),
REQMAP_DIR(SPI, 4, RX),
REQMAP_DIR(SPI, 5, TX), // Not available in smaller packages
REQMAP_DIR(SPI, 5, RX), // ditto
// REQMAP_DIR(SPI, 6, TX), // SPI6 is on BDMA (todo)
// REQMAP_DIR(SPI, 6, TX), // ditto
REQMAP_DIR(SPI, 1, MOSI),
REQMAP_DIR(SPI, 1, MISO),
REQMAP_DIR(SPI, 2, MOSI),
REQMAP_DIR(SPI, 2, MISO),
REQMAP_DIR(SPI, 3, MOSI),
REQMAP_DIR(SPI, 3, MISO),
REQMAP_DIR(SPI, 4, MOSI),
REQMAP_DIR(SPI, 4, MISO),
REQMAP_DIR(SPI, 5, MOSI), // Not available in smaller packages
REQMAP_DIR(SPI, 5, MISO), // ditto
// REQMAP_DIR(SPI, 6, MOSI), // SPI6 is on BDMA (todo)
// REQMAP_DIR(SPI, 6, MOSI), // ditto
#endif // USE_SPI
#ifdef USE_ADC
@ -343,24 +365,24 @@ static dmaChannelSpec_t dmaChannelSpec[MAX_PERIPHERAL_DMA_OPTIONS] = {
static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
#ifdef USE_SPI
// Everything including F405 and F446
{ DMA_PERIPH_SPI_TX, SPIDEV_1, { DMA(2, 3, 3), DMA(2, 5, 3) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_1, { DMA(2, 0, 3), DMA(2, 2, 3) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_2, { DMA(1, 4, 0) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_2, { DMA(1, 3, 0) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_3, { DMA(1, 5, 0), DMA(1, 7, 0) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_3, { DMA(1, 0, 0), DMA(1, 2, 0) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_1, { DMA(2, 3, 3), DMA(2, 5, 3) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_1, { DMA(2, 0, 3), DMA(2, 2, 3) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_2, { DMA(1, 4, 0) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_2, { DMA(1, 3, 0) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_3, { DMA(1, 5, 0), DMA(1, 7, 0) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_3, { DMA(1, 0, 0), DMA(1, 2, 0) } },
#if defined(STM32F411xE) || defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx) || defined(STM32F722xx)
{ DMA_PERIPH_SPI_TX, SPIDEV_4, { DMA(2, 1, 4) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_4, { DMA(2, 0, 4) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_4, { DMA(2, 1, 4) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_4, { DMA(2, 0, 4) } },
#ifdef USE_EXTENDED_SPI_DEVICE
{ DMA_PERIPH_SPI_TX, SPIDEV_5, { DMA(2, 6, 7) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_5, { DMA(2, 5, 7) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_5, { DMA(2, 6, 7) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_5, { DMA(2, 5, 7) } },
#if !defined(STM32F722xx)
{ DMA_PERIPH_SPI_TX, SPIDEV_6, { DMA(2, 5, 1) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_6, { DMA(2, 6, 1) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_6, { DMA(2, 5, 1) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_6, { DMA(2, 6, 1) } },
#endif
#endif // USE_EXTENDED_SPI_DEVICE
#endif
@ -434,12 +456,12 @@ static const dmaTimerMapping_t dmaTimerMapping[] = {
#define DMA(d, c) { DMA_CODE(d, 0, c), (dmaResource_t *)DMA ## d ## _Channel ## c }
static const dmaPeripheralMapping_t dmaPeripheralMapping[18] = {
#ifdef USE_SPI
{ DMA_PERIPH_SPI_TX, SPIDEV_1, { DMA(1, 3) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_1, { DMA(1, 2) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_2, { DMA(1, 5) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_2, { DMA(1, 4) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_3, { DMA(2, 2) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_3, { DMA(2, 1) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_1, { DMA(1, 3) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_1, { DMA(1, 2) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_2, { DMA(1, 5) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_2, { DMA(1, 4) } },
{ DMA_PERIPH_SPI_MOSI, SPIDEV_3, { DMA(2, 2) } },
{ DMA_PERIPH_SPI_MISO, SPIDEV_3, { DMA(2, 1) } },
#endif
#ifdef USE_ADC

View file

@ -42,8 +42,8 @@ typedef struct dmaChannelSpec_s {
#define DMA_CODE_REQUEST(code) DMA_CODE_CHANNEL(code)
typedef enum {
DMA_PERIPH_SPI_TX,
DMA_PERIPH_SPI_RX,
DMA_PERIPH_SPI_MOSI,
DMA_PERIPH_SPI_MISO,
DMA_PERIPH_ADC,
DMA_PERIPH_SDIO,
DMA_PERIPH_UART_TX,

View file

@ -964,14 +964,25 @@ void init(void)
setArmingDisabled(ARMING_DISABLED_BOOT_GRACE_TIME);
// On F4/F7 allocate SPI DMA streams before motor timers
#if defined(STM32F4) || defined(STM32F7)
#ifdef USE_SPI
// Attempt to enable DMA on all SPI busses
spiInitBusDMA();
#endif
#endif
#ifdef USE_MOTOR
motorPostInit();
motorEnable();
#endif
// On H7/G4 allocate SPI DMA streams after motor timers as SPI DMA allocate will always be possible
#if defined(STM32H7) || defined(STM32G4)
#ifdef USE_SPI
// Attempt to enable DMA on all SPI busses
spiInitBusDMA();
#endif
#endif
swdPinsInit();

View file

@ -25,6 +25,7 @@
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "pg/bus_spi.h"
#include "pg/pg.h"
#include "pg/pg_ids.h"