From 1f9f221e0122b319f4b480689a2d0a9c65ff7f87 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 12:24:09 +0200 Subject: [PATCH 01/19] spi: data-ready reads on F4 and F7, through DMA The SPI of F7 has a 4-byte FIFO and that of F4 none, so there every data-ready read goes through two DMA streams. The SPI stays enabled, as for the main loop's transfers, and setting its DMA requests starts the read. The streams are taken like on H7, among the options the reference manual gives each request, at the end of initialisation. Nobody has tested this on an F4 or F7 board yet, so gyro_data_ready AUTO leaves it off there: ON turns it on. --- docs/Settings.md | 2 +- src/main/drivers/adc.h | 6 ++ src/main/drivers/adc_stm32f4xx.c | 26 +++++++ src/main/drivers/adc_stm32f7xx.c | 21 ++++++ src/main/drivers/bus_spi.c | 81 ++++++++++++++++++++++ src/main/drivers/bus_spi_data_ready_dma.c | 67 ++++++++++++++++-- src/main/drivers/bus_spi_data_ready_impl.h | 6 +- src/main/drivers/bus_spi_hal_ll.c | 54 ++++++++++++++- src/main/fc/settings.yaml | 2 +- src/main/target/common.h | 2 +- 10 files changed, 258 insertions(+), 9 deletions(-) diff --git a/docs/Settings.md b/docs/Settings.md index 82809020ba7..f608fdc6c92 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -2140,7 +2140,7 @@ Gyro processing anti-aliasing filter cutoff frequency. In normal operation this ### gyro_data_ready -Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin. AUTO and ON do it, OFF polls the gyro. +Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin. AUTO does it on H7. On F4 and F7 the read goes through DMA and is new: set ON to try it, and please report how it works. OFF polls the gyro everywhere. | Allowed Values | | | --- | --- | diff --git a/src/main/drivers/adc.h b/src/main/drivers/adc.h index 1749c9fa63e..6955bbb987b 100644 --- a/src/main/drivers/adc.h +++ b/src/main/drivers/adc.h @@ -45,6 +45,12 @@ typedef struct drv_adc_config_s { void adcInit(drv_adc_config_t *init); uint16_t adcGetChannel(uint8_t channel); +#if defined(STM32F4) || defined(STM32F7) +struct dmaChannelDescriptor_s; +// ADC1 can use DMA2 stream 0 or stream 4. If it has `stream` and the other one is free, it moves +// there, for a user that can have only `stream`. For users that take their streams after everyone else +bool adcDmaMoveOff(struct dmaChannelDescriptor_s *stream); +#endif bool adcIsFunctionAssigned(uint8_t function); int adcGetFunctionChannelAllocation(uint8_t function); diff --git a/src/main/drivers/adc_stm32f4xx.c b/src/main/drivers/adc_stm32f4xx.c index 42f9583ed8c..f9ef7eb15cc 100644 --- a/src/main/drivers/adc_stm32f4xx.c +++ b/src/main/drivers/adc_stm32f4xx.c @@ -153,6 +153,32 @@ static void adcInstanceInit(ADCDevice adcDevice) ADC_SoftwareStartConv(adc->ADCx); } +bool adcDmaMoveOff(DMA_t stream) +{ + adcDevice_t *adc = &adcHardware[ADCDEV_1]; + if (!adc->enabled || dmaGetByRef(adc->DMAy_Streamx) != stream) { + return false; + } + DMA_Stream_TypeDef *other = adc->DMAy_Streamx == DMA2_Stream0 ? DMA2_Stream4 : DMA2_Stream0; + DMA_t otherDma = dmaGetByRef(other); + if (!otherDma || dmaGetOwner(otherDma) != OWNER_FREE) { + return false; + } + + // Stopped first: a conversion the DMA misses would be an overrun, which stops its requests + ADC_Cmd(adc->ADCx, DISABLE); + ADC_DMACmd(adc->ADCx, DISABLE); + DMA_Cmd(adc->DMAy_Streamx, DISABLE); + while (DMA_GetCmdStatus(adc->DMAy_Streamx) != DISABLE) { + } + ADC_ClearFlag(adc->ADCx, ADC_FLAG_OVR); + dmaInit(stream, OWNER_FREE, 0); + + adc->DMAy_Streamx = other; + adcInstanceInit(ADCDEV_1); + return true; +} + void adcHardwareInit(drv_adc_config_t *init) { UNUSED(init); diff --git a/src/main/drivers/adc_stm32f7xx.c b/src/main/drivers/adc_stm32f7xx.c index c680f2c379f..b9bea381237 100644 --- a/src/main/drivers/adc_stm32f7xx.c +++ b/src/main/drivers/adc_stm32f7xx.c @@ -164,6 +164,27 @@ static void adcInstanceInit(ADCDevice adcDevice) } } +bool adcDmaMoveOff(DMA_t stream) +{ + adcDevice_t *adc = &adcHardware[ADCDEV_1]; + if (!adc->enabled || dmaGetByRef(adc->DMAy_Streamx) != stream) { + return false; + } + DMA_Stream_TypeDef *other = adc->DMAy_Streamx == DMA2_Stream0 ? DMA2_Stream4 : DMA2_Stream0; + DMA_t otherDma = dmaGetByRef(other); + if (!otherDma || dmaGetOwner(otherDma) != OWNER_FREE) { + return false; + } + + HAL_ADC_Stop_DMA(&adc->ADCHandle); + HAL_DMA_DeInit(&adc->DmaHandle); + dmaInit(stream, OWNER_FREE, 0); + + adc->DMAy_Streamx = other; + adcInstanceInit(ADCDEV_1); + return true; +} + void adcHardwareInit(drv_adc_config_t *init) { UNUSED(init); diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 8220ad01cd9..18f7a489cec 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -18,11 +18,14 @@ #include #include +#include + #include #ifdef USE_SPI #include "drivers/bus_spi.h" +#include "drivers/bus_spi_data_ready_impl.h" #include "drivers/exti.h" #include "drivers/io.h" #include "drivers/io_impl.h" @@ -248,6 +251,84 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len return true; } +#if defined(USE_SPI_DATA_READY) +// Data-ready reads (see bus_spi_data_ready.c). The F4 SPI has no FIFO, so every read uses two +// DMA streams; the buffers stay out of the CCM RAM, which the DMA can not reach + +// Longest read, address included +#define SPI_DATA_READY_MAX 32 + +typedef struct { + uint8_t len; // bytes after the address + spiDataReadyDma_t streams; +} spiDataReadyHw_t; + +static spiDataReadyHw_t spiDataReadyHw[SPIDEV_COUNT]; +static uint8_t spiDataReadyTx[SPIDEV_COUNT][SPI_DATA_READY_MAX]; +static uint8_t spiDataReadyRx[SPIDEV_COUNT][SPI_DATA_READY_MAX]; + +static void spiDataReadyDmaDone(DMA_t rx) +{ + const SPIDevice device = (SPIDevice)rx->userParam; + if (!spiDataReadyDmaEnded(rx)) { + // The read never ends: the main loop takes it off the bus when it next needs it + return; + } + + // A copy: a data-ready that came meanwhile starts the next read into the same buffer + uint8_t data[SPI_DATA_READY_MAX]; + memcpy(data, spiDataReadyRx[device] + 1, spiDataReadyHw[device].len); + spiDataReadyDone(device, data); +} + +bool spiDataReadyHwInit(SPIDevice device, uint8_t reg, uint8_t len) +{ + spiDataReadyHw_t *h = &spiDataReadyHw[device]; + if (!spiHardwareMap[device].dev || len + 1 > SPI_DATA_READY_MAX) { + return false; + } + if (!spiDataReadyDmaInit(device, &h->streams, spiDataReadyDmaDone, device)) { + return false; + } + + h->len = len; + memset(spiDataReadyTx[device], 0xFF, SPI_DATA_READY_MAX); + spiDataReadyTx[device][0] = reg; + return true; +} + +// Setting the DMA requests starts the read: receive first, as the reference manual has it +void spiDataReadyHwStart(SPIDevice device) +{ + const spiDataReadyHw_t *h = &spiDataReadyHw[device]; + SPI_TypeDef *instance = spiHardwareMap[device].dev; + + // A byte left in the data register would be taken for the first one of this read + (void)instance->DR; + spiDataReadyDmaStart(&h->streams, &instance->DR, &instance->DR, spiDataReadyTx[device], spiDataReadyRx[device], h->len + 1); + instance->CR2 |= SPI_CR2_RXDMAEN; + instance->CR2 |= SPI_CR2_TXDMAEN; +} + +void spiDataReadyHwStop(SPIDevice device) +{ + const spiDataReadyHw_t *h = &spiDataReadyHw[device]; + SPI_TypeDef *instance = spiHardwareMap[device].dev; + + spiDataReadyDmaStop(&h->streams); + instance->CR2 &= ~(SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + + // A read stopped half way may leave a byte going out: let it finish and drop the echo + for (int timeout = 1000; timeout && (!(instance->SR & SPI_SR_TXE) || (instance->SR & SPI_SR_BSY)); timeout--); + (void)instance->DR; +} + +void spiDataReadyHwDisable(SPIDevice device) +{ + spiDataReadyDmaDisable(&spiDataReadyHw[device].streams); +} +#endif + void spiSetSpeed(SPI_TypeDef *instance, SPIClockSpeed_e speed) { #define BR_CLEAR_MASK 0xFFC7 diff --git a/src/main/drivers/bus_spi_data_ready_dma.c b/src/main/drivers/bus_spi_data_ready_dma.c index 3cec396c896..844e3127ec7 100644 --- a/src/main/drivers/bus_spi_data_ready_dma.c +++ b/src/main/drivers/bus_spi_data_ready_dma.c @@ -26,19 +26,24 @@ #include "drivers/bus_spi.h" -#if defined(USE_SPI_DATA_READY) && defined(STM32H7) +#if defined(USE_SPI_DATA_READY) && (defined(STM32F4) || defined(STM32F7) || defined(STM32H7)) #include "drivers/bus_spi_data_ready_impl.h" +#include "drivers/adc.h" #include "drivers/dma.h" #include "drivers/nvic.h" #include "drivers/resource.h" +#if defined(STM32H7) #include "stm32h7xx_ll_dma.h" +#endif // DMA streams for data-ready reads, taken at the end of init from those nobody owns; a bus with -// no free pair reads without DMA. H7 routes any request through its DMAMUX +// no free pair reads without DMA. H7 routes any request through its DMAMUX, F4/F7 have fixed ones #define SPI_DMA_FLAGS (DMA_IT_TCIF | DMA_IT_HTIF | DMA_IT_TEIF | DMA_IT_DMEIF | DMA_IT_FEIF) +// F4 and F7: the request's channel in the stream's CR (CHSEL) +#define SPI_DMA_CHSEL(ch) ((uint32_t)(ch) << 25) // Streams named for serial ports stay theirs: a port may open after init static const dmaTag_t spiDmaReserved[] = { @@ -106,6 +111,7 @@ static bool spiDmaIsFree(DMA_t d) return true; } +#if defined(STM32H7) static const uint32_t spiDmaRequest[SPIDEV_COUNT][2] = { { DMA_REQUEST_SPI1_RX, DMA_REQUEST_SPI1_TX }, { DMA_REQUEST_SPI2_RX, DMA_REQUEST_SPI2_TX }, @@ -125,9 +131,44 @@ static DMA_t spiDmaFindFree(DMA_t other) } return NULL; } +#else +// The streams, with their channel, each SPI's receive and transmit requests can use +static const dmaTag_t spiDmaOptions[SPIDEV_COUNT][2][2] = { + { { DMA_TAG(2, 0, 3), DMA_TAG(2, 2, 3) }, { DMA_TAG(2, 3, 3), DMA_TAG(2, 5, 3) } }, // SPI1 + { { DMA_TAG(1, 3, 0), DMA_NONE }, { DMA_TAG(1, 4, 0), DMA_NONE } }, // SPI2 + { { DMA_TAG(1, 0, 0), DMA_TAG(1, 2, 0) }, { DMA_TAG(1, 5, 0), DMA_TAG(1, 7, 0) } }, // SPI3 +#if defined(STM32F7) + { { DMA_TAG(2, 0, 4), DMA_TAG(2, 3, 5) }, { DMA_TAG(2, 1, 4), DMA_TAG(2, 4, 5) } }, // SPI4 +#endif +}; + +static DMA_t spiDmaFindFree(const dmaTag_t *options, uint32_t *channel) +{ + for (int i = 0; i < 2; i++) { + DMA_t d = options[i] ? dmaGetByTag(options[i]) : NULL; + if (spiDmaIsFree(d)) { + *channel = SPI_DMA_CHSEL(DMATAG_GET_CHANNEL(options[i])); + return d; + } + } +#if defined(USE_ADC) + // Both taken: move the ADC to its other stream (many boards give it DMA2 stream 0, and a timer + // the other stream SPI1 could receive on) + for (int i = 0; i < 2; i++) { + DMA_t d = options[i] ? dmaGetByTag(options[i]) : NULL; + if (d && dmaGetOwner(d) == OWNER_ADC && adcDmaMoveOff(d) && spiDmaIsFree(d)) { + *channel = SPI_DMA_CHSEL(DMATAG_GET_CHANNEL(options[i])); + return d; + } + } +#endif + return NULL; +} +#endif bool spiDataReadyDmaInit(SPIDevice device, spiDataReadyDma_t *dma, dmaCallbackHandlerFuncPtr done, uint32_t userParam) { +#if defined(STM32H7) DMA_t rx = spiDmaFindFree(NULL); DMA_t tx = spiDmaFindFree(rx); if (!rx || !tx) { @@ -135,6 +176,19 @@ bool spiDataReadyDmaInit(SPIDevice device, spiDataReadyDma_t *dma, dmaCallbackHa } LL_DMA_SetPeriphRequest(rx->dma, DMATAG_GET_STREAM(rx->tag), spiDmaRequest[device][0]); LL_DMA_SetPeriphRequest(tx->dma, DMATAG_GET_STREAM(tx->tag), spiDmaRequest[device][1]); +#else + DMA_t rx = spiDmaFindFree(spiDmaOptions[device][0], &dma->rxChannel); + if (!rx) { + return false; + } + // Owned before the transmit search: moving the ADC for that one must not put it back here + dmaInit(rx, OWNER_SPI, device + 1); + DMA_t tx = spiDmaFindFree(spiDmaOptions[device][1], &dma->txChannel); + if (!tx) { + dmaInit(rx, OWNER_FREE, 0); + return false; + } +#endif dmaInit(rx, OWNER_SPI, device + 1); dmaInit(tx, OWNER_SPI, device + 1); @@ -168,8 +222,13 @@ static void spiDmaStreamStart(DMA_t d, uint32_t cr, volatile void *periph, const void spiDataReadyDmaStart(const spiDataReadyDma_t *dma, volatile void *txReg, volatile void *rxReg, const uint8_t *tx, uint8_t *rx, uint16_t n) { - spiDmaStreamStart(dma->rx, DMA_SxCR_MINC | DMA_SxCR_PL_1 | DMA_SxCR_TCIE | DMA_SxCR_TEIE, rxReg, rx, n); - spiDmaStreamStart(dma->tx, DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PL_0, txReg, tx, n); +#if defined(STM32H7) + const uint32_t rxChannel = 0, txChannel = 0; // the DMAMUX routes the requests +#else + const uint32_t rxChannel = dma->rxChannel, txChannel = dma->txChannel; +#endif + spiDmaStreamStart(dma->rx, rxChannel | DMA_SxCR_MINC | DMA_SxCR_PL_1 | DMA_SxCR_TCIE | DMA_SxCR_TEIE, rxReg, rx, n); + spiDmaStreamStart(dma->tx, txChannel | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PL_0, txReg, tx, n); } void spiDataReadyDmaStop(const spiDataReadyDma_t *dma) diff --git a/src/main/drivers/bus_spi_data_ready_impl.h b/src/main/drivers/bus_spi_data_ready_impl.h index 216219f9187..ce0f18a6001 100644 --- a/src/main/drivers/bus_spi_data_ready_impl.h +++ b/src/main/drivers/bus_spi_data_ready_impl.h @@ -40,13 +40,17 @@ void spiTimeoutUserCallback(SPI_TypeDef *instance); uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance); #endif -#if defined(STM32H7) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) #include "drivers/dma.h" // Reads longer than the SPI FIFO go through two DMA streams (bus_spi_data_ready_dma.c) typedef struct { DMA_t rx; DMA_t tx; +#if defined(STM32F4) || defined(STM32F7) + uint32_t rxChannel; // the stream's channel for this SPI + uint32_t txChannel; +#endif } spiDataReadyDma_t; // Takes a free stream for each direction. done() runs at the end of each read, or when the diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index 60a760ff294..1f2ab33e5d4 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -494,7 +494,7 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *rxData, const uint8_t *txData, #if defined(USE_SPI_DATA_READY) // Data-ready reads (see bus_spi_data_ready.c). On H7 a read that fits the SPI FIFO (16 bytes on // SPI1-3, 8 on SPI4-6) needs no DMA: the end-of-transfer interrupt takes it all back. Longer -// reads use two DMA streams +// reads, and all on F7 (4-byte FIFO), use two DMA streams // Longest read, address included #define SPI_DATA_READY_MAX 32 @@ -541,6 +541,7 @@ static bool spiDataReadyDmaSetup(SPIDevice device) return true; } +#if defined(STM32H7) static const IRQn_Type spiIrq[SPIDEV_COUNT] = { SPI1_IRQn, SPI2_IRQn, SPI3_IRQn, SPI4_IRQn }; static uint8_t spiFifoSize(SPI_TypeDef *instance) @@ -647,6 +648,57 @@ void SPI3_IRQHandler(void) { spiDataReadyIrqHandler(SPIDEV_3); } void SPI4_IRQHandler(void) { spiDataReadyIrqHandler(SPIDEV_4); } #endif +#else // STM32F7 + +bool spiDataReadyHwInit(SPIDevice device, uint8_t reg, uint8_t len) +{ + SPI_TypeDef *instance = spiHardwareMap[device].dev; + spiDataReadyHw_t *h = &spiDataReadyHw[device]; + if (!instance || len + 1 > SPI_DATA_READY_MAX) { + return false; + } + + h->reg = reg; + h->len = len; + return spiDataReadyDmaSetup(device); +} + +// Setting the DMA requests starts the read: receive first, as the reference manual has it +void spiDataReadyHwStart(SPIDevice device) +{ + const spiDataReadyHw_t *h = &spiDataReadyHw[device]; + SPI_TypeDef *instance = spiHardwareMap[device].dev; + + // A byte left in the receive FIFO would be taken for the first one of this read + for (int n = 0; n < 8 && LL_SPI_GetRxFIFOLevel(instance) != LL_SPI_RX_FIFO_EMPTY; n++) { + (void)LL_SPI_ReceiveData8(instance); + } + spiDataReadyDmaStart(&h->streams, &instance->DR, &instance->DR, spiDataReadyTx[device], spiDataReadyRx[device], h->len + 1); + SET_BIT(instance->CR2, SPI_CR2_RXDMAEN); + SET_BIT(instance->CR2, SPI_CR2_TXDMAEN); +} + +void spiDataReadyHwStop(SPIDevice device) +{ + const spiDataReadyHw_t *h = &spiDataReadyHw[device]; + SPI_TypeDef *instance = spiHardwareMap[device].dev; + + spiDataReadyDmaStop(&h->streams); + CLEAR_BIT(instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + + // A read stopped half way leaves bytes behind: send them and drop what comes back, or the main + // loop's next transfer would take it for its own + for (int timeout = 1000; timeout && (LL_SPI_GetTxFIFOLevel(instance) != LL_SPI_TX_FIFO_EMPTY || LL_SPI_IsActiveFlag_BSY(instance)); timeout--); + for (int n = 0; n < 8 && LL_SPI_GetRxFIFOLevel(instance) != LL_SPI_RX_FIFO_EMPTY; n++) { + (void)LL_SPI_ReceiveData8(instance); + } +} + +void spiDataReadyHwDisable(SPIDevice device) +{ + spiDataReadyDmaDisable(&spiDataReadyHw[device].streams); +} +#endif #endif void spiSetSpeed(SPI_TypeDef *instance, SPIClockSpeed_e speed) diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index 149922dd18c..c5ab8f34ed3 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -353,7 +353,7 @@ groups: field: gyro_secondary_enabled type: bool - name: gyro_data_ready - description: "Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin. AUTO and ON do it, OFF polls the gyro." + description: "Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin. AUTO does it on H7. On F4 and F7 the read goes through DMA and is new: set ON to try it, and please report how it works. OFF polls the gyro everywhere." default_value: "AUTO" condition: USE_SPI_DATA_READY field: gyro_data_ready diff --git a/src/main/target/common.h b/src/main/target/common.h index b2c31746e48..59bc211aa0d 100644 --- a/src/main/target/common.h +++ b/src/main/target/common.h @@ -18,7 +18,7 @@ #pragma once // SPI reads started by a device's data-ready interrupt (drivers/bus_spi_data_ready.c) -#if defined(STM32H7) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) #define USE_SPI_DATA_READY #endif From 697e995e50d37a3aa8281a1a5d7a9c87f1a75628 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 12:24:09 +0200 Subject: [PATCH 02/19] targets: gyro data-ready pins on F4 and F7 boards Pins added where INAV and Betaflight's config for the same board agree on the gyro's CS pin and SPI bus. In a folder with several targets the pin goes only to those Betaflight confirms. Two targets had a pin that disagreed with Betaflight and is fixed: KAKUTEF4WING (PB12, now PB2) and AOCODARCF405AIO (PC5, now PC4, as on the rest of the Aocoda F405 family, where PC5 is a PINIO). INAV never read those pins, so the wrong values never showed. --- src/main/target/AIKONF4V2/target.h | 1 + src/main/target/AOCODARCF405AIO/target.h | 6 +++--- src/main/target/AOCODARCF722AIO/target.c | 2 +- src/main/target/AXISFLYINGF7PRO/target.h | 1 + src/main/target/BETAFPVF722/target.h | 1 + src/main/target/BLADE_F4/target.h | 1 + src/main/target/BOTWINGF405/target.h | 1 + src/main/target/BOTWINGF722/target.h | 1 + src/main/target/BROTHERHOBBYF405V3/target.h | 1 + src/main/target/CADDXF4_AIO_ELRS/target.h | 1 + src/main/target/DAKEFPVF405/target.h | 1 + src/main/target/DAKEFPVF722/target.h | 1 + src/main/target/FLASHHOBBYF405/target.h | 1 + src/main/target/FLASHHOBBYF722/target.h | 1 + src/main/target/FLYWOOF405PRO/target.h | 1 + src/main/target/FLYWOOF722PRO/target.c | 2 +- src/main/target/FLYWOOF722PRO/target.h | 1 + src/main/target/FLYWOOF745/target.h | 1 + src/main/target/FOXEERF405V2/target.h | 1 + src/main/target/FOXEERF722V4/target.h | 1 + src/main/target/FOXEERF745AIO/target.h | 1 + src/main/target/FURYF4OSD/target.h | 3 +++ src/main/target/GEPRCF405/target.h | 1 + src/main/target/GEPRCF405_BT_HD/target.h | 1 + src/main/target/GEPRCF722/target.h | 1 + src/main/target/GEPRCF722_BT_HD/target.h | 1 + src/main/target/GEPRCF745_BT_HD/target.c | 8 ++++---- src/main/target/GEPRCF745_BT_HD/target.h | 2 ++ src/main/target/GEPRC_F722_AIO/target.h | 1 + src/main/target/HAKRCF405D/target.c | 2 +- src/main/target/HAKRCF405D/target.h | 1 + src/main/target/HAKRCF405V2/target.h | 1 + src/main/target/HAKRCF411D/target.h | 1 + src/main/target/HAKRCF722V2/target.c | 12 ++++++------ src/main/target/HAKRCF722V2/target.h | 2 ++ src/main/target/HGLRCF405V2/target.h | 1 + src/main/target/HUMMINGBIRD_FC305/target.c | 2 +- src/main/target/HUMMINGBIRD_FC305/target.h | 1 + src/main/target/IFLIGHT_BLITZ_F722/target.h | 1 + src/main/target/IFLIGHT_BLITZ_F722_X1/target.h | 1 + src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h | 1 + src/main/target/JHEF405PRO/target.h | 1 + src/main/target/KAKUTEF4/target.h | 3 +++ src/main/target/KAKUTEF4WING/target.h | 2 +- src/main/target/MAMBAF405_2022A/target.h | 1 + src/main/target/MAMBAF722_2022A/target.h | 1 + src/main/target/MATEKF405SE/target.h | 1 + src/main/target/MATEKF405TE/target.h | 1 + src/main/target/PRINCIPIOTF7/target.h | 1 + src/main/target/RADIOLINKF405/target.h | 1 + src/main/target/RADIOLINKF722/target.c | 2 +- src/main/target/RADIOLINKF722/target.h | 1 + src/main/target/SKYSTARSF405HD/target.h | 3 +++ src/main/target/SKYSTARSF405V2/target.h | 1 + src/main/target/SOLOGOODF722/target.h | 1 + src/main/target/SPEDIXF405/target.h | 1 + src/main/target/SPEDIXF722/target.h | 1 + src/main/target/SPEEDYBEEF405AIO/target.h | 1 + src/main/target/SPEEDYBEEF405MINI/target.h | 1 + src/main/target/SPEEDYBEEF405V4/target.c | 2 +- src/main/target/SPEEDYBEEF405V4/target.h | 1 + src/main/target/TAKERF722SE/target.h | 1 + src/main/target/TMOTORF7/target.h | 3 +++ src/main/target/TMOTORF7V2/target.h | 1 + src/main/target/TMOTORVELOXF7V2/target.h | 1 + src/main/target/WARPF7/target.h | 1 + 66 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/main/target/AIKONF4V2/target.h b/src/main/target/AIKONF4V2/target.h index a93415371bd..d2c2ff7c0bc 100644 --- a/src/main/target/AIKONF4V2/target.h +++ b/src/main/target/AIKONF4V2/target.h @@ -96,6 +96,7 @@ #define IMU_MPU6000_ALIGN CW0_DEG #define USE_IMU_ICM42605 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 #define IMU_ICM42605_ALIGN CW90_DEG // OSD diff --git a/src/main/target/AOCODARCF405AIO/target.h b/src/main/target/AOCODARCF405AIO/target.h index d732ebdd042..f7593f11ffd 100644 --- a/src/main/target/AOCODARCF405AIO/target.h +++ b/src/main/target/AOCODARCF405AIO/target.h @@ -65,19 +65,19 @@ #define USE_IMU_MPU6500 #define MPU6500_CS_PIN PA4 #define MPU6500_SPI_BUS BUS_SPI1 -#define MPU6500_EXTI_PIN PC5 +#define MPU6500_EXTI_PIN PC4 #define IMU_MPU6500_ALIGN CW90_DEG #define USE_IMU_MPU6000 #define MPU6000_CS_PIN PA4 #define MPU6000_SPI_BUS BUS_SPI1 -#define MPU6000_EXTI_PIN PC5 +#define MPU6000_EXTI_PIN PC4 #define IMU_MPU6000_ALIGN CW90_DEG #define USE_IMU_BMI270 #define BMI270_CS_PIN PA4 #define BMI270_SPI_BUS BUS_SPI1 -#define BMI270_EXTI_PIN PC5 +#define BMI270_EXTI_PIN PC4 #define IMU_BMI270_ALIGN CW90_DEG /*** I2C (Baro & Mag) ***/ diff --git a/src/main/target/AOCODARCF722AIO/target.c b/src/main/target/AOCODARCF722AIO/target.c index 84ccbfd6708..7ec1ee6880a 100644 --- a/src/main/target/AOCODARCF722AIO/target.c +++ b/src/main/target/AOCODARCF722AIO/target.c @@ -26,7 +26,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6500, DEVHW_MPU6500, MPU6500_SPI_BUS, MPU6500_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6500_ALIGN); BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, ICM42605_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); timerHardware_t timerHardware[] = { // DEF_TIM(TIM9, CH2, PA3, TIM_USE_PPM, 0, 0), // PPM diff --git a/src/main/target/AXISFLYINGF7PRO/target.h b/src/main/target/AXISFLYINGF7PRO/target.h index 39c94e47e9a..d40c74483f8 100644 --- a/src/main/target/AXISFLYINGF7PRO/target.h +++ b/src/main/target/AXISFLYINGF7PRO/target.h @@ -57,6 +57,7 @@ #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW0_DEG diff --git a/src/main/target/BETAFPVF722/target.h b/src/main/target/BETAFPVF722/target.h index cab6d2ff146..886b2659036 100755 --- a/src/main/target/BETAFPVF722/target.h +++ b/src/main/target/BETAFPVF722/target.h @@ -44,6 +44,7 @@ #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW180_DEG diff --git a/src/main/target/BLADE_F4/target.h b/src/main/target/BLADE_F4/target.h index 71cf76cc0cf..125f1327897 100644 --- a/src/main/target/BLADE_F4/target.h +++ b/src/main/target/BLADE_F4/target.h @@ -69,6 +69,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 //BMI270 #define USE_IMU_BMI270 diff --git a/src/main/target/BOTWINGF405/target.h b/src/main/target/BOTWINGF405/target.h index f4860c653a5..7e4312c753f 100644 --- a/src/main/target/BOTWINGF405/target.h +++ b/src/main/target/BOTWINGF405/target.h @@ -73,6 +73,7 @@ */ #define USE_IMU_ICM42605 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 #define IMU_ICM42605_ALIGN CW0_DEG diff --git a/src/main/target/BOTWINGF722/target.h b/src/main/target/BOTWINGF722/target.h index 2d3823f2a04..e31d6859074 100644 --- a/src/main/target/BOTWINGF722/target.h +++ b/src/main/target/BOTWINGF722/target.h @@ -46,6 +46,7 @@ // #define ICM42605_CS_PIN SPI3_NSS_PIN #define ICM42605_CS_PIN PD2 +#define ICM42605_EXTI_PIN PC13 #define ICM42605_SPI_BUS BUS_SPI3 #define USE_BEEPER diff --git a/src/main/target/BROTHERHOBBYF405V3/target.h b/src/main/target/BROTHERHOBBYF405V3/target.h index 9a9115bbf36..d01b4789af9 100644 --- a/src/main/target/BROTHERHOBBYF405V3/target.h +++ b/src/main/target/BROTHERHOBBYF405V3/target.h @@ -97,6 +97,7 @@ // Gyro & ACC #define USE_IMU_ICM42605 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 #define IMU_ICM42605_ALIGN CW90_DEG diff --git a/src/main/target/CADDXF4_AIO_ELRS/target.h b/src/main/target/CADDXF4_AIO_ELRS/target.h index 85a1718f684..0a46b81eb4a 100644 --- a/src/main/target/CADDXF4_AIO_ELRS/target.h +++ b/src/main/target/CADDXF4_AIO_ELRS/target.h @@ -35,6 +35,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 #define USE_BARO diff --git a/src/main/target/DAKEFPVF405/target.h b/src/main/target/DAKEFPVF405/target.h index 30834b7682b..9f6c37cbf95 100644 --- a/src/main/target/DAKEFPVF405/target.h +++ b/src/main/target/DAKEFPVF405/target.h @@ -66,6 +66,7 @@ #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW90_DEG diff --git a/src/main/target/DAKEFPVF722/target.h b/src/main/target/DAKEFPVF722/target.h index 7d993971a40..ddf980860ca 100644 --- a/src/main/target/DAKEFPVF722/target.h +++ b/src/main/target/DAKEFPVF722/target.h @@ -66,6 +66,7 @@ #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW90_DEG diff --git a/src/main/target/FLASHHOBBYF405/target.h b/src/main/target/FLASHHOBBYF405/target.h index 937917c95c1..8f71f0967f1 100644 --- a/src/main/target/FLASHHOBBYF405/target.h +++ b/src/main/target/FLASHHOBBYF405/target.h @@ -49,6 +49,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/FLASHHOBBYF722/target.h b/src/main/target/FLASHHOBBYF722/target.h index f0cc7881352..7a816fc85f4 100644 --- a/src/main/target/FLASHHOBBYF722/target.h +++ b/src/main/target/FLASHHOBBYF722/target.h @@ -47,6 +47,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/FLYWOOF405PRO/target.h b/src/main/target/FLYWOOF405PRO/target.h index 22ddd0a6fd2..4fd4ee9fbfa 100644 --- a/src/main/target/FLYWOOF405PRO/target.h +++ b/src/main/target/FLYWOOF405PRO/target.h @@ -50,6 +50,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG_FLIP #define ICM42605_CS_PIN PB12 +#define ICM42605_EXTI_PIN GYRO_INT_EXTI #define ICM42605_SPI_BUS BUS_SPI1 #define USE_EXTI diff --git a/src/main/target/FLYWOOF722PRO/target.c b/src/main/target/FLYWOOF722PRO/target.c index e8b78979f95..7eba2b3344e 100644 --- a/src/main/target/FLYWOOF722PRO/target.c +++ b/src/main/target/FLYWOOF722PRO/target.c @@ -27,7 +27,7 @@ BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_ICM42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_ICM42605, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, ICM42605_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); BUSDEV_REGISTER_SPI_TAG(busdev_BMI270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); timerHardware_t timerHardware[] = { diff --git a/src/main/target/FLYWOOF722PRO/target.h b/src/main/target/FLYWOOF722PRO/target.h index 3f11b44e317..0db06779723 100644 --- a/src/main/target/FLYWOOF722PRO/target.h +++ b/src/main/target/FLYWOOF722PRO/target.h @@ -42,6 +42,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC3 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW180_DEG diff --git a/src/main/target/FLYWOOF745/target.h b/src/main/target/FLYWOOF745/target.h index d00c2455945..a54899f5f02 100644 --- a/src/main/target/FLYWOOF745/target.h +++ b/src/main/target/FLYWOOF745/target.h @@ -49,6 +49,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN SPI4_NSS_PIN +#define ICM42605_EXTI_PIN PE1 #define ICM42605_SPI_BUS BUS_SPI4 #define USB_IO diff --git a/src/main/target/FOXEERF405V2/target.h b/src/main/target/FOXEERF405V2/target.h index 1b0a3e65134..93b787cf418 100644 --- a/src/main/target/FOXEERF405V2/target.h +++ b/src/main/target/FOXEERF405V2/target.h @@ -76,6 +76,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 diff --git a/src/main/target/FOXEERF722V4/target.h b/src/main/target/FOXEERF722V4/target.h index fe6d4279d26..d764f3399d8 100644 --- a/src/main/target/FOXEERF722V4/target.h +++ b/src/main/target/FOXEERF722V4/target.h @@ -31,6 +31,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PB2 +#define ICM42605_EXTI_PIN PC4 #define USE_IMU_MPU6000 #define IMU_MPU6000_ALIGN CW270_DEG diff --git a/src/main/target/FOXEERF745AIO/target.h b/src/main/target/FOXEERF745AIO/target.h index 860ea18d861..43886731db3 100644 --- a/src/main/target/FOXEERF745AIO/target.h +++ b/src/main/target/FOXEERF745AIO/target.h @@ -32,6 +32,7 @@ #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_SPI_BUS BUS_SPI3 #define ICM42605_CS_PIN PA15 +#define ICM42605_EXTI_PIN PD0 #else diff --git a/src/main/target/FURYF4OSD/target.h b/src/main/target/FURYF4OSD/target.h index 71abc9a8c68..6b6b3f6d8a9 100644 --- a/src/main/target/FURYF4OSD/target.h +++ b/src/main/target/FURYF4OSD/target.h @@ -50,6 +50,9 @@ #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#ifndef MAMBAF405 +#define ICM42605_EXTI_PIN PC4 +#endif #define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT #define USE_SPI_DEVICE_3 diff --git a/src/main/target/GEPRCF405/target.h b/src/main/target/GEPRCF405/target.h index 0b96d5b8b1e..f35a4bd7e8c 100644 --- a/src/main/target/GEPRCF405/target.h +++ b/src/main/target/GEPRCF405/target.h @@ -54,6 +54,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN PA15 +#define ICM42605_EXTI_PIN PC3 #define ICM42605_SPI_BUS BUS_SPI3 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/GEPRCF405_BT_HD/target.h b/src/main/target/GEPRCF405_BT_HD/target.h index 185a3970a11..e76ce06e305 100644 --- a/src/main/target/GEPRCF405_BT_HD/target.h +++ b/src/main/target/GEPRCF405_BT_HD/target.h @@ -52,6 +52,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN PA15 +#define ICM42605_EXTI_PIN PC3 #define ICM42605_SPI_BUS BUS_SPI3 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/GEPRCF722/target.h b/src/main/target/GEPRCF722/target.h index df7cc6d3eca..a0ca42a6bbc 100644 --- a/src/main/target/GEPRCF722/target.h +++ b/src/main/target/GEPRCF722/target.h @@ -51,6 +51,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN PA15 +#define ICM42605_EXTI_PIN PC3 #define ICM42605_SPI_BUS BUS_SPI3 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/GEPRCF722_BT_HD/target.h b/src/main/target/GEPRCF722_BT_HD/target.h index e388203c6aa..450324aff43 100644 --- a/src/main/target/GEPRCF722_BT_HD/target.h +++ b/src/main/target/GEPRCF722_BT_HD/target.h @@ -49,6 +49,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN PA15 +#define ICM42605_EXTI_PIN PA8 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/GEPRCF745_BT_HD/target.c b/src/main/target/GEPRCF745_BT_HD/target.c index 91f9957fefc..de23e37be15 100644 --- a/src/main/target/GEPRCF745_BT_HD/target.c +++ b/src/main/target/GEPRCF745_BT_HD/target.c @@ -26,11 +26,11 @@ #include "drivers/sensor.h" -BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, IMU1_SPI_BUS, IMU1_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU1_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000_2, DEVHW_MPU6000, IMU2_SPI_BUS, IMU2_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU2_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, IMU1_SPI_BUS, IMU1_CS_PIN, IMU1_EXTI_PIN, 0, DEVFLAGS_NONE, IMU1_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000_2, DEVHW_MPU6000, IMU2_SPI_BUS, IMU2_CS_PIN, IMU2_EXTI_PIN, 1, DEVFLAGS_NONE, IMU2_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, IMU1_SPI_BUS, IMU1_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU1_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688_2, DEVHW_ICM42605, IMU2_SPI_BUS, IMU2_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU2_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, IMU1_SPI_BUS, IMU1_CS_PIN, IMU1_EXTI_PIN, 0, DEVFLAGS_NONE, IMU1_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688_2, DEVHW_ICM42605, IMU2_SPI_BUS, IMU2_CS_PIN, IMU2_EXTI_PIN, 1, DEVFLAGS_NONE, IMU2_ALIGN); diff --git a/src/main/target/GEPRCF745_BT_HD/target.h b/src/main/target/GEPRCF745_BT_HD/target.h index c6c84a32ad3..dbd5772c40e 100644 --- a/src/main/target/GEPRCF745_BT_HD/target.h +++ b/src/main/target/GEPRCF745_BT_HD/target.h @@ -65,6 +65,7 @@ #define IMU1_ALIGN CW180_DEG #define IMU1_SPI_BUS BUS_SPI1 #define IMU1_CS_PIN PA4 +#define IMU1_EXTI_PIN PD0 @@ -72,6 +73,7 @@ #define IMU2_ALIGN CW0_DEG #define IMU2_SPI_BUS BUS_SPI2 #define IMU2_CS_PIN PB12 +#define IMU2_EXTI_PIN PD8 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/GEPRC_F722_AIO/target.h b/src/main/target/GEPRC_F722_AIO/target.h index ee2b9330552..eed916d473f 100644 --- a/src/main/target/GEPRC_F722_AIO/target.h +++ b/src/main/target/GEPRC_F722_AIO/target.h @@ -53,6 +53,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_CS_PIN PA15 +#define ICM42605_EXTI_PIN PA8 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/HAKRCF405D/target.c b/src/main/target/HAKRCF405D/target.c index 14447efed4b..ffdecfc6c64 100644 --- a/src/main/target/HAKRCF405D/target.c +++ b/src/main/target/HAKRCF405D/target.c @@ -25,7 +25,7 @@ #include "drivers/sensor.h" BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, ICM42605_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, MPU6000_SPI_BUS, MPU6000_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); diff --git a/src/main/target/HAKRCF405D/target.h b/src/main/target/HAKRCF405D/target.h index d47ec61dc99..f626ab22d85 100644 --- a/src/main/target/HAKRCF405D/target.h +++ b/src/main/target/HAKRCF405D/target.h @@ -67,6 +67,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC3 //BMI270 #define USE_IMU_BMI270 diff --git a/src/main/target/HAKRCF405V2/target.h b/src/main/target/HAKRCF405V2/target.h index 85cc164230b..e48a6e7c3a2 100644 --- a/src/main/target/HAKRCF405V2/target.h +++ b/src/main/target/HAKRCF405V2/target.h @@ -68,6 +68,7 @@ #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 //BMI270 #define USE_IMU_BMI270 diff --git a/src/main/target/HAKRCF411D/target.h b/src/main/target/HAKRCF411D/target.h index 5b3a479ed19..a67932cb9c5 100644 --- a/src/main/target/HAKRCF411D/target.h +++ b/src/main/target/HAKRCF411D/target.h @@ -59,6 +59,7 @@ #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PA1 //BMI270 #define USE_IMU_BMI270 diff --git a/src/main/target/HAKRCF722V2/target.c b/src/main/target/HAKRCF722V2/target.c index 9738db56d0c..14ef569f08f 100644 --- a/src/main/target/HAKRCF722V2/target.c +++ b/src/main/target/HAKRCF722V2/target.c @@ -23,14 +23,14 @@ #include "drivers/sensor.h" #include "drivers/pwm_mapping.h" -BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, GYRO_SPI_BUS, GYRO1_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000_2, DEVHW_MPU6000, GYRO_SPI_BUS, GYRO2_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000, DEVHW_MPU6000, GYRO_SPI_BUS, GYRO1_CS_PIN, GYRO1_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_mpu6000_2, DEVHW_MPU6000, GYRO_SPI_BUS, GYRO2_CS_PIN, GYRO2_EXTI_PIN, 1, DEVFLAGS_NONE, IMU_MPU6000_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, GYRO_SPI_BUS, GYRO1_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688_2, DEVHW_ICM42605, GYRO_SPI_BUS, GYRO2_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, GYRO_SPI_BUS, GYRO1_CS_PIN, GYRO1_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688_2, DEVHW_ICM42605, GYRO_SPI_BUS, GYRO2_CS_PIN, GYRO2_EXTI_PIN, 1, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, GYRO_SPI_BUS, GYRO1_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_bmi270_2, DEVHW_BMI270, GYRO_SPI_BUS, GYRO2_CS_PIN, NONE, 1, DEVFLAGS_NONE, IMU_BMI270_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, GYRO_SPI_BUS, GYRO1_CS_PIN, GYRO1_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_bmi270_2, DEVHW_BMI270, GYRO_SPI_BUS, GYRO2_CS_PIN, GYRO2_EXTI_PIN, 1, DEVFLAGS_NONE, IMU_BMI270_ALIGN); timerHardware_t timerHardware[] = { DEF_TIM(TIM8, CH3, PC8, TIM_USE_OUTPUT_AUTO, 0, 0), // S1 diff --git a/src/main/target/HAKRCF722V2/target.h b/src/main/target/HAKRCF722V2/target.h index 52c07b6545a..814cfa65d5a 100644 --- a/src/main/target/HAKRCF722V2/target.h +++ b/src/main/target/HAKRCF722V2/target.h @@ -63,7 +63,9 @@ #define GYRO_SPI_BUS BUS_SPI1 #define GYRO1_CS_PIN SPI1_NSS1_PIN +#define GYRO1_EXTI_PIN PC4 #define GYRO2_CS_PIN SPI1_NSS2_PIN +#define GYRO2_EXTI_PIN PB10 // MPU6000 #define USE_IMU_MPU6000 diff --git a/src/main/target/HGLRCF405V2/target.h b/src/main/target/HGLRCF405V2/target.h index 9f3a02b48f7..8d427eedb2c 100644 --- a/src/main/target/HGLRCF405V2/target.h +++ b/src/main/target/HGLRCF405V2/target.h @@ -66,6 +66,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 /*** OSD ***/ #define USE_MAX7456 diff --git a/src/main/target/HUMMINGBIRD_FC305/target.c b/src/main/target/HUMMINGBIRD_FC305/target.c index 275d3f27935..f97f1e1e549 100644 --- a/src/main/target/HUMMINGBIRD_FC305/target.c +++ b/src/main/target/HUMMINGBIRD_FC305/target.c @@ -24,7 +24,7 @@ #include "drivers/bus.h" #include "drivers/sensor.h" -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, ICM42605_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); BUSDEV_REGISTER_SPI(busdev_sdcard_spi, DEVHW_SDCARD, SDCARD_SPI_BUS, SDCARD_CS_PIN, NONE, DEVFLAGS_SPI_MODE_0, 0); BUSDEV_REGISTER_SPI(busdev_max7456, DEVHW_MAX7456, MAX7456_SPI_BUS, MAX7456_CS_PIN, NONE, DEVFLAGS_USE_RAW_REGISTERS, 0); BUSDEV_REGISTER_I2C(busdev_dps310, DEVHW_DPS310, BARO_I2C_BUS, DPS310_I2C_ADDR, NONE, DEVFLAGS_NONE, 0); diff --git a/src/main/target/HUMMINGBIRD_FC305/target.h b/src/main/target/HUMMINGBIRD_FC305/target.h index 7b121a775b2..52fd3e7fddf 100644 --- a/src/main/target/HUMMINGBIRD_FC305/target.h +++ b/src/main/target/HUMMINGBIRD_FC305/target.h @@ -46,6 +46,7 @@ #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_SPI_BUS BUS_SPI2 #define ICM42605_CS_PIN SPI2_NSS_PIN +#define ICM42605_EXTI_PIN PB6 // *************** I2C /Baro/Mag ********************* #define USE_I2C diff --git a/src/main/target/IFLIGHT_BLITZ_F722/target.h b/src/main/target/IFLIGHT_BLITZ_F722/target.h index cea6b4422ac..bac54b97841 100644 --- a/src/main/target/IFLIGHT_BLITZ_F722/target.h +++ b/src/main/target/IFLIGHT_BLITZ_F722/target.h @@ -46,6 +46,7 @@ #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 // *************** I2C /Baro/Mag ********************* #define USE_I2C diff --git a/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h b/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h index 03196254420..200ec9c14c7 100644 --- a/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h +++ b/src/main/target/IFLIGHT_BLITZ_F722_X1/target.h @@ -42,6 +42,7 @@ #define IMU_ICM42605_ALIGN CW90_DEG_FLIP #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 // *************** I2C /Baro/Mag ********************* #define USE_I2C diff --git a/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h b/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h index 69ea37e5357..aac23727644 100644 --- a/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h +++ b/src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h @@ -67,6 +67,7 @@ #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PD0 // *************** I2C/Baro/Mag ********************* #define USE_I2C diff --git a/src/main/target/JHEF405PRO/target.h b/src/main/target/JHEF405PRO/target.h index 43547cd2efa..4d288f83a44 100644 --- a/src/main/target/JHEF405PRO/target.h +++ b/src/main/target/JHEF405PRO/target.h @@ -33,6 +33,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_CS_PIN PB12 +#define ICM42605_EXTI_PIN GYRO_INT_EXTI #define ICM42605_SPI_BUS BUS_SPI1 #define USE_EXTI diff --git a/src/main/target/KAKUTEF4/target.h b/src/main/target/KAKUTEF4/target.h index 92cbcf13414..345b3fa5a3a 100644 --- a/src/main/target/KAKUTEF4/target.h +++ b/src/main/target/KAKUTEF4/target.h @@ -60,6 +60,9 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN PC4 +#if defined(KAKUTEF4) || defined(KAKUTEF4V2) +#define ICM42605_EXTI_PIN PC5 +#endif #define ICM42605_SPI_BUS BUS_SPI1 #if defined(KAKUTEF4V2) || defined(KAKUTEF4V23) || defined(KAKUTEF4V24) diff --git a/src/main/target/KAKUTEF4WING/target.h b/src/main/target/KAKUTEF4WING/target.h index 70eb125646a..fde9f45fbd8 100644 --- a/src/main/target/KAKUTEF4WING/target.h +++ b/src/main/target/KAKUTEF4WING/target.h @@ -37,7 +37,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 -#define ICM42605_EXTI_PIN PB12 +#define ICM42605_EXTI_PIN PB2 // *************** I2C **************** #define USE_I2C diff --git a/src/main/target/MAMBAF405_2022A/target.h b/src/main/target/MAMBAF405_2022A/target.h index 5a24771288d..8f836ff378e 100644 --- a/src/main/target/MAMBAF405_2022A/target.h +++ b/src/main/target/MAMBAF405_2022A/target.h @@ -60,6 +60,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #endif diff --git a/src/main/target/MAMBAF722_2022A/target.h b/src/main/target/MAMBAF722_2022A/target.h index cf834b11ea6..617aae32305 100644 --- a/src/main/target/MAMBAF722_2022A/target.h +++ b/src/main/target/MAMBAF722_2022A/target.h @@ -64,6 +64,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #endif diff --git a/src/main/target/MATEKF405SE/target.h b/src/main/target/MATEKF405SE/target.h index 38c8f56f5d9..3a5cbb58142 100644 --- a/src/main/target/MATEKF405SE/target.h +++ b/src/main/target/MATEKF405SE/target.h @@ -46,6 +46,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG_FLIP #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C /Baro/Mag ********************* diff --git a/src/main/target/MATEKF405TE/target.h b/src/main/target/MATEKF405TE/target.h index fc7c1ad0ce9..2cdc3aadb57 100644 --- a/src/main/target/MATEKF405TE/target.h +++ b/src/main/target/MATEKF405TE/target.h @@ -45,6 +45,7 @@ #define IMU_ICM42605_ALIGN CW270_DEG_FLIP #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PC14 +#define ICM42605_EXTI_PIN PC15 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW270_DEG_FLIP diff --git a/src/main/target/PRINCIPIOTF7/target.h b/src/main/target/PRINCIPIOTF7/target.h index 0208f55a361..5e241023fde 100644 --- a/src/main/target/PRINCIPIOTF7/target.h +++ b/src/main/target/PRINCIPIOTF7/target.h @@ -113,6 +113,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_CS_PIN PB2 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // BARO diff --git a/src/main/target/RADIOLINKF405/target.h b/src/main/target/RADIOLINKF405/target.h index 9a1afd47739..270a6f6309e 100644 --- a/src/main/target/RADIOLINKF405/target.h +++ b/src/main/target/RADIOLINKF405/target.h @@ -39,6 +39,7 @@ #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define USE_IMU_BMI270 #define IMU_BMI270_ALIGN CW90_DEG diff --git a/src/main/target/RADIOLINKF722/target.c b/src/main/target/RADIOLINKF722/target.c index 6ebb384b046..8da44a3497c 100644 --- a/src/main/target/RADIOLINKF722/target.c +++ b/src/main/target/RADIOLINKF722/target.c @@ -29,7 +29,7 @@ #include "drivers/sensor.h" BUSDEV_REGISTER_SPI_TAG(busdev_bmi270, DEVHW_BMI270, BMI270_SPI_BUS, BMI270_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_BMI270_ALIGN); -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42688_SPI_BUS, ICM42688_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42688_SPI_BUS, ICM42688_CS_PIN, ICM42688_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); timerHardware_t timerHardware[] = { diff --git a/src/main/target/RADIOLINKF722/target.h b/src/main/target/RADIOLINKF722/target.h index efa3bdea750..e7345bfee38 100644 --- a/src/main/target/RADIOLINKF722/target.h +++ b/src/main/target/RADIOLINKF722/target.h @@ -76,6 +76,7 @@ #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42688_SPI_BUS BUS_SPI1 #define ICM42688_CS_PIN PB2 +#define ICM42688_EXTI_PIN PC4 //BMI270 #define USE_IMU_BMI270 diff --git a/src/main/target/SKYSTARSF405HD/target.h b/src/main/target/SKYSTARSF405HD/target.h index c3711fcb4c2..65767a4332d 100644 --- a/src/main/target/SKYSTARSF405HD/target.h +++ b/src/main/target/SKYSTARSF405HD/target.h @@ -46,6 +46,9 @@ #define USE_IMU_ICM42605 #define ICM42605_SPI_BUS BUS_SPI1 #define ICM42605_CS_PIN PA4 +#if defined(SKYSTARSF405AIO) +#define ICM42605_EXTI_PIN PC4 +#endif // *************** M25P256 flash ******************** #define USE_FLASHFS diff --git a/src/main/target/SKYSTARSF405V2/target.h b/src/main/target/SKYSTARSF405V2/target.h index 1fe4e2614c4..1591e4ff3e3 100644 --- a/src/main/target/SKYSTARSF405V2/target.h +++ b/src/main/target/SKYSTARSF405V2/target.h @@ -37,6 +37,7 @@ #define SPI1_MOSI_PIN PA7 #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG diff --git a/src/main/target/SOLOGOODF722/target.h b/src/main/target/SOLOGOODF722/target.h index dd017691ef3..b89527a7b71 100644 --- a/src/main/target/SOLOGOODF722/target.h +++ b/src/main/target/SOLOGOODF722/target.h @@ -49,6 +49,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/SPEDIXF405/target.h b/src/main/target/SPEDIXF405/target.h index 3f46890b48d..0140dfebd03 100644 --- a/src/main/target/SPEDIXF405/target.h +++ b/src/main/target/SPEDIXF405/target.h @@ -48,6 +48,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/SPEDIXF722/target.h b/src/main/target/SPEDIXF722/target.h index 511381587a0..c6d9ab071c7 100644 --- a/src/main/target/SPEDIXF722/target.h +++ b/src/main/target/SPEDIXF722/target.h @@ -49,6 +49,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN SPI1_NSS_PIN +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/SPEEDYBEEF405AIO/target.h b/src/main/target/SPEEDYBEEF405AIO/target.h index a6abdfcc37f..ca1991a018b 100644 --- a/src/main/target/SPEEDYBEEF405AIO/target.h +++ b/src/main/target/SPEEDYBEEF405AIO/target.h @@ -92,6 +92,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PE9 #define ICM42605_SPI_BUS BUS_SPI1 /* diff --git a/src/main/target/SPEEDYBEEF405MINI/target.h b/src/main/target/SPEEDYBEEF405MINI/target.h index c20ee9aa0ff..52541254a31 100644 --- a/src/main/target/SPEEDYBEEF405MINI/target.h +++ b/src/main/target/SPEEDYBEEF405MINI/target.h @@ -94,6 +94,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 /* diff --git a/src/main/target/SPEEDYBEEF405V4/target.c b/src/main/target/SPEEDYBEEF405V4/target.c index 2d398bd1bbe..926589f4482 100644 --- a/src/main/target/SPEEDYBEEF405V4/target.c +++ b/src/main/target/SPEEDYBEEF405V4/target.c @@ -32,7 +32,7 @@ #include "drivers/pinio.h" #include "drivers/sensor.h" -BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, NONE, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); +BUSDEV_REGISTER_SPI_TAG(busdev_icm42688, DEVHW_ICM42605, ICM42605_SPI_BUS, ICM42605_CS_PIN, ICM42605_EXTI_PIN, 0, DEVFLAGS_NONE, IMU_ICM42605_ALIGN); timerHardware_t timerHardware[] = { DEF_TIM(TIM4, CH1, PB6, TIM_USE_OUTPUT_AUTO, 1, 0), // S1 diff --git a/src/main/target/SPEEDYBEEF405V4/target.h b/src/main/target/SPEEDYBEEF405V4/target.h index 1c5c847597f..2130ddde499 100644 --- a/src/main/target/SPEEDYBEEF405V4/target.h +++ b/src/main/target/SPEEDYBEEF405V4/target.h @@ -88,6 +88,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW90_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C(Baro & I2C) ************************** diff --git a/src/main/target/TAKERF722SE/target.h b/src/main/target/TAKERF722SE/target.h index 599d5610ad4..09007ab930e 100644 --- a/src/main/target/TAKERF722SE/target.h +++ b/src/main/target/TAKERF722SE/target.h @@ -104,6 +104,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // *************** I2C/Baro/Mag ********************* diff --git a/src/main/target/TMOTORF7/target.h b/src/main/target/TMOTORF7/target.h index a62b42d0990..109b998f134 100644 --- a/src/main/target/TMOTORF7/target.h +++ b/src/main/target/TMOTORF7/target.h @@ -47,6 +47,9 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN PA4 +#ifdef TMOTORF7 +#define ICM42605_EXTI_PIN PC4 +#endif #define ICM42605_SPI_BUS BUS_SPI1 #define USE_IMU_BMI270 diff --git a/src/main/target/TMOTORF7V2/target.h b/src/main/target/TMOTORF7V2/target.h index f5def98a403..2a37231dff3 100644 --- a/src/main/target/TMOTORF7V2/target.h +++ b/src/main/target/TMOTORF7V2/target.h @@ -70,6 +70,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW0_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // OSD -- SPI2 diff --git a/src/main/target/TMOTORVELOXF7V2/target.h b/src/main/target/TMOTORVELOXF7V2/target.h index 09f30857ec8..9207e5e88e5 100644 --- a/src/main/target/TMOTORVELOXF7V2/target.h +++ b/src/main/target/TMOTORVELOXF7V2/target.h @@ -50,6 +50,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN PB2 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 diff --git a/src/main/target/WARPF7/target.h b/src/main/target/WARPF7/target.h index e06d6e2ae1d..b535af98f33 100644 --- a/src/main/target/WARPF7/target.h +++ b/src/main/target/WARPF7/target.h @@ -107,6 +107,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN PA4 +#define ICM42605_EXTI_PIN PC4 #define ICM42605_SPI_BUS BUS_SPI1 // BARO From b26c9f7ac47d72370a2194f76fad81283133af85 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 12:24:10 +0200 Subject: [PATCH 03/19] gyro: read the ICM426xx through its FIFO on data-ready gyro_fifo_samples (0 to 4, default 0: register reads as before) lets the ICM426xx queue that many samples in its FIFO and raise its interrupt once for all of them. One read from FIFO_COUNTH brings the count and the packets, and the gyro task still gets every sample. A FIFO that falls behind or out of step is flushed from the gyro task. --- docs/Settings.md | 10 ++ src/main/drivers/accgyro/accgyro.h | 6 +- src/main/drivers/accgyro/accgyro_data_ready.c | 109 +++++++++++++++++- src/main/drivers/accgyro/accgyro_data_ready.h | 22 ++++ src/main/drivers/accgyro/accgyro_icm42605.c | 91 +++++++++++++++ src/main/drivers/bus_spi.c | 3 +- src/main/drivers/bus_spi_hal_ll.c | 3 +- src/main/fc/settings.yaml | 7 ++ src/main/sensors/gyro.c | 3 + src/main/sensors/gyro.h | 2 + 10 files changed, 247 insertions(+), 9 deletions(-) diff --git a/docs/Settings.md b/docs/Settings.md index f608fdc6c92..eb0cdb56ba2 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -2180,6 +2180,16 @@ Minimum frequency of the gyro Dynamic LPF --- +### gyro_fifo_samples + +With gyro_data_ready, the IMU queues this many samples in its FIFO and signals once for all of them, read in one transfer: fewer interrupts, and a sample read late is kept, but the older samples of a group wait up to that many sample periods. 0 reads each sample from the IMU's registers. ICM-42605 and ICM-42688-P. + +| Default | Min | Max | +| --- | --- | --- | +| 0 | 0 | 4 | + +--- + ### gyro_filter_mode Specifies the type of the software LPF of the gyro signals. diff --git a/src/main/drivers/accgyro/accgyro.h b/src/main/drivers/accgyro/accgyro.h index 310696517f0..b1e603aee44 100644 --- a/src/main/drivers/accgyro/accgyro.h +++ b/src/main/drivers/accgyro/accgyro.h @@ -36,8 +36,9 @@ typedef struct { uint8_t gyroConfigValues[2]; } gyroFilterAndRateConfig_t; -// 2 ms at 4 kHz: the interrupt brings samples at the sensor's rate, the task follows on average -#define GYRO_SAMPLE_QUEUE_LENGTH 8 +// Two reads' worth of FIFO samples (gyro_fifo_samples up to 4) plus margin: the interrupt brings +// them at the sensor's rate, the task only follows on average +#define GYRO_SAMPLE_QUEUE_LENGTH 16 // Whether a driver that can reads its gyro on the data-ready interrupt (gyro_data_ready) typedef enum { @@ -69,6 +70,7 @@ typedef struct gyroDev_s { // Set by gyro.c before initFn gyroDevDataReady_e readOnDataReady; bool readOnDataReadyWithAcc; + uint8_t dataReadyFifoSamples; // samples per interrupt through the IMU's FIFO, 0 for none // Set by a driver that can (accgyro_data_ready.h); started at the end of init const struct gyroDataReadyDriver_s *dataReadyDriver; // Set once reading on data-ready: readFn then returns false when no sample came, not a failure diff --git a/src/main/drivers/accgyro/accgyro_data_ready.c b/src/main/drivers/accgyro/accgyro_data_ready.c index 4eed429779f..e7cdb994801 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.c +++ b/src/main/drivers/accgyro/accgyro_data_ready.c @@ -30,6 +30,7 @@ #include "build/atomic.h" +#include "common/maths.h" #include "common/utils.h" #include "drivers/accgyro/accgyro.h" @@ -56,8 +57,20 @@ struct gyroDataReady_s { volatile int16_t temp; volatile timeUs_t lastSampleUs; timeUs_t resumedUs; // when a read after a pause turned the interrupt back on + uint8_t fifoSamples; // samples per interrupt through the IMU's FIFO, 0 for register reads + uint8_t fifoPackets; // packets each read brings: one more than that where it fits + uint8_t fifoPacketLen; + volatile bool fifoFlush; // the FIFO fell behind or out of step: empty it from the task + uint8_t fifoFruitlessReads; // reads in a row that found packets counted but no sample }; +// Reads in a row with packets counted but none held: out of step. One alone is normal (a packet +// counted just before it can be read); a read that found the queue full doesn't count +#define GYRO_DATA_READY_FIFO_FRUITLESS 4 + +// Further behind than this many reads' worth, the FIFO is emptied rather than caught up +#define GYRO_DATA_READY_FIFO_BEHIND 2 + // The primary gyro and the secondary static gyroDataReady_t gyroDataReady[2]; @@ -124,6 +137,59 @@ static void gyroDataReadySample(void *arg, const uint8_t *data) d->lastSampleUs = microsISR(); } +// The count, then fifoPackets packets, oldest first. Every packet read has left the FIFO, even +// one that came after the count, so all are decoded up to the first empty one +static void gyroDataReadyFifoSamples(void *arg, const uint8_t *data) +{ + gyroDataReady_t *d = arg; + const gyroDataReadyFifo_t *fifo = d->driver->fifo; + const uint16_t count = (data[0] << 8) | data[1]; + const uint8_t *packet = &data[2]; + int16_t gyro[XYZ_AXIS_COUNT]; + int16_t acc[XYZ_AXIS_COUNT]; + int16_t temp = 0; + + if (count > GYRO_DATA_READY_FIFO_BEHIND * d->fifoSamples) { + d->fifoFlush = true; + } + + unsigned pushed = 0; + for (unsigned i = 0; i < d->fifoPackets; i++, packet += d->fifoPacketLen) { + const gyroFifoPacket_e what = fifo->parse(packet, d->withAccAndTemp, gyro, acc, &temp); + if (what == GYRO_FIFO_PACKET_EMPTY) { + break; + } + if (what == GYRO_FIFO_PACKET_UNEXPECTED) { + d->fifoFlush = true; + break; + } + if (what == GYRO_FIFO_PACKET_INVALID) { + continue; + } + if (d->withAccAndTemp) { + d->acc[X] = acc[X]; + d->acc[Y] = acc[Y]; + d->acc[Z] = acc[Z]; + d->temp = temp; + } + if (!gyroSampleQueuePush(d->gyro, gyro[X], gyro[Y], gyro[Z])) { + EXTIEnable(d->gyro->busDev->irqPin, false); + d->paused = true; + break; + } + pushed++; + } + + if (pushed) { + d->fifoFruitlessReads = 0; + d->lastSampleUs = microsISR(); + } else if (count && !d->paused && ++d->fifoFruitlessReads >= GYRO_DATA_READY_FIFO_FRUITLESS) { + // Until the flush, and whenever no sample comes for a while, the task reads the registers + d->fifoFlush = true; + d->fifoFruitlessReads = 0; + } +} + static void gyroDataReadyExti(extiCallbackRec_t *cb) { gyroDataReady_t *d = (gyroDataReady_t *)cb; @@ -135,6 +201,22 @@ static bool gyroDataReadyRead(gyroDev_t *gyro) { gyroDataReady_t *d = gyro->dataReadyState; + if (d->fifoSamples && (d->paused || d->fifoFlush)) { + // What the FIFO holds is old, or out of step with the reads + d->driver->fifo->flush(gyro); + d->fifoFlush = false; + if (d->paused) { + // No register read: a sample taken during the flush would come again from the FIFO + ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { + gyro->sampleQueueTail = gyro->sampleQueueHead; + d->paused = false; + EXTIEnable(gyro->busDev->irqPin, true); + } + d->resumedUs = micros(); + return false; + } + } + if (d->paused) { // After a pause the queue is old: turn the interrupt back on and read the registers ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { @@ -205,11 +287,28 @@ void gyroDataReadyStart(gyroDev_t *gyro) d->driver = driver; d->lastSampleUs = micros(); - d->withAccAndTemp = gyro->readOnDataReadyWithAcc && driver->withAccAndTemp.len; - if (!d->withAccAndTemp || !spiDataReadyInit(dev, driver->withAccAndTemp.reg, driver->withAccAndTemp.len, gyroDataReadySample, d)) { - d->withAccAndTemp = false; - if (!driver->gyroOnly.len || !spiDataReadyInit(dev, driver->gyroOnly.reg, driver->gyroOnly.len, gyroDataReadySample, d)) { - return; + const gyroDataReadyFifo_t *fifo = driver->fifo; + d->fifoSamples = 0; + if (gyro->dataReadyFifoSamples && fifo) { + d->withAccAndTemp = gyro->readOnDataReadyWithAcc && fifo->packetLen; + d->fifoPacketLen = d->withAccAndTemp ? fifo->packetLen : fifo->gyroOnlyPacketLen; + // One packet more than the threshold where it fits, or a read behind by one stays behind + for (d->fifoPackets = gyro->dataReadyFifoSamples + 1; d->fifoPacketLen && d->fifoPackets >= gyro->dataReadyFifoSamples; d->fifoPackets--) { + if (spiDataReadyInit(dev, fifo->countReg, 2 + d->fifoPackets * d->fifoPacketLen, gyroDataReadyFifoSamples, d)) { + d->fifoSamples = gyro->dataReadyFifoSamples; + fifo->start(gyro, d->withAccAndTemp, d->fifoSamples); + break; + } + } + } + + if (!d->fifoSamples) { + d->withAccAndTemp = gyro->readOnDataReadyWithAcc && driver->withAccAndTemp.len; + if (!d->withAccAndTemp || !spiDataReadyInit(dev, driver->withAccAndTemp.reg, driver->withAccAndTemp.len, gyroDataReadySample, d)) { + d->withAccAndTemp = false; + if (!driver->gyroOnly.len || !spiDataReadyInit(dev, driver->gyroOnly.reg, driver->gyroOnly.len, gyroDataReadySample, d)) { + return; + } } } d->gyro = gyro; diff --git a/src/main/drivers/accgyro/accgyro_data_ready.h b/src/main/drivers/accgyro/accgyro_data_ready.h index 721817c74e0..15577419be6 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.h +++ b/src/main/drivers/accgyro/accgyro_data_ready.h @@ -33,6 +33,27 @@ typedef struct gyroDataReadyRead_s { uint8_t len; // bytes after the address, 0 for no such read } gyroDataReadyRead_t; +// What one FIFO packet held +typedef enum { + GYRO_FIFO_PACKET_SAMPLE, // a sample + GYRO_FIFO_PACKET_INVALID, // a packet without a valid sample, such as one before the first ODR + GYRO_FIFO_PACKET_EMPTY, // counted a moment before but not there yet: it comes with the next read + GYRO_FIFO_PACKET_UNEXPECTED, // not a packet the FIFO was set up for: the reads are out of step +} gyroFifoPacket_e; + +// An IMU FIFO signalling once for several samples: one read from the count register brings the +// count and the packets after it +typedef struct gyroDataReadyFifo_s { + uint8_t countReg; // as sent (read bit included), the packets follow it + uint8_t packetLen; // with the accelerometer and temperature + uint8_t gyroOnlyPacketLen; + // Puts the samples in the FIFO and the interrupt on `samples` of them + void (*start)(gyroDev_t *gyro, bool withAccAndTemp, uint8_t samples); + // Empties the FIFO, from the gyro task + void (*flush)(gyroDev_t *gyro); + gyroFifoPacket_e (*parse)(const uint8_t *packet, bool withAccAndTemp, int16_t *gyro, int16_t *acc, int16_t *temp); +} gyroDataReadyFifo_t; + typedef struct gyroDataReadyDriver_s { gyroDataReadyRead_t withAccAndTemp; // the gyro with the accelerometer (and temperature) gyroDataReadyRead_t gyroOnly; @@ -40,6 +61,7 @@ typedef struct gyroDataReadyDriver_s { gyroDataReadyParseFn parse; sensorGyroReadFuncPtr registerRead; // the driver's own read, for when samples stop coming bool tested; // gyro_data_ready AUTO turns it on + const gyroDataReadyFifo_t *fifo; // NULL if the IMU has no FIFO this can use } gyroDataReadyDriver_t; typedef struct gyroDataReady_s gyroDataReady_t; diff --git a/src/main/drivers/accgyro/accgyro_icm42605.c b/src/main/drivers/accgyro/accgyro_icm42605.c index 1c657aa8b87..ec82971d8c3 100644 --- a/src/main/drivers/accgyro/accgyro_icm42605.c +++ b/src/main/drivers/accgyro/accgyro_icm42605.c @@ -162,6 +162,96 @@ static void setUserBank(const busDevice_t *dev, const uint8_t user_bank) #if defined(USE_SPI_DATA_READY) static bool icm42605GyroRead(gyroDev_t *gyro); +// FIFO, all in User Bank 0 +#define ICM426XX_RA_FIFO_CONFIG 0x16 +#define ICM426XX_FIFO_MODE_STREAM (1 << 6) +#define ICM426XX_RA_FIFO_COUNTH 0x2E +#define ICM426XX_RA_SIGNAL_PATH_RESET 0x4B +#define ICM426XX_FIFO_FLUSH (1 << 1) +#define ICM426XX_RA_INTF_CONFIG0 0x4C +#define ICM426XX_FIFO_COUNT_REC (1 << 6) +#define ICM426XX_RA_FIFO_CONFIG1 0x5F +#define ICM426XX_FIFO_WM_GT_TH (1 << 5) +#define ICM426XX_FIFO_TEMP_EN (1 << 2) +#define ICM426XX_FIFO_GYRO_EN (1 << 1) +#define ICM426XX_FIFO_ACCEL_EN (1 << 0) +#define ICM426XX_RA_FIFO_CONFIG2 0x60 +#define ICM426XX_RA_FIFO_CONFIG3 0x61 +#define ICM426XX_FIFO_THS_INT1_EN (1 << 2) +#define ICM426XX_FIFO_HEADER_EMPTY (1 << 7) +#define ICM426XX_FIFO_HEADER_ACCEL (1 << 6) +#define ICM426XX_FIFO_HEADER_GYRO (1 << 5) +#define ICM426XX_FIFO_HEADER_20 (1 << 4) +// What the FIFO holds for a sample that is not valid, such as one taken before the first ODR +#define ICM426XX_FIFO_INVALID_SAMPLE (-32768) + +// Packet 3, 16 bytes: header, accelerometer and gyro X, Y, Z big-endian, 8 bit temperature, +// timestamp. Packet 2, 8 bytes: header, gyro, temperature +#define ICM426XX_FIFO_PACKET3_SIZE 16 +#define ICM426XX_FIFO_PACKET2_SIZE 8 + +static void icm426xxFifoFlush(gyroDev_t *gyro) +{ + busWrite(gyro->busDev, ICM426XX_RA_SIGNAL_PATH_RESET, ICM426XX_FIFO_FLUSH); +} + +static void icm426xxFifoStart(gyroDev_t *gyro, bool withAccAndTemp, uint8_t samples) +{ + busDevice_t *dev = gyro->busDev; + uint8_t intfConfig0Value; + + // Count in packets; the interrupt again at every sample while `samples` or more are queued, + // so a read that fell behind catches up. Stream mode keeps the newest if it fills + busRead(dev, ICM426XX_RA_INTF_CONFIG0, &intfConfig0Value); + busWrite(dev, ICM426XX_RA_INTF_CONFIG0, intfConfig0Value | ICM426XX_FIFO_COUNT_REC); + busWrite(dev, ICM426XX_RA_FIFO_CONFIG1, ICM426XX_FIFO_WM_GT_TH | ICM426XX_FIFO_TEMP_EN | ICM426XX_FIFO_GYRO_EN | (withAccAndTemp ? ICM426XX_FIFO_ACCEL_EN : 0)); + busWrite(dev, ICM426XX_RA_FIFO_CONFIG2, samples); + busWrite(dev, ICM426XX_RA_FIFO_CONFIG3, 0); + busWrite(dev, ICM426XX_RA_FIFO_CONFIG, ICM426XX_FIFO_MODE_STREAM); + icm426xxFifoFlush(gyro); + busWrite(dev, ICM42605_RA_INT_SOURCE0, ICM426XX_FIFO_THS_INT1_EN); +} + +static gyroFifoPacket_e icm426xxFifoParse(const uint8_t *packet, bool withAccAndTemp, int16_t *gyro, int16_t *acc, int16_t *temp) +{ + const uint8_t header = packet[0]; + const uint8_t expected = ICM426XX_FIFO_HEADER_GYRO | (withAccAndTemp ? ICM426XX_FIFO_HEADER_ACCEL : 0); + + if (header & ICM426XX_FIFO_HEADER_EMPTY) { + return GYRO_FIFO_PACKET_EMPTY; + } + if ((header & (ICM426XX_FIFO_HEADER_ACCEL | ICM426XX_FIFO_HEADER_GYRO | ICM426XX_FIFO_HEADER_20)) != expected) { + return GYRO_FIFO_PACKET_UNEXPECTED; + } + + const uint8_t *axes = &packet[1]; + if (withAccAndTemp) { + acc[X] = int16_val_big_endian(axes, 0); + acc[Y] = int16_val_big_endian(axes, 1); + acc[Z] = int16_val_big_endian(axes, 2); + axes += 6; + } + gyro[X] = int16_val_big_endian(axes, 0); + gyro[Y] = int16_val_big_endian(axes, 1); + gyro[Z] = int16_val_big_endian(axes, 2); + // 8 bits at 2.07 per degree, where the register has 16 at 132.48: 64 times as much + *temp = (int16_t)((int8_t)axes[6] * 64); + + if (gyro[X] == ICM426XX_FIFO_INVALID_SAMPLE || gyro[Y] == ICM426XX_FIFO_INVALID_SAMPLE || gyro[Z] == ICM426XX_FIFO_INVALID_SAMPLE) { + return GYRO_FIFO_PACKET_INVALID; + } + return GYRO_FIFO_PACKET_SAMPLE; +} + +static const gyroDataReadyFifo_t icm426xxFifo = { + .countReg = ICM426XX_RA_FIFO_COUNTH | 0x80, + .packetLen = ICM426XX_FIFO_PACKET3_SIZE, + .gyroOnlyPacketLen = ICM426XX_FIFO_PACKET2_SIZE, + .start = icm426xxFifoStart, + .flush = icm426xxFifoFlush, + .parse = icm426xxFifoParse, +}; + // From TEMP_DATA1: temperature, accelerometer X, Y, Z, gyro X, Y, Z, big-endian static void icm426xxDataReadyParse(const uint8_t *data, bool withAccAndTemp, int16_t *gyro, int16_t *acc, int16_t *temp) { @@ -186,6 +276,7 @@ static const gyroDataReadyDriver_t icm426xxDataReady = { #if defined(STM32H7) .tested = true, #endif + .fifo = &icm426xxFifo, }; #endif diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 18f7a489cec..3fdadb4f4b4 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -256,7 +256,8 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len // DMA streams; the buffers stay out of the CCM RAM, which the DMA can not reach // Longest read, address included -#define SPI_DATA_READY_MAX 32 +// The address and up to four FIFO packets of 16 bytes after the count +#define SPI_DATA_READY_MAX 72 typedef struct { uint8_t len; // bytes after the address diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index 1f2ab33e5d4..f9b22ee0d21 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -497,7 +497,8 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *rxData, const uint8_t *txData, // reads, and all on F7 (4-byte FIFO), use two DMA streams // Longest read, address included -#define SPI_DATA_READY_MAX 32 +// The address and up to four FIFO packets of 16 bytes after the count +#define SPI_DATA_READY_MAX 72 typedef struct { uint8_t reg; // the first register, as sent (read bit included) diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index c5ab8f34ed3..230255d508e 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -358,6 +358,13 @@ groups: condition: USE_SPI_DATA_READY field: gyro_data_ready table: gyro_data_ready + - name: gyro_fifo_samples + description: "With gyro_data_ready, the IMU queues this many samples in its FIFO and signals once for all of them, read in one transfer: fewer interrupts, and a sample read late is kept, but the older samples of a group wait up to that many sample periods. 0 reads each sample from the IMU's registers. ICM-42605 and ICM-42688-P." + default_value: 0 + min: 0 + max: 4 + condition: USE_SPI_DATA_READY + field: gyro_fifo_samples - name: setpoint_kalman_enabled description: "Enable Kalman filter on the gyro data" default_value: ON diff --git a/src/main/sensors/gyro.c b/src/main/sensors/gyro.c index 0d315a5f9d6..ec2cdb91b40 100644 --- a/src/main/sensors/gyro.c +++ b/src/main/sensors/gyro.c @@ -132,6 +132,7 @@ PG_RESET_TEMPLATE(gyroConfig_t, gyroConfig, #endif #ifdef USE_SPI_DATA_READY .gyro_data_ready = SETTING_GYRO_DATA_READY_DEFAULT, + .gyro_fifo_samples = SETTING_GYRO_FIFO_SAMPLES_DEFAULT, #endif .gyro_main_lpf_hz = SETTING_GYRO_MAIN_LPF_HZ_DEFAULT, .gyroDynamicLpfMinHz = SETTING_GYRO_DYN_LPF_MIN_HZ_DEFAULT, @@ -390,6 +391,7 @@ bool gyroInit(void) #ifdef USE_SPI_DATA_READY gyroDev[0].readOnDataReady = gyroReadOnDataReady(); gyroDev[0].readOnDataReadyWithAcc = true; + gyroDev[0].dataReadyFifoSamples = gyroConfig()->gyro_fifo_samples; #endif gyroDevStart(&gyroDev[0]); @@ -412,6 +414,7 @@ bool gyroInit(void) #ifdef USE_SPI_DATA_READY // Its interrupt stays off while no log is written gyroDev[GYRO_SECONDARY].readOnDataReady = gyroReadOnDataReady(); + gyroDev[GYRO_SECONDARY].dataReadyFifoSamples = gyroConfig()->gyro_fifo_samples; #endif gyroDevStart(&gyroDev[GYRO_SECONDARY]); gyro.secondaryInitialized = true; diff --git a/src/main/sensors/gyro.h b/src/main/sensors/gyro.h index be665dcfa4e..554d667ddcf 100644 --- a/src/main/sensors/gyro.h +++ b/src/main/sensors/gyro.h @@ -121,6 +121,8 @@ typedef struct gyroConfig_s { #ifdef USE_SPI_DATA_READY // Appended too, so zero is the default: AUTO uint8_t gyro_data_ready; // gyroDataReady_e + // Samples the IMU queues in its FIFO before its interrupt, read together; 0 for none + uint8_t gyro_fifo_samples; #endif } gyroConfig_t; From 8eeefc1da18da2888ebfbe3f067d3a2599d5f23b Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:08:35 +0200 Subject: [PATCH 04/19] gyro: a data-ready that came during the last read starts nothing before a flash write --- src/main/drivers/accgyro/accgyro_data_ready.c | 1 + src/main/drivers/bus_spi.h | 2 ++ src/main/drivers/bus_spi_data_ready.c | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/src/main/drivers/accgyro/accgyro_data_ready.c b/src/main/drivers/accgyro/accgyro_data_ready.c index e7cdb994801..8102d409025 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.c +++ b/src/main/drivers/accgyro/accgyro_data_ready.c @@ -257,6 +257,7 @@ void gyroDataReadySuspend(void) } const SPIDevice bus = d->gyro->busDev->busdev.spi.spiBus; spiBusAcquire(bus); + spiDataReadyCancelPending(bus); spiBusRelease(bus); } } diff --git a/src/main/drivers/bus_spi.h b/src/main/drivers/bus_spi.h index 34fdf15ccef..aa0ca8df494 100644 --- a/src/main/drivers/bus_spi.h +++ b/src/main/drivers/bus_spi.h @@ -139,6 +139,8 @@ bool spiInitDevice(SPIDevice device, bool leadingEdge); // The main loop's transfers on a bus take turns with those reads void spiBusAcquire(SPIDevice device); void spiBusRelease(SPIDevice device); + // Between the two: forgets a data-ready that came meanwhile, so the release starts no read + void spiDataReadyCancelPending(SPIDevice device); #else // Nothing to take turns with: the argument is not even evaluated #define spiBusAcquire(device) do { } while (0) diff --git a/src/main/drivers/bus_spi_data_ready.c b/src/main/drivers/bus_spi_data_ready.c index c610bfbed6f..f727d4b4383 100644 --- a/src/main/drivers/bus_spi_data_ready.c +++ b/src/main/drivers/bus_spi_data_ready.c @@ -161,6 +161,16 @@ void spiBusAcquire(SPIDevice device) } } +void spiDataReadyCancelPending(SPIDevice device) +{ + if ((unsigned)device >= SPIDEV_COUNT) { + return; + } + ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { + spiDataReady[device].pending = false; + } +} + void spiBusRelease(SPIDevice device) { if ((unsigned)device >= SPIDEV_COUNT || !spiDataReady[device].dev) { From b3b43ac0f68c02917c91463d3a711df718c7855d Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:08:36 +0200 Subject: [PATCH 05/19] spi: an H7 data-ready read clears the EOT a polled transfer left behind --- src/main/drivers/bus_spi_hal_ll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index f9b22ee0d21..250dd625948 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -575,6 +575,8 @@ void spiDataReadyHwStart(SPIDevice device) SPI_TypeDef *instance = spiHardwareMap[device].dev; LL_SPI_Disable(instance); + // A polled transfer leaves EOT set: this read would look over before it began + WRITE_REG(instance->IFCR, SPI_IFCR_EOTC | SPI_IFCR_TXTFC); LL_SPI_SetTransferSize(instance, h->len + 1); if (h->dma) { spiDataReadyDmaStart(&h->streams, &instance->TXDR, &instance->RXDR, spiDataReadyTx[device], spiDataReadyRx[device], h->len + 1); From 25513a9e399e708efd2a7b56053e9efec00f624a Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:05:43 +0200 Subject: [PATCH 06/19] spi: on F7 an aborted transfer waits for its queued bytes by time, not by a count --- src/main/drivers/bus_spi_hal_ll.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index 250dd625948..983be53e5bc 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -32,6 +32,7 @@ #include "drivers/io.h" #include "io_impl.h" #include "drivers/nvic.h" +#include "drivers/time.h" #include "rcc.h" #ifndef SPI1_SCK_PIN @@ -400,8 +401,12 @@ static void spiTransferAbort(SPI_TypeDef *instance) WRITE_REG(instance->IFCR, SPI_IFCR_EOTC | SPI_IFCR_TXTFC | SPI_IFCR_UDRC | SPI_IFCR_OVRC | SPI_IFCR_CRCEC | SPI_IFCR_TIFREC | SPI_IFCR_MODFC | SPI_IFCR_TSERFC | SPI_IFCR_SUSPC); #else - // F7 stays enabled: drain what is left, or the next transfer would take it for its own - for (int spiTimeout = 1000; spiTimeout && (LL_SPI_GetTxFIFOLevel(instance) != LL_SPI_TX_FIFO_EMPTY || LL_SPI_IsActiveFlag_BSY(instance)); spiTimeout--); + // F7 stays enabled: drain what is left, or the next transfer would take it for its own. + // Timed, not counted: the 5 bytes still queued take 0.2 ms at the slowest clock + const timeUs_t start = micros(); + while ((LL_SPI_GetTxFIFOLevel(instance) != LL_SPI_TX_FIFO_EMPTY || LL_SPI_IsActiveFlag_BSY(instance)) + && cmpTimeUs(micros(), start) < 1000) { + } for (int n = 0; n < 8 && LL_SPI_GetRxFIFOLevel(instance) != LL_SPI_RX_FIFO_EMPTY; n++) { (void)LL_SPI_ReceiveData8(instance); } From 86f7bf5398b62b76fe9f5ca851744a17c8ec67e2 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:09:42 +0200 Subject: [PATCH 07/19] spi: register reads and writes report a transfer that failed --- src/main/drivers/bus_busdev_spi.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/drivers/bus_busdev_spi.c b/src/main/drivers/bus_busdev_spi.c index 1ec5261200b..aa3cdf50d9b 100644 --- a/src/main/drivers/bus_busdev_spi.c +++ b/src/main/drivers/bus_busdev_spi.c @@ -129,16 +129,16 @@ bool spiBusTransferMultiple(const busDevice_t * dev, busTransferDescriptor_t * d // Address and data in one transfer: on H7 starting and ending one costs about as much as the bytes #if defined(AT32F43x) -static void spiBusTransferRegister(spi_type * instance, uint8_t reg, uint8_t * rxData, const uint8_t * txData, int len) +static bool spiBusTransferRegister(spi_type * instance, uint8_t reg, uint8_t * rxData, const uint8_t * txData, int len) #else -static void spiBusTransferRegister(SPI_TypeDef * instance, uint8_t reg, uint8_t * rxData, const uint8_t * txData, int len) +static bool spiBusTransferRegister(SPI_TypeDef * instance, uint8_t reg, uint8_t * rxData, const uint8_t * txData, int len) #endif { #if defined(STM32H7) || defined(STM32F7) - spiTransferRegister(instance, reg, rxData, txData, len); + return spiTransferRegister(instance, reg, rxData, txData, len); #else spiTransferByte(instance, reg); - spiTransfer(instance, rxData, txData, len); + return spiTransfer(instance, rxData, txData, len); #endif } @@ -154,13 +154,13 @@ bool spiBusWriteRegister(const busDevice_t * dev, uint8_t reg, uint8_t data) spiBusSelectDevice(dev); } - spiBusTransferRegister(instance, reg, NULL, &data, 1); + const bool ok = spiBusTransferRegister(instance, reg, NULL, &data, 1); if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) { spiBusDeselectDevice(dev); } - return true; + return ok; } bool spiBusWriteBuffer(const busDevice_t * dev, uint8_t reg, const uint8_t * data, uint8_t length) @@ -175,13 +175,13 @@ bool spiBusWriteBuffer(const busDevice_t * dev, uint8_t reg, const uint8_t * dat spiBusSelectDevice(dev); } - spiBusTransferRegister(instance, reg, NULL, data, length); + const bool ok = spiBusTransferRegister(instance, reg, NULL, data, length); if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) { spiBusDeselectDevice(dev); } - return true; + return ok; } bool spiBusReadBuffer(const busDevice_t * dev, uint8_t reg, uint8_t * data, uint8_t length) @@ -196,13 +196,13 @@ bool spiBusReadBuffer(const busDevice_t * dev, uint8_t reg, uint8_t * data, uint spiBusSelectDevice(dev); } - spiBusTransferRegister(instance, reg, data, NULL, length); + const bool ok = spiBusTransferRegister(instance, reg, data, NULL, length); if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) { spiBusDeselectDevice(dev); } - return true; + return ok; } bool spiBusReadRegister(const busDevice_t * dev, uint8_t reg, uint8_t * data) @@ -217,13 +217,13 @@ bool spiBusReadRegister(const busDevice_t * dev, uint8_t reg, uint8_t * data) spiBusSelectDevice(dev); } - spiBusTransferRegister(instance, reg, data, NULL, 1); + const bool ok = spiBusTransferRegister(instance, reg, data, NULL, 1); if (!(dev->flags & DEVFLAGS_USE_MANUAL_DEVICE_SELECT)) { spiBusDeselectDevice(dev); } - return true; + return ok; } bool spiBusIsBusy(const busDevice_t * dev) From 194c496855c14aec9f597a5f2ce8813ed7fc33f7 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:10:30 +0200 Subject: [PATCH 08/19] gyro: on F4 the data-ready interrupt is on the rising edge, not on no edge at all --- src/main/drivers/accgyro/accgyro_data_ready.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/drivers/accgyro/accgyro_data_ready.c b/src/main/drivers/accgyro/accgyro_data_ready.c index 8102d409025..4ff8572b053 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.c +++ b/src/main/drivers/accgyro/accgyro_data_ready.c @@ -316,7 +316,11 @@ void gyroDataReadyStart(gyroDev_t *gyro) IOInit(dev->irqPin, OWNER_MPU, RESOURCE_EXTI, RESOURCE_INDEX(gyro->imuSensorToUse)); EXTIHandlerInit(&d->exti, gyroDataReadyExti); - EXTIConfig(dev->irqPin, &d->exti, NVIC_PRIO_GYRO_DATA_READY, IOCFG_IN_FLOATING); +#if defined(STM32F7) || defined(STM32H7) + EXTIConfig(dev->irqPin, &d->exti, NVIC_PRIO_GYRO_DATA_READY, IOCFG_IN_FLOATING); // always on the rising edge +#else + EXTIConfig(dev->irqPin, &d->exti, NVIC_PRIO_GYRO_DATA_READY, EXTI_Trigger_Rising); +#endif EXTIEnable(dev->irqPin, true); gyro->dataReadyState = d; From 18d07916583cf4f1e6812f0f30a60ddaef2efb7d Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:10:30 +0200 Subject: [PATCH 09/19] spi: a data-ready read stopped on F4 clears the overrun it may leave --- src/main/drivers/bus_spi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 3fdadb4f4b4..0a4b90f79b4 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -319,9 +319,11 @@ void spiDataReadyHwStop(SPIDevice device) spiDataReadyDmaStop(&h->streams); instance->CR2 &= ~(SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); - // A read stopped half way may leave a byte going out: let it finish and drop the echo + // A read stopped half way may leave a byte going out: let it finish and drop the echo. + // DR then SR also clears an overrun, which would hand the next transfer a stale byte for (int timeout = 1000; timeout && (!(instance->SR & SPI_SR_TXE) || (instance->SR & SPI_SR_BSY)); timeout--); (void)instance->DR; + (void)instance->SR; } void spiDataReadyHwDisable(SPIDevice device) From 57d3cf5ea6f5757cde608d067a8938404ce35f55 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 15:11:43 +0200 Subject: [PATCH 10/19] gyro: a FIFO flush also drops the samples already queued from the backlog --- src/main/drivers/accgyro/accgyro_data_ready.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/drivers/accgyro/accgyro_data_ready.c b/src/main/drivers/accgyro/accgyro_data_ready.c index 4ff8572b053..7d5e5af0fb5 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.c +++ b/src/main/drivers/accgyro/accgyro_data_ready.c @@ -202,19 +202,19 @@ static bool gyroDataReadyRead(gyroDev_t *gyro) gyroDataReady_t *d = gyro->dataReadyState; if (d->fifoSamples && (d->paused || d->fifoFlush)) { - // What the FIFO holds is old, or out of step with the reads + // What the FIFO holds is old, or out of step with the reads, and so is what came from it d->driver->fifo->flush(gyro); d->fifoFlush = false; - if (d->paused) { - // No register read: a sample taken during the flush would come again from the FIFO - ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { - gyro->sampleQueueTail = gyro->sampleQueueHead; + ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { + gyro->sampleQueueTail = gyro->sampleQueueHead; + if (d->paused) { d->paused = false; EXTIEnable(gyro->busDev->irqPin, true); } - d->resumedUs = micros(); - return false; } + d->resumedUs = micros(); + // No register read: a sample taken during the flush would come again from the FIFO + return false; } if (d->paused) { From 57246ba250850dce9274c0a6e7f57dd64812d89b Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 16:45:57 +0200 Subject: [PATCH 11/19] targets: no data-ready pin on SPEEDYBEEF405AIO, whose port E the target does not enable --- src/main/target/SPEEDYBEEF405AIO/target.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/target/SPEEDYBEEF405AIO/target.h b/src/main/target/SPEEDYBEEF405AIO/target.h index ca1991a018b..a6abdfcc37f 100644 --- a/src/main/target/SPEEDYBEEF405AIO/target.h +++ b/src/main/target/SPEEDYBEEF405AIO/target.h @@ -92,7 +92,6 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW180_DEG #define ICM42605_CS_PIN PA4 -#define ICM42605_EXTI_PIN PE9 #define ICM42605_SPI_BUS BUS_SPI1 /* From c082ca5a3e74687a4f70cdc9a3316d92f1269302 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:39:38 +0200 Subject: [PATCH 12/19] gyro: new config version for gyro_data_ready --- src/main/sensors/gyro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/sensors/gyro.c b/src/main/sensors/gyro.c index ec2cdb91b40..a263d138923 100644 --- a/src/main/sensors/gyro.c +++ b/src/main/sensors/gyro.c @@ -121,7 +121,7 @@ EXTENDED_FASTRAM secondaryDynamicGyroNotchState_t secondaryDynamicGyroNotchState #endif -PG_REGISTER_WITH_RESET_TEMPLATE(gyroConfig_t, gyroConfig, PG_GYRO_CONFIG, 12); +PG_REGISTER_WITH_RESET_TEMPLATE(gyroConfig_t, gyroConfig, PG_GYRO_CONFIG, 13); PG_RESET_TEMPLATE(gyroConfig_t, gyroConfig, .gyro_anti_aliasing_lpf_hz = SETTING_GYRO_ANTI_ALIASING_LPF_HZ_DEFAULT, From f7be8355acf279fd0809f5bbcbc65fb6b0b75528 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:39:58 +0200 Subject: [PATCH 13/19] gyro: new config version for gyro_fifo_samples --- src/main/sensors/gyro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/sensors/gyro.c b/src/main/sensors/gyro.c index a263d138923..0619dedc0a8 100644 --- a/src/main/sensors/gyro.c +++ b/src/main/sensors/gyro.c @@ -121,7 +121,7 @@ EXTENDED_FASTRAM secondaryDynamicGyroNotchState_t secondaryDynamicGyroNotchState #endif -PG_REGISTER_WITH_RESET_TEMPLATE(gyroConfig_t, gyroConfig, PG_GYRO_CONFIG, 13); +PG_REGISTER_WITH_RESET_TEMPLATE(gyroConfig_t, gyroConfig, PG_GYRO_CONFIG, 14); PG_RESET_TEMPLATE(gyroConfig_t, gyroConfig, .gyro_anti_aliasing_lpf_hz = SETTING_GYRO_ANTI_ALIASING_LPF_HZ_DEFAULT, From 6cd9e99d16e2b74b67e650ef8abc0742a2bce022 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 21:19:54 +0200 Subject: [PATCH 14/19] gyro, spi: shorter comments --- src/main/drivers/accgyro/accgyro_data_ready.c | 5 ++--- src/main/drivers/bus_spi_data_ready.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/drivers/accgyro/accgyro_data_ready.c b/src/main/drivers/accgyro/accgyro_data_ready.c index 7d5e5af0fb5..c41f2bd6447 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.c +++ b/src/main/drivers/accgyro/accgyro_data_ready.c @@ -241,9 +241,8 @@ static bool gyroDataReadyRead(gyroDev_t *gyro) return false; } -// Before a flash write, which stalls every interrupt running from flash (over a second on H7): -// no reads meanwhile. With a DMA read around a flash write and the host closing the USB port, -// an H7 has stopped entirely +// No reads during a flash write: with a DMA read in flight and the USB port closing, an H7 has +// stopped entirely void gyroDataReadySuspend(void) { for (unsigned i = 0; i < ARRAYLEN(gyroDataReady); i++) { diff --git a/src/main/drivers/bus_spi_data_ready.c b/src/main/drivers/bus_spi_data_ready.c index f727d4b4383..ef8a9b8ea74 100644 --- a/src/main/drivers/bus_spi_data_ready.c +++ b/src/main/drivers/bus_spi_data_ready.c @@ -35,9 +35,8 @@ #include "drivers/nvic.h" #include "drivers/time.h" -// Reads started by a data-ready interrupt take turns with the main loop's transfers: -// spiBusAcquire() waits for one on its way, and one asked for meanwhile starts at the last -// spiBusRelease(). The two nest: a speed change can come while a device is selected +// Data-ready reads take turns with the main loop's transfers: acquire waits for one on its way, +// the last release starts one asked for meanwhile (they nest: speed changes come mid-select) typedef struct { const busDevice_t *dev; // NULL: no reads started by a data-ready on this bus From 32f2928a2b2c80667f19b3e06069c84ce3816a57 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 28 Sep 2026 21:19:54 +0200 Subject: [PATCH 15/19] gyro: data-ready on by default for the ICM426xx on F4 and F7 too AUTO now reads the ICM-42605 and ICM-42688-P on their data-ready interrupt on every family. Where no interrupt arrives the gyro is read from its registers as before. --- docs/Settings.md | 2 +- src/main/drivers/accgyro/accgyro.h | 2 +- src/main/drivers/accgyro/accgyro_icm42605.c | 2 -- src/main/fc/settings.yaml | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/Settings.md b/docs/Settings.md index eb0cdb56ba2..d1074143b53 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -2140,7 +2140,7 @@ Gyro processing anti-aliasing filter cutoff frequency. In normal operation this ### gyro_data_ready -Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin. AUTO does it on H7. On F4 and F7 the read goes through DMA and is new: set ON to try it, and please report how it works. OFF polls the gyro everywhere. +Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin; without interrupts the gyro is read as before. AUTO and ON do it, OFF polls the gyro. | Allowed Values | | | --- | --- | diff --git a/src/main/drivers/accgyro/accgyro.h b/src/main/drivers/accgyro/accgyro.h index b1e603aee44..d396855e457 100644 --- a/src/main/drivers/accgyro/accgyro.h +++ b/src/main/drivers/accgyro/accgyro.h @@ -43,7 +43,7 @@ typedef struct { // Whether a driver that can reads its gyro on the data-ready interrupt (gyro_data_ready) typedef enum { GYRO_DEV_DATA_READY_OFF = 0, - GYRO_DEV_DATA_READY_WHERE_TESTED, // only where that driver has been tested + GYRO_DEV_DATA_READY_WHERE_TESTED, // where the driver turns it on for AUTO GYRO_DEV_DATA_READY_ON, } gyroDevDataReady_e; diff --git a/src/main/drivers/accgyro/accgyro_icm42605.c b/src/main/drivers/accgyro/accgyro_icm42605.c index ec82971d8c3..6b5eeb3e0c0 100644 --- a/src/main/drivers/accgyro/accgyro_icm42605.c +++ b/src/main/drivers/accgyro/accgyro_icm42605.c @@ -273,9 +273,7 @@ static const gyroDataReadyDriver_t icm426xxDataReady = { .hasTemp = true, .parse = icm426xxDataReadyParse, .registerRead = icm42605GyroRead, -#if defined(STM32H7) .tested = true, -#endif .fifo = &icm426xxFifo, }; #endif diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index 230255d508e..eefde33fada 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -353,7 +353,7 @@ groups: field: gyro_secondary_enabled type: bool - name: gyro_data_ready - description: "Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin. AUTO does it on H7. On F4 and F7 the read goes through DMA and is new: set ON to try it, and please report how it works. OFF polls the gyro everywhere." + description: "Read the gyro when it signals a new sample, on its data-ready interrupt, instead of polling it: every sample once, and the CPU no longer waits on the bus. Needs a supported IMU (ICM-42605, ICM-42688-P) and a target that declares the interrupt pin; without interrupts the gyro is read as before. AUTO and ON do it, OFF polls the gyro." default_value: "AUTO" condition: USE_SPI_DATA_READY field: gyro_data_ready From 8a0d29c9fe965d9514049ab819293c5d0bd23d17 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Tue, 29 Sep 2026 01:40:24 +0200 Subject: [PATCH 16/19] targets: FLYWOOF405S_AIO's ICM-42605 data-ready pin, which the first Betaflight comparison missed --- src/main/target/FLYWOOF405S_AIO/target.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/target/FLYWOOF405S_AIO/target.h b/src/main/target/FLYWOOF405S_AIO/target.h index 4250943633e..840cf7e6f49 100644 --- a/src/main/target/FLYWOOF405S_AIO/target.h +++ b/src/main/target/FLYWOOF405S_AIO/target.h @@ -46,6 +46,7 @@ #define USE_IMU_ICM42605 #define IMU_ICM42605_ALIGN CW270_DEG #define ICM42605_CS_PIN PB12 +#define ICM42605_EXTI_PIN PB13 #define ICM42605_SPI_BUS BUS_SPI1 #define USE_EXTI From d51b6387aa446b82601da9566e5f0c1ae071759e Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Tue, 29 Sep 2026 16:51:58 +0200 Subject: [PATCH 17/19] spi: clean the data-ready transmit buffer from the cache before DMA reads it Written once at setup, so cleaned once there: nothing at run time. A no-op today: DMA_RAM is Shareable in the H7 MPU setup and the Cortex-M7 does not cache it, and on F7, which runs the same setup, INAV leaves the D-cache off. It matches the invalidate on the reply and stays right should either change. (cherry picked from commit 42874294ca38444c6d60bb95b076354feeea5a65) --- src/main/drivers/bus_spi_hal_ll.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index 983be53e5bc..3ca5f49bdf2 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -543,6 +543,8 @@ static bool spiDataReadyDmaSetup(SPIDevice device) } memset(spiDataReadyTx[device], 0xFF, SPI_DATA_READY_MAX); spiDataReadyTx[device][0] = h->reg; + // A no-op while DMA_RAM stays uncached, as the invalidate on the reply is + SCB_CleanDCache_by_Addr((uint32_t *)spiDataReadyTx[device], SPI_DATA_READY_MAX); h->dma = true; return true; } From 3285977e07a36f9bdbd80fb0a1758b99eceefff8 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:04:27 +0200 Subject: [PATCH 18/19] gyro: keep PG_GYRO_CONFIG at version 12 The new fields are appended with a zero default, so stored settings load as they are: pgLoad copies the stored bytes over the defaults. On H7 without USE_DUAL_GYRO gyro_data_ready takes the old record's tail padding, which the reset template leaves at zero. --- src/main/sensors/gyro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/sensors/gyro.c b/src/main/sensors/gyro.c index 0619dedc0a8..ec2cdb91b40 100644 --- a/src/main/sensors/gyro.c +++ b/src/main/sensors/gyro.c @@ -121,7 +121,7 @@ EXTENDED_FASTRAM secondaryDynamicGyroNotchState_t secondaryDynamicGyroNotchState #endif -PG_REGISTER_WITH_RESET_TEMPLATE(gyroConfig_t, gyroConfig, PG_GYRO_CONFIG, 14); +PG_REGISTER_WITH_RESET_TEMPLATE(gyroConfig_t, gyroConfig, PG_GYRO_CONFIG, 12); PG_RESET_TEMPLATE(gyroConfig_t, gyroConfig, .gyro_anti_aliasing_lpf_hz = SETTING_GYRO_ANTI_ALIASING_LPF_HZ_DEFAULT, From 9f5b757714069ab3304e9f910dcba80a35535c58 Mon Sep 17 00:00:00 2001 From: MrScothh <167884257+MrScothh@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:57:33 +0200 Subject: [PATCH 19/19] gyro: FIFO only where it can run, a limit on its flushes, GYRO_FIFO debug USE_GYRO_FIFO is defined only when the ICM426xx driver is built and the target names its interrupt pin. It carries the FIFO code, the larger data-ready rows and sample queue, and gyro_fifo_samples; the other data-ready builds keep the smaller ones (about -0.6 KB flash, -0.4 KB RAM). Three flushes for a fault within a second make the FIFO give up for the session: the interrupt is disabled and the gyro is read from its registers. The flush and the clear of its flag run under one hold of the bus, so no read starts between them. The GYRO_FIFO debug mode shows the flushes, the samples they dropped, the samples per read and whether the FIFO gave up. On F7 and H7 the rows are 96 B, whole cache lines. --- docs/Settings.md | 1 + src/main/build/debug.h | 1 + src/main/drivers/accgyro/accgyro.h | 5 ++ src/main/drivers/accgyro/accgyro_data_ready.c | 62 ++++++++++++++++++- src/main/drivers/accgyro/accgyro_data_ready.h | 2 + src/main/drivers/accgyro/accgyro_icm42605.c | 4 ++ src/main/drivers/bus_spi.c | 4 ++ src/main/drivers/bus_spi_hal_ll.c | 8 ++- src/main/fc/cli.c | 3 +- src/main/fc/settings.yaml | 4 +- src/main/sensors/gyro.c | 2 + src/main/target/common_post.h | 5 ++ 12 files changed, 95 insertions(+), 6 deletions(-) diff --git a/docs/Settings.md b/docs/Settings.md index 6485f2b33ad..81678e9b809 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -803,6 +803,7 @@ Defines debug values exposed in debug variables (developer / debugging setting) | ESC | | | FW_TURN | | | MAG | | +| GYRO_FIFO | | --- diff --git a/src/main/build/debug.h b/src/main/build/debug.h index 23caa6b6fa7..29dbe195297 100644 --- a/src/main/build/debug.h +++ b/src/main/build/debug.h @@ -87,6 +87,7 @@ typedef enum { DEBUG_ESC, DEBUG_FW_TURN, DEBUG_MAG, + DEBUG_GYRO_FIFO, DEBUG_COUNT // also update debugModeNames in cli.c } debugType_e; diff --git a/src/main/drivers/accgyro/accgyro.h b/src/main/drivers/accgyro/accgyro.h index d396855e457..3d06cef10c3 100644 --- a/src/main/drivers/accgyro/accgyro.h +++ b/src/main/drivers/accgyro/accgyro.h @@ -36,9 +36,14 @@ typedef struct { uint8_t gyroConfigValues[2]; } gyroFilterAndRateConfig_t; +#ifdef USE_GYRO_FIFO // Two reads' worth of FIFO samples (gyro_fifo_samples up to 4) plus margin: the interrupt brings // them at the sensor's rate, the task only follows on average #define GYRO_SAMPLE_QUEUE_LENGTH 16 +#else +// 2 ms at 4 kHz: the interrupt brings samples at the sensor's rate, the task follows on average +#define GYRO_SAMPLE_QUEUE_LENGTH 8 +#endif // Whether a driver that can reads its gyro on the data-ready interrupt (gyro_data_ready) typedef enum { diff --git a/src/main/drivers/accgyro/accgyro_data_ready.c b/src/main/drivers/accgyro/accgyro_data_ready.c index c41f2bd6447..6d0f6e6c6df 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.c +++ b/src/main/drivers/accgyro/accgyro_data_ready.c @@ -29,6 +29,7 @@ #if defined(USE_SPI_DATA_READY) #include "build/atomic.h" +#include "build/debug.h" #include "common/maths.h" #include "common/utils.h" @@ -57,13 +58,21 @@ struct gyroDataReady_s { volatile int16_t temp; volatile timeUs_t lastSampleUs; timeUs_t resumedUs; // when a read after a pause turned the interrupt back on +#ifdef USE_GYRO_FIFO uint8_t fifoSamples; // samples per interrupt through the IMU's FIFO, 0 for register reads uint8_t fifoPackets; // packets each read brings: one more than that where it fits uint8_t fifoPacketLen; volatile bool fifoFlush; // the FIFO fell behind or out of step: empty it from the task uint8_t fifoFruitlessReads; // reads in a row that found packets counted but no sample + uint8_t fifoFaults; // flushes for a fault since fifoFaultsSinceUs + timeUs_t fifoFaultsSinceUs; + bool fifoGaveUp; // read from the registers for the rest of the session + uint16_t fifoFlushes; // for the GYRO_FIFO debug mode + uint16_t fifoDropped; +#endif }; +#ifdef USE_GYRO_FIFO // Reads in a row with packets counted but none held: out of step. One alone is normal (a packet // counted just before it can be read); a read that found the queue full doesn't count #define GYRO_DATA_READY_FIFO_FRUITLESS 4 @@ -71,6 +80,11 @@ struct gyroDataReady_s { // Further behind than this many reads' worth, the FIFO is emptied rather than caught up #define GYRO_DATA_READY_FIFO_BEHIND 2 +// This many fault flushes within the window is a fault the FIFO won't get over: the registers are read from then on +#define GYRO_DATA_READY_FIFO_MAX_FAULTS 3 +#define GYRO_DATA_READY_FIFO_FAULT_WINDOW_US 1000000 +#endif + // The primary gyro and the secondary static gyroDataReady_t gyroDataReady[2]; @@ -137,6 +151,7 @@ static void gyroDataReadySample(void *arg, const uint8_t *data) d->lastSampleUs = microsISR(); } +#ifdef USE_GYRO_FIFO // The count, then fifoPackets packets, oldest first. Every packet read has left the FIFO, even // one that came after the count, so all are decoded up to the first empty one static void gyroDataReadyFifoSamples(void *arg, const uint8_t *data) @@ -188,8 +203,27 @@ static void gyroDataReadyFifoSamples(void *arg, const uint8_t *data) d->fifoFlush = true; d->fifoFruitlessReads = 0; } + if (d == &gyroDataReady[0]) { + DEBUG_SET(DEBUG_GYRO_FIFO, 2, pushed); + } } +static void gyroDataReadyFifoFault(gyroDataReady_t *d) +{ + const timeUs_t now = micros(); + if (cmpTimeUs(now, d->fifoFaultsSinceUs) > GYRO_DATA_READY_FIFO_FAULT_WINDOW_US) { + d->fifoFaultsSinceUs = now; + d->fifoFaults = 0; + } + if (++d->fifoFaults >= GYRO_DATA_READY_FIFO_MAX_FAULTS) { + ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { + EXTIEnable(d->gyro->busDev->irqPin, false); + d->fifoGaveUp = true; + } + } +} +#endif + static void gyroDataReadyExti(extiCallbackRec_t *cb) { gyroDataReady_t *d = (gyroDataReady_t *)cb; @@ -201,21 +235,43 @@ static bool gyroDataReadyRead(gyroDev_t *gyro) { gyroDataReady_t *d = gyro->dataReadyState; +#ifdef USE_GYRO_FIFO + if (d->fifoGaveUp) { + return d->driver->registerRead(gyro); + } + if (d->fifoSamples && (d->paused || d->fifoFlush)) { + // A fault, not the restart after a pause + const bool fault = d->fifoFlush; + // No read starts between the flush and the clear; the one in flight can only re-raise what the flush empties + const SPIDevice bus = gyro->busDev->busdev.spi.spiBus; + spiBusAcquire(bus); // What the FIFO holds is old, or out of step with the reads, and so is what came from it d->driver->fifo->flush(gyro); d->fifoFlush = false; ATOMIC_BLOCK(NVIC_PRIO_GYRO_DATA_READY) { + d->fifoDropped += (gyro->sampleQueueHead + GYRO_SAMPLE_QUEUE_LENGTH - gyro->sampleQueueTail) % GYRO_SAMPLE_QUEUE_LENGTH; gyro->sampleQueueTail = gyro->sampleQueueHead; if (d->paused) { d->paused = false; EXTIEnable(gyro->busDev->irqPin, true); } } + spiBusRelease(bus); d->resumedUs = micros(); + d->fifoFlushes++; + if (fault) { + gyroDataReadyFifoFault(d); + } + if (d == &gyroDataReady[0]) { + DEBUG_SET(DEBUG_GYRO_FIFO, 0, d->fifoFlushes); + DEBUG_SET(DEBUG_GYRO_FIFO, 1, d->fifoDropped); + DEBUG_SET(DEBUG_GYRO_FIFO, 3, d->fifoGaveUp); + } // No register read: a sample taken during the flush would come again from the FIFO return false; } +#endif if (d->paused) { // After a pause the queue is old: turn the interrupt back on and read the registers @@ -287,6 +343,8 @@ void gyroDataReadyStart(gyroDev_t *gyro) d->driver = driver; d->lastSampleUs = micros(); + bool viaFifo = false; +#ifdef USE_GYRO_FIFO const gyroDataReadyFifo_t *fifo = driver->fifo; d->fifoSamples = 0; if (gyro->dataReadyFifoSamples && fifo) { @@ -297,12 +355,14 @@ void gyroDataReadyStart(gyroDev_t *gyro) if (spiDataReadyInit(dev, fifo->countReg, 2 + d->fifoPackets * d->fifoPacketLen, gyroDataReadyFifoSamples, d)) { d->fifoSamples = gyro->dataReadyFifoSamples; fifo->start(gyro, d->withAccAndTemp, d->fifoSamples); + viaFifo = true; break; } } } +#endif - if (!d->fifoSamples) { + if (!viaFifo) { d->withAccAndTemp = gyro->readOnDataReadyWithAcc && driver->withAccAndTemp.len; if (!d->withAccAndTemp || !spiDataReadyInit(dev, driver->withAccAndTemp.reg, driver->withAccAndTemp.len, gyroDataReadySample, d)) { d->withAccAndTemp = false; diff --git a/src/main/drivers/accgyro/accgyro_data_ready.h b/src/main/drivers/accgyro/accgyro_data_ready.h index 15577419be6..8ed44e5396d 100644 --- a/src/main/drivers/accgyro/accgyro_data_ready.h +++ b/src/main/drivers/accgyro/accgyro_data_ready.h @@ -61,7 +61,9 @@ typedef struct gyroDataReadyDriver_s { gyroDataReadyParseFn parse; sensorGyroReadFuncPtr registerRead; // the driver's own read, for when samples stop coming bool tested; // gyro_data_ready AUTO turns it on +#ifdef USE_GYRO_FIFO const gyroDataReadyFifo_t *fifo; // NULL if the IMU has no FIFO this can use +#endif } gyroDataReadyDriver_t; typedef struct gyroDataReady_s gyroDataReady_t; diff --git a/src/main/drivers/accgyro/accgyro_icm42605.c b/src/main/drivers/accgyro/accgyro_icm42605.c index 6b5eeb3e0c0..bdbd7699c07 100644 --- a/src/main/drivers/accgyro/accgyro_icm42605.c +++ b/src/main/drivers/accgyro/accgyro_icm42605.c @@ -162,6 +162,7 @@ static void setUserBank(const busDevice_t *dev, const uint8_t user_bank) #if defined(USE_SPI_DATA_READY) static bool icm42605GyroRead(gyroDev_t *gyro); +#if defined(USE_GYRO_FIFO) // FIFO, all in User Bank 0 #define ICM426XX_RA_FIFO_CONFIG 0x16 #define ICM426XX_FIFO_MODE_STREAM (1 << 6) @@ -251,6 +252,7 @@ static const gyroDataReadyFifo_t icm426xxFifo = { .flush = icm426xxFifoFlush, .parse = icm426xxFifoParse, }; +#endif // From TEMP_DATA1: temperature, accelerometer X, Y, Z, gyro X, Y, Z, big-endian static void icm426xxDataReadyParse(const uint8_t *data, bool withAccAndTemp, int16_t *gyro, int16_t *acc, int16_t *temp) @@ -274,7 +276,9 @@ static const gyroDataReadyDriver_t icm426xxDataReady = { .parse = icm426xxDataReadyParse, .registerRead = icm42605GyroRead, .tested = true, +#if defined(USE_GYRO_FIFO) .fifo = &icm426xxFifo, +#endif }; #endif diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 0a4b90f79b4..30841362881 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -256,8 +256,12 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len // DMA streams; the buffers stay out of the CCM RAM, which the DMA can not reach // Longest read, address included +#ifdef USE_GYRO_FIFO // The address and up to four FIFO packets of 16 bytes after the count #define SPI_DATA_READY_MAX 72 +#else +#define SPI_DATA_READY_MAX 32 +#endif typedef struct { uint8_t len; // bytes after the address diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index a798ce43ae0..17cff141181 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -521,9 +521,13 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *rxData, const uint8_t *txData, // SPI1-3, 8 on SPI4-6) needs no DMA: the end-of-transfer interrupt takes it all back. Longer // reads, and all on F7 (4-byte FIFO), use two DMA streams -// Longest read, address included +// Longest read, address included, in whole cache lines so no two buses share one +#ifdef USE_GYRO_FIFO // The address and up to four FIFO packets of 16 bytes after the count -#define SPI_DATA_READY_MAX 72 +#define SPI_DATA_READY_MAX 96 +#else +#define SPI_DATA_READY_MAX 32 +#endif typedef struct { uint8_t reg; // the first register, as sent (read bit included) diff --git a/src/main/fc/cli.c b/src/main/fc/cli.c index 15339c4f39e..542f0fe275c 100644 --- a/src/main/fc/cli.c +++ b/src/main/fc/cli.c @@ -238,7 +238,8 @@ static const char *debugModeNames[DEBUG_COUNT] = { "TERRAIN_NAV", "ESC", "FW_TURN", - "MAG" + "MAG", + "GYRO_FIFO" }; /* Sensor names (used in lookup tables for *_hardware settings and in status diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index 02af517b533..ab9d511a9dc 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -93,7 +93,7 @@ tables: "AUTOTRIM", "AUTOTUNE", "RATE_DYNAMICS", "LANDING", "POS_EST", "ADAPTIVE_FILTER", "HEADTRACKER", "GPS", "LULU", "SBUS2", "OSD_REFRESH", "MAG_CALIB", "VTOL_TRANSITION", "VTOL_MC_PROTECT", "TERRAIN_NAV", "ESC", - "FW_TURN", "MAG"] + "FW_TURN", "MAG", "GYRO_FIFO"] - name: vtol_mc_protection_mode values: ["OFF", "NAV", "NAV_AND_STABILIZED"] - name: aux_operator @@ -363,7 +363,7 @@ groups: default_value: 0 min: 0 max: 4 - condition: USE_SPI_DATA_READY + condition: USE_GYRO_FIFO field: gyro_fifo_samples - name: setpoint_kalman_enabled description: "Enable Kalman filter on the gyro data" diff --git a/src/main/sensors/gyro.c b/src/main/sensors/gyro.c index ec2cdb91b40..859c3fb1e71 100644 --- a/src/main/sensors/gyro.c +++ b/src/main/sensors/gyro.c @@ -132,6 +132,8 @@ PG_RESET_TEMPLATE(gyroConfig_t, gyroConfig, #endif #ifdef USE_SPI_DATA_READY .gyro_data_ready = SETTING_GYRO_DATA_READY_DEFAULT, +#endif +#ifdef USE_GYRO_FIFO .gyro_fifo_samples = SETTING_GYRO_FIFO_SAMPLES_DEFAULT, #endif .gyro_main_lpf_hz = SETTING_GYRO_MAIN_LPF_HZ_DEFAULT, diff --git a/src/main/target/common_post.h b/src/main/target/common_post.h index 183b44a3908..d3b1c09a21a 100644 --- a/src/main/target/common_post.h +++ b/src/main/target/common_post.h @@ -122,6 +122,11 @@ extern uint8_t __config_end; #endif // USE_MAG_ALL +// The IMU FIFO on data-ready: only the ICM426xx driver has one, and only a gyro with its interrupt pin can use it +#if defined(USE_SPI_DATA_READY) && defined(USE_IMU_ICM42605) && (defined(ICM42605_EXTI_PIN) || defined(GYRO1_EXTI_PIN) || defined(GYRO2_EXTI_PIN)) +#define USE_GYRO_FIFO +#endif + #if defined(DEFAULT_I2C_BUS) && !defined(MAG_I2C_BUS) #define MAG_I2C_BUS DEFAULT_I2C_BUS #endif