diff options
Diffstat (limited to 'tmk_core/common')
-rw-r--r-- | tmk_core/common/chibios/sleep_led.c | 88 |
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 | */ |
34 | static 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}; | 26 | static 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 */ | 28 | void sleep_led_timer_callback(void) { |
37 | OSAL_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 */ | ||
78 | OSAL_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 */ |
90 | void sleep_led_init(void) { | 90 | void 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 */ | ||
165 | void 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 */ | 164 | static 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 */ | 169 | static 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 */ | 172 | void sleep_led_init(void) { gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); } |
184 | } | ||
185 | 173 | ||
186 | void sleep_led_enable(void) { | 174 | void 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 | ||
192 | void sleep_led_disable(void) { | 176 | void sleep_led_disable(void) { gptStopTimer(&SLEEP_LED_GPT_DRIVER); } |
193 | /* Disable the timer */ | ||
194 | STM32_TIM14->CR1 = 0; | ||
195 | } | ||
196 | 177 | ||
197 | void sleep_led_toggle(void) { | 178 | void 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 | ||