timer.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <stdint.h>
  2. #include "system.h"
  3. #include "led.h"
  4. #include "timer.h"
  5. #include <stdlib.h>
  6. #include "settings.h"
  7. #define S_PER_MINUTE (60)
  8. extern uint32_t cpu_freq;
  9. void (*beat_callback)(uint32_t b) = NULL;
  10. void timer_set_beat_callback(void (*b_cb)(uint32_t))
  11. {
  12. beat_callback = b_cb;
  13. }
  14. void timer_clear_beat_callback(void)
  15. {
  16. timer_set_beat_callback(NULL);
  17. }
  18. int timer_set_bpm(void)
  19. {
  20. uint32_t val = 0;
  21. uint32_t psc = 1;
  22. uint32_t err = 0;
  23. uint32_t reg = 0;
  24. uint32_t clock = (cpu_freq / (4 * Settings->bpm)) * (S_PER_MINUTE);;
  25. while (psc < 65535) {
  26. val = clock / psc;
  27. err = clock % psc;
  28. if ((val < 65535) && (err < (psc / 2))) {
  29. val--;
  30. break;
  31. }
  32. val = 0;
  33. psc++;
  34. }
  35. if (val == 0)
  36. return -1;
  37. TIM4_CR1 = 0;
  38. __asm__ volatile ("dmb");
  39. TIM4_PSC = psc;
  40. TIM4_ARR = val;
  41. TIM4_CNT = val - 1;
  42. return 0;
  43. }
  44. int timer_start(void)
  45. {
  46. TIM4_CR1 |= TIM_CR1_CLOCK_ENABLE;
  47. TIM4_DIER |= TIM_DIER_UIE;
  48. }
  49. int timer_stop(void)
  50. {
  51. TIM4_CR1 &= ~TIM_CR1_CLOCK_ENABLE;
  52. TIM4_DIER &= ~TIM_DIER_UIE;
  53. }
  54. static void timer_irq_setup(void)
  55. {
  56. nvic_irq_enable(NVIC_TIM4_IRQN);
  57. nvic_irq_setprio(NVIC_TIM4_IRQN, 0);
  58. APB1_CLOCK_RST |= TIM4_APB1_CLOCK_ER_VAL;
  59. __asm__ volatile ("dmb");
  60. APB1_CLOCK_RST &= ~TIM4_APB1_CLOCK_ER_VAL;
  61. APB1_CLOCK_ER |= TIM4_APB1_CLOCK_ER_VAL;
  62. }
  63. int timer_init(void)
  64. {
  65. timer_stop();
  66. timer_irq_setup();
  67. timer_set_bpm();
  68. return 0;
  69. }
  70. static volatile uint32_t tim4_ticks = 0;
  71. static volatile int pending_cb = 0;
  72. void isr_tim1(void)
  73. {
  74. TIM1_SR &= ~TIM_SR_UIF;
  75. }
  76. void isr_tim3(void)
  77. {
  78. TIM3_SR &= ~TIM_SR_UIF;
  79. }
  80. static int beat = 1;
  81. int timer_get_beat(void)
  82. {
  83. return beat;
  84. }
  85. void timer_set_beat(int b)
  86. {
  87. beat = b;
  88. }
  89. void timer_poll(void)
  90. {
  91. if (beat_callback && (pending_cb > 0)) {
  92. pending_cb--;
  93. beat_callback(beat);
  94. beat++;
  95. }
  96. }
  97. void isr_tim4(void)
  98. {
  99. TIM4_SR &= ~TIM_SR_UIF;
  100. tim4_ticks++;
  101. if (beat_callback) {
  102. pending_cb++;
  103. } else {
  104. led_beat((beat % 8) + 1);
  105. }
  106. }