123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include <stdint.h>
- #include "system.h"
- #include "led.h"
- #include "timer.h"
- #include <stdlib.h>
- #include "settings.h"
- #define S_PER_MINUTE (60)
- extern uint32_t cpu_freq;
- void (*beat_callback)(uint32_t b) = NULL;
- void timer_set_beat_callback(void (*b_cb)(uint32_t))
- {
- beat_callback = b_cb;
- }
- void timer_clear_beat_callback(void)
- {
- timer_set_beat_callback(NULL);
- }
- int timer_set_bpm(void)
- {
- uint32_t val = 0;
- uint32_t psc = 1;
- uint32_t err = 0;
- uint32_t reg = 0;
- uint32_t clock = (cpu_freq / (4 * Settings->bpm)) * (S_PER_MINUTE);;
- while (psc < 65535) {
- val = clock / psc;
- err = clock % psc;
- if ((val < 65535) && (err < (psc / 2))) {
- val--;
- break;
- }
- val = 0;
- psc++;
- }
- if (val == 0)
- return -1;
- TIM4_CR1 = 0;
- __asm__ volatile ("dmb");
- TIM4_PSC = psc;
- TIM4_ARR = val;
- TIM4_CNT = val - 1;
- return 0;
- }
- int timer_start(void)
- {
- TIM4_CR1 |= TIM_CR1_CLOCK_ENABLE;
- TIM4_DIER |= TIM_DIER_UIE;
- }
- int timer_stop(void)
- {
- TIM4_CR1 &= ~TIM_CR1_CLOCK_ENABLE;
- TIM4_DIER &= ~TIM_DIER_UIE;
- }
- static void timer_irq_setup(void)
- {
- nvic_irq_enable(NVIC_TIM4_IRQN);
- nvic_irq_setprio(NVIC_TIM4_IRQN, 0);
- APB1_CLOCK_RST |= TIM4_APB1_CLOCK_ER_VAL;
- __asm__ volatile ("dmb");
- APB1_CLOCK_RST &= ~TIM4_APB1_CLOCK_ER_VAL;
- APB1_CLOCK_ER |= TIM4_APB1_CLOCK_ER_VAL;
- }
- int timer_init(void)
- {
- timer_stop();
- timer_irq_setup();
- timer_set_bpm();
- return 0;
- }
- static volatile uint32_t tim4_ticks = 0;
- static volatile int pending_cb = 0;
- void isr_tim1(void)
- {
- TIM1_SR &= ~TIM_SR_UIF;
- }
- void isr_tim3(void)
- {
- TIM3_SR &= ~TIM_SR_UIF;
- }
- static int beat = 1;
- int timer_get_beat(void)
- {
- return beat;
- }
- void timer_set_beat(int b)
- {
- beat = b;
- }
- void timer_poll(void)
- {
- if (beat_callback && (pending_cb > 0)) {
- pending_cb--;
- beat_callback(beat);
- beat++;
- }
- }
- void isr_tim4(void)
- {
- TIM4_SR &= ~TIM_SR_UIF;
- tim4_ticks++;
- if (beat_callback) {
- pending_cb++;
- } else {
- led_beat((beat % 8) + 1);
- }
- }
|