aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/timers.h
blob: 27e599918efbd0612d62aea0805c37f0552296ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* Note to self:
 * The timer clock frequencies are automatically fixed by hardware.
 * There are two cases:
 *     1.  if the APB prescaler is 1, the timer clock frequencies are
 *         set to the same frequency as that of the APB domain to which
 *         the timers are connected.
 *     2.  otherwise, they are set to twice (x2) the frequency of the
 *         APB domain to which the timers are connected.
 * See stm32 manual, 77/995
 *
 * hence, 72 mhz timers
 * */

/* Maple Timer channels:
 * Timer        Maple Pin               STM32 Pin     Type
 * TIM1_CH1     D6                      PA8           Advanced
 * TIM1_CH2     D7                      PA9           Advanced
 * TIM1_CH3     D8                      PA10          Advanced
 *
 * TIM2_CH1     D2                      PA0
 * TIM2_CH2     D3                      PA1
 * TIM2_CH3     D1                      PA2
 * TIM2_CH4     D0                      PA3
 *
 * TIM3_CH1     D12                     PA6
 * TIM3_CH2     D11                     PA7
 * TIM3_CH3     EXT7                    PB0
 * TIM3_CH4     EXT8                    PB1
 *
 * TIM4_CH1     EXT5                    PB6
 * TIM4_CH1     EXT9                    PB7
 * TIM4_CH1     EXT15                   PB8
 * TIM4_CH1     EXT4                    PB9
 *
 * Not supported:
 * TIM1_CH4    USBDM, not available     PA11          Advanced
 * TIM1_CH1_N  EXT12                    PB13
 * TIM1_CH2_N  EXT13                    PB14
 * TIM1_CH3_N  EXT14                    PB15
 * */

/* I don't like the Arduino API for dealing with pin modes.
 * How about...
 *
 * pinMode(digitalPin, PWM);
 * pwmWrite(digitalPin) */


#ifndef _TIMERS_H_
#define _TIMERS_H_
#include  <inttypes.h>

#ifdef __cplusplus
extern "C"{
#endif

typedef volatile uint32_t* TimerCCR;

#define TIMER1_BASE        0x40012C00
#define TIMER2_BASE        0x40000000
#define TIMER3_BASE        0x40000400
#define TIMER4_BASE        0x40000800

#define ARPE               BIT(7)                // Auto-reload preload enable
#define NOT_A_TIMER        0

#define TIMER1_CH1_CCR     (TimerCCR)(TIMER1_BASE + 0x34)
#define TIMER1_CH2_CCR     (TimerCCR)(TIMER1_BASE + 0x38)
#define TIMER1_CH3_CCR     (TimerCCR)(TIMER1_BASE + 0x3C)
#define TIMER1_CH4_CCR     (TimerCCR)(TIMER1_BASE + 0x40)

#define TIMER2_CH1_CCR     (TimerCCR)(TIMER2_BASE + 0x34)
#define TIMER2_CH2_CCR     (TimerCCR)(TIMER2_BASE + 0x38)
#define TIMER2_CH3_CCR     (TimerCCR)(TIMER2_BASE + 0x3C)
#define TIMER2_CH4_CCR     (TimerCCR)(TIMER2_BASE + 0x40)

#define TIMER3_CH1_CCR     (TimerCCR)(TIMER3_BASE + 0x34)
#define TIMER3_CH2_CCR     (TimerCCR)(TIMER3_BASE + 0x38)
#define TIMER3_CH3_CCR     (TimerCCR)(TIMER3_BASE + 0x3C)
#define TIMER3_CH4_CCR     (TimerCCR)(TIMER3_BASE + 0x40)

#define TIMER4_CH1_CCR     (TimerCCR)(TIMER4_BASE + 0x34)
#define TIMER4_CH2_CCR     (TimerCCR)(TIMER4_BASE + 0x38)
#define TIMER4_CH3_CCR     (TimerCCR)(TIMER4_BASE + 0x3C)
#define TIMER4_CH4_CCR     (TimerCCR)(TIMER4_BASE + 0x40)


/* Turn on timer with prescale as the divisor
 * void timer_init(uint32_t timer, uint16_t prescale)
 *      timer     ->  {1-4}
 *      prescale  ->  {1-65535}
 * */
void timer_init(uint8_t, uint16_t);

/* Turn on PWM with duty_cycle on the specified channel in timer.
 * This function takes in a pointer to the corresponding CCR
 * register for the pin cause it saves pwmWrite() a couple of
 * cycles.
 *
 * void timer_pwm(uint8_t channel, uint8_t duty_cycle);
 *      channel    -> {TIMERx_CHn_CCR}
 *      duty_cycle -> {0-65535}
 *
 * PRECONDITIONS:
 *      pin has been set to alternate function output
 *      timer has been initialized
 */
static inline void timer_pwm_write_ccr(TimerCCR CCR, uint16_t duty_cycle) {
    *CCR = duty_cycle;
}

#ifdef __cplusplus
} // extern "C"
#endif


#endif