diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index 5deca99a29..0236f3db3f 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -4810,6 +4810,14 @@ dmaoptEntry_t dmaoptEntryTable[] = { #define DMA_OPT_UI_INDEX(i) ((i) + 1) #define DMA_OPT_STRING_BUFSIZE 5 +#ifdef STM32H7 +#define DMA_CHANREQ_STRING "Request" +#else +#define DMA_CHANREQ_STRING "Channel" +#endif + +#define DMASPEC_FORMAT_STRING "DMA%d Stream %d " DMA_CHANREQ_STRING " %d" + static void optToString(int optval, char *buf) { if (optval == DMA_OPT_UNUSED) { @@ -4832,7 +4840,7 @@ static void printPeripheralDmaoptDetails(dmaoptEntry_t *entry, int index, const dmaCode = dmaChannelSpec->code; } printValue(dumpMask, equalsDefault, - "# %s %d: DMA%d Stream %d Channel %d", + "# %s %d: " DMASPEC_FORMAT_STRING, entry->device, DMA_OPT_UI_INDEX(index), DMA_CODE_CONTROLLER(dmaCode), DMA_CODE_STREAM(dmaCode), DMA_CODE_CHANNEL(dmaCode)); } else if (!(dumpMask & HIDE_UNUSED)) { printValue(dumpMask, equalsDefault, @@ -4892,7 +4900,7 @@ static void printTimerDmaoptDetails(const ioTag_t ioTag, const timerHardware_t * if (dmaChannelSpec) { dmaCode = dmaChannelSpec->code; printValue(dumpMask, false, - "# pin %c%02d: DMA%d Stream %d Channel %d", + "# pin %c%02d: " DMASPEC_FORMAT_STRING, IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag), DMA_CODE_CONTROLLER(dmaCode), DMA_CODE_STREAM(dmaCode), DMA_CODE_CHANNEL(dmaCode) ); @@ -5077,11 +5085,11 @@ static void cliDmaopt(char *cmdline) const dmaChannelSpec_t *dmaChannelSpec; if (entry) { for (int opt = 0; (dmaChannelSpec = dmaGetChannelSpecByPeripheral(entry->peripheral, index, opt)); opt++) { - cliPrintLinef("# %d: DMA%d Stream %d channel %d", opt, DMA_CODE_CONTROLLER(dmaChannelSpec->code), DMA_CODE_STREAM(dmaChannelSpec->code), DMA_CODE_CHANNEL(dmaChannelSpec->code)); + cliPrintLinef("# %d: " DMASPEC_FORMAT_STRING, opt, DMA_CODE_CONTROLLER(dmaChannelSpec->code), DMA_CODE_STREAM(dmaChannelSpec->code), DMA_CODE_CHANNEL(dmaChannelSpec->code)); } } else { for (int opt = 0; (dmaChannelSpec = dmaGetChannelSpecByTimerValue(timer->tim, timer->channel, opt)); opt++) { - cliPrintLinef("# %d: DMA%d Stream %d channel %d", opt, DMA_CODE_CONTROLLER(dmaChannelSpec->code), DMA_CODE_STREAM(dmaChannelSpec->code), DMA_CODE_CHANNEL(dmaChannelSpec->code)); + cliPrintLinef("# %d: " DMASPEC_FORMAT_STRING, opt, DMA_CODE_CONTROLLER(dmaChannelSpec->code), DMA_CODE_STREAM(dmaChannelSpec->code), DMA_CODE_CHANNEL(dmaChannelSpec->code)); } } diff --git a/src/main/drivers/dma_reqmap.c b/src/main/drivers/dma_reqmap.c index 6e79b15cb5..1080a03c8e 100644 --- a/src/main/drivers/dma_reqmap.c +++ b/src/main/drivers/dma_reqmap.c @@ -122,7 +122,6 @@ static const dmaPeripheralMapping_t dmaPeripheralMapping[] = { #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan) -//#define REQMAP_TIM(tim, chan) { tim, TC(chan), DEF_TIM_DMA_REQ__BTCH_ ## tim ## _ ## chan } #define REQMAP_TIM(tim, chan) { tim, TC(chan), DMA_REQUEST_ ## tim ## _ ## chan } static const dmaTimerMapping_t dmaTimerMapping[] = { @@ -444,14 +443,20 @@ const dmaChannelSpec_t *dmaGetChannelSpecByTimer(const timerHardware_t *timer) return dmaGetChannelSpecByTimerValue(timer->tim, timer->channel, dmaopt); } +// dmaGetOptionByTimer is called by pgResetFn_timerIOConfig to find out dmaopt for pre-configured timer. + dmaoptValue_t dmaGetOptionByTimer(const timerHardware_t *timer) { +#if defined(STM32H7) + for (unsigned opt = 0; opt < ARRAYLEN(dmaChannelSpec); opt++) { + if (timer->dmaRefConfigured == dmaChannelSpec[opt].ref) { + return (dmaoptValue_t)opt; + } + } +#else for (unsigned i = 0 ; i < ARRAYLEN(dmaTimerMapping); i++) { const dmaTimerMapping_t *timerMapping = &dmaTimerMapping[i]; if (timerMapping->tim == timer->tim && timerMapping->channel == timer->channel) { -#if defined(STM32H7) - return timerMapping->dmaRequest; -#else for (unsigned j = 0; j < MAX_TIMER_DMA_OPTIONS; j++) { const dmaChannelSpec_t *dma = &timerMapping->channelSpec[j]; if (dma->ref == timer->dmaRefConfigured @@ -462,9 +467,9 @@ dmaoptValue_t dmaGetOptionByTimer(const timerHardware_t *timer) return j; } } -#endif } } +#endif return DMA_OPT_UNUSED; } diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index e30300b834..a500ca204d 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -187,6 +187,10 @@ extern const timerHardware_t timerHardware[]; #define FULL_TIMER_CHANNEL_COUNT 78 +#elif defined(STM32H7) + +#define FULL_TIMER_CHANNEL_COUNT 87 + #endif extern const timerHardware_t fullTimerHardware[]; @@ -206,6 +210,10 @@ extern const timerHardware_t fullTimerHardware[]; #define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) ) +#elif defined(STM32H7) + +#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) ) + #else #error "No timer / channel tag definition found for CPU" #endif diff --git a/src/main/drivers/timer_def.h b/src/main/drivers/timer_def.h index 662726fbbd..2178be5bc4 100644 --- a/src/main/drivers/timer_def.h +++ b/src/main/drivers/timer_def.h @@ -718,7 +718,7 @@ #elif defined(STM32H7) #define DEF_TIM(tim, chan, pin, flags, out, dmaopt, upopt) { \ tim, \ - IO_TAG(pin), \ + TIMER_GET_IO_TAG(pin), \ DEF_TIM_CHANNEL(CH_ ## chan), \ flags, \ (DEF_TIM_OUTPUT(CH_ ## chan) | out), \ diff --git a/src/main/drivers/timer_stm32h7xx.c b/src/main/drivers/timer_stm32h7xx.c index a5ad78347f..8d8179ae20 100644 --- a/src/main/drivers/timer_stm32h7xx.c +++ b/src/main/drivers/timer_stm32h7xx.c @@ -24,6 +24,10 @@ #include "common/utils.h" +#include "drivers/dma.h" +#include "drivers/io.h" +#include "drivers/timer_def.h" + #include "stm32h7xx.h" #include "rcc.h" #include "timer.h" @@ -45,6 +49,116 @@ const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = { { .TIMx = TIM17, .rcc = RCC_APB2(TIM17), .inputIrq = TIM17_IRQn}, }; +#if defined(USE_TIMER_MGMT) +const timerHardware_t fullTimerHardware[FULL_TIMER_CHANNEL_COUNT] = { +// Auto-generated from 'timer_def.h' +// Port A + DEF_TIM(TIM2, CH1, PA0, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH2, PA1, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH3, PA2, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH4, PA3, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH1, PA5, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH1N, PA7, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH2, PA9, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH3, PA10, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH4, PA11, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH1, PA15, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM5, CH1, PA0, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM5, CH4, PA3, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH1, PA6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH2, PA7, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM8, CH1N, PA5, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH1N, PA7, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM13, CH1, PA6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM14, CH1, PA7, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM15, CH1N, PA1, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM15, CH1, PA2, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM15, CH2, PA2, TIM_USE_ANY, 0, 0, 0), + +// Port B + DEF_TIM(TIM1, CH2N, PB0, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH3N, PB1, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH2, PB3, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM16, CH1N, PB6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM17, CH1N, PB7, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM16, CH1, PB8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM17, CH1, PB9, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH3, PB10, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM2, CH4, PB11, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH1N, PB13, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH2N, PB14, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH3N, PB15, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM3, CH3, PB0, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH4, PB1, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH1, PB4, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH2, PB5, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH1, PB6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH2, PB7, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH3, PB8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM12, CH1, PB14, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0, 0), + +// Port C + DEF_TIM(TIM3, CH1, PC6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH2, PC7, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH3, PC8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM3, CH4, PC9, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0, 0), + +// Port D + DEF_TIM(TIM4, CH1, PD12, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH2, PD13, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH3, PD14, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM4, CH4, PD15, TIM_USE_ANY, 0, 0, 0), + +// Port E + DEF_TIM(TIM1, CH1N, PE8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH1, PE9, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH2N, PE10, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH2, PE11, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH3N, PE12, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH3, PE13, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM1, CH4, PE14, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM15, CH1N, PE4, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM15, CH1, PE5, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM15, CH2, PE6, TIM_USE_ANY, 0, 0, 0), + +// Port F + DEF_TIM(TIM16, CH1, PF6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM17, CH1, PF7, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM16, CH1N, PF8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM17, CH1N, PF9, TIM_USE_ANY, 0, 0, 0), + + DEF_TIM(TIM13, CH1N, PF8, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM14, CH1N, PF9, TIM_USE_ANY, 0, 0, 0), + +// Port H + DEF_TIM(TIM12, CH1, PH6, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM12, CH2, PH9, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM5, CH1, PH10, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM5, CH2, PH11, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM5, CH3, PH12, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH1N, PH13, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH2N, PH14, TIM_USE_ANY, 0, 0, 0), + DEF_TIM(TIM8, CH3N, PH15, TIM_USE_ANY, 0, 0, 0), +}; +#endif + uint32_t timerClock(TIM_TypeDef *tim) { int timpre; diff --git a/src/main/target/common_pre.h b/src/main/target/common_pre.h index 2c26df5d05..0ce7f5f5bb 100644 --- a/src/main/target/common_pre.h +++ b/src/main/target/common_pre.h @@ -105,6 +105,7 @@ #define USE_ADC_INTERNAL #define USE_USB_CDC_HID #define USE_DMA_SPEC +#define USE_TIMER_MGMT #endif #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)