stm32h743: implement timer API

Change-Id: Idcac3ab528e154097fb76fcfda78540ef02494df
This commit is contained in:
Aidan MacDonald 2026-07-11 11:38:58 +01:00 • committed by Solomon Peachy
parent c187b4c674
commit 862370982c
11 changed files with 458 additions and 21 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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,
};

View file

@ -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__ */

View file

@ -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)

View file

@ -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();
}

View file

@ -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;

View file

@ -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;
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);
}

View file

@ -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__ */

View file

@ -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] */