aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tmk_core/chibios.mk3
-rw-r--r--tmk_core/common/chibios/_wait.c89
-rw-r--r--tmk_core/common/chibios/_wait.h24
-rw-r--r--tmk_core/common/chibios/wait.c90
4 files changed, 127 insertions, 79 deletions
diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk
index 7962516a0..18839710b 100644
--- a/tmk_core/chibios.mk
+++ b/tmk_core/chibios.mk
@@ -211,7 +211,8 @@ CHIBISRC = $(STARTUPSRC) \
211 $(BOARDSRC) \ 211 $(BOARDSRC) \
212 $(STREAMSSRC) \ 212 $(STREAMSSRC) \
213 $(CHIBIOS)/os/various/syscalls.c \ 213 $(CHIBIOS)/os/various/syscalls.c \
214 $(PLATFORM_COMMON_DIR)/syscall-fallbacks.c 214 $(PLATFORM_COMMON_DIR)/syscall-fallbacks.c \
215 $(PLATFORM_COMMON_DIR)/wait.c
215 216
216# Ensure the ASM files are not subjected to LTO -- it'll strip out interrupt handlers otherwise. 217# Ensure the ASM files are not subjected to LTO -- it'll strip out interrupt handlers otherwise.
217QUANTUM_LIB_SRC += $(STARTUPASM) $(PORTASM) $(OSALASM) $(PLATFORMASM) 218QUANTUM_LIB_SRC += $(STARTUPASM) $(PORTASM) $(OSALASM) $(PLATFORMASM)
diff --git a/tmk_core/common/chibios/_wait.c b/tmk_core/common/chibios/_wait.c
new file mode 100644
index 000000000..1fbea2dd5
--- /dev/null
+++ b/tmk_core/common/chibios/_wait.c
@@ -0,0 +1,89 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __OPTIMIZE__
18# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
19#endif
20
21#define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t"
22
23__attribute__((always_inline)) static inline void wait_cpuclock(unsigned int n) { /* n: 1..135 */
24 /* The argument n must be a constant expression.
25 * That way, compiler optimization will remove unnecessary code. */
26 if (n < 1) {
27 return;
28 }
29 if (n > 8) {
30 unsigned int n8 = n / 8;
31 n = n - n8 * 8;
32 switch (n8) {
33 case 16:
34 asm volatile(CLOCK_DELAY_NOP8::: "memory");
35 case 15:
36 asm volatile(CLOCK_DELAY_NOP8::: "memory");
37 case 14:
38 asm volatile(CLOCK_DELAY_NOP8::: "memory");
39 case 13:
40 asm volatile(CLOCK_DELAY_NOP8::: "memory");
41 case 12:
42 asm volatile(CLOCK_DELAY_NOP8::: "memory");
43 case 11:
44 asm volatile(CLOCK_DELAY_NOP8::: "memory");
45 case 10:
46 asm volatile(CLOCK_DELAY_NOP8::: "memory");
47 case 9:
48 asm volatile(CLOCK_DELAY_NOP8::: "memory");
49 case 8:
50 asm volatile(CLOCK_DELAY_NOP8::: "memory");
51 case 7:
52 asm volatile(CLOCK_DELAY_NOP8::: "memory");
53 case 6:
54 asm volatile(CLOCK_DELAY_NOP8::: "memory");
55 case 5:
56 asm volatile(CLOCK_DELAY_NOP8::: "memory");
57 case 4:
58 asm volatile(CLOCK_DELAY_NOP8::: "memory");
59 case 3:
60 asm volatile(CLOCK_DELAY_NOP8::: "memory");
61 case 2:
62 asm volatile(CLOCK_DELAY_NOP8::: "memory");
63 case 1:
64 asm volatile(CLOCK_DELAY_NOP8::: "memory");
65 case 0:
66 break;
67 }
68 }
69 switch (n) {
70 case 8:
71 asm volatile("nop" ::: "memory");
72 case 7:
73 asm volatile("nop" ::: "memory");
74 case 6:
75 asm volatile("nop" ::: "memory");
76 case 5:
77 asm volatile("nop" ::: "memory");
78 case 4:
79 asm volatile("nop" ::: "memory");
80 case 3:
81 asm volatile("nop" ::: "memory");
82 case 2:
83 asm volatile("nop" ::: "memory");
84 case 1:
85 asm volatile("nop" ::: "memory");
86 case 0:
87 break;
88 }
89}
diff --git a/tmk_core/common/chibios/_wait.h b/tmk_core/common/chibios/_wait.h
index 5bface53e..4a5172536 100644
--- a/tmk_core/common/chibios/_wait.h
+++ b/tmk_core/common/chibios/_wait.h
@@ -16,6 +16,7 @@
16#pragma once 16#pragma once
17 17
18#include <ch.h> 18#include <ch.h>
19#include <hal.h>
19 20
20/* chThdSleepX of zero maps to infinite - so we map to a tiny delay to still yield */ 21/* chThdSleepX of zero maps to infinite - so we map to a tiny delay to still yield */
21#define wait_ms(ms) \ 22#define wait_ms(ms) \
@@ -26,14 +27,19 @@
26 chThdSleepMicroseconds(1); \ 27 chThdSleepMicroseconds(1); \
27 } \ 28 } \
28 } while (0) 29 } while (0)
29#define wait_us(us) \ 30
30 do { \ 31#ifdef WAIT_US_TIMER
31 if (us != 0) { \ 32void wait_us(uint16_t duration);
32 chThdSleepMicroseconds(us); \ 33#else
33 } else { \ 34# define wait_us(us) \
34 chThdSleepMicroseconds(1); \ 35 do { \
35 } \ 36 if (us != 0) { \
36 } while (0) 37 chThdSleepMicroseconds(us); \
38 } else { \
39 chThdSleepMicroseconds(1); \
40 } \
41 } while (0)
42#endif
37 43
38/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus 44/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus
39 * to which the GPIO is connected. 45 * to which the GPIO is connected.
@@ -46,7 +52,7 @@
46 * (A fairly large value of 0.25 microseconds is set.) 52 * (A fairly large value of 0.25 microseconds is set.)
47 */ 53 */
48 54
49#include "wait.c" 55#include "_wait.c"
50 56
51#ifndef GPIO_INPUT_PIN_DELAY 57#ifndef GPIO_INPUT_PIN_DELAY
52# define GPIO_INPUT_PIN_DELAY (STM32_SYSCLK / 1000000L / 4) 58# define GPIO_INPUT_PIN_DELAY (STM32_SYSCLK / 1000000L / 4)
diff --git a/tmk_core/common/chibios/wait.c b/tmk_core/common/chibios/wait.c
index c6270fd95..56fd6ffce 100644
--- a/tmk_core/common/chibios/wait.c
+++ b/tmk_core/common/chibios/wait.c
@@ -14,76 +14,28 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16 16
17#ifndef __OPTIMIZE__ 17#include <ch.h>
18# pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed" 18#include <hal.h>
19#endif
20 19
21#define CLOCK_DELAY_NOP8 "nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t nop\n\t" 20#include "_wait.h"
22 21
23__attribute__((always_inline)) static inline void wait_cpuclock(unsigned int n) { /* n: 1..135 */ 22#ifdef WAIT_US_TIMER
24 /* The argument n must be a constant expression. 23void wait_us(uint16_t duration) {
25 * That way, compiler optimization will remove unnecessary code. */ 24 static const GPTConfig gpt_cfg = {1000000, NULL, 0, 0}; /* 1MHz timer, no callback */
26 if (n < 1) { 25
27 return; 26 if (duration == 0) {
28 } 27 duration = 1;
29 if (n > 8) {
30 unsigned int n8 = n / 8;
31 n = n - n8 * 8;
32 switch (n8) {
33 case 16:
34 asm volatile(CLOCK_DELAY_NOP8::: "memory");
35 case 15:
36 asm volatile(CLOCK_DELAY_NOP8::: "memory");
37 case 14:
38 asm volatile(CLOCK_DELAY_NOP8::: "memory");
39 case 13:
40 asm volatile(CLOCK_DELAY_NOP8::: "memory");
41 case 12:
42 asm volatile(CLOCK_DELAY_NOP8::: "memory");
43 case 11:
44 asm volatile(CLOCK_DELAY_NOP8::: "memory");
45 case 10:
46 asm volatile(CLOCK_DELAY_NOP8::: "memory");
47 case 9:
48 asm volatile(CLOCK_DELAY_NOP8::: "memory");
49 case 8:
50 asm volatile(CLOCK_DELAY_NOP8::: "memory");
51 case 7:
52 asm volatile(CLOCK_DELAY_NOP8::: "memory");
53 case 6:
54 asm volatile(CLOCK_DELAY_NOP8::: "memory");
55 case 5:
56 asm volatile(CLOCK_DELAY_NOP8::: "memory");
57 case 4:
58 asm volatile(CLOCK_DELAY_NOP8::: "memory");
59 case 3:
60 asm volatile(CLOCK_DELAY_NOP8::: "memory");
61 case 2:
62 asm volatile(CLOCK_DELAY_NOP8::: "memory");
63 case 1:
64 asm volatile(CLOCK_DELAY_NOP8::: "memory");
65 case 0:
66 break;
67 }
68 } 28 }
69 switch (n) { 29
70 case 8: 30 /*
71 asm volatile("nop" ::: "memory"); 31 * Only use this timer on the main thread;
72 case 7: 32 * other threads need to use their own timer.
73 asm volatile("nop" ::: "memory"); 33 */
74 case 6: 34 if (chThdGetSelfX() == &ch.mainthread && duration < (1ULL << (sizeof(gptcnt_t) * 8))) {
75 asm volatile("nop" ::: "memory"); 35 gptStart(&WAIT_US_TIMER, &gpt_cfg);
76 case 5: 36 gptPolledDelay(&WAIT_US_TIMER, duration);
77 asm volatile("nop" ::: "memory"); 37 } else {
78 case 4: 38 chThdSleepMicroseconds(duration);
79 asm volatile("nop" ::: "memory");
80 case 3:
81 asm volatile("nop" ::: "memory");
82 case 2:
83 asm volatile("nop" ::: "memory");
84 case 1:
85 asm volatile("nop" ::: "memory");
86 case 0:
87 break;
88 } 39 }
89} \ No newline at end of file 40}
41#endif