]> mj.ucw.cz Git - home-hw.git/blob - protab/timer5-pwm/timer.c
Protab: More PWM
[home-hw.git] / protab / timer5-pwm / timer.c
1 #include <libopencm3/cm3/nvic.h>
2 #include <libopencm3/stm32/rcc.h>
3 #include <libopencm3/stm32/gpio.h>
4 #include <libopencm3/stm32/timer.h>
5
6 int up = 1;
7 int pwm;
8
9 void tim4_isr(void)
10 {
11         if (TIM_SR(TIM4) & TIM_SR_UIF) {
12                 TIM_SR(TIM4) &= ~TIM_SR_UIF;
13                 if (up) {
14                         pwm += 5;
15                         if (pwm == 1000) {
16                                 pwm = 995;
17                                 up = 0;
18                         }
19                 } else {
20                         pwm -= 5;
21                         if (pwm < 0) {
22                                 pwm = 5;
23                                 up = 1;
24                         }
25                 }
26                 timer_set_oc_value(TIM3, TIM_OC3, pwm);
27         }
28 }
29
30 int main(void)
31 {
32         rcc_clock_setup_in_hse_8mhz_out_72mhz();
33         rcc_periph_clock_enable(RCC_GPIOB);
34         rcc_periph_clock_enable(RCC_GPIOC);
35         rcc_periph_clock_enable(RCC_TIM3);
36         rcc_periph_clock_enable(RCC_TIM4);
37         rcc_periph_reset_pulse(RST_TIM3);       // XXX
38         rcc_periph_reset_pulse(RST_TIM4);       // XXX
39
40         // PC13 = BluePill LED
41         gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
42         gpio_set(GPIOC, GPIO13);
43
44         // PB0 = TIM3_CH3
45         gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO0);
46
47         timer_set_prescaler(TIM3, 1);           // 72 MHz / 2 = 36 MHz
48         timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
49         timer_set_period(TIM3, 999);            // 36 MHz / 1000 = 36 kHz
50         timer_update_on_overflow(TIM3);
51
52         timer_set_oc_mode(TIM3, TIM_OC3, TIM_OCM_PWM1);
53         timer_set_oc_value(TIM3, TIM_OC3, 50);
54         timer_set_oc_polarity_high(TIM3, TIM_OC3);
55         timer_enable_oc_output(TIM3, TIM_OC3);
56
57         timer_enable_counter(TIM3);
58
59         timer_set_prescaler(TIM4, 35999);       // 72 MHz / 36000 = 2 kHz
60         timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
61         timer_set_period(TIM4, 2);              // 2 kHz / 2 = 1 kHz
62         timer_update_on_overflow(TIM4);
63         timer_enable_irq(TIM4, TIM_DIER_UIE);
64         nvic_enable_irq(NVIC_TIM4_IRQ);
65         timer_enable_counter(TIM4);
66
67         for (;;) {
68                 asm volatile ("wfi");
69         }
70
71         return 0;
72 }