altos/stm32f1: Add ao_fast_timer.c
authorKeith Packard <keithp@keithp.com>
Mon, 8 Jan 2024 00:20:18 +0000 (16:20 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 1 Feb 2024 01:50:19 +0000 (17:50 -0800)
Needed for TeleLCO

Signed-off-by: Keith Packard <keithp@keithp.com>
src/stm32f1/ao_fast_timer.c [new file with mode: 0644]
src/stm32f1/stm32f1.h

diff --git a/src/stm32f1/ao_fast_timer.c b/src/stm32f1/ao_fast_timer.c
new file mode 100644 (file)
index 0000000..bfbc286
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright © 2024 Keith Packard <keithp@keithp.com>
+ *
+ * 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 program is distributed in the hope that it 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 program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <ao.h>
+#include <ao_fast_timer.h>
+
+static void (*ao_fast_timer_callback[AO_FAST_TIMER_MAX])(void);
+static uint8_t ao_fast_timer_count;
+static uint8_t ao_fast_timer_users;
+
+static void
+ao_fast_timer_enable(void)
+{
+       stm_tim1.cr1 = ((0 << STM_TIM18_CR1_CKD) |
+                       (0 << STM_TIM18_CR1_ARPE) |
+                       (0 << STM_TIM18_CR1_CMS) |
+                       (0 << STM_TIM18_CR1_DIR) |
+                       (0 << STM_TIM18_CR1_OPM) |
+                       (1 << STM_TIM18_CR1_URS) |
+                       (0 << STM_TIM18_CR1_UDIS) |
+                       (1 << STM_TIM18_CR1_CEN));
+}
+
+static void
+ao_fast_timer_disable(void)
+{
+       stm_tim1.cr1 = ((0 << STM_TIM18_CR1_CKD) |
+                       (0 << STM_TIM18_CR1_ARPE) |
+                       (0 << STM_TIM18_CR1_CMS) |
+                       (0 << STM_TIM18_CR1_DIR) |
+                       (0 << STM_TIM18_CR1_OPM) |
+                       (1 << STM_TIM18_CR1_URS) |
+                       (0 << STM_TIM18_CR1_UDIS) |
+                       (0 << STM_TIM18_CR1_CEN));
+}
+
+void
+ao_fast_timer_on(void (*callback)(void))
+{
+       ao_fast_timer_callback[ao_fast_timer_count] = callback;
+       if (!ao_fast_timer_count++)
+               ao_fast_timer_enable();
+}
+
+void
+ao_fast_timer_off(void (*callback)(void))
+{
+       uint8_t n;
+
+       for (n = 0; n < ao_fast_timer_count; n++)
+               if (ao_fast_timer_callback[n] == callback) {
+                       for (; n < ao_fast_timer_count-1; n++) {
+                               ao_fast_timer_callback[n] = ao_fast_timer_callback[n+1];
+                       }
+                       if (!--ao_fast_timer_count)
+                               ao_fast_timer_disable();
+                       break;
+               }
+}
+
+void stm_tim1_up_isr(void)
+{
+       uint8_t i;
+       if (stm_tim1.sr & (1 << STM_TIM18_SR_UIF)) {
+               stm_tim1.sr = 0;
+
+               for (i = 0; i < ao_fast_timer_count; i++)
+                       (*ao_fast_timer_callback[i])();
+       }
+}
+
+/*
+ * According to the STM clock-configuration, timers run
+ * twice as fast as the APB2 clock *if* the APB2 prescaler
+ * is greater than 1.
+ */
+
+#if AO_APB1_PRESCALER > 1
+#define TIMER_18_SCALER 2
+#else
+#define TIMER_18_SCALER 1
+#endif
+
+#ifndef FAST_TIMER_FREQ
+#define FAST_TIMER_FREQ        10000
+#endif
+
+#define TIMER_FAST     ((AO_PCLK2 * TIMER_18_SCALER) / FAST_TIMER_FREQ)
+
+void
+ao_fast_timer_init(void)
+{
+       if (!ao_fast_timer_users) {
+               stm_nvic_set_enable(STM_ISR_TIM1_UP_POS);
+               stm_nvic_set_priority(STM_ISR_TIM1_UP_POS, AO_STM_NVIC_CLOCK_PRIORITY);
+
+               /* Turn on timer 1 */
+               stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_TIM1EN);
+
+               stm_tim1.psc = TIMER_FAST;
+               stm_tim1.arr = 9;
+               stm_tim1.cnt = 0;
+
+               /* Enable update interrupt */
+               stm_tim1.dier = (1 << STM_TIM18_DIER_UIE);
+
+               /* Poke timer to reload values */
+               stm_tim1.egr |= (1 << STM_TIM18_EGR_UG);
+
+               stm_tim1.cr2 = (STM_TIM18_CR2_MMS_RESET << STM_TIM18_CR2_MMS);
+               ao_fast_timer_disable();
+       }
+       if (ao_fast_timer_users == AO_FAST_TIMER_MAX)
+               ao_panic(AO_PANIC_FAST_TIMER);
+       ao_fast_timer_users++;
+}
+
index a5b579a0e54c6fbe6cdcad6a01195b1316718b15..9d59ebe53069e71edcf67feedbf880752736214c 100644 (file)
@@ -1204,6 +1204,297 @@ stm_exticr_set(struct stm_gpio *gpio, int pin) {
        stm_afio.exticr[reg] = (stm_afio.exticr[reg] & (uint32_t) ~(0xf << shift)) | val << shift;
 }
 
+struct stm_tim18 {
+       vuint32_t       cr1;
+       vuint32_t       cr2;
+       vuint32_t       smcr;
+       vuint32_t       dier;
+
+       vuint32_t       sr;
+       vuint32_t       egr;
+       vuint32_t       ccmr1;
+       vuint32_t       ccmr2;
+
+       vuint32_t       ccer;
+       vuint32_t       cnt;
+       vuint32_t       psc;
+       vuint32_t       arr;
+
+       vuint32_t       rcr;
+       vuint32_t       ccr1;
+       vuint32_t       ccr2;
+       vuint32_t       ccr3;
+
+       vuint32_t       ccr4;
+       uint32_t        bdtr;
+       vuint32_t       dcr;
+       vuint32_t       dmar;
+};
+
+extern struct stm_tim18 stm_tim1, stm_tim8;
+
+#define stm_tim1       (*((struct stm_tim18 *) 0x40012c00))
+#define stm_tim8       (*((struct stm_tim18 *) 0x40013400))
+
+#define STM_TIM18_CR1_CKD      8
+#define  STM_TIM18_CR1_CKD_1           0
+#define  STM_TIM18_CR1_CKD_2           1
+#define  STM_TIM18_CR1_CKD_4           2
+#define  STM_TIM18_CR1_CKD_MASK        3UL
+#define STM_TIM18_CR1_ARPE     7
+#define STM_TIM18_CR1_CMS      5
+#define  STM_TIM18_CR1_CMS_EDGE        0
+#define  STM_TIM18_CR1_CMS_CENTER_1    1
+#define  STM_TIM18_CR1_CMS_CENTER_2    2
+#define  STM_TIM18_CR1_CMS_CENTER_3    3
+#define  STM_TIM18_CR1_CMS_MASK        3UL
+#define STM_TIM18_CR1_DIR      4
+#define  STM_TIM18_CR1_DIR_UP          0
+#define  STM_TIM18_CR1_DIR_DOWN        1
+#define STM_TIM18_CR1_OPM      3
+#define STM_TIM18_CR1_URS      2
+#define STM_TIM18_CR1_UDIS     1
+#define STM_TIM18_CR1_CEN      0
+
+#define STM_TIM18_CR2_TI1S     7
+#define STM_TIM18_CR2_MMS      4
+#define  STM_TIM18_CR2_MMS_RESET               0
+#define  STM_TIM18_CR2_MMS_ENABLE              1
+#define  STM_TIM18_CR2_MMS_UPDATE              2
+#define  STM_TIM18_CR2_MMS_COMPARE_PULSE       3
+#define  STM_TIM18_CR2_MMS_COMPARE_OC1REF      4
+#define  STM_TIM18_CR2_MMS_COMPARE_OC2REF      5
+#define  STM_TIM18_CR2_MMS_COMPARE_OC3REF      6
+#define  STM_TIM18_CR2_MMS_COMPARE_OC4REF      7
+#define  STM_TIM18_CR2_MMS_MASK                7UL
+#define STM_TIM18_CR2_CCDS     3
+
+#define STM_TIM18_SMCR_ETP     15
+#define STM_TIM18_SMCR_ECE     14
+#define STM_TIM18_SMCR_ETPS    12
+#define  STM_TIM18_SMCR_ETPS_OFF               0
+#define  STM_TIM18_SMCR_ETPS_DIV_2             1
+#define  STM_TIM18_SMCR_ETPS_DIV_4             2
+#define  STM_TIM18_SMCR_ETPS_DIV_8             3
+#define  STM_TIM18_SMCR_ETPS_MASK              3UL
+#define STM_TIM18_SMCR_ETF     8
+#define  STM_TIM18_SMCR_ETF_NONE               0
+#define  STM_TIM18_SMCR_ETF_INT_N_2            1
+#define  STM_TIM18_SMCR_ETF_INT_N_4            2
+#define  STM_TIM18_SMCR_ETF_INT_N_8            3
+#define  STM_TIM18_SMCR_ETF_DTS_2_N_6          4
+#define  STM_TIM18_SMCR_ETF_DTS_2_N_8          5
+#define  STM_TIM18_SMCR_ETF_DTS_4_N_6          6
+#define  STM_TIM18_SMCR_ETF_DTS_4_N_8          7
+#define  STM_TIM18_SMCR_ETF_DTS_8_N_6          8
+#define  STM_TIM18_SMCR_ETF_DTS_8_N_8          9
+#define  STM_TIM18_SMCR_ETF_DTS_16_N_5         10
+#define  STM_TIM18_SMCR_ETF_DTS_16_N_6         11
+#define  STM_TIM18_SMCR_ETF_DTS_16_N_8         12
+#define  STM_TIM18_SMCR_ETF_DTS_32_N_5         13
+#define  STM_TIM18_SMCR_ETF_DTS_32_N_6         14
+#define  STM_TIM18_SMCR_ETF_DTS_32_N_8         15
+#define  STM_TIM18_SMCR_ETF_MASK               15UL
+#define STM_TIM18_SMCR_MSM     7
+#define STM_TIM18_SMCR_TS      4
+#define  STM_TIM18_SMCR_TS_ITR0                0
+#define  STM_TIM18_SMCR_TS_ITR1                1
+#define  STM_TIM18_SMCR_TS_ITR2                2
+#define  STM_TIM18_SMCR_TS_ITR3                3
+#define  STM_TIM18_SMCR_TS_TI1F_ED             4
+#define  STM_TIM18_SMCR_TS_TI1FP1              5
+#define  STM_TIM18_SMCR_TS_TI2FP2              6
+#define  STM_TIM18_SMCR_TS_ETRF                7
+#define  STM_TIM18_SMCR_TS_MASK                7UL
+#define STM_TIM18_SMCR_SMS     0
+#define  STM_TIM18_SMCR_SMS_DISABLE            0
+#define  STM_TIM18_SMCR_SMS_ENCODER_MODE_1     1
+#define  STM_TIM18_SMCR_SMS_ENCODER_MODE_2     2
+#define  STM_TIM18_SMCR_SMS_ENCODER_MODE_3     3
+#define  STM_TIM18_SMCR_SMS_RESET_MODE         4
+#define  STM_TIM18_SMCR_SMS_GATED_MODE         5
+#define  STM_TIM18_SMCR_SMS_TRIGGER_MODE       6
+#define  STM_TIM18_SMCR_SMS_EXTERNAL_CLOCK     7
+#define  STM_TIM18_SMCR_SMS_MASK               7UL
+
+#define STM_TIM18_DIER_TDE             14
+#define STM_TIM18_DIER_CC4DE           12
+#define STM_TIM18_DIER_CC3DE           11
+#define STM_TIM18_DIER_CC2DE           10
+#define STM_TIM18_DIER_CC1DE           9
+#define STM_TIM18_DIER_UDE             8
+
+#define STM_TIM18_DIER_TIE             6
+#define STM_TIM18_DIER_CC4IE           4
+#define STM_TIM18_DIER_CC3IE           3
+#define STM_TIM18_DIER_CC2IE           2
+#define STM_TIM18_DIER_CC1IE           1
+#define STM_TIM18_DIER_UIE             0
+
+#define STM_TIM18_SR_CC4OF     12
+#define STM_TIM18_SR_CC3OF     11
+#define STM_TIM18_SR_CC2OF     10
+#define STM_TIM18_SR_CC1OF     9
+#define STM_TIM18_SR_TIF       6
+#define STM_TIM18_SR_CC4IF     4
+#define STM_TIM18_SR_CC3IF     3
+#define STM_TIM18_SR_CC2IF     2
+#define STM_TIM18_SR_CC1IF     1
+#define STM_TIM18_SR_UIF       0
+
+#define STM_TIM18_EGR_TG       6
+#define STM_TIM18_EGR_CC4G     4
+#define STM_TIM18_EGR_CC3G     3
+#define STM_TIM18_EGR_CC2G     2
+#define STM_TIM18_EGR_CC1G     1
+#define STM_TIM18_EGR_UG       0
+
+#define STM_TIM18_CCMR1_OC2CE  15
+#define STM_TIM18_CCMR1_OC2M   12
+#define  STM_TIM18_CCMR1_OC2M_FROZEN                   0
+#define  STM_TIM18_CCMR1_OC2M_SET_HIGH_ON_MATCH        1
+#define  STM_TIM18_CCMR1_OC2M_SET_LOW_ON_MATCH         2
+#define  STM_TIM18_CCMR1_OC2M_TOGGLE                   3
+#define  STM_TIM18_CCMR1_OC2M_FORCE_LOW                4
+#define  STM_TIM18_CCMR1_OC2M_FORCE_HIGH               5
+#define  STM_TIM18_CCMR1_OC2M_PWM_MODE_1               6
+#define  STM_TIM18_CCMR1_OC2M_PWM_MODE_2               7
+#define  STM_TIM18_CCMR1_OC2M_MASK                     7UL
+#define STM_TIM18_CCMR1_OC2PE  11
+#define STM_TIM18_CCMR1_OC2FE  10
+#define STM_TIM18_CCMR1_CC2S   8
+#define  STM_TIM18_CCMR1_CC2S_OUTPUT                   0
+#define  STM_TIM18_CCMR1_CC2S_INPUT_TI2                1
+#define  STM_TIM18_CCMR1_CC2S_INPUT_TI1                2
+#define  STM_TIM18_CCMR1_CC2S_INPUT_TRC                3
+#define  STM_TIM18_CCMR1_CC2S_MASK                     3UL
+
+#define STM_TIM18_CCMR1_OC1CE  7
+#define STM_TIM18_CCMR1_OC1M   4
+#define  STM_TIM18_CCMR1_OC1M_FROZEN                   0
+#define  STM_TIM18_CCMR1_OC1M_SET_HIGH_ON_MATCH        1
+#define  STM_TIM18_CCMR1_OC1M_SET_LOW_ON_MATCH         2
+#define  STM_TIM18_CCMR1_OC1M_TOGGLE                   3
+#define  STM_TIM18_CCMR1_OC1M_FORCE_LOW                4
+#define  STM_TIM18_CCMR1_OC1M_FORCE_HIGH               5
+#define  STM_TIM18_CCMR1_OC1M_PWM_MODE_1               6
+#define  STM_TIM18_CCMR1_OC1M_PWM_MODE_2               7
+#define  STM_TIM18_CCMR1_OC1M_MASK                     7UL
+#define STM_TIM18_CCMR1_OC1PE  3
+#define STM_TIM18_CCMR1_OC1FE  2
+#define STM_TIM18_CCMR1_CC1S   0
+#define  STM_TIM18_CCMR1_CC1S_OUTPUT                   0
+#define  STM_TIM18_CCMR1_CC1S_INPUT_TI1                1
+#define  STM_TIM18_CCMR1_CC1S_INPUT_TI2                2
+#define  STM_TIM18_CCMR1_CC1S_INPUT_TRC                3
+#define  STM_TIM18_CCMR1_CC1S_MASK                     3UL
+
+#define STM_TIM18_CCMR1_IC2F   12
+#define  STM_TIM18_CCMR1_IC2F_NONE                     0
+#define  STM_TIM18_CCMR1_IC2F_CK_INT_N_2               1
+#define  STM_TIM18_CCMR1_IC2F_CK_INT_N_4               2
+#define  STM_TIM18_CCMR1_IC2F_CK_INT_N_8               3
+#define  STM_TIM18_CCMR1_IC2F_DTS_2_N_6                4
+#define  STM_TIM18_CCMR1_IC2F_DTS_2_N_8                5
+#define  STM_TIM18_CCMR1_IC2F_DTS_4_N_6                6
+#define  STM_TIM18_CCMR1_IC2F_DTS_4_N_8                7
+#define  STM_TIM18_CCMR1_IC2F_DTS_8_N_6                8
+#define  STM_TIM18_CCMR1_IC2F_DTS_8_N_8                9
+#define  STM_TIM18_CCMR1_IC2F_DTS_16_N_5               10
+#define  STM_TIM18_CCMR1_IC2F_DTS_16_N_6               11
+#define  STM_TIM18_CCMR1_IC2F_DTS_16_N_8               12
+#define  STM_TIM18_CCMR1_IC2F_DTS_32_N_5               13
+#define  STM_TIM18_CCMR1_IC2F_DTS_32_N_6               14
+#define  STM_TIM18_CCMR1_IC2F_DTS_32_N_8               15
+#define STM_TIM18_CCMR1_IC2PSC 10
+#define  STM_TIM18_CCMR1_IC2PSC_NONE                   0
+#define  STM_TIM18_CCMR1_IC2PSC_2                      1
+#define  STM_TIM18_CCMR1_IC2PSC_4                      2
+#define  STM_TIM18_CCMR1_IC2PSC_8                      3
+#define STM_TIM18_CCMR1_IC1F   4
+#define  STM_TIM18_CCMR1_IC1F_NONE                     0
+#define  STM_TIM18_CCMR1_IC1F_CK_INT_N_2               1
+#define  STM_TIM18_CCMR1_IC1F_CK_INT_N_4               2
+#define  STM_TIM18_CCMR1_IC1F_CK_INT_N_8               3
+#define  STM_TIM18_CCMR1_IC1F_DTS_2_N_6                4
+#define  STM_TIM18_CCMR1_IC1F_DTS_2_N_8                5
+#define  STM_TIM18_CCMR1_IC1F_DTS_4_N_6                6
+#define  STM_TIM18_CCMR1_IC1F_DTS_4_N_8                7
+#define  STM_TIM18_CCMR1_IC1F_DTS_8_N_6                8
+#define  STM_TIM18_CCMR1_IC1F_DTS_8_N_8                9
+#define  STM_TIM18_CCMR1_IC1F_DTS_16_N_5               10
+#define  STM_TIM18_CCMR1_IC1F_DTS_16_N_6               11
+#define  STM_TIM18_CCMR1_IC1F_DTS_16_N_8               12
+#define  STM_TIM18_CCMR1_IC1F_DTS_32_N_5               13
+#define  STM_TIM18_CCMR1_IC1F_DTS_32_N_6               14
+#define  STM_TIM18_CCMR1_IC1F_DTS_32_N_8               15
+#define STM_TIM18_CCMR1_IC1PSC 2
+#define  STM_TIM18_CCMR1_IC1PSC_NONE                   0
+#define  STM_TIM18_CCMR1_IC1PSC_2                      1
+#define  STM_TIM18_CCMR1_IC1PSC_4                      2
+#define  STM_TIM18_CCMR1_IC1PSC_8                      3
+
+#define STM_TIM18_CCMR2_OC4CE  15
+#define STM_TIM18_CCMR2_OC4M   12
+#define  STM_TIM18_CCMR2_OC4M_FROZEN                   0
+#define  STM_TIM18_CCMR2_OC4M_SET_HIGH_ON_MATCH        1
+#define  STM_TIM18_CCMR2_OC4M_SET_LOW_ON_MATCH         2
+#define  STM_TIM18_CCMR2_OC4M_TOGGLE                   3
+#define  STM_TIM18_CCMR2_OC4M_FORCE_LOW                4
+#define  STM_TIM18_CCMR2_OC4M_FORCE_HIGH               5
+#define  STM_TIM18_CCMR2_OC4M_PWM_MODE_1               6
+#define  STM_TIM18_CCMR2_OC4M_PWM_MODE_2               7
+#define  STM_TIM18_CCMR2_OC4M_MASK                     7UL
+#define STM_TIM18_CCMR2_OC4PE  11
+#define STM_TIM18_CCMR2_OC4FE  10
+#define STM_TIM18_CCMR2_CC4S   8
+#define  STM_TIM18_CCMR2_CC4S_OUTPUT                   0
+#define  STM_TIM18_CCMR2_CC4S_INPUT_TI4                1
+#define  STM_TIM18_CCMR2_CC4S_INPUT_TI3                2
+#define  STM_TIM18_CCMR2_CC4S_INPUT_TRC                3
+#define  STM_TIM18_CCMR2_CC4S_MASK                     3UL
+
+#define STM_TIM18_CCMR2_OC3CE  7
+#define STM_TIM18_CCMR2_OC3M   4
+#define  STM_TIM18_CCMR2_OC3M_FROZEN                   0
+#define  STM_TIM18_CCMR2_OC3M_SET_HIGH_ON_MATCH        1
+#define  STM_TIM18_CCMR2_OC3M_SET_LOW_ON_MATCH         2
+#define  STM_TIM18_CCMR2_OC3M_TOGGLE                   3
+#define  STM_TIM18_CCMR2_OC3M_FORCE_LOW                4
+#define  STM_TIM18_CCMR2_OC3M_FORCE_HIGH               5
+#define  STM_TIM18_CCMR2_OC3M_PWM_MODE_1               6
+#define  STM_TIM18_CCMR2_OC3M_PWM_MODE_2               7
+#define  STM_TIM18_CCMR2_OC3M_MASK                     7UL
+#define STM_TIM18_CCMR2_OC3PE  3
+#define STM_TIM18_CCMR2_OC3FE  2
+#define STM_TIM18_CCMR2_CC3S   0
+#define  STM_TIM18_CCMR2_CC3S_OUTPUT                   0
+#define  STM_TIM18_CCMR2_CC3S_INPUT_TI3                1
+#define  STM_TIM18_CCMR2_CC3S_INPUT_TI4                2
+#define  STM_TIM18_CCMR2_CC3S_INPUT_TRC                3
+#define  STM_TIM18_CCMR2_CC3S_MASK                     3UL
+
+#define STM_TIM18_CCER_CC4NP   15
+#define STM_TIM18_CCER_CC4P    13
+#define  STM_TIM18_CCER_CC4P_ACTIVE_HIGH       0
+#define  STM_TIM18_CCER_CC4P_ACTIVE_LOW        1
+#define STM_TIM18_CCER_CC4E    12
+#define STM_TIM18_CCER_CC3NP   11
+#define STM_TIM18_CCER_CC3P    9
+#define  STM_TIM18_CCER_CC3P_ACTIVE_HIGH       0
+#define  STM_TIM18_CCER_CC3P_ACTIVE_LOW        1
+#define STM_TIM18_CCER_CC3E    8
+#define STM_TIM18_CCER_CC2NP   7
+#define STM_TIM18_CCER_CC2P    5
+#define  STM_TIM18_CCER_CC2P_ACTIVE_HIGH       0
+#define  STM_TIM18_CCER_CC2P_ACTIVE_LOW        1
+#define STM_TIM18_CCER_CC2E    4
+#define STM_TIM18_CCER_CC1NP   3
+#define STM_TIM18_CCER_CC1P    1
+#define  STM_TIM18_CCER_CC1P_ACTIVE_HIGH       0
+#define  STM_TIM18_CCER_CC1P_ACTIVE_LOW        1
+#define STM_TIM18_CCER_CC1E    0
+
 struct stm_tim234 {
        vuint32_t       cr1;
        vuint32_t       cr2;
@@ -1496,6 +1787,44 @@ extern struct stm_tim234 stm_tim2, stm_tim3, stm_tim4;
 #define  STM_TIM234_CCER_CC1P_ACTIVE_LOW       1
 #define STM_TIM234_CCER_CC1E   0
 
+struct stm_tim67 {
+       vuint32_t       cr1;
+       vuint32_t       cr2;
+       uint32_t        _unused_08;
+       vuint32_t       dier;
+
+       vuint32_t       sr;
+       vuint32_t       egr;
+       uint32_t        _unused_18;
+       uint32_t        _unused_1c;
+
+       uint32_t        _unused_20;
+       vuint32_t       cnt;
+       vuint32_t       psc;
+       vuint32_t       arr;
+};
+
+extern struct stm_tim67 stm_tim6;
+
+#define STM_TIM67_CR1_ARPE     (7)
+#define STM_TIM67_CR1_OPM      (3)
+#define STM_TIM67_CR1_URS      (2)
+#define STM_TIM67_CR1_UDIS     (1)
+#define STM_TIM67_CR1_CEN      (0)
+
+#define STM_TIM67_CR2_MMS      (4)
+#define  STM_TIM67_CR2_MMS_RESET       0
+#define  STM_TIM67_CR2_MMS_ENABLE      1
+#define  STM_TIM67_CR2_MMS_UPDATE      2
+#define  STM_TIM67_CR2_MMS_MASK                7UL
+
+#define STM_TIM67_DIER_UDE     (8)
+#define STM_TIM67_DIER_UIE     (0)
+
+#define STM_TIM67_SR_UIF       (0)
+
+#define STM_TIM67_EGR_UG       (0)
+
 #define isr_decl(name) void stm_ ## name ## _isr(void)
 
 isr_decl(halt);