diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index 7082fae350..c9162c680c 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -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) { // 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, // but we are lucky that TIMUP is the only peripheral with non-contiguous numbering. - int uiIndex; - - if (entry->presenceMask) { - uiIndex = timerGetNumberByIndex(index); - } else { - uiIndex = DMA_OPT_UI_INDEX(index); + int uiIndex = getDmaOptDisplayNumber(entry, index); + if (uiIndex == -1) { + return; } if (dmaopt != DMA_OPT_UNUSED) { @@ -5641,8 +5667,8 @@ static void cliDmaopt(const char *cmdName, char *cmdline) const timerHardware_t *timer = NULL; pch = strtok_r(NULL, " ", &saveptr); if (entry) { - index = pch ? (atoi(pch) - 1) : -1; - if (index < 0 || index >= entry->maxIndex || (entry->presenceMask != MASK_IGNORED && !(entry->presenceMask & BIT(index + 1)))) { + index = displayNumberToDmaOptIndex(entry, pch ? atoi(pch) : -1); + if (index == -1) { cliPrintErrorLinef(cmdName, "BAD INDEX: '%s'", pch ? pch : ""); return; } @@ -5707,7 +5733,7 @@ static void cliDmaopt(const char *cmdName, char *cmdline) if (entry) { 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; } @@ -5730,7 +5756,7 @@ static void cliDmaopt(const char *cmdName, char *cmdline) if (entry) { *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 { #if defined(USE_TIMER_MGMT) timerIoConfig->dmaopt = optval; @@ -5740,7 +5766,7 @@ static void cliDmaopt(const char *cmdName, char *cmdline) } } else { 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 { cliPrintLinef("# dma %c%02d: no change: %s", IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag),orgvalString); } diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index 13bfec69c5..9df5639128 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -48,6 +48,8 @@ #endif #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) @@ -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); int8_t timerGetNumberByIndex(uint8_t index); +int8_t timerGetIndexByNumber(uint8_t number); int8_t timerGetTIMNumber(const TIM_TypeDef *tim); uint8_t timerLookupChannelIndex(const uint16_t channel); diff --git a/src/main/pg/timerup.c b/src/main/pg/timerup.c index 39c6ecf435..df6e604315 100644 --- a/src/main/pg/timerup.c +++ b/src/main/pg/timerup.c @@ -37,53 +37,41 @@ void pgResetFn_timerUpConfig(timerUpConfig_t *config) config[timno].dmaopt = DMA_OPT_UNUSED; } -#if defined(TIMUP1_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 0) - config[0].dmaopt = TIMUP1_DMA_OPT; +#if defined(TIMUP1_DMA_OPT) && (TIMUP_TIMERS & TIM_N(1)) + config[TIMER_INDEX(1)].dmaopt = TIMUP1_DMA_OPT; #endif -#if defined(TIMUP2_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 1) - config[1].dmaopt = TIMUP2_DMA_OPT; +#if defined(TIMUP2_DMA_OPT) && (TIMUP_TIMERS & TIM_N(2)) + config[TIMER_INDEX(2)].dmaopt = TIMUP2_DMA_OPT; #endif -#if defined(TIMUP3_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 2) - config[2].dmaopt = TIMUP3_DMA_OPT; +#if defined(TIMUP3_DMA_OPT) && (TIMUP_TIMERS & TIM_N(3)) + config[TIMER_INDEX(3)].dmaopt = TIMUP3_DMA_OPT; #endif -#if defined(TIMUP4_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 3) - config[3].dmaopt = TIMUP4_DMA_OPT; +#if defined(TIMUP4_DMA_OPT) && (TIMUP_TIMERS & TIM_N(4)) + config[TIMER_INDEX(4)].dmaopt = TIMUP4_DMA_OPT; #endif -#if defined(TIMUP5_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 4) - config[4].dmaopt = TIMUP5_DMA_OPT; +#if defined(TIMUP5_DMA_OPT) && (TIMUP_TIMERS & TIM_N(5)) + config[TIMER_INDEX(5)].dmaopt = TIMUP5_DMA_OPT; #endif -#if defined(TIMUP8_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 7) - config[7].dmaopt = TIMUP8_DMA_OPT; +#if defined(TIMUP6_DMA_OPT) && (TIMUP_TIMERS & TIM_N(6)) + config[TIMER_INDEX(6)].dmaopt = TIMUP6_DMA_OPT; #endif -#if defined(TIMUP9_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 8) - config[8].dmaopt = TIMUP9_DMA_OPT; +#if defined(TIMUP7_DMA_OPT) && (TIMUP_TIMERS & TIM_N(7)) + config[TIMER_INDEX(7)].dmaopt = TIMUP7_DMA_OPT; #endif -#if defined(TIMUP10_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 9) - config[9].dmaopt = TIMUP10_DMA_OPT; +#if defined(TIMUP8_DMA_OPT) && (TIMUP_TIMERS & TIM_N(8)) + config[TIMER_INDEX(8)].dmaopt = TIMUP8_DMA_OPT; #endif -#if defined(TIMUP11_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 10) - config[10].dmaopt = TIMUP11_DMA_OPT; +#if defined(TIMUP15_DMA_OPT) && (TIMUP_TIMERS & TIM_N(15)) + config[TIMER_INDEX(15)].dmaopt = TIMUP15_DMA_OPT; #endif -#if defined(TIMUP12_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 11) - config[11].dmaopt = TIMUP12_DMA_OPT; +#if defined(TIMUP16_DMA_OPT) && (TIMUP_TIMERS & TIM_N(16)) + config[TIMER_INDEX(16)].dmaopt = TIMUP16_DMA_OPT; #endif -#if defined(TIMUP13_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 12) - config[12].dmaopt = TIMUP13_DMA_OPT; +#if defined(TIMUP17_DMA_OPT) && (TIMUP_TIMERS & TIM_N(17)) + config[TIMER_INDEX(17)].dmaopt = TIMUP17_DMA_OPT; #endif -#if defined(TIMUP14_DMA_OPT) && (HARDWARE_TIMER_DEFINITION_COUNT > 13) - config[13].dmaopt = TIMUP14_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; +#if defined(TIMUP20_DMA_OPT) && (TIMUP_TIMERS & TIM_N(20)) + config[TIMER_INDEX(20)].dmaopt = TIMUP20_DMA_OPT; #endif } #endif diff --git a/src/main/pg/timerup.h b/src/main/pg/timerup.h index 24ecd1fd7c..7008390bb4 100644 --- a/src/main/pg/timerup.h +++ b/src/main/pg/timerup.h @@ -29,6 +29,10 @@ #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 { int8_t dmaopt; } timerUpConfig_t; diff --git a/src/platform/APM32/timer_apm32.c b/src/platform/APM32/timer_apm32.c index 710ebc509a..e516c2af8b 100644 --- a/src/platform/APM32/timer_apm32.c +++ b/src/platform/APM32/timer_apm32.c @@ -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) { uint8_t index = lookupTimerIndex(tim); diff --git a/src/platform/APM32/timer_def.h b/src/platform/APM32/timer_def.h index 157fe314f6..103de9844c 100644 --- a/src/platform/APM32/timer_def.h +++ b/src/platform/APM32/timer_def.h @@ -336,5 +336,5 @@ #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 HARDWARE_TIMER_DEFINITION_COUNT 14 +#define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS) diff --git a/src/platform/AT32/dma_reqmap_mcu.c b/src/platform/AT32/dma_reqmap_mcu.c index 653efd3c3f..96ef5551c7 100644 --- a/src/platform/AT32/dma_reqmap_mcu.c +++ b/src/platform/AT32/dma_reqmap_mcu.c @@ -49,7 +49,7 @@ typedef struct dmaTimerMapping_s { #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_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_TX DMAMUX_DMAREQ_ID_USART1_TX diff --git a/src/platform/AT32/timer_at32bsp.c b/src/platform/AT32/timer_at32bsp.c index a6da1cb51c..24e28a0fd7 100644 --- a/src/platform/AT32/timer_at32bsp.c +++ b/src/platform/AT32/timer_at32bsp.c @@ -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) { const uint8_t index = lookupTimerIndex(tim); diff --git a/src/platform/AT32/timer_def.h b/src/platform/AT32/timer_def.h index cc60f84718..3c35f6e49d 100644 --- a/src/platform/AT32/timer_def.h +++ b/src/platform/AT32/timer_def.h @@ -24,10 +24,10 @@ #include "platform.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 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 #if defined(USE_TIMER_DMA) diff --git a/src/platform/STM32/dma_reqmap_mcu.c b/src/platform/STM32/dma_reqmap_mcu.c index 57001a1919..e2862119e9 100644 --- a/src/platform/STM32/dma_reqmap_mcu.c +++ b/src/platform/STM32/dma_reqmap_mcu.c @@ -59,7 +59,7 @@ typedef struct dmaTimerMapping_s { #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_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 #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(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_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 #define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX diff --git a/src/platform/STM32/timer_def.h b/src/platform/STM32/timer_def.h index d31af27c39..bd9df782e8 100644 --- a/src/platform/STM32/timer_def.h +++ b/src/platform/STM32/timer_def.h @@ -1128,20 +1128,20 @@ #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 HARDWARE_TIMER_DEFINITION_COUNT 14 +#define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS) #elif defined(STM32F4) #if defined(STM32F411xE) #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 HARDWARE_TIMER_DEFINITION_COUNT 10 +#define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS) #else #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 HARDWARE_TIMER_DEFINITION_COUNT 14 +#define HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS) #endif //STM32F411xE @@ -1149,14 +1149,14 @@ #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 HARDWARE_TIMER_DEFINITION_COUNT 17 -#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 HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS) +#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) #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 HARDWARE_TIMER_DEFINITION_COUNT 12 -#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 HARDWARE_TIMER_DEFINITION_COUNT BITCOUNT(USED_TIMERS) +#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 diff --git a/src/platform/STM32/timer_hal.c b/src/platform/STM32/timer_hal.c index e4ea1a413a..c22fb2186c 100644 --- a/src/platform/STM32/timer_hal.c +++ b/src/platform/STM32/timer_hal.c @@ -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) { uint8_t index = lookupTimerIndex(tim); diff --git a/src/platform/STM32/timer_stdperiph.c b/src/platform/STM32/timer_stdperiph.c index c5ecefba24..2bba4b28b0 100644 --- a/src/platform/STM32/timer_stdperiph.c +++ b/src/platform/STM32/timer_stdperiph.c @@ -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) { const uint8_t index = lookupTimerIndex(tim);