mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-16 21:05:35 +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:
parent
adcc36888b
commit
246a02dcc1
6 changed files with 107 additions and 51 deletions
|
@ -5393,14 +5393,17 @@ 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),
|
||||
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),
|
||||
DEFW("UART_RX", DMA_PERIPH_UART_RX, PG_SERIAL_UART_CONFIG, serialUartConfig_t, rxDmaopt, UARTDEV_CONFIG_MAX, 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),
|
||||
DEFW("UART_RX", DMA_PERIPH_UART_RX, PG_SERIAL_UART_CONFIG, serialUartConfig_t, rxDmaopt, UARTDEV_CONFIG_MAX, MASK_IGNORED),
|
||||
#if defined(STM32H7) || defined(STM32G4)
|
||||
DEFW("TIMUP", DMA_PERIPH_TIMUP, PG_TIMER_UP_CONFIG, timerUpConfig_t, dmaopt, HARDWARE_TIMER_DEFINITION_COUNT, TIMUP_TIMERS),
|
||||
DEFW("TIMUP", DMA_PERIPH_TIMUP, PG_TIMER_UP_CONFIG, timerUpConfig_t, dmaopt, HARDWARE_TIMER_DEFINITION_COUNT, TIMUP_TIMERS),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue