aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/chibios/sleep_led.c88
1 files changed, 33 insertions, 55 deletions
diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c
index 5595eec0e..477056a45 100644
--- a/tmk_core/common/chibios/sleep_led.c
+++ b/tmk_core/common/chibios/sleep_led.c
@@ -9,21 +9,13 @@
9 * Use LP timer on Kinetises, TIM14 on STM32F0. 9 * Use LP timer on Kinetises, TIM14 on STM32F0.
10 */ 10 */
11 11
12#if defined(KL2x) || defined(K20x) 12#ifndef SLEEP_LED_GPT_DRIVER
13 13# if defined(STM32F0XX)
14/* Use Low Power Timer (LPTMR) */ 14# define SLEEP_LED_GPT_DRIVER GPTD14
15# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR 15# endif
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 16#endif
25 17
26#if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */ 18#if defined(KL2x) || defined(K20x) || defined(SLEEP_LED_GPT_DRIVER) /* common parts for timers/interrupts */
27 19
28/* Breathing Sleep LED brighness(PWM On period) table 20/* Breathing Sleep LED brighness(PWM On period) table
29 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle 21 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
@@ -33,10 +25,7 @@
33 */ 25 */
34static const uint8_t breathing_table[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 26static const uint8_t breathing_table[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
35 27
36/* interrupt handler */ 28void sleep_led_timer_callback(void) {
37OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
38 OSAL_IRQ_PROLOGUE();
39
40 /* Software PWM 29 /* Software PWM
41 * timer:1111 1111 1111 1111 30 * timer:1111 1111 1111 1111
42 * \_____/\/ \_______/____ count(0-255) 31 * \_____/\/ \_______/____ count(0-255)
@@ -64,17 +53,16 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
64 if (timer.pwm.count == breathing_table[timer.pwm.index]) { 53 if (timer.pwm.count == breathing_table[timer.pwm.index]) {
65 led_set(0); 54 led_set(0);
66 } 55 }
67
68 /* Reset the counter */
69 RESET_COUNTER;
70
71 OSAL_IRQ_EPILOGUE();
72} 56}
73 57
74#endif /* common parts for known platforms */ 58#endif /* common parts for known platforms */
75 59
76#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */ 60#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
77 61
62/* Use Low Power Timer (LPTMR) */
63# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
64# define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
65
78/* LPTMR clock options */ 66/* LPTMR clock options */
79# define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */ 67# define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
80# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ 68# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@@ -86,6 +74,18 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
86# define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER 74# define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER
87# endif 75# endif
88 76
77/* interrupt handler */
78OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
79 OSAL_IRQ_PROLOGUE();
80
81 sleep_led_timer_callback();
82
83 /* Reset the counter */
84 RESET_COUNTER;
85
86 OSAL_IRQ_EPILOGUE();
87}
88
89/* Initialise the timer */ 89/* Initialise the timer */
90void sleep_led_init(void) { 90void sleep_led_init(void) {
91 /* Make sure the clock to the LPTMR is enabled */ 91 /* Make sure the clock to the LPTMR is enabled */
@@ -159,45 +159,23 @@ void sleep_led_toggle(void) {
159 LPTMR0->CSR ^= LPTMRx_CSR_TEN; 159 LPTMR0->CSR ^= LPTMRx_CSR_TEN;
160} 160}
161 161
162#elif defined(STM32F0XX) /* platform selection: STM32F0XX */ 162#elif defined(SLEEP_LED_GPT_DRIVER)
163
164/* Initialise the timer */
165void sleep_led_init(void) {
166 /* enable clock */
167 rccEnableTIM14(FALSE); /* low power enable = FALSE */
168 rccResetTIM14();
169
170 /* prescale */
171 /* Assuming 48MHz internal clock */
172 /* getting cca 65484 irqs/sec */
173 STM32_TIM14->PSC = 733;
174 163
175 /* auto-reload */ 164static void gptTimerCallback(GPTDriver *gptp) {
176 /* 0 => interrupt every time */ 165 (void)gptp;
177 STM32_TIM14->ARR = 3; 166 sleep_led_timer_callback();
167}
178 168
179 /* enable counter update event interrupt */ 169static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0};
180 STM32_TIM14->DIER |= STM32_TIM_DIER_UIE;
181 170
182 /* register interrupt vector */ 171/* Initialise the timer */
183 nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */ 172void sleep_led_init(void) { gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); }
184}
185 173
186void sleep_led_enable(void) { 174void sleep_led_enable(void) { gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); }
187 /* Enable the timer */
188 STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS;
189 /* URS => update event only on overflow; setting UG bit disabled */
190}
191 175
192void sleep_led_disable(void) { 176void sleep_led_disable(void) { gptStopTimer(&SLEEP_LED_GPT_DRIVER); }
193 /* Disable the timer */
194 STM32_TIM14->CR1 = 0;
195}
196 177
197void sleep_led_toggle(void) { 178void sleep_led_toggle(void) { (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); }
198 /* Toggle the timer */
199 STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN;
200}
201 179
202#else /* platform selection: not on familiar chips */ 180#else /* platform selection: not on familiar chips */
203 181