diff options
Diffstat (limited to 'tmk_core/common')
27 files changed, 581 insertions, 1261 deletions
diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c index ccd5d15a54..ff1a692623 100644 --- a/tmk_core/common/arm_atsam/eeprom.c +++ b/tmk_core/common/arm_atsam/eeprom.c @@ -13,24 +13,110 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - #include "eeprom.h" +#include "debug.h" +#include "samd51j18a.h" +#include "core_cm4.h" +#include "component/nvmctrl.h" #ifndef EEPROM_SIZE # include "eeconfig.h" # define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO #endif -__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE]; +#ifndef MAX +# define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) +#endif + +#ifndef BUSY_RETRIES +# define BUSY_RETRIES 10000 +#endif + +// #define DEBUG_EEPROM_OUTPUT + +/* + * Debug print utils + */ +#if defined(DEBUG_EEPROM_OUTPUT) +# define eeprom_printf(fmt, ...) xprintf(fmt, ##__VA_ARGS__); +#else /* NO_DEBUG */ +# define eeprom_printf(fmt, ...) +#endif /* NO_DEBUG */ + +__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE] = {0}; +volatile uint8_t * SmartEEPROM8 = (uint8_t *)SEEPROM_ADDR; + +static inline bool eeprom_is_busy(void) { + int timeout = BUSY_RETRIES; + while (NVMCTRL->SEESTAT.bit.BUSY && timeout-- > 0) + ; + + return NVMCTRL->SEESTAT.bit.BUSY; +} + +static uint32_t get_virtual_eeprom_size(void) { + // clang-format off + static const uint32_t VIRTUAL_EEPROM_MAP[11][8] = { + /* 4 8 16 32 64 128 256 512 */ + /* 0*/ { 0, 0, 0, 0, 0, 0, 0, 0 }, + /* 1*/ { 512, 1024, 2048, 4096, 4096, 4096, 4096, 4096 }, + /* 2*/ { 512, 1024, 2048, 4096, 8192, 8192, 8192, 8192 }, + /* 3*/ { 512, 1024, 2048, 4096, 8192, 16384, 16384, 16384 }, + /* 4*/ { 512, 1024, 2048, 4096, 8192, 16384, 16384, 16384 }, + /* 5*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, + /* 6*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, + /* 7*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, + /* 8*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 }, + /* 9*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }, + /*10*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 }, + }; + // clang-format on + + static uint32_t virtual_eeprom_size = UINT32_MAX; + if (virtual_eeprom_size == UINT32_MAX) { + virtual_eeprom_size = VIRTUAL_EEPROM_MAP[NVMCTRL->SEESTAT.bit.PSZ][NVMCTRL->SEESTAT.bit.SBLK]; + } + // eeprom_printf("get_virtual_eeprom_size:: %d:%d:%d\n", NVMCTRL->SEESTAT.bit.PSZ, NVMCTRL->SEESTAT.bit.SBLK, virtual_eeprom_size); + return virtual_eeprom_size; +} uint8_t eeprom_read_byte(const uint8_t *addr) { uintptr_t offset = (uintptr_t)addr; - return buffer[offset]; + if (offset >= MAX(EEPROM_SIZE, get_virtual_eeprom_size())) { + eeprom_printf("eeprom_read_byte:: out of bounds\n"); + return 0x0; + } + + if (get_virtual_eeprom_size() == 0) { + return buffer[offset]; + } + + if (eeprom_is_busy()) { + eeprom_printf("eeprom_write_byte:: timeout\n"); + return 0x0; + } + + return SmartEEPROM8[offset]; } void eeprom_write_byte(uint8_t *addr, uint8_t value) { uintptr_t offset = (uintptr_t)addr; - buffer[offset] = value; + if (offset >= MAX(EEPROM_SIZE, get_virtual_eeprom_size())) { + eeprom_printf("eeprom_write_byte:: out of bounds\n"); + return; + } + + if (get_virtual_eeprom_size() == 0) { + buffer[offset] = value; + return; + } + + if (eeprom_is_busy()) { + eeprom_printf("eeprom_write_byte:: timeout\n"); + return; + } + + SmartEEPROM8[offset] = value; } uint16_t eeprom_read_word(const uint16_t *addr) { diff --git a/tmk_core/common/arm_atsam/gpio.h b/tmk_core/common/arm_atsam/gpio.h index c2d5a30889..915ed0ef4f 100644 --- a/tmk_core/common/arm_atsam/gpio.h +++ b/tmk_core/common/arm_atsam/gpio.h @@ -64,7 +64,13 @@ typedef uint8_t pin_t; PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define writePin(pin, level) ((level) ? (writePinHigh(pin)) : (writePinLow(pin))) +#define writePin(pin, level) \ + do { \ + if (level) \ + PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \ + else \ + PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ + } while (0) #define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0) diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 690d7f38ca..b614746e6c 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c @@ -16,25 +16,6 @@ # include "vusb.h" #endif -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#ifdef AUDIO_ENABLE -# include "audio.h" -#endif /* AUDIO_ENABLE */ - -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -# 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 @@ -50,17 +31,6 @@ void suspend_idle(uint8_t time) { // TODO: This needs some cleanup -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_user(void) {} -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } - #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) // clang-format off @@ -135,41 +105,9 @@ void suspend_power_down(void) { if (!vusb_suspended) return; #endif - suspend_power_down_kb(); + suspend_power_down_quantum(); #ifndef NO_SUSPEND_POWER_DOWN - // Turn off backlight -# ifdef BACKLIGHT_ENABLE - backlight_set(0); -# endif - - // Turn off LED indicators - uint8_t leds_off = 0; -# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) - if (is_backlight_enabled()) { - // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off - leds_off |= (1 << USB_LED_CAPS_LOCK); - } -# endif - led_set(leds_off); - - // Turn off audio -# ifdef AUDIO_ENABLE - stop_all_notes(); -# endif - - // Turn off underglow -# 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 - // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt) # if defined(WDT_vect) power_down(WDTO_15MS); @@ -189,18 +127,6 @@ bool suspend_wakeup_condition(void) { return false; } -/** \brief run user level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_user(void) {} - -/** \brief run keyboard level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } - /** \brief run immediately after wakeup * * FIXME: needs doc @@ -209,27 +135,7 @@ void suspend_wakeup_init(void) { // clear keyboard state clear_keyboard(); - // Turn on backlight -#ifdef BACKLIGHT_ENABLE - backlight_init(); -#endif - - // Restore LED indicators - led_set(host_keyboard_leds()); - - // Wake up underglow -#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(); + suspend_wakeup_init_quantum(); } #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) diff --git a/tmk_core/common/chibios/_wait.h b/tmk_core/common/chibios/_wait.h index b740afbd24..2f36c64a2e 100644 --- a/tmk_core/common/chibios/_wait.h +++ b/tmk_core/common/chibios/_wait.h @@ -43,8 +43,6 @@ void wait_us(uint16_t duration); #include "_wait.c" -#define CPU_CLOCK STM32_SYSCLK - /* 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. diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c index f9514ee5f3..5cadadeeeb 100644 --- a/tmk_core/common/chibios/bootloader.c +++ b/tmk_core/common/chibios/bootloader.c @@ -95,6 +95,28 @@ void enter_bootloader_mode_if_requested(void) { } } +#elif defined(GD32VF103) + +# define DBGMCU_KEY_UNLOCK 0x4B5A6978 +# define DBGMCU_CMD_RESET 0x1 + +__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU; +__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U; + +__attribute__((weak)) void bootloader_jump(void) { + /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST + * register to generate a software reset request. + * BUT instead two undocumented registers in the debug peripheral + * that allow issueing a software reset. WHO would need the MSFRST + * register anyway? Source: + * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */ + *DBGMCU_KEY = DBGMCU_KEY_UNLOCK; + *DBGMCU_CMD = DBGMCU_CMD_RESET; +} + +void enter_bootloader_mode_if_requested(void) { /* Jumping to bootloader is not possible from user code. */ +} + #elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS /* Kinetis */ diff --git a/tmk_core/common/chibios/chibios_config.h b/tmk_core/common/chibios/chibios_config.h index 23c65f9428..ad2f808a95 100644 --- a/tmk_core/common/chibios/chibios_config.h +++ b/tmk_core/common/chibios/chibios_config.h @@ -19,22 +19,60 @@ # define SPLIT_USB_DETECT // Force this on when dedicated pin is not used #endif -#if defined(STM32F1XX) -# define USE_GPIOV1 +// STM32 compatibility +#if defined(MCU_STM32) +# define CPU_CLOCK STM32_SYSCLK + +# if defined(STM32F1XX) +# define USE_GPIOV1 +# define PAL_MODE_ALTERNATE_OPENDRAIN PAL_MODE_STM32_ALTERNATE_OPENDRAIN +# define PAL_MODE_ALTERNATE_PUSHPULL PAL_MODE_STM32_ALTERNATE_PUSHPULL +# else +# define PAL_OUTPUT_TYPE_OPENDRAIN PAL_STM32_OTYPE_OPENDRAIN +# define PAL_OUTPUT_TYPE_PUSHPULL PAL_STM32_OTYPE_PUSHPULL +# define PAL_OUTPUT_SPEED_HIGHEST PAL_STM32_OSPEED_HIGHEST +# define PAL_PUPDR_FLOATING PAL_STM32_PUPDR_FLOATING +# endif + +# if defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32L1XX) +# define USE_I2CV1 +# endif +#endif + +// GD32 compatibility +#if defined(MCU_GD32V) +# define CPU_CLOCK GD32_SYSCLK + +# if defined(GD32VF103) +# define USE_GPIOV1 +# define USE_I2CV1 +# define PAL_MODE_ALTERNATE_OPENDRAIN PAL_MODE_GD32_ALTERNATE_OPENDRAIN +# define PAL_MODE_ALTERNATE_PUSHPULL PAL_MODE_GD32_ALTERNATE_PUSHPULL +# endif #endif -#if defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32L1XX) -# define USE_I2CV1 +#if defined(GD32VF103) +/* This chip has the same API as STM32F103, but uses different names for literally the same thing. + * As of 4.7.2021 QMK is tailored to use STM32 defines/names, for compatibility sake + * we just redefine the GD32 names. */ +# include "gd32v_compatibility.h" #endif -// teensy -#if defined(K20x) || defined(KL2x) -# 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 +// teensy compatibility +#if defined(MCU_KINETIS) +# define CPU_CLOCK KINETIS_SYSCLK_FREQUENCY + +# if defined(K20x) || defined(KL2x) +# define USE_I2CV1 +# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed +# define USE_GPIOV1 +# endif #endif -#if defined(MK66F18) -# define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY +#if defined(HT32) +# define CPU_CLOCK HT32_CK_SYS_FREQUENCY +# define PAL_MODE_ALTERNATE PAL_HT32_MODE_AF +# define PAL_OUTPUT_TYPE_OPENDRAIN (PAL_HT32_MODE_OD | PAL_HT32_MODE_DIR) +# define PAL_OUTPUT_TYPE_PUSHPULL PAL_HT32_MODE_DIR +# define PAL_OUTPUT_SPEED_HIGHEST 0 #endif diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c index 1fdf8c1e29..acc6a48516 100644 --- a/tmk_core/common/chibios/eeprom_stm32.c +++ b/tmk_core/common/chibios/eeprom_stm32.c @@ -620,48 +620,11 @@ uint16_t EEPROM_ReadDataWord(uint16_t Address) { } /***************************************************************************** - * Wrap library in AVR style functions. + * Bind to eeprom_driver.c *******************************************************************************/ -uint8_t eeprom_read_byte(const uint8_t *Address) { return EEPROM_ReadDataByte((const uintptr_t)Address); } +void eeprom_driver_init(void) { EEPROM_Init(); } -void eeprom_write_byte(uint8_t *Address, uint8_t Value) { EEPROM_WriteDataByte((uintptr_t)Address, Value); } - -void eeprom_update_byte(uint8_t *Address, uint8_t Value) { EEPROM_WriteDataByte((uintptr_t)Address, Value); } - -uint16_t eeprom_read_word(const uint16_t *Address) { return EEPROM_ReadDataWord((const uintptr_t)Address); } - -void eeprom_write_word(uint16_t *Address, uint16_t Value) { EEPROM_WriteDataWord((uintptr_t)Address, Value); } - -void eeprom_update_word(uint16_t *Address, uint16_t Value) { EEPROM_WriteDataWord((uintptr_t)Address, Value); } - -uint32_t eeprom_read_dword(const uint32_t *Address) { - const uint16_t p = (const uintptr_t)Address; - /* Check word alignment */ - if (p % 2) { - /* Not aligned */ - return (uint32_t)EEPROM_ReadDataByte(p) | (uint32_t)(EEPROM_ReadDataWord(p + 1) << 8) | (uint32_t)(EEPROM_ReadDataByte(p + 3) << 24); - } else { - /* Aligned */ - return EEPROM_ReadDataWord(p) | (EEPROM_ReadDataWord(p + 2) << 16); - } -} - -void eeprom_write_dword(uint32_t *Address, uint32_t Value) { - uint16_t p = (const uintptr_t)Address; - /* Check word alignment */ - if (p % 2) { - /* Not aligned */ - EEPROM_WriteDataByte(p, (uint8_t)Value); - EEPROM_WriteDataWord(p + 1, (uint16_t)(Value >> 8)); - EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24)); - } else { - /* Aligned */ - EEPROM_WriteDataWord(p, (uint16_t)Value); - EEPROM_WriteDataWord(p + 2, (uint16_t)(Value >> 16)); - } -} - -void eeprom_update_dword(uint32_t *Address, uint32_t Value) { eeprom_write_dword(Address, Value); } +void eeprom_driver_erase(void) { EEPROM_Erase(); } void eeprom_read_block(void *buf, const void *addr, size_t len) { const uint8_t *src = (const uint8_t *)addr; @@ -670,14 +633,14 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) { /* Check word alignment */ if (len && (uintptr_t)src % 2) { /* Read the unaligned first byte */ - *dest++ = eeprom_read_byte(src++); + *dest++ = EEPROM_ReadDataByte((const uintptr_t)src++); --len; } uint16_t value; bool aligned = ((uintptr_t)dest % 2 == 0); while (len > 1) { - value = eeprom_read_word((uint16_t *)src); + value = EEPROM_ReadDataWord((const uintptr_t)((uint16_t *)src)); if (aligned) { *(uint16_t *)dest = value; dest += 2; @@ -689,7 +652,7 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) { len -= 2; } if (len) { - *dest = eeprom_read_byte(src); + *dest = EEPROM_ReadDataByte((const uintptr_t)src); } } @@ -700,7 +663,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) { /* Check word alignment */ if (len && (uintptr_t)dest % 2) { /* Write the unaligned first byte */ - eeprom_write_byte(dest++, *src++); + EEPROM_WriteDataByte((uintptr_t)dest++, *src++); --len; } @@ -712,15 +675,13 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) { } else { value = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8); } - eeprom_write_word((uint16_t *)dest, value); + EEPROM_WriteDataWord((uintptr_t)((uint16_t *)dest), value); dest += 2; src += 2; len -= 2; } if (len) { - eeprom_write_byte(dest, *src); + EEPROM_WriteDataByte((uintptr_t)dest, *src); } } - -void eeprom_update_block(const void *buf, void *addr, size_t len) { eeprom_write_block(buf, addr, len); } diff --git a/tmk_core/common/chibios/eeprom_stm32_defs.h b/tmk_core/common/chibios/eeprom_stm32_defs.h index 22b4ab858e..66904f247f 100644 --- a/tmk_core/common/chibios/eeprom_stm32_defs.h +++ b/tmk_core/common/chibios/eeprom_stm32_defs.h @@ -18,7 +18,7 @@ #include <hal.h> #if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) -# if defined(STM32F103xB) || defined(STM32F042x6) +# if defined(STM32F103xB) || defined(STM32F042x6) || defined(GD32VF103C8) || defined(GD32VF103CB) # ifndef FEE_PAGE_SIZE # define FEE_PAGE_SIZE 0x400 // Page size = 1KByte # endif @@ -32,25 +32,38 @@ # ifndef FEE_PAGE_COUNT # define FEE_PAGE_COUNT 4 // How many pages are used # endif +# elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) +# ifndef FEE_PAGE_SIZE +# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte +# endif +# ifndef FEE_PAGE_COUNT +# define FEE_PAGE_COUNT 1 // How many pages are used +# endif # endif #endif #if !defined(FEE_MCU_FLASH_SIZE) # if defined(STM32F042x6) # define FEE_MCU_FLASH_SIZE 32 // Size in Kb -# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) +# elif defined(GD32VF103C8) +# define FEE_MCU_FLASH_SIZE 64 // Size in Kb +# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) || defined(GD32VF103CB) # define FEE_MCU_FLASH_SIZE 128 // Size in Kb -# elif defined(STM32F303xC) +# elif defined(STM32F303xC) || defined(STM32F401xC) # define FEE_MCU_FLASH_SIZE 256 // Size in Kb -# elif defined(STM32F103xE) +# elif defined(STM32F103xE) || defined(STM32F401xE) || defined(STM32F411xE) # define FEE_MCU_FLASH_SIZE 512 // Size in Kb +# elif defined(STM32F405xG) +# define FEE_MCU_FLASH_SIZE 1024 // Size in Kb # endif #endif /* Start of the emulated eeprom */ #if !defined(FEE_PAGE_BASE_ADDRESS) -# if 0 -/* TODO: Add support for F4 */ +# if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) +# ifndef FEE_PAGE_BASE_ADDRESS +# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page +# endif # else # ifndef FEE_FLASH_BASE # define FEE_FLASH_BASE 0x8000000 diff --git a/tmk_core/common/chibios/eeprom_teensy.c b/tmk_core/common/chibios/eeprom_teensy.c index 4aaf665269..97da6f9e14 100644 --- a/tmk_core/common/chibios/eeprom_teensy.c +++ b/tmk_core/common/chibios/eeprom_teensy.c @@ -39,7 +39,126 @@ * SOFTWARE. */ -#if defined(K20x) /* chip selection */ +#define SMC_PMSTAT_RUN ((uint8_t)0x01) +#define SMC_PMSTAT_HSRUN ((uint8_t)0x80) + +#define F_CPU KINETIS_SYSCLK_FREQUENCY + +static inline int kinetis_hsrun_disable(void) { +#if defined(MK66F18) + if (SMC->PMSTAT == SMC_PMSTAT_HSRUN) { +// First, reduce the CPU clock speed, but do not change +// the peripheral speed (F_BUS). Serial1 & Serial2 baud +// rates will be impacted, but most other peripherals +// will continue functioning at the same speed. +# if F_CPU == 256000000 && F_BUS == 64000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // TODO: TEST +# elif F_CPU == 256000000 && F_BUS == 128000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // TODO: TEST +# elif F_CPU == 240000000 && F_BUS == 60000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // ok +# elif F_CPU == 240000000 && F_BUS == 80000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok +# elif F_CPU == 240000000 && F_BUS == 120000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok +# elif F_CPU == 216000000 && F_BUS == 54000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // ok +# elif F_CPU == 216000000 && F_BUS == 72000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok +# elif F_CPU == 216000000 && F_BUS == 108000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok +# elif F_CPU == 192000000 && F_BUS == 48000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // ok +# elif F_CPU == 192000000 && F_BUS == 64000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok +# elif F_CPU == 192000000 && F_BUS == 96000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok +# elif F_CPU == 180000000 && F_BUS == 60000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok +# elif F_CPU == 180000000 && F_BUS == 90000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok +# elif F_CPU == 168000000 && F_BUS == 56000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 5); // ok +# elif F_CPU == 144000000 && F_BUS == 48000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 5); // ok +# elif F_CPU == 144000000 && F_BUS == 72000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 5); // ok +# elif F_CPU == 120000000 && F_BUS == 60000000 + SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1 - 1) | SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2 - 1) | +# if defined(MK66F18) + SIM_CLKDIV1_OUTDIV3(KINETIS_CLKDIV1_OUTDIV3 - 1) | +# endif + SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4 - 1); +# else + return 0; +# endif + // Then turn off HSRUN mode + SMC->PMCTRL = SMC_PMCTRL_RUNM_SET(0); + while (SMC->PMSTAT == SMC_PMSTAT_HSRUN) + ; // wait + return 1; + } +#endif + return 0; +} + +static inline int kinetis_hsrun_enable(void) { +#if defined(MK66F18) + if (SMC->PMSTAT == SMC_PMSTAT_RUN) { + // Turn HSRUN mode on + SMC->PMCTRL = SMC_PMCTRL_RUNM_SET(3); + while (SMC->PMSTAT != SMC_PMSTAT_HSRUN) { + ; + } // wait +// Then configure clock for full speed +# if F_CPU == 256000000 && F_BUS == 64000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7); +# elif F_CPU == 256000000 && F_BUS == 128000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 7); +# elif F_CPU == 240000000 && F_BUS == 60000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7); +# elif F_CPU == 240000000 && F_BUS == 80000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 7); +# elif F_CPU == 240000000 && F_BUS == 120000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 7); +# elif F_CPU == 216000000 && F_BUS == 54000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7); +# elif F_CPU == 216000000 && F_BUS == 72000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 7); +# elif F_CPU == 216000000 && F_BUS == 108000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 7); +# elif F_CPU == 192000000 && F_BUS == 48000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 6); +# elif F_CPU == 192000000 && F_BUS == 64000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 6); +# elif F_CPU == 192000000 && F_BUS == 96000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 6); +# elif F_CPU == 180000000 && F_BUS == 60000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 6); +# elif F_CPU == 180000000 && F_BUS == 90000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 6); +# elif F_CPU == 168000000 && F_BUS == 56000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 5); +# elif F_CPU == 144000000 && F_BUS == 48000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 4); +# elif F_CPU == 144000000 && F_BUS == 72000000 + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 4); +# elif F_CPU == 120000000 && F_BUS == 60000000 + SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1 - 1) | SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2 - 1) | +# if defined(MK66F18) + SIM_CLKDIV1_OUTDIV3(KINETIS_CLKDIV1_OUTDIV3 - 1) | +# endif + SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4 - 1); +# else + return 0; +# endif + return 1; + } +#endif + return 0; +} + +#if defined(K20x) || defined(MK66F18) /* chip selection */ /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ // The EEPROM is really RAM with a hardware-based backup system to @@ -69,22 +188,34 @@ // # define HANDLE_UNALIGNED_WRITES +# if defined(K20x) +# define EEPROM_MAX 2048 +# define EEPARTITION 0x03 // all 32K dataflash for EEPROM, none for Data +# define EEESPLIT 0x30 // must be 0x30 on these chips +# elif defined(MK66F18) +# define EEPROM_MAX 4096 +# define EEPARTITION 0x05 // 128K dataflash for EEPROM, 128K for Data +# define EEESPLIT 0x10 // best endurance: 0x00 = first 12%, 0x10 = first 25%, 0x30 = all equal +# endif + // Minimum EEPROM Endurance // ------------------------ -# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word -# define EEESIZE 0x33 +# if (EEPROM_SIZE == 4096) +# define EEESIZE 0x02 +# elif (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word +# define EEESIZE 0x03 # elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word -# define EEESIZE 0x34 +# define EEESIZE 0x04 # elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word -# define EEESIZE 0x35 +# define EEESIZE 0x05 # elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word -# define EEESIZE 0x36 +# define EEESIZE 0x06 # elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word -# define EEESIZE 0x37 +# define EEESIZE 0x07 # elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word -# define EEESIZE 0x38 +# define EEESIZE 0x08 # elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word -# define EEESIZE 0x39 +# define EEESIZE 0x09 # endif /** \brief eeprom initialization @@ -97,15 +228,21 @@ void eeprom_initialize(void) { uint8_t status; if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; + // FlexRAM is configured as traditional RAM // We need to reconfigure for EEPROM usage - FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command - FTFL->FCCOB4 = EEESIZE; // EEPROM Size - FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup + kinetis_hsrun_disable(); + FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command + FTFL->FCCOB3 = 0; + FTFL->FCCOB4 = EEESPLIT | EEESIZE; + FTFL->FCCOB5 = EEPARTITION; __disable_irq(); // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); __enable_irq(); + kinetis_hsrun_enable(); status = FTFL->FSTAT; if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) { FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)); @@ -114,11 +251,11 @@ void eeprom_initialize(void) { } // wait for eeprom to become ready (is this really necessary?) while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { - if (++count > 20000) break; + if (++count > 200000) break; } } -# define FlexRAM ((uint8_t *)0x14000000) +# define FlexRAM ((volatile uint8_t *)0x14000000) /** \brief eeprom read byte * @@ -195,8 +332,12 @@ void eeprom_write_byte(uint8_t *addr, uint8_t value) { if (offset >= EEPROM_SIZE) return; if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); if (FlexRAM[offset] != value) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; FlexRAM[offset] = value; flexram_wait(); + kinetis_hsrun_enable(); } } @@ -213,18 +354,30 @@ void eeprom_write_word(uint16_t *addr, uint16_t value) { if ((offset & 1) == 0) { # endif if (*(uint16_t *)(&FlexRAM[offset]) != value) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint16_t *)(&FlexRAM[offset]) = value; flexram_wait(); + kinetis_hsrun_enable(); } # ifdef HANDLE_UNALIGNED_WRITES } else { if (FlexRAM[offset] != value) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; FlexRAM[offset] = value; flexram_wait(); + kinetis_hsrun_enable(); } if (FlexRAM[offset + 1] != (value >> 8)) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; FlexRAM[offset + 1] = value >> 8; flexram_wait(); + kinetis_hsrun_enable(); } } # endif @@ -244,33 +397,57 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) { case 0: # endif if (*(uint32_t *)(&FlexRAM[offset]) != value) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint32_t *)(&FlexRAM[offset]) = value; flexram_wait(); + kinetis_hsrun_enable(); } return; # ifdef HANDLE_UNALIGNED_WRITES case 2: if (*(uint16_t *)(&FlexRAM[offset]) != value) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint16_t *)(&FlexRAM[offset]) = value; flexram_wait(); + kinetis_hsrun_enable(); } if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; flexram_wait(); + kinetis_hsrun_enable(); } return; default: if (FlexRAM[offset] != value) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; FlexRAM[offset] = value; flexram_wait(); + kinetis_hsrun_enable(); } if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; flexram_wait(); + kinetis_hsrun_enable(); } if (FlexRAM[offset + 3] != (value >> 24)) { + kinetis_hsrun_disable(); + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; FlexRAM[offset + 3] = value >> 24; flexram_wait(); + kinetis_hsrun_enable(); } } # endif @@ -288,6 +465,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); if (len >= EEPROM_SIZE) len = EEPROM_SIZE; if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; + kinetis_hsrun_disable(); while (len > 0) { uint32_t lsb = offset & 3; if (lsb == 0 && len >= 4) { @@ -298,6 +476,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { val32 |= (*src++ << 16); val32 |= (*src++ << 24); if (*(uint32_t *)(&FlexRAM[offset]) != val32) { + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint32_t *)(&FlexRAM[offset]) = val32; flexram_wait(); } @@ -309,6 +489,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { val16 = *src++; val16 |= (*src++ << 8); if (*(uint16_t *)(&FlexRAM[offset]) != val16) { + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; *(uint16_t *)(&FlexRAM[offset]) = val16; flexram_wait(); } @@ -318,6 +500,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { // write 8 bits uint8_t val8 = *src++; if (FlexRAM[offset] != val8) { + uint8_t stat = FTFL->FSTAT & 0x70; + if (stat) FTFL->FSTAT = stat; FlexRAM[offset] = val8; flexram_wait(); } @@ -325,6 +509,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { len--; } } + kinetis_hsrun_enable(); } /* diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index 6b80ff71c3..72c41b8b78 100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c @@ -19,10 +19,38 @@ #include <hal.h> #include "flash_stm32.h" -#if defined(EEPROM_EMU_STM32F103xB) +#if defined(STM32F1XX) # define FLASH_SR_WRPERR FLASH_SR_WRPRTERR #endif +#if defined(MCU_GD32V) +/* GigaDevice GD32VF103 is a STM32F103 clone at heart. */ +# include "gd32v_compatibility.h" +#endif + +#if defined(STM32F4XX) +# define FLASH_SR_PGERR (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR) + +# define FLASH_KEY1 0x45670123U +# define FLASH_KEY2 0xCDEF89ABU + +static uint8_t ADDR2PAGE(uint32_t Page_Address) { + switch (Page_Address) { + case 0x08000000 ... 0x08003FFF: + return 0; + case 0x08004000 ... 0x08007FFF: + return 1; + case 0x08008000 ... 0x0800BFFF: + return 2; + case 0x0800C000 ... 0x0800FFFF: + return 3; + } + + // TODO: bad times... + return 7; +} +#endif + /* Delay definition */ #define EraseTimeout ((uint32_t)0x00000FFF) #define ProgramTimeout ((uint32_t)0x0000001F) @@ -53,7 +81,9 @@ FLASH_Status FLASH_GetStatus(void) { if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; +#if defined(FLASH_OBR_OPTERR) if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; +#endif return FLASH_COMPLETE; } @@ -95,15 +125,24 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the page */ +#if defined(FLASH_CR_SNB) + FLASH->CR &= ~FLASH_CR_SNB; + FLASH->CR |= FLASH_CR_SER | (ADDR2PAGE(Page_Address) << FLASH_CR_SNB_Pos); +#else FLASH->CR |= FLASH_CR_PER; FLASH->AR = Page_Address; +#endif FLASH->CR |= FLASH_CR_STRT; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(EraseTimeout); if (status != FLASH_TIMEOUT) { - /* if the erase operation is completed, disable the PER Bit */ + /* if the erase operation is completed, disable the configured Bits */ +#if defined(FLASH_CR_SNB) + FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB); +#else FLASH->CR &= ~FLASH_CR_PER; +#endif } FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); } @@ -126,6 +165,11 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { status = FLASH_WaitForLastOperation(ProgramTimeout); if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ + +#if defined(FLASH_CR_PSIZE) + FLASH->CR &= ~FLASH_CR_PSIZE; + FLASH->CR |= FLASH_CR_PSIZE_0; +#endif FLASH->CR |= FLASH_CR_PG; *(__IO uint16_t*)Address = Data; /* Wait for last operation to be completed */ diff --git a/tmk_core/common/chibios/gd32v_compatibility.h b/tmk_core/common/chibios/gd32v_compatibility.h new file mode 100644 index 0000000000..f4dcfd8c55 --- /dev/null +++ b/tmk_core/common/chibios/gd32v_compatibility.h @@ -0,0 +1,120 @@ +/* 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 2 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 + +/* GD32VF103 has the same API as STM32F103, but uses different names for literally the same thing. + * As of 23.7.2021 QMK is tailored to use STM32 defines/names, for compatibility sake + * we just redefine the GD32 names. */ + +/* Close your eyes kids. */ +#define MCU_STM32 + +/* AFIO redefines */ +#define MAPR PCF0 +#define AFIO_MAPR_USART1_REMAP AFIO_PCF0_USART0_REMAP +#define AFIO_MAPR_USART2_REMAP AFIO_PCF0_USART1_REMAP +#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP AFIO_PCF0_USART2_REMAP_PARTIALREMAP +#define AFIO_MAPR_USART3_REMAP_FULLREMAP AFIO_PCF0_USART2_REMAP_FULLREMAP + +/* DMA redefines. */ +#define STM32_DMA_STREAM(stream) GD32_DMA_STREAM(stream) +#define STM32_DMA_STREAM_ID(peripheral, channel) GD32_DMA_STREAM_ID(peripheral - 1, channel - 1) +#define STM32_DMA_CR_DIR_M2P GD32_DMA_CTL_DIR_M2P +#define STM32_DMA_CR_PSIZE_WORD GD32_DMA_CTL_PWIDTH_WORD +#define STM32_DMA_CR_MSIZE_WORD GD32_DMA_CTL_MWIDTH_WORD +#define STM32_DMA_CR_MINC GD32_DMA_CTL_MNAGA +#define STM32_DMA_CR_CIRC GD32_DMA_CTL_CMEN +#define STM32_DMA_CR_PL GD32_DMA_CTL_PRIO +#define STM32_DMA_CR_CHSEL GD32_DMA_CTL_CHSEL +#define cr1 ctl0 +#define cr2 ctl1 +#define cr3 ctl2 +#define dier dmainten + +/* ADC redefines */ +#if HAL_USE_ADC +# define STM32_ADC_USE_ADC1 GD32_ADC_USE_ADC0 + +# define smpr1 sampt0 +# define smpr2 sampt1 +# define sqr1 rsq0 +# define sqr2 rsq1 +# define sqr3 rsq2 + +# define ADC_SMPR2_SMP_AN0 ADC_SAMPT1_SMP_SPT0 +# define ADC_SMPR2_SMP_AN1 ADC_SAMPT1_SMP_SPT1 +# define ADC_SMPR2_SMP_AN2 ADC_SAMPT1_SMP_SPT2 +# define ADC_SMPR2_SMP_AN3 ADC_SAMPT1_SMP_SPT3 +# define ADC_SMPR2_SMP_AN4 ADC_SAMPT1_SMP_SPT4 +# define ADC_SMPR2_SMP_AN5 ADC_SAMPT1_SMP_SPT5 +# define ADC_SMPR2_SMP_AN6 ADC_SAMPT1_SMP_SPT6 +# define ADC_SMPR2_SMP_AN7 ADC_SAMPT1_SMP_SPT7 +# define ADC_SMPR2_SMP_AN8 ADC_SAMPT1_SMP_SPT8 +# define ADC_SMPR2_SMP_AN9 ADC_SAMPT1_SMP_SPT9 + +# define ADC_SMPR1_SMP_AN10 ADC_SAMPT0_SMP_SPT10 +# define ADC_SMPR1_SMP_AN11 ADC_SAMPT0_SMP_SPT11 +# define ADC_SMPR1_SMP_AN12 ADC_SAMPT0_SMP_SPT12 +# define ADC_SMPR1_SMP_AN13 ADC_SAMPT0_SMP_SPT13 +# define ADC_SMPR1_SMP_AN14 ADC_SAMPT0_SMP_SPT14 +# define ADC_SMPR1_SMP_AN15 ADC_SAMPT0_SMP_SPT15 + +# define ADC_SQR3_SQ1_N ADC_RSQ2_RSQ1_N +#endif + +/* FLASH redefines */ +#if defined(EEPROM_ENABLE) +# define SR STAT +# define FLASH_SR_BSY FLASH_STAT_BUSY +# define FLASH_SR_PGERR FLASH_STAT_PGERR +# define FLASH_SR_EOP FLASH_STAT_ENDF +# define FLASH_SR_WRPRTERR FLASH_STAT_WPERR +# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR +# define FLASH_OBR_OPTERR FLASH_OBSTAT_OBERR +# define AR ADDR +# define CR CTL +# define FLASH_CR_PER FLASH_CTL_PER +# define FLASH_CR_STRT FLASH_CTL_START +# define FLASH_CR_LOCK FLASH_CTL_LK +# define FLASH_CR_PG FLASH_CTL_PG +# define KEYR KEY +#endif + +/* Serial USART redefines. */ +#if HAL_USE_SERIAL +# if !defined(SERIAL_USART_CR1) +# define SERIAL_USART_CR1 (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL) // parity enable, odd parity, 9 bit length +# endif +# if !defined(SERIAL_USART_CR2) +# define SERIAL_USART_CR2 (USART_CTL1_STB_1) // 2 stop bits +# endif +# if !defined(SERIAL_USART_CR3) +# define SERIAL_USART_CR3 0x0 +# endif +# define USART_CR3_HDSEL USART_CTL2_HDEN +# define CCR CHCV +#endif + +/* SPI redefines. */ +#if HAL_USE_SPI +# define SPI_CR1_LSBFIRST SPI_CTL0_LF +# define SPI_CR1_CPHA SPI_CTL0_CKPH +# define SPI_CR1_CPOL SPI_CTL0_CKPL +# define SPI_CR1_BR_0 SPI_CTL0_PSC_0 +# define SPI_CR1_BR_1 SPI_CTL0_PSC_1 +# define SPI_CR1_BR_2 SPI_CTL0_PSC_2 +#endif diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c index 1c65016a42..477056a454 100644 --- a/tmk_core/common/chibios/sleep_led.c +++ b/tmk_core/common/chibios/sleep_led.c @@ -65,7 +65,7 @@ void sleep_led_timer_callback(void) { /* LPTMR clock options */ # define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */ -# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ +# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */ # define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */ # define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */ @@ -121,7 +121,7 @@ void sleep_led_init(void) { MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock # if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; -# endif /* KL27 */ +# endif /* KL27 */ MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock // to work in stop mode, also MCG_C1_IREFSTEN // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c index 38517e06f0..9310a99920 100644 --- a/tmk_core/common/chibios/suspend.c +++ b/tmk_core/common/chibios/suspend.c @@ -7,30 +7,12 @@ #include "action.h" #include "action_util.h" #include "mousekey.h" +#include "programmable_button.h" #include "host.h" #include "suspend.h" #include "led.h" #include "wait.h" -#ifdef AUDIO_ENABLE -# include "audio.h" -#endif /* AUDIO_ENABLE */ - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) -# 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 @@ -40,61 +22,12 @@ void suspend_idle(uint8_t time) { wait_ms(time); } -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_user(void) {} -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } - /** \brief suspend power down * * FIXME: needs doc */ void suspend_power_down(void) { -#ifdef BACKLIGHT_ENABLE - 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) - if (is_backlight_enabled()) { - // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off - leds_off |= (1 << USB_LED_CAPS_LOCK); - } -#endif - led_set(leds_off); - - // TODO: figure out what to power down and how - // shouldn't power down TPM/FTM if we want a breathing LED - // also shouldn't power down USB -#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 */ - - suspend_power_down_kb(); + suspend_power_down_quantum(); // on AVR, this enables the watchdog for 15ms (max), and goes to // SLEEP_MODE_PWR_DOWN @@ -147,23 +80,13 @@ void suspend_wakeup_init(void) { #ifdef MOUSEKEY_ENABLE mousekey_clear(); #endif /* MOUSEKEY_ENABLE */ +#ifdef PROGRAMMABLE_BUTTON_ENABLE + programmable_button_clear(); +#endif /* PROGRAMMABLE_BUTTON_ENABLE */ #ifdef EXTRAKEY_ENABLE host_system_send(0); host_consumer_send(0); #endif /* EXTRAKEY_ENABLE */ -#ifdef BACKLIGHT_ENABLE - backlight_init(); -#endif /* BACKLIGHT_ENABLE */ - led_set(host_keyboard_leds()); -#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(); + suspend_wakeup_init_quantum(); } diff --git a/tmk_core/common/chibios/syscall-fallbacks.c b/tmk_core/common/chibios/syscall-fallbacks.c index 739017ae1d..4569879c7c 100644 --- a/tmk_core/common/chibios/syscall-fallbacks.c +++ b/tmk_core/common/chibios/syscall-fallbacks.c @@ -18,6 +18,12 @@ #include <sys/stat.h> #include <sys/types.h> +/* To compile the ChibiOS syscall stubs with picolibc + * the _reent struct has to be defined. */ +#if defined(USE_PICOLIBC) +struct _reent; +#endif + #pragma GCC diagnostic ignored "-Wmissing-prototypes" __attribute__((weak, used)) int _open_r(struct _reent *r, const char *path, int flag, int m) { diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c deleted file mode 100644 index f0c396b189..0000000000 --- a/tmk_core/common/host.c +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2011,2012 Jun Wako <wakojun@gmail.com> - -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 2 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/>. -*/ - -#include <stdint.h> -//#include <avr/interrupt.h> -#include "keyboard.h" -#include "keycode.h" -#include "host.h" -#include "util.h" -#include "debug.h" -#include "digitizer.h" - -#ifdef NKRO_ENABLE -# include "keycode_config.h" -extern keymap_config_t keymap_config; -#endif - -static host_driver_t *driver; -static uint16_t last_system_report = 0; -static uint16_t last_consumer_report = 0; - -void host_set_driver(host_driver_t *d) { driver = d; } - -host_driver_t *host_get_driver(void) { return driver; } - -#ifdef SPLIT_KEYBOARD -uint8_t split_led_state = 0; -void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; } -#endif - -uint8_t host_keyboard_leds(void) { -#ifdef SPLIT_KEYBOARD - if (!is_keyboard_master()) return split_led_state; -#endif - if (!driver) return 0; - return (*driver->keyboard_leds)(); -} - -led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); } - -/* send report */ -void host_keyboard_send(report_keyboard_t *report) { - if (!driver) return; -#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP) - if (keyboard_protocol && keymap_config.nkro) { - /* The callers of this function assume that report->mods is where mods go in. - * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID. - */ - report->nkro.mods = report->mods; - report->nkro.report_id = REPORT_ID_NKRO; - } else -#endif - { -#ifdef KEYBOARD_SHARED_EP - report->report_id = REPORT_ID_KEYBOARD; -#endif - } - (*driver->send_keyboard)(report); - - if (debug_keyboard) { - dprint("keyboard_report: "); - for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { - dprintf("%02X ", report->raw[i]); - } - dprint("\n"); - } -} - -void host_mouse_send(report_mouse_t *report) { - if (!driver) return; -#ifdef MOUSE_SHARED_EP - report->report_id = REPORT_ID_MOUSE; -#endif - (*driver->send_mouse)(report); -} - -void host_system_send(uint16_t report) { - if (report == last_system_report) return; - last_system_report = report; - - if (!driver) return; - (*driver->send_system)(report); -} - -void host_consumer_send(uint16_t report) { - if (report == last_consumer_report) return; - last_consumer_report = report; - - if (!driver) return; - (*driver->send_consumer)(report); -} - -void host_digitizer_send(digitizer_t *digitizer) { - if (!driver) return; - - report_digitizer_t report = { -#ifdef DIGITIZER_SHARED_EP - .report_id = REPORT_ID_DIGITIZER, -#endif - .tip = digitizer->tipswitch & 0x1, - .inrange = digitizer->inrange & 0x1, - .x = (uint16_t)(digitizer->x * 0x7FFF), - .y = (uint16_t)(digitizer->y * 0x7FFF), - }; - - send_digitizer(&report); -} - -__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {} - -uint16_t host_last_system_report(void) { return last_system_report; } - -uint16_t host_last_consumer_report(void) { return last_consumer_report; } diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h deleted file mode 100644 index 2cffef6e15..0000000000 --- a/tmk_core/common/host.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -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 2 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 <stdint.h> -#include <stdbool.h> -#include "report.h" -#include "host_driver.h" -#include "led.h" - -#define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name))) -#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name))) - -#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name) -#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name) - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint8_t keyboard_idle; -extern uint8_t keyboard_protocol; - -/* host driver */ -void host_set_driver(host_driver_t *driver); -host_driver_t *host_get_driver(void); - -/* host driver interface */ -uint8_t host_keyboard_leds(void); -led_t host_keyboard_led_state(void); -void host_keyboard_send(report_keyboard_t *report); -void host_mouse_send(report_mouse_t *report); -void host_system_send(uint16_t data); -void host_consumer_send(uint16_t data); - -uint16_t host_last_system_report(void); -uint16_t host_last_consumer_report(void); - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h deleted file mode 100644 index 2aebca043d..0000000000 --- a/tmk_core/common/host_driver.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2011 Jun Wako <wakojun@gmail.com> - -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 2 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 <stdint.h> -#include "report.h" -#ifdef MIDI_ENABLE -# include "midi.h" -#endif - -typedef struct { - uint8_t (*keyboard_leds)(void); - void (*send_keyboard)(report_keyboard_t *); - void (*send_mouse)(report_mouse_t *); - void (*send_system)(uint16_t); - void (*send_consumer)(uint16_t); -} host_driver_t; - -void send_digitizer(report_digitizer_t *report);
\ No newline at end of file diff --git a/tmk_core/common/raw_hid.h b/tmk_core/common/raw_hid.h deleted file mode 100644 index 6d60ab2bff..0000000000 --- a/tmk_core/common/raw_hid.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -void raw_hid_receive(uint8_t *data, uint8_t length); - -void raw_hid_send(uint8_t *data, uint8_t length); diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c deleted file mode 100644 index 2a7fc006c4..0000000000 --- a/tmk_core/common/report.c +++ /dev/null @@ -1,280 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * 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 2 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/>. - */ - -#include "report.h" -#include "host.h" -#include "keycode_config.h" -#include "debug.h" -#include "util.h" -#include <string.h> - -#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE -# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS) -# define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS) -# define RO_INC(a) RO_ADD(a, 1) -# define RO_DEC(a) RO_SUB(a, 1) -static int8_t cb_head = 0; -static int8_t cb_tail = 0; -static int8_t cb_count = 0; -#endif - -/** \brief has_anykey - * - * FIXME: Needs doc - */ -uint8_t has_anykey(report_keyboard_t* keyboard_report) { - uint8_t cnt = 0; - uint8_t* p = keyboard_report->keys; - uint8_t lp = sizeof(keyboard_report->keys); -#ifdef NKRO_ENABLE - if (keyboard_protocol && keymap_config.nkro) { - p = keyboard_report->nkro.bits; - lp = sizeof(keyboard_report->nkro.bits); - } -#endif - while (lp--) { - if (*p++) cnt++; - } - return cnt; -} - -/** \brief get_first_key - * - * FIXME: Needs doc - */ -uint8_t get_first_key(report_keyboard_t* keyboard_report) { -#ifdef NKRO_ENABLE - if (keyboard_protocol && keymap_config.nkro) { - uint8_t i = 0; - for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) - ; - return i << 3 | biton(keyboard_report->nkro.bits[i]); - } -#endif -#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE - uint8_t i = cb_head; - do { - if (keyboard_report->keys[i] != 0) { - break; - } - i = RO_INC(i); - } while (i != cb_tail); - return keyboard_report->keys[i]; -#else - return keyboard_report->keys[0]; -#endif -} - -/** \brief Checks if a key is pressed in the report - * - * Returns true if the keyboard_report reports that the key is pressed, otherwise false - * Note: The function doesn't support modifers currently, and it returns false for KC_NO - */ -bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) { - if (key == KC_NO) { - return false; - } -#ifdef NKRO_ENABLE - if (keyboard_protocol && keymap_config.nkro) { - if ((key >> 3) < KEYBOARD_REPORT_BITS) { - return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7); - } else { - return false; - } - } -#endif - for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - if (keyboard_report->keys[i] == key) { - return true; - } - } - return false; -} - -/** \brief add key byte - * - * FIXME: Needs doc - */ -void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) { -#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE - int8_t i = cb_head; - int8_t empty = -1; - if (cb_count) { - do { - if (keyboard_report->keys[i] == code) { - return; - } - if (empty == -1 && keyboard_report->keys[i] == 0) { - empty = i; - } - i = RO_INC(i); - } while (i != cb_tail); - if (i == cb_tail) { - if (cb_tail == cb_head) { - // buffer is full - if (empty == -1) { - // pop head when has no empty space - cb_head = RO_INC(cb_head); - cb_count--; - } else { - // left shift when has empty space - uint8_t offset = 1; - i = RO_INC(empty); - do { - if (keyboard_report->keys[i] != 0) { - keyboard_report->keys[empty] = keyboard_report->keys[i]; - keyboard_report->keys[i] = 0; - empty = RO_INC(empty); - } else { - offset++; - } - i = RO_INC(i); - } while (i != cb_tail); - cb_tail = RO_SUB(cb_tail, offset); - } - } - } - } - // add to tail - keyboard_report->keys[cb_tail] = code; - cb_tail = RO_INC(cb_tail); - cb_count++; -#else - int8_t i = 0; - int8_t empty = -1; - for (; i < KEYBOARD_REPORT_KEYS; i++) { - if (keyboard_report->keys[i] == code) { - break; - } - if (empty == -1 && keyboard_report->keys[i] == 0) { - empty = i; - } - } - if (i == KEYBOARD_REPORT_KEYS) { - if (empty != -1) { - keyboard_report->keys[empty] = code; - } - } -#endif -} - -/** \brief del key byte - * - * FIXME: Needs doc - */ -void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) { -#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE - uint8_t i = cb_head; - if (cb_count) { - do { - if (keyboard_report->keys[i] == code) { - keyboard_report->keys[i] = 0; - cb_count--; - if (cb_count == 0) { - // reset head and tail - cb_tail = cb_head = 0; - } - if (i == RO_DEC(cb_tail)) { - // left shift when next to tail - do { - cb_tail = RO_DEC(cb_tail); - if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) { - break; - } - } while (cb_tail != cb_head); - } - break; - } - i = RO_INC(i); - } while (i != cb_tail); - } -#else - for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - if (keyboard_report->keys[i] == code) { - keyboard_report->keys[i] = 0; - } - } -#endif -} - -#ifdef NKRO_ENABLE -/** \brief add key bit - * - * FIXME: Needs doc - */ -void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { - if ((code >> 3) < KEYBOARD_REPORT_BITS) { - keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7); - } else { - dprintf("add_key_bit: can't add: %02X\n", code); - } -} - -/** \brief del key bit - * - * FIXME: Needs doc - */ -void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) { - if ((code >> 3) < KEYBOARD_REPORT_BITS) { - keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7)); - } else { - dprintf("del_key_bit: can't del: %02X\n", code); - } -} -#endif - -/** \brief add key to report - * - * FIXME: Needs doc - */ -void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) { -#ifdef NKRO_ENABLE - if (keyboard_protocol && keymap_config.nkro) { - add_key_bit(keyboard_report, key); - return; - } -#endif - add_key_byte(keyboard_report, key); -} - -/** \brief del key from report - * - * FIXME: Needs doc - */ -void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) { -#ifdef NKRO_ENABLE - if (keyboard_protocol && keymap_config.nkro) { - del_key_bit(keyboard_report, key); - return; - } -#endif - del_key_byte(keyboard_report, key); -} - -/** \brief clear key from report - * - * FIXME: Needs doc - */ -void clear_keys_from_report(report_keyboard_t* keyboard_report) { - // not clear mods -#ifdef NKRO_ENABLE - if (keyboard_protocol && keymap_config.nkro) { - memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits)); - return; - } -#endif - memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys)); -} diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h deleted file mode 100644 index f2223e8063..0000000000 --- a/tmk_core/common/report.h +++ /dev/null @@ -1,319 +0,0 @@ -/* -Copyright 2011,2012 Jun Wako <wakojun@gmail.com> - -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 2 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 <stdint.h> -#include <stdbool.h> -#include "keycode.h" - -// clang-format off - -/* HID report IDs */ -enum hid_report_ids { - REPORT_ID_KEYBOARD = 1, - REPORT_ID_MOUSE, - REPORT_ID_SYSTEM, - REPORT_ID_CONSUMER, - REPORT_ID_NKRO, - REPORT_ID_JOYSTICK, - REPORT_ID_DIGITIZER -}; - -/* Mouse buttons */ -#define MOUSE_BTN_MASK(n) (1 << (n)) -enum mouse_buttons { - MOUSE_BTN1 = MOUSE_BTN_MASK(0), - MOUSE_BTN2 = MOUSE_BTN_MASK(1), - MOUSE_BTN3 = MOUSE_BTN_MASK(2), - MOUSE_BTN4 = MOUSE_BTN_MASK(3), - MOUSE_BTN5 = MOUSE_BTN_MASK(4), - MOUSE_BTN6 = MOUSE_BTN_MASK(5), - MOUSE_BTN7 = MOUSE_BTN_MASK(6), - MOUSE_BTN8 = MOUSE_BTN_MASK(7) -}; - -/* Consumer Page (0x0C) - * - * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75 - */ -enum consumer_usages { - // 15.5 Display Controls - SNAPSHOT = 0x065, - BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf - BRIGHTNESS_DOWN = 0x070, - // 15.7 Transport Controls - TRANSPORT_RECORD = 0x0B2, - TRANSPORT_FAST_FORWARD = 0x0B3, - TRANSPORT_REWIND = 0x0B4, - TRANSPORT_NEXT_TRACK = 0x0B5, - TRANSPORT_PREV_TRACK = 0x0B6, - TRANSPORT_STOP = 0x0B7, - TRANSPORT_EJECT = 0x0B8, - TRANSPORT_RANDOM_PLAY = 0x0B9, - TRANSPORT_STOP_EJECT = 0x0CC, - TRANSPORT_PLAY_PAUSE = 0x0CD, - // 15.9.1 Audio Controls - Volume - AUDIO_MUTE = 0x0E2, - AUDIO_VOL_UP = 0x0E9, - AUDIO_VOL_DOWN = 0x0EA, - // 15.15 Application Launch Buttons - AL_CC_CONFIG = 0x183, - AL_EMAIL = 0x18A, - AL_CALCULATOR = 0x192, - AL_LOCAL_BROWSER = 0x194, - AL_LOCK = 0x19E, - AL_CONTROL_PANEL = 0x19F, - AL_ASSISTANT = 0x1CB, - AL_KEYBOARD_LAYOUT = 0x1AE, - // 15.16 Generic GUI Application Controls - AC_NEW = 0x201, - AC_OPEN = 0x202, - AC_CLOSE = 0x203, - AC_EXIT = 0x204, - AC_MAXIMIZE = 0x205, - AC_MINIMIZE = 0x206, - AC_SAVE = 0x207, - AC_PRINT = 0x208, - AC_PROPERTIES = 0x209, - AC_UNDO = 0x21A, - AC_COPY = 0x21B, - AC_CUT = 0x21C, - AC_PASTE = 0x21D, - AC_SELECT_ALL = 0x21E, - AC_FIND = 0x21F, - AC_SEARCH = 0x221, - AC_HOME = 0x223, - AC_BACK = 0x224, - AC_FORWARD = 0x225, - AC_STOP = 0x226, - AC_REFRESH = 0x227, - AC_BOOKMARKS = 0x22A -}; - -/* Generic Desktop Page (0x01) - * - * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26 - */ -enum desktop_usages { - // 4.5.1 System Controls - Power Controls - SYSTEM_POWER_DOWN = 0x81, - SYSTEM_SLEEP = 0x82, - SYSTEM_WAKE_UP = 0x83, - SYSTEM_RESTART = 0x8F, - // 4.10 System Display Controls - SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5 -}; - -// clang-format on - -#define NKRO_SHARED_EP -/* key report size(NKRO or boot mode) */ -#if defined(NKRO_ENABLE) -# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS) -# include "protocol/usb_descriptor.h" -# define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2) -# elif defined(PROTOCOL_ARM_ATSAM) -# include "protocol/arm_atsam/usb/udi_device_epsize.h" -# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) -# undef NKRO_SHARED_EP -# undef MOUSE_SHARED_EP -# else -# error "NKRO not supported with this protocol" -# endif -#endif - -#ifdef KEYBOARD_SHARED_EP -# define KEYBOARD_REPORT_SIZE 9 -#else -# define KEYBOARD_REPORT_SIZE 8 -#endif - -#define KEYBOARD_REPORT_KEYS 6 - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys. - * - * byte |0 |1 |2 |3 |4 |5 |6 |7 - * -----+--------+--------+--------+--------+--------+--------+--------+-------- - * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5] - * - * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode. - * - * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15 - * -----+--------+--------+--------+--------+--------+--------+--------+-------- +-------- - * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14] - * - * mods retains state of 8 modifiers. - * - * bit |0 |1 |2 |3 |4 |5 |6 |7 - * -----+--------+--------+--------+--------+--------+--------+--------+-------- - * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui - * - */ -typedef union { - uint8_t raw[KEYBOARD_REPORT_SIZE]; - struct { -#ifdef KEYBOARD_SHARED_EP - uint8_t report_id; -#endif - uint8_t mods; - uint8_t reserved; - uint8_t keys[KEYBOARD_REPORT_KEYS]; - }; -#ifdef NKRO_ENABLE - struct nkro_report { -# ifdef NKRO_SHARED_EP - uint8_t report_id; -# endif - uint8_t mods; - uint8_t bits[KEYBOARD_REPORT_BITS]; - } nkro; -#endif -} __attribute__((packed)) report_keyboard_t; - -typedef struct { - uint8_t report_id; - uint16_t usage; -} __attribute__((packed)) report_extra_t; - -typedef struct { -#ifdef MOUSE_SHARED_EP - uint8_t report_id; -#endif - uint8_t buttons; - int8_t x; - int8_t y; - int8_t v; - int8_t h; -} __attribute__((packed)) report_mouse_t; - -typedef struct { -#ifdef DIGITIZER_SHARED_EP - uint8_t report_id; -#endif - uint8_t tip : 1; - uint8_t inrange : 1; - uint8_t pad2 : 6; - uint16_t x; - uint16_t y; -} __attribute__((packed)) report_digitizer_t; - -typedef struct { -#if JOYSTICK_AXES_COUNT > 0 -# if JOYSTICK_AXES_RESOLUTION > 8 - int16_t axes[JOYSTICK_AXES_COUNT]; -# else - int8_t axes[JOYSTICK_AXES_COUNT]; -# endif -#endif - -#if JOYSTICK_BUTTON_COUNT > 0 - uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; -#endif -} __attribute__((packed)) joystick_report_t; - -/* keycode to system usage */ -static inline uint16_t KEYCODE2SYSTEM(uint8_t key) { - switch (key) { - case KC_SYSTEM_POWER: - return SYSTEM_POWER_DOWN; - case KC_SYSTEM_SLEEP: - return SYSTEM_SLEEP; - case KC_SYSTEM_WAKE: - return SYSTEM_WAKE_UP; - default: - return 0; - } -} - -/* keycode to consumer usage */ -static inline uint16_t KEYCODE2CONSUMER(uint8_t key) { - switch (key) { - case KC_AUDIO_MUTE: - return AUDIO_MUTE; - case KC_AUDIO_VOL_UP: - return AUDIO_VOL_UP; - case KC_AUDIO_VOL_DOWN: - return AUDIO_VOL_DOWN; - case KC_MEDIA_NEXT_TRACK: - return TRANSPORT_NEXT_TRACK; - case KC_MEDIA_PREV_TRACK: - return TRANSPORT_PREV_TRACK; - case KC_MEDIA_FAST_FORWARD: - return TRANSPORT_FAST_FORWARD; - case KC_MEDIA_REWIND: - return TRANSPORT_REWIND; - case KC_MEDIA_STOP: - return TRANSPORT_STOP; - case KC_MEDIA_EJECT: - return TRANSPORT_STOP_EJECT; - case KC_MEDIA_PLAY_PAUSE: - return TRANSPORT_PLAY_PAUSE; - case KC_MEDIA_SELECT: - return AL_CC_CONFIG; - case KC_MAIL: - return AL_EMAIL; - case KC_CALCULATOR: - return AL_CALCULATOR; - case KC_MY_COMPUTER: - return AL_LOCAL_BROWSER; - case KC_WWW_SEARCH: - return AC_SEARCH; - case KC_WWW_HOME: - return AC_HOME; - case KC_WWW_BACK: - return AC_BACK; - case KC_WWW_FORWARD: - return AC_FORWARD; - case KC_WWW_STOP: - return AC_STOP; - case KC_WWW_REFRESH: - return AC_REFRESH; - case KC_BRIGHTNESS_UP: - return BRIGHTNESS_UP; - case KC_BRIGHTNESS_DOWN: - return BRIGHTNESS_DOWN; - case KC_WWW_FAVORITES: - return AC_BOOKMARKS; - default: - return 0; - } -} - -uint8_t has_anykey(report_keyboard_t* keyboard_report); -uint8_t get_first_key(report_keyboard_t* keyboard_report); -bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key); - -void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code); -void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code); -#ifdef NKRO_ENABLE -void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code); -void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code); -#endif - -void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key); -void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key); -void clear_keys_from_report(report_keyboard_t* keyboard_report); - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h index 95845e4b63..081735f90e 100644 --- a/tmk_core/common/suspend.h +++ b/tmk_core/common/suspend.h @@ -10,8 +10,10 @@ void suspend_wakeup_init(void); void suspend_wakeup_init_user(void); void suspend_wakeup_init_kb(void); +void suspend_wakeup_init_quantum(void); void suspend_power_down_user(void); void suspend_power_down_kb(void); +void suspend_power_down_quantum(void); #ifndef USB_SUSPEND_WAKEUP_DELAY # define USB_SUSPEND_WAKEUP_DELAY 0 diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c deleted file mode 100644 index 68b92d8b43..0000000000 --- a/tmk_core/common/sync_timer.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -If you happen to meet one of the copyright holders in a bar you are obligated -to buy them one pint of beer. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "sync_timer.h" -#include "keyboard.h" - -#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) -volatile int32_t sync_timer_ms; - -void sync_timer_init(void) { sync_timer_ms = 0; } - -void sync_timer_update(uint32_t time) { - if (is_keyboard_master()) return; - sync_timer_ms = time - timer_read32(); -} - -uint16_t sync_timer_read(void) { - if (is_keyboard_master()) return timer_read(); - return sync_timer_read32(); -} - -uint32_t sync_timer_read32(void) { - if (is_keyboard_master()) return timer_read32(); - return sync_timer_ms + timer_read32(); -} - -uint16_t sync_timer_elapsed(uint16_t last) { - if (is_keyboard_master()) return timer_elapsed(last); - return TIMER_DIFF_16(sync_timer_read(), last); -} - -uint32_t sync_timer_elapsed32(uint32_t last) { - if (is_keyboard_master()) return timer_elapsed32(last); - return TIMER_DIFF_32(sync_timer_read32(), last); -} -#endif diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h deleted file mode 100644 index 744e2b50d5..0000000000 --- a/tmk_core/common/sync_timer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -If you happen to meet one of the copyright holders in a bar you are obligated -to buy them one pint of beer. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include <stdint.h> -#include "timer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER) -void sync_timer_init(void); -void sync_timer_update(uint32_t time); -uint16_t sync_timer_read(void); -uint32_t sync_timer_read32(void); -uint16_t sync_timer_elapsed(uint16_t last); -uint32_t sync_timer_elapsed32(uint32_t last); -#else -# define sync_timer_init() -# define sync_timer_clear() -# define sync_timer_update(t) -# define sync_timer_read() timer_read() -# define sync_timer_read32() timer_read32() -# define sync_timer_elapsed(t) timer_elapsed(t) -# define sync_timer_elapsed32(t) timer_elapsed32(t) -#endif - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/common/test/rules.mk b/tmk_core/common/test/rules.mk index 48632a095b..73d2302da7 100644 --- a/tmk_core/common/test/rules.mk +++ b/tmk_core/common/test/rules.mk @@ -16,6 +16,7 @@ eeprom_stm32_tiny_INC := $(eeprom_stm32_INC) eeprom_stm32_large_INC := $(eeprom_stm32_INC) eeprom_stm32_SRC := \ + $(TOP_DIR)/drivers/eeprom/eeprom_driver.c \ $(TMK_PATH)/common/test/eeprom_stm32_tests.cpp \ $(TMK_PATH)/common/test/flash_stm32_mock.c \ $(TMK_PATH)/common/chibios/eeprom_stm32.c diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c deleted file mode 100644 index dd1deeaa11..0000000000 --- a/tmk_core/common/usb_util.c +++ /dev/null @@ -1,29 +0,0 @@ -/* 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/>. - */ -#include "quantum.h" -#include "usb_util.h" - -__attribute__((weak)) void usb_disconnect(void) {} -__attribute__((weak)) bool usb_connected_state(void) { return true; } -__attribute__((weak)) bool usb_vbus_state(void) { -#ifdef USB_VBUS_PIN - setPinInput(USB_VBUS_PIN); - wait_us(5); - return readPin(USB_VBUS_PIN); -#else - return true; -#endif -} diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h deleted file mode 100644 index 13db9fbfbd..0000000000 --- a/tmk_core/common/usb_util.h +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 <stdbool.h> - -void usb_disconnect(void); -bool usb_connected_state(void); -bool usb_vbus_state(void); diff --git a/tmk_core/common/virtser.h b/tmk_core/common/virtser.h deleted file mode 100644 index a0645f9e03..0000000000 --- a/tmk_core/common/virtser.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -/* Define this function in your code to process incoming bytes */ -void virtser_recv(const uint8_t ch); - -/* Call this to send a character over the Virtual Serial Device */ -void virtser_send(const uint8_t byte); |