diff options
Diffstat (limited to 'quantum')
82 files changed, 688 insertions, 6321 deletions
| diff --git a/quantum/action.c b/quantum/action.c index be135f18f2..95f39d23d4 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -18,6 +18,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "keycode.h"  #include "keyboard.h"  #include "mousekey.h" +#include "programmable_button.h"  #include "command.h"  #include "led.h"  #include "action_layer.h" @@ -988,6 +989,10 @@ void clear_keyboard_but_mods_and_keys() {      mousekey_clear();      mousekey_send();  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    programmable_button_clear(); +    programmable_button_send(); +#endif  }  /** \brief Utilities for actions. (FIXME: Needs better description) diff --git a/quantum/api.c b/quantum/api.c deleted file mode 100644 index 1685744589..0000000000 --- a/quantum/api.c +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 "api.h" -#include "quantum.h" - -void dword_to_bytes(uint32_t dword, uint8_t* bytes) { -    bytes[0] = (dword >> 24) & 0xFF; -    bytes[1] = (dword >> 16) & 0xFF; -    bytes[2] = (dword >> 8) & 0xFF; -    bytes[3] = (dword >> 0) & 0xFF; -} - -uint32_t bytes_to_dword(uint8_t* bytes, uint8_t index) { return ((uint32_t)bytes[index + 0] << 24) | ((uint32_t)bytes[index + 1] << 16) | ((uint32_t)bytes[index + 2] << 8) | (uint32_t)bytes[index + 3]; } - -__attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data) { return process_api_keyboard(length, data); } - -__attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data) { return process_api_user(length, data); } - -__attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data) { return true; } - -void process_api(uint16_t length, uint8_t* data) { -    // SEND_STRING("\nRX: "); -    // for (uint8_t i = 0; i < length; i++) { -    //     send_byte(data[i]); -    //     SEND_STRING(" "); -    // } -    if (!process_api_quantum(length, data)) return; - -    switch (data[0]) { -        case MT_SET_DATA: -            switch (data[1]) { -                case DT_DEFAULT_LAYER: { -                    eeconfig_update_default_layer(data[2]); -                    default_layer_set((uint32_t)(data[2])); -                    break; -                } -                case DT_KEYMAP_OPTIONS: { -                    eeconfig_update_keymap(data[2]); -                    break; -                } -                case DT_RGBLIGHT: { -#ifdef RGBLIGHT_ENABLE -                    uint32_t rgblight = bytes_to_dword(data, 2); -                    eeconfig_update_rgblight(rgblight); -#endif -                    break; -                } -            } -        case MT_GET_DATA: -            switch (data[1]) { -                case DT_HANDSHAKE: { -                    MT_GET_DATA_ACK(DT_HANDSHAKE, NULL, 0); -                    break; -                } -                case DT_DEBUG: { -                    uint8_t debug_bytes[1] = {eeprom_read_byte(EECONFIG_DEBUG)}; -                    MT_GET_DATA_ACK(DT_DEBUG, debug_bytes, 1); -                    break; -                } -                case DT_DEFAULT_LAYER: { -                    uint8_t default_bytes[1] = {eeprom_read_byte(EECONFIG_DEFAULT_LAYER)}; -                    MT_GET_DATA_ACK(DT_DEFAULT_LAYER, default_bytes, 1); -                    break; -                } -                case DT_CURRENT_LAYER: { -                    uint8_t layer_state_bytes[4]; -                    dword_to_bytes(layer_state, layer_state_bytes); -                    MT_GET_DATA_ACK(DT_CURRENT_LAYER, layer_state_bytes, 4); -                    break; -                } -                case DT_AUDIO: { -#ifdef AUDIO_ENABLE -                    uint8_t audio_bytes[1] = {eeprom_read_byte(EECONFIG_AUDIO)}; -                    MT_GET_DATA_ACK(DT_AUDIO, audio_bytes, 1); -#else -                    MT_GET_DATA_ACK(DT_AUDIO, NULL, 0); -#endif -                    break; -                } -                case DT_BACKLIGHT: { -#ifdef BACKLIGHT_ENABLE -                    uint8_t backlight_bytes[1] = {eeprom_read_byte(EECONFIG_BACKLIGHT)}; -                    MT_GET_DATA_ACK(DT_BACKLIGHT, backlight_bytes, 1); -#else -                    MT_GET_DATA_ACK(DT_BACKLIGHT, NULL, 0); -#endif -                    break; -                } -                case DT_RGBLIGHT: { -#ifdef RGBLIGHT_ENABLE -                    uint8_t rgblight_bytes[4]; -                    dword_to_bytes(eeconfig_read_rgblight(), rgblight_bytes); -                    MT_GET_DATA_ACK(DT_RGBLIGHT, rgblight_bytes, 4); -#else -                    MT_GET_DATA_ACK(DT_RGBLIGHT, NULL, 0); -#endif -                    break; -                } -                case DT_KEYMAP_OPTIONS: { -                    uint8_t keymap_bytes[1] = {eeconfig_read_keymap()}; -                    MT_GET_DATA_ACK(DT_KEYMAP_OPTIONS, keymap_bytes, 1); -                    break; -                } -                case DT_KEYMAP_SIZE: { -                    uint8_t keymap_size[2] = {MATRIX_ROWS, MATRIX_COLS}; -                    MT_GET_DATA_ACK(DT_KEYMAP_SIZE, keymap_size, 2); -                    break; -                } -                // This may be too much -                // case DT_KEYMAP: { -                //     uint8_t keymap_data[MATRIX_ROWS * MATRIX_COLS * 4 + 3]; -                //     keymap_data[0] = data[2]; -                //     keymap_data[1] = MATRIX_ROWS; -                //     keymap_data[2] = MATRIX_COLS; -                //     for (int i = 0; i < MATRIX_ROWS; i++) { -                //         for (int j = 0; j < MATRIX_COLS; j++) { -                //             keymap_data[3 + (i*MATRIX_COLS*2) + (j*2)] = pgm_read_word(&keymaps[data[2]][i][j]) >> 8; -                //             keymap_data[3 + (i*MATRIX_COLS*2) + (j*2) + 1] = pgm_read_word(&keymaps[data[2]][i][j]) & 0xFF; -                //         } -                //     } -                //     MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, MATRIX_ROWS * MATRIX_COLS * 4 + 3); -                //     // uint8_t keymap_data[5]; -                //     // keymap_data[0] = data[2]; -                //     // keymap_data[1] = data[3]; -                //     // keymap_data[2] = data[4]; -                //     // keymap_data[3] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) >> 8; -                //     // keymap_data[4] = pgm_read_word(&keymaps[data[2]][data[3]][data[4]]) & 0xFF; - -                //     // MT_GET_DATA_ACK(DT_KEYMAP, keymap_data, 5); -                //     break; -                // } -                default: -                    break; -            } -            break; -        case MT_SET_DATA_ACK: -        case MT_GET_DATA_ACK: -            break; -        case MT_SEND_DATA: -            break; -        case MT_SEND_DATA_ACK: -            break; -        case MT_EXE_ACTION: -            break; -        case MT_EXE_ACTION_ACK: -            break; -        case MT_TYPE_ERROR: -            break; -        default:;  // command not recognised -            SEND_BYTES(MT_TYPE_ERROR, DT_NONE, data, length); -            break; - -            // #ifdef RGBLIGHT_ENABLE -            // case 0x27: ; // RGB LED functions -            //     switch (*data++) { -            //         case 0x00: ; // Update HSV -            //             rgblight_sethsv((data[0] << 8 | data[1]) % 360, data[2], data[3]); -            //             break; -            //         case 0x01: ; // Update RGB -            //             break; -            //         case 0x02: ; // Update mode -            //             rgblight_mode(data[0]); -            //             break; -            //     } -            //     break; -            // #endif -    } -} diff --git a/quantum/api.h b/quantum/api.h deleted file mode 100644 index 0a30e9d6cc..0000000000 --- a/quantum/api.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 - -#ifdef __AVR__ -#    include "lufa.h" -#endif - -enum MESSAGE_TYPE { -    MT_GET_DATA       = 0x10,  // Get data from keyboard -    MT_GET_DATA_ACK   = 0x11,  // returned data to process (ACK) -    MT_SET_DATA       = 0x20,  // Set data on keyboard -    MT_SET_DATA_ACK   = 0x21,  // returned data to confirm (ACK) -    MT_SEND_DATA      = 0x30,  // Sending data/action from keyboard -    MT_SEND_DATA_ACK  = 0x31,  // returned data/action confirmation (ACK) -    MT_EXE_ACTION     = 0x40,  // executing actions on keyboard -    MT_EXE_ACTION_ACK = 0x41,  // return confirmation/value (ACK) -    MT_TYPE_ERROR     = 0x80   // type not recognised (ACK) -}; - -enum DATA_TYPE { DT_NONE = 0x00, DT_HANDSHAKE, DT_DEFAULT_LAYER, DT_CURRENT_LAYER, DT_KEYMAP_OPTIONS, DT_BACKLIGHT, DT_RGBLIGHT, DT_UNICODE, DT_DEBUG, DT_AUDIO, DT_QUANTUM_ACTION, DT_KEYBOARD_ACTION, DT_USER_ACTION, DT_KEYMAP_SIZE, DT_KEYMAP }; - -void     dword_to_bytes(uint32_t dword, uint8_t* bytes); -uint32_t bytes_to_dword(uint8_t* bytes, uint8_t index); - -#define MT_GET_DATA(data_type, data, length) SEND_BYTES(MT_GET_DATA, data_type, data, length) -#define MT_GET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_GET_DATA_ACK, data_type, data, length) -#define MT_SET_DATA(data_type, data, length) SEND_BYTES(MT_SET_DATA, data_type, data, length) -#define MT_SET_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SET_DATA_ACK, data_type, data, length) -#define MT_SEND_DATA(data_type, data, length) SEND_BYTES(MT_SEND_DATA, data_type, data, length) -#define MT_SEND_DATA_ACK(data_type, data, length) SEND_BYTES(MT_SEND_DATA_ACK, data_type, data, length) -#define MT_EXE_ACTION(data_type, data, length) SEND_BYTES(MT_EXE_ACTION, data_type, data, length) -#define MT_EXE_ACTION_ACK(data_type, data, length) SEND_BYTES(MT_EXE_ACTION_ACK, data_type, data, length) - -void process_api(uint16_t length, uint8_t* data); - -__attribute__((weak)) bool process_api_quantum(uint8_t length, uint8_t* data); - -__attribute__((weak)) bool process_api_keyboard(uint8_t length, uint8_t* data); - -__attribute__((weak)) bool process_api_user(uint8_t length, uint8_t* data); diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c deleted file mode 100644 index 07c90cf804..0000000000 --- a/quantum/api/api_sysex.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2016 Jack Humbert, 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 "api_sysex.h" -#include "sysex_tools.h" -#include "print.h" -#include "qmk_midi.h" - -void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length) { -    // SEND_STRING("\nTX: "); -    // for (uint8_t i = 0; i < length; i++) { -    //     send_byte(bytes[i]); -    //     SEND_STRING(" "); -    // } -    if (length > API_SYSEX_MAX_SIZE) { -        xprintf("Sysex msg too big %d %d %d", message_type, data_type, length); -        return; -    } - -    // The buffer size required is calculated as the following -    // API_SYSEX_MAX_SIZE is the maximum length -    // In addition to that we have a two byte message header consisting of the message_type and data_type -    // This has to be encoded with an additional overhead of one byte for every starting 7 bytes -    // We just add one extra byte in case it's not divisible by 7 -    // Then we have an unencoded header consisting of 4 bytes -    // Plus a one byte terminator -    const unsigned message_header    = 2; -    const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header; -    const unsigned encoding_overhead = unencoded_message / 7 + 1; -    const unsigned encoded_size      = unencoded_message + encoding_overhead; -    const unsigned unencoded_header  = 4; -    const unsigned terminator        = 1; -    const unsigned buffer_size       = encoded_size + unencoded_header + terminator; -    uint8_t        buffer[encoded_size + unencoded_header + terminator]; -    // The unencoded header -    buffer[0] = 0xF0; -    buffer[1] = 0x00; -    buffer[2] = 0x00; -    buffer[3] = 0x00; - -    // We copy the message to the end of the array, this way we can do an inplace encoding, using the same -    // buffer for both input and output -    const unsigned message_size    = length + message_header; -    uint8_t*       unencoded_start = buffer + buffer_size - message_size; -    uint8_t*       ptr             = unencoded_start; -    *(ptr++)                       = message_type; -    *(ptr++)                       = data_type; -    memcpy(ptr, bytes, length); - -    unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size); -    unsigned final_size     = unencoded_header + encoded_length + terminator; -    buffer[final_size - 1]  = 0xF7; -    midi_send_array(&midi_device, final_size, buffer); - -    // SEND_STRING("\nTD: "); -    // for (uint8_t i = 0; i < encoded_length + 5; i++) { -    //     send_byte(buffer[i]); -    //     SEND_STRING(" "); -    // } -} diff --git a/quantum/api/api_sysex.h b/quantum/api/api_sysex.h deleted file mode 100644 index eb0a18848d..0000000000 --- a/quantum/api/api_sysex.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 "api.h" - -#define API_SYSEX_MAX_SIZE 32 - -void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t* bytes, uint16_t length); - -#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l) diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h index 56b9158a1a..290d461f5a 100644 --- a/quantum/audio/audio.h +++ b/quantum/audio/audio.h @@ -26,17 +26,12 @@  #if defined(__AVR__)  #    include <avr/io.h> -#    if defined(AUDIO_DRIVER_PWM) -#        include "driver_avr_pwm.h" -#    endif  #endif -#if defined(PROTOCOL_CHIBIOS) -#    if defined(AUDIO_DRIVER_PWM) -#        include "driver_chibios_pwm.h" -#    elif defined(AUDIO_DRIVER_DAC) -#        include "driver_chibios_dac.h" -#    endif +#if defined(AUDIO_DRIVER_PWM) +#    include "audio_pwm.h" +#elif defined(AUDIO_DRIVER_DAC) +#    include "audio_dac.h"  #endif  typedef union { diff --git a/quantum/audio/driver_avr_pwm.h b/quantum/audio/driver_avr_pwm.h deleted file mode 100644 index d6eb3571da..0000000000 --- a/quantum/audio/driver_avr_pwm.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 diff --git a/quantum/audio/driver_avr_pwm_hardware.c b/quantum/audio/driver_avr_pwm_hardware.c deleted file mode 100644 index df03a4558c..0000000000 --- a/quantum/audio/driver_avr_pwm_hardware.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Copyright 2016 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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/>. - */ - -#if defined(__AVR__) -#    include <avr/pgmspace.h> -#    include <avr/interrupt.h> -#    include <avr/io.h> -#endif - -#include "audio.h" - -extern bool    playing_note; -extern bool    playing_melody; -extern uint8_t note_timbre; - -#define CPU_PRESCALER 8 - -/* -  Audio Driver: PWM - -  drive up to two speakers through the AVR PWM hardware-peripheral, using timer1 and/or timer3 on Atmega32U4. - -  the primary channel_1 can be connected to either pin PC4 PC5 or PC6 (the later being used by most AVR based keyboards) with a PMW signal generated by timer3 -  and an optional secondary channel_2 on either pin PB5, PB6 or PB7, with a PWM signal from timer1 - -  alternatively, the PWM pins on PORTB can be used as only/primary speaker -*/ - -#if defined(AUDIO_PIN) && (AUDIO_PIN != C4) && (AUDIO_PIN != C5) && (AUDIO_PIN != C6) && (AUDIO_PIN != B5) && (AUDIO_PIN != B6) && (AUDIO_PIN != B7) && (AUDIO_PIN != D5) -#    error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under the AVR settings for available options." -#endif - -#if (AUDIO_PIN == C4) || (AUDIO_PIN == C5) || (AUDIO_PIN == C6) -#    define AUDIO1_PIN_SET -#    define AUDIO1_TIMSKx TIMSK3 -#    define AUDIO1_TCCRxA TCCR3A -#    define AUDIO1_TCCRxB TCCR3B -#    define AUDIO1_ICRx ICR3 -#    define AUDIO1_WGMx0 WGM30 -#    define AUDIO1_WGMx1 WGM31 -#    define AUDIO1_WGMx2 WGM32 -#    define AUDIO1_WGMx3 WGM33 -#    define AUDIO1_CSx0 CS30 -#    define AUDIO1_CSx1 CS31 -#    define AUDIO1_CSx2 CS32 - -#    if (AUDIO_PIN == C6) -#        define AUDIO1_COMxy0 COM3A0 -#        define AUDIO1_COMxy1 COM3A1 -#        define AUDIO1_OCIExy OCIE3A -#        define AUDIO1_OCRxy OCR3A -#        define AUDIO1_PIN C6 -#        define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPA_vect -#    elif (AUDIO_PIN == C5) -#        define AUDIO1_COMxy0 COM3B0 -#        define AUDIO1_COMxy1 COM3B1 -#        define AUDIO1_OCIExy OCIE3B -#        define AUDIO1_OCRxy OCR3B -#        define AUDIO1_PIN C5 -#        define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPB_vect -#    elif (AUDIO_PIN == C4) -#        define AUDIO1_COMxy0 COM3C0 -#        define AUDIO1_COMxy1 COM3C1 -#        define AUDIO1_OCIExy OCIE3C -#        define AUDIO1_OCRxy OCR3C -#        define AUDIO1_PIN C4 -#        define AUDIO1_TIMERx_COMPy_vect TIMER3_COMPC_vect -#    endif -#endif - -#if defined(AUDIO_PIN) && defined(AUDIO_PIN_ALT) && (AUDIO_PIN == AUDIO_PIN_ALT) -#    error "Audio feature: AUDIO_PIN and AUDIO_PIN_ALT on the same pin makes no sense." -#endif - -#if ((AUDIO_PIN == B5) && ((AUDIO_PIN_ALT == B6) || (AUDIO_PIN_ALT == B7))) || ((AUDIO_PIN == B6) && ((AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B7))) || ((AUDIO_PIN == B7) && ((AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B6))) -#    error "Audio feature: PORTB as AUDIO_PIN and AUDIO_PIN_ALT at the same time is not supported." -#endif - -#if defined(AUDIO_PIN_ALT) && (AUDIO_PIN_ALT != B5) && (AUDIO_PIN_ALT != B6) && (AUDIO_PIN_ALT != B7) -#    error "Audio feature: the pin selected as AUDIO_PIN_ALT is not supported." -#endif - -#if (AUDIO_PIN == B5) || (AUDIO_PIN == B6) || (AUDIO_PIN == B7) || (AUDIO_PIN_ALT == B5) || (AUDIO_PIN_ALT == B6) || (AUDIO_PIN_ALT == B7) || (AUDIO_PIN == D5) -#    define AUDIO2_PIN_SET -#    define AUDIO2_TIMSKx TIMSK1 -#    define AUDIO2_TCCRxA TCCR1A -#    define AUDIO2_TCCRxB TCCR1B -#    define AUDIO2_ICRx ICR1 -#    define AUDIO2_WGMx0 WGM10 -#    define AUDIO2_WGMx1 WGM11 -#    define AUDIO2_WGMx2 WGM12 -#    define AUDIO2_WGMx3 WGM13 -#    define AUDIO2_CSx0 CS10 -#    define AUDIO2_CSx1 CS11 -#    define AUDIO2_CSx2 CS12 - -#    if (AUDIO_PIN == B5) || (AUDIO_PIN_ALT == B5) -#        define AUDIO2_COMxy0 COM1A0 -#        define AUDIO2_COMxy1 COM1A1 -#        define AUDIO2_OCIExy OCIE1A -#        define AUDIO2_OCRxy OCR1A -#        define AUDIO2_PIN B5 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -#    elif (AUDIO_PIN == B6) || (AUDIO_PIN_ALT == B6) -#        define AUDIO2_COMxy0 COM1B0 -#        define AUDIO2_COMxy1 COM1B1 -#        define AUDIO2_OCIExy OCIE1B -#        define AUDIO2_OCRxy OCR1B -#        define AUDIO2_PIN B6 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPB_vect -#    elif (AUDIO_PIN == B7) || (AUDIO_PIN_ALT == B7) -#        define AUDIO2_COMxy0 COM1C0 -#        define AUDIO2_COMxy1 COM1C1 -#        define AUDIO2_OCIExy OCIE1C -#        define AUDIO2_OCRxy OCR1C -#        define AUDIO2_PIN B7 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPC_vect -#    elif (AUDIO_PIN == D5) && defined(__AVR_ATmega32A__) -#        pragma message "Audio support for ATmega32A is experimental and can cause crashes." -#        undef AUDIO2_TIMSKx -#        define AUDIO2_TIMSKx TIMSK -#        define AUDIO2_COMxy0 COM1A0 -#        define AUDIO2_COMxy1 COM1A1 -#        define AUDIO2_OCIExy OCIE1A -#        define AUDIO2_OCRxy OCR1A -#        define AUDIO2_PIN D5 -#        define AUDIO2_TIMERx_COMPy_vect TIMER1_COMPA_vect -#    endif -#endif - -// C6 seems to be the assumed default by many existing keyboard - but sill warn the user -#if !defined(AUDIO1_PIN_SET) && !defined(AUDIO2_PIN_SET) -#    pragma message "Audio feature enabled, but no suitable pin selected - see docs/feature_audio under the AVR settings for available options. Don't expect to hear anything... :-)" -// TODO: make this an error - go through the breaking-change-process and change all keyboards to the new define -#endif -// ----------------------------------------------------------------------------- - -#ifdef AUDIO1_PIN_SET -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    if (freq == 0.0f)  // a pause/rest is a valid "note" with freq=0 -    { -        // disable the output, but keep the pwm-ISR going (with the previous -        // frequency) so the audio-state keeps getting updated -        // Note: setting the duty-cycle 0 is not possible on non-inverting PWM mode - see the AVR data-sheet -        AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); -        return; -    } else { -        AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1);  // enable output, PWM mode -    } - -    channel_1_frequency = freq; - -    // set pwm period -    AUDIO1_ICRx = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); -    // and duty cycle -    AUDIO1_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); -} - -void channel_1_start(void) { -    // enable timer-counter ISR -    AUDIO1_TIMSKx |= _BV(AUDIO1_OCIExy); -    // enable timer-counter output -    AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1); -} - -void channel_1_stop(void) { -    // disable timer-counter ISR -    AUDIO1_TIMSKx &= ~_BV(AUDIO1_OCIExy); -    // disable timer-counter output -    AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); -} -#endif - -#ifdef AUDIO2_PIN_SET -static float channel_2_frequency = 0.0f; -void         channel_2_set_frequency(float freq) { -    if (freq == 0.0f) { -        AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); -        return; -    } else { -        AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); -    } - -    channel_2_frequency = freq; - -    AUDIO2_ICRx  = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); -    AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); -} - -float channel_2_get_frequency(void) { return channel_2_frequency; } - -void channel_2_start(void) { -    AUDIO2_TIMSKx |= _BV(AUDIO2_OCIExy); -    AUDIO2_TCCRxA |= _BV(AUDIO2_COMxy1); -} - -void channel_2_stop(void) { -    AUDIO2_TIMSKx &= ~_BV(AUDIO2_OCIExy); -    AUDIO2_TCCRxA &= ~(_BV(AUDIO2_COMxy1) | _BV(AUDIO2_COMxy0)); -} -#endif - -void audio_driver_initialize() { -#ifdef AUDIO1_PIN_SET -    channel_1_stop(); -    setPinOutput(AUDIO1_PIN); -#endif - -#ifdef AUDIO2_PIN_SET -    channel_2_stop(); -    setPinOutput(AUDIO2_PIN); -#endif - -    // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B -    // Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation -    //   OC3A -- PC6 -    //   OC3B -- PC5 -    //   OC3C -- PC4 -    //   OC1A -- PB5 -    //   OC1B -- PB6 -    //   OC1C -- PB7 - -    // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A) -    //   OCR3A - PC6 -    //   OCR3B - PC5 -    //   OCR3C - PC4 -    //   OCR1A - PB5 -    //   OCR1B - PB6 -    //   OCR1C - PB7 - -    // Clock Select (CS3n) = 0b010 = Clock / 8 -#ifdef AUDIO1_PIN_SET -    // initialize timer-counter -    AUDIO1_TCCRxA = (0 << AUDIO1_COMxy1) | (0 << AUDIO1_COMxy0) | (1 << AUDIO1_WGMx1) | (0 << AUDIO1_WGMx0); -    AUDIO1_TCCRxB = (1 << AUDIO1_WGMx3) | (1 << AUDIO1_WGMx2) | (0 << AUDIO1_CSx2) | (1 << AUDIO1_CSx1) | (0 << AUDIO1_CSx0); -#endif - -#ifdef AUDIO2_PIN_SET -    AUDIO2_TCCRxA = (0 << AUDIO2_COMxy1) | (0 << AUDIO2_COMxy0) | (1 << AUDIO2_WGMx1) | (0 << AUDIO2_WGMx0); -    AUDIO2_TCCRxB = (1 << AUDIO2_WGMx3) | (1 << AUDIO2_WGMx2) | (0 << AUDIO2_CSx2) | (1 << AUDIO2_CSx1) | (0 << AUDIO2_CSx0); -#endif -} - -void audio_driver_stop() { -#ifdef AUDIO1_PIN_SET -    channel_1_stop(); -#endif - -#ifdef AUDIO2_PIN_SET -    channel_2_stop(); -#endif -} - -void audio_driver_start(void) { -#ifdef AUDIO1_PIN_SET -    channel_1_start(); -    if (playing_note) { -        channel_1_set_frequency(audio_get_processed_frequency(0)); -    } -#endif - -#if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) -    channel_2_start(); -    if (playing_note) { -        channel_2_set_frequency(audio_get_processed_frequency(0)); -    } -#endif -} - -static volatile uint32_t isr_counter = 0; -#ifdef AUDIO1_PIN_SET -ISR(AUDIO1_TIMERx_COMPy_vect) { -    isr_counter++; -    if (isr_counter < channel_1_frequency / (CPU_PRESCALER * 8)) return; - -    isr_counter        = 0; -    bool state_changed = audio_update_state(); - -    if (!playing_note && !playing_melody) { -        channel_1_stop(); -#    ifdef AUDIO2_PIN_SET -        channel_2_stop(); -#    endif -        return; -    } - -    if (state_changed) { -        channel_1_set_frequency(audio_get_processed_frequency(0)); -#    ifdef AUDIO2_PIN_SET -        if (audio_get_number_of_active_tones() > 1) { -            channel_2_set_frequency(audio_get_processed_frequency(1)); -        } else { -            channel_2_stop(); -        } -#    endif -    } -} -#endif - -#if !defined(AUDIO1_PIN_SET) && defined(AUDIO2_PIN_SET) -ISR(AUDIO2_TIMERx_COMPy_vect) { -    isr_counter++; -    if (isr_counter < channel_2_frequency / (CPU_PRESCALER * 8)) return; - -    isr_counter        = 0; -    bool state_changed = audio_update_state(); - -    if (!playing_note && !playing_melody) { -        channel_2_stop(); -        return; -    } - -    if (state_changed) { -        channel_2_set_frequency(audio_get_processed_frequency(0)); -    } -} -#endif diff --git a/quantum/audio/driver_chibios_dac.h b/quantum/audio/driver_chibios_dac.h deleted file mode 100644 index 07cd622ead..0000000000 --- a/quantum/audio/driver_chibios_dac.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright 2019 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 - -#ifndef A4 -#    define A4 PAL_LINE(GPIOA, 4) -#endif -#ifndef A5 -#    define A5 PAL_LINE(GPIOA, 5) -#endif - -/** - * Size of the dac_buffer arrays. All must be the same size. - */ -#define AUDIO_DAC_BUFFER_SIZE 256U - -/** - * Highest value allowed sample value. - - * since the DAC is limited to 12 bit, the absolute max is 0xfff = 4095U; - * lower values adjust the peak-voltage aka volume down. - * adjusting this value has only an effect on a sample-buffer whose values are - * are NOT pregenerated - see square-wave - */ -#ifndef AUDIO_DAC_SAMPLE_MAX -#    define AUDIO_DAC_SAMPLE_MAX 4095U -#endif - -#if !defined(AUDIO_DAC_SAMPLE_RATE) && !defined(AUDIO_MAX_SIMULTANEOUS_TONES) && !defined(AUDIO_DAC_QUALITY_VERY_LOW) && !defined(AUDIO_DAC_QUALITY_LOW) && !defined(AUDIO_DAC_QUALITY_HIGH) && !defined(AUDIO_DAC_QUALITY_VERY_HIGH) -#    define AUDIO_DAC_QUALITY_SANE_MINIMUM -#endif - -/** - * These presets allow you to quickly switch between quality settings for - * the DAC. The sample rate and maximum number of simultaneous tones roughly - * has an inverse relationship - slightly higher sample rates may be possible. - * - * NOTE: a high sample-rate results in a higher cpu-load, which might lead to - *       (audible) discontinuities and/or starve other processes of cpu-time - *       (like RGB-led back-lighting, ...) - */ -#ifdef AUDIO_DAC_QUALITY_VERY_LOW -#    define AUDIO_DAC_SAMPLE_RATE 11025U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 8 -#endif - -#ifdef AUDIO_DAC_QUALITY_LOW -#    define AUDIO_DAC_SAMPLE_RATE 22050U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 4 -#endif - -#ifdef AUDIO_DAC_QUALITY_HIGH -#    define AUDIO_DAC_SAMPLE_RATE 44100U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 2 -#endif - -#ifdef AUDIO_DAC_QUALITY_VERY_HIGH -#    define AUDIO_DAC_SAMPLE_RATE 88200U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 1 -#endif - -#ifdef AUDIO_DAC_QUALITY_SANE_MINIMUM -/* a sane-minimum config: with a trade-off between cpu-load and tone-range - * - * the (currently) highest defined note is NOTE_B8 with 7902Hz; if we now - * aim for an even even multiple of the buffer-size, we end up with: - * ( roundUptoPow2(highest note / AUDIO_DAC_BUFFER_SIZE) * nyquist-rate * AUDIO_DAC_BUFFER_SIZE) - *                              7902/256 = 30.867        *       2      * 256 ~= 16384 - * which works out (but the 'scope shows some sampling artifacts with lower harmonics :-P) - */ -#    define AUDIO_DAC_SAMPLE_RATE 16384U -#    define AUDIO_MAX_SIMULTANEOUS_TONES 8 -#endif - -/** - * Effective bit-rate of the DAC. 44.1khz is the standard for most audio - any - * lower will sacrifice perceptible audio quality. Any higher will limit the - * number of simultaneous tones. In most situations, a tenth (1/10) of the - * sample rate is where notes become unbearable. - */ -#ifndef AUDIO_DAC_SAMPLE_RATE -#    define AUDIO_DAC_SAMPLE_RATE 44100U -#endif - -/** - * The number of tones that can be played simultaneously. If too high a value - * is used here, the keyboard will freeze and glitch-out when that many tones - * are being played. - */ -#ifndef AUDIO_MAX_SIMULTANEOUS_TONES -#    define AUDIO_MAX_SIMULTANEOUS_TONES 2 -#endif - -/** - * The default value of the DAC when not playing anything. Certain hardware - * setups may require a high (AUDIO_DAC_SAMPLE_MAX) or low (0) value here. - * Since multiple added sine waves tend to oscillate around the midpoint, - * and possibly never/rarely reach either 0 of MAX, 1/2 MAX can be a - * reasonable default value. - */ -#ifndef AUDIO_DAC_OFF_VALUE -#    define AUDIO_DAC_OFF_VALUE AUDIO_DAC_SAMPLE_MAX / 2 -#endif - -#if AUDIO_DAC_OFF_VALUE > AUDIO_DAC_SAMPLE_MAX -#    error "AUDIO_DAC: OFF_VALUE may not be larger than SAMPLE_MAX" -#endif - -/** - *user overridable sample generation/processing - */ -uint16_t dac_value_generate(void); diff --git a/quantum/audio/driver_chibios_dac_additive.c b/quantum/audio/driver_chibios_dac_additive.c deleted file mode 100644 index db304adb87..0000000000 --- a/quantum/audio/driver_chibios_dac_additive.c +++ /dev/null @@ -1,335 +0,0 @@ -/* Copyright 2016-2019 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 "audio.h" -#include <ch.h> -#include <hal.h> - -/* -  Audio Driver: DAC - -  which utilizes the dac unit many STM32 are equipped with, to output a modulated waveform from samples stored in the dac_buffer_* array who are passed to the hardware through DMA - -  it is also possible to have a custom sample-LUT by implementing/overriding 'dac_value_generate' - -  this driver allows for multiple simultaneous tones to be played through one single channel by doing additive wave-synthesis -*/ - -#if !defined(AUDIO_PIN) -#    error "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC additive)' for available options." -#endif -#if defined(AUDIO_PIN_ALT) && !defined(AUDIO_PIN_ALT_AS_NEGATIVE) -#    pragma message "Audio feature: AUDIO_PIN_ALT set, but not AUDIO_PIN_ALT_AS_NEGATIVE - pin will be left unused; audio might still work though." -#endif - -#if !defined(AUDIO_PIN_ALT) -// no ALT pin defined is valid, but the c-ifs below need some value set -#    define AUDIO_PIN_ALT PAL_NOLINE -#endif - -#if !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) && !defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) -#    define AUDIO_DAC_SAMPLE_WAVEFORM_SINE -#endif - -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SINE -/* one full sine wave over [0,2*pi], but shifted up one amplitude and left pi/4; for the samples to start at 0 - */ -static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = { -    // 256 values, max 4095 -    0x0,   0x1,   0x2,   0x6,   0xa,   0xf,   0x16,  0x1e,  0x27,  0x32,  0x3d,  0x4a,  0x58,  0x67,  0x78,  0x89,  0x9c,  0xb0,  0xc5,  0xdb,  0xf2,  0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, -    0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2,  0xdb,  0xc5,  0xb0,  0x9c,  0x89,  0x78,  0x67,  0x58,  0x4a,  0x3d,  0x32,  0x27,  0x1e,  0x16,  0xf,   0xa,   0x6,   0x2,   0x1}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_SINE -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE -static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = { -    // 256 values, max 4095 -    0x0,   0x20,  0x40,  0x60,  0x80,  0xa0,  0xc0,  0xe0,  0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, -    0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0,  0xc0,  0xa0,  0x80,  0x60,  0x40,  0x20}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE -static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = { -    [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1]                     = 0,                     // first and -    [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX,  // second half -}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE -/* -// four steps: 0, 1/3, 2/3 and 1 -static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { -    [0 ... AUDIO_DAC_BUFFER_SIZE/3 -1 ]                               = 0, -    [AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE / 2 -1 ]     = AUDIO_DAC_SAMPLE_MAX / 3, -    [AUDIO_DAC_BUFFER_SIZE / 2 ... 3 * AUDIO_DAC_BUFFER_SIZE / 4 -1 ] = 2 * AUDIO_DAC_SAMPLE_MAX / 3, -    [3 * AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE -1 ]     = AUDIO_DAC_SAMPLE_MAX, -} -*/ -#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID -static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0,   0x1f,  0x7f,  0xdf,  0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, -                                                                        0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf,  0x7f,  0x1f,  0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0,   0x0}; -#endif  // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID - -static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALUE}; - -/* keep track of the sample position for for each frequency */ -static float dac_if[AUDIO_MAX_SIMULTANEOUS_TONES] = {0.0}; - -static float   active_tones_snapshot[AUDIO_MAX_SIMULTANEOUS_TONES] = {0, 0}; -static uint8_t active_tones_snapshot_length                        = 0; - -typedef enum { -    OUTPUT_SHOULD_START, -    OUTPUT_RUN_NORMALLY, -    // path 1: wait for zero, then change/update active tones -    OUTPUT_TONES_CHANGED, -    OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE, -    // path 2: hardware should stop, wait for zero then turn output off = stop the timer -    OUTPUT_SHOULD_STOP, -    OUTPUT_REACHED_ZERO_BEFORE_OFF, -    OUTPUT_OFF, -    OUTPUT_OFF_1, -    OUTPUT_OFF_2,  // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level -    number_of_output_states -} output_states_t; -output_states_t state = OUTPUT_OFF_2; - -/** - * Generation of the waveform being passed to the callback. Declared weak so users - * can override it with their own wave-forms/noises. - */ -__attribute__((weak)) uint16_t dac_value_generate(void) { -    // DAC is running/asking for values but snapshot length is zero -> must be playing a pause -    if (active_tones_snapshot_length == 0) { -        return AUDIO_DAC_OFF_VALUE; -    } - -    /* doing additive wave synthesis over all currently playing tones = adding up -     * sine-wave-samples for each frequency, scaled by the number of active tones -     */ -    uint16_t value     = 0; -    float    frequency = 0.0f; - -    for (uint8_t i = 0; i < active_tones_snapshot_length; i++) { -        /* Note: a user implementation does not have to rely on the active_tones_snapshot, but -         * could directly query the active frequencies through audio_get_processed_frequency */ -        frequency = active_tones_snapshot[i]; - -        dac_if[i] = dac_if[i] + ((frequency * AUDIO_DAC_BUFFER_SIZE) / AUDIO_DAC_SAMPLE_RATE) * 2 / 3; -        /*Note: the 2/3 are necessary to get the correct frequencies on the -         *      DAC output (as measured with an oscilloscope), since the gpt -         *      timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback -         *      is called twice per conversion.*/ - -        dac_if[i] = fmod(dac_if[i], AUDIO_DAC_BUFFER_SIZE); - -        // Wavetable generation/lookup -        uint16_t dac_i = (uint16_t)dac_if[i]; - -#if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE) -        value += dac_buffer_sine[dac_i] / active_tones_snapshot_length; -#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE) -        value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length; -#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID) -        value += dac_buffer_trapezoid[dac_i] / active_tones_snapshot_length; -#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE) -        value += dac_buffer_square[dac_i] / active_tones_snapshot_length; -#endif -        /* -        // SINE -        value += dac_buffer_sine[dac_i] / active_tones_snapshot_length / 3; -        // TRIANGLE -        value += dac_buffer_triangle[dac_i] / active_tones_snapshot_length / 3; -        // SQUARE -        value += dac_buffer_square[dac_i] / active_tones_snapshot_length / 3; -        //NOTE: combination of these three wave-forms is more exemplary - and doesn't sound particularly good :-P -        */ - -        // STAIRS (mostly usefully as test-pattern) -        // value_avg = dac_buffer_staircase[dac_i] / active_tones_snapshot_length; -    } - -    return value; -} - -/** - * DAC streaming callback. Does all of the main computing for playing songs. - * - * Note: chibios calls this CB twice: during the 'half buffer event', and the 'full buffer event'. - */ -static void dac_end(DACDriver *dacp) { -    dacsample_t *sample_p = (dacp)->samples; - -    // work on the other half of the buffer -    if (dacIsBufferComplete(dacp)) { -        sample_p += AUDIO_DAC_BUFFER_SIZE / 2;  // 'half_index' -    } - -    for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { -        if (OUTPUT_OFF <= state) { -            sample_p[s] = AUDIO_DAC_OFF_VALUE; -            continue; -        } else { -            sample_p[s] = dac_value_generate(); -        } - -        /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) -         * ============================*=*========================== AUDIO_DAC_SAMPLE_MAX -         *                          *       * -         *                        *           * -         * --------------------------------------------------------- -         *                     *                 *                  } AUDIO_DAC_SAMPLE_MAX/100 -         * --------------------------------------------------------- AUDIO_DAC_OFF_VALUE -         *                  *                       *               } AUDIO_DAC_SAMPLE_MAX/100 -         * --------------------------------------------------------- -         *               * -         * *           * -         *   *       * -         * =====*=*================================================= 0x0 -         */ -        if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) &&  // value approaches from below -            (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100)))     // or above -        ) { -            if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { -                state = OUTPUT_RUN_NORMALLY; -            } else if (OUTPUT_TONES_CHANGED == state) { -                state = OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE; -            } else if (OUTPUT_SHOULD_STOP == state) { -                state = OUTPUT_REACHED_ZERO_BEFORE_OFF; -            } -        } - -        // still 'ramping up', reset the output to OFF_VALUE until the generated values reach that value, to do a smooth handover -        if (OUTPUT_SHOULD_START == state) { -            sample_p[s] = AUDIO_DAC_OFF_VALUE; -        } - -        if ((OUTPUT_SHOULD_START == state) || (OUTPUT_REACHED_ZERO_BEFORE_OFF == state) || (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state)) { -            uint8_t active_tones         = MIN(AUDIO_MAX_SIMULTANEOUS_TONES, audio_get_number_of_active_tones()); -            active_tones_snapshot_length = 0; -            // update the snapshot - once, and only on occasion that something changed; -            // -> saves cpu cycles (?) -            for (uint8_t i = 0; i < active_tones; i++) { -                float freq = audio_get_processed_frequency(i); -                if (freq > 0) {  // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step -                    active_tones_snapshot[active_tones_snapshot_length++] = freq; -                } -            } - -            if ((0 == active_tones_snapshot_length) && (OUTPUT_REACHED_ZERO_BEFORE_OFF == state)) { -                state = OUTPUT_OFF; -            } -            if (OUTPUT_REACHED_ZERO_BEFORE_TONE_CHANGE == state) { -                state = OUTPUT_RUN_NORMALLY; -            } -        } -    } - -    // update audio internal state (note position, current_note, ...) -    if (audio_update_state()) { -        if (OUTPUT_SHOULD_STOP != state) { -            state = OUTPUT_TONES_CHANGED; -        } -    } - -    if (OUTPUT_OFF <= state) { -        if (OUTPUT_OFF_2 == state) { -            // stopping timer6 = stopping the DAC at whatever value it is currently pushing to the output = AUDIO_DAC_OFF_VALUE -            gptStopTimer(&GPTD6); -        } else { -            state++; -        } -    } -} - -static void dac_error(DACDriver *dacp, dacerror_t err) { -    (void)dacp; -    (void)err; - -    chSysHalt("DAC failure. halp"); -} - -static const GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE * 3, -                                   .callback  = NULL, -                                   .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.  */ -                                   .dier      = 0U}; - -static const DACConfig dac_conf = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; - -/** - * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered - * on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency - * to be a third of what we expect. - * - * Here are all the values for DAC_TRG (TSEL in the ref manual) - * TIM15_TRGO 0b011 - * TIM2_TRGO  0b100 - * TIM3_TRGO  0b001 - * TIM6_TRGO  0b000 - * TIM7_TRGO  0b010 - * EXTI9      0b110 - * SWTRIG     0b111 - */ -static const DACConversionGroup dac_conv_cfg = {.num_channels = 1U, .end_cb = dac_end, .error_cb = dac_error, .trigger = DAC_TRG(0b000)}; - -void audio_driver_initialize() { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        palSetLineMode(A4, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD1, &dac_conf); -    } -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        palSetLineMode(A5, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD2, &dac_conf); -    } - -    /* enable the output buffer, to directly drive external loads with no additional circuitry -     * -     * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers -     * Note: Buffer-Off bit -> has to be set 0 to enable the output buffer -     * Note: enabling the output buffer imparts an additional dc-offset of a couple mV -     * -     * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet -     * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' -     */ -    DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -    DACD2.params->dac->CR &= ~DAC_CR_BOFF2; - -    if (AUDIO_PIN == A4) { -        dacStartConversion(&DACD1, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -    } else if (AUDIO_PIN == A5) { -        dacStartConversion(&DACD2, &dac_conv_cfg, dac_buffer_empty, AUDIO_DAC_BUFFER_SIZE); -    } - -    // no inverted/out-of-phase waveform (yet?), only pulling AUDIO_PIN_ALT to AUDIO_DAC_OFF_VALUE -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    if (AUDIO_PIN_ALT == A4) { -        dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); -    } else if (AUDIO_PIN_ALT == A5) { -        dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); -    } -#endif - -    gptStart(&GPTD6, &gpt6cfg1); -} - -void audio_driver_stop(void) { state = OUTPUT_SHOULD_STOP; } - -void audio_driver_start(void) { -    gptStartContinuous(&GPTD6, 2U); - -    for (uint8_t i = 0; i < AUDIO_MAX_SIMULTANEOUS_TONES; i++) { -        dac_if[i]                = 0.0f; -        active_tones_snapshot[i] = 0.0f; -    } -    active_tones_snapshot_length = 0; -    state                        = OUTPUT_SHOULD_START; -} diff --git a/quantum/audio/driver_chibios_dac_basic.c b/quantum/audio/driver_chibios_dac_basic.c deleted file mode 100644 index fac6513506..0000000000 --- a/quantum/audio/driver_chibios_dac_basic.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright 2016-2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 "audio.h" -#include "ch.h" -#include "hal.h" - -/* -  Audio Driver: DAC - -  which utilizes both channels of the DAC unit many STM32 are equipped with to output a modulated square-wave, from precomputed samples stored in a buffer, which is passed to the hardware through DMA - -  this driver can either be used to drive to separate speakers, wired to A4+Gnd and A5+Gnd, which allows two tones to be played simultaneously -  OR -  one speaker wired to A4+A5 with the AUDIO_PIN_ALT_AS_NEGATIVE define set - see docs/feature_audio - -*/ - -#if !defined(AUDIO_PIN) -#    pragma message "Audio feature enabled, but no suitable pin selected as AUDIO_PIN - see docs/feature_audio under 'ARM (DAC basic)' for available options." -// TODO: make this an 'error' instead; go through a breaking change, and add AUDIO_PIN A5 to all keyboards currently using AUDIO on STM32 based boards? - for now: set the define here -#    define AUDIO_PIN A5 -#endif -// check configuration for ONE speaker, connected to both DAC pins -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) && !defined(AUDIO_PIN_ALT) -#    error "Audio feature: AUDIO_PIN_ALT_AS_NEGATIVE set, but no pin configured as AUDIO_PIN_ALT" -#endif - -#ifndef AUDIO_PIN_ALT -// no ALT pin defined is valid, but the c-ifs below need some value set -#    define AUDIO_PIN_ALT -1 -#endif - -#if !defined(AUDIO_STATE_TIMER) -#    define AUDIO_STATE_TIMER GPTD8 -#endif - -// square-wave -static const dacsample_t dac_buffer_1[AUDIO_DAC_BUFFER_SIZE] = { -    // First half is max, second half is 0 -    [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1]                     = AUDIO_DAC_SAMPLE_MAX, -    [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = 0, -}; - -// square-wave -static const dacsample_t dac_buffer_2[AUDIO_DAC_BUFFER_SIZE] = { -    // opposite of dac_buffer above -    [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1]                     = 0, -    [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, -}; - -GPTConfig gpt6cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, -                      .callback  = NULL, -                      .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.    */ -                      .dier      = 0U}; -GPTConfig gpt7cfg1 = {.frequency = AUDIO_DAC_SAMPLE_RATE, -                      .callback  = NULL, -                      .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.    */ -                      .dier      = 0U}; - -static void gpt_audio_state_cb(GPTDriver *gptp); -GPTConfig   gptStateUpdateCfg = {.frequency = 10, -                               .callback  = gpt_audio_state_cb, -                               .cr2       = TIM_CR2_MMS_1, /* MMS = 010 = TRGO on Update Event.    */ -                               .dier      = 0U}; - -static const DACConfig dac_conf_ch1 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; -static const DACConfig dac_conf_ch2 = {.init = AUDIO_DAC_OFF_VALUE, .datamode = DAC_DHRM_12BIT_RIGHT}; - -/** - * @note The DAC_TRG(0) here selects the Timer 6 TRGO event, which is triggered - * on the rising edge after 3 APB1 clock cycles, causing our gpt6cfg1.frequency - * to be a third of what we expect. - * - * Here are all the values for DAC_TRG (TSEL in the ref manual) - * TIM15_TRGO 0b011 - * TIM2_TRGO  0b100 - * TIM3_TRGO  0b001 - * TIM6_TRGO  0b000 - * TIM7_TRGO  0b010 - * EXTI9      0b110 - * SWTRIG     0b111 - */ -static const DACConversionGroup dac_conv_grp_ch1 = {.num_channels = 1U, .trigger = DAC_TRG(0b000)}; -static const DACConversionGroup dac_conv_grp_ch2 = {.num_channels = 1U, .trigger = DAC_TRG(0b010)}; - -void channel_1_start(void) { -    gptStart(&GPTD6, &gpt6cfg1); -    gptStartContinuous(&GPTD6, 2U); -    palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); -} - -void channel_1_stop(void) { -    gptStopTimer(&GPTD6); -    palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL); -    palSetPad(GPIOA, 4); -} - -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    channel_1_frequency = freq; - -    channel_1_stop(); -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; -    channel_1_start(); -} -float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_2_start(void) { -    gptStart(&GPTD7, &gpt7cfg1); -    gptStartContinuous(&GPTD7, 2U); -    palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); -} - -void channel_2_stop(void) { -    gptStopTimer(&GPTD7); -    palSetPadMode(GPIOA, 5, PAL_MODE_OUTPUT_PUSHPULL); -    palSetPad(GPIOA, 5); -} - -static float channel_2_frequency = 0.0f; -void         channel_2_set_frequency(float freq) { -    channel_2_frequency = freq; - -    channel_2_stop(); -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; -    channel_2_start(); -} -float channel_2_get_frequency(void) { return channel_2_frequency; } - -static void gpt_audio_state_cb(GPTDriver *gptp) { -    if (audio_update_state()) { -#if defined(AUDIO_PIN_ALT_AS_NEGATIVE) -        // one piezo/speaker connected to both audio pins, the generated square-waves are inverted -        channel_1_set_frequency(audio_get_processed_frequency(0)); -        channel_2_set_frequency(audio_get_processed_frequency(0)); - -#else  // two separate audio outputs/speakers -       // primary speaker on A4, optional secondary on A5 -        if (AUDIO_PIN == A4) { -            channel_1_set_frequency(audio_get_processed_frequency(0)); -            if (AUDIO_PIN_ALT == A5) { -                if (audio_get_number_of_active_tones() > 1) { -                    channel_2_set_frequency(audio_get_processed_frequency(1)); -                } else { -                    channel_2_stop(); -                } -            } -        } - -        // primary speaker on A5, optional secondary on A4 -        if (AUDIO_PIN == A5) { -            channel_2_set_frequency(audio_get_processed_frequency(0)); -            if (AUDIO_PIN_ALT == A4) { -                if (audio_get_number_of_active_tones() > 1) { -                    channel_1_set_frequency(audio_get_processed_frequency(1)); -                } else { -                    channel_1_stop(); -                } -            } -        } -#endif -    } -} - -void audio_driver_initialize() { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        palSetPadMode(GPIOA, 4, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD1, &dac_conf_ch1); - -        // initial setup of the dac-triggering timer is still required, even -        // though it gets reconfigured and restarted later on -        gptStart(&GPTD6, &gpt6cfg1); -    } - -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_ANALOG); -        dacStart(&DACD2, &dac_conf_ch2); - -        gptStart(&GPTD7, &gpt7cfg1); -    } - -    /* enable the output buffer, to directly drive external loads with no additional circuitry -     * -     * see: AN4566 Application note: Extending the DAC performance of STM32 microcontrollers -     * Note: Buffer-Off bit -> has to be set 0 to enable the output buffer -     * Note: enabling the output buffer imparts an additional dc-offset of a couple mV -     * -     * this is done here, reaching directly into the stm32 registers since chibios has not implemented BOFF handling yet -     * (see: chibios/os/hal/ports/STM32/todo.txt '- BOFF handling in DACv1.' -     */ -    DACD1.params->dac->CR &= ~DAC_CR_BOFF1; -    DACD2.params->dac->CR &= ~DAC_CR_BOFF2; - -    // start state-updater -    gptStart(&AUDIO_STATE_TIMER, &gptStateUpdateCfg); -} - -void audio_driver_stop(void) { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        gptStopTimer(&GPTD6); - -        // stop the ongoing conversion and put the output in a known state -        dacStopConversion(&DACD1); -        dacPutChannelX(&DACD1, 0, AUDIO_DAC_OFF_VALUE); -    } - -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        gptStopTimer(&GPTD7); - -        dacStopConversion(&DACD2); -        dacPutChannelX(&DACD2, 0, AUDIO_DAC_OFF_VALUE); -    } -    gptStopTimer(&AUDIO_STATE_TIMER); -} - -void audio_driver_start(void) { -    if ((AUDIO_PIN == A4) || (AUDIO_PIN_ALT == A4)) { -        dacStartConversion(&DACD1, &dac_conv_grp_ch1, (dacsample_t *)dac_buffer_1, AUDIO_DAC_BUFFER_SIZE); -    } -    if ((AUDIO_PIN == A5) || (AUDIO_PIN_ALT == A5)) { -        dacStartConversion(&DACD2, &dac_conv_grp_ch2, (dacsample_t *)dac_buffer_2, AUDIO_DAC_BUFFER_SIZE); -    } -    gptStartContinuous(&AUDIO_STATE_TIMER, 2U); -} diff --git a/quantum/audio/driver_chibios_pwm.h b/quantum/audio/driver_chibios_pwm.h deleted file mode 100644 index 86cab916e1..0000000000 --- a/quantum/audio/driver_chibios_pwm.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 - -#if !defined(AUDIO_PWM_DRIVER) -// NOTE: Timer2 seems to be used otherwise in QMK, otherwise we could default to A5 (= TIM2_CH1, with PWMD2 and alternate-function(1)) -#    define AUDIO_PWM_DRIVER PWMD1 -#endif - -#if !defined(AUDIO_PWM_CHANNEL) -// NOTE: sticking to the STM data-sheet numbering: TIMxCH1 to TIMxCH4 -// default: STM32F303CC PA8+TIM1_CH1 -> 1 -#    define AUDIO_PWM_CHANNEL 1 -#endif - -#if !defined(AUDIO_PWM_PAL_MODE) -// pin-alternate function: see the data-sheet for which pin needs what AF to connect to TIMx_CHy -// default: STM32F303CC PA8+TIM1_CH1 -> 6 -#    define AUDIO_PWM_PAL_MODE 6 -#endif - -#if !defined(AUDIO_STATE_TIMER) -// timer used to trigger updates in the audio-system, configured/enabled in chibios mcuconf. -// Tim6 is the default for "larger" STMs, smaller ones might not have this one (enabled) and need to switch to a different one (e.g.: STM32F103 has only Tim1-Tim4) -#    define AUDIO_STATE_TIMER GPTD6 -#endif diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c deleted file mode 100644 index 3c7d89b290..0000000000 --- a/quantum/audio/driver_chibios_pwm_hardware.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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/>. - */ - -/* -Audio Driver: PWM - -the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. - -this driver uses the chibios-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. -The hardware directly toggles the pin via its alternate function. see your MCUs data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. - - */ - -#include "audio.h" -#include "ch.h" -#include "hal.h" - -#if !defined(AUDIO_PIN) -#    error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" -#endif - -extern bool    playing_note; -extern bool    playing_melody; -extern uint8_t note_timbre; - -static PWMConfig pwmCFG = { -    .frequency = 100000, /* PWM clock frequency  */ -    // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no output=silence in the meantime -    .period   = 2,    /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ -    .callback = NULL, /* no callback, the hardware directly toggles the pin */ -    .channels = -        { -#if AUDIO_PWM_CHANNEL == 4 -            {PWM_OUTPUT_DISABLED, NULL},   /* channel 0 -> TIMx_CH1 */ -            {PWM_OUTPUT_DISABLED, NULL},   /* channel 1 -> TIMx_CH2 */ -            {PWM_OUTPUT_DISABLED, NULL},   /* channel 2 -> TIMx_CH3 */ -            {PWM_OUTPUT_ACTIVE_HIGH, NULL} /* channel 3 -> TIMx_CH4 */ -#elif AUDIO_PWM_CHANNEL == 3 -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH3 */ -            {PWM_OUTPUT_DISABLED, NULL} -#elif AUDIO_PWM_CHANNEL == 2 -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH2 */ -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL} -#else /*fallback to CH1 */ -            {PWM_OUTPUT_ACTIVE_HIGH, NULL}, /* TIMx_CH1 */ -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL}, -            {PWM_OUTPUT_DISABLED, NULL} -#endif -        }, -}; - -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    channel_1_frequency = freq; - -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    pwmcnt_t period = (pwmCFG.frequency / freq); -    pwmChangePeriod(&AUDIO_PWM_DRIVER, period); -    pwmEnableChannel(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, -                     // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH -                     PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); -} - -float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_1_start(void) { -    pwmStop(&AUDIO_PWM_DRIVER); -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); -} - -void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); } - -static void gpt_callback(GPTDriver *gptp); -GPTConfig   gptCFG = { -    /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 -       the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 -       the tempo (which might vary!) is in bpm (beats per minute) -       therefore: if the timer ticks away at .frequency = (60*64)Hz, -       and the .interval counts from 64 downwards - audio_update_state is -       called just often enough to not miss any notes -    */ -    .frequency = 60 * 64, -    .callback  = gpt_callback, -}; - -void audio_driver_initialize(void) { -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - -    // connect the AUDIO_PIN to the PWM hardware -#if defined(USE_GPIOV1)  // STM32F103C8 -    palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); -#else  // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) -    palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PAL_MODE)); -#endif - -    gptStart(&AUDIO_STATE_TIMER, &gptCFG); -} - -void audio_driver_start(void) { -    channel_1_stop(); -    channel_1_start(); - -    if (playing_note || playing_melody) { -        gptStartContinuous(&AUDIO_STATE_TIMER, 64); -    } -} - -void audio_driver_stop(void) { -    channel_1_stop(); -    gptStopTimer(&AUDIO_STATE_TIMER); -} - -/* a regular timer task, that checks the note to be currently played - * and updates the pwm to output that frequency - */ -static void gpt_callback(GPTDriver *gptp) { -    float freq;  // TODO: freq_alt - -    if (audio_update_state()) { -        freq = audio_get_processed_frequency(0);  // freq_alt would be index=1 -        channel_1_set_frequency(freq); -    } -} diff --git a/quantum/audio/driver_chibios_pwm_software.c b/quantum/audio/driver_chibios_pwm_software.c deleted file mode 100644 index 15c3e98b6a..0000000000 --- a/quantum/audio/driver_chibios_pwm_software.c +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright 2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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/>. - */ - -/* -Audio Driver: PWM - -the duty-cycle is always kept at 50%, and the pwm-period is adjusted to match the frequency of a note to be played back. - -this driver uses the chibios-PWM system to produce a square-wave on any given output pin in software -- a pwm callback is used to set/clear the configured pin. - - */ -#include "audio.h" -#include "ch.h" -#include "hal.h" - -#if !defined(AUDIO_PIN) -#    error "Audio feature enabled, but no pin selected - see docs/feature_audio under the ARM PWM settings" -#endif -extern bool    playing_note; -extern bool    playing_melody; -extern uint8_t note_timbre; - -static void pwm_audio_period_callback(PWMDriver *pwmp); -static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp); - -static PWMConfig pwmCFG = { -    .frequency = 100000, /* PWM clock frequency  */ -    // CHIBIOS-BUG? can't set the initial period to <2, or the pwm (hard or software) takes ~130ms with .frequency=500000 for a pwmChangePeriod to take effect; with no output=silence in the meantime -    .period   = 2, /* initial PWM period (in ticks) 1S (1/10kHz=0.1mS 0.1ms*10000 ticks=1S) */ -    .callback = pwm_audio_period_callback, -    .channels = -        { -            // software-PWM just needs another callback on any channel -            {PWM_OUTPUT_ACTIVE_HIGH, pwm_audio_channel_interrupt_callback}, /* channel 0 -> TIMx_CH1 */ -            {PWM_OUTPUT_DISABLED, NULL},                                    /* channel 1 -> TIMx_CH2 */ -            {PWM_OUTPUT_DISABLED, NULL},                                    /* channel 2 -> TIMx_CH3 */ -            {PWM_OUTPUT_DISABLED, NULL}                                     /* channel 3 -> TIMx_CH4 */ -        }, -}; - -static float channel_1_frequency = 0.0f; -void         channel_1_set_frequency(float freq) { -    channel_1_frequency = freq; - -    if (freq <= 0.0)  // a pause/rest has freq=0 -        return; - -    pwmcnt_t period = (pwmCFG.frequency / freq); -    pwmChangePeriod(&AUDIO_PWM_DRIVER, period); - -    pwmEnableChannel(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1, -                     // adjust the duty-cycle so that the output is for 'note_timbre' duration HIGH -                     PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); -} - -float channel_1_get_frequency(void) { return channel_1_frequency; } - -void channel_1_start(void) { -    pwmStop(&AUDIO_PWM_DRIVER); -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - -    pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); -    pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); -} - -void channel_1_stop(void) { -    pwmStop(&AUDIO_PWM_DRIVER); - -    palClearLine(AUDIO_PIN);  // leave the line low, after last note was played - -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    palClearLine(AUDIO_PIN_ALT);  // leave the line low, after last note was played -#endif -} - -// generate a PWM signal on any pin, not necessarily the one connected to the timer -static void pwm_audio_period_callback(PWMDriver *pwmp) { -    (void)pwmp; -    palClearLine(AUDIO_PIN); - -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    palSetLine(AUDIO_PIN_ALT); -#endif -} -static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { -    (void)pwmp; -    if (channel_1_frequency > 0) { -        palSetLine(AUDIO_PIN);  // generate a PWM signal on any pin, not necessarily the one connected to the timer -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -        palClearLine(AUDIO_PIN_ALT); -#endif -    } -} - -static void gpt_callback(GPTDriver *gptp); -GPTConfig   gptCFG = { -    /* a whole note is one beat, which is - per definition in musical_notes.h - set to 64 -       the longest note is BREAVE_DOT=128+64=192, the shortest SIXTEENTH=4 -       the tempo (which might vary!) is in bpm (beats per minute) -       therefore: if the timer ticks away at .frequency = (60*64)Hz, -       and the .interval counts from 64 downwards - audio_update_state is -       called just often enough to not miss anything -    */ -    .frequency = 60 * 64, -    .callback  = gpt_callback, -}; - -void audio_driver_initialize(void) { -    pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); - -    palSetLineMode(AUDIO_PIN, PAL_MODE_OUTPUT_PUSHPULL); -    palClearLine(AUDIO_PIN); - -#if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) -    palSetLineMode(AUDIO_PIN_ALT, PAL_MODE_OUTPUT_PUSHPULL); -    palClearLine(AUDIO_PIN_ALT); -#endif - -    pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER);  // enable pwm callbacks -    pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); - -    gptStart(&AUDIO_STATE_TIMER, &gptCFG); -} - -void audio_driver_start(void) { -    channel_1_stop(); -    channel_1_start(); - -    if (playing_note || playing_melody) { -        gptStartContinuous(&AUDIO_STATE_TIMER, 64); -    } -} - -void audio_driver_stop(void) { -    channel_1_stop(); -    gptStopTimer(&AUDIO_STATE_TIMER); -} - -/* a regular timer task, that checks the note to be currently played - * and updates the pwm to output that frequency - */ -static void gpt_callback(GPTDriver *gptp) { -    float freq;  // TODO: freq_alt - -    if (audio_update_state()) { -        freq = audio_get_processed_frequency(0);  // freq_alt would be index=1 -        channel_1_set_frequency(freq); -    } -} diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h index b54b397e1c..8e80a016aa 100644 --- a/quantum/audio/song_list.h +++ b/quantum/audio/song_list.h @@ -20,11 +20,9 @@  #include "musical_notes.h" -#if __GNUC__ > 5  // don't use for older gcc compilers since check isn't supported. -#    if __has_include("user_song_list.h") -#        include "user_song_list.h" -#    endif  // if file exists -#endif      // __GNUC__ +#if __has_include("user_song_list.h") +#    include "user_song_list.h" +#endif  // if file exists  #define NO_SOUND diff --git a/quantum/backlight/backlight_chibios.c b/quantum/backlight/backlight_chibios.c index 4d5a69e14e..7c6edd10d6 100644 --- a/quantum/backlight/backlight_chibios.c +++ b/quantum/backlight/backlight_chibios.c @@ -8,9 +8,13 @@  #    define BACKLIGHT_LIMIT_VAL 255  #endif -// GPIOV2 && GPIOV3  #ifndef BACKLIGHT_PAL_MODE -#    define BACKLIGHT_PAL_MODE 2 +#    if defined(USE_GPIOV1) +#        define BACKLIGHT_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL +#    else +// GPIOV2 && GPIOV3 +#        define BACKLIGHT_PAL_MODE 5 +#    endif  #endif  // GENERIC @@ -70,7 +74,7 @@ static uint32_t rescale_limit_val(uint32_t val) {  void backlight_init_ports(void) {  #ifdef USE_GPIOV1 -    palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL); +    palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), BACKLIGHT_PAL_MODE);  #else      palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE));  #endif diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c index 92f0ac4439..4c2ad2490c 100644 --- a/quantum/eeconfig.c +++ b/quantum/eeconfig.c @@ -4,11 +4,6 @@  #include "eeconfig.h"  #include "action_layer.h" -#ifdef STM32_EEPROM_ENABLE -#    include <hal.h> -#    include "eeprom_stm32.h" -#endif -  #if defined(EEPROM_DRIVER)  #    include "eeprom_driver.h"  #endif @@ -43,9 +38,6 @@ __attribute__((weak)) void eeconfig_init_kb(void) {   * FIXME: needs doc   */  void eeconfig_init_quantum(void) { -#ifdef STM32_EEPROM_ENABLE -    EEPROM_Erase(); -#endif  #if defined(EEPROM_DRIVER)      eeprom_driver_erase();  #endif @@ -111,9 +103,6 @@ void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_N   * FIXME: needs doc   */  void eeconfig_disable(void) { -#ifdef STM32_EEPROM_ENABLE -    EEPROM_Erase(); -#endif  #if defined(EEPROM_DRIVER)      eeprom_driver_erase();  #endif diff --git a/quantum/eeconfig.h b/quantum/eeconfig.h index bd39971b2c..22d874273c 100644 --- a/quantum/eeconfig.h +++ b/quantum/eeconfig.h @@ -111,3 +111,29 @@ void     eeconfig_update_haptic(uint32_t val);  bool eeconfig_read_handedness(void);  void eeconfig_update_handedness(bool val); + +#define EECONFIG_DEBOUNCE_HELPER(name, offset, config)                     \ +    static uint8_t dirty_##name = false;                                   \ +                                                                           \ +    static inline void eeconfig_init_##name(void) {                        \ +        eeprom_read_block(&config, offset, sizeof(config));                \ +        dirty_##name = false;                                              \ +    }                                                                      \ +    static inline void eeconfig_flush_##name(bool force) {                 \ +        if (force || dirty_##name) {                                       \ +            eeprom_update_block(&config, offset, sizeof(config));          \ +            dirty_##name = false;                                          \ +        }                                                                  \ +    }                                                                      \ +    static inline void eeconfig_flush_##name##_task(uint16_t timeout) {    \ +        static uint16_t flush_timer = 0;                                   \ +        if (timer_elapsed(flush_timer) > timeout) {                        \ +            eeconfig_flush_##name(false);                                  \ +            flush_timer = timer_read();                                    \ +        }                                                                  \ +    }                                                                      \ +    static inline void eeconfig_flag_##name(bool v) { dirty_##name |= v; } \ +    static inline void eeconfig_write_##name(typeof(config) conf) {        \ +        memcpy(&config, &conf, sizeof(config));                            \ +        eeconfig_flag_##name(true);                                        \ +    } diff --git a/quantum/keyboard.c b/quantum/keyboard.c index b98fc64e45..f2a0889c12 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -43,9 +43,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef SERIAL_MOUSE_ENABLE  #    include "serial_mouse.h"  #endif -#ifdef ADB_MOUSE_ENABLE -#    include "adb.h" -#endif  #ifdef RGBLIGHT_ENABLE  #    include "rgblight.h"  #endif @@ -61,12 +58,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef STENO_ENABLE  #    include "process_steno.h"  #endif -#ifdef SERIAL_LINK_ENABLE -#    include "serial_link/system/serial_link.h" -#endif -#ifdef VISUALIZER_ENABLE -#    include "visualizer/visualizer.h" -#endif  #ifdef POINTING_DEVICE_ENABLE  #    include "pointing_device.h"  #endif @@ -76,12 +67,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef JOYSTICK_ENABLE  #    include "process_joystick.h"  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +#    include "programmable_button.h" +#endif  #ifdef HD44780_ENABLE  #    include "hd44780.h"  #endif -#ifdef QWIIC_ENABLE -#    include "qwiic.h" -#endif  #ifdef OLED_ENABLE  #    include "oled_driver.h"  #endif @@ -97,9 +88,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #ifdef DIP_SWITCH_ENABLE  #    include "dip_switch.h"  #endif -#ifdef STM32_EEPROM_ENABLE -#    include "eeprom_stm32.h" -#endif  #ifdef EEPROM_DRIVER  #    include "eeprom_driver.h"  #endif @@ -246,9 +234,6 @@ void keyboard_setup(void) {      disable_jtag();  #endif      print_set_sendchar(sendchar); -#ifdef STM32_EEPROM_ENABLE -    EEPROM_Init(); -#endif  #ifdef EEPROM_DRIVER      eeprom_driver_init();  #endif @@ -316,9 +301,6 @@ void keyboard_init(void) {  #if defined(CRC_ENABLE)      crc_init();  #endif -#ifdef QWIIC_ENABLE -    qwiic_init(); -#endif  #ifdef OLED_ENABLE      oled_init(OLED_ROTATION_0);  #endif @@ -331,9 +313,6 @@ void keyboard_init(void) {  #ifdef SERIAL_MOUSE_ENABLE      serial_mouse_init();  #endif -#ifdef ADB_MOUSE_ENABLE -    adb_mouse_init(); -#endif  #ifdef BACKLIGHT_ENABLE      backlight_init();  #endif @@ -384,7 +363,6 @@ void switch_events(uint8_t row, uint8_t col, bool pressed) {   *   * * scan matrix   * * handle mouse movements - * * run visualizer code   * * handle midi commands   * * light LEDs   * @@ -473,10 +451,6 @@ MATRIX_LOOP_END:      if (encoders_changed) last_encoder_activity_trigger();  #endif -#ifdef QWIIC_ENABLE -    qwiic_task(); -#endif -  #ifdef OLED_ENABLE      oled_task();  #    if OLED_TIMEOUT > 0 @@ -514,18 +488,6 @@ MATRIX_LOOP_END:      serial_mouse_task();  #endif -#ifdef ADB_MOUSE_ENABLE -    adb_mouse_task(); -#endif - -#ifdef SERIAL_LINK_ENABLE -    serial_link_update(); -#endif - -#ifdef VISUALIZER_ENABLE -    visualizer_update(default_layer_state, layer_state, visualizer_get_mods(), host_keyboard_leds()); -#endif -  #ifdef POINTING_DEVICE_ENABLE      pointing_device_task();  #endif @@ -548,6 +510,10 @@ MATRIX_LOOP_END:      digitizer_task();  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +    programmable_button_send(); +#endif +      // update LED      if (led_status != host_keyboard_leds()) {          led_status = host_keyboard_leds(); diff --git a/quantum/keymap_extras/keymap_turkish_f.h b/quantum/keymap_extras/keymap_turkish_f.h index 226f8cbeb0..f86ef21546 100644 --- a/quantum/keymap_extras/keymap_turkish_f.h +++ b/quantum/keymap_extras/keymap_turkish_f.h @@ -111,7 +111,7 @@  #define TR_LPRN S(TR_8)    // (  #define TR_RPRN S(TR_9)    // )  #define TR_EQL  S(TR_0)    // = -#define TR_QUES S(TR_ASTR) // ? +#define TR_QUES S(TR_SLSH) // ?  #define TR_UNDS S(TR_MINS) // _  // Row 4  #define TR_RABK S(TR_LABK) // > diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 50510e49aa..85556d1573 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -33,14 +33,6 @@ const led_point_t k_led_matrix_center = {112, 32};  const led_point_t k_led_matrix_center = LED_MATRIX_CENTER;  #endif -// clang-format off -#ifndef LED_MATRIX_IMMEDIATE_EEPROM -#    define led_eeconfig_update(v) led_update_eeprom |= v -#else -#    define led_eeconfig_update(v) if (v) eeconfig_update_led_matrix() -#endif -// clang-format on -  // Generic effect runners  #include "led_matrix_runners.inc" @@ -107,7 +99,6 @@ last_hit_t g_last_hit_tracker;  // internals  static bool            suspend_state     = false; -static bool            led_update_eeprom = false;  static uint8_t         led_last_enable   = UINT8_MAX;  static uint8_t         led_last_effect   = UINT8_MAX;  static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false}; @@ -127,9 +118,9 @@ static last_hit_t last_hit_buffer;  const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;  #endif -void eeconfig_read_led_matrix(void) { eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); } +EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig); -void eeconfig_update_led_matrix(void) { eeprom_update_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); } +void eeconfig_update_led_matrix(void) { eeconfig_flush_led_matrix(true); }  void eeconfig_update_led_matrix_default(void) {      dprintf("eeconfig_update_led_matrix_default\n"); @@ -138,7 +129,7 @@ void eeconfig_update_led_matrix_default(void) {      led_matrix_eeconfig.val    = LED_MATRIX_STARTUP_VAL;      led_matrix_eeconfig.speed  = LED_MATRIX_STARTUP_SPD;      led_matrix_eeconfig.flags  = LED_FLAG_ALL; -    eeconfig_update_led_matrix(); +    eeconfig_flush_led_matrix(true);  }  void eeconfig_debug_led_matrix(void) { @@ -279,9 +270,8 @@ static void led_task_timers(void) {  }  static void led_task_sync(void) { +    eeconfig_flush_led_matrix(false);      // next task -    if (led_update_eeprom) eeconfig_update_led_matrix(); -    led_update_eeprom = false;      if (sync_timer_elapsed32(g_led_timer) >= LED_MATRIX_LED_FLUSH_LIMIT) led_task_state = STARTING;  } @@ -449,7 +439,7 @@ void led_matrix_init(void) {          eeconfig_update_led_matrix_default();      } -    eeconfig_read_led_matrix(); +    eeconfig_init_led_matrix();      if (!led_matrix_eeconfig.mode) {          dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");          eeconfig_update_led_matrix_default(); @@ -472,7 +462,7 @@ bool led_matrix_get_suspend_state(void) { return suspend_state; }  void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) {      led_matrix_eeconfig.enable ^= 1;      led_task_state = STARTING; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable);  }  void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); } @@ -480,7 +470,7 @@ void led_matrix_toggle(void) { led_matrix_toggle_eeprom_helper(true); }  void led_matrix_enable(void) {      led_matrix_enable_noeeprom(); -    led_eeconfig_update(true); +    eeconfig_flag_led_matrix(true);  }  void led_matrix_enable_noeeprom(void) { @@ -490,7 +480,7 @@ void led_matrix_enable_noeeprom(void) {  void led_matrix_disable(void) {      led_matrix_disable_noeeprom(); -    led_eeconfig_update(true); +    eeconfig_flag_led_matrix(true);  }  void led_matrix_disable_noeeprom(void) { @@ -512,7 +502,7 @@ void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {          led_matrix_eeconfig.mode = mode;      }      led_task_state = STARTING; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode);  }  void led_matrix_mode_noeeprom(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, false); } @@ -539,7 +529,7 @@ void led_matrix_set_val_eeprom_helper(uint8_t val, bool write_to_eeprom) {          return;      }      led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val);  }  void led_matrix_set_val_noeeprom(uint8_t val) { led_matrix_set_val_eeprom_helper(val, false); } @@ -557,7 +547,7 @@ void led_matrix_decrease_val(void) { led_matrix_decrease_val_helper(true); }  void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {      led_matrix_eeconfig.speed = speed; -    led_eeconfig_update(write_to_eeprom); +    eeconfig_flag_led_matrix(write_to_eeprom);      dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed);  }  void led_matrix_set_speed_noeeprom(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, false); } diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c index 1d46b2c506..efe0082dcb 100644 --- a/quantum/led_matrix/led_matrix_drivers.c +++ b/quantum/led_matrix/led_matrix_drivers.c @@ -26,128 +26,123 @@   */  #if defined(IS31FL3731) || defined(IS31FL3733) -  #    include "i2c_master.h"  static void init(void) {      i2c_init(); -#    ifdef IS31FL3731 -#        ifdef LED_DRIVER_ADDR_1 + +#    if defined(IS31FL3731)      IS31FL3731_init(LED_DRIVER_ADDR_1); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3731_init(LED_DRIVER_ADDR_2); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3731_init(LED_DRIVER_ADDR_3); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3731_init(LED_DRIVER_ADDR_4); -#        endif -#    else -#        ifdef LED_DRIVER_ADDR_1 -#            ifndef LED_DRIVER_SYNC_1 -#                define LED_DRIVER_SYNC_1 0 +#                endif  #            endif -    IS31FL3733_init(LED_DRIVER_ADDR_1, LED_DRIVER_SYNC_1);  #        endif -#        ifdef LED_DRIVER_ADDR_2 -#            ifndef LED_DRIVER_SYNC_2 + +#    elif defined(IS31FL3733) +#        if !defined(LED_DRIVER_SYNC_1) +#            define LED_DRIVER_SYNC_1 0 +#        endif +    IS31FL3733_init(LED_DRIVER_ADDR_1, LED_DRIVER_SYNC_1); +#        if defined(LED_DRIVER_ADDR_2) +#            if !defined(LED_DRIVER_SYNC_2)  #                define LED_DRIVER_SYNC_2 0  #            endif      IS31FL3733_init(LED_DRIVER_ADDR_2, LED_DRIVER_SYNC_2); -#        endif -#        ifdef LED_DRIVER_ADDR_3 -#            ifndef LED_DRIVER_SYNC_3 -#                define LED_DRIVER_SYNC_3 0 -#            endif +#            if defined(LED_DRIVER_ADDR_3) +#                if !defined(LED_DRIVER_SYNC_3) +#                    define LED_DRIVER_SYNC_3 0 +#                endif      IS31FL3733_init(LED_DRIVER_ADDR_3, LED_DRIVER_SYNC_3); -#        endif -#        ifdef LED_DRIVER_ADDR_4 -#            ifndef LED_DRIVER_SYNC_4 -#                define LED_DRIVER_SYNC_4 0 -#            endif +#                if defined(LED_DRIVER_ADDR_4) +#                    if !defined(LED_DRIVER_SYNC_4) +#                        define LED_DRIVER_SYNC_4 0 +#                    endif      IS31FL3733_init(LED_DRIVER_ADDR_4, LED_DRIVER_SYNC_4); +#                endif +#            endif  #        endif  #    endif      for (int index = 0; index < DRIVER_LED_TOTAL; index++) { -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)          IS31FL3731_set_led_control_register(index, true); -#    else +#    elif defined(IS31FL3733)          IS31FL3733_set_led_control_register(index, true);  #    endif      } +  // This actually updates the LED drivers -#    ifdef IS31FL3731 -#        ifdef LED_DRIVER_ADDR_1 +#    if defined(IS31FL3731)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif -#    else -#        ifdef LED_DRIVER_ADDR_1 + +#    elif defined(IS31FL3733)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  #    endif  } +#    if defined(IS31FL3731)  static void flush(void) { -#    ifdef IS31FL3731 -#        ifdef LED_DRIVER_ADDR_1      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif -#    else -#        ifdef LED_DRIVER_ADDR_1 +} + +const led_matrix_driver_t led_matrix_driver = { +    .init          = init, +    .flush         = flush, +    .set_value     = IS31FL3731_set_value, +    .set_value_all = IS31FL3731_set_value_all, +}; + +#    elif defined(IS31FL3733) +static void flush(void) {      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_1, 0); -#        endif -#        ifdef LED_DRIVER_ADDR_2 +#        if defined(LED_DRIVER_ADDR_2)      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_2, 1); -#        endif -#        ifdef LED_DRIVER_ADDR_3 +#            if defined(LED_DRIVER_ADDR_3)      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_3, 2); -#        endif -#        ifdef LED_DRIVER_ADDR_4 +#                if defined(LED_DRIVER_ADDR_4)      IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  #    endif  }  const led_matrix_driver_t led_matrix_driver = { -    .init  = init, -    .flush = flush, -#    ifdef IS31FL3731 -    .set_value     = IS31FL3731_set_value, -    .set_value_all = IS31FL3731_set_value_all, -#    else -    .set_value = IS31FL3733_set_value, +    .init          = init, +    .flush         = flush, +    .set_value     = IS31FL3733_set_value,      .set_value_all = IS31FL3733_set_value_all, -#    endif  }; -  #endif diff --git a/quantum/matrix.c b/quantum/matrix.c index 33586c431b..4fbcc2419c 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -288,10 +288,8 @@ void matrix_init(void) {      matrix_init_pins();      // initialize matrix state: all keys off -    for (uint8_t i = 0; i < MATRIX_ROWS; i++) { -        raw_matrix[i] = 0; -        matrix[i]     = 0; -    } +    memset(matrix, 0, sizeof(matrix)); +    memset(raw_matrix, 0, sizeof(raw_matrix));      debounce_init(ROWS_PER_HAND); @@ -312,24 +310,22 @@ __attribute__((weak)) bool transport_master_if_connected(matrix_row_t master_mat  bool matrix_post_scan(void) {      bool changed = false;      if (is_keyboard_master()) { +        static bool  last_connected              = false;          matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};          if (transport_master_if_connected(matrix + thisHand, slave_matrix)) { -            for (int i = 0; i < ROWS_PER_HAND; ++i) { -                if (matrix[thatHand + i] != slave_matrix[i]) { -                    matrix[thatHand + i] = slave_matrix[i]; -                    changed              = true; -                } -            } -        } else { -            // reset other half if disconnected -            for (int i = 0; i < ROWS_PER_HAND; ++i) { -                matrix[thatHand + i] = 0; -                slave_matrix[i]      = 0; -            } +            changed = memcmp(matrix + thatHand, slave_matrix, sizeof(slave_matrix)) != 0; +            last_connected = true; +        } else if (last_connected) { +            // reset other half when disconnected +            memset(slave_matrix, 0, sizeof(slave_matrix));              changed = true; + +            last_connected = false;          } +        if (changed) memcpy(matrix + thatHand, slave_matrix, sizeof(slave_matrix)); +          matrix_scan_quantum();      } else {          transport_slave(matrix + thatHand, matrix + thisHand); diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk index f7eaeec8ac..92e3a7c923 100644 --- a/quantum/mcu_selection.mk +++ b/quantum/mcu_selection.mk @@ -81,7 +81,7 @@ ifneq ($(findstring MK20DX256, $(MCU)),)    BOARD ?= PJRC_TEENSY_3_1  endif -ifneq ($(findstring MK66F18, $(MCU)),) +ifneq ($(findstring MK66FX1M0, $(MCU)),)    # Cortex version    MCU = cortex-m4 @@ -273,6 +273,38 @@ ifneq ($(findstring STM32F401, $(MCU)),)    UF2_FAMILY ?= STM32F4  endif +ifneq ($(findstring STM32F405, $(MCU)),) +  # Cortex version +  MCU = cortex-m4 + +  # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +  ARMV = 7 + +  ## chip/board settings +  # - the next two should match the directories in +  #   <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +  MCU_FAMILY = STM32 +  MCU_SERIES = STM32F4xx + +  # Linker script to use +  # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ +  #   or <keyboard_dir>/ld/ +  MCU_LDSCRIPT ?= STM32F405xG + +  # Startup code to use +  #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ +  MCU_STARTUP ?= stm32f4xx + +  # Board: it should exist either in <chibios>/os/hal/boards/, +  # <keyboard_dir>/boards/, or drivers/boards/ +  BOARD ?= GENERIC_STM32_F405XG + +  USE_FPU ?= yes + +  # UF2 settings +  UF2_FAMILY ?= STM32F4 +endif +  ifneq ($(findstring STM32F407, $(MCU)),)    # Cortex version    MCU = cortex-m4 diff --git a/quantum/process_keycode/process_haptic.c b/quantum/process_keycode/process_haptic.c index 64d455d009..1b9c2f24fa 100644 --- a/quantum/process_keycode/process_haptic.c +++ b/quantum/process_keycode/process_haptic.c @@ -32,6 +32,7 @@ __attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t              break;          case KC_LCTRL ... KC_RGUI:          case QK_MOMENTARY ... QK_MOMENTARY_MAX: +        case QK_LAYER_MOD ... QK_LAYER_MOD_MAX:  #endif  #ifdef NO_HAPTIC_FN          case KC_FN0 ... KC_FN31: diff --git a/quantum/process_keycode/process_programmable_button.c b/quantum/process_keycode/process_programmable_button.c new file mode 100644 index 0000000000..c6e77faacc --- /dev/null +++ b/quantum/process_keycode/process_programmable_button.c @@ -0,0 +1,31 @@ +/* +Copyright 2021 Thomas Weißschuh <[email protected]> + +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 "process_programmable_button.h" +#include "programmable_button.h" + +bool process_programmable_button(uint16_t keycode, keyrecord_t *record) { +    if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) { +        uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1; +        if (record->event.pressed) { +            programmable_button_on(button); +        } else { +            programmable_button_off(button); +        } +    } +    return true; +} diff --git a/quantum/process_keycode/process_programmable_button.h b/quantum/process_keycode/process_programmable_button.h new file mode 100644 index 0000000000..47c6ce5614 --- /dev/null +++ b/quantum/process_keycode/process_programmable_button.h @@ -0,0 +1,23 @@ +/* +Copyright 2021 Thomas Weißschuh <[email protected]> + +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 "quantum.h" + +bool process_programmable_button(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c index 46fcaaa86b..7853c22c5d 100644 --- a/quantum/process_keycode/process_unicode_common.c +++ b/quantum/process_keycode/process_unicode_common.c @@ -22,6 +22,7 @@  unicode_config_t unicode_config;  uint8_t          unicode_saved_mods;  bool             unicode_saved_caps_lock; +bool             unicode_saved_num_lock;  #if UNICODE_SELECTED_MODES != -1  static uint8_t selected[]     = {UNICODE_SELECTED_MODES}; @@ -79,13 +80,14 @@ void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE,  __attribute__((weak)) void unicode_input_start(void) {      unicode_saved_caps_lock = host_keyboard_led_state().caps_lock; +    unicode_saved_num_lock  = host_keyboard_led_state().num_lock;      // Note the order matters here!      // Need to do this before we mess around with the mods, or else      // UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work      // correctly in the shifted case.      if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) { -        tap_code(KC_CAPS); +        tap_code(KC_CAPSLOCK);      }      unicode_saved_mods = get_mods();  // Save current mods @@ -99,8 +101,12 @@ __attribute__((weak)) void unicode_input_start(void) {              tap_code16(UNICODE_KEY_LNX);              break;          case UC_WIN: +            // For increased reliability, use numpad keys for inputting digits +            if (!unicode_saved_num_lock) { +                tap_code(KC_NUMLOCK); +            }              register_code(KC_LALT); -            tap_code(KC_PPLS); +            tap_code(KC_KP_PLUS);              break;          case UC_WINC:              tap_code(UNICODE_KEY_WINC); @@ -117,13 +123,16 @@ __attribute__((weak)) void unicode_input_finish(void) {              unregister_code(UNICODE_KEY_MAC);              break;          case UC_LNX: -            tap_code(KC_SPC); +            tap_code(KC_SPACE);              if (unicode_saved_caps_lock) { -                tap_code(KC_CAPS); +                tap_code(KC_CAPSLOCK);              }              break;          case UC_WIN:              unregister_code(KC_LALT); +            if (!unicode_saved_num_lock) { +                tap_code(KC_NUMLOCK); +            }              break;          case UC_WINC:              tap_code(KC_ENTER); @@ -139,26 +148,44 @@ __attribute__((weak)) void unicode_input_cancel(void) {              unregister_code(UNICODE_KEY_MAC);              break;          case UC_LNX: -            tap_code(KC_ESC); +            tap_code(KC_ESCAPE);              if (unicode_saved_caps_lock) { -                tap_code(KC_CAPS); +                tap_code(KC_CAPSLOCK);              }              break;          case UC_WINC: -            tap_code(KC_ESC); +            tap_code(KC_ESCAPE);              break;          case UC_WIN:              unregister_code(KC_LALT); +            if (!unicode_saved_num_lock) { +                tap_code(KC_NUMLOCK); +            }              break;      }      set_mods(unicode_saved_mods);  // Reregister previously set mods  } +// clang-format off + +static void send_nibble_wrapper(uint8_t digit) { +    if (unicode_config.input_mode == UC_WIN) { +        uint8_t kc = digit < 10 +                   ? KC_KP_1 + (10 + digit - 1) % 10 +                   : KC_A + (digit - 10); +        tap_code(kc); +        return; +    } +    send_nibble(digit); +} + +// clang-format on +  void register_hex(uint16_t hex) {      for (int i = 3; i >= 0; i--) {          uint8_t digit = ((hex >> (i * 4)) & 0xF); -        send_nibble(digit); +        send_nibble_wrapper(digit);      }  } @@ -171,10 +198,10 @@ void register_hex32(uint32_t hex) {          uint8_t digit = ((hex >> (i * 4)) & 0xF);          if (digit == 0) {              if (!onzerostart) { -                send_nibble(digit); +                send_nibble_wrapper(digit);              }          } else { -            send_nibble(digit); +            send_nibble_wrapper(digit);              onzerostart = false;          }      } diff --git a/quantum/programmable_button.c b/quantum/programmable_button.c new file mode 100644 index 0000000000..be828fd17c --- /dev/null +++ b/quantum/programmable_button.c @@ -0,0 +1,37 @@ +/* +Copyright 2021 Thomas Weißschuh <[email protected]> + +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 "programmable_button.h" +#include "host.h" + +#define REPORT_BIT(index) (((uint32_t)1) << (index - 1)) + +static uint32_t programmable_button_report = 0; + +void programmable_button_clear(void) { programmable_button_report = 0; } + +void programmable_button_send(void) { host_programmable_button_send(programmable_button_report); } + +void programmable_button_on(uint8_t index) { programmable_button_report |= REPORT_BIT(index); } + +void programmable_button_off(uint8_t index) { programmable_button_report &= ~REPORT_BIT(index); } + +bool programmable_button_is_on(uint8_t index) { return !!(programmable_button_report & REPORT_BIT(index)); }; + +uint32_t programmable_button_get_report(void) { return programmable_button_report; }; + +void programmable_button_set_report(uint32_t report) { programmable_button_report = report; } diff --git a/quantum/programmable_button.h b/quantum/programmable_button.h new file mode 100644 index 0000000000..e89b8b9fd6 --- /dev/null +++ b/quantum/programmable_button.h @@ -0,0 +1,30 @@ +/* +Copyright 2021 Thomas Weißschuh <[email protected]> + +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" + +void     programmable_button_clear(void); +void     programmable_button_send(void); +void     programmable_button_on(uint8_t index); +void     programmable_button_off(uint8_t index); +bool     programmable_button_is_on(uint8_t index); +uint32_t programmable_button_get_report(void); +void     programmable_button_set_report(uint32_t report); diff --git a/quantum/quantum.c b/quantum/quantum.c index e60378afe4..ac8857df85 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -25,10 +25,6 @@  #    include "backlight.h"  #endif -#ifdef API_ENABLE -#    include "api.h" -#endif -  #ifdef MIDI_ENABLE  #    include "process_midi.h"  #endif @@ -145,12 +141,13 @@ void reset_keyboard(void) {  /* Convert record into usable keycode via the contained event. */  uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) {  #ifdef COMBO_ENABLE -    if (record->keycode) { return record->keycode; } +    if (record->keycode) { +        return record->keycode; +    }  #endif      return get_event_keycode(record->event, update_layer_cache);  } -  /* Convert event into usable keycode. Checks the layer cache to ensure that it   * retains the correct keycode after a layer change, if the key is still pressed.   * "update_layer_cache" is to ensure that it only updates the layer cache when @@ -179,12 +176,12 @@ uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) {  bool pre_process_record_quantum(keyrecord_t *record) {      if (!(  #ifdef COMBO_ENABLE -        process_combo(get_record_keycode(record, true), record) && +            process_combo(get_record_keycode(record, true), record) &&  #endif -        true)) { +            true)) {          return false;      } -    return true; // continue processing +    return true;  // continue processing  }  /* Get keycode, and then call keyboard function */ @@ -296,6 +293,9 @@ bool process_record_quantum(keyrecord_t *record) {  #ifdef JOYSTICK_ENABLE              process_joystick(keycode, record) &&  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +            process_programmable_button(keycode, record) && +#endif              true)) {          return false;      } @@ -465,14 +465,6 @@ void matrix_scan_quantum() {  #    include "hd44780.h"  #endif -void api_send_unicode(uint32_t unicode) { -#ifdef API_ENABLE -    uint8_t chunk[4]; -    dword_to_bytes(unicode, chunk); -    MT_SEND_DATA(DT_UNICODE, chunk, 5); -#endif -} -  //------------------------------------------------------------------------------  // Override these functions in your keymap file to play different tunes on  // different events such as startup and bootloader jump @@ -480,3 +472,99 @@ void api_send_unicode(uint32_t unicode) {  __attribute__((weak)) void startup_user() {}  __attribute__((weak)) void shutdown_user() {} + +/** \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(); } + +void suspend_power_down_quantum(void) { +#ifndef NO_SUSPEND_POWER_DOWN +// Turn off backlight +#    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); + +// 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 + +#    ifdef OLED_ENABLE +    oled_off(); +#    endif +#    ifdef ST7565_ENABLE +    st7565_off(); +#    endif +#endif +} + +/** \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(); } + +__attribute__((weak)) void suspend_wakeup_init_quantum(void) { +// 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(); +} diff --git a/quantum/quantum.h b/quantum/quantum.h index 86b717e445..9250f5acce 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -147,6 +147,10 @@ extern layer_state_t layer_state;  #    include "process_joystick.h"  #endif +#ifdef PROGRAMMABLE_BUTTON_ENABLE +#    include "process_programmable_button.h" +#endif +  #ifdef GRAVE_ESC_ENABLE  #    include "process_grave_esc.h"  #endif @@ -233,5 +237,3 @@ void led_set_user(uint8_t usb_led);  void led_set_kb(uint8_t usb_led);  bool led_update_user(led_t led_state);  bool led_update_kb(led_t led_state); - -void api_send_unicode(uint32_t unicode); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index ef4b0f457b..2ea81dd4c8 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -524,6 +524,40 @@ enum quantum_keycodes {      // Additional magic key      MAGIC_TOGGLE_GUI, +    // Programmable Button +    PROGRAMMABLE_BUTTON_1, +    PROGRAMMABLE_BUTTON_2, +    PROGRAMMABLE_BUTTON_3, +    PROGRAMMABLE_BUTTON_4, +    PROGRAMMABLE_BUTTON_5, +    PROGRAMMABLE_BUTTON_6, +    PROGRAMMABLE_BUTTON_7, +    PROGRAMMABLE_BUTTON_8, +    PROGRAMMABLE_BUTTON_9, +    PROGRAMMABLE_BUTTON_10, +    PROGRAMMABLE_BUTTON_11, +    PROGRAMMABLE_BUTTON_12, +    PROGRAMMABLE_BUTTON_13, +    PROGRAMMABLE_BUTTON_14, +    PROGRAMMABLE_BUTTON_15, +    PROGRAMMABLE_BUTTON_16, +    PROGRAMMABLE_BUTTON_17, +    PROGRAMMABLE_BUTTON_18, +    PROGRAMMABLE_BUTTON_19, +    PROGRAMMABLE_BUTTON_20, +    PROGRAMMABLE_BUTTON_21, +    PROGRAMMABLE_BUTTON_22, +    PROGRAMMABLE_BUTTON_23, +    PROGRAMMABLE_BUTTON_24, +    PROGRAMMABLE_BUTTON_25, +    PROGRAMMABLE_BUTTON_26, +    PROGRAMMABLE_BUTTON_27, +    PROGRAMMABLE_BUTTON_28, +    PROGRAMMABLE_BUTTON_29, +    PROGRAMMABLE_BUTTON_30, +    PROGRAMMABLE_BUTTON_31, +    PROGRAMMABLE_BUTTON_32, +      // Start of custom keycode range for keyboards and keymaps - always leave at the end      SAFE_RANGE  }; @@ -854,3 +888,39 @@ enum quantum_keycodes {  #define OS_TOGG ONESHOT_TOGGLE  #define OS_ON ONESHOT_ENABLE  #define OS_OFF ONESHOT_DISABLE + +// Programmable Button aliases +#define PB_1 PROGRAMMABLE_BUTTON_1 +#define PB_2 PROGRAMMABLE_BUTTON_2 +#define PB_3 PROGRAMMABLE_BUTTON_3 +#define PB_4 PROGRAMMABLE_BUTTON_4 +#define PB_5 PROGRAMMABLE_BUTTON_5 +#define PB_6 PROGRAMMABLE_BUTTON_6 +#define PB_7 PROGRAMMABLE_BUTTON_7 +#define PB_8 PROGRAMMABLE_BUTTON_8 +#define PB_9 PROGRAMMABLE_BUTTON_9 +#define PB_10 PROGRAMMABLE_BUTTON_10 +#define PB_11 PROGRAMMABLE_BUTTON_11 +#define PB_12 PROGRAMMABLE_BUTTON_12 +#define PB_13 PROGRAMMABLE_BUTTON_13 +#define PB_14 PROGRAMMABLE_BUTTON_14 +#define PB_15 PROGRAMMABLE_BUTTON_15 +#define PB_16 PROGRAMMABLE_BUTTON_16 +#define PB_17 PROGRAMMABLE_BUTTON_17 +#define PB_18 PROGRAMMABLE_BUTTON_18 +#define PB_19 PROGRAMMABLE_BUTTON_19 +#define PB_20 PROGRAMMABLE_BUTTON_20 +#define PB_21 PROGRAMMABLE_BUTTON_21 +#define PB_22 PROGRAMMABLE_BUTTON_22 +#define PB_23 PROGRAMMABLE_BUTTON_23 +#define PB_24 PROGRAMMABLE_BUTTON_24 +#define PB_25 PROGRAMMABLE_BUTTON_25 +#define PB_26 PROGRAMMABLE_BUTTON_26 +#define PB_27 PROGRAMMABLE_BUTTON_27 +#define PB_28 PROGRAMMABLE_BUTTON_28 +#define PB_29 PROGRAMMABLE_BUTTON_29 +#define PB_30 PROGRAMMABLE_BUTTON_30 +#define PB_31 PROGRAMMABLE_BUTTON_31 +#define PB_32 PROGRAMMABLE_BUTTON_32 +#define PROGRAMMABLE_BUTTON_MIN PROGRAMMABLE_BUTTON_1 +#define PROGRAMMABLE_BUTTON_MAX PROGRAMMABLE_BUTTON_32 diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 8f00b40877..c260b6e1e8 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -31,14 +31,6 @@ const led_point_t k_rgb_matrix_center = {112, 32};  const led_point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;  #endif -// clang-format off -#ifndef RGB_MATRIX_IMMEDIATE_EEPROM -#    define rgb_eeconfig_update(v) rgb_update_eeprom |= v -#else -#    define rgb_eeconfig_update(v) if (v) eeconfig_update_rgb_matrix() -#endif -// clang-format on -  __attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); }  // Generic effect runners @@ -128,7 +120,6 @@ last_hit_t g_last_hit_tracker;  // internals  static bool            suspend_state     = false; -static bool            rgb_update_eeprom = false;  static uint8_t         rgb_last_enable   = UINT8_MAX;  static uint8_t         rgb_last_effect   = UINT8_MAX;  static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false}; @@ -148,9 +139,9 @@ static last_hit_t last_hit_buffer;  const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;  #endif -void eeconfig_read_rgb_matrix(void) { eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); } +EECONFIG_DEBOUNCE_HELPER(rgb_matrix, EECONFIG_RGB_MATRIX, rgb_matrix_config); -void eeconfig_update_rgb_matrix(void) { eeprom_update_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); } +void eeconfig_update_rgb_matrix(void) { eeconfig_flush_rgb_matrix(true); }  void eeconfig_update_rgb_matrix_default(void) {      dprintf("eeconfig_update_rgb_matrix_default\n"); @@ -159,7 +150,7 @@ void eeconfig_update_rgb_matrix_default(void) {      rgb_matrix_config.hsv    = (HSV){RGB_MATRIX_STARTUP_HUE, RGB_MATRIX_STARTUP_SAT, RGB_MATRIX_STARTUP_VAL};      rgb_matrix_config.speed  = RGB_MATRIX_STARTUP_SPD;      rgb_matrix_config.flags  = LED_FLAG_ALL; -    eeconfig_update_rgb_matrix(); +    eeconfig_flush_rgb_matrix(true);  }  void eeconfig_debug_rgb_matrix(void) { @@ -314,9 +305,8 @@ static void rgb_task_timers(void) {  }  static void rgb_task_sync(void) { +    eeconfig_flush_rgb_matrix(false);      // next task -    if (rgb_update_eeprom) eeconfig_update_rgb_matrix(); -    rgb_update_eeprom = false;      if (sync_timer_elapsed32(g_rgb_timer) >= RGB_MATRIX_LED_FLUSH_LIMIT) rgb_task_state = STARTING;  } @@ -491,7 +481,7 @@ void rgb_matrix_init(void) {          eeconfig_update_rgb_matrix_default();      } -    eeconfig_read_rgb_matrix(); +    eeconfig_init_rgb_matrix();      if (!rgb_matrix_config.mode) {          dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n");          eeconfig_update_rgb_matrix_default(); @@ -514,7 +504,7 @@ bool rgb_matrix_get_suspend_state(void) { return suspend_state; }  void rgb_matrix_toggle_eeprom_helper(bool write_to_eeprom) {      rgb_matrix_config.enable ^= 1;      rgb_task_state = STARTING; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix toggle [%s]: rgb_matrix_config.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.enable);  }  void rgb_matrix_toggle_noeeprom(void) { rgb_matrix_toggle_eeprom_helper(false); } @@ -522,7 +512,7 @@ void rgb_matrix_toggle(void) { rgb_matrix_toggle_eeprom_helper(true); }  void rgb_matrix_enable(void) {      rgb_matrix_enable_noeeprom(); -    rgb_eeconfig_update(true); +    eeconfig_flag_rgb_matrix(true);  }  void rgb_matrix_enable_noeeprom(void) { @@ -532,7 +522,7 @@ void rgb_matrix_enable_noeeprom(void) {  void rgb_matrix_disable(void) {      rgb_matrix_disable_noeeprom(); -    rgb_eeconfig_update(true); +    eeconfig_flag_rgb_matrix(true);  }  void rgb_matrix_disable_noeeprom(void) { @@ -554,7 +544,7 @@ void rgb_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {          rgb_matrix_config.mode = mode;      }      rgb_task_state = STARTING; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.mode);  }  void rgb_matrix_mode_noeeprom(uint8_t mode) { rgb_matrix_mode_eeprom_helper(mode, false); } @@ -583,7 +573,7 @@ void rgb_matrix_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, boo      rgb_matrix_config.hsv.h = hue;      rgb_matrix_config.hsv.s = sat;      rgb_matrix_config.hsv.v = (val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) ? RGB_MATRIX_MAXIMUM_BRIGHTNESS : val; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix set hsv [%s]: %u,%u,%u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v);  }  void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { rgb_matrix_sethsv_eeprom_helper(hue, sat, val, false); } @@ -620,7 +610,7 @@ void rgb_matrix_decrease_val(void) { rgb_matrix_decrease_val_helper(true); }  void rgb_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {      rgb_matrix_config.speed = speed; -    rgb_eeconfig_update(write_to_eeprom); +    eeconfig_flag_rgb_matrix(write_to_eeprom);      dprintf("rgb matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.speed);  }  void rgb_matrix_set_speed_noeeprom(uint8_t speed) { rgb_matrix_set_speed_eeprom_helper(speed, false); } diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index 2cec162e22..4335088eb8 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c @@ -24,110 +24,126 @@   */  #if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) -  #    include "i2c_master.h" +// TODO: Remove this at some later date +#    if defined(DRIVER_ADDR_1) && defined(DRIVER_ADDR_2) +#        if DRIVER_ADDR_1 == DRIVER_ADDR_2 +#            error "Setting DRIVER_ADDR_2 == DRIVER_ADDR_1 is obsolete. If you are only using one ISSI driver, set DRIVER_COUNT to 1 and remove DRIVER_ADDR_2" +#        endif +#    endif +  static void init(void) {      i2c_init(); -#    ifdef IS31FL3731 + +#    if defined(IS31FL3731)      IS31FL3731_init(DRIVER_ADDR_1); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3731_init(DRIVER_ADDR_2); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3731_init(DRIVER_ADDR_3); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3731_init(DRIVER_ADDR_4); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3733) -#        ifndef DRIVER_SYNC_1 +#        if !defined(DRIVER_SYNC_1)  #            define DRIVER_SYNC_1 0  #        endif      IS31FL3733_init(DRIVER_ADDR_1, DRIVER_SYNC_1); -#        if defined DRIVER_ADDR_2 && (DRIVER_ADDR_1 != DRIVER_ADDR_2) -#            ifndef DRIVER_SYNC_2 +#        if defined(DRIVER_ADDR_2) +#            if !defined(DRIVER_SYNC_2)  #                define DRIVER_SYNC_2 0  #            endif      IS31FL3733_init(DRIVER_ADDR_2, DRIVER_SYNC_2); -#        endif -#        ifdef DRIVER_ADDR_3 -#            ifndef DRIVER_SYNC_3 -#                define DRIVER_SYNC_3 0 -#            endif +#            if defined(DRIVER_ADDR_3) +#                if !defined(DRIVER_SYNC_3) +#                    define DRIVER_SYNC_3 0 +#                endif      IS31FL3733_init(DRIVER_ADDR_3, DRIVER_SYNC_3); -#        endif -#        ifdef DRIVER_ADDR_4 -#            ifndef DRIVER_SYNC_4 -#                define DRIVER_SYNC_4 0 -#            endif +#                if defined(DRIVER_ADDR_4) +#                    if !defined(DRIVER_SYNC_4) +#                        define DRIVER_SYNC_4 0 +#                    endif      IS31FL3733_init(DRIVER_ADDR_4, DRIVER_SYNC_4); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3737)      IS31FL3737_init(DRIVER_ADDR_1); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3737_init(DRIVER_ADDR_2);  #        endif -#    else + +#    elif defined(IS31FL3741)      IS31FL3741_init(DRIVER_ADDR_1);  #    endif +      for (int index = 0; index < DRIVER_LED_TOTAL; index++) {          bool enabled = true; +          // This only caches it for later -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)          IS31FL3731_set_led_control_register(index, enabled, enabled, enabled);  #    elif defined(IS31FL3733)          IS31FL3733_set_led_control_register(index, enabled, enabled, enabled);  #    elif defined(IS31FL3737)          IS31FL3737_set_led_control_register(index, enabled, enabled, enabled); -#    else +#    elif defined(IS31FL3741)          IS31FL3741_set_led_control_register(index, enabled, enabled, enabled);  #    endif      } +      // This actually updates the LED drivers -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3731_update_led_control_registers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3733)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3733_update_led_control_registers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif +  #    elif defined(IS31FL3737)      IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1);  #        endif -#    else + +#    elif defined(IS31FL3741)      IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0);  #    endif  } -#    ifdef IS31FL3731 +#    if defined(IS31FL3731)  static void flush(void) {      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3731_update_pwm_buffers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  } @@ -137,17 +153,18 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color     = IS31FL3731_set_color,      .set_color_all = IS31FL3731_set_color_all,  }; +  #    elif defined(IS31FL3733)  static void flush(void) {      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        ifdef DRIVER_ADDR_2 +#        if defined(DRIVER_ADDR_2)      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1); -#        endif -#        ifdef DRIVER_ADDR_3 +#            if defined(DRIVER_ADDR_3)      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_3, 2); -#        endif -#        ifdef DRIVER_ADDR_4 +#                if defined(DRIVER_ADDR_4)      IS31FL3733_update_pwm_buffers(DRIVER_ADDR_4, 3); +#                endif +#            endif  #        endif  } @@ -157,10 +174,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color = IS31FL3733_set_color,      .set_color_all = IS31FL3733_set_color_all,  }; +  #    elif defined(IS31FL3737)  static void flush(void) {      IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1);  #        endif  } @@ -171,10 +189,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {      .set_color = IS31FL3737_set_color,      .set_color_all = IS31FL3737_set_color_all,  }; -#    else + +#    elif defined(IS31FL3741)  static void flush(void) {      IS31FL3741_update_pwm_buffers(DRIVER_ADDR_1, 0); -#        if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1)  // provides backward compatibility +#        if defined(DRIVER_ADDR_2)      IS31FL3741_update_pwm_buffers(DRIVER_ADDR_2, 1);  #        endif  } @@ -189,17 +208,19 @@ const rgb_matrix_driver_t rgb_matrix_driver = {  #elif defined(AW20216)  #    include "spi_master.h" +  static void init(void) {      spi_init(); +      AW20216_init(DRIVER_1_CS, DRIVER_1_EN); -#    ifdef DRIVER_2_CS +#    if defined(DRIVER_2_CS)      AW20216_init(DRIVER_2_CS, DRIVER_2_EN);  #    endif  }  static void flush(void) {      AW20216_update_pwm_buffers(DRIVER_1_CS, 0); -#    ifdef DRIVER_2_CS +#    if defined(DRIVER_2_CS)      AW20216_update_pwm_buffers(DRIVER_2_CS, 1);  #    endif  } diff --git a/quantum/sequencer/tests/rules.mk b/quantum/sequencer/tests/rules.mk index 76c221cf92..87a204669c 100644 --- a/quantum/sequencer/tests/rules.mk +++ b/quantum/sequencer/tests/rules.mk @@ -1,5 +1,5 @@  # The letter case of these variables might seem odd. However: -# - it is consistent with the serial_link example that is used as a reference in the Unit Testing article (https://docs.qmk.fm/#/unit_testing?id=adding-tests-for-new-or-existing-features) +# - it is consistent with the example that is used as a reference in the Unit Testing article (https://docs.qmk.fm/#/unit_testing?id=adding-tests-for-new-or-existing-features)  # - Neither `make test:sequencer` or `make test:SEQUENCER` work when using SCREAMING_SNAKE_CASE  sequencer_DEFS := -DNO_DEBUG -DMIDI_MOCKED diff --git a/quantum/serial_link/LICENSE b/quantum/serial_link/LICENSE deleted file mode 100644 index d13cc4b26a..0000000000 --- a/quantum/serial_link/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -The MIT License (MIT) - -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. - -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. diff --git a/quantum/serial_link/README.md b/quantum/serial_link/README.md deleted file mode 100644 index 05871dbdf7..0000000000 --- a/quantum/serial_link/README.md +++ /dev/null @@ -1 +0,0 @@ -# qmk_serial_link diff --git a/quantum/serial_link/protocol/byte_stuffer.c b/quantum/serial_link/protocol/byte_stuffer.c deleted file mode 100644 index d3a91d8286..0000000000 --- a/quantum/serial_link/protocol/byte_stuffer.c +++ /dev/null @@ -1,135 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" -#include <stdbool.h> - -// This implements the "Consistent overhead byte stuffing protocol" -// https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing -// http://www.stuartcheshire.org/papers/COBSforToN.pdf - -typedef struct byte_stuffer_state { -    uint16_t next_zero; -    uint16_t data_pos; -    bool     long_frame; -    uint8_t  data[MAX_FRAME_SIZE]; -} byte_stuffer_state_t; - -static byte_stuffer_state_t states[NUM_LINKS]; - -void init_byte_stuffer_state(byte_stuffer_state_t* state) { -    state->next_zero  = 0; -    state->data_pos   = 0; -    state->long_frame = false; -} - -void init_byte_stuffer(void) { -    int i; -    for (i = 0; i < NUM_LINKS; i++) { -        init_byte_stuffer_state(&states[i]); -    } -} - -void byte_stuffer_recv_byte(uint8_t link, uint8_t data) { -    byte_stuffer_state_t* state = &states[link]; -    // Start of a new frame -    if (state->next_zero == 0) { -        state->next_zero  = data; -        state->long_frame = data == 0xFF; -        state->data_pos   = 0; -        return; -    } - -    state->next_zero--; -    if (data == 0) { -        if (state->next_zero == 0) { -            // The frame is completed -            if (state->data_pos > 0) { -                validator_recv_frame(link, state->data, state->data_pos); -            } -        } else { -            // The frame is invalid, so reset -            init_byte_stuffer_state(state); -        } -    } else { -        if (state->data_pos == MAX_FRAME_SIZE) { -            // We exceeded our maximum frame size -            // therefore there's nothing else to do than reset to a new frame -            state->next_zero  = data; -            state->long_frame = data == 0xFF; -            state->data_pos   = 0; -        } else if (state->next_zero == 0) { -            if (state->long_frame) { -                // This is part of a long frame, so continue -                state->next_zero  = data; -                state->long_frame = data == 0xFF; -            } else { -                // Special case for zeroes -                state->next_zero               = data; -                state->data[state->data_pos++] = 0; -            } -        } else { -            state->data[state->data_pos++] = data; -        } -    } -} - -static void send_block(uint8_t link, uint8_t* start, uint8_t* end, uint8_t num_non_zero) { -    send_data(link, &num_non_zero, 1); -    if (end > start) { -        send_data(link, start, end - start); -    } -} - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { -    const uint8_t zero = 0; -    if (size > 0) { -        uint16_t num_non_zero = 1; -        uint8_t* end          = data + size; -        uint8_t* start        = data; -        while (data < end) { -            if (num_non_zero == 0xFF) { -                // There's more data after big non-zero block -                // So send it, and start a new block -                send_block(link, start, data, num_non_zero); -                start        = data; -                num_non_zero = 1; -            } else { -                if (*data == 0) { -                    // A zero encountered, so send the block -                    send_block(link, start, data, num_non_zero); -                    start        = data + 1; -                    num_non_zero = 1; -                } else { -                    num_non_zero++; -                } -                ++data; -            } -        } -        send_block(link, start, data, num_non_zero); -        send_data(link, &zero, 1); -    } -} diff --git a/quantum/serial_link/protocol/byte_stuffer.h b/quantum/serial_link/protocol/byte_stuffer.h deleted file mode 100644 index 397ed3baae..0000000000 --- a/quantum/serial_link/protocol/byte_stuffer.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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> - -#define MAX_FRAME_SIZE 1024 -#define NUM_LINKS 2 - -void init_byte_stuffer(void); -void byte_stuffer_recv_byte(uint8_t link, uint8_t data); -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/frame_router.c b/quantum/serial_link/protocol/frame_router.c deleted file mode 100644 index 5292673700..0000000000 --- a/quantum/serial_link/protocol/frame_router.c +++ /dev/null @@ -1,64 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_validator.h" - -static bool is_master; - -void router_set_master(bool master) { is_master = master; } - -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { -    if (is_master) { -        if (link == DOWN_LINK) { -            transport_recv_frame(data[size - 1], data, size - 1); -        } -    } else { -        if (link == UP_LINK) { -            if (data[size - 1] & 1) { -                transport_recv_frame(0, data, size - 1); -            } -            data[size - 1] >>= 1; -            validator_send_frame(DOWN_LINK, data, size); -        } else { -            data[size - 1]++; -            validator_send_frame(UP_LINK, data, size); -        } -    } -} - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { -    if (destination == 0) { -        if (!is_master) { -            data[size] = 1; -            validator_send_frame(UP_LINK, data, size + 1); -        } -    } else { -        if (is_master) { -            data[size] = destination; -            validator_send_frame(DOWN_LINK, data, size + 1); -        } -    } -} diff --git a/quantum/serial_link/protocol/frame_router.h b/quantum/serial_link/protocol/frame_router.h deleted file mode 100644 index 9325fe4eed..0000000000 --- a/quantum/serial_link/protocol/frame_router.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 <stdbool.h> - -#define UP_LINK 0 -#define DOWN_LINK 1 - -void router_set_master(bool master); -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size); -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/frame_validator.c b/quantum/serial_link/protocol/frame_validator.c deleted file mode 100644 index bc9136f70b..0000000000 --- a/quantum/serial_link/protocol/frame_validator.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/byte_stuffer.h" -#include <string.h> - -const uint32_t poly8_lookup[256] = {0,          0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, -                                    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, -                                    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, -                                    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; - -static uint32_t crc32_byte(uint8_t* p, uint32_t bytelength) { -    uint32_t crc = 0xffffffff; -    while (bytelength-- != 0) crc = poly8_lookup[((uint8_t)crc ^ *(p++))] ^ (crc >> 8); -    // return (~crc); also works -    return (crc ^ 0xffffffff); -} - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { -    if (size > 4) { -        uint32_t frame_crc; -        memcpy(&frame_crc, data + size - 4, 4); -        uint32_t expected_crc = crc32_byte(data, size - 4); -        if (frame_crc == expected_crc) { -            route_incoming_frame(link, data, size - 4); -        } -    } -} - -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size) { -    uint32_t crc = crc32_byte(data, size); -    memcpy(data + size, &crc, 4); -    byte_stuffer_send_frame(link, data, size + 4); -} diff --git a/quantum/serial_link/protocol/frame_validator.h b/quantum/serial_link/protocol/frame_validator.h deleted file mode 100644 index 0f78768a00..0000000000 --- a/quantum/serial_link/protocol/frame_validator.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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> - -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size); -// The buffer pointed to by the data needs 4 additional bytes -void validator_send_frame(uint8_t link, uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/physical.h b/quantum/serial_link/protocol/physical.h deleted file mode 100644 index 399c9d1f76..0000000000 --- a/quantum/serial_link/protocol/physical.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 - -void send_data(uint8_t link, const uint8_t* data, uint16_t size); diff --git a/quantum/serial_link/protocol/transport.c b/quantum/serial_link/protocol/transport.c deleted file mode 100644 index 73b8dc62e9..0000000000 --- a/quantum/serial_link/protocol/transport.c +++ /dev/null @@ -1,121 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "serial_link/protocol/triple_buffered_object.h" -#include <string.h> - -#define MAX_REMOTE_OBJECTS 16 -static remote_object_t* remote_objects[MAX_REMOTE_OBJECTS]; -static uint32_t         num_remote_objects = 0; - -void reinitialize_serial_link_transport(void) { num_remote_objects = 0; } - -void add_remote_objects(remote_object_t** _remote_objects, uint32_t _num_remote_objects) { -    unsigned int i; -    for (i = 0; i < _num_remote_objects; i++) { -        remote_object_t* obj                 = _remote_objects[i]; -        remote_objects[num_remote_objects++] = obj; -        if (obj->object_type == MASTER_TO_ALL_SLAVES) { -            triple_buffer_object_t* tb = (triple_buffer_object_t*)obj->buffer; -            triple_buffer_init(tb); -            uint8_t* start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); -            tb             = (triple_buffer_object_t*)start; -            triple_buffer_init(tb); -        } else if (obj->object_type == MASTER_TO_SINGLE_SLAVE) { -            uint8_t*     start = obj->buffer; -            unsigned int j; -            for (j = 0; j < NUM_SLAVES; j++) { -                triple_buffer_object_t* tb = (triple_buffer_object_t*)start; -                triple_buffer_init(tb); -                start += LOCAL_OBJECT_SIZE(obj->object_size); -            } -            triple_buffer_object_t* tb = (triple_buffer_object_t*)start; -            triple_buffer_init(tb); -        } else { -            uint8_t*                start = obj->buffer; -            triple_buffer_object_t* tb    = (triple_buffer_object_t*)start; -            triple_buffer_init(tb); -            start += LOCAL_OBJECT_SIZE(obj->object_size); -            unsigned int j; -            for (j = 0; j < NUM_SLAVES; j++) { -                tb = (triple_buffer_object_t*)start; -                triple_buffer_init(tb); -                start += REMOTE_OBJECT_SIZE(obj->object_size); -            } -        } -    } -} - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { -    uint8_t id = data[size - 1]; -    if (id < num_remote_objects) { -        remote_object_t* obj = remote_objects[id]; -        if (obj->object_size == size - 1) { -            uint8_t* start; -            if (obj->object_type == MASTER_TO_ALL_SLAVES) { -                start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); -            } else if (obj->object_type == SLAVE_TO_MASTER) { -                start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size); -                start += (from - 1) * REMOTE_OBJECT_SIZE(obj->object_size); -            } else { -                start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size); -            } -            triple_buffer_object_t* tb  = (triple_buffer_object_t*)start; -            void*                   ptr = triple_buffer_begin_write_internal(obj->object_size, tb); -            memcpy(ptr, data, size - 1); -            triple_buffer_end_write_internal(tb); -        } -    } -} - -void update_transport(void) { -    unsigned int i; -    for (i = 0; i < num_remote_objects; i++) { -        remote_object_t* obj = remote_objects[i]; -        if (obj->object_type == MASTER_TO_ALL_SLAVES || obj->object_type == SLAVE_TO_MASTER) { -            triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer; -            uint8_t*                ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); -            if (ptr) { -                ptr[obj->object_size] = i; -                uint8_t dest          = obj->object_type == MASTER_TO_ALL_SLAVES ? 0xFF : 0; -                router_send_frame(dest, ptr, obj->object_size + 1); -            } -        } else { -            uint8_t*     start = obj->buffer; -            unsigned int j; -            for (j = 0; j < NUM_SLAVES; j++) { -                triple_buffer_object_t* tb  = (triple_buffer_object_t*)start; -                uint8_t*                ptr = (uint8_t*)triple_buffer_read_internal(obj->object_size + LOCAL_OBJECT_EXTRA, tb); -                if (ptr) { -                    ptr[obj->object_size] = i; -                    uint8_t dest          = j + 1; -                    router_send_frame(dest, ptr, obj->object_size + 1); -                } -                start += LOCAL_OBJECT_SIZE(obj->object_size); -            } -        } -    } -} diff --git a/quantum/serial_link/protocol/transport.h b/quantum/serial_link/protocol/transport.h deleted file mode 100644 index 3ce0c9fe4e..0000000000 --- a/quantum/serial_link/protocol/transport.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" - -#define NUM_SLAVES 8 -#define LOCAL_OBJECT_EXTRA 16 - -// master -> slave = 1 local(target all), 1 remote object -// slave -> master = 1 local(target 0), multiple remote objects -// master -> single slave (multiple local, target id), 1 remote object -typedef enum { -    MASTER_TO_ALL_SLAVES, -    MASTER_TO_SINGLE_SLAVE, -    SLAVE_TO_MASTER, -} remote_object_type; - -typedef struct { -    remote_object_type object_type; -    uint16_t           object_size; -    uint8_t            buffer[] __attribute__((aligned(4))); -} remote_object_t; - -#define REMOTE_OBJECT_SIZE(objectsize) (sizeof(triple_buffer_object_t) + objectsize * 3) -#define LOCAL_OBJECT_SIZE(objectsize) (sizeof(triple_buffer_object_t) + (objectsize + LOCAL_OBJECT_EXTRA) * 3) - -#define REMOTE_OBJECT_HELPER(name, type, num_local, num_remote)                                                              \ -    typedef struct {                                                                                                         \ -        remote_object_t object;                                                                                              \ -        uint8_t         buffer[num_remote * REMOTE_OBJECT_SIZE(sizeof(type)) + num_local * LOCAL_OBJECT_SIZE(sizeof(type))]; \ -    } remote_object_##name##_t; - -#define MASTER_TO_ALL_SLAVES_OBJECT(name, type)                                                                     \ -    REMOTE_OBJECT_HELPER(name, type, 1, 1)                                                                          \ -    remote_object_##name##_t remote_object_##name = {.object = {                                                    \ -                                                         .object_type = MASTER_TO_ALL_SLAVES,                       \ -                                                         .object_size = sizeof(type),                               \ -                                                     }};                                                            \ -    type*                    begin_write_##name(void) {                                                             \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                   \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                      \ -        return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ -    }                                                                                                               \ -    void end_write_##name(void) {                                                                                   \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                                      \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                                         \ -        triple_buffer_end_write_internal(tb);                                                                       \ -        signal_data_written();                                                                                      \ -    }                                                                                                               \ -    type* read_##name(void) {                                                                                       \ -        remote_object_t*        obj   = (remote_object_t*)&remote_object_##name;                                    \ -        uint8_t*                start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);                          \ -        triple_buffer_object_t* tb    = (triple_buffer_object_t*)start;                                             \ -        return (type*)triple_buffer_read_internal(obj->object_size, tb);                                            \ -    } - -#define MASTER_TO_SINGLE_SLAVE_OBJECT(name, type)                                                                   \ -    REMOTE_OBJECT_HELPER(name, type, NUM_SLAVES, 1)                                                                 \ -    remote_object_##name##_t remote_object_##name = {.object = {                                                    \ -                                                         .object_type = MASTER_TO_SINGLE_SLAVE,                     \ -                                                         .object_size = sizeof(type),                               \ -                                                     }};                                                            \ -    type*                    begin_write_##name(uint8_t slave) {                                                    \ -        remote_object_t* obj   = (remote_object_t*)&remote_object_##name;                        \ -        uint8_t*         start = obj->buffer;                                                    \ -        start += slave * LOCAL_OBJECT_SIZE(obj->object_size);                                    \ -        triple_buffer_object_t* tb = (triple_buffer_object_t*)start;                             \ -        return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ -    }                                                                                                               \ -    void end_write_##name(uint8_t slave) {                                                                          \ -        remote_object_t* obj   = (remote_object_t*)&remote_object_##name;                                           \ -        uint8_t*         start = obj->buffer;                                                                       \ -        start += slave * LOCAL_OBJECT_SIZE(obj->object_size);                                                       \ -        triple_buffer_object_t* tb = (triple_buffer_object_t*)start;                                                \ -        triple_buffer_end_write_internal(tb);                                                                       \ -        signal_data_written();                                                                                      \ -    }                                                                                                               \ -    type* read_##name() {                                                                                           \ -        remote_object_t*        obj   = (remote_object_t*)&remote_object_##name;                                    \ -        uint8_t*                start = obj->buffer + NUM_SLAVES * LOCAL_OBJECT_SIZE(obj->object_size);             \ -        triple_buffer_object_t* tb    = (triple_buffer_object_t*)start;                                             \ -        return (type*)triple_buffer_read_internal(obj->object_size, tb);                                            \ -    } - -#define SLAVE_TO_MASTER_OBJECT(name, type)                                                                          \ -    REMOTE_OBJECT_HELPER(name, type, 1, NUM_SLAVES)                                                                 \ -    remote_object_##name##_t remote_object_##name = {.object = {                                                    \ -                                                         .object_type = SLAVE_TO_MASTER,                            \ -                                                         .object_size = sizeof(type),                               \ -                                                     }};                                                            \ -    type*                    begin_write_##name(void) {                                                             \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                   \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                      \ -        return (type*)triple_buffer_begin_write_internal(sizeof(type) + LOCAL_OBJECT_EXTRA, tb); \ -    }                                                                                                               \ -    void end_write_##name(void) {                                                                                   \ -        remote_object_t*        obj = (remote_object_t*)&remote_object_##name;                                      \ -        triple_buffer_object_t* tb  = (triple_buffer_object_t*)obj->buffer;                                         \ -        triple_buffer_end_write_internal(tb);                                                                       \ -        signal_data_written();                                                                                      \ -    }                                                                                                               \ -    type* read_##name(uint8_t slave) {                                                                              \ -        remote_object_t* obj   = (remote_object_t*)&remote_object_##name;                                           \ -        uint8_t*         start = obj->buffer + LOCAL_OBJECT_SIZE(obj->object_size);                                 \ -        start += slave * REMOTE_OBJECT_SIZE(obj->object_size);                                                      \ -        triple_buffer_object_t* tb = (triple_buffer_object_t*)start;                                                \ -        return (type*)triple_buffer_read_internal(obj->object_size, tb);                                            \ -    } - -#define REMOTE_OBJECT(name) (remote_object_t*)&remote_object_##name - -void add_remote_objects(remote_object_t** remote_objects, uint32_t num_remote_objects); -void reinitialize_serial_link_transport(void); -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size); -void update_transport(void); diff --git a/quantum/serial_link/protocol/triple_buffered_object.c b/quantum/serial_link/protocol/triple_buffered_object.c deleted file mode 100644 index e0c6d702a5..0000000000 --- a/quantum/serial_link/protocol/triple_buffered_object.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "serial_link/protocol/triple_buffered_object.h" -#include "serial_link/system/serial_link.h" -#include <stdbool.h> -#include <stddef.h> - -#define GET_READ_INDEX() object->state & 3 -#define GET_WRITE_INDEX() (object->state >> 2) & 3 -#define GET_SHARED_INDEX() (object->state >> 4) & 3 -#define GET_DATA_AVAILABLE() (object->state >> 6) & 1 - -#define SET_READ_INDEX(i) object->state = ((object->state & ~3) | i) -#define SET_WRITE_INDEX(i) object->state = ((object->state & ~(3 << 2)) | (i << 2)) -#define SET_SHARED_INDEX(i) object->state = ((object->state & ~(3 << 4)) | (i << 4)) -#define SET_DATA_AVAILABLE(i) object->state = ((object->state & ~(1 << 6)) | (i << 6)) - -void triple_buffer_init(triple_buffer_object_t* object) { -    object->state = 0; -    SET_WRITE_INDEX(0); -    SET_READ_INDEX(1); -    SET_SHARED_INDEX(2); -    SET_DATA_AVAILABLE(0); -} - -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object) { -    serial_link_lock(); -    if (GET_DATA_AVAILABLE()) { -        uint8_t shared_index = GET_SHARED_INDEX(); -        uint8_t read_index   = GET_READ_INDEX(); -        SET_READ_INDEX(shared_index); -        SET_SHARED_INDEX(read_index); -        SET_DATA_AVAILABLE(false); -        serial_link_unlock(); -        return object->buffer + object_size * shared_index; -    } else { -        serial_link_unlock(); -        return NULL; -    } -} - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object) { -    uint8_t write_index = GET_WRITE_INDEX(); -    return object->buffer + object_size * write_index; -} - -void triple_buffer_end_write_internal(triple_buffer_object_t* object) { -    serial_link_lock(); -    uint8_t shared_index = GET_SHARED_INDEX(); -    uint8_t write_index  = GET_WRITE_INDEX(); -    SET_SHARED_INDEX(write_index); -    SET_WRITE_INDEX(shared_index); -    SET_DATA_AVAILABLE(true); -    serial_link_unlock(); -} diff --git a/quantum/serial_link/protocol/triple_buffered_object.h b/quantum/serial_link/protocol/triple_buffered_object.h deleted file mode 100644 index 717d6d7b8b..0000000000 --- a/quantum/serial_link/protocol/triple_buffered_object.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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> - -typedef struct { -    uint8_t state; -    uint8_t buffer[] __attribute__((aligned(4))); -} triple_buffer_object_t; - -void triple_buffer_init(triple_buffer_object_t* object); - -#define triple_buffer_begin_write(object) (typeof(*object.buffer[0])*)triple_buffer_begin_write_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -#define triple_buffer_end_write(object) triple_buffer_end_write_internal((triple_buffer_object_t*)object) - -#define triple_buffer_read(object) (typeof(*object.buffer[0])*)triple_buffer_read_internal(sizeof(*object.buffer[0]), (triple_buffer_object_t*)object) - -void* triple_buffer_begin_write_internal(uint16_t object_size, triple_buffer_object_t* object); -void  triple_buffer_end_write_internal(triple_buffer_object_t* object); -void* triple_buffer_read_internal(uint16_t object_size, triple_buffer_object_t* object); diff --git a/quantum/serial_link/system/serial_link.c b/quantum/serial_link/system/serial_link.c deleted file mode 100644 index 6363f8ff3b..0000000000 --- a/quantum/serial_link/system/serial_link.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "report.h" -#include "host_driver.h" -#include "serial_link/system/serial_link.h" -#include <hal.h> -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/frame_router.h" -#include "matrix.h" -#include "sync_timer.h" -#include <stdbool.h> -#include "print.h" -#include "config.h" - -#define SYNC_TIMER_OFFSET 2 - -static event_source_t new_data_event; -static bool           serial_link_connected; -static bool           is_master = false; - -static uint8_t keyboard_leds(void); -static void    send_keyboard(report_keyboard_t* report); -static void    send_mouse(report_mouse_t* report); -static void    send_system(uint16_t data); -static void    send_consumer(uint16_t data); - -host_driver_t serial_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; - -// Define these in your Config.h file -#ifndef SERIAL_LINK_BAUD -#    error "Serial link baud is not set" -#endif - -#ifndef SERIAL_LINK_THREAD_PRIORITY -#    error "Serial link thread priority not set" -#endif - -static SerialConfig config = {.sc_speed = SERIAL_LINK_BAUD}; - -//#define DEBUG_LINK_ERRORS - -static uint32_t read_from_serial(SerialDriver* driver, uint8_t link) { -    const uint32_t buffer_size = 16; -    uint8_t        buffer[buffer_size]; -    uint32_t       bytes_read = sdAsynchronousRead(driver, buffer, buffer_size); -    uint8_t*       current    = buffer; -    uint8_t*       end        = current + bytes_read; -    while (current < end) { -        byte_stuffer_recv_byte(link, *current); -        current++; -    } -    return bytes_read; -} - -static void print_error(char* str, eventflags_t flags, SerialDriver* driver) { -#ifdef DEBUG_LINK_ERRORS -    if (flags & SD_PARITY_ERROR) { -        print(str); -        print(" Parity error\n"); -    } -    if (flags & SD_FRAMING_ERROR) { -        print(str); -        print(" Framing error\n"); -    } -    if (flags & SD_OVERRUN_ERROR) { -        print(str); -        uint32_t size = qSpaceI(&(driver->iqueue)); -        xprintf(" Overrun error, queue size %d\n", size); -    } -    if (flags & SD_NOISE_ERROR) { -        print(str); -        print(" Noise error\n"); -    } -    if (flags & SD_BREAK_DETECTED) { -        print(str); -        print(" Break detected\n"); -    } -#else -    (void)str; -    (void)flags; -    (void)driver; -#endif -} - -bool is_serial_link_master(void) { return is_master; } - -// TODO: Optimize the stack size, this is probably way too big -static THD_WORKING_AREA(serialThreadStack, 1024); -static THD_FUNCTION(serialThread, arg) { -    (void)arg; -    event_listener_t new_data_listener; -    event_listener_t sd1_listener; -    event_listener_t sd2_listener; -    chEvtRegister(&new_data_event, &new_data_listener, 0); -    eventflags_t events = CHN_INPUT_AVAILABLE | SD_PARITY_ERROR | SD_FRAMING_ERROR | SD_OVERRUN_ERROR | SD_NOISE_ERROR | SD_BREAK_DETECTED; -    chEvtRegisterMaskWithFlags(chnGetEventSource(&SD1), &sd1_listener, EVENT_MASK(1), events); -    chEvtRegisterMaskWithFlags(chnGetEventSource(&SD2), &sd2_listener, EVENT_MASK(2), events); -    bool need_wait = false; -    while (true) { -        eventflags_t flags1 = 0; -        eventflags_t flags2 = 0; -        if (need_wait) { -            eventmask_t mask = chEvtWaitAnyTimeout(ALL_EVENTS, TIME_MS2I(1000)); -            if (mask & EVENT_MASK(1)) { -                flags1 = chEvtGetAndClearFlags(&sd1_listener); -                print_error("DOWNLINK", flags1, &SD1); -            } -            if (mask & EVENT_MASK(2)) { -                flags2 = chEvtGetAndClearFlags(&sd2_listener); -                print_error("UPLINK", flags2, &SD2); -            } -        } - -        // Always stay as master, even if the USB goes into sleep mode -        is_master |= usbGetDriverStateI(&USBD1) == USB_ACTIVE; -        router_set_master(is_master); - -        need_wait = true; -        need_wait &= read_from_serial(&SD2, UP_LINK) == 0; -        need_wait &= read_from_serial(&SD1, DOWN_LINK) == 0; -        update_transport(); -    } -} - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { -    if (link == DOWN_LINK) { -        sdWrite(&SD1, data, size); -    } else { -        sdWrite(&SD2, data, size); -    } -} - -static systime_t last_update = 0; - -typedef struct { -    matrix_row_t rows[MATRIX_ROWS]; -} matrix_object_t; - -static matrix_object_t last_matrix = {}; - -SLAVE_TO_MASTER_OBJECT(keyboard_matrix, matrix_object_t); -MASTER_TO_ALL_SLAVES_OBJECT(serial_link_connected, bool); -#ifndef DISABLE_SYNC_TIMER -MASTER_TO_ALL_SLAVES_OBJECT(sync_timer, uint32_t); -#endif - -static remote_object_t* remote_objects[] = { -    REMOTE_OBJECT(serial_link_connected), -    REMOTE_OBJECT(keyboard_matrix), -#ifndef DISABLE_SYNC_TIMER -    REMOTE_OBJECT(sync_timer), -#endif -}; - -void init_serial_link(void) { -    serial_link_connected = false; -    init_serial_link_hal(); -    add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*)); -    init_byte_stuffer(); -    sdStart(&SD1, &config); -    sdStart(&SD2, &config); -    chEvtObjectInit(&new_data_event); -    (void)chThdCreateStatic(serialThreadStack, sizeof(serialThreadStack), SERIAL_LINK_THREAD_PRIORITY, serialThread, NULL); -} - -void matrix_set_remote(matrix_row_t* rows, uint8_t index); - -void serial_link_update(void) { -    if (read_serial_link_connected()) { -        serial_link_connected = true; -    } - -    matrix_object_t matrix; -    bool            changed = false; -    for (uint8_t i = 0; i < MATRIX_ROWS; i++) { -        matrix.rows[i] = matrix_get_row(i); -        changed |= matrix.rows[i] != last_matrix.rows[i]; -    } - -    systime_t current_time = chVTGetSystemTimeX(); -    systime_t delta        = current_time - last_update; -    if (changed || delta > TIME_US2I(5000)) { -        last_update        = current_time; -        last_matrix        = matrix; -        matrix_object_t* m = begin_write_keyboard_matrix(); -        for (uint8_t i = 0; i < MATRIX_ROWS; i++) { -            m->rows[i] = matrix.rows[i]; -        } -        end_write_keyboard_matrix(); - -        *begin_write_serial_link_connected() = true; -        end_write_serial_link_connected(); - -#ifndef DISABLE_SYNC_TIMER -        *begin_write_sync_timer() = sync_timer_read32() + SYNC_TIMER_OFFSET; -        end_write_sync_timer(); -#endif -    } - -    matrix_object_t* m = read_keyboard_matrix(0); -    if (m) { -        matrix_set_remote(m->rows, 0); -    } - -#ifndef DISABLE_SYNC_TIMER -    uint32_t* t = read_sync_timer(); -    if (t) { -        sync_timer_update(*t); -    } -#endif -} - -void signal_data_written(void) { chEvtBroadcast(&new_data_event); } - -bool is_serial_link_connected(void) { return serial_link_connected; } - -host_driver_t* get_serial_link_driver(void) { return &serial_driver; } - -// NOTE: The driver does nothing, because the master handles everything -uint8_t keyboard_leds(void) { return 0; } - -void send_keyboard(report_keyboard_t* report) { (void)report; } - -void send_mouse(report_mouse_t* report) { (void)report; } - -void send_system(uint16_t data) { (void)data; } - -void send_consumer(uint16_t data) { (void)data; } diff --git a/quantum/serial_link/system/serial_link.h b/quantum/serial_link/system/serial_link.h deleted file mode 100644 index adc1f6e93d..0000000000 --- a/quantum/serial_link/system/serial_link.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "host_driver.h" -#include <stdbool.h> - -void           init_serial_link(void); -void           init_serial_link_hal(void); -bool           is_serial_link_connected(void); -bool           is_serial_link_master(void); -host_driver_t* get_serial_link_driver(void); -void           serial_link_update(void); - -#if defined(PROTOCOL_CHIBIOS) -#    include <ch.h> - -static inline void serial_link_lock(void) { chSysLock(); } - -static inline void serial_link_unlock(void) { chSysUnlock(); } - -void signal_data_written(void); - -#else - -inline void serial_link_lock(void) {} - -inline void serial_link_unlock(void) {} - -void signal_data_written(void); - -#endif diff --git a/quantum/serial_link/tests/Makefile b/quantum/serial_link/tests/Makefile deleted file mode 100644 index 11dd355b22..0000000000 --- a/quantum/serial_link/tests/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2016 Fred Sundvik -# -# 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. -# -# 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. - -CC = gcc -CFLAGS	= -INCLUDES = -I. -I../../ -LDFLAGS = -L$(BUILDDIR)/cgreen/build-c/src -shared -LDLIBS = -lcgreen -UNITOBJ = $(BUILDDIR)/serialtest/unitobj -DEPDIR = $(BUILDDIR)/serialtest/unit.d -UNITTESTS = $(BUILDDIR)/serialtest/unittests -DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td -EXT = .so -UNAME := $(shell uname) -ifneq (, $(findstring MINGW, $(UNAME))) -	EXT = .dll -endif -ifneq (, $(findstring CYGWIN, $(UNAME))) -	EXT = .dll -endif - -SRC = $(wildcard *.c) -TESTFILES = $(patsubst %.c, $(UNITTESTS)/%$(EXT), $(SRC)) -$(shell mkdir -p $(DEPDIR) >/dev/null) - -test: $(TESTFILES) -	@$(BUILDDIR)/cgreen/build-c/tools/cgreen-runner --color $(TESTFILES) - -$(UNITTESTS)/%$(EXT): $(UNITOBJ)/%.o -	@mkdir -p $(UNITTESTS) -	$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) - -$(UNITOBJ)/%.o : %.c -$(UNITOBJ)/%.o: %.c $(DEPDIR)/%.d -	@mkdir -p $(UNITOBJ) -	$(CC) $(CFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ -	@mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d - -$(DEPDIR)/%.d: ; -.PRECIOUS: $(DEPDIR)/%.d - --include $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRC))) diff --git a/quantum/serial_link/tests/byte_stuffer_tests.cpp b/quantum/serial_link/tests/byte_stuffer_tests.cpp deleted file mode 100644 index 9e4e1768f4..0000000000 --- a/quantum/serial_link/tests/byte_stuffer_tests.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "gtest/gtest.h" -#include "gmock/gmock.h" -#include <vector> -#include <algorithm> -extern "C" { -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_validator.h" -#include "serial_link/protocol/physical.h" -} - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -class ByteStuffer : public ::testing::Test { -   public: -    ByteStuffer() { -        Instance = this; -        init_byte_stuffer(); -    } - -    ~ByteStuffer() { Instance = nullptr; } - -    MOCK_METHOD3(validator_recv_frame, void(uint8_t link, uint8_t* data, uint16_t size)); - -    void                 send_data(uint8_t link, const uint8_t* data, uint16_t size) { std::copy(data, data + size, std::back_inserter(sent_data)); } -    std::vector<uint8_t> sent_data; - -    static ByteStuffer* Instance; -}; - -ByteStuffer* ByteStuffer::Instance = nullptr; - -extern "C" { -void validator_recv_frame(uint8_t link, uint8_t* data, uint16_t size) { ByteStuffer::Instance->validator_recv_frame(link, data, size); } - -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { ByteStuffer::Instance->send_data(link, data, size); } -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_single_zero_byte) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_single_FF_byte) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 0xFF); -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_single_random_byte) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 0x4A); -} - -TEST_F(ByteStuffer, receives_no_frame_for_a_zero_length_frame) { -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_single_byte_valid_frame) { -    uint8_t expected[] = {0x37}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 0x37); -    byte_stuffer_recv_byte(0, 0); -} -TEST_F(ByteStuffer, receives_three_bytes_valid_frame) { -    uint8_t expected[] = {0x37, 0x99, 0xFF}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 4); -    byte_stuffer_recv_byte(0, 0x37); -    byte_stuffer_recv_byte(0, 0x99); -    byte_stuffer_recv_byte(0, 0xFF); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_single_zero_valid_frame) { -    uint8_t expected[] = {0}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_valid_frame_with_zeroes) { -    uint8_t expected[] = {5, 0, 3, 0}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 5); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 3); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_two_valid_frames) { -    uint8_t expected1[] = {5, 0}; -    uint8_t expected2[] = {3}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected1))); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected2))); -    byte_stuffer_recv_byte(1, 2); -    byte_stuffer_recv_byte(1, 5); -    byte_stuffer_recv_byte(1, 1); -    byte_stuffer_recv_byte(1, 0); -    byte_stuffer_recv_byte(1, 2); -    byte_stuffer_recv_byte(1, 3); -    byte_stuffer_recv_byte(1, 0); -} - -TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_zero) { -    uint8_t expected[] = {5, 7}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(1, 3); -    byte_stuffer_recv_byte(1, 1); -    byte_stuffer_recv_byte(1, 0); -    byte_stuffer_recv_byte(1, 3); -    byte_stuffer_recv_byte(1, 5); -    byte_stuffer_recv_byte(1, 7); -    byte_stuffer_recv_byte(1, 0); -} - -TEST_F(ByteStuffer, receives_valid_frame_after_unexpected_non_zero) { -    uint8_t expected[] = {5, 7}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 9); -    byte_stuffer_recv_byte(0, 4);  // This should have been zero -    byte_stuffer_recv_byte(0, 0); -    byte_stuffer_recv_byte(0, 3); -    byte_stuffer_recv_byte(0, 5); -    byte_stuffer_recv_byte(0, 7); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_and_then_end_of_frame) { -    uint8_t expected[254]; -    int     i; -    for (i = 0; i < 254; i++) { -        expected[i] = i + 1; -    } -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_non_zero) { -    uint8_t expected[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        expected[i] = i + 1; -    } -    expected[254] = 7; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 7); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_a_valid_frame_with_over254_non_zeroes_next_byte_is_zero) { -    uint8_t expected[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        expected[i] = i + 1; -    } -    expected[254] = 0; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_two_long_frames_and_some_more) { -    uint8_t expected[515]; -    int     i; -    int     j; -    for (j = 0; j < 2; j++) { -        for (i = 0; i < 254; i++) { -            expected[i + 254 * j] = i + 1; -        } -    } -    for (i = 0; i < 7; i++) { -        expected[254 * 2 + i] = i + 1; -    } -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 0xFF); -    for (i = 0; i < 254; i++) { -        byte_stuffer_recv_byte(0, i + 1); -    } -    byte_stuffer_recv_byte(0, 8); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 3); -    byte_stuffer_recv_byte(0, 4); -    byte_stuffer_recv_byte(0, 5); -    byte_stuffer_recv_byte(0, 6); -    byte_stuffer_recv_byte(0, 7); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, receives_an_all_zeros_frame_that_is_maximum_size) { -    uint8_t expected[MAX_FRAME_SIZE] = {}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    int i; -    byte_stuffer_recv_byte(0, 1); -    for (i = 0; i < MAX_FRAME_SIZE; i++) { -        byte_stuffer_recv_byte(0, 1); -    } -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, doesnt_recv_a_frame_thats_too_long_all_zeroes) { -    uint8_t expected[1] = {0}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).Times(0); -    int i; -    byte_stuffer_recv_byte(0, 1); -    for (i = 0; i < MAX_FRAME_SIZE; i++) { -        byte_stuffer_recv_byte(0, 1); -    } -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, received_frame_is_aborted_when_its_too_long) { -    uint8_t expected[1] = {1}; -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    int i; -    byte_stuffer_recv_byte(0, 1); -    for (i = 0; i < MAX_FRAME_SIZE; i++) { -        byte_stuffer_recv_byte(0, 1); -    } -    byte_stuffer_recv_byte(0, 2); -    byte_stuffer_recv_byte(0, 1); -    byte_stuffer_recv_byte(0, 0); -} - -TEST_F(ByteStuffer, does_nothing_when_sending_zero_size_frame) { -    EXPECT_EQ(sent_data.size(), 0); -    byte_stuffer_send_frame(0, NULL, 0); -} - -TEST_F(ByteStuffer, send_one_byte_frame) { -    uint8_t data[] = {5}; -    byte_stuffer_send_frame(1, data, 1); -    uint8_t expected[] = {2, 5, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_two_byte_frame) { -    uint8_t data[] = {5, 0x77}; -    byte_stuffer_send_frame(0, data, 2); -    uint8_t expected[] = {3, 5, 0x77, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_one_byte_frame_with_zero) { -    uint8_t data[] = {0}; -    byte_stuffer_send_frame(0, data, 1); -    uint8_t expected[] = {1, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_two_byte_frame_starting_with_zero) { -    uint8_t data[] = {0, 9}; -    byte_stuffer_send_frame(1, data, 2); -    uint8_t expected[] = {1, 2, 9, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_two_byte_frame_starting_with_non_zero) { -    uint8_t data[] = {9, 0}; -    byte_stuffer_send_frame(1, data, 2); -    uint8_t expected[] = {2, 9, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_three_byte_frame_zero_in_the_middle) { -    uint8_t data[] = {9, 0, 0x68}; -    byte_stuffer_send_frame(0, data, 3); -    uint8_t expected[] = {2, 9, 2, 0x68, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_three_byte_frame_data_in_the_middle) { -    uint8_t data[] = {0, 0x55, 0}; -    byte_stuffer_send_frame(0, data, 3); -    uint8_t expected[] = {1, 2, 0x55, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_three_byte_frame_with_all_zeroes) { -    uint8_t data[] = {0, 0, 0}; -    byte_stuffer_send_frame(0, data, 3); -    uint8_t expected[] = {1, 1, 1, 1, 0}; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_frame_with_254_non_zeroes) { -    uint8_t data[254]; -    int     i; -    for (i = 0; i < 254; i++) { -        data[i] = i + 1; -    } -    byte_stuffer_send_frame(0, data, 254); -    uint8_t expected[256]; -    expected[0] = 0xFF; -    for (i = 1; i < 255; i++) { -        expected[i] = i; -    } -    expected[255] = 0; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_frame_with_255_non_zeroes) { -    uint8_t data[255]; -    int     i; -    for (i = 0; i < 255; i++) { -        data[i] = i + 1; -    } -    byte_stuffer_send_frame(0, data, 255); -    uint8_t expected[258]; -    expected[0] = 0xFF; -    for (i = 1; i < 255; i++) { -        expected[i] = i; -    } -    expected[255] = 2; -    expected[256] = 255; -    expected[257] = 0; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_frame_with_254_non_zeroes_followed_by_zero) { -    uint8_t data[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        data[i] = i + 1; -    } -    data[254] = 0; -    byte_stuffer_send_frame(0, data, 255); -    uint8_t expected[258]; -    expected[0] = 0xFF; -    for (i = 1; i < 255; i++) { -        expected[i] = i; -    } -    expected[255] = 1; -    expected[256] = 1; -    expected[257] = 0; -    EXPECT_THAT(sent_data, ElementsAreArray(expected)); -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet) { -    uint8_t original_data[] = {1, 2, 3}; -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    int i; -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_small_packet_with_zeros) { -    uint8_t original_data[] = {1, 0, 3, 0, 0, 9}; -    byte_stuffer_send_frame(1, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    int i; -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes) { -    uint8_t original_data[254]; -    int     i; -    for (i = 0; i < 254; i++) { -        original_data[i] = i + 1; -    } -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_256_bytes) { -    uint8_t original_data[256]; -    int     i; -    for (i = 0; i < 254; i++) { -        original_data[i] = i + 1; -    } -    original_data[254] = 22; -    original_data[255] = 23; -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} - -TEST_F(ByteStuffer, sends_and_receives_full_roundtrip_254_bytes_and_then_zero) { -    uint8_t original_data[255]; -    int     i; -    for (i = 0; i < 254; i++) { -        original_data[i] = i + 1; -    } -    original_data[254] = 0; -    byte_stuffer_send_frame(0, original_data, sizeof(original_data)); -    EXPECT_CALL(*this, validator_recv_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(original_data))); -    for (auto& d : sent_data) { -        byte_stuffer_recv_byte(1, d); -    } -} diff --git a/quantum/serial_link/tests/frame_router_tests.cpp b/quantum/serial_link/tests/frame_router_tests.cpp deleted file mode 100644 index f76dfb33d6..0000000000 --- a/quantum/serial_link/tests/frame_router_tests.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "gtest/gtest.h" -#include "gmock/gmock.h" -#include <array> -extern "C" { -#include "serial_link/protocol/transport.h" -#include "serial_link/protocol/byte_stuffer.h" -#include "serial_link/protocol/frame_router.h" -} - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -class FrameRouter : public testing::Test { -   public: -    FrameRouter() : current_router_buffer(nullptr) { -        Instance = this; -        init_byte_stuffer(); -    } - -    ~FrameRouter() { Instance = nullptr; } - -    void send_data(uint8_t link, const uint8_t* data, uint16_t size) { -        auto& buffer = current_router_buffer->send_buffers[link]; -        std::copy(data, data + size, std::back_inserter(buffer)); -    } - -    void receive_data(uint8_t link, uint8_t* data, uint16_t size) { -        int i; -        for (i = 0; i < size; i++) { -            byte_stuffer_recv_byte(link, data[i]); -        } -    } - -    void activate_router(uint8_t num) { -        current_router_buffer = router_buffers + num; -        router_set_master(num == 0); -    } - -    void simulate_transport(uint8_t from, uint8_t to) { -        activate_router(to); -        if (from > to) { -            receive_data(DOWN_LINK, router_buffers[from].send_buffers[UP_LINK].data(), router_buffers[from].send_buffers[UP_LINK].size()); -        } else if (to > from) { -            receive_data(UP_LINK, router_buffers[from].send_buffers[DOWN_LINK].data(), router_buffers[from].send_buffers[DOWN_LINK].size()); -        } -    } - -    MOCK_METHOD3(transport_recv_frame, void(uint8_t from, uint8_t* data, uint16_t size)); - -    std::vector<uint8_t> received_data; - -    struct router_buffer { -        std::vector<uint8_t> send_buffers[2]; -    }; - -    router_buffer  router_buffers[8]; -    router_buffer* current_router_buffer; - -    static FrameRouter* Instance; -}; - -FrameRouter* FrameRouter::Instance = nullptr; - -typedef struct { -    std::array<uint8_t, 4> data; -    uint8_t                extra[16]; -} frame_buffer_t; - -extern "C" { -void send_data(uint8_t link, const uint8_t* data, uint16_t size) { FrameRouter::Instance->send_data(link, data, size); } - -void transport_recv_frame(uint8_t from, uint8_t* data, uint16_t size) { FrameRouter::Instance->transport_recv_frame(from, data, size); } -} - -TEST_F(FrameRouter, master_broadcast_is_received_by_everyone) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(0); -    router_send_frame(0xFF, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(0, 1); -    EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 2); -    EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, master_send_is_received_by_targets) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(0); -    router_send_frame((1 << 1) | (1 << 2), (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); - -    simulate_transport(0, 1); -    EXPECT_GT(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 2); -    EXPECT_GT(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[2].send_buffers[UP_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(0, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(2, 3); -    EXPECT_GT(router_buffers[3].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[3].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, first_link_sends_to_master) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(1); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(1, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, second_link_sends_to_master) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(2); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[2].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[2].send_buffers[DOWN_LINK].size(), 0); - -    simulate_transport(2, 1); -    EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(2, _, _)).With(Args<1, 2>(ElementsAreArray(data.data))); -    simulate_transport(1, 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -} - -TEST_F(FrameRouter, master_sends_to_master_does_nothing) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(0); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -} - -TEST_F(FrameRouter, link_sends_to_other_link_does_nothing) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(1); -    router_send_frame(2, (uint8_t*)&data, 4); -    EXPECT_EQ(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); -} - -TEST_F(FrameRouter, master_receives_on_uplink_does_nothing) { -    frame_buffer_t data; -    data.data = {0xAB, 0x70, 0x55, 0xBB}; -    activate_router(1); -    router_send_frame(0, (uint8_t*)&data, 4); -    EXPECT_GT(router_buffers[1].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[1].send_buffers[DOWN_LINK].size(), 0); - -    EXPECT_CALL(*this, transport_recv_frame(_, _, _)).Times(0); -    activate_router(0); -    receive_data(UP_LINK, router_buffers[1].send_buffers[UP_LINK].data(), router_buffers[1].send_buffers[UP_LINK].size()); -    EXPECT_EQ(router_buffers[0].send_buffers[UP_LINK].size(), 0); -    EXPECT_EQ(router_buffers[0].send_buffers[DOWN_LINK].size(), 0); -} diff --git a/quantum/serial_link/tests/frame_validator_tests.cpp b/quantum/serial_link/tests/frame_validator_tests.cpp deleted file mode 100644 index 43dc57b633..0000000000 --- a/quantum/serial_link/tests/frame_validator_tests.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "gtest/gtest.h" -#include "gmock/gmock.h" -extern "C" { -#include "serial_link/protocol/frame_validator.h" -} - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -class FrameValidator : public testing::Test { -   public: -    FrameValidator() { Instance = this; } - -    ~FrameValidator() { Instance = nullptr; } - -    MOCK_METHOD3(route_incoming_frame, void(uint8_t link, uint8_t* data, uint16_t size)); -    MOCK_METHOD3(byte_stuffer_send_frame, void(uint8_t link, uint8_t* data, uint16_t size)); - -    static FrameValidator* Instance; -}; - -FrameValidator* FrameValidator::Instance = nullptr; - -extern "C" { -void route_incoming_frame(uint8_t link, uint8_t* data, uint16_t size) { FrameValidator::Instance->route_incoming_frame(link, data, size); } - -void byte_stuffer_send_frame(uint8_t link, uint8_t* data, uint16_t size) { FrameValidator::Instance->byte_stuffer_send_frame(link, data, size); } -} - -TEST_F(FrameValidator, doesnt_validate_frames_under_5_bytes) { -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).Times(0); -    uint8_t data[] = {1, 2}; -    validator_recv_frame(0, 0, 1); -    validator_recv_frame(0, data, 2); -    validator_recv_frame(0, data, 3); -    validator_recv_frame(0, data, 4); -} - -TEST_F(FrameValidator, validates_one_byte_frame_with_correct_crc) { -    uint8_t data[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(data, 1))); -    validator_recv_frame(0, data, 5); -} - -TEST_F(FrameValidator, does_not_validate_one_byte_frame_with_incorrect_crc) { -    uint8_t data[] = {0x44, 0, 0, 0, 0}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).Times(0); -    validator_recv_frame(1, data, 5); -} - -TEST_F(FrameValidator, validates_four_byte_frame_with_correct_crc) { -    uint8_t data[] = {0x44, 0x10, 0xFF, 0x00, 0x74, 0x4E, 0x30, 0xBA}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(data, 4))); -    validator_recv_frame(1, data, 8); -} - -TEST_F(FrameValidator, validates_five_byte_frame_with_correct_crc) { -    uint8_t data[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; -    EXPECT_CALL(*this, route_incoming_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(data, 5))); -    validator_recv_frame(0, data, 9); -} - -TEST_F(FrameValidator, sends_one_byte_with_correct_crc) { -    uint8_t original[] = {0x44, 0, 0, 0, 0}; -    uint8_t expected[] = {0x44, 0x04, 0x6A, 0xB3, 0xA3}; -    EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    validator_send_frame(0, original, 1); -} - -TEST_F(FrameValidator, sends_five_bytes_with_correct_crc) { -    uint8_t original[] = {1, 2, 3, 4, 5, 0, 0, 0, 0}; -    uint8_t expected[] = {1, 2, 3, 4, 5, 0xF4, 0x99, 0x0B, 0x47}; -    EXPECT_CALL(*this, byte_stuffer_send_frame(_, _, _)).With(Args<1, 2>(ElementsAreArray(expected))); -    validator_send_frame(0, original, 5); -} diff --git a/quantum/serial_link/tests/rules.mk b/quantum/serial_link/tests/rules.mk deleted file mode 100644 index b81515bc55..0000000000 --- a/quantum/serial_link/tests/rules.mk +++ /dev/null @@ -1,22 +0,0 @@ -serial_link_byte_stuffer_SRC :=\ -	$(SERIAL_PATH)/tests/byte_stuffer_tests.cpp \ -	$(SERIAL_PATH)/protocol/byte_stuffer.c - -serial_link_frame_validator_SRC := \ -	$(SERIAL_PATH)/tests/frame_validator_tests.cpp \ -	$(SERIAL_PATH)/protocol/frame_validator.c  - -serial_link_frame_router_SRC := \ -	$(SERIAL_PATH)/tests/frame_router_tests.cpp \ -	$(SERIAL_PATH)/protocol/byte_stuffer.c \ -	$(SERIAL_PATH)/protocol/frame_validator.c \ -	$(SERIAL_PATH)/protocol/frame_router.c - -serial_link_triple_buffered_object_SRC := \ -	$(SERIAL_PATH)/tests/triple_buffered_object_tests.cpp \ -	$(SERIAL_PATH)/protocol/triple_buffered_object.c  - -serial_link_transport_SRC := \ -	$(SERIAL_PATH)/tests/transport_tests.cpp \ -	$(SERIAL_PATH)/protocol/transport.c \ -	$(SERIAL_PATH)/protocol/triple_buffered_object.c  diff --git a/quantum/serial_link/tests/testlist.mk b/quantum/serial_link/tests/testlist.mk deleted file mode 100644 index c5edaf478f..0000000000 --- a/quantum/serial_link/tests/testlist.mk +++ /dev/null @@ -1,6 +0,0 @@ -TEST_LIST +=\ -	serial_link_byte_stuffer\ -	serial_link_frame_validator\ -	serial_link_frame_router\ -	serial_link_triple_buffered_object\ -	serial_link_transport diff --git a/quantum/serial_link/tests/transport_tests.cpp b/quantum/serial_link/tests/transport_tests.cpp deleted file mode 100644 index cfd1110460..0000000000 --- a/quantum/serial_link/tests/transport_tests.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "gtest/gtest.h" -#include "gmock/gmock.h" - -using testing::_; -using testing::Args; -using testing::ElementsAreArray; - -extern "C" { -#include "serial_link/protocol/transport.h" -} - -struct test_object1 { -    uint32_t test; -}; - -struct test_object2 { -    uint32_t test1; -    uint32_t test2; -}; - -MASTER_TO_ALL_SLAVES_OBJECT(master_to_slave, test_object1); -MASTER_TO_SINGLE_SLAVE_OBJECT(master_to_single_slave, test_object1); -SLAVE_TO_MASTER_OBJECT(slave_to_master, test_object1); - -static remote_object_t* test_remote_objects[] = { -    REMOTE_OBJECT(master_to_slave), -    REMOTE_OBJECT(master_to_single_slave), -    REMOTE_OBJECT(slave_to_master), -}; - -class Transport : public testing::Test { -   public: -    Transport() { -        Instance = this; -        add_remote_objects(test_remote_objects, sizeof(test_remote_objects) / sizeof(remote_object_t*)); -    } - -    ~Transport() { -        Instance = nullptr; -        reinitialize_serial_link_transport(); -    } - -    MOCK_METHOD0(signal_data_written, void()); -    MOCK_METHOD1(router_send_frame, void(uint8_t destination)); - -    void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { -        router_send_frame(destination); -        std::copy(data, data + size, std::back_inserter(sent_data)); -    } - -    static Transport* Instance; - -    std::vector<uint8_t> sent_data; -}; - -Transport* Transport::Instance = nullptr; - -extern "C" { -void signal_data_written(void) { Transport::Instance->signal_data_written(); } - -void router_send_frame(uint8_t destination, uint8_t* data, uint16_t size) { Transport::Instance->router_send_frame(destination, data, size); } -} - -TEST_F(Transport, write_to_local_signals_an_event) { -    begin_write_master_to_slave(); -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    begin_write_slave_to_master(); -    EXPECT_CALL(*this, signal_data_written()); -    end_write_slave_to_master(); -    begin_write_master_to_single_slave(1); -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_single_slave(1); -} - -TEST_F(Transport, writes_from_master_to_all_slaves) { -    update_transport(); -    test_object1* obj = begin_write_master_to_slave(); -    obj->test         = 5; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    EXPECT_CALL(*this, router_send_frame(0xFF)); -    update_transport(); -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_slave(); -    EXPECT_NE(obj2, nullptr); -    EXPECT_EQ(obj2->test, 5); -} - -TEST_F(Transport, writes_from_slave_to_master) { -    update_transport(); -    test_object1* obj = begin_write_slave_to_master(); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_slave_to_master(); -    EXPECT_CALL(*this, router_send_frame(0)); -    update_transport(); -    transport_recv_frame(3, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_slave_to_master(2); -    EXPECT_EQ(read_slave_to_master(0), nullptr); -    EXPECT_NE(obj2, nullptr); -    EXPECT_EQ(obj2->test, 7); -} - -TEST_F(Transport, writes_from_master_to_single_slave) { -    update_transport(); -    test_object1* obj = begin_write_master_to_single_slave(3); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_single_slave(3); -    EXPECT_CALL(*this, router_send_frame(4)); -    update_transport(); -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_single_slave(); -    EXPECT_NE(obj2, nullptr); -    EXPECT_EQ(obj2->test, 7); -} - -TEST_F(Transport, ignores_object_with_invalid_id) { -    update_transport(); -    test_object1* obj = begin_write_master_to_single_slave(3); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_single_slave(3); -    EXPECT_CALL(*this, router_send_frame(4)); -    update_transport(); -    sent_data[sent_data.size() - 1] = 44; -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_single_slave(); -    EXPECT_EQ(obj2, nullptr); -} - -TEST_F(Transport, ignores_object_with_size_too_small) { -    update_transport(); -    test_object1* obj = begin_write_master_to_slave(); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    EXPECT_CALL(*this, router_send_frame(_)); -    update_transport(); -    sent_data[sent_data.size() - 2] = 0; -    transport_recv_frame(0, sent_data.data(), sent_data.size() - 1); -    test_object1* obj2 = read_master_to_slave(); -    EXPECT_EQ(obj2, nullptr); -} - -TEST_F(Transport, ignores_object_with_size_too_big) { -    update_transport(); -    test_object1* obj = begin_write_master_to_slave(); -    obj->test         = 7; -    EXPECT_CALL(*this, signal_data_written()); -    end_write_master_to_slave(); -    EXPECT_CALL(*this, router_send_frame(_)); -    update_transport(); -    sent_data.resize(sent_data.size() + 22); -    sent_data[sent_data.size() - 1] = 0; -    transport_recv_frame(0, sent_data.data(), sent_data.size()); -    test_object1* obj2 = read_master_to_slave(); -    EXPECT_EQ(obj2, nullptr); -} diff --git a/quantum/serial_link/tests/triple_buffered_object_tests.cpp b/quantum/serial_link/tests/triple_buffered_object_tests.cpp deleted file mode 100644 index 8de9bfdebf..0000000000 --- a/quantum/serial_link/tests/triple_buffered_object_tests.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "gtest/gtest.h" -extern "C" { -#include "serial_link/protocol/triple_buffered_object.h" -} - -struct test_object { -    uint8_t  state; -    uint32_t buffer[3]; -}; - -test_object test_object; - -class TripleBufferedObject : public testing::Test { -   public: -    TripleBufferedObject() { triple_buffer_init((triple_buffer_object_t*)&test_object); } -}; - -TEST_F(TripleBufferedObject, writes_and_reads_object) { -    *triple_buffer_begin_write(&test_object) = 0x3456ABCC; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*triple_buffer_read(&test_object), 0x3456ABCC); -} - -TEST_F(TripleBufferedObject, does_not_read_empty) { EXPECT_EQ(triple_buffer_read(&test_object), nullptr); } - -TEST_F(TripleBufferedObject, writes_twice_and_reads_object) { -    *triple_buffer_begin_write(&test_object) = 0x3456ABCC; -    triple_buffer_end_write(&test_object); -    *triple_buffer_begin_write(&test_object) = 0x44778899; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*triple_buffer_read(&test_object), 0x44778899); -} - -TEST_F(TripleBufferedObject, performs_another_write_in_the_middle_of_read) { -    *triple_buffer_begin_write(&test_object) = 1; -    triple_buffer_end_write(&test_object); -    uint32_t* read                           = triple_buffer_read(&test_object); -    *triple_buffer_begin_write(&test_object) = 2; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*read, 1); -    EXPECT_EQ(*triple_buffer_read(&test_object), 2); -    EXPECT_EQ(triple_buffer_read(&test_object), nullptr); -} - -TEST_F(TripleBufferedObject, performs_two_writes_in_the_middle_of_read) { -    *triple_buffer_begin_write(&test_object) = 1; -    triple_buffer_end_write(&test_object); -    uint32_t* read                           = triple_buffer_read(&test_object); -    *triple_buffer_begin_write(&test_object) = 2; -    triple_buffer_end_write(&test_object); -    *triple_buffer_begin_write(&test_object) = 3; -    triple_buffer_end_write(&test_object); -    EXPECT_EQ(*read, 1); -    EXPECT_EQ(*triple_buffer_read(&test_object), 3); -    EXPECT_EQ(triple_buffer_read(&test_object), nullptr); -} diff --git a/quantum/usb_device_state.c b/quantum/usb_device_state.c new file mode 100644 index 0000000000..5ccd309ec2 --- /dev/null +++ b/quantum/usb_device_state.c @@ -0,0 +1,51 @@ +/* + * Copyright 2021 Andrei Purdea <[email protected]> + * + * 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 "usb_device_state.h" + +enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT; + +__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { notify_usb_device_state_change_user(usb_device_state); } + +__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {} + +static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { notify_usb_device_state_change_kb(usb_device_state); } + +void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) { +    usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; +    notify_usb_device_state_change(usb_device_state); +} + +void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) { +    usb_device_state = USB_DEVICE_STATE_SUSPEND; +    notify_usb_device_state_change(usb_device_state); +} + +void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) { +    usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; +    notify_usb_device_state_change(usb_device_state); +} + +void usb_device_state_set_reset(void) { +    usb_device_state = USB_DEVICE_STATE_INIT; +    notify_usb_device_state_change(usb_device_state); +} + +void usb_device_state_init(void) { +    usb_device_state = USB_DEVICE_STATE_INIT; +    notify_usb_device_state_change(usb_device_state); +} diff --git a/quantum/usb_device_state.h b/quantum/usb_device_state.h new file mode 100644 index 0000000000..c229311d46 --- /dev/null +++ b/quantum/usb_device_state.h @@ -0,0 +1,39 @@ +/* + * Copyright 2021 Andrei Purdea <[email protected]> + * + * 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 <stdbool.h> +#include <stdint.h> + +void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber); +void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber); +void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber); +void usb_device_state_set_reset(void); +void usb_device_state_init(void); + +enum usb_device_state { +    USB_DEVICE_STATE_NO_INIT    = 0,  // We're in this state before calling usb_device_state_init() +    USB_DEVICE_STATE_INIT       = 1,  // Can consume up to 100mA +    USB_DEVICE_STATE_CONFIGURED = 2,  // Can consume up to what is specified in configuration descriptor, typically 500mA +    USB_DEVICE_STATE_SUSPEND    = 3   // Can consume only suspend current +}; + +extern enum usb_device_state usb_device_state; + +void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state); +void notify_usb_device_state_change_user(enum usb_device_state usb_device_state); diff --git a/quantum/visualizer/LICENSE.md b/quantum/visualizer/LICENSE.md deleted file mode 100644 index 22d4c3f08b..0000000000 --- a/quantum/visualizer/LICENSE.md +++ /dev/null @@ -1,29 +0,0 @@ -The files in this project are licensed under the MIT license -It uses the following libraries -uGFX - with it's own license, see the license.html file in the uGFX subfolder for more information -tmk_core - is indirectly used and not included in the repository. It's licensed under the GPLv2 license -Chibios - which is used by tmk_core is licensed under GPLv3. - -Therefore the effective license for any project using the library is GPLv3 - -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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. diff --git a/quantum/visualizer/common_gfxconf.h b/quantum/visualizer/common_gfxconf.h deleted file mode 100644 index e0735b37d0..0000000000 --- a/quantum/visualizer/common_gfxconf.h +++ /dev/null @@ -1,354 +0,0 @@ -/** - * This file has a different license to the rest of the uGFX system. - * You can copy, modify and distribute this file as you see fit. - * You do not need to publish your source modifications to this file. - * The only thing you are not permitted to do is to relicense it - * under a different license. - */ - -/** - * Copy this file into your project directory and rename it as gfxconf.h - * Edit your copy to turn on the uGFX features you want to use. - * The values below are the defaults. - * - * Only remove the comments from lines where you want to change the - * default value. This allows definitions to be included from - * driver makefiles when required and provides the best future - * compatibility for your project. - * - * Please use spaces instead of tabs in this file. - */ - -#pragma once - -/////////////////////////////////////////////////////////////////////////// -// GFX - Compatibility options                                           // -/////////////////////////////////////////////////////////////////////////// -//#define GFX_COMPAT_V2                                GFXON -//#define GFX_COMPAT_OLDCOLORS                         GFXON - -/////////////////////////////////////////////////////////////////////////// -// GOS - One of these must be defined, preferably in your Makefile       // -/////////////////////////////////////////////////////////////////////////// -//#define GFX_USE_OS_CHIBIOS                           GFXOFF -//#define GFX_USE_OS_FREERTOS                          GFXOFF -//    #define GFX_FREERTOS_USE_TRACE                   GFXOFF -//#define GFX_USE_OS_WIN32                             GFXOFF -//#define GFX_USE_OS_LINUX                             GFXOFF -//#define GFX_USE_OS_OSX                               GFXOFF -//#define GFX_USE_OS_ECOS                              GFXOFF -//#define GFX_USE_OS_RAWRTOS                           GFXOFF -//#define GFX_USE_OS_ARDUINO                           GFXOFF -//#define GFX_USE_OS_KEIL                              GFXOFF -//#define GFX_USE_OS_RTX5                              GFXOFF -//#define GFX_USE_OS_CMSIS                             GFXOFF -//#define GFX_USE_OS_CMSIS2                            GFXOFF -//#define GFX_USE_OS_RAW32                             GFXOFF -//#define GFX_USE_OS_ZEPHYR                            GFXOFF -//#define GFX_USE_OS_NIOS                              GFXOFF -//#define GFX_USE_OS_QT                                GFXOFF -//    #define INTERRUPTS_OFF()                         optional_code -//    #define INTERRUPTS_ON()                          optional_code - -// Options that (should where relevant) apply to all operating systems -#define GFX_NO_INLINE GFXON -//    #define GFX_COMPILER                             GFX_COMPILER_UNKNOWN -//    #define GFX_SHOW_COMPILER                        GFXOFF -//    #define GFX_CPU                                  GFX_CPU_UNKNOWN -//    #define GFX_CPU_NO_ALIGNMENT_FAULTS              GFXOFF -//    #define GFX_CPU_ENDIAN                           GFX_CPU_ENDIAN_UNKNOWN -//    #define GFX_OS_HEAP_SIZE                         0 -//    #define GFX_OS_NO_INIT                           GFXOFF -//    #define GFX_OS_INIT_NO_WARNING                   GFXOFF -//    #define GFX_OS_PRE_INIT_FUNCTION                 myHardwareInitRoutine -//    #define GFX_OS_EXTRA_INIT_FUNCTION               myOSInitRoutine -//    #define GFX_OS_EXTRA_DEINIT_FUNCTION             myOSDeInitRoutine -//    #define GFX_OS_CALL_UGFXMAIN                     GFXOFF -//    #define GFX_OS_UGFXMAIN_STACKSIZE                0 -//    #define GFX_EMULATE_MALLOC                       GFXOFF -//    #define GFX_MEM_LT64K                            GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GDISP                                                                 // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GDISP GFXON - -//#define GDISP_NEED_AUTOFLUSH                         GFXOFF -//#define GDISP_NEED_TIMERFLUSH                        GFXOFF -//#define GDISP_NEED_VALIDATION                        GFXON -//#define GDISP_NEED_CLIP                              GFXON -#define GDISP_NEED_CIRCLE GFXON -//#define GDISP_NEED_DUALCIRCLE                        GFXOFF -#define GDISP_NEED_ELLIPSE GFXON -#define GDISP_NEED_ARC GFXON -#define GDISP_NEED_ARCSECTORS GFXON -#define GDISP_NEED_CONVEX_POLYGON GFXON -//#define GDISP_NEED_SCROLL                            GFXOFF -#define GDISP_NEED_PIXELREAD GFXON -#define GDISP_NEED_CONTROL GFXON -//#define GDISP_NEED_QUERY                             GFXOFF -//#define GDISP_NEED_MULTITHREAD                       GFXOFF -//#define GDISP_NEED_STREAMING                         GFXOFF -#define GDISP_NEED_TEXT GFXON -//    #define GDISP_NEED_TEXT_WORDWRAP                 GFXOFF -//    #define GDISP_NEED_TEXT_BOXPADLR                 1 -//    #define GDISP_NEED_TEXT_BOXPADTB                 1 -//    #define GDISP_NEED_ANTIALIAS                     GFXOFF -//    #define GDISP_NEED_UTF8                          GFXOFF -#define GDISP_NEED_TEXT_KERNING GFXON -//    #define GDISP_INCLUDE_FONT_UI1                   GFXOFF -//    #define GDISP_INCLUDE_FONT_UI2                   GFXOFF		// The smallest preferred font. -//    #define GDISP_INCLUDE_FONT_LARGENUMBERS          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS10          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS12          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS16          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS20          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS24          GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS32          GFXOFF -#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 GFXON -//    #define GDISP_INCLUDE_FONT_FIXED_10X20           GFXOFF -//    #define GDISP_INCLUDE_FONT_FIXED_7X14            GFXOFF -#define GDISP_INCLUDE_FONT_FIXED_5X8 GFXON -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA       GFXOFF -//    #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA   GFXOFF -//    #define GDISP_INCLUDE_USER_FONTS                 GFXOFF - -//#define GDISP_NEED_IMAGE                             GFXOFF -//    #define GDISP_NEED_IMAGE_NATIVE                  GFXOFF -//    #define GDISP_NEED_IMAGE_GIF                     GFXOFF -//        #define GDISP_IMAGE_GIF_BLIT_BUFFER_SIZE     32 -//    #define GDISP_NEED_IMAGE_BMP                     GFXOFF -//        #define GDISP_NEED_IMAGE_BMP_1               GFXON -//        #define GDISP_NEED_IMAGE_BMP_4               GFXON -//        #define GDISP_NEED_IMAGE_BMP_4_RLE           GFXON -//        #define GDISP_NEED_IMAGE_BMP_8               GFXON -//        #define GDISP_NEED_IMAGE_BMP_8_RLE           GFXON -//        #define GDISP_NEED_IMAGE_BMP_16              GFXON -//        #define GDISP_NEED_IMAGE_BMP_24              GFXON -//        #define GDISP_NEED_IMAGE_BMP_32              GFXON -//        #define GDISP_IMAGE_BMP_BLIT_BUFFER_SIZE     32 -//    #define GDISP_NEED_IMAGE_JPG                     GFXOFF -//    #define GDISP_NEED_IMAGE_PNG                     GFXOFF -//        #define GDISP_NEED_IMAGE_PNG_INTERLACED      GFXOFF -//        #define GDISP_NEED_IMAGE_PNG_TRANSPARENCY    GFXON -//        #define GDISP_NEED_IMAGE_PNG_BACKGROUND      GFXON -//        #define GDISP_NEED_IMAGE_PNG_ALPHACLIFF      32 -//        #define GDISP_NEED_IMAGE_PNG_PALETTE_124     GFXON -//        #define GDISP_NEED_IMAGE_PNG_PALETTE_8       GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYSCALE_124   GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYSCALE_8     GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYSCALE_16    GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYALPHA_8     GFXON -//        #define GDISP_NEED_IMAGE_PNG_GRAYALPHA_16    GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGB_8           GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGB_16          GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGBALPHA_8      GFXON -//        #define GDISP_NEED_IMAGE_PNG_RGBALPHA_16     GFXON -//        #define GDISP_IMAGE_PNG_BLIT_BUFFER_SIZE     32 -//        #define GDISP_IMAGE_PNG_FILE_BUFFER_SIZE     8 -//        #define GDISP_IMAGE_PNG_Z_BUFFER_SIZE        32768 -//    #define GDISP_NEED_IMAGE_ACCOUNTING              GFXOFF - -//#define GDISP_NEED_PIXMAP                            GFXOFF -//    #define GDISP_NEED_PIXMAP_IMAGE                  GFXOFF - -//#define GDISP_DEFAULT_ORIENTATION                    gOrientationLandscape    // If not defined the native hardware orientation is used. -//#define GDISP_LINEBUF_SIZE                           128 -//#define GDISP_STARTUP_COLOR                          GFX_BLACK -#define GDISP_NEED_STARTUP_LOGO GFXOFF - -//#define GDISP_TOTAL_DISPLAYS                         1 - -//#define GDISP_DRIVER_LIST                            GDISPVMT_Win32, GDISPVMT_Win32 -#ifdef GDISP_DRIVER_LIST -//        // For code and speed optimization define as GFXON or GFXOFF if all controllers have the same capability -#    define GDISP_HARDWARE_STREAM_WRITE GFXOFF -#    define GDISP_HARDWARE_STREAM_READ GFXOFF -#    define GDISP_HARDWARE_STREAM_POS GFXOFF -#    define GDISP_HARDWARE_DRAWPIXEL GFXON -#    define GDISP_HARDWARE_CLEARS GFXOFF -#    define GDISP_HARDWARE_FILLS GFXOFF -//#define GDISP_HARDWARE_BITFILLS              GFXOFF -#    define GDISP_HARDWARE_SCROLL GFXOFF -#    define GDISP_HARDWARE_PIXELREAD GFXON -#    define GDISP_HARDWARE_CONTROL GFXON -#    define GDISP_HARDWARE_QUERY GFXOFF -#    define GDISP_HARDWARE_CLIP GFXOFF - -#    define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 -#endif - -#define GDISP_USE_GFXNET GFXOFF -//    #define GDISP_GFXNET_PORT                        13001 -//    #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP         GFXOFF -//    #define GDISP_DONT_WAIT_FOR_NET_DISPLAY          GFXOFF -//    #define GDISP_GFXNET_UNSAFE_SOCKETS              GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GWIN                                                                  // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GWIN GFXOFF - -//#define GWIN_NEED_WINDOWMANAGER                      GFXOFF -//    #define GWIN_REDRAW_IMMEDIATE                    GFXOFF -//    #define GWIN_REDRAW_SINGLEOP                     GFXOFF -//    #define GWIN_NEED_FLASHING                       GFXOFF -//        #define GWIN_FLASHING_PERIOD                 250 - -//#define GWIN_NEED_CONSOLE                            GFXOFF -//    #define GWIN_CONSOLE_USE_HISTORY                 GFXOFF -//        #define GWIN_CONSOLE_HISTORY_AVERAGING       GFXOFF -//        #define GWIN_CONSOLE_HISTORY_ATCREATE        GFXOFF -//    #define GWIN_CONSOLE_ESCSEQ                      GFXOFF -//    #define GWIN_CONSOLE_USE_BASESTREAM              GFXOFF -//    #define GWIN_CONSOLE_USE_FLOAT                   GFXOFF -//#define GWIN_NEED_GRAPH                              GFXOFF -//#define GWIN_NEED_GL3D                               GFXOFF - -//#define GWIN_NEED_WIDGET                             GFXOFF -//#define GWIN_FOCUS_HIGHLIGHT_WIDTH                   1 -//    #define GWIN_NEED_LABEL                          GFXOFF -//        #define GWIN_LABEL_ATTRIBUTE                 GFXOFF -//    #define GWIN_NEED_BUTTON                         GFXOFF -//        #define GWIN_BUTTON_LAZY_RELEASE             GFXOFF -//    #define GWIN_NEED_SLIDER                         GFXOFF -//        #define GWIN_SLIDER_NOSNAP                   GFXOFF -//        #define GWIN_SLIDER_DEAD_BAND                5 -//        #define GWIN_SLIDER_TOGGLE_INC               20 -//    #define GWIN_NEED_CHECKBOX                       GFXOFF -//    #define GWIN_NEED_IMAGE                          GFXOFF -//        #define GWIN_NEED_IMAGE_ANIMATION            GFXOFF -//    #define GWIN_NEED_RADIO                          GFXOFF -//    #define GWIN_NEED_LIST                           GFXOFF -//        #define GWIN_NEED_LIST_IMAGES                GFXOFF -//    #define GWIN_NEED_PROGRESSBAR                    GFXOFF -//        #define GWIN_PROGRESSBAR_AUTO                GFXOFF -//    #define GWIN_NEED_KEYBOARD                       GFXOFF -//        #define GWIN_KEYBOARD_DEFAULT_LAYOUT         VirtualKeyboard_English1 -//        #define GWIN_NEED_KEYBOARD_ENGLISH1          GFXON -//    #define GWIN_NEED_TEXTEDIT                       GFXOFF -//    #define GWIN_FLAT_STYLING                        GFXOFF -//    #define GWIN_WIDGET_TAGS                         GFXOFF - -//#define GWIN_NEED_CONTAINERS                         GFXOFF -//    #define GWIN_NEED_CONTAINER                      GFXOFF -//    #define GWIN_NEED_FRAME                          GFXOFF -//    #define GWIN_NEED_TABSET                         GFXOFF -//        #define GWIN_TABSET_TABHEIGHT                18 - -/////////////////////////////////////////////////////////////////////////// -// GTRANS                                                                // -/////////////////////////////////////////////////////////////////////////// -//#define GFX_USE_GTRANS                               GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GEVENT                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GEVENT GFXON - -//#define GEVENT_ASSERT_NO_RESOURCE                    GFXOFF -//#define GEVENT_MAXIMUM_SIZE                          32 -//#define GEVENT_MAX_SOURCE_LISTENERS                  32 - -/////////////////////////////////////////////////////////////////////////// -// GTIMER                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GTIMER GFXOFF - -//#define GTIMER_THREAD_PRIORITY                       gThreadpriorityHigh -//#define GTIMER_THREAD_WORKAREA_SIZE                  2048 - -/////////////////////////////////////////////////////////////////////////// -// GQUEUE                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GQUEUE GFXOFF - -//#define GQUEUE_NEED_ASYNC                            GFXOFF -//#define GQUEUE_NEED_GSYNC                            GFXOFF -//#define GQUEUE_NEED_FSYNC                            GFXOFF -//#define GQUEUE_NEED_BUFFERS                          GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GINPUT                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GINPUT GFXOFF - -//#define GINPUT_NEED_MOUSE                            GFXOFF -//    #define GINPUT_TOUCH_STARTRAW                    GFXOFF -//    #define GINPUT_TOUCH_NOTOUCH                     GFXOFF -//    #define GINPUT_TOUCH_NOCALIBRATE                 GFXOFF -//    #define GINPUT_TOUCH_NOCALIBRATE_GUI             GFXOFF -//    #define GINPUT_MOUSE_POLL_PERIOD                 25 -//    #define GINPUT_MOUSE_CLICK_TIME                  300 -//    #define GINPUT_TOUCH_CXTCLICK_TIME               700 -//    #define GINPUT_TOUCH_USER_CALIBRATION_LOAD       GFXOFF -//    #define GINPUT_TOUCH_USER_CALIBRATION_SAVE       GFXOFF -//    #define GMOUSE_DRIVER_LIST                       GMOUSEVMT_Win32, GMOUSEVMT_Win32 -//    #define GINPUT_TOUCH_CALIBRATION_FONT1           "* Double" -//    #define GINPUT_TOUCH_CALIBRATION_FONT2           "* Narrow" -//    #define GINPUT_TOUCH_CALIBRATION_TITLE           "Calibration" -//    #define GINPUT_TOUCH_CALIBRATION_ERROR           "Calibration Failed!" -//#define GINPUT_NEED_KEYBOARD                         GFXOFF -//    #define GINPUT_KEYBOARD_POLL_PERIOD              200 -//    #define GKEYBOARD_DRIVER_LIST                    GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32 -//    #define GKEYBOARD_LAYOUT_OFF                     GFXOFF -//        #define GKEYBOARD_LAYOUT_SCANCODE2_US        GFXOFF -//#define GINPUT_NEED_TOGGLE                           GFXOFF -//#define GINPUT_NEED_DIAL                             GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GFILE                                                                 // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GFILE GFXOFF - -//#define GFILE_NEED_PRINTG                            GFXOFF -//#define GFILE_NEED_SCANG                             GFXOFF -//#define GFILE_NEED_STRINGS                           GFXOFF -//#define GFILE_NEED_FILELISTS                         GFXOFF -//#define GFILE_NEED_STDIO                             GFXOFF -//#define GFILE_NEED_NOAUTOMOUNT                       GFXOFF -//#define GFILE_NEED_NOAUTOSYNC                        GFXOFF - -//#define GFILE_NEED_MEMFS                             GFXOFF -//#define GFILE_NEED_ROMFS                             GFXOFF -//#define GFILE_NEED_RAMFS                             GFXOFF -//#define GFILE_NEED_FATFS                             GFXOFF -//#define GFILE_NEED_NATIVEFS                          GFXOFF -//#define GFILE_NEED_CHBIOSFS                          GFXOFF -//#define GFILE_NEED_USERFS                            GFXOFF - -//#define GFILE_ALLOW_FLOATS                           GFXOFF -//#define GFILE_ALLOW_DEVICESPECIFIC                   GFXOFF -//#define GFILE_MAX_GFILES                             3 - -/////////////////////////////////////////////////////////////////////////// -// GADC                                                                  // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GADC GFXOFF -//    #define GADC_MAX_LOWSPEED_DEVICES                4 - -/////////////////////////////////////////////////////////////////////////// -// GAUDIO                                                                // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GAUDIO GFXOFF -//    #define GAUDIO_NEED_PLAY                         GFXOFF -//    #define GAUDIO_NEED_RECORD                       GFXOFF - -/////////////////////////////////////////////////////////////////////////// -// GMISC                                                                 // -/////////////////////////////////////////////////////////////////////////// -#define GFX_USE_GMISC GFXON - -//#define GMISC_NEED_ARRAYOPS                          GFXOFF -//#define GMISC_NEED_FASTTRIG                          GFXOFF -//#define GMISC_NEED_FIXEDTRIG                         GFXOFF -//#define GMISC_NEED_INVSQRT                           GFXOFF -//    #define GMISC_INVSQRT_MIXED_ENDIAN               GFXOFF -//    #define GMISC_INVSQRT_REAL_SLOW                  GFXOFF -#define GMISC_NEED_MATRIXFLOAT2D GFXON -#define GMISC_NEED_MATRIXFIXED2D GFXOFF -//#define GMISC_NEED_HITTEST_POLY                      GFXOFF diff --git a/quantum/visualizer/default_animations.c b/quantum/visualizer/default_animations.c deleted file mode 100644 index 2f43c67cc8..0000000000 --- a/quantum/visualizer/default_animations.c +++ /dev/null @@ -1,177 +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/>. - */ - -#if defined(VISUALIZER_ENABLE) - -#    include "default_animations.h" -#    include "visualizer.h" -#    ifdef LCD_ENABLE -#        include "lcd_keyframes.h" -#    endif -#    ifdef LCD_BACKLIGHT_ENABLE -#        include "lcd_backlight_keyframes.h" -#    endif - -#    ifdef BACKLIGHT_ENABLE -#        include "led_backlight_keyframes.h" -#    endif - -#    include "visualizer_keyframes.h" - -#    if defined(LCD_ENABLE) || defined(LCD_BACKLIGHT_ENABLE) || defined(BACKLIGHT_ENABLE) - -static bool keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -#        ifdef LCD_ENABLE -    lcd_keyframe_enable(animation, state); -#        endif -#        ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_keyframe_enable(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    led_backlight_keyframe_enable(animation, state); -#        endif -    return false; -} - -static bool keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -#        ifdef LCD_ENABLE -    lcd_keyframe_disable(animation, state); -#        endif -#        ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_keyframe_disable(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    led_backlight_keyframe_disable(animation, state); -#        endif -    return false; -} - -static bool keyframe_fade_in(keyframe_animation_t* animation, visualizer_state_t* state) { -    bool ret = false; -#        ifdef LCD_BACKLIGHT_ENABLE -    ret |= lcd_backlight_keyframe_animate_color(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    ret |= led_backlight_keyframe_fade_in_all(animation, state); -#        endif -    return ret; -} - -static bool keyframe_fade_out(keyframe_animation_t* animation, visualizer_state_t* state) { -    bool ret = false; -#        ifdef LCD_BACKLIGHT_ENABLE -    ret |= lcd_backlight_keyframe_animate_color(animation, state); -#        endif -#        ifdef BACKLIGHT_ENABLE -    ret |= led_backlight_keyframe_fade_out_all(animation, state); -#        endif -    return ret; -} - -// Don't worry, if the startup animation is long, you can use the keyboard like normal -// during that time -keyframe_animation_t default_startup_animation = { -#        if LCD_ENABLE -    .num_frames = 3, -#        else -    .num_frames = 2, -#        endif -    .loop          = false, -    .frame_lengths = {0, -#        if LCD_ENABLE -                      0, -#        endif -                      gfxMillisecondsToTicks(5000)}, -    .frame_functions = -        { -            keyframe_enable, -#        if LCD_ENABLE -            lcd_keyframe_draw_logo, -#        endif -            keyframe_fade_in, -        }, -}; - -keyframe_animation_t default_suspend_animation = { -#        if LCD_ENABLE -    .num_frames = 3, -#        else -    .num_frames = 2, -#        endif -    .loop = false, -    .frame_lengths = -        { -#        if LCD_ENABLE -            0, -#        endif -            gfxMillisecondsToTicks(1000), 0}, -    .frame_functions = -        { -#        if LCD_ENABLE -            lcd_keyframe_display_layer_text, -#        endif -            keyframe_fade_out, -            keyframe_disable, -        }, -}; -#    endif - -#    if defined(BACKLIGHT_ENABLE) -#        define CROSSFADE_TIME 1000 -#        define GRADIENT_TIME 3000 - -keyframe_animation_t led_test_animation = { -    .num_frames = 14, -    .loop       = true, -    .frame_lengths = -        { -            gfxMillisecondsToTicks(1000),            // fade in -            gfxMillisecondsToTicks(1000),            // no op (leds on) -            gfxMillisecondsToTicks(1000),            // fade out -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // left to rigt (outside in) -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // top_to_bottom -            0,                                       // mirror leds -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // left_to_right (mirrored, so inside out) -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade -            gfxMillisecondsToTicks(GRADIENT_TIME),   // top_to_bottom -            0,                                       // normal leds -            gfxMillisecondsToTicks(CROSSFADE_TIME),  // crossfade - -        }, -    .frame_functions = -        { -            led_backlight_keyframe_fade_in_all, -            keyframe_no_operation, -            led_backlight_keyframe_fade_out_all, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_left_to_right_gradient, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_top_to_bottom_gradient, -            led_backlight_keyframe_mirror_orientation, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_left_to_right_gradient, -            led_backlight_keyframe_crossfade, -            led_backlight_keyframe_top_to_bottom_gradient, -            led_backlight_keyframe_normal_orientation, -            led_backlight_keyframe_crossfade, -        }, -}; -#    endif - -#endif diff --git a/quantum/visualizer/default_animations.h b/quantum/visualizer/default_animations.h deleted file mode 100644 index 9accd89774..0000000000 --- a/quantum/visualizer/default_animations.h +++ /dev/null @@ -1,27 +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/>. - */ - -#pragma once - -#include "visualizer.h" - -// You can use these default animations, but of course you can also write your own custom ones instead -extern keyframe_animation_t default_startup_animation; -extern keyframe_animation_t default_suspend_animation; - -// An animation for testing and demonstrating the led support, should probably not be used for real world -// cases -extern keyframe_animation_t led_test_animation; diff --git a/quantum/visualizer/lcd_backlight.c b/quantum/visualizer/lcd_backlight.c deleted file mode 100644 index 23978974e3..0000000000 --- a/quantum/visualizer/lcd_backlight.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "lcd_backlight.h" -#include <math.h> - -static uint8_t current_hue        = 0; -static uint8_t current_saturation = 0; -static uint8_t current_intensity  = 0; -static uint8_t current_brightness = 0; - -void lcd_backlight_init(void) { -    lcd_backlight_hal_init(); -    lcd_backlight_color(current_hue, current_saturation, current_intensity); -} - -// This code is based on Brian Neltner's blogpost and example code -// "Why every LED light should be using HSI colorspace". -// http://blog.saikoled.com/post/43693602826/why-every-led-light-should-be-using-hsi -static void hsi_to_rgb(float h, float s, float i, uint16_t* r_out, uint16_t* g_out, uint16_t* b_out) { -    unsigned int r, g, b; -    h = fmodf(h, 360.0f);                         // cycle h around to 0-360 degrees -    h = 3.14159f * h / 180.0f;                    // Convert to radians. -    s = s > 0.0f ? (s < 1.0f ? s : 1.0f) : 0.0f;  // clamp s and i to interval [0,1] -    i = i > 0.0f ? (i < 1.0f ? i : 1.0f) : 0.0f; - -    // Math! Thanks in part to Kyle Miller. -    if (h < 2.09439f) { -        r = 65535.0f * i / 3.0f * (1.0f + s * cos(h) / cosf(1.047196667f - h)); -        g = 65535.0f * i / 3.0f * (1.0f + s * (1.0f - cosf(h) / cos(1.047196667f - h))); -        b = 65535.0f * i / 3.0f * (1.0f - s); -    } else if (h < 4.188787) { -        h = h - 2.09439; -        g = 65535.0f * i / 3.0f * (1.0f + s * cosf(h) / cosf(1.047196667f - h)); -        b = 65535.0f * i / 3.0f * (1.0f + s * (1.0f - cosf(h) / cosf(1.047196667f - h))); -        r = 65535.0f * i / 3.0f * (1.0f - s); -    } else { -        h = h - 4.188787; -        b = 65535.0f * i / 3.0f * (1.0f + s * cosf(h) / cosf(1.047196667f - h)); -        r = 65535.0f * i / 3.0f * (1.0f + s * (1.0f - cosf(h) / cosf(1.047196667f - h))); -        g = 65535.0f * i / 3.0f * (1.0f - s); -    } -    *r_out = r > 65535 ? 65535 : r; -    *g_out = g > 65535 ? 65535 : g; -    *b_out = b > 65535 ? 65535 : b; -} - -void lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity) { -    uint16_t r, g, b; -    float    hue_f        = 360.0f * (float)hue / 255.0f; -    float    saturation_f = (float)saturation / 255.0f; -    float    intensity_f  = (float)intensity / 255.0f; -    intensity_f *= (float)current_brightness / 255.0f; -    hsi_to_rgb(hue_f, saturation_f, intensity_f, &r, &g, &b); -    current_hue        = hue; -    current_saturation = saturation; -    current_intensity  = intensity; -    lcd_backlight_hal_color(r, g, b); -} - -void lcd_backlight_brightness(uint8_t b) { -    current_brightness = b; -    lcd_backlight_color(current_hue, current_saturation, current_intensity); -} - -uint8_t lcd_get_backlight_brightness(void) { return current_brightness; } diff --git a/quantum/visualizer/lcd_backlight.h b/quantum/visualizer/lcd_backlight.h deleted file mode 100644 index 4ea5b14639..0000000000 --- a/quantum/visualizer/lcd_backlight.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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> - -// Helper macros for storing hue, staturation and intensity as unsigned integers -#define LCD_COLOR(hue, saturation, intensity) (hue << 16 | saturation << 8 | intensity) -#define LCD_HUE(color) ((color >> 16) & 0xFF) -#define LCD_SAT(color) ((color >> 8) & 0xFF) -#define LCD_INT(color) (color & 0xFF) - -static inline uint32_t change_lcd_color_intensity(uint32_t color, uint8_t new_intensity) { return (color & 0xFFFFFF00) | new_intensity; } - -void    lcd_backlight_init(void); -void    lcd_backlight_color(uint8_t hue, uint8_t saturation, uint8_t intensity); -void    lcd_backlight_brightness(uint8_t b); -uint8_t lcd_get_backlight_brightness(void); - -void lcd_backlight_hal_init(void); -void lcd_backlight_hal_color(uint16_t r, uint16_t g, uint16_t b); diff --git a/quantum/visualizer/lcd_backlight_keyframes.c b/quantum/visualizer/lcd_backlight_keyframes.c deleted file mode 100644 index c13cce311d..0000000000 --- a/quantum/visualizer/lcd_backlight_keyframes.c +++ /dev/null @@ -1,69 +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 "lcd_backlight_keyframes.h" - -bool lcd_backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state) { -    int     frame_length = animation->frame_lengths[animation->current_frame]; -    int     current_pos  = frame_length - animation->time_left_in_frame; -    uint8_t t_h          = LCD_HUE(state->target_lcd_color); -    uint8_t t_s          = LCD_SAT(state->target_lcd_color); -    uint8_t t_i          = LCD_INT(state->target_lcd_color); -    uint8_t p_h          = LCD_HUE(state->prev_lcd_color); -    uint8_t p_s          = LCD_SAT(state->prev_lcd_color); -    uint8_t p_i          = LCD_INT(state->prev_lcd_color); - -    uint8_t d_h1 = t_h - p_h;  // Modulo arithmetic since we want to wrap around -    int     d_h2 = t_h - p_h; -    // Chose the shortest way around -    int d_h = abs(d_h2) < d_h1 ? d_h2 : d_h1; -    int d_s = t_s - p_s; -    int d_i = t_i - p_i; - -    int hue       = (d_h * current_pos) / frame_length; -    int sat       = (d_s * current_pos) / frame_length; -    int intensity = (d_i * current_pos) / frame_length; -    // dprintf("%X -> %X = %X\n", p_h, t_h, hue); -    hue += p_h; -    sat += p_s; -    intensity += p_i; -    state->current_lcd_color = LCD_COLOR(hue, sat, intensity); -    lcd_backlight_color(LCD_HUE(state->current_lcd_color), LCD_SAT(state->current_lcd_color), LCD_INT(state->current_lcd_color)); - -    return true; -} - -bool lcd_backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    state->prev_lcd_color    = state->target_lcd_color; -    state->current_lcd_color = state->target_lcd_color; -    lcd_backlight_color(LCD_HUE(state->current_lcd_color), LCD_SAT(state->current_lcd_color), LCD_INT(state->current_lcd_color)); -    return false; -} - -bool lcd_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    lcd_backlight_hal_color(0, 0, 0); -    return false; -} - -bool lcd_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    lcd_backlight_color(LCD_HUE(state->current_lcd_color), LCD_SAT(state->current_lcd_color), LCD_INT(state->current_lcd_color)); -    return false; -} diff --git a/quantum/visualizer/lcd_backlight_keyframes.h b/quantum/visualizer/lcd_backlight_keyframes.h deleted file mode 100644 index 88768dd4a5..0000000000 --- a/quantum/visualizer/lcd_backlight_keyframes.h +++ /dev/null @@ -1,27 +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/>. - */ - -#pragma once - -#include "visualizer.h" - -// Animates the LCD backlight color between the current color and the target color (of the state) -bool lcd_backlight_keyframe_animate_color(keyframe_animation_t* animation, visualizer_state_t* state); -// Sets the backlight color to the target color -bool lcd_backlight_keyframe_set_color(keyframe_animation_t* animation, visualizer_state_t* state); - -bool lcd_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool lcd_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/visualizer/lcd_keyframes.c b/quantum/visualizer/lcd_keyframes.c deleted file mode 100644 index 1d6f3dca18..0000000000 --- a/quantum/visualizer/lcd_keyframes.c +++ /dev/null @@ -1,184 +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 "lcd_keyframes.h" -#include <string.h> -#include "action_util.h" -#include "led.h" -#include "resources/resources.h" - -bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    gdispClear(White); -    gdispDrawString(0, 10, state->layer_text, state->font_dejavusansbold12, Black); -    return false; -} - -static void format_layer_bitmap_string(uint16_t default_layer, uint16_t layer, char* buffer) { -    for (int i = 0; i < 16; i++) { -        uint32_t mask = (1u << i); -        if (default_layer & mask) { -            if (layer & mask) { -                *buffer = 'B'; -            } else { -                *buffer = 'D'; -            } -        } else if (layer & mask) { -            *buffer = '1'; -        } else { -            *buffer = '0'; -        } -        ++buffer; - -        if (i == 3 || i == 7 || i == 11) { -            *buffer = ' '; -            ++buffer; -        } -    } -    *buffer = 0; -} - -bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    const char* layer_help = "1=On D=Default B=Both"; -    char        layer_buffer[16 + 4];  // 3 spaces and one null terminator -    gdispClear(White); -    gdispDrawString(0, 0, layer_help, state->font_fixed5x8, Black); -    format_layer_bitmap_string(state->status.default_layer, state->status.layer, layer_buffer); -    gdispDrawString(0, 10, layer_buffer, state->font_fixed5x8, Black); -    format_layer_bitmap_string(state->status.default_layer >> 16, state->status.layer >> 16, layer_buffer); -    gdispDrawString(0, 20, layer_buffer, state->font_fixed5x8, Black); -    return false; -} - -static void format_mods_bitmap_string(uint8_t mods, char* buffer) { -    *buffer = ' '; -    ++buffer; - -    for (int i = 0; i < 8; i++) { -        uint32_t mask = (1u << i); -        if (mods & mask) { -            *buffer = '1'; -        } else { -            *buffer = '0'; -        } -        ++buffer; - -        if (i == 3) { -            *buffer = ' '; -            ++buffer; -        } -    } -    *buffer = 0; -} - -bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; - -    const char* title       = "Modifier states"; -    const char* mods_header = " CSAG CSAG "; -    char        status_buffer[12]; - -    gdispClear(White); -    gdispDrawString(0, 0, title, state->font_fixed5x8, Black); -    gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black); -    format_mods_bitmap_string(state->status.mods, status_buffer); -    gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black); - -    return false; -} - -#define LED_STATE_STRING_SIZE sizeof("NUM CAPS SCRL COMP KANA") - -static void get_led_state_string(char* output, visualizer_state_t* state) { -    uint8_t pos = 0; - -    if (state->status.leds & (1u << USB_LED_NUM_LOCK)) { -        memcpy(output + pos, "NUM ", 4); -        pos += 4; -    } -    if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { -        memcpy(output + pos, "CAPS ", 5); -        pos += 5; -    } -    if (state->status.leds & (1u << USB_LED_SCROLL_LOCK)) { -        memcpy(output + pos, "SCRL ", 5); -        pos += 5; -    } -    if (state->status.leds & (1u << USB_LED_COMPOSE)) { -        memcpy(output + pos, "COMP ", 5); -        pos += 5; -    } -    if (state->status.leds & (1u << USB_LED_KANA)) { -        memcpy(output + pos, "KANA", 4); -        pos += 4; -    } -    output[pos] = 0; -} - -bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    char output[LED_STATE_STRING_SIZE]; -    get_led_state_string(output, state); -    gdispClear(White); -    gdispDrawString(0, 10, output, state->font_dejavusansbold12, Black); -    return false; -} - -bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    gdispClear(White); -    uint8_t y = 10; -    if (state->status.leds) { -        char output[LED_STATE_STRING_SIZE]; -        get_led_state_string(output, state); -        gdispDrawString(0, 1, output, state->font_dejavusansbold12, Black); -        y = 17; -    } -    gdispDrawString(0, y, state->layer_text, state->font_dejavusansbold12, Black); -    return false; -} - -bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    // Read the uGFX documentation for information how to use the displays -    // http://wiki.ugfx.org/index.php/Main_Page -    gdispClear(Black); - -    // You can use static variables for things that can't be found in the animation -    // or state structs, here we use the image - -    // gdispGBlitArea is a tricky function to use since it supports blitting part of the image -    // if you have full screen image, then just use LCD_WIDTH and LCD_HEIGHT for both source and target dimensions -    gdispGBlitArea(GDISP, 0, 0, 128, 32, 0, 0, LCD_WIDTH, (pixel_t*)resource_lcd_logo); - -    return false; -} - -bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    gdispSetPowerMode(powerOff); -    return false; -} - -bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    gdispSetPowerMode(powerOn); -    return false; -} diff --git a/quantum/visualizer/lcd_keyframes.h b/quantum/visualizer/lcd_keyframes.h deleted file mode 100644 index b7125e8323..0000000000 --- a/quantum/visualizer/lcd_keyframes.h +++ /dev/null @@ -1,35 +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/>. - */ - -#pragma once - -#include "visualizer.h" - -// Displays the layer text centered vertically on the screen -bool lcd_keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays a bitmap (0/1) of all the currently active layers -bool lcd_keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays a bitmap (0/1) of all the currently active mods -bool lcd_keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays the keyboard led states (CAPS (Caps lock), NUM (Num lock), SCRL (Scroll lock), COMP (Compose), KANA) -bool lcd_keyframe_display_led_states(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays both the layer text and the led states -bool lcd_keyframe_display_layer_and_led_states(keyframe_animation_t* animation, visualizer_state_t* state); -// Displays the QMK logo on the LCD screen -bool lcd_keyframe_draw_logo(keyframe_animation_t* animation, visualizer_state_t* state); - -bool lcd_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool lcd_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); diff --git a/quantum/visualizer/led_backlight_keyframes.c b/quantum/visualizer/led_backlight_keyframes.c deleted file mode 100644 index 338ada5227..0000000000 --- a/quantum/visualizer/led_backlight_keyframes.c +++ /dev/null @@ -1,143 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "gfx.h" -#include <math.h> -#include "led_backlight_keyframes.h" - -static uint8_t fade_led_color(keyframe_animation_t* animation, int from, int to) { -    int frame_length = animation->frame_lengths[animation->current_frame]; -    int current_pos  = frame_length - animation->time_left_in_frame; -    int delta        = to - from; -    int luma         = (delta * current_pos) / frame_length; -    luma += from; -    return luma; -} - -static void keyframe_fade_all_leds_from_to(keyframe_animation_t* animation, uint8_t from, uint8_t to) { -    uint8_t luma  = fade_led_color(animation, from, to); -    color_t color = LUMA2COLOR(luma); -    gdispGClear(LED_DISPLAY, color); -} - -// TODO: Should be customizable per keyboard -#define NUM_ROWS LED_HEIGHT -#define NUM_COLS LED_WIDTH - -static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; -static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; - -static uint8_t compute_gradient_color(float t, float index, float num) { -    const float two_pi           = M_PI * 2.0f; -    float       normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; -    float       x                = t * two_pi + normalized_index; -    float       v                = 0.5 * (cosf(x) + 1.0f); -    return (uint8_t)(255.0f * v); -} - -bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    keyframe_fade_all_leds_from_to(animation, 0, 255); -    return true; -} - -bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    keyframe_fade_all_leds_from_to(animation, 255, 0); -    return true; -} - -bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    float frame_length = animation->frame_lengths[animation->current_frame]; -    float current_pos  = frame_length - animation->time_left_in_frame; -    float t            = current_pos / frame_length; -    for (int i = 0; i < NUM_COLS; i++) { -        uint8_t color = compute_gradient_color(t, i, NUM_COLS); -        gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); -    } -    return true; -} - -bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    float frame_length = animation->frame_lengths[animation->current_frame]; -    float current_pos  = frame_length - animation->time_left_in_frame; -    float t            = current_pos / frame_length; -    for (int i = 0; i < NUM_ROWS; i++) { -        uint8_t color = compute_gradient_color(t, i, NUM_ROWS); -        gdispGDrawLine(LED_DISPLAY, 0, i, NUM_COLS - 1, i, LUMA2COLOR(color)); -    } -    return true; -} - -static void copy_current_led_state(uint8_t* dest) { -    for (int i = 0; i < NUM_ROWS; i++) { -        for (int j = 0; j < NUM_COLS; j++) { -            dest[i * NUM_COLS + j] = gdispGGetPixelColor(LED_DISPLAY, j, i); -        } -    } -} -bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    if (animation->first_update_of_frame) { -        copy_current_led_state(&crossfade_start_frame[0][0]); -        run_next_keyframe(animation, state); -        copy_current_led_state(&crossfade_end_frame[0][0]); -    } -    for (int i = 0; i < NUM_ROWS; i++) { -        for (int j = 0; j < NUM_COLS; j++) { -            color_t color = LUMA2COLOR(fade_led_color(animation, crossfade_start_frame[i][j], crossfade_end_frame[i][j])); -            gdispGDrawPixel(LED_DISPLAY, j, i, color); -        } -    } -    return true; -} - -bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_180); -    return false; -} - -bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetOrientation(LED_DISPLAY, GDISP_ROTATE_0); -    return false; -} - -bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetPowerMode(LED_DISPLAY, powerOff); -    return false; -} - -bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)state; -    (void)animation; -    gdispGSetPowerMode(LED_DISPLAY, powerOn); -    return false; -} diff --git a/quantum/visualizer/led_backlight_keyframes.h b/quantum/visualizer/led_backlight_keyframes.h deleted file mode 100644 index 90153be5eb..0000000000 --- a/quantum/visualizer/led_backlight_keyframes.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "visualizer.h" - -bool led_backlight_keyframe_fade_in_all(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_fade_out_all(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_left_to_right_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_top_to_bottom_gradient(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_crossfade(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_mirror_orientation(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_normal_orientation(keyframe_animation_t* animation, visualizer_state_t* state); - -bool led_backlight_keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state); - -extern keyframe_animation_t led_test_animation; diff --git a/quantum/visualizer/readme.md b/quantum/visualizer/readme.md deleted file mode 100644 index 298efb742f..0000000000 --- a/quantum/visualizer/readme.md +++ /dev/null @@ -1,18 +0,0 @@ -# A visualization library for the TMK keyboard firmware - -This library is designed to work together with the [TMK keyboard firmware](https://github.com/tmk/tmk_keyboard). Currently it only works for [Chibios](http://www.chibios.org/) - flavors, but it would be possible to add support for other configurations as well. The LCD display functionality is provided by the [uGFX library](https://ugfx.io/).  - -## To use this library as a user -You can and should modify the visualizer\_user.c file. Check the comments in the file for more information. - -## To add this library to custom keyboard projects - -1. Add tmk_visualizer as a submodule to your project -1. Set VISUALIZER_DIR in the main keyboard project makefile to point to the submodule -1. Define LCD\_ENABLE and/or LCD\_BACKLIGHT\_ENABLE, to enable support -1. Include the visualizer.mk make file -1. Copy the files in the example\_integration folder to your keyboard project -1. All other files than the callback.c file are included automatically, so you will need to add callback.c to your makefile manually. If you already have a similar file in your project, you can just copy the functions instead of the whole file. -1. Edit the files to match your hardware. You might might want to read the Chibios and UGfx documentation, for more information. -1. If you enable LCD support you might also have to write a custom uGFX display driver, check the uGFX documentation for that. You probably also want to enable SPI support in your Chibios configuration. diff --git a/quantum/visualizer/resources/lcd_logo.c b/quantum/visualizer/resources/lcd_logo.c deleted file mode 100644 index 13bf734cb3..0000000000 --- a/quantum/visualizer/resources/lcd_logo.c +++ /dev/null @@ -1,45 +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 "resources.h" - -// clang-format off - -// To generate an image array like this -// Ensure the image is 128 x 32 or smaller -// Convert the bitmap to a C array using a program like http://www.riuson.com/lcd-image-converter/ -// Ensure the the conversion process produces a monochrome format array - 1 bit/pixel, left to right, top to bottom -// Update array in the source code with the C array produced by the conversion program - -// The image below is generated from lcd_logo.png -__attribute__((weak)) const uint8_t resource_lcd_logo[512] = { -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0xFE, 0xEE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xEE, 0xF0, 0x01, 0xC6, 0x0D, 0x8C, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0xFE, 0xEE, 0xFE, 0x03, 0xE7, 0x1D, 0x9C, 0x1F, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0xEE, 0xF0, 0x06, 0x37, 0x1D, 0xB8, 0x18, 0x0B, 0x59, 0xC8, 0x09, 0xE5, 0x9E, 0x00, -    0x00, 0x1E, 0xEE, 0xF0, 0x06, 0x37, 0xBD, 0xF0, 0x18, 0x6F, 0x7F, 0xEC, 0x9B, 0x37, 0xB3, 0x00, 0x00, 0xFE, 0xEE, 0xFE, 0x06, 0x37, 0xBD, 0xE0, 0x1F, 0x6C, 0x66, 0x6D, 0xD8, 0x36, 0x33, 0x00, -    0x00, 0x1E, 0xEE, 0xF0, 0x06, 0x36, 0xED, 0xF0, 0x1F, 0x6C, 0x66, 0x6D, 0x59, 0xF6, 0x3E, 0x00, 0x00, 0x1F, 0x6D, 0xF0, 0x06, 0x36, 0xED, 0xB8, 0x18, 0x6C, 0x66, 0x67, 0x73, 0x36, 0x30, 0x00, -    0x00, 0xFF, 0x83, 0xFE, 0x03, 0xE6, 0x4D, 0x9C, 0x18, 0x6C, 0x66, 0x67, 0x73, 0x36, 0x1F, 0x00, 0x00, 0x1F, 0xEF, 0xF0, 0x01, 0xC6, 0x0D, 0x8C, 0x18, 0x6C, 0x66, 0x62, 0x21, 0xD6, 0x0E, 0x00, -    0x00, 0xFF, 0xEF, 0xFE, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x02, 0x92, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; diff --git a/quantum/visualizer/resources/lcd_logo.png b/quantum/visualizer/resources/lcd_logo.pngBinary files differ deleted file mode 100644 index 178ef65f15..0000000000 --- a/quantum/visualizer/resources/lcd_logo.png +++ /dev/null diff --git a/quantum/visualizer/resources/resources.h b/quantum/visualizer/resources/resources.h deleted file mode 100644 index 5178fbe55a..0000000000 --- a/quantum/visualizer/resources/resources.h +++ /dev/null @@ -1,23 +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/>. - */ - -#pragma once - -#include <stdint.h> - -#ifdef LCD_ENABLE -extern const uint8_t resource_lcd_logo[]; -#endif diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c deleted file mode 100644 index 709affbb77..0000000000 --- a/quantum/visualizer/visualizer.c +++ /dev/null @@ -1,483 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 "config.h" -#include "visualizer.h" -#include <string.h> -#ifdef PROTOCOL_CHIBIOS -#    include <ch.h> -#endif - -#include "gfx.h" - -#ifdef LCD_BACKLIGHT_ENABLE -#    include "lcd_backlight.h" -#endif - -//#define DEBUG_VISUALIZER - -#ifdef DEBUG_VISUALIZER -#    include "debug.h" -#else -#    include "nodebug.h" -#endif - -#ifdef SERIAL_LINK_ENABLE -#    include "serial_link/protocol/transport.h" -#    include "serial_link/system/serial_link.h" -#endif - -#include "action_util.h" - -// Define this in config.h -#ifndef VISUALIZER_THREAD_PRIORITY -// The visualizer needs gfx thread priorities -#    define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2) -#endif - -static visualizer_keyboard_status_t current_status = {.layer         = 0xFFFFFFFF, -                                                      .default_layer = 0xFFFFFFFF, -                                                      .leds          = 0xFFFFFFFF, -#ifdef BACKLIGHT_ENABLE -                                                      .backlight_level = 0, -#endif -                                                      .mods      = 0xFF, -                                                      .suspended = false, -#ifdef VISUALIZER_USER_DATA_SIZE -                                                      .user_data = {0} -#endif -}; - -static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { -    return status1->layer == status2->layer && status1->default_layer == status2->default_layer && status1->mods == status2->mods && status1->leds == status2->leds && status1->suspended == status2->suspended -#ifdef BACKLIGHT_ENABLE -           && status1->backlight_level == status2->backlight_level -#endif -#ifdef VISUALIZER_USER_DATA_SIZE -           && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0 -#endif -        ; -} - -static bool visualizer_enabled = false; - -#ifdef VISUALIZER_USER_DATA_SIZE -static uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; -#endif - -#define MAX_SIMULTANEOUS_ANIMATIONS 4 -static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {}; - -#ifdef SERIAL_LINK_ENABLE -MASTER_TO_ALL_SLAVES_OBJECT(current_status, visualizer_keyboard_status_t); - -static remote_object_t* remote_objects[] = { -    REMOTE_OBJECT(current_status), -}; - -#endif - -GDisplay* LCD_DISPLAY = 0; -GDisplay* LED_DISPLAY = 0; - -#ifdef LCD_DISPLAY_NUMBER -__attribute__((weak)) GDisplay* get_lcd_display(void) { return gdispGetDisplay(LCD_DISPLAY_NUMBER); } -#endif - -#ifdef LED_DISPLAY_NUMBER -__attribute__((weak)) GDisplay* get_led_display(void) { return gdispGetDisplay(LED_DISPLAY_NUMBER); } -#endif - -void start_keyframe_animation(keyframe_animation_t* animation) { -    animation->current_frame      = -1; -    animation->time_left_in_frame = 0; -    animation->need_update        = true; -    int free_index                = -1; -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        if (animations[i] == animation) { -            return; -        } -        if (free_index == -1 && animations[i] == NULL) { -            free_index = i; -        } -    } -    if (free_index != -1) { -        animations[free_index] = animation; -    } -} - -void stop_keyframe_animation(keyframe_animation_t* animation) { -    animation->current_frame         = animation->num_frames; -    animation->time_left_in_frame    = 0; -    animation->need_update           = true; -    animation->first_update_of_frame = false; -    animation->last_update_of_frame  = false; -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        if (animations[i] == animation) { -            animations[i] = NULL; -            return; -        } -    } -} - -void stop_all_keyframe_animations(void) { -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        if (animations[i]) { -            animations[i]->current_frame         = animations[i]->num_frames; -            animations[i]->time_left_in_frame    = 0; -            animations[i]->need_update           = true; -            animations[i]->first_update_of_frame = false; -            animations[i]->last_update_of_frame  = false; -            animations[i]                        = NULL; -        } -    } -} - -static uint8_t get_num_running_animations(void) { -    uint8_t count = 0; -    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -        count += animations[i] ? 1 : 0; -    } -    return count; -} - -static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) { -    // TODO: Clean up this messy code -    dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, animation->time_left_in_frame, delta); -    if (animation->current_frame == animation->num_frames) { -        animation->need_update = false; -        return false; -    } -    if (animation->current_frame == -1) { -        animation->current_frame         = 0; -        animation->time_left_in_frame    = animation->frame_lengths[0]; -        animation->need_update           = true; -        animation->first_update_of_frame = true; -    } else { -        animation->time_left_in_frame -= delta; -        while (animation->time_left_in_frame <= 0) { -            int left = animation->time_left_in_frame; -            if (animation->need_update) { -                animation->time_left_in_frame   = 0; -                animation->last_update_of_frame = true; -                (*animation->frame_functions[animation->current_frame])(animation, state); -                animation->last_update_of_frame = false; -            } -            animation->current_frame++; -            animation->need_update           = true; -            animation->first_update_of_frame = true; -            if (animation->current_frame == animation->num_frames) { -                if (animation->loop) { -                    animation->current_frame = 0; -                } else { -                    stop_keyframe_animation(animation); -                    return false; -                } -            } -            delta                         = -left; -            animation->time_left_in_frame = animation->frame_lengths[animation->current_frame]; -            animation->time_left_in_frame -= delta; -        } -    } -    if (animation->need_update) { -        animation->need_update           = (*animation->frame_functions[animation->current_frame])(animation, state); -        animation->first_update_of_frame = false; -    } - -    systemticks_t wanted_sleep = animation->need_update ? gfxMillisecondsToTicks(10) : (unsigned)animation->time_left_in_frame; -    if (wanted_sleep < *sleep_time) { -        *sleep_time = wanted_sleep; -    } - -    return true; -} - -void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state) { -    int next_frame = animation->current_frame + 1; -    if (next_frame == animation->num_frames) { -        next_frame = 0; -    } -    keyframe_animation_t temp_animation  = *animation; -    temp_animation.current_frame         = next_frame; -    temp_animation.time_left_in_frame    = animation->frame_lengths[next_frame]; -    temp_animation.first_update_of_frame = true; -    temp_animation.last_update_of_frame  = false; -    temp_animation.need_update           = false; -    visualizer_state_t temp_state        = *state; -    (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state); -} - -// TODO: Optimize the stack size, this is probably way too big -static DECLARE_THREAD_STACK(visualizerThreadStack, 1024); -static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { -    (void)arg; - -    GListener event_listener; -    geventListenerInit(&event_listener); -    geventAttachSource(&event_listener, (GSourceHandle)¤t_status, 0); - -    visualizer_keyboard_status_t initial_status = { -        .default_layer = 0xFFFFFFFF, -        .layer         = 0xFFFFFFFF, -        .mods          = 0xFF, -        .leds          = 0xFFFFFFFF, -        .suspended     = false, -#ifdef BACKLIGHT_ENABLE -        .backlight_level = 0, -#endif -#ifdef VISUALIZER_USER_DATA_SIZE -        .user_data = {0}, -#endif -    }; - -    visualizer_state_t state = {.status            = initial_status, -                                .current_lcd_color = 0, -#ifdef LCD_ENABLE -                                .font_fixed5x8         = gdispOpenFont("fixed_5x8"), -                                .font_dejavusansbold12 = gdispOpenFont("DejaVuSansBold12") -#endif -    }; -    initialize_user_visualizer(&state); -    state.prev_lcd_color = state.current_lcd_color; - -#ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_color(LCD_HUE(state.current_lcd_color), LCD_SAT(state.current_lcd_color), LCD_INT(state.current_lcd_color)); -#endif - -    systemticks_t sleep_time   = TIME_INFINITE; -    systemticks_t current_time = gfxSystemTicks(); -    bool          force_update = true; - -    while (true) { -        systemticks_t new_time = gfxSystemTicks(); -        systemticks_t delta    = new_time - current_time; -        current_time           = new_time; -        bool enabled           = visualizer_enabled; -        if (force_update || !same_status(&state.status, ¤t_status)) { -            force_update = false; -#if BACKLIGHT_ENABLE -            if (current_status.backlight_level != state.status.backlight_level) { -                if (current_status.backlight_level != 0) { -                    gdispGSetPowerMode(LED_DISPLAY, powerOn); -                    uint16_t percent = (uint16_t)current_status.backlight_level * 100 / BACKLIGHT_LEVELS; -                    gdispGSetBacklight(LED_DISPLAY, percent); -                } else { -                    gdispGSetPowerMode(LED_DISPLAY, powerOff); -                } -                state.status.backlight_level = current_status.backlight_level; -            } -#endif -            if (visualizer_enabled) { -                if (current_status.suspended) { -                    stop_all_keyframe_animations(); -                    visualizer_enabled = false; -                    state.status       = current_status; -                    user_visualizer_suspend(&state); -                } else { -                    visualizer_keyboard_status_t prev_status = state.status; -                    state.status                             = current_status; -                    update_user_visualizer_state(&state, &prev_status); -                } -                state.prev_lcd_color = state.current_lcd_color; -            } -        } -        if (!enabled && state.status.suspended && current_status.suspended == false) { -            // Setting the status to the initial status will force an update -            // when the visualizer is enabled again -            state.status           = initial_status; -            state.status.suspended = false; -            stop_all_keyframe_animations(); -            user_visualizer_resume(&state); -            state.prev_lcd_color = state.current_lcd_color; -        } -        sleep_time = TIME_INFINITE; -        for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) { -            if (animations[i]) { -                update_keyframe_animation(animations[i], &state, delta, &sleep_time); -            } -        } -#ifdef BACKLIGHT_ENABLE -        gdispGFlush(LED_DISPLAY); -#endif - -#ifdef LCD_ENABLE -        gdispGFlush(LCD_DISPLAY); -#endif - -#ifdef EMULATOR -        draw_emulator(); -#endif -        // Enable the visualizer when the startup or the suspend animation has finished -        if (!visualizer_enabled && state.status.suspended == false && get_num_running_animations() == 0) { -            visualizer_enabled = true; -            force_update       = true; -            sleep_time         = 0; -        } - -        systemticks_t after_update = gfxSystemTicks(); -        unsigned      update_delta = after_update - current_time; -        if (sleep_time != TIME_INFINITE) { -            if (sleep_time > update_delta) { -                sleep_time -= update_delta; -            } else { -                sleep_time = 0; -            } -        } -        dprintf("Update took %d, last delta %d, sleep_time %d\n", update_delta, delta, sleep_time); -#ifdef PROTOCOL_CHIBIOS -        // The gEventWait function really takes milliseconds, even if the documentation says ticks. -        // Unfortunately there's no generic ugfx conversion from system time to milliseconds, -        // so let's do it in a platform dependent way. - -        // On windows the system ticks is the same as milliseconds anyway -        if (sleep_time != TIME_INFINITE) { -            sleep_time = TIME_I2MS(sleep_time); -        } -#endif -        geventEventWait(&event_listener, sleep_time); -    } -#ifdef LCD_ENABLE -    gdispCloseFont(state.font_fixed5x8); -    gdispCloseFont(state.font_dejavusansbold12); -#endif - -    return 0; -} - -void visualizer_init(void) { -    gfxInit(); - -#ifdef LCD_BACKLIGHT_ENABLE -    lcd_backlight_init(); -#endif - -#ifdef SERIAL_LINK_ENABLE -    add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*)); -#endif - -#ifdef LCD_ENABLE -    LCD_DISPLAY = get_lcd_display(); -#endif - -#ifdef BACKLIGHT_ENABLE -    LED_DISPLAY = get_led_display(); -#endif - -    // We are using a low priority thread, the idea is to have it run only -    // when the main thread is sleeping during the matrix scanning -    gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL); -} - -void update_status(bool changed) { -    if (changed) { -        GSourceListener* listener = geventGetSourceListener((GSourceHandle)¤t_status, NULL); -        if (listener) { -            geventSendEvent(listener); -        } -    } -#ifdef SERIAL_LINK_ENABLE -    static systime_t last_update    = 0; -    systime_t        current_update = chVTGetSystemTimeX(); -    systime_t        delta          = current_update - last_update; -    if (changed || delta > TIME_MS2I(10)) { -        last_update                     = current_update; -        visualizer_keyboard_status_t* r = begin_write_current_status(); -        *r                              = current_status; -        end_write_current_status(); -    } -#endif -} - -uint8_t visualizer_get_mods() { -    uint8_t mods = get_mods(); - -#ifndef NO_ACTION_ONESHOT -    if (!has_oneshot_mods_timed_out()) { -        mods |= get_oneshot_mods(); -    } -#endif -    return mods; -} - -#ifdef VISUALIZER_USER_DATA_SIZE -void visualizer_set_user_data(void* u) { memcpy(user_data, u, VISUALIZER_USER_DATA_SIZE); } -#endif - -void visualizer_update(layer_state_t default_state, layer_state_t state, uint8_t mods, uint32_t leds) { -    // Note that there's a small race condition here, the thread could read -    // a state where one of these are set but not the other. But this should -    // not really matter as it will be fixed during the next loop step. -    // Alternatively a mutex could be used instead of the volatile variables - -    bool changed = false; -#ifdef SERIAL_LINK_ENABLE -    if (is_serial_link_connected()) { -        visualizer_keyboard_status_t* new_status = read_current_status(); -        if (new_status) { -            if (!same_status(¤t_status, new_status)) { -                changed        = true; -                current_status = *new_status; -            } -        } -    } else { -#else -    { -#endif -        visualizer_keyboard_status_t new_status = { -            .layer         = state, -            .default_layer = default_state, -            .mods          = mods, -            .leds          = leds, -#ifdef BACKLIGHT_ENABLE -            .backlight_level = current_status.backlight_level, -#endif -            .suspended = current_status.suspended, -        }; -#ifdef VISUALIZER_USER_DATA_SIZE -        memcpy(new_status.user_data, user_data, VISUALIZER_USER_DATA_SIZE); -#endif -        if (!same_status(¤t_status, &new_status)) { -            changed        = true; -            current_status = new_status; -        } -    } -    update_status(changed); -} - -void visualizer_suspend(void) { -    current_status.suspended = true; -    update_status(true); -} - -void visualizer_resume(void) { -    current_status.suspended = false; -    update_status(true); -} - -#ifdef BACKLIGHT_ENABLE -void backlight_set(uint8_t level) { -    current_status.backlight_level = level; -    update_status(true); -} -#endif diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h deleted file mode 100644 index 627c80a305..0000000000 --- a/quantum/visualizer/visualizer.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Fred Sundvik - -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. - -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 <stdlib.h> -#include <stdint.h> -#include <stdbool.h> - -#include "config.h" -#include "gfx.h" -#include "action_layer.h" - -#ifdef LCD_BACKLIGHT_ENABLE -#    include "lcd_backlight.h" -#endif - -#ifdef BACKLIGHT_ENABLE -#    include "backlight.h" -#endif - -// use this function to merge both real_mods and oneshot_mods in a uint16_t -uint8_t visualizer_get_mods(void); - -// This need to be called once at the start -void visualizer_init(void); -// This should be called at every matrix scan -void visualizer_update(layer_state_t default_state, layer_state_t state, uint8_t mods, uint32_t leds); - -// This should be called when the keyboard goes to suspend state -void visualizer_suspend(void); -// This should be called when the keyboard wakes up from suspend state -void visualizer_resume(void); - -// These functions are week, so they can be overridden by the keyboard -// if needed -GDisplay* get_lcd_display(void); -GDisplay* get_led_display(void); - -// For emulator builds, this function need to be implemented -#ifdef EMULATOR -void draw_emulator(void); -#endif - -// If you need support for more than 16 keyframes per animation, you can change this -#define MAX_VISUALIZER_KEY_FRAMES 16 - -struct keyframe_animation_t; - -typedef struct { -    layer_state_t layer; -    layer_state_t default_layer; -    uint32_t      leds;  // See led.h for available statuses -    uint8_t       mods; -    bool          suspended; -#ifdef BACKLIGHT_ENABLE -    uint8_t backlight_level; -#endif -#ifdef VISUALIZER_USER_DATA_SIZE -    uint8_t user_data[VISUALIZER_USER_DATA_SIZE]; -#endif -} visualizer_keyboard_status_t; - -// The state struct is used by the various keyframe functions -// It's also used for setting the LCD color and layer text -// from the user customized code -typedef struct visualizer_state_t { -    // The user code should primarily be modifying these -    uint32_t    target_lcd_color; -    const char* layer_text; - -    // The user visualizer(and animation functions) can read these -    visualizer_keyboard_status_t status; - -    // These are used by the animation functions -    uint32_t current_lcd_color; -    uint32_t prev_lcd_color; -#ifdef LCD_ENABLE -    gFont font_fixed5x8; -    gFont font_dejavusansbold12; -#endif -} visualizer_state_t; - -// Any custom keyframe function should have this signature -// return true to get continuous updates, otherwise you will only get one -// update per frame -typedef bool (*frame_func)(struct keyframe_animation_t*, visualizer_state_t*); - -// Represents a keyframe animation, so fields are internal to the system -// while others are meant to be initialized by the user code -typedef struct keyframe_animation_t { -    // These should be initialized -    int        num_frames; -    bool       loop; -    int        frame_lengths[MAX_VISUALIZER_KEY_FRAMES]; -    frame_func frame_functions[MAX_VISUALIZER_KEY_FRAMES]; - -    // Used internally by the system, and can also be read by -    // keyframe update functions -    int  current_frame; -    int  time_left_in_frame; -    bool first_update_of_frame; -    bool last_update_of_frame; -    bool need_update; - -} keyframe_animation_t; - -extern GDisplay* LCD_DISPLAY; -extern GDisplay* LED_DISPLAY; - -void start_keyframe_animation(keyframe_animation_t* animation); -void stop_keyframe_animation(keyframe_animation_t* animation); -// This runs the next keyframe, but does not update the animation state -// Useful for crossfades for example -void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state); - -// The master can set userdata which will be transferred to the slave -#ifdef VISUALIZER_USER_DATA_SIZE -void visualizer_set_user_data(void* user_data); -#endif - -// These functions have to be implemented by the user -// Called regularly each time the state has changed (but not every scan loop) -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status); -// Called when the computer goes to suspend, will also stop calling update_user_visualizer_state -void user_visualizer_suspend(visualizer_state_t* state); -// You have to start at least one animation as a response to the following two functions -// When the animation has finished the visualizer will resume normal operation and start calling the -// update_user_visualizer_state again -// Called when the keyboard boots up -void initialize_user_visualizer(visualizer_state_t* state); -// Called when the computer resumes from a suspend -void user_visualizer_resume(visualizer_state_t* state); diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk deleted file mode 100644 index 4c961ac59d..0000000000 --- a/quantum/visualizer/visualizer.mk +++ /dev/null @@ -1,123 +0,0 @@ -# The MIT License (MIT) -#  -# Copyright (c) 2016 Fred Sundvik -#  -# 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. -#  -# 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. - -define ADD_DRIVER -    $(1)_DRIVER:=$(strip $($(1)_DRIVER)) -    $(1)_WIDTH:=$(strip $($(1)_WIDTH)) -    $(1)_HEIGHT:=$(strip $($(1)_HEIGHT)) -    ifeq ($($(1)_DRIVER),) -        $$(error $(1)_DRIVER is not defined) -    endif -    ifeq ($($(1)_WIDTH),) -        $$(error $(1)_WIDTH is not defined) -    endif -    ifeq ($($(1)_HEIGHT),) -        $$(error $(1)_HEIGHT is not defined) -    endif -    OPT_DEFS+=-D$(1)_WIDTH=$($(1)_WIDTH) -    OPT_DEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT) -    GFXDEFS+=-D$(1)_WIDTH=$($(1)_WIDTH) -    GFXDEFS+=-D$(1)_HEIGHT=$($(1)_HEIGHT) -    $(1)_DISPLAY_NUMBER:=$$(words $$(GDISP_DRIVER_LIST)) -    OPT_DEFS+=-D$(1)_DISPLAY_NUMBER=$$($(1)_DISPLAY_NUMBER) -    include $(TOP_DIR)/drivers/ugfx/gdisp/$($(1)_DRIVER)/driver.mk -endef - -GDISP_DRIVER_LIST:= - -SRC += $(VISUALIZER_DIR)/visualizer.c \ -	$(VISUALIZER_DIR)/visualizer_keyframes.c -EXTRAINCDIRS += $(GFXINC) $(VISUALIZER_DIR) -GFXLIB = $(LIB_PATH)/ugfx -VPATH += $(VISUALIZER_PATH) - -OPT_DEFS += -DVISUALIZER_ENABLE - -ifdef LCD_ENABLE -OPT_DEFS += -DLCD_ENABLE -ULIBS += -lm -endif - -ifeq ($(strip $(LCD_ENABLE)), yes) -    SRC += $(VISUALIZER_DIR)/lcd_keyframes.c -    ifeq ($(strip $(LCD_BACKLIGHT_ENABLE)), yes) -        OPT_DEFS += -DLCD_BACKLIGHT_ENABLE -        SRC += $(VISUALIZER_DIR)/lcd_backlight.c -        SRC += $(VISUALIZER_DIR)/lcd_backlight_keyframes.c -    endif -# Note, that the linker will strip out any resources that are not actually in use -SRC += $(VISUALIZER_DIR)/resources/lcd_logo.c -$(eval $(call ADD_DRIVER,LCD)) -endif - -ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) -SRC += $(VISUALIZER_DIR)/led_backlight_keyframes.c -$(eval $(call ADD_DRIVER,LED)) -endif - -SRC += $(VISUALIZER_DIR)/default_animations.c - -include $(GFXLIB)/gfx.mk -# For the common_gfxconf.h -GFXINC += quantum/visualizer - -GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC)) -GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) - -GDISP_LIST_COMMA=, -GDISP_LIST_EMPTY= -GDISP_LIST_SPACE=$(GDISP_LIST_EMPTY) $(GDISP_LIST_EMPTY) - -GDISP_DRIVER_LIST := $(strip $(GDISP_DRIVER_LIST)) -GDISP_DRIVER_LIST := $(subst $(GDISP_LIST_SPACE),$(GDISP_LIST_COMMA),$(GDISP_DRIVER_LIST)) - -GFXDEFS +=-DGDISP_DRIVER_LIST="$(GDISP_DRIVER_LIST)" - -ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") -    SRC += $(KEYMAP_PATH)/visualizer.c -else  -    VISUALIZER_1 := $(KEYBOARD_PATH_1)/visualizer.c -    VISUALIZER_2 := $(KEYBOARD_PATH_2)/visualizer.c -    VISUALIZER_3 := $(KEYBOARD_PATH_3)/visualizer.c -    VISUALIZER_4 := $(KEYBOARD_PATH_4)/visualizer.c -    VISUALIZER_5 := $(KEYBOARD_PATH_5)/visualizer.c - -    ifneq ("$(wildcard $(VISUALIZER_5))","") -        SRC += $(VISUALIZER_5) -    endif -    ifneq ("$(wildcard $(VISUALIZER_4))","") -        SRC += $(VISUALIZER_4) -    endif -    ifneq ("$(wildcard $(VISUALIZER_3))","") -        SRC += $(VISUALIZER_3) -    endif -    ifneq ("$(wildcard $(VISUALIZER_2))","") -        SRC += $(VISUALIZER_2) -    endif -    ifneq ("$(wildcard $(VISUALIZER_1))","") -        SRC += $(VISUALIZER_1) -    endif -endif - -ifdef EMULATOR -UINCDIR += $(TMK_DIR)/common -endif diff --git a/quantum/visualizer/visualizer_keyframes.c b/quantum/visualizer/visualizer_keyframes.c deleted file mode 100644 index 8f6a7e15a4..0000000000 --- a/quantum/visualizer/visualizer_keyframes.c +++ /dev/null @@ -1,23 +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 "visualizer_keyframes.h" - -bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state) { -    (void)animation; -    (void)state; -    return false; -} diff --git a/quantum/visualizer/visualizer_keyframes.h b/quantum/visualizer/visualizer_keyframes.h deleted file mode 100644 index c92ff16113..0000000000 --- a/quantum/visualizer/visualizer_keyframes.h +++ /dev/null @@ -1,23 +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/>. - */ - -#pragma once - -#include "visualizer.h" - -// Some predefined keyframe functions that can be used by the user code -// Does nothing, useful for adding delays -bool keyframe_no_operation(keyframe_animation_t* animation, visualizer_state_t* state); | 
