-
Notifications
You must be signed in to change notification settings - Fork 8
/
LedBlink.h
74 lines (56 loc) · 1.64 KB
/
LedBlink.h
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
#pragma once
#include "stm32_tim.h"
#include "Pins.h"
#include "SysClock.h"
// Creates a short pulse on LED outupts to indicate data rx/tx events
// Uses TIM3, channels 1, 2
class LedBlink {
using Tmr = STM32::TIM::Timer<STM32::TIM::TIM_3>;
public:
static void init()
{
#if BOARD == BOARD_CSAT || BOARD == BOARD_2CAN2LIN
PinLedTx::Mode(ALT_OUTPUT); // ch1
PinLedRx::Mode(ALT_OUTPUT); // ch2
Tmr::EnableClocks();
// Timer clock = 1000 Hz
const uint32_t prescaler = CLOCK_APB1_TIM / 1000;
static_assert(prescaler < 0xffff);
Tmr::TIMx->PSC = prescaler - 1;
Tmr::TIMx->ARR = 0xFFFF;
Tmr::Ch1::CCMRx = (Tmr::Ch1::CCMRx & ~Tmr::Ch1::CCMR_MASK)
| Tmr::Ch1::CCMR_CCS_OUTPUT
| Tmr::Ch1::CCMR_OCM_FORCE_OFF;
Tmr::Ch2::CCMRx = (Tmr::Ch2::CCMRx & ~Tmr::Ch2::CCMR_MASK)
| Tmr::Ch2::CCMR_CCS_OUTPUT
| Tmr::Ch2::CCMR_OCM_FORCE_OFF;
// enable, with inverse polarity
Tmr::TIMx->CCER = 0
| Tmr::Ch1::CCER_CCxP | Tmr::Ch1::CCER_CCxE
| Tmr::Ch2::CCER_CCxP | Tmr::Ch2::CCER_CCxE;
Tmr::TIMx->EGR = TIM_EGR_UG; // force update
Tmr::Enable();
#endif
}
static void pulseTx() {
runChannel<Tmr::Ch1>(10);
}
static void pulseRx() {
runChannel<Tmr::Ch2>(10);
}
private:
template <class Channel>
static void runChannel(uint16_t timeout)
{
(void)timeout;
#if BOARD == BOARD_CSAT || BOARD == BOARD_2CAN2LIN
// force active
Channel::CCMRx = (Channel::CCMRx & ~Channel::CCMR_OCM)
| Channel::CCMR_OCM_FORCE_ON;
// set inactive on compare
Channel::CCRx = Tmr::Count() + timeout;
Channel::CCMRx = (Channel::CCMRx & ~Channel::CCMR_OCM)
| Channel::CCMR_OCM_RESET;
#endif
}
};