diff options
Diffstat (limited to 'firmware/main.c')
-rw-r--r-- | firmware/main.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/firmware/main.c b/firmware/main.c new file mode 100644 index 0000000..8e39278 --- /dev/null +++ b/firmware/main.c @@ -0,0 +1,143 @@ +// vim: shiftwidth=4 tabstop=4 noexpandtab + + +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/timer.h> +#include <libopencm3/cm3/nvic.h> + + +static void clock_init(void); +static void gpio_init(void); +static void nvic_init(void); +static void timer_init(void); + +void tim2_isr(void); + + +void main(void) +{ + clock_init(); + gpio_init(); + gpio_clear(GPIOC, GPIO13); // set onboard LED on + nvic_init(); + timer_init(); + + while(1); // wait forever +} + + +static void clock_init(void) +{ + // set sysclk to 72 MHz via external 8 MHz crystal + rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); + + // enable clocks for GPIO ports B and C + rcc_periph_clock_enable(RCC_GPIOB); + rcc_periph_clock_enable(RCC_GPIOC); + + // enable clock for timer 2 (blinking) + rcc_periph_clock_enable(RCC_TIM2); + + // enable clock for timer 3 (PWM) + rcc_periph_clock_enable(RCC_TIM3); + + // enable clock for alternate functions + rcc_periph_clock_enable(RCC_AFIO); // TODO is this necessary? +} + + +static void gpio_init(void) +{ + // init PC13 onboard LED for blinking + gpio_set_mode( + GPIOC, + GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, + GPIO13 + ); + + // setup PB0 (connected to TIM3_CH3) for PWM + gpio_set_mode( + GPIOB, + GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, + GPIO_TIM3_CH3 + ); +} + + +static void nvic_init(void) +{ + // enable timer 2 interrupt and set priority + nvic_enable_irq(NVIC_TIM2_IRQ); + nvic_set_priority(NVIC_TIM2_IRQ, 1); +} + + +static void timer_init(void) +{ + // setup timer 2 for blinking + timer_set_counter(TIM2, 1); + timer_set_prescaler(TIM2, 1440); + timer_set_period(TIM2, 50); + + // enable timer / counter 2 and the corresponding interrupt for blinking + timer_enable_irq(TIM2, TIM_DIER_UIE); + timer_enable_counter(TIM2); + + /* + enable timer / counter 3 + */ + + /* Clock division and mode */ + TIM3_CR1 = TIM_CR1_CKD_CK_INT | TIM_CR1_CMS_EDGE; + /* Period */ + TIM3_ARR = 65535; + /* Prescaler */ + TIM3_PSC = 0; + TIM3_EGR = TIM_EGR_UG; + + /* ---- */ + /* Output compare 3 mode and preload */ + TIM3_CCMR2 |= TIM_CCMR2_OC3M_PWM1 | TIM_CCMR2_OC3PE; + + /* Polarity and state */ + TIM3_CCER |= TIM_CCER_CC3P | TIM_CCER_CC3E; + //TIM3_CCER |= TIM_CCER_CC3E; + + /* Capture compare value */ + TIM3_CCR3 = 30000; + + /* ---- */ + /* ARR reload enable */ + TIM3_CR1 |= TIM_CR1_ARPE; + + /* Counter enable */ + TIM3_CR1 |= TIM_CR1_CEN; +} + + +void tim2_isr(void) +{ + // PWM handling + static uint32_t pwm_value; + if (pwm_value == 0) { + pwm_value = 65535; + } + else { + pwm_value -= 20; + } + TIM3_CCR3 = pwm_value; + + // toggle blink LED + static uint32_t counter; + counter += 1; + if (counter > 500) { + gpio_toggle(GPIOC, GPIO13); + counter = 0; + } + + // clear interrrupt flag + TIM_SR(TIM2) &= ~TIM_SR_UIF; +} |