Browse Source

Move gpio wait logic to wait.h (#12067)

Joel Challis 4 years ago
parent
commit
40c7ecfdea

+ 0 - 33
quantum/quantum.h

@@ -200,39 +200,6 @@ extern layer_state_t layer_state;
 #    include "usbpd.h"
 #endif
 
-// Function substitutions to ease GPIO manipulation
-#if defined(__AVR__)
-
-/*   The AVR series GPIOs have a one clock read delay for changes in the digital input signal.
- *   But here's more margin to make it two clocks. */
-#    if !defined(GPIO_INPUT_PIN_DELAY)
-#        define GPIO_INPUT_PIN_DELAY 2
-#    endif
-#    define waitInputPinDelay() wait_cpuclock(GPIO_INPUT_PIN_DELAY)
-
-#elif defined(__ARMEL__) || defined(__ARMEB__)
-
-/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus
- * to which the GPIO is connected.
- * The connected buses differ depending on the various series of MCUs.
- * And since the instruction execution clock of the CPU and the bus clock of GPIO are different,
- * there is a delay of several clocks to read the change of the input signal.
- *
- * Define this delay with the GPIO_INPUT_PIN_DELAY macro.
- * If the GPIO_INPUT_PIN_DELAY macro is not defined, the following default values will be used.
- * (A fairly large value of 0.25 microseconds is set.)
- */
-#    if !defined(GPIO_INPUT_PIN_DELAY)
-#        if defined(STM32_SYSCLK)
-#            define GPIO_INPUT_PIN_DELAY (STM32_SYSCLK / 1000000L / 4)
-#        elif defined(KINETIS_SYSCLK_FREQUENCY)
-#            define GPIO_INPUT_PIN_DELAY (KINETIS_SYSCLK_FREQUENCY / 1000000L / 4)
-#        endif
-#    endif
-#    define waitInputPinDelay() wait_cpuclock(GPIO_INPUT_PIN_DELAY)
-
-#endif
-
 // For tri-layer
 void          update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
 layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);

+ 22 - 0
tmk_core/common/arm_atsam/_wait.h

@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "clks.h"
+
+#define wait_ms(ms) CLK_delay_ms(ms)
+#define wait_us(us) CLK_delay_us(us)
+#define waitInputPinDelay()

+ 29 - 0
tmk_core/common/avr/_wait.h

@@ -0,0 +1,29 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <util/delay.h>
+
+#define wait_ms(ms) _delay_ms(ms)
+#define wait_us(us) _delay_us(us)
+
+/* The AVR series GPIOs have a one clock read delay for changes in the digital input signal.
+ * But here's more margin to make it two clocks. */
+#ifndef GPIO_INPUT_PIN_DELAY
+#    define GPIO_INPUT_PIN_DELAY 2
+#endif
+
+#define waitInputPinDelay() __builtin_avr_delay_cycles(GPIO_INPUT_PIN_DELAY)

+ 55 - 0
tmk_core/common/chibios/_wait.h

@@ -0,0 +1,55 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <ch.h>
+
+/* chThdSleepX of zero maps to infinite - so we map to a tiny delay to still yield */
+#define wait_ms(ms)                     \
+    do {                                \
+        if (ms != 0) {                  \
+            chThdSleepMilliseconds(ms); \
+        } else {                        \
+            chThdSleepMicroseconds(1);  \
+        }                               \
+    } while (0)
+#define wait_us(us)                     \
+    do {                                \
+        if (us != 0) {                  \
+            chThdSleepMicroseconds(us); \
+        } else {                        \
+            chThdSleepMicroseconds(1);  \
+        }                               \
+    } while (0)
+
+/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus
+ * to which the GPIO is connected.
+ * The connected buses differ depending on the various series of MCUs.
+ * And since the instruction execution clock of the CPU and the bus clock of GPIO are different,
+ * there is a delay of several clocks to read the change of the input signal.
+ *
+ * Define this delay with the GPIO_INPUT_PIN_DELAY macro.
+ * If the GPIO_INPUT_PIN_DELAY macro is not defined, the following default values will be used.
+ * (A fairly large value of 0.25 microseconds is set.)
+ */
+
+#include "wait.c"
+
+#ifndef GPIO_INPUT_PIN_DELAY
+#    define GPIO_INPUT_PIN_DELAY (STM32_SYSCLK / 1000000L / 4)
+#endif
+
+#define waitInputPinDelay() wait_cpuclock(GPIO_INPUT_PIN_DELAY)

+ 1 - 0
tmk_core/common/chibios/chibios_config.h

@@ -30,4 +30,5 @@
 #    define USE_I2CV1
 #    define USE_I2CV1_CONTRIB  // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed
 #    define USE_GPIOV1
+#    define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY
 #endif

+ 89 - 0
tmk_core/common/chibios/wait.c

@@ -0,0 +1,89 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __OPTIMIZE__
+#    pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
+#endif
+
+#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"
+
+__attribute__((always_inline)) static inline void wait_cpuclock(unsigned int n) { /* n: 1..135 */
+    /* The argument n must be a constant expression.
+     * That way, compiler optimization will remove unnecessary code. */
+    if (n < 1) {
+        return;
+    }
+    if (n > 8) {
+        unsigned int n8 = n / 8;
+        n               = n - n8 * 8;
+        switch (n8) {
+            case 16:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 15:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 14:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 13:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 12:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 11:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 10:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 9:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 8:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 7:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 6:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 5:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 4:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 3:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 2:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 1:
+                asm volatile(CLOCK_DELAY_NOP8::: "memory");
+            case 0:
+                break;
+        }
+    }
+    switch (n) {
+        case 8:
+            asm volatile("nop" ::: "memory");
+        case 7:
+            asm volatile("nop" ::: "memory");
+        case 6:
+            asm volatile("nop" ::: "memory");
+        case 5:
+            asm volatile("nop" ::: "memory");
+        case 4:
+            asm volatile("nop" ::: "memory");
+        case 3:
+            asm volatile("nop" ::: "memory");
+        case 2:
+            asm volatile("nop" ::: "memory");
+        case 1:
+            asm volatile("nop" ::: "memory");
+        case 0:
+            break;
+    }
+}

+ 22 - 0
tmk_core/common/test/_wait.h

@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <inttypes.h>
+
+void wait_ms(uint32_t ms);
+#define wait_us(us) wait_ms(us / 1000)
+#define waitInputPinDelay()

+ 17 - 108
tmk_core/common/wait.h

@@ -1,3 +1,18 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
 #pragma once
 
 #include <inttypes.h>
@@ -6,114 +21,8 @@
 extern "C" {
 #endif
 
-#if defined(__ARMEL__) || defined(__ARMEB__)
-#    ifndef __OPTIMIZE__
-#        pragma message "Compiler optimizations disabled; wait_cpuclock() won't work as designed"
-#    endif
-
-#    define wait_cpuclock(x) wait_cpuclock_allnop(x)
-
-#    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"
-
-__attribute__((always_inline)) static inline void wait_cpuclock_allnop(unsigned int n) { /* n: 1..135 */
-    /* The argument n must be a constant expression.
-     * That way, compiler optimization will remove unnecessary code. */
-    if (n < 1) {
-        return;
-    }
-    if (n > 8) {
-        unsigned int n8 = n / 8;
-        n               = n - n8 * 8;
-        switch (n8) {
-            case 16:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 15:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 14:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 13:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 12:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 11:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 10:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 9:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 8:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 7:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 6:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 5:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 4:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 3:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 2:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 1:
-                asm volatile(CLOCK_DELAY_NOP8::: "memory");
-            case 0:
-                break;
-        }
-    }
-    switch (n) {
-        case 8:
-            asm volatile("nop" ::: "memory");
-        case 7:
-            asm volatile("nop" ::: "memory");
-        case 6:
-            asm volatile("nop" ::: "memory");
-        case 5:
-            asm volatile("nop" ::: "memory");
-        case 4:
-            asm volatile("nop" ::: "memory");
-        case 3:
-            asm volatile("nop" ::: "memory");
-        case 2:
-            asm volatile("nop" ::: "memory");
-        case 1:
-            asm volatile("nop" ::: "memory");
-        case 0:
-            break;
-    }
-}
-#endif
-
-#if defined(__AVR__)
-#    include <util/delay.h>
-#    define wait_ms(ms) _delay_ms(ms)
-#    define wait_us(us) _delay_us(us)
-#    define wait_cpuclock(x) __builtin_avr_delay_cycles(x)
-#elif defined PROTOCOL_CHIBIOS
-#    include <ch.h>
-#    define wait_ms(ms)                     \
-        do {                                \
-            if (ms != 0) {                  \
-                chThdSleepMilliseconds(ms); \
-            } else {                        \
-                chThdSleepMicroseconds(1);  \
-            }                               \
-        } while (0)
-#    define wait_us(us)                     \
-        do {                                \
-            if (us != 0) {                  \
-                chThdSleepMicroseconds(us); \
-            } else {                        \
-                chThdSleepMicroseconds(1);  \
-            }                               \
-        } while (0)
-#elif defined PROTOCOL_ARM_ATSAM
-#    include "clks.h"
-#    define wait_ms(ms) CLK_delay_ms(ms)
-#    define wait_us(us) CLK_delay_us(us)
-#else  // Unit tests
-void wait_ms(uint32_t ms);
-#    define wait_us(us) wait_ms(us / 1000)
+#if __has_include_next("_wait.h")
+#    include_next "_wait.h" /* Include the platforms _wait.h */
 #endif
 
 #ifdef __cplusplus