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

Fix incorrect TIMUP DMA configuration dump on H743 (#14502)

## Commit Summary: Fix incorrect TIMUP DMA configuration dump on H743

**Problem**: H743 platform had incorrect TIMUP DMA configuration dumping and parsing, causing errors when restoring dumped configurations.

**Solution**: This PR implements a comprehensive fix for TIMUP DMA handling across multiple areas:

### CLI DMA Option Handling (`src/main/cli/cli.c`)
- Added `getDmaOptDisplayNumber()` and `displayNumberToDmaOptIndex()` helper functions
- Properly translates between internal DMA option indices and user-facing display numbers
- Integrates presence mask validation for `DMA_PERIPH_TIMUP` peripheral
- Ensures only valid/present timer options are displayed and accepted

### Timer Definition Refactoring (Multiple Platforms)
- Replaced hardcoded `HARDWARE_TIMER_DEFINITION_COUNT` with dynamic `BITCOUNT(USED_TIMERS)` 
- Updated STM32H7/G4 `TIMUP_TIMERS` macros to use `TIM_N(x)` instead of `BIT(x)`
- Expanded AT32 `USED_TIMERS` to include timers 6 and 7
- Added static assertion to verify `TIMUP_TIMERS` bits are included in `USED_TIMERS`

### Timer Index Management (`src/main/drivers/timer.h` + platform implementations)
- Added `TIM_N(n)` macro for timer bitmask generation
- Added `TIMER_INDEX(i)` macro for proper index calculation
- Implemented `timerGetIndexByNumber()` function across all platforms (STM32, AT32, APM32)
- Provides bidirectional timer number ↔ index conversion

### DMA Request Mapping Updates
- Modified `REQMAP_TIMUP` macros to use `TIMER_INDEX(timno)` instead of `timno - 1`
- Ensures correct DMA request mapping for non-contiguous timer numbering

### Timer Configuration (`src/main/pg/timerup.c`)
- Replaced hardware timer count checks with `TIMUP_TIMERS` bitmask validation
- Added support for timers 6 and 7 that were previously omitted
- Uses computed `TIMER_INDEX()` for proper array indexing
This commit is contained in:
ke deng 2025-07-10 19:36:39 +08:00 committed by GitHub
parent 90d2503274
commit acbab53d13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 101 additions and 60 deletions

View file

@ -5419,6 +5419,35 @@ static void optToString(int optval, char *buf)
} }
} }
static int getDmaOptDisplayNumber(dmaoptEntry_t *entry, int index)
{
if (entry->peripheral == DMA_PERIPH_TIMUP) {
const int dispNum = timerGetNumberByIndex(index);
if (!(TIM_N(dispNum) & entry->presenceMask)) {
return -1;
}
return dispNum;
}
return DMA_OPT_UI_INDEX(index);
}
static int displayNumberToDmaOptIndex(dmaoptEntry_t *entry, int dispNum)
{
if (dispNum < 0) {
return -1;
}
if (entry->peripheral == DMA_PERIPH_TIMUP) {
if (!(entry->presenceMask & TIM_N(dispNum))) {
return -1;
}
return timerGetIndexByNumber(dispNum);
}
const int index = dispNum - 1;
return (index < 0 || index >= entry->maxIndex) ? -1 : index;
}
static void printPeripheralDmaoptDetails(dmaoptEntry_t *entry, int index, const dmaoptValue_t dmaopt, const bool equalsDefault, const dumpFlags_t dumpMask, printFn *printValue) static void printPeripheralDmaoptDetails(dmaoptEntry_t *entry, int index, const dmaoptValue_t dmaopt, const bool equalsDefault, const dumpFlags_t dumpMask, printFn *printValue)
{ {
// We compute number to display for different peripherals in advance. // We compute number to display for different peripherals in advance.
@ -5426,12 +5455,9 @@ static void printPeripheralDmaoptDetails(dmaoptEntry_t *entry, int index, const
// Note that using timerGetNumberByIndex is not a generic solution, // Note that using timerGetNumberByIndex is not a generic solution,
// but we are lucky that TIMUP is the only peripheral with non-contiguous numbering. // but we are lucky that TIMUP is the only peripheral with non-contiguous numbering.
int uiIndex; int uiIndex = getDmaOptDisplayNumber(entry, index);
if (uiIndex == -1) {
if (entry->presenceMask) { return;
uiIndex = timerGetNumberByIndex(index);
} else {
uiIndex = DMA_OPT_UI_INDEX(index);
} }
if (dmaopt != DMA_OPT_UNUSED) { if (dmaopt != DMA_OPT_UNUSED) {
@ -5641,8 +5667,8 @@ static void cliDmaopt(const char *cmdName, char *cmdline)
const timerHardware_t *timer = NULL; const timerHardware_t *timer = NULL;
pch = strtok_r(NULL, " ", &saveptr); pch = strtok_r(NULL, " ", &saveptr);
if (entry) { if (entry) {
index = pch ? (atoi(pch) - 1) : -1; index = displayNumberToDmaOptIndex(entry, pch ? atoi(pch) : -1);
if (index < 0 || index >= entry->maxIndex || (entry->presenceMask != MASK_IGNORED && !(entry->presenceMask & BIT(index + 1)))) { if (index == -1) {
cliPrintErrorLinef(cmdName, "BAD INDEX: '%s'", pch ? pch : ""); cliPrintErrorLinef(cmdName, "BAD INDEX: '%s'", pch ? pch : "");
return; return;
} }
@ -5707,7 +5733,7 @@ static void cliDmaopt(const char *cmdName, char *cmdline)
if (entry) { if (entry) {
if (!dmaGetChannelSpecByPeripheral(entry->peripheral, index, optval)) { if (!dmaGetChannelSpecByPeripheral(entry->peripheral, index, optval)) {
cliPrintErrorLinef(cmdName, "INVALID DMA OPTION FOR %s %d: '%s'", entry->device, DMA_OPT_UI_INDEX(index), pch); cliPrintErrorLinef(cmdName, "INVALID DMA OPTION FOR %s %d: '%s'", entry->device, getDmaOptDisplayNumber(entry, index), pch);
return; return;
} }
@ -5730,7 +5756,7 @@ static void cliDmaopt(const char *cmdName, char *cmdline)
if (entry) { if (entry) {
*optaddr = optval; *optaddr = optval;
cliPrintLinef("# dma %s %d: changed from %s to %s", entry->device, DMA_OPT_UI_INDEX(index), orgvalString, optvalString); cliPrintLinef("# dma %s %d: changed from %s to %s", entry->device, getDmaOptDisplayNumber(entry, index), orgvalString, optvalString);
} else { } else {
#if defined(USE_TIMER_MGMT) #if defined(USE_TIMER_MGMT)
timerIoConfig->dmaopt = optval; timerIoConfig->dmaopt = optval;
@ -5740,7 +5766,7 @@ static void cliDmaopt(const char *cmdName, char *cmdline)
} }
} else { } else {
if (entry) { if (entry) {
cliPrintLinef("# dma %s %d: no change: %s", entry->device, DMA_OPT_UI_INDEX(index), orgvalString); cliPrintLinef("# dma %s %d: no change: %s", entry->device, getDmaOptDisplayNumber(entry, index), orgvalString);
} else { } else {
cliPrintLinef("# dma %c%02d: no change: %s", IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag),orgvalString); cliPrintLinef("# dma %c%02d: no change: %s", IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag),orgvalString);
} }

View file

@ -48,6 +48,8 @@
#endif #endif
#define TIM_CH_TO_SELCHANNEL(ch) ((ch - 1) * 2) #define TIM_CH_TO_SELCHANNEL(ch) ((ch - 1) * 2)
#define TIM_N(n) (1 << (n))
#define TIMER_INDEX(i) BITCOUNT((TIM_N(i) - 1) & USED_TIMERS)
typedef uint16_t captureCompare_t; // 16 bit on both 103 and 303, just register access must be 32bit sometimes (use timCCR_t) typedef uint16_t captureCompare_t; // 16 bit on both 103 and 303, just register access must be 32bit sometimes (use timCCR_t)
@ -222,6 +224,7 @@ uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz); uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz);
int8_t timerGetNumberByIndex(uint8_t index); int8_t timerGetNumberByIndex(uint8_t index);
int8_t timerGetIndexByNumber(uint8_t number);
int8_t timerGetTIMNumber(const TIM_TypeDef *tim); int8_t timerGetTIMNumber(const TIM_TypeDef *tim);
uint8_t timerLookupChannelIndex(const uint16_t channel); uint8_t timerLookupChannelIndex(const uint16_t channel);

View file

@ -37,53 +37,41 @@ void pgResetFn_timerUpConfig(timerUpConfig_t *config)
config[timno].dmaopt = DMA_OPT_UNUSED; config[timno].dmaopt = DMA_OPT_UNUSED;
} }
#if defined(TIMUP1_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 0) #if defined(TIMUP1_DMA_OPT) && (TIMUP_TIMERS & TIM_N(1))
config[0].dmaopt = TIMUP1_DMA_OPT; config[TIMER_INDEX(1)].dmaopt = TIMUP1_DMA_OPT;
#endif #endif
#if defined(TIMUP2_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 1) #if defined(TIMUP2_DMA_OPT) && (TIMUP_TIMERS & TIM_N(2))
config[1].dmaopt = TIMUP2_DMA_OPT; config[TIMER_INDEX(2)].dmaopt = TIMUP2_DMA_OPT;
#endif #endif
#if defined(TIMUP3_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 2) #if defined(TIMUP3_DMA_OPT) && (TIMUP_TIMERS & TIM_N(3))
config[2].dmaopt = TIMUP3_DMA_OPT; config[TIMER_INDEX(3)].dmaopt = TIMUP3_DMA_OPT;
#endif #endif
#if defined(TIMUP4_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 3) #if defined(TIMUP4_DMA_OPT) && (TIMUP_TIMERS & TIM_N(4))
config[3].dmaopt = TIMUP4_DMA_OPT; config[TIMER_INDEX(4)].dmaopt = TIMUP4_DMA_OPT;
#endif #endif
#if defined(TIMUP5_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 4) #if defined(TIMUP5_DMA_OPT) && (TIMUP_TIMERS & TIM_N(5))
config[4].dmaopt = TIMUP5_DMA_OPT; config[TIMER_INDEX(5)].dmaopt = TIMUP5_DMA_OPT;
#endif #endif
#if defined(TIMUP8_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 7) #if defined(TIMUP6_DMA_OPT) && (TIMUP_TIMERS & TIM_N(6))
config[7].dmaopt = TIMUP8_DMA_OPT; config[TIMER_INDEX(6)].dmaopt = TIMUP6_DMA_OPT;
#endif #endif
#if defined(TIMUP9_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 8) #if defined(TIMUP7_DMA_OPT) && (TIMUP_TIMERS & TIM_N(7))
config[8].dmaopt = TIMUP9_DMA_OPT; config[TIMER_INDEX(7)].dmaopt = TIMUP7_DMA_OPT;
#endif #endif
#if defined(TIMUP10_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 9) #if defined(TIMUP8_DMA_OPT) && (TIMUP_TIMERS & TIM_N(8))
config[9].dmaopt = TIMUP10_DMA_OPT; config[TIMER_INDEX(8)].dmaopt = TIMUP8_DMA_OPT;
#endif #endif
#if defined(TIMUP11_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 10) #if defined(TIMUP15_DMA_OPT) && (TIMUP_TIMERS & TIM_N(15))
config[10].dmaopt = TIMUP11_DMA_OPT; config[TIMER_INDEX(15)].dmaopt = TIMUP15_DMA_OPT;
#endif #endif
#if defined(TIMUP12_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 11) #if defined(TIMUP16_DMA_OPT) && (TIMUP_TIMERS & TIM_N(16))
config[11].dmaopt = TIMUP12_DMA_OPT; config[TIMER_INDEX(16)].dmaopt = TIMUP16_DMA_OPT;
#endif #endif
#if defined(TIMUP13_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 12) #if defined(TIMUP17_DMA_OPT) && (TIMUP_TIMERS & TIM_N(17))
config[12].dmaopt = TIMUP13_DMA_OPT; config[TIMER_INDEX(17)].dmaopt = TIMUP17_DMA_OPT;
#endif #endif
#if defined(TIMUP14_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 13) #if defined(TIMUP20_DMA_OPT) && (TIMUP_TIMERS & TIM_N(20))
config[13].dmaopt = TIMUP14_DMA_OPT; config[TIMER_INDEX(20)].dmaopt = TIMUP20_DMA_OPT;
#endif
#if defined(TIMUP15_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 14)
config[14].dmaopt = TIMUP15_DMA_OPT;
#endif
#if defined(TIMUP16_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 15)
config[15].dmaopt = TIMUP16_DMA_OPT;
#endif
#if defined(TIMUP17_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 16)
config[16].dmaopt = TIMUP17_DMA_OPT;
#endif
#if defined(TIMUP20_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 19)
config[19].dmaopt = TIMUP20_DMA_OPT;
#endif #endif
} }
#endif #endif

View file

@ -29,6 +29,10 @@
#if defined(USE_TIMER_MGMT) && defined(USE_TIMER_UP_CONFIG) #if defined(USE_TIMER_MGMT) && defined(USE_TIMER_UP_CONFIG)
#if defined(USED_TIMERS) && defined(TIMUP_TIMERS)
STATIC_ASSERT((~USED_TIMERS & TIMUP_TIMERS) == 0, "All TIMUP timers must be used");
#endif
typedef struct timerUpConfig_s { typedef struct timerUpConfig_s {
int8_t dmaopt; int8_t dmaopt;
} timerUpConfig_t; } timerUpConfig_t;

View file

@ -284,6 +284,11 @@ int8_t timerGetNumberByIndex(uint8_t index)
} }
} }
int8_t timerGetIndexByNumber(uint8_t number)
{
return TIM_N(number) & USED_TIMERS ? popcount((TIM_N(number) - 1) & USED_TIMERS) : -1;
}
int8_t timerGetTIMNumber(const TMR_TypeDef *tim) int8_t timerGetTIMNumber(const TMR_TypeDef *tim)
{ {
uint8_t index = lookupTimerIndex(tim); uint8_t index = lookupTimerIndex(tim);

View file

@ -336,5 +336,5 @@
#define FULL_TIMER_CHANNEL_COUNT 78 #define FULL_TIMER_CHANNEL_COUNT 78
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) ) #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) )
#define HARDWARE_TIMER_DEFINITION_COUNT 14 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)

View file

@ -49,7 +49,7 @@ typedef struct dmaTimerMapping_s {
#define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph } #define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph }
#define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device } #define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device }
#define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir } #define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir }
#define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, timno - 1, DMAMUX_DMAREQ_ID_ ## TMR ## timno ## _OVERFLOW } #define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, TIMER_INDEX(timno), DMAMUX_DMAREQ_ID_ ## TMR ## timno ## _OVERFLOW }
#define DMA_REQUEST_UART1_RX DMAMUX_DMAREQ_ID_USART1_RX #define DMA_REQUEST_UART1_RX DMAMUX_DMAREQ_ID_USART1_RX
#define DMA_REQUEST_UART1_TX DMAMUX_DMAREQ_ID_USART1_TX #define DMA_REQUEST_UART1_TX DMAMUX_DMAREQ_ID_USART1_TX

View file

@ -283,6 +283,11 @@ int8_t timerGetNumberByIndex(uint8_t index)
} }
} }
int8_t timerGetIndexByNumber(uint8_t number)
{
return TIM_N(number) & USED_TIMERS ? popcount((TIM_N(number) - 1) & USED_TIMERS) : -1;
}
int8_t timerGetTIMNumber(const tmr_type *tim) int8_t timerGetTIMNumber(const tmr_type *tim)
{ {
const uint8_t index = lookupTimerIndex(tim); const uint8_t index = lookupTimerIndex(tim);

View file

@ -24,10 +24,10 @@
#include "platform.h" #include "platform.h"
#include "common/utils.h" #include "common/utils.h"
#define USED_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(20) ) #define USED_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(20) )
#define TIMUP_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(8) | BIT(20) ) #define TIMUP_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(8) | BIT(20) )
#define FULL_TIMER_CHANNEL_COUNT 109 #define FULL_TIMER_CHANNEL_COUNT 109
#define HARDWARE_TIMER_DEFINITION_COUNT 15 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)
// allow conditional definition of DMA related members // allow conditional definition of DMA related members
#if defined(USE_TIMER_DMA) #if defined(USE_TIMER_DMA)

View file

@ -59,7 +59,7 @@ typedef struct dmaTimerMapping_s {
#define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph } #define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph }
#define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device } #define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device }
#define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir } #define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir }
#define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, timno - 1, DMA_REQUEST_ ## TIM ## timno ## _UP } #define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, TIMER_INDEX(timno), DMA_REQUEST_ ## TIM ## timno ## _UP }
// Resolve UART/USART mess // Resolve UART/USART mess
#define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX #define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX
@ -215,7 +215,7 @@ static dmaChannelSpec_t dmaChannelSpec[MAX_PERIPHERAL_DMA_OPTIONS] = {
#define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph } #define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph }
#define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device } #define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device }
#define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir } #define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir }
#define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, timno - 1, DMA_REQUEST_ ## TIM ## timno ## _UP } #define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, TIMER_INDEX(timno), DMA_REQUEST_ ## TIM ## timno ## _UP }
// Resolve UART/USART mess // Resolve UART/USART mess
#define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX #define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX

View file

@ -1128,20 +1128,20 @@
#define FULL_TIMER_CHANNEL_COUNT 78 #define FULL_TIMER_CHANNEL_COUNT 78
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) ) #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) )
#define HARDWARE_TIMER_DEFINITION_COUNT 14 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)
#elif defined(STM32F4) #elif defined(STM32F4)
#if defined(STM32F411xE) #if defined(STM32F411xE)
#define FULL_TIMER_CHANNEL_COUNT 59 #define FULL_TIMER_CHANNEL_COUNT 59
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(9) | TIM_N(10) | TIM_N(11) ) #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(9) | TIM_N(10) | TIM_N(11) )
#define HARDWARE_TIMER_DEFINITION_COUNT 10 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)
#else #else
#define FULL_TIMER_CHANNEL_COUNT 78 #define FULL_TIMER_CHANNEL_COUNT 78
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) ) #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) )
#define HARDWARE_TIMER_DEFINITION_COUNT 14 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)
#endif //STM32F411xE #endif //STM32F411xE
@ -1149,14 +1149,14 @@
#define FULL_TIMER_CHANNEL_COUNT 91 #define FULL_TIMER_CHANNEL_COUNT 91
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(12) | TIM_N(13) | TIM_N(14) | TIM_N(15) | TIM_N(16) | TIM_N(17) ) #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(12) | TIM_N(13) | TIM_N(14) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
#define HARDWARE_TIMER_DEFINITION_COUNT 17 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)
#define TIMUP_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(15) | BIT(16) | BIT(17) ) #define TIMUP_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
#elif defined(STM32G4) #elif defined(STM32G4)
#define FULL_TIMER_CHANNEL_COUNT 93 // XXX Need review #define FULL_TIMER_CHANNEL_COUNT 93 // XXX Need review
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) | TIM_N(20) ) #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) | TIM_N(20) )
#define HARDWARE_TIMER_DEFINITION_COUNT 12 #define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS)
#define TIMUP_TIMERS ( BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(15) | BIT(16) | BIT(17) | BIT(20)) #define TIMUP_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) | TIM_N(20))
#endif #endif

View file

@ -292,6 +292,11 @@ int8_t timerGetNumberByIndex(uint8_t index)
} }
} }
int8_t timerGetIndexByNumber(uint8_t number)
{
return TIM_N(number) & USED_TIMERS ? popcount((TIM_N(number) - 1) & USED_TIMERS) : -1;
}
int8_t timerGetTIMNumber(const TIM_TypeDef *tim) int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
{ {
uint8_t index = lookupTimerIndex(tim); uint8_t index = lookupTimerIndex(tim);

View file

@ -274,6 +274,11 @@ int8_t timerGetNumberByIndex(uint8_t index)
} }
} }
int8_t timerGetIndexByNumber(uint8_t number)
{
return TIM_N(number) & USED_TIMERS ? popcount((TIM_N(number) - 1) & USED_TIMERS) : -1;
}
int8_t timerGetTIMNumber(const TIM_TypeDef *tim) int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
{ {
const uint8_t index = lookupTimerIndex(tim); const uint8_t index = lookupTimerIndex(tim);