stm32h743: implement timer API
rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Sat, 11 Jul 2026 17:23:37 -0400
| Newsgroups | gmane.comp.systems.archos.rockbox.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 862370982ca32e6376cd19c4c745e73d59f26b10 Author: Aidan MacDonald <[email protected]> Date: Sat Jul 11 11:38:58 2026 +0100 stm32h743: implement timer API Change-Id: Idcac3ab528e154097fb76fcfda78540ef02494df diff --git a/firmware/SOURCES b/firmware/SOURCES index 20158f8489..58bc753fc4 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1970,6 +1970,7 @@ target/arm/stm32/echoplayer/pcm-echoplayer.c target/arm/stm32/echoplayer/power-echoplayer.c target/arm/stm32/echoplayer/sdmmc-echoplayer.c target/arm/stm32/echoplayer/system-echoplayer.c +target/arm/stm32/echoplayer/timer-echoplayer.c target/arm/stm32/echoplayer/usb-echoplayer.c #endif diff --git a/firmware/export/config/echor1.h b/firmware/export/config/echor1.h index dd8ad30f66..f6c8760db0 100644 --- a/firmware/export/config/echor1.h +++ b/firmware/export/config/echor1.h @@ -15,7 +15,7 @@ #define CPU_FREQ 480000000 #ifndef SIMULATOR -#define TIMER_FREQ STM32_HSE_FREQ +#define TIMER_FREQ (CPU_FREQ / 2) #endif /* Kernel defines */ diff --git a/firmware/reggen/stm32h743.regs b/firmware/reggen/stm32h743.regs index 03292c347c..8134b08f06 100644 --- a/firmware/reggen/stm32h743.regs +++ b/firmware/reggen/stm32h743.regs @@ -1757,3 +1757,283 @@ block ADC { ADC1 @ 0x40022000 : ADC ADC2 @ 0x40022100 : ADC ADC3 @ 0x58026000 : ADC + +block TIM { + CR1 @ 0x00 : reg { + -- 11 UIFREMAP + 09 08 CKD + -- 07 ARPE + 06 05 CMS + -- 04 DIR + -- 03 OPM + -- 02 URS + -- 01 UDIS + -- 00 CEN + } + + CR2 @ 0x04 : reg { + 23 20 MMS2 + -- 18 OIS6 + -- 16 OIS5 + -- 14 OIS4 + -- 13 OIS3N + -- 12 OIS3 + -- 11 OIS2N + -- 10 OIS2 + -- 09 OIS1N + -- 08 OIS1 + -- 07 TI1S + 06 04 MMS + -- 03 CCDS + -- 02 CCUS + -- 00 CCPC + } + + SMCR @ 0x08 : reg { + 21 20 TS_4_3 + -- 16 SMS3 + -- 15 ETP + -- 14 ECE + 13 12 ETPS + 11 08 ETF + -- 07 MSM + 06 04 TS + 02 00 SMS + } + + DIER @ 0x0c : reg { + -- 14 TDE + -- 13 COMDE + -- 12 CC4DE + -- 11 CC3DE + -- 10 CC2DE + -- 09 CC1DE + -- 08 UDE + -- 07 BIE + -- 06 TIE + -- 05 COMIE + -- 04 CC4IE + -- 03 CC3IE + -- 02 CC2IE + -- 01 CC1IE + -- 00 UIE + } + + SR @ 0x10 : reg { + -- 17 CC6IF + -- 16 CC5IF + -- 13 SBIF + -- 12 CC4OF + -- 11 CC3OF + -- 10 CC2OF + -- 09 CC1OF + -- 08 B2IF + -- 07 BIF + -- 06 TIF + -- 05 COMIF + -- 04 CC4IF + -- 03 CC3IF + -- 02 CC2IF + -- 01 CC1IF + -- 00 UIF + } + + EGR @ 0x14 : reg { + -- 08 B2G + -- 07 BG + -- 06 TG + -- 05 COMG + -- 04 CC4G + -- 03 CC3G + -- 02 CC2G + -- 01 CC1G + -- 00 UG + } + + CCMR1 @ 0x18 : reg { + 09 08 CC2S + 01 00 CC1S + } + + CCMR1_IN @ 0x18 : reg { + 15 12 IC2F + 11 10 IC2PSC + 09 08 CC2S + 07 04 IC1F + 03 02 IC1PSC + 01 00 CC1S + } + + CCMR1_OUT @ 0x18 : reg { + -- 24 OC2M3 + -- 16 OC1M3 + -- 15 OC2CE + 14 12 OC2M + -- 11 OC2PE + -- 10 OC2FE + 09 08 CC2S + -- 07 OC1CE + 06 04 OC1M + -- 03 OC1PE + -- 02 OC1FE + 01 00 CC1S + } + + CCMR2 @ 0x1c : reg { + 09 08 CC4S + 01 00 CC3S + } + + CCMR2_IN @ 0x1c : reg { + 15 12 IC4F + 11 10 IC4PSC + 09 08 CC4S + 07 04 IC3F + 03 02 IC3PSC + 01 00 CC3S + } + + CCMR2_OUT @ 0x1c : reg { + -- 24 OC4M3 + -- 16 OC3M3 + -- 15 OC4CE + 14 12 OC4M + -- 11 OC4PE + -- 10 OC4FE + 09 08 CC4S + -- 07 OC3CE + 06 04 OC3M + -- 03 OC3PE + -- 02 OC3FE + 01 00 CC3S + } + + CCER @ 0x20 : reg { + -- 21 CC6P + -- 20 CC6E + -- 17 CC5P + -- 16 CC5E + -- 15 CC4NP + -- 14 CC4NE + -- 13 CC4P + -- 12 CC4E + -- 11 CC3NP + -- 10 CC3NE + -- 09 CC3P + -- 08 CC3E + -- 07 CC2NP + -- 06 CC2NE + -- 05 CC2P + -- 04 CC2E + -- 03 CC1NP + -- 02 CC1NE + -- 01 CC1P + -- 00 CC1E + } + + CNT @ 0x24 : reg { + -- 31 UIFCPY + 15 00 CNT + } + + CNT32 @ 0x24 : reg { + -- 31 UIFCPY + 30 00 CNT + } + + PSC @ 0x28 : reg + ARR @ 0x2c : reg + RCR @ 0x30 : reg + + CCR1 @ 0x34 : reg + CCR2 @ 0x38 : reg + CCR3 @ 0x3c : reg + CCR4 @ 0x40 : reg + + BDTR @ 0x44 : reg { + -- 25 BK2P + -- 24 BK2E + 23 20 BK2F + 19 16 BKF + -- 15 MOE + -- 14 AOE + -- 13 BKP + -- 12 BKE + -- 11 OSSR + -- 10 OSSI + 09 08 LOCK + 07 00 DTG + } + + DCR @ 0x48 : reg { + 12 08 DBL + 04 00 DBA + } + + DMAR @ 0x4c : reg + + CCMR3_OUT @ 0x54 : reg { + -- 24 OC6M3 + -- 16 OC5M3 + -- 15 OC6CE + 14 12 OC6M + -- 11 OC6PE + -- 10 OC6FE + -- 07 OC5CE + 06 04 OC5M + -- 03 OC5PE + -- 02 OC5FE + } + + CCR5 @ 0x58 : reg { + -- 31 GC5C3 + -- 30 GC5C2 + -- 29 GC5C1 + 15 00 CCR5 + } + + CCR6 @ 0x5c : reg + + AF1 @ 0x60 : reg { + 17 14 ETRSEL + -- 11 BKCMP2P + -- 10 BKCMP1P + -- 09 BKINP + -- 08 BKDFxBKxE // differs for TIM1/TIM8 + -- 02 BKCMP2E + -- 01 BKCMP1E + -- 00 BKINE + } + + AF2 @ 0x64 : reg { + -- 11 BK2CMP2P + -- 10 BK2CMP1P + -- 09 BK2INP + -- 08 BK2DFxBKxE // differs for TIM1/TIM8 + -- 02 BK2CMP2E + -- 01 BK2CMP1E + -- 00 BK2INE + } + + TISEL @ 0x68 : reg { + 27 24 TI4SEL + 19 16 TI3SEL + 11 08 TI2SEL + 03 00 TI1SEL + } +} + +TIM17 @ 0x40014800 : TIM +TIM16 @ 0x40014400 : TIM +TIM15 @ 0x40014000 : TIM +TIM8 @ 0x40010400 : TIM +TIM1 @ 0x40010000 : TIM +TIM14 @ 0x40002000 : TIM +TIM13 @ 0x40001c00 : TIM +TIM12 @ 0x40001800 : TIM +TIM7 @ 0x40001400 : TIM +TIM6 @ 0x40001000 : TIM +TIM5 @ 0x40000c00 : TIM +TIM4 @ 0x40000800 : TIM +TIM3 @ 0x40000400 : TIM +TIM2 @ 0x40000000 : TIM diff --git a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c index 59cdc7a2cb..04b469a91d 100644 --- a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c +++ b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.c @@ -211,3 +211,11 @@ const struct stm32_clock i2c1_ker_clock = { .lpen_reg = ITA_RCC_APB1LLPENR, .lpen_bit = BM_RCC_APB1LENR_I2C1EN, }; + +const struct stm32_clock tim7_ker_clock = { + .frequency = TIMER_FREQ, + .en_reg = ITA_RCC_APB1LENR, + .en_bit = BM_RCC_APB1LENR_TIM7EN, + .lpen_reg = ITA_RCC_APB1LLPENR, + .lpen_bit = BM_RCC_APB1LENR_TIM7EN, +}; diff --git a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h index 8af8f57e44..e2d4f0be4a 100644 --- a/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h +++ b/firmware/target/arm/stm32/echoplayer/clock-echoplayer.h @@ -28,5 +28,6 @@ extern const struct stm32_clock sdmmc1_ker_clock; extern const struct stm32_clock ltdc_ker_clock; extern const struct stm32_clock spi5_ker_clock; extern const struct stm32_clock i2c1_ker_clock; +extern const struct stm32_clock tim7_ker_clock; #endif /* __CLOCK_ECHOPLAYER_H__ */ diff --git a/firmware/target/arm/stm32/echoplayer/system-echoplayer.c b/firmware/target/arm/stm32/echoplayer/system-echoplayer.c index 79555f7256..2a5073915c 100644 --- a/firmware/target/arm/stm32/echoplayer/system-echoplayer.c +++ b/firmware/target/arm/stm32/echoplayer/system-echoplayer.c @@ -19,13 +19,16 @@ ****************************************************************************/ #include "system.h" #include "button.h" +#include "nvic-arm.h" #include "gpio-stm32h7.h" +#include "timer-stm32h7.h" #include "clock-echoplayer.h" #include "system-echoplayer.h" #include "regs/stm32h743/fmc.h" #include "regs/stm32h743/pwr.h" #include "regs/stm32h743/rcc.h" #include "regs/stm32h743/rtc.h" +#include "regs/stm32h743/tim.h" #include "regs/cortex-m/cm_scb.h" #ifdef BOOTLOADER @@ -251,6 +254,9 @@ void system_init(void) /* Disable RTC_OUT pin */ echoplayer_set_rtcout_mode(ECHOPLAYER_RTCOUT_DISABLED); + + /* Setup for timer API */ + stm32h7_timer_init(ITA_TIM7, NVIC_IRQN_TIM7, &tim7_ker_clock); } void system_exception_wait(void) diff --git a/firmware/target/arm/stm32/echoplayer/timer-echoplayer.c b/firmware/target/arm/stm32/echoplayer/timer-echoplayer.c new file mode 100644 index 0000000000..845d83e0a6 --- /dev/null +++ b/firmware/target/arm/stm32/echoplayer/timer-echoplayer.c @@ -0,0 +1,25 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2026 Aidan MacDonald + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "timer-stm32h7.h" + +void tim7_irq_handler(void) +{ + stm32h7_timer_irq(); +} diff --git a/firmware/target/arm/stm32/irqhandlers-stm32h743.c b/firmware/target/arm/stm32/irqhandlers-stm32h743.c index c9a2d65d90..b40b1bdf2f 100644 --- a/firmware/target/arm/stm32/irqhandlers-stm32h743.c +++ b/firmware/target/arm/stm32/irqhandlers-stm32h743.c @@ -68,6 +68,22 @@ void spi3_irq_handler(void) ATTR_IRQ_HANDLER; void spi4_irq_handler(void) ATTR_IRQ_HANDLER; void spi5_irq_handler(void) ATTR_IRQ_HANDLER; void spi6_irq_handler(void) ATTR_IRQ_HANDLER; +void tim1_brk_irq_handler(void) ATTR_IRQ_HANDLER; +void tim1_cc_irq_handler(void) ATTR_IRQ_HANDLER; +void tim1_trg_irq_handler(void) ATTR_IRQ_HANDLER; +void tim1_up_irq_handler(void) ATTR_IRQ_HANDLER; +void tim2_irq_handler(void) ATTR_IRQ_HANDLER; +void tim3_irq_handler(void) ATTR_IRQ_HANDLER; +void tim4_irq_handler(void) ATTR_IRQ_HANDLER; +void tim6_dac_irq_handler(void) ATTR_IRQ_HANDLER; +void tim7_irq_handler(void) ATTR_IRQ_HANDLER; +void tim8_brk_tim12_irq_handler(void) ATTR_IRQ_HANDLER; +void tim8_cc_irq_handler(void) ATTR_IRQ_HANDLER; +void tim8_trg_tim14_irq_handler(void) ATTR_IRQ_HANDLER; +void tim8_up_tim13_irq_handler(void) ATTR_IRQ_HANDLER; +void tim15_irq_handler(void) ATTR_IRQ_HANDLER; +void tim16_irq_handler(void) ATTR_IRQ_HANDLER; +void tim17_irq_handler(void) ATTR_IRQ_HANDLER; void exti0_irq_handler(void) ATTR_IRQ_HANDLER; void exti1_irq_handler(void) ATTR_IRQ_HANDLER; void exti2_irq_handler(void) ATTR_IRQ_HANDLER; diff --git a/firmware/target/arm/stm32/timer-stm32h7.c b/firmware/target/arm/stm32/timer-stm32h7.c index 5135d9a384..a5610bf10c 100644 --- a/firmware/target/arm/stm32/timer-stm32h7.c +++ b/firmware/target/arm/stm32/timer-stm32h7.c @@ -18,19 +18,88 @@ * ****************************************************************************/ #include "timer.h" +#include "nvic-arm.h" +#include "clock-stm32h7.h" +#include "regs/stm32h743/rcc.h" +#include "regs/stm32h743/tim.h" + +static uint32_t tim_reg; +static int tim_irq; +static const struct stm32_clock *tim_clk; + +void stm32h7_timer_init(uint32_t instance, + int irq, + const struct stm32_clock *clock) +{ + tim_reg = instance; + tim_irq = irq; + tim_clk = clock; +} + +void stm32h7_timer_irq(void) +{ + reg_assignlf(tim_reg, TIM_SR, UIF(0)); + + if (pfn_timer) + pfn_timer(); +} bool timer_set(long cycles, bool start) { - (void)cycles; - (void)start; - return false; + if (cycles <= 0) + return false; + + /* Calculate timer interval */ + uint32_t counter = cycles; + uint32_t prescaler = 1; + while (counter > 0xFFFF && prescaler < 0x10000) + { + counter >>= 1; + prescaler <<= 1; + } + + /* Duration too long */ + if (counter >= 0xFFFF) + return false; + + /* Unregister old function */ + if (start && pfn_unregister) + { + pfn_unregister(); + pfn_unregister = NULL; + } + + /* Set up timer */ + stm32_clock_enable(tim_clk); + reg_writef(RCC_APB1LENR, TIM7EN(1)); + reg_assignlf(tim_reg, TIM_CR1, URS(1)); + reg_assignlf(tim_reg, TIM_EGR, UG(1)); + reg_assignlf(tim_reg, TIM_DIER, UIE(1)); + reg_assignlf(tim_reg, TIM_SR, UIF(1)); + reg_varl(tim_reg, TIM_CNT) = 0; + reg_varl(tim_reg, TIM_ARR) = counter; + reg_varl(tim_reg, TIM_PSC) = prescaler - 1; + + if (start) + return timer_start(); + + return true; } bool timer_start(void) { - return false; + stm32_clock_enable(tim_clk); + nvic_enable_irq(tim_irq); + + reg_writef(RCC_APB1LENR, TIM7EN(1)); + reg_writelf(tim_reg, TIM_CR1, URS(0), CEN(1)); + return true; } void timer_stop(void) { + nvic_disable_irq(tim_irq); + + reg_writelf(tim_reg, TIM_CR1, CEN(0)); + stm32_clock_disable(tim_clk); } diff --git a/firmware/target/arm/stm32/timer-stm32h7.h b/firmware/target/arm/stm32/timer-stm32h7.h new file mode 100644 index 0000000000..4b7527b73c --- /dev/null +++ b/firmware/target/arm/stm32/timer-stm32h7.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2026 Aidan MacDonald + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __TIMER_STM32H7_H__ +#define __TIMER_STM32H7_H__ + +#include <stdint.h> + +struct stm32_clock; + +void stm32h7_timer_init(uint32_t instance, int irq, + const struct stm32_clock *clock); +void stm32h7_timer_irq(void); + +#endif /* __TIMER_STM32H7_H__ */ diff --git a/firmware/target/arm/stm32/vectors-stm32h7.S b/firmware/target/arm/stm32/vectors-stm32h7.S index d283d808ad..9ee0b153f6 100644 --- a/firmware/target/arm/stm32/vectors-stm32h7.S +++ b/firmware/target/arm/stm32/vectors-stm32h7.S @@ -50,13 +50,13 @@ __vectors_platform: .word UIE /* [ 21] */ .word UIE /* [ 22] */ .word exti9_5_irq_handler /* [ 23] EXTI5 to EXTI9 */ - .word UIE /* [ 24] */ - .word UIE /* [ 25] */ - .word UIE /* [ 26] */ - .word UIE /* [ 27] */ - .word UIE /* [ 28] */ - .word UIE /* [ 29] */ - .word UIE /* [ 30] */ + .word tim1_brk_irq_handler /* [ 24] TIM1_BRK */ + .word tim1_up_irq_handler /* [ 25] TIM1_UP */ + .word tim1_trg_irq_handler /* [ 26] TIM1_TRG_COM */ + .word tim1_cc_irq_handler /* [ 27] TIM1_CC */ + .word tim2_irq_handler /* [ 28] TIM2 */ + .word tim3_irq_handler /* [ 29] TIM3 */ + .word tim4_irq_handler /* [ 30] TIM4 */ .word i2c1_irq_handler /* [ 31] I2C1 event */ .word i2c1_irq_handler /* [ 32] I2C1 error */ .word i2c2_irq_handler /* [ 33] I2C2 event */ @@ -69,10 +69,10 @@ __vectors_platform: .word exti15_10_irq_handler /* [ 40] EXTI10 to EXTI15 */ .word UIE /* [ 41] */ .word UIE /* [ 42] */ - .word UIE /* [ 43] */ - .word UIE /* [ 44] */ - .word UIE /* [ 45] */ - .word UIE /* [ 46] */ + .word tim8_brk_tim12_irq_handler /* [ 43] TIM8_BRK / TIM12 */ + .word tim8_up_tim13_irq_handler /* [ 44] TIM8_UP / TIM13 */ + .word tim8_trg_tim14_irq_handler /* [ 45] TIM8_TRG_COM / TIM14 */ + .word tim8_cc_irq_handler /* [ 46] TIM8_CC */ .word dma1_ch7_irq_handler /* [ 47] DMA1 Stream7 */ .word UIE /* [ 48] */ .word sdmmc1_irq_handler /* [ 49] SDMMC1 */ @@ -80,8 +80,8 @@ __vectors_platform: .word spi3_irq_handler /* [ 51] SPI3 */ .word UIE /* [ 52] */ .word UIE /* [ 53] */ - .word UIE /* [ 54] */ - .word UIE /* [ 55] */ + .word tim6_dac_irq_handler /* [ 54] TIM6 / DAC */ + .word tim7_irq_handler /* [ 55] TIM7 */ .word dma2_ch0_irq_handler /* [ 56] DMA2 Stream0 */ .word dma2_ch1_irq_handler /* [ 57] DMA2 Stream1 */ .word dma2_ch2_irq_handler /* [ 58] DMA2 Stream2 */ @@ -142,9 +142,9 @@ __vectors_platform: .word UIE /* [113] */ .word sai3_irq_handler /* [114] SAI3 */ .word UIE /* [115] */ - .word UIE /* [116] */ - .word UIE /* [117] */ - .word UIE /* [118] */ + .word tim15_irq_handler /* [116] TIM15 */ + .word tim16_irq_handler /* [117] TIM16 */ + .word tim17_irq_handler /* [118] TIM17 */ .word UIE /* [119] */ .word UIE /* [120] */ .word UIE /* [121] */ -- rockbox-cvs mailing list [email protected] https://lists.haxx.se/mailman/listinfo/rockbox-cvs