diff options
Diffstat (limited to 'tmk_core/common/chibios')
| -rw-r--r-- | tmk_core/common/chibios/_wait.h | 55 | ||||
| -rw-r--r-- | tmk_core/common/chibios/bootloader.c | 20 | ||||
| -rw-r--r-- | tmk_core/common/chibios/chibios_config.h | 7 | ||||
| -rw-r--r-- | tmk_core/common/chibios/pin_defs.h | 81 | ||||
| -rw-r--r-- | tmk_core/common/chibios/sleep_led.c | 88 | ||||
| -rw-r--r-- | tmk_core/common/chibios/suspend.c | 28 | ||||
| -rw-r--r-- | tmk_core/common/chibios/wait.c | 89 | 
7 files changed, 311 insertions, 57 deletions
diff --git a/tmk_core/common/chibios/_wait.h b/tmk_core/common/chibios/_wait.h new file mode 100644 index 0000000000..5bface53e1 --- /dev/null +++ b/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) diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c index 6cabcc4b81..11f7abf432 100644 --- a/tmk_core/common/chibios/bootloader.c +++ b/tmk_core/common/chibios/bootloader.c @@ -13,7 +13,23 @@  #    define STM32_BOOTLOADER_DUAL_BANK FALSE  #endif -#if STM32_BOOTLOADER_DUAL_BANK +#ifdef BOOTLOADER_TINYUF2 + +#    define DBL_TAP_MAGIC 0xf01669ef  // From tinyuf2's board_api.h + +// defined by linker script +extern uint32_t _board_dfu_dbl_tap[]; +#    define DBL_TAP_REG _board_dfu_dbl_tap[0] + +void bootloader_jump(void) { +    DBL_TAP_REG = DBL_TAP_MAGIC; +    NVIC_SystemReset(); +} + +void enter_bootloader_mode_if_requested(void) { /* not needed, no two-stage reset */ +} + +#elif STM32_BOOTLOADER_DUAL_BANK  // Need pin definitions  #    include "config_common.h" @@ -79,7 +95,7 @@ void enter_bootloader_mode_if_requested(void) {      }  } -#elif defined(KL2x) || defined(K20x)  // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS +#elif defined(KL2x) || defined(K20x) || defined(MK66F18)  // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS  /* Kinetis */  #    if defined(BOOTLOADER_KIIBOHD) diff --git a/tmk_core/common/chibios/chibios_config.h b/tmk_core/common/chibios/chibios_config.h index b4d96465d1..1d8ace4955 100644 --- a/tmk_core/common/chibios/chibios_config.h +++ b/tmk_core/common/chibios/chibios_config.h @@ -15,6 +15,8 @@   */  #pragma once +#define SPLIT_USB_DETECT  // Force this on for now +  #if defined(STM32F1XX)  #    define USE_GPIOV1  #endif @@ -28,4 +30,9 @@  #    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 + +#if defined(MK66F18) +#    define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY  #endif diff --git a/tmk_core/common/chibios/pin_defs.h b/tmk_core/common/chibios/pin_defs.h index 86bc1076e8..c03f8de0c2 100644 --- a/tmk_core/common/chibios/pin_defs.h +++ b/tmk_core/common/chibios/pin_defs.h @@ -70,6 +70,23 @@  #    define A13 PAL_LINE(GPIOA, 13)  #    define A14 PAL_LINE(GPIOA, 14)  #    define A15 PAL_LINE(GPIOA, 15) +#    define A16 PAL_LINE(GPIOA, 16) +#    define A17 PAL_LINE(GPIOA, 17) +#    define A18 PAL_LINE(GPIOA, 18) +#    define A19 PAL_LINE(GPIOA, 19) +#    define A20 PAL_LINE(GPIOA, 20) +#    define A21 PAL_LINE(GPIOA, 21) +#    define A22 PAL_LINE(GPIOA, 22) +#    define A23 PAL_LINE(GPIOA, 23) +#    define A24 PAL_LINE(GPIOA, 24) +#    define A25 PAL_LINE(GPIOA, 25) +#    define A26 PAL_LINE(GPIOA, 26) +#    define A27 PAL_LINE(GPIOA, 27) +#    define A28 PAL_LINE(GPIOA, 28) +#    define A29 PAL_LINE(GPIOA, 29) +#    define A30 PAL_LINE(GPIOA, 30) +#    define A31 PAL_LINE(GPIOA, 31) +#    define A32 PAL_LINE(GPIOA, 32)  #    define B0 PAL_LINE(GPIOB, 0)  #    define B1 PAL_LINE(GPIOB, 1)  #    define B2 PAL_LINE(GPIOB, 2) @@ -90,6 +107,19 @@  #    define B17 PAL_LINE(GPIOB, 17)  #    define B18 PAL_LINE(GPIOB, 18)  #    define B19 PAL_LINE(GPIOB, 19) +#    define B20 PAL_LINE(GPIOB, 20) +#    define B21 PAL_LINE(GPIOB, 21) +#    define B22 PAL_LINE(GPIOB, 22) +#    define B23 PAL_LINE(GPIOB, 23) +#    define B24 PAL_LINE(GPIOB, 24) +#    define B25 PAL_LINE(GPIOB, 25) +#    define B26 PAL_LINE(GPIOB, 26) +#    define B27 PAL_LINE(GPIOB, 27) +#    define B28 PAL_LINE(GPIOB, 28) +#    define B29 PAL_LINE(GPIOB, 29) +#    define B30 PAL_LINE(GPIOB, 30) +#    define B31 PAL_LINE(GPIOB, 31) +#    define B32 PAL_LINE(GPIOB, 32)  #    define C0 PAL_LINE(GPIOC, 0)  #    define C1 PAL_LINE(GPIOC, 1)  #    define C2 PAL_LINE(GPIOC, 2) @@ -106,6 +136,23 @@  #    define C13 PAL_LINE(GPIOC, 13)  #    define C14 PAL_LINE(GPIOC, 14)  #    define C15 PAL_LINE(GPIOC, 15) +#    define C16 PAL_LINE(GPIOC, 16) +#    define C17 PAL_LINE(GPIOC, 17) +#    define C18 PAL_LINE(GPIOC, 18) +#    define C19 PAL_LINE(GPIOC, 19) +#    define C20 PAL_LINE(GPIOC, 20) +#    define C21 PAL_LINE(GPIOC, 21) +#    define C22 PAL_LINE(GPIOC, 22) +#    define C23 PAL_LINE(GPIOC, 23) +#    define C24 PAL_LINE(GPIOC, 24) +#    define C25 PAL_LINE(GPIOC, 25) +#    define C26 PAL_LINE(GPIOC, 26) +#    define C27 PAL_LINE(GPIOC, 27) +#    define C28 PAL_LINE(GPIOC, 28) +#    define C29 PAL_LINE(GPIOC, 29) +#    define C30 PAL_LINE(GPIOC, 30) +#    define C31 PAL_LINE(GPIOC, 31) +#    define C32 PAL_LINE(GPIOC, 32)  #    define D0 PAL_LINE(GPIOD, 0)  #    define D1 PAL_LINE(GPIOD, 1)  #    define D2 PAL_LINE(GPIOD, 2) @@ -122,6 +169,23 @@  #    define D13 PAL_LINE(GPIOD, 13)  #    define D14 PAL_LINE(GPIOD, 14)  #    define D15 PAL_LINE(GPIOD, 15) +#    define D16 PAL_LINE(GPIOD, 16) +#    define D17 PAL_LINE(GPIOD, 17) +#    define D18 PAL_LINE(GPIOD, 18) +#    define D19 PAL_LINE(GPIOD, 19) +#    define D20 PAL_LINE(GPIOD, 20) +#    define D21 PAL_LINE(GPIOD, 21) +#    define D22 PAL_LINE(GPIOD, 22) +#    define D23 PAL_LINE(GPIOD, 23) +#    define D24 PAL_LINE(GPIOD, 24) +#    define D25 PAL_LINE(GPIOD, 25) +#    define D26 PAL_LINE(GPIOD, 26) +#    define D27 PAL_LINE(GPIOD, 27) +#    define D28 PAL_LINE(GPIOD, 28) +#    define D29 PAL_LINE(GPIOD, 29) +#    define D30 PAL_LINE(GPIOD, 30) +#    define D31 PAL_LINE(GPIOD, 31) +#    define D32 PAL_LINE(GPIOD, 32)  #    define E0 PAL_LINE(GPIOE, 0)  #    define E1 PAL_LINE(GPIOE, 1)  #    define E2 PAL_LINE(GPIOE, 2) @@ -138,6 +202,23 @@  #    define E13 PAL_LINE(GPIOE, 13)  #    define E14 PAL_LINE(GPIOE, 14)  #    define E15 PAL_LINE(GPIOE, 15) +#    define E16 PAL_LINE(GPIOE, 16) +#    define E17 PAL_LINE(GPIOE, 17) +#    define E18 PAL_LINE(GPIOE, 18) +#    define E19 PAL_LINE(GPIOE, 19) +#    define E20 PAL_LINE(GPIOE, 20) +#    define E21 PAL_LINE(GPIOE, 21) +#    define E22 PAL_LINE(GPIOE, 22) +#    define E23 PAL_LINE(GPIOE, 23) +#    define E24 PAL_LINE(GPIOE, 24) +#    define E25 PAL_LINE(GPIOE, 25) +#    define E26 PAL_LINE(GPIOE, 26) +#    define E27 PAL_LINE(GPIOE, 27) +#    define E28 PAL_LINE(GPIOE, 28) +#    define E29 PAL_LINE(GPIOE, 29) +#    define E30 PAL_LINE(GPIOE, 30) +#    define E31 PAL_LINE(GPIOE, 31) +#    define E32 PAL_LINE(GPIOE, 32)  #    define F0 PAL_LINE(GPIOF, 0)  #    define F1 PAL_LINE(GPIOF, 1)  #    define F2 PAL_LINE(GPIOF, 2) diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c index 5595eec0e5..477056a454 100644 --- a/tmk_core/common/chibios/sleep_led.c +++ b/tmk_core/common/chibios/sleep_led.c @@ -9,21 +9,13 @@   * Use LP timer on Kinetises, TIM14 on STM32F0.   */ -#if defined(KL2x) || defined(K20x) - -/* Use Low Power Timer (LPTMR) */ -#    define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR -#    define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF - -#elif defined(STM32F0XX) - -/* Use TIM14 manually */ -#    define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER -#    define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF - +#ifndef SLEEP_LED_GPT_DRIVER +#    if defined(STM32F0XX) +#        define SLEEP_LED_GPT_DRIVER GPTD14 +#    endif  #endif -#if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */ +#if defined(KL2x) || defined(K20x) || defined(SLEEP_LED_GPT_DRIVER) /* common parts for timers/interrupts */  /* Breathing Sleep LED brighness(PWM On period) table   * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle @@ -33,10 +25,7 @@   */  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}; -/* interrupt handler */ -OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { -    OSAL_IRQ_PROLOGUE(); - +void sleep_led_timer_callback(void) {      /* Software PWM       * timer:1111 1111 1111 1111       *       \_____/\/ \_______/____  count(0-255) @@ -64,17 +53,16 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {      if (timer.pwm.count == breathing_table[timer.pwm.index]) {          led_set(0);      } - -    /* Reset the counter */ -    RESET_COUNTER; - -    OSAL_IRQ_EPILOGUE();  }  #endif /* common parts for known platforms */  #if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */ +/* Use Low Power Timer (LPTMR) */ +#    define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR +#    define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF +  /* LPTMR clock options */  #    define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */  #    define LPTMR_CLOCK_LPO 1      /* 1kHz clock */ @@ -86,6 +74,18 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {  #        define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER  #    endif +/* interrupt handler */ +OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { +    OSAL_IRQ_PROLOGUE(); + +    sleep_led_timer_callback(); + +    /* Reset the counter */ +    RESET_COUNTER; + +    OSAL_IRQ_EPILOGUE(); +} +  /* Initialise the timer */  void sleep_led_init(void) {      /* Make sure the clock to the LPTMR is enabled */ @@ -159,45 +159,23 @@ void sleep_led_toggle(void) {      LPTMR0->CSR ^= LPTMRx_CSR_TEN;  } -#elif defined(STM32F0XX) /* platform selection: STM32F0XX */ - -/* Initialise the timer */ -void sleep_led_init(void) { -    /* enable clock */ -    rccEnableTIM14(FALSE); /* low power enable = FALSE */ -    rccResetTIM14(); - -    /* prescale */ -    /* Assuming 48MHz internal clock */ -    /* getting cca 65484 irqs/sec */ -    STM32_TIM14->PSC = 733; +#elif defined(SLEEP_LED_GPT_DRIVER) -    /* auto-reload */ -    /* 0 => interrupt every time */ -    STM32_TIM14->ARR = 3; +static void gptTimerCallback(GPTDriver *gptp) { +    (void)gptp; +    sleep_led_timer_callback(); +} -    /* enable counter update event interrupt */ -    STM32_TIM14->DIER |= STM32_TIM_DIER_UIE; +static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0}; -    /* register interrupt vector */ -    nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */ -} +/* Initialise the timer */ +void sleep_led_init(void) { gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); } -void sleep_led_enable(void) { -    /* Enable the timer */ -    STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS; -    /* URS => update event only on overflow; setting UG bit disabled */ -} +void sleep_led_enable(void) { gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); } -void sleep_led_disable(void) { -    /* Disable the timer */ -    STM32_TIM14->CR1 = 0; -} +void sleep_led_disable(void) { gptStopTimer(&SLEEP_LED_GPT_DRIVER); } -void sleep_led_toggle(void) { -    /* Toggle the timer */ -    STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN; -} +void sleep_led_toggle(void) { (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); }  #else /* platform selection: not on familiar chips */ diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 49e20641fb..38517e06f0 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c @@ -24,6 +24,13 @@  #    include "rgblight.h"  #endif +#ifdef LED_MATRIX_ENABLE +#    include "led_matrix.h" +#endif +#ifdef RGB_MATRIX_ENABLE +#    include "rgb_matrix.h" +#endif +  /** \brief suspend idle   *   * FIXME: needs doc @@ -53,6 +60,13 @@ void suspend_power_down(void) {      backlight_set(0);  #endif +#ifdef LED_MATRIX_ENABLE +    led_matrix_task(); +#endif +#ifdef RGB_MATRIX_ENABLE +    rgb_matrix_task(); +#endif +      // Turn off LED indicators      uint8_t leds_off = 0;  #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) @@ -69,6 +83,13 @@ void suspend_power_down(void) {  #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)      rgblight_suspend();  #endif + +#if defined(LED_MATRIX_ENABLE) +    led_matrix_set_suspend_state(true); +#endif +#if defined(RGB_MATRIX_ENABLE) +    rgb_matrix_set_suspend_state(true); +#endif  #ifdef AUDIO_ENABLE      stop_all_notes();  #endif /* AUDIO_ENABLE */ @@ -137,5 +158,12 @@ void suspend_wakeup_init(void) {  #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)      rgblight_wakeup();  #endif + +#if defined(LED_MATRIX_ENABLE) +    led_matrix_set_suspend_state(false); +#endif +#if defined(RGB_MATRIX_ENABLE) +    rgb_matrix_set_suspend_state(false); +#endif      suspend_wakeup_init_kb();  } diff --git a/tmk_core/common/chibios/wait.c b/tmk_core/common/chibios/wait.c new file mode 100644 index 0000000000..c6270fd95e --- /dev/null +++ b/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; +    } +}
\ No newline at end of file  | 
