diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index bb9d08a686..73954a7366 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -50,6 +50,11 @@ typedef uint32_t timCCR_t; typedef uint32_t timCCER_t; typedef uint32_t timSR_t; typedef uint32_t timCNT_t; +#elif defined(STM32H7) +typedef uint32_t timCCR_t; +typedef uint32_t timCCER_t; +typedef uint32_t timSR_t; +typedef uint32_t timCNT_t; #elif defined(STM32F1) typedef uint16_t timCCR_t; typedef uint16_t timCCER_t; @@ -104,12 +109,12 @@ typedef struct timerHardware_s { uint8_t channel; timerUsageFlag_e usageFlags; uint8_t output; -#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) +#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) uint8_t alternateFunction; #endif #if defined(USE_DSHOT) || defined(USE_LED_STRIP) || defined(USE_TRANSPONDER) #if defined(USE_DMA_SPEC) -#if defined(STM32F4) || defined(STM32F7) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) DMA_Stream_TypeDef *dmaRefConfigured; uint32_t dmaChannelConfigured; #else @@ -119,14 +124,22 @@ typedef struct timerHardware_s { #if defined(STM32F4) || defined(STM32F7) DMA_Stream_TypeDef *dmaRef; uint32_t dmaChannel; +#elif defined(STM32H7) + DMA_Stream_TypeDef *dmaRef; + uint8_t dmaRequest; + uint8_t dmaIrqHandler; // XXX Should be gone (can be substituted by dmaGetIdentifier) #else DMA_Channel_TypeDef *dmaRef; #endif #endif -#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) + +#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) // TIMUP #ifdef STM32F3 DMA_Channel_TypeDef *dmaTimUPRef; +#elif defined(STM32H7) + DMA_Stream_TypeDef *dmaTimUPRef; + uint8_t dmaTimUPRequest; #else DMA_Stream_TypeDef *dmaTimUPRef; uint32_t dmaTimUPChannel; @@ -158,6 +171,8 @@ typedef enum { #define HARDWARE_TIMER_DEFINITION_COUNT 14 #elif defined(STM32F7) #define HARDWARE_TIMER_DEFINITION_COUNT 14 +#elif defined(STM32H7) +#define HARDWARE_TIMER_DEFINITION_COUNT 17 #endif #define MHZ_TO_HZ(x) ((x) * 1000000) diff --git a/src/main/drivers/timer_def.h b/src/main/drivers/timer_def.h index f32bad84d2..57b843c1c2 100644 --- a/src/main/drivers/timer_def.h +++ b/src/main/drivers/timer_def.h @@ -101,9 +101,23 @@ // Create accessor macro and call it with entry from table // DMA_VARIANT_MISSING are used to satisfy variable arguments (-Wpedantic) and to get better error message (undefined symbol instead of preprocessor error) #define DEF_TIM_DMA_GET(variant, timch) PP_CALL(CONCAT(DEF_TIM_DMA_GET_VARIANT__, variant), CONCAT(DEF_TIM_DMA__, DEF_TIM_TCH2BTCH(timch)), DMA_VARIANT_MISSING, DMA_VARIANT_MISSING, ERROR) -#define DEF_TIM_DMA_GET_VARIANT__0(_0, ...) _0 -#define DEF_TIM_DMA_GET_VARIANT__1(_0, _1, ...) _1 + +#define DEF_TIM_DMA_GET_VARIANT__0(_0, ...) _0 +#define DEF_TIM_DMA_GET_VARIANT__1(_0, _1, ...) _1 #define DEF_TIM_DMA_GET_VARIANT__2(_0, _1, _2, ...) _2 +#define DEF_TIM_DMA_GET_VARIANT__3(_0, _1, _2, _3, ...) _3 +#define DEF_TIM_DMA_GET_VARIANT__4(_0, _1, _2, _3, _4, ...) _4 +#define DEF_TIM_DMA_GET_VARIANT__5(_0, _1, _2, _3, _4, _5, ...) _5 +#define DEF_TIM_DMA_GET_VARIANT__6(_0, _1, _2, _3, _4, _5, _6, ...) _6 +#define DEF_TIM_DMA_GET_VARIANT__7(_0, _1, _2, _3, _4, _5, _6, _7, ...) _7 +#define DEF_TIM_DMA_GET_VARIANT__8(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) _8 +#define DEF_TIM_DMA_GET_VARIANT__9(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) _9 +#define DEF_TIM_DMA_GET_VARIANT__10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) _10 +#define DEF_TIM_DMA_GET_VARIANT__11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) _11 +#define DEF_TIM_DMA_GET_VARIANT__12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) _12 +#define DEF_TIM_DMA_GET_VARIANT__13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) _13 +#define DEF_TIM_DMA_GET_VARIANT__14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) _14 +#define DEF_TIM_DMA_GET_VARIANT__15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15 // symbolic names for DMA variants #define DMA_VAR0 0 @@ -699,4 +713,294 @@ #define DEF_TIM_AF__PI6__TCH_TIM8_CH2 D(3, 8) #define DEF_TIM_AF__PI7__TCH_TIM8_CH3 D(3, 8) +#elif defined(STM32H7) +#define DEF_TIM(tim, chan, pin, flags, out, dmaopt, upopt) { \ + tim, \ + IO_TAG(pin), \ + DEF_TIM_CHANNEL(CH_ ## chan), \ + flags, \ + (DEF_TIM_OUTPUT(CH_ ## chan) | out), \ + DEF_TIM_AF(TCH_## tim ## _ ## chan, pin) \ + DEF_TIM_DMA_COND(/* add comma */ , \ + DEF_TIM_DMA_STREAM(dmaopt, TCH_## tim ## _ ## chan), \ + DEF_TIM_DMA_REQUEST(TCH_## tim ## _ ## chan), \ + DEF_TIM_DMA_HANDLER(dmaopt, TCH_## tim ## _ ## chan) \ + ) \ + DEF_TIM_DMA_COND(/* add comma */ , \ + DEF_TIM_DMA_STREAM(upopt, TCH_## tim ## _UP), \ + DEF_TIM_DMA_REQUEST(TCH_## tim ## _UP), \ + DEF_TIM_DMA_HANDLER(upopt, TCH_## tim ## _UP) \ + ) \ +} \ +/**/ + +#define DEF_TIM_CHANNEL(ch) CONCAT(DEF_TIM_CHANNEL__, DEF_TIM_CH_GET(ch)) +#define DEF_TIM_CHANNEL__D(chan_n, n_channel) TIM_CHANNEL_ ## chan_n + +#define DEF_TIM_AF(timch, pin) CONCAT(DEF_TIM_AF__, DEF_TIM_AF_GET(timch, pin)) +#define DEF_TIM_AF__D(af_n, tim_n) GPIO_AF ## af_n ## _TIM ## tim_n + +#define DEF_TIM_DMA_STREAM(variant, timch) \ + CONCAT(DEF_TIM_DMA_STREAM__, DEF_TIM_DMA_GET(variant, timch)) +#define DEF_TIM_DMA_STREAM__D(dma_n, stream_n) DMA ## dma_n ## _Stream ## stream_n +#define DEF_TIM_DMA_STREAM__NONE NULL + +// XXX This is awful. There must be some smart way of doing this ... +#define DEF_TIM_DMA_REQUEST(timch) \ + CONCAT(DEF_TIM_DMA_REQ__, DEF_TIM_TCH2BTCH(timch)) + +#define DEF_TIM_DMA_HANDLER(variant, timch) \ + CONCAT(DEF_TIM_DMA_HANDLER__, DEF_TIM_DMA_GET(variant, timch)) +#define DEF_TIM_DMA_HANDLER__D(dma_n, stream_n) DMA ## dma_n ## _ST ## stream_n ## _HANDLER +#define DEF_TIM_DMA_HANDLER__NONE 0 + +/* H7 Stream Mappings */ +// D(DMAx, Stream) + +// H7 has DMAMUX that allow arbitrary assignment of peripherals to streams. + +#define DEF_TIM_DMA_FULL \ + D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7), \ + D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7) + +#define DEF_TIM_DMA__BTCH_TIM1_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM1_CH2 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM1_CH3 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM1_CH4 DEF_TIM_DMA_FULL + +#define DEF_TIM_DMA__BTCH_TIM2_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM2_CH2 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM2_CH3 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM2_CH4 DEF_TIM_DMA_FULL + +#define DEF_TIM_DMA__BTCH_TIM3_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM3_CH2 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM3_CH3 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM3_CH4 DEF_TIM_DMA_FULL + +#define DEF_TIM_DMA__BTCH_TIM4_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM4_CH2 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM4_CH3 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM4_CH4 NONE + +#define DEF_TIM_DMA__BTCH_TIM5_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM5_CH2 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM5_CH3 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM5_CH4 DEF_TIM_DMA_FULL + +#define DEF_TIM_DMA__BTCH_TIM8_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM8_CH2 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM8_CH3 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM8_CH4 DEF_TIM_DMA_FULL + +#define DEF_TIM_DMA__BTCH_TIM12_CH1 NONE +#define DEF_TIM_DMA__BTCH_TIM12_CH2 NONE + +#define DEF_TIM_DMA__BTCH_TIM13_CH1 NONE + +#define DEF_TIM_DMA__BTCH_TIM14_CH1 NONE + +#define DEF_TIM_DMA__BTCH_TIM15_CH1 DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM15_CH2 NONE + +#define DEF_TIM_DMA__BTCH_TIM16_CH1 DEF_TIM_DMA_FULL + +#define DEF_TIM_DMA__BTCH_TIM17_CH1 DEF_TIM_DMA_FULL + +// TIM_UP table +#define DEF_TIM_DMA__BTCH_TIM1_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM2_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM3_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM4_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM5_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM6_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM7_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM8_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM12_UP NONE +#define DEF_TIM_DMA__BTCH_TIM13_UP NONE +#define DEF_TIM_DMA__BTCH_TIM14_UP NONE +#define DEF_TIM_DMA__BTCH_TIM15_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM16_UP DEF_TIM_DMA_FULL +#define DEF_TIM_DMA__BTCH_TIM17_UP DEF_TIM_DMA_FULL + +// TIMx_CHy request table + +// This is not defined in stm32h7xx_hal_timer.h +#define DMA_REQUEST_NONE 255 + +#define DEF_TIM_DMA_REQ__BTCH_TIM1_CH1 DMA_REQUEST_TIM1_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM1_CH2 DMA_REQUEST_TIM1_CH2 +#define DEF_TIM_DMA_REQ__BTCH_TIM1_CH3 DMA_REQUEST_TIM1_CH3 +#define DEF_TIM_DMA_REQ__BTCH_TIM1_CH4 DMA_REQUEST_TIM1_CH4 + +#define DEF_TIM_DMA_REQ__BTCH_TIM2_CH1 DMA_REQUEST_TIM2_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM2_CH2 DMA_REQUEST_TIM2_CH2 +#define DEF_TIM_DMA_REQ__BTCH_TIM2_CH3 DMA_REQUEST_TIM2_CH3 +#define DEF_TIM_DMA_REQ__BTCH_TIM2_CH4 DMA_REQUEST_TIM2_CH4 + +#define DEF_TIM_DMA_REQ__BTCH_TIM3_CH1 DMA_REQUEST_TIM3_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM3_CH2 DMA_REQUEST_TIM3_CH2 +#define DEF_TIM_DMA_REQ__BTCH_TIM3_CH3 DMA_REQUEST_TIM3_CH3 +#define DEF_TIM_DMA_REQ__BTCH_TIM3_CH4 DMA_REQUEST_TIM3_CH4 + +#define DEF_TIM_DMA_REQ__BTCH_TIM4_CH1 DMA_REQUEST_TIM4_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM4_CH2 DMA_REQUEST_TIM4_CH2 +#define DEF_TIM_DMA_REQ__BTCH_TIM4_CH3 DMA_REQUEST_TIM4_CH3 +#define DEF_TIM_DMA_REQ__BTCH_TIM4_CH4 DMA_REQUEST_NONE + +#define DEF_TIM_DMA_REQ__BTCH_TIM5_CH1 DMA_REQUEST_TIM5_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM5_CH2 DMA_REQUEST_TIM5_CH2 +#define DEF_TIM_DMA_REQ__BTCH_TIM5_CH3 DMA_REQUEST_TIM5_CH3 +#define DEF_TIM_DMA_REQ__BTCH_TIM5_CH4 DMA_REQUEST_TIM5_CH4 + +#define DEF_TIM_DMA_REQ__BTCH_TIM8_CH1 DMA_REQUEST_TIM8_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM8_CH2 DMA_REQUEST_TIM8_CH2 +#define DEF_TIM_DMA_REQ__BTCH_TIM8_CH3 DMA_REQUEST_TIM8_CH3 +#define DEF_TIM_DMA_REQ__BTCH_TIM8_CH4 DMA_REQUEST_TIM8_CH4 + +#define DEF_TIM_DMA_REQ__BTCH_TIM12_CH1 DMA_REQUEST_NONE +#define DEF_TIM_DMA_REQ__BTCH_TIM12_CH2 DMA_REQUEST_NONE + +#define DEF_TIM_DMA_REQ__BTCH_TIM13_CH1 DMA_REQUEST_NONE + +#define DEF_TIM_DMA_REQ__BTCH_TIM14_CH1 DMA_REQUEST_NONE + +#define DEF_TIM_DMA_REQ__BTCH_TIM15_CH1 DMA_REQUEST_TIM15_CH1 +#define DEF_TIM_DMA_REQ__BTCH_TIM15_CH2 DMA_REQUEST_NONE + +#define DEF_TIM_DMA_REQ__BTCH_TIM16_CH1 DMA_REQUEST_TIM16_CH1 + +#define DEF_TIM_DMA_REQ__BTCH_TIM17_CH1 DMA_REQUEST_TIM17_CH1 + +// TIM_UP request table +#define DEF_TIM_DMA_REQ__BTCH_TIM1_UP DMA_REQUEST_TIM1_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM2_UP DMA_REQUEST_TIM2_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM3_UP DMA_REQUEST_TIM3_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM4_UP DMA_REQUEST_TIM4_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM5_UP DMA_REQUEST_TIM5_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM6_UP DMA_REQUEST_TIM6_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM7_UP DMA_REQUEST_TIM7_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM8_UP DMA_REQUEST_TIM8_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM12_UP DMA_REQUEST_NONE +#define DEF_TIM_DMA_REQ__BTCH_TIM13_UP DMA_REQUEST_NONE +#define DEF_TIM_DMA_REQ__BTCH_TIM14_UP DMA_REQUEST_NONE +#define DEF_TIM_DMA_REQ__BTCH_TIM15_UP DMA_REQUEST_TIM15_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM16_UP DMA_REQUEST_TIM16_UP +#define DEF_TIM_DMA_REQ__BTCH_TIM17_UP DMA_REQUEST_TIM17_UP + +// AF table + +//PORTA +#define DEF_TIM_AF__PA0__TCH_TIM2_CH1 D(1, 2) +#define DEF_TIM_AF__PA1__TCH_TIM2_CH2 D(1, 2) +#define DEF_TIM_AF__PA2__TCH_TIM2_CH3 D(1, 2) +#define DEF_TIM_AF__PA3__TCH_TIM2_CH4 D(1, 2) +#define DEF_TIM_AF__PA5__TCH_TIM2_CH1 D(1, 2) +#define DEF_TIM_AF__PA7__TCH_TIM1_CH1N D(1, 1) +#define DEF_TIM_AF__PA8__TCH_TIM1_CH1 D(1, 1) +#define DEF_TIM_AF__PA9__TCH_TIM1_CH2 D(1, 1) +#define DEF_TIM_AF__PA10__TCH_TIM1_CH3 D(1, 1) +#define DEF_TIM_AF__PA11__TCH_TIM1_CH4 D(1, 1) +#define DEF_TIM_AF__PA15__TCH_TIM2_CH1 D(1, 2) + +#define DEF_TIM_AF__PA0__TCH_TIM5_CH1 D(2, 5) +#define DEF_TIM_AF__PA1__TCH_TIM5_CH2 D(2, 5) +#define DEF_TIM_AF__PA2__TCH_TIM5_CH3 D(2, 5) +#define DEF_TIM_AF__PA3__TCH_TIM5_CH4 D(2, 5) +#define DEF_TIM_AF__PA6__TCH_TIM3_CH1 D(2, 3) +#define DEF_TIM_AF__PA7__TCH_TIM3_CH2 D(2, 3) + +#define DEF_TIM_AF__PA5__TCH_TIM8_CH1N D(3, 8) +#define DEF_TIM_AF__PA7__TCH_TIM8_CH1N D(3, 8) + +#define DEF_TIM_AF__PA6__TCH_TIM13_CH1 D(9, 13) +#define DEF_TIM_AF__PA7__TCH_TIM14_CH1 D(9, 14) + +#define DEF_TIM_AF__PA1__TCH_TIM15_CH1N D(4, 15) +#define DEF_TIM_AF__PA2__TCH_TIM15_CH1 D(4, 15) +#define DEF_TIM_AF__PA2__TCH_TIM15_CH2 D(4, 15) + +//PORTB +#define DEF_TIM_AF__PB0__TCH_TIM1_CH2N D(1, 1) +#define DEF_TIM_AF__PB1__TCH_TIM1_CH3N D(1, 1) +#define DEF_TIM_AF__PB3__TCH_TIM2_CH2 D(1, 2) +#define DEF_TIM_AF__PB6__TCH_TIM16_CH1N D(1, 16) +#define DEF_TIM_AF__PB7__TCH_TIM17_CH1N D(1, 17) +#define DEF_TIM_AF__PB8__TCH_TIM16_CH1 D(1, 16) +#define DEF_TIM_AF__PB9__TCH_TIM17_CH1 D(1, 17) +#define DEF_TIM_AF__PB10__TCH_TIM2_CH3 D(1, 2) +#define DEF_TIM_AF__PB11__TCH_TIM2_CH4 D(1, 2) +#define DEF_TIM_AF__PB13__TCH_TIM1_CH1N D(1, 1) +#define DEF_TIM_AF__PB14__TCH_TIM1_CH2N D(1, 1) +#define DEF_TIM_AF__PB15__TCH_TIM1_CH3N D(1, 1) + +#define DEF_TIM_AF__PB0__TCH_TIM3_CH3 D(2, 3) +#define DEF_TIM_AF__PB1__TCH_TIM3_CH4 D(2, 3) +#define DEF_TIM_AF__PB4__TCH_TIM3_CH1 D(2, 3) +#define DEF_TIM_AF__PB5__TCH_TIM3_CH2 D(2, 3) +#define DEF_TIM_AF__PB6__TCH_TIM4_CH1 D(2, 4) +#define DEF_TIM_AF__PB7__TCH_TIM4_CH2 D(2, 4) +#define DEF_TIM_AF__PB8__TCH_TIM4_CH3 D(2, 4) +#define DEF_TIM_AF__PB9__TCH_TIM4_CH4 D(2, 4) + +#define DEF_TIM_AF__PB14__TCH_TIM12_CH1 D(2, 12) +#define DEF_TIM_AF__PB15__TCH_TIM12_CH2 D(2, 12) + +//PORTC +#define DEF_TIM_AF__PC6__TCH_TIM3_CH1 D(2, 3) +#define DEF_TIM_AF__PC7__TCH_TIM3_CH2 D(2, 3) +#define DEF_TIM_AF__PC8__TCH_TIM3_CH3 D(2, 3) +#define DEF_TIM_AF__PC9__TCH_TIM3_CH4 D(2, 3) + +#define DEF_TIM_AF__PC6__TCH_TIM8_CH1 D(3, 8) +#define DEF_TIM_AF__PC7__TCH_TIM8_CH2 D(3, 8) +#define DEF_TIM_AF__PC8__TCH_TIM8_CH3 D(3, 8) +#define DEF_TIM_AF__PC9__TCH_TIM8_CH4 D(3, 8) + +//PORTD +#define DEF_TIM_AF__PD12__TCH_TIM4_CH1 D(2, 4) +#define DEF_TIM_AF__PD13__TCH_TIM4_CH2 D(2, 4) +#define DEF_TIM_AF__PD14__TCH_TIM4_CH3 D(2, 4) +#define DEF_TIM_AF__PD15__TCH_TIM4_CH4 D(2, 4) + +//PORTE +#define DEF_TIM_AF__PE8__TCH_TIM1_CH1N D(1, 1) +#define DEF_TIM_AF__PE9__TCH_TIM1_CH1 D(1, 1) +#define DEF_TIM_AF__PE10__TCH_TIM1_CH2N D(1, 1) +#define DEF_TIM_AF__PE11__TCH_TIM1_CH2 D(1, 1) +#define DEF_TIM_AF__PE12__TCH_TIM1_CH3N D(1, 1) +#define DEF_TIM_AF__PE13__TCH_TIM1_CH3 D(1, 1) +#define DEF_TIM_AF__PE14__TCH_TIM1_CH4 D(1, 1) + +#define DEF_TIM_AF__PE4__TCH_TIM15_CH1N D(4, 15) +#define DEF_TIM_AF__PE5__TCH_TIM15_CH1 D(4, 15) +#define DEF_TIM_AF__PE6__TCH_TIM15_CH2 D(4, 15) + +//PORTF +#define DEF_TIM_AF__PF6__TCH_TIM16_CH1 D(1, 16) +#define DEF_TIM_AF__PF7__TCH_TIM17_CH1 D(1, 17) +#define DEF_TIM_AF__PF8__TCH_TIM16_CH1N D(1, 16) +#define DEF_TIM_AF__PF9__TCH_TIM17_CH1N D(1, 17) + +#define DEF_TIM_AF__PF8__TCH_TIM13_CH1N D(1, 13) +#define DEF_TIM_AF__PF9__TCH_TIM14_CH1N D(1, 14) + +//PORTH +#define DEF_TIM_AF__PH6__TCH_TIM12_CH1 D(2, 12) +#define DEF_TIM_AF__PH9__TCH_TIM12_CH2 D(2, 12) +#define DEF_TIM_AF__PH10__TCH_TIM5_CH1 D(2, 5) +#define DEF_TIM_AF__PH11__TCH_TIM5_CH2 D(2, 5) +#define DEF_TIM_AF__PH12__TCH_TIM5_CH3 D(2, 5) +#define DEF_TIM_AF__PH13__TCH_TIM8_CH1N D(3, 8) +#define DEF_TIM_AF__PH14__TCH_TIM8_CH2N D(3, 8) +#define DEF_TIM_AF__PH15__TCH_TIM8_CH3N D(3, 8) + +//PORTI +#define DEF_TIM_AF__PI0__TCH_TIM5_CH4 D(2, 5) + +#define DEF_TIM_AF__PI2__TCH_TIM8_CH4 D(3, 8) +#define DEF_TIM_AF__PI5__TCH_TIM8_CH1 D(3, 8) +#define DEF_TIM_AF__PI6__TCH_TIM8_CH2 D(3, 8) +#define DEF_TIM_AF__PI7__TCH_TIM8_CH3 D(3, 8) + #endif diff --git a/src/main/drivers/timer_hal.c b/src/main/drivers/timer_hal.c index 24c2403577..ae5aed74b5 100644 --- a/src/main/drivers/timer_hal.c +++ b/src/main/drivers/timer_hal.c @@ -174,6 +174,7 @@ TIM_TypeDef * const usedTimers[USED_TIMER_COUNT] = { #if USED_TIMERS & TIM_N(8) _DEF(8), #endif +#if !defined(STM32H7) #if USED_TIMERS & TIM_N(9) _DEF(9), #endif @@ -183,6 +184,7 @@ TIM_TypeDef * const usedTimers[USED_TIMER_COUNT] = { #if USED_TIMERS & TIM_N(11) _DEF(11), #endif +#endif #if USED_TIMERS & TIM_N(12) _DEF(12), #endif @@ -339,7 +341,11 @@ void configTimeBase(TIM_TypeDef *tim, uint16_t period, uint32_t hz) timerHandle[timerIndex].Handle.Init.RepetitionCounter = 0x0000; HAL_TIM_Base_Init(&timerHandle[timerIndex].Handle); - if (tim == TIM1 || tim == TIM2 || tim == TIM3 || tim == TIM4 || tim == TIM5 || tim == TIM8 || tim == TIM9) { + if (tim == TIM1 || tim == TIM2 || tim == TIM3 || tim == TIM4 || tim == TIM5 || tim == TIM8 +#if !defined(STM32H7) + || tim == TIM9 +#endif + ) { TIM_ClockConfigTypeDef sClockSourceConfig; memset(&sClockSourceConfig, 0, sizeof(sClockSourceConfig)); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; @@ -375,7 +381,13 @@ void timerConfigure(const timerHardware_t *timerHardwarePtr, uint16_t period, ui switch (irq) { case TIM1_CC_IRQn: +#if defined(STM32F7) timerNVICConfigure(TIM1_UP_TIM10_IRQn); +#elif defined(STM32H7) + timerNVICConfigure(TIM1_UP_IRQn); +#else + // Empty +#endif break; case TIM8_CC_IRQn: timerNVICConfigure(TIM8_UP_TIM13_IRQn); @@ -764,10 +776,14 @@ static void timCCxHandler(TIM_TypeDef *tim, timerConfig_t *timerConfig) #if USED_TIMERS & TIM_N(1) _TIM_IRQ_HANDLER(TIM1_CC_IRQHandler, 1); -# if USED_TIMERS & TIM_N(10) -_TIM_IRQ_HANDLER2(TIM1_UP_TIM10_IRQHandler, 1, 10); // both timers are in use +# if defined(STM32H7) +_TIM_IRQ_HANDLER(TIM1_UP_IRQHandler, 1); # else +# if USED_TIMERS & TIM_N(10) +_TIM_IRQ_HANDLER2(TIM1_UP_TIM10_IRQHandler, 1, 10); // both timers are in use +# else _TIM_IRQ_HANDLER(TIM1_UP_TIM10_IRQHandler, 1); // timer10 is not used +# endif # endif #endif @@ -841,6 +857,7 @@ void timerInit(void) #if USED_TIMERS & TIM_N(8) __HAL_RCC_TIM8_CLK_ENABLE(); #endif +#if !defined(STM32H7) #if USED_TIMERS & TIM_N(9) __HAL_RCC_TIM9_CLK_ENABLE(); #endif @@ -850,6 +867,7 @@ void timerInit(void) #if USED_TIMERS & TIM_N(11) __HAL_RCC_TIM11_CLK_ENABLE(); #endif +#endif #if USED_TIMERS & TIM_N(12) __HAL_RCC_TIM12_CLK_ENABLE(); #endif @@ -874,7 +892,7 @@ void timerInit(void) RCC_ClockCmd(timerRCC(TIMER_HARDWARE[i].tim), ENABLE); } -#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) +#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) for (unsigned timerIndex = 0; timerIndex < TIMER_CHANNEL_COUNT; timerIndex++) { const timerHardware_t *timerHardwarePtr = &TIMER_HARDWARE[timerIndex]; if (timerHardwarePtr->usageFlags == TIM_USE_NONE) { diff --git a/src/main/drivers/timer_stm32h7xx.c b/src/main/drivers/timer_stm32h7xx.c new file mode 100644 index 0000000000..a5ad78347f --- /dev/null +++ b/src/main/drivers/timer_stm32h7xx.c @@ -0,0 +1,78 @@ +/* + * This file is part of Cleanflight and Betaflight. + * + * Cleanflight and Betaflight are free software. You can redistribute + * this software and/or modify this software under the terms of the + * GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Cleanflight and Betaflight are distributed in the hope that they + * will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software. + * + * If not, see . + */ + +#include "platform.h" + +#ifdef USE_TIMER + +#include "common/utils.h" + +#include "stm32h7xx.h" +#include "rcc.h" +#include "timer.h" + +const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = { + { .TIMx = TIM1, .rcc = RCC_APB2(TIM1), .inputIrq = TIM1_CC_IRQn}, + { .TIMx = TIM2, .rcc = RCC_APB1L(TIM2), .inputIrq = TIM2_IRQn}, + { .TIMx = TIM3, .rcc = RCC_APB1L(TIM3), .inputIrq = TIM3_IRQn}, + { .TIMx = TIM4, .rcc = RCC_APB1L(TIM4), .inputIrq = TIM4_IRQn}, + { .TIMx = TIM5, .rcc = RCC_APB1L(TIM5), .inputIrq = TIM5_IRQn}, + { .TIMx = TIM6, .rcc = RCC_APB1L(TIM6), .inputIrq = 0}, + { .TIMx = TIM7, .rcc = RCC_APB1L(TIM7), .inputIrq = 0}, + { .TIMx = TIM8, .rcc = RCC_APB2(TIM8), .inputIrq = TIM8_CC_IRQn}, + { .TIMx = TIM12, .rcc = RCC_APB1L(TIM12), .inputIrq = TIM8_BRK_TIM12_IRQn}, + { .TIMx = TIM13, .rcc = RCC_APB1L(TIM13), .inputIrq = TIM8_UP_TIM13_IRQn}, + { .TIMx = TIM14, .rcc = RCC_APB1L(TIM14), .inputIrq = TIM8_TRG_COM_TIM14_IRQn}, + { .TIMx = TIM15, .rcc = RCC_APB2(TIM15), .inputIrq = TIM15_IRQn}, + { .TIMx = TIM16, .rcc = RCC_APB2(TIM16), .inputIrq = TIM16_IRQn}, + { .TIMx = TIM17, .rcc = RCC_APB2(TIM17), .inputIrq = TIM17_IRQn}, +}; + +uint32_t timerClock(TIM_TypeDef *tim) +{ + int timpre; + uint32_t pclk; + uint32_t ppre; + + // Implement the table: + // RM0433 "Table 48. Ratio between clock timer and pclk" + + if (tim == TIM1 || tim == TIM8 || tim == TIM15 || tim == TIM16 || tim == TIM17) { + // Timers on APB2 + pclk = HAL_RCC_GetPCLK2Freq(); + ppre = (RCC->D2CFGR & RCC_D2CFGR_D2PPRE2) >> RCC_D2CFGR_D2PPRE2_Pos; + } else { + // Timers on APB1 + pclk = HAL_RCC_GetPCLK1Freq(); + ppre = (RCC->D2CFGR & RCC_D2CFGR_D2PPRE1) >> RCC_D2CFGR_D2PPRE1_Pos; + } + + timpre = (RCC->CFGR & RCC_CFGR_TIMPRE) ? 1 : 0; + + int index = (timpre << 3) | ppre; + + static uint8_t periphToKernel[16] = { // The mutiplier table + 1, 1, 1, 1, 2, 2, 2, 2, // TIMPRE = 0 + 1, 1, 1, 1, 2, 4, 4, 4 // TIMPRE = 1 + }; + + return pclk * periphToKernel[index]; +} +#endif