mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	Move gpio wait logic to wait.h (#12067)
This commit is contained in:
		
							parent
							
								
									2e24cfadb7
								
							
						
					
					
						commit
						40c7ecfdea
					
				| @ -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
									
								
								tmk_core/common/arm_atsam/_wait.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tmk_core/common/arm_atsam/_wait.h
									
									
									
									
									
										Normal file
									
								
							| @ -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
									
								
								tmk_core/common/avr/_wait.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tmk_core/common/avr/_wait.h
									
									
									
									
									
										Normal file
									
								
							| @ -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
									
								
								tmk_core/common/chibios/_wait.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								tmk_core/common/chibios/_wait.h
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
| @ -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
									
								
								tmk_core/common/chibios/wait.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								tmk_core/common/chibios/wait.c
									
									
									
									
									
										Normal file
									
								
							| @ -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
									
								
								tmk_core/common/test/_wait.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tmk_core/common/test/_wait.h
									
									
									
									
									
										Normal file
									
								
							| @ -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() | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Joel Challis
						Joel Challis