4
4
#include "led.h"
5
5
#include "sleep_led.h"
6
6
7
- #if defined(KL2x ) || defined(K20x ) /* platform selection: familiar Kinetis chips */
8
- /* All right, we go the "software" way: LP timer, toggle LED in interrupt.
7
+ /* All right, we go the "software" way: timer, toggle LED in interrupt.
9
8
* Based on hasu's code for AVRs.
9
+ * Use LP timer on Kinetises, TIM14 on STM32F0.
10
10
*/
11
11
12
+ #if defined(KL2x ) || defined(K20x )
13
+
14
+ /* Use Low Power Timer (LPTMR) */
15
+ #define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
16
+ #define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
17
+
18
+ #elif defined(STM32F0XX )
19
+
20
+ /* Use TIM14 manually */
21
+ #define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
22
+ #define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
23
+
24
+ #endif
25
+
26
+ #if defined(KL2x ) || defined(K20x ) || defined(STM32F0XX ) /* common parts for timers/interrupts */
27
+
12
28
/* Breathing Sleep LED brighness(PWM On period) table
13
29
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
14
30
*
@@ -22,8 +38,8 @@ static const uint8_t breathing_table[64] = {
22
38
15 , 10 , 6 , 4 , 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
23
39
};
24
40
25
- /* Low Power Timer interrupt handler */
26
- OSAL_IRQ_HANDLER (KINETIS_LPTMR0_IRQ_VECTOR ) {
41
+ /* interrupt handler */
42
+ OSAL_IRQ_HANDLER (TIMER_INTERRUPT_VECTOR ) {
27
43
OSAL_IRQ_PROLOGUE ();
28
44
29
45
/* Software PWM
@@ -55,11 +71,16 @@ OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
55
71
}
56
72
57
73
/* Reset the counter */
58
- LPTMR0 -> CSR |= LPTMRx_CSR_TCF ;
74
+ RESET_COUNTER ;
59
75
60
76
OSAL_IRQ_EPILOGUE ();
61
77
}
62
78
79
+ #endif /* common parts for known platforms */
80
+
81
+
82
+ #if defined(KL2x ) || defined(K20x ) /* platform selection: familiar Kinetis chips */
83
+
63
84
/* LPTMR clock options */
64
85
#define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
65
86
#define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@@ -144,7 +165,48 @@ void sleep_led_toggle(void) {
144
165
LPTMR0 -> CSR ^= LPTMRx_CSR_TEN ;
145
166
}
146
167
147
- #else /* platform selection: not on familiar Kinetis chips */
168
+ #elif defined(STM32F0XX ) /* platform selection: STM32F0XX */
169
+
170
+ /* Initialise the timer */
171
+ void sleep_led_init (void ) {
172
+ /* enable clock */
173
+ rccEnableTIM14 (FALSE); /* low power enable = FALSE */
174
+ rccResetTIM14 ();
175
+
176
+ /* prescale */
177
+ /* Assuming 48MHz internal clock */
178
+ /* getting cca 65484 irqs/sec */
179
+ STM32_TIM14 -> PSC = 733 ;
180
+
181
+ /* auto-reload */
182
+ /* 0 => interrupt every time */
183
+ STM32_TIM14 -> ARR = 3 ;
184
+
185
+ /* enable counter update event interrupt */
186
+ STM32_TIM14 -> DIER |= STM32_TIM_DIER_UIE ;
187
+
188
+ /* register interrupt vector */
189
+ nvicEnableVector (STM32_TIM14_NUMBER , 2 ); /* vector, priority */
190
+ }
191
+
192
+ void sleep_led_enable (void ) {
193
+ /* Enable the timer */
194
+ STM32_TIM14 -> CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS ;
195
+ /* URS => update event only on overflow; setting UG bit disabled */
196
+ }
197
+
198
+ void sleep_led_disable (void ) {
199
+ /* Disable the timer */
200
+ STM32_TIM14 -> CR1 = 0 ;
201
+ }
202
+
203
+ void sleep_led_toggle (void ) {
204
+ /* Toggle the timer */
205
+ STM32_TIM14 -> CR1 ^= STM32_TIM_CR1_CEN ;
206
+ }
207
+
208
+
209
+ #else /* platform selection: not on familiar chips */
148
210
149
211
void sleep_led_init (void ) {
150
212
}
0 commit comments