├── .gitignore ├── CMakeLists.txt ├── Dockerfile ├── README.md ├── build.sh ├── components ├── battery │ ├── CMakeLists.txt │ ├── battery_monitor.c │ └── include │ │ └── battery_monitor.h ├── ble │ ├── CMakeLists.txt │ ├── hal_ble.c │ ├── hid_dev.c │ ├── hid_device_le_prf.c │ ├── include │ │ ├── common.h │ │ ├── hal_ble.h │ │ ├── hid_dev.h │ │ ├── hidd_le_prf_int.h │ │ ├── keyboard.h │ │ ├── keylayouts.h │ │ └── undefkeylayouts.h │ └── keyboard.c ├── espnowmk32 │ ├── CMakeLists.txt │ ├── espnow_receive.c │ ├── espnow_send.c │ └── include │ │ ├── espnow_receive.h │ │ └── espnow_send.h ├── hidkeycodeconv │ ├── CMakeLists.txt │ ├── include │ │ └── keycode_conv.h │ └── keycode_conv.c ├── nvsfuncs │ ├── CMakeLists.txt │ ├── arr_conv.c │ ├── include │ │ ├── arr_conv.h │ │ ├── nvs_funcs.h │ │ └── nvs_keymaps.h │ └── nvs_funcs.c ├── oled │ ├── CMakeLists.txt │ ├── include │ │ ├── oled_tasks.h │ │ ├── u8g2.h │ │ ├── u8g2_esp32_hal.h │ │ └── u8x8.h │ ├── oled_tasks.c │ ├── u8g2_bitmap.c │ ├── u8g2_box.c │ ├── u8g2_buffer.c │ ├── u8g2_circle.c │ ├── u8g2_cleardisplay.c │ ├── u8g2_d_memory.c │ ├── u8g2_d_setup.c │ ├── u8g2_esp32_hal.c │ ├── u8g2_font.c │ ├── u8g2_fonts.c │ ├── u8g2_hvline.c │ ├── u8g2_input_value.c │ ├── u8g2_intersection.c │ ├── u8g2_kerning.c │ ├── u8g2_line.c │ ├── u8g2_ll_hvline.c │ ├── u8g2_message.c │ ├── u8g2_polygon.c │ ├── u8g2_selection_list.c │ ├── u8g2_setup.c │ ├── u8log.c │ ├── u8log_u8g2.c │ ├── u8log_u8x8.c │ ├── u8x8_8x8.c │ ├── u8x8_byte.c │ ├── u8x8_cad.c │ ├── u8x8_d_a2printer.c │ ├── u8x8_d_il3820_296x128.c │ ├── u8x8_d_ist3020.c │ ├── u8x8_d_ks0108.c │ ├── u8x8_d_lc7981.c │ ├── u8x8_d_ld7032_60x32.c │ ├── u8x8_d_ls013b7dh03.c │ ├── u8x8_d_max7219.c │ ├── u8x8_d_pcd8544_84x48.c │ ├── u8x8_d_pcf8812.c │ ├── u8x8_d_pcf8814_hx1230.c │ ├── u8x8_d_sbn1661.c │ ├── u8x8_d_sed1330.c │ ├── u8x8_d_sh1106_64x32.c │ ├── u8x8_d_sh1106_72x40.c │ ├── u8x8_d_sh1107.c │ ├── u8x8_d_sh1108.c │ ├── u8x8_d_sh1122.c │ ├── u8x8_d_ssd1305.c │ ├── u8x8_d_ssd1306_128x32.c │ ├── u8x8_d_ssd1306_128x64_noname.c │ ├── u8x8_d_ssd1306_48x64.c │ ├── u8x8_d_ssd1306_64x32.c │ ├── u8x8_d_ssd1306_64x48.c │ ├── u8x8_d_ssd1306_96x16.c │ ├── u8x8_d_ssd1309.c │ ├── u8x8_d_ssd1317.c │ ├── u8x8_d_ssd1322.c │ ├── u8x8_d_ssd1325.c │ ├── u8x8_d_ssd1326.c │ ├── u8x8_d_ssd1327.c │ ├── u8x8_d_ssd1329.c │ ├── u8x8_d_ssd1606_172x72.c │ ├── u8x8_d_ssd1607_200x200.c │ ├── u8x8_d_st75256.c │ ├── u8x8_d_st7565.c │ ├── u8x8_d_st7567.c │ ├── u8x8_d_st7586s_erc240160.c │ ├── u8x8_d_st7586s_s028hn118a.c │ ├── u8x8_d_st7588.c │ ├── u8x8_d_st7920.c │ ├── u8x8_d_stdio.c │ ├── u8x8_d_t6963.c │ ├── u8x8_d_uc1601.c │ ├── u8x8_d_uc1604.c │ ├── u8x8_d_uc1608.c │ ├── u8x8_d_uc1610.c │ ├── u8x8_d_uc1611.c │ ├── u8x8_d_uc1617.c │ ├── u8x8_d_uc1638.c │ ├── u8x8_d_uc1701_dogs102.c │ ├── u8x8_d_uc1701_mini12864.c │ ├── u8x8_debounce.c │ ├── u8x8_display.c │ ├── u8x8_fonts.c │ ├── u8x8_gpio.c │ ├── u8x8_input_value.c │ ├── u8x8_message.c │ ├── u8x8_selection_list.c │ ├── u8x8_setup.c │ ├── u8x8_string.c │ ├── u8x8_u16toa.c │ └── u8x8_u8toa.c ├── plugins │ ├── CMakeLists.txt │ ├── include │ │ ├── layout_server.h │ │ ├── plugin_manager.h │ │ ├── plugins.h │ │ └── testFunc.h │ ├── layout_server.c │ ├── plugin_manager.c │ ├── plugins.c │ └── testFunc.c ├── rotencoder │ ├── CMakeLists.txt │ ├── include │ │ └── r_encoder.h │ └── r_encoder.c └── wifiman │ ├── CMakeLists.txt │ ├── include │ └── wifi_manager.h │ └── wifi_manager.c ├── keyboards ├── catiONE │ ├── keyboard_config.h │ ├── keymap.c │ └── matrix.c ├── default │ ├── keyboard_config.h │ ├── keymap.c │ └── matrix.c ├── letSplitIsh │ ├── keyboard_config.h │ ├── keymap.c │ └── matrix.c └── x32k │ ├── keyboard_config.h │ ├── keymap.h │ └── matrix.h ├── main ├── CMakeLists.txt ├── key_definitions.h ├── keyboard_config.h ├── keymap.c ├── keymap.h ├── keypress_handles.c ├── matrix.c ├── matrix.h └── mk32_main.cpp ├── partitions.csv ├── run.sh └── sdkconfig.defaults /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | .vscode/ 3 | cmake-* 4 | .idea/ 5 | sdkconfig.old 6 | sdkconfig -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about build system see 2 | # https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html 3 | # The following five lines of boilerplate have to be in your project's 4 | # CMakeLists in this exact order for cmake to work correctly 5 | cmake_minimum_required(VERSION 3.5) 6 | 7 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 8 | project(MK32) 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM espressif/idf:release-v4.4 2 | RUN mkdir /home/workspace 3 | RUN mkdir /home/workspace/cmakebuild 4 | COPY components /home/workspace/components 5 | COPY main /home/workspace/main 6 | COPY CMakeLists.txt /home/workspace/ 7 | COPY partitions.csv /home/workspace/ 8 | COPY README.md /home/workspace/ 9 | COPY sdkconfig.defaults /home/workspace/ 10 | WORKDIR /home/workspace/cmakebuild 11 | RUN /bin/bash -c "source /opt/esp/idf/export.sh" 12 | ENV PATH="/opt/esp/tools/cmake/3.23.1/bin:${PATH}" 13 | ENV PATH="/opt/esp/idf/components/esptool_py/esptool:${PATH}" 14 | ENV PATH="/opt/esp/idf/components/espcoredump:${PATH}" 15 | ENV PATH="/opt/esp/idf/components/partition_table:${PATH}" 16 | ENV PATH="/opt/esp/idf/components/app_update:${PATH}" 17 | ENV PATH="/opt/esp/tools/xtensa-esp32-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32-elf/bin:${PATH}" 18 | ENV PATH="/opt/esp/tools/xtensa-esp32s2-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s2-elf/bin:${PATH}" 19 | ENV PATH="/opt/esp/tools/xtensa-esp32s3-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s3-elf/bin:${PATH}" 20 | ENV PATH="/opt/esp/tools/riscv32-esp-elf/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin:${PATH}" 21 | ENV PATH="/opt/esp/tools/esp32ulp-elf/2.35_20220830/esp32ulp-elf-binutils/bin:${PATH}" 22 | ENV PATH="/opt/esp/tools/openocd-esp32/v0.11.0-esp32-20221026/openocd-esp32/bin:${PATH}" 23 | ENV PATH="/opt/esp/python_env/idf4.4_py3.8_env/bin:${PATH}" 24 | ENV PATH="/opt/esp/idf/tools:${PATH}" 25 | RUN cmake /home/workspace/ 26 | RUN make 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MK32 - Simple BLE keyboard for ESP32 2 | 3 | ### *** This repo is not maintained *** 4 | ### *** This was one of my first software projects and is very poorly designed and written. I recommend seeking an alternative FW solution *** 5 | dungphan90's fork: 6 | - Updated to ESP-IDF v4.4. 7 | - Migrated to CMake build system. 8 | - Added Docker to avoid dependency mess. 9 | - Added keyboard config and layout for "CatiONE OLKB" (https://github.com/dungphan90/OLKBBLE.git). 10 | 11 | ### Easy build process with Docker. 12 | ``` 13 | git clone https://github.com/Galzai/MK32.git 14 | cd MK32 15 | chmod +x ./build.sh 16 | chmod +x ./run.sh 17 | ./build.sh 18 | ./run.sh 19 | ``` 20 | Once you're inside the container, you can run `make` to buid, `make flash` to flash the firmware, and `make monitor` to run debug. 21 | ___ 22 | 23 | MK32 is a BLE keyboard firmware for ESP32 Microcontrollers,designed to be relatively easily customizable. 24 | Please refer to the [MK32 Wiki page](https://github.com/Galzai/MK32/wiki) for information about building your own keyboard. 25 | Also note that this repository is not heavily maintained. 26 | 27 | ### Many thanks to: 28 | - Benjamin Aigner for his work on implementing HID over BLE on the ESP32: https://github.com/asterics/esp32_mouse_keyboard. 29 | - Neil Kolban for his great contributions to the ESP32 SW (in particular the Bluetooth support): https://github.com/nkolban 30 | - QMK for their layouts and inspiration for this project: https://github.com/qmk/qmk_firmware/ 31 | 32 | ## Features: 33 | - Split Keyboards 34 | - I2C/SPI displays 35 | - Customizable layouts 36 | - Macros 37 | - Rotary Encoders (With customizable encoder commands) 38 | - Battery Monitoring 39 | - Power Management 40 | - Basic plugin support 41 | 42 | ## To-do: 43 | - Refactor some bad coding habits (magic numbers etc, sorry I started this project when I had 0 experience!). 44 | - Plugin API support(Implemented): 45 | * Currently only one plugin can run at a time (to modify). 46 | - More than 2 pads with espnow (currently supports 2 pads) - Optional. 47 | - Connection switching. 48 | - Modify keymap via webserver: 49 | * Functions for storing (and reading) AP data on flash complete. 50 | * Starting web server from plugin complete. 51 | * need to create proper web GUI for keymap modifications. 52 | - Wifi manager: 53 | * Add plugin for adding AP. 54 | * Functions for storing (and reading) AP from flash done. 55 | * ESPNOW does not work if wifi AP is not on the same channel (Problematic for ESPNOW Based split boards). 56 | 57 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | # Build 4 | docker build -t mk32:latest . 5 | -------------------------------------------------------------------------------- /components/battery/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "battery_monitor.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES esp_adc_cal oled) 4 | -------------------------------------------------------------------------------- /components/battery/battery_monitor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This battery monitoring code is based on reading the voltage 3 | * after after a voltage divider and checking the level on an analog pin 4 | * Based on the adc example from Espressif 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 | * MA 02110-1301, USA. 20 | * 21 | * Copyright 2018 Gal Zaidenstein. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "esp_system.h" 30 | #include "driver/gpio.h" 31 | #include "driver/adc.h" 32 | #include "esp_adc_cal.h" 33 | #include "keyboard_config.h" 34 | 35 | #include "battery_monitor.h" 36 | 37 | #define DEFAULT_VREF 1100 //Use adc2_vref_to_gpio() to obtain a better estimate 38 | #define NO_OF_SAMPLES 500 //Multisampling 39 | 40 | static const adc_channel_t channel = BATT_PIN; 41 | static const adc_atten_t atten = ADC_ATTEN_DB_2_5; 42 | static const adc_unit_t unit = ADC_UNIT_1; 43 | 44 | uint32_t voltage = 0; 45 | 46 | static esp_adc_cal_characteristics_t *adc_chars; 47 | //check battery level 48 | 49 | uint32_t get_battery_level(void) { 50 | 51 | uint32_t adc_reading = 0; 52 | //Multisampling 53 | 54 | for (int i = 0; i < NO_OF_SAMPLES; i++) { 55 | adc_reading += adc1_get_raw((adc1_channel_t) channel); 56 | } 57 | adc_reading /= NO_OF_SAMPLES; 58 | 59 | //Convert adc_reading to voltage in mV 60 | voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); 61 | uint32_t battery_percent = ((voltage - Vout_min) * 100 62 | / (Vout_max - Vout_min)); 63 | // printf("Raw: %d\tVoltage: %dmV\tPercent: %d\n", adc_reading, voltage, battery_percent); 64 | return battery_percent; 65 | 66 | } 67 | 68 | //initialize battery monitor pin 69 | void init_batt_monitor(void) { 70 | 71 | adc1_config_width(ADC_WIDTH_BIT_12); 72 | adc1_config_channel_atten(BATT_PIN, atten); 73 | adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t)); 74 | esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, 75 | adc_chars); 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /components/battery/include/battery_monitor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * battery_monitor.h 3 | * 4 | * Created on: 6 Sep 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef BATTERY_MONITOR_BATTERY_MONITOR_H_ 9 | #define BATTERY_MONITOR_BATTERY_MONITOR_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /* 16 | *Please make sure you understand what is a voltage divider before modifying 17 | * */ 18 | 19 | #define R_1 47 //Pull-up resistor [kOhm] 20 | #define R_2 22 //Pull-down resistor [kOhm] 21 | 22 | /*These are approximate values, 23 | * battery voltage isn't completely linear, it would be better to use a table for specific battery 24 | * For now this is an ok approximation. 25 | */ 26 | #define Vin_max 4200 //Max Battery voltage [mV] 27 | #define Vin_min 3400 //Battery discharge Voltage[mV] 28 | 29 | #define Vout_max Vin_max*R_2/(R_1+R_2) //Max voltage on analog pin [mV] 30 | #define Vout_min Vin_min*R_2/(R_1+R_2) //Min voltage on analog pin [mV] 31 | 32 | uint32_t get_battery_level(void); 33 | 34 | //initialize battery monitor pin 35 | void init_batt_monitor(void); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* BATTERY_MONITOR_BATTERY_MONITOR_H_ */ 42 | -------------------------------------------------------------------------------- /components/ble/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "keyboard.c" "hal_ble.c" "hid_dev.c" "hid_device_le_prf.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES "bt" "battery") -------------------------------------------------------------------------------- /components/ble/hid_dev.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "hid_dev.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "esp_log.h" 21 | 22 | static hid_report_map_t *hid_dev_rpt_tbl; 23 | static uint8_t hid_dev_rpt_tbl_Len; 24 | 25 | static hid_report_map_t *hid_dev_rpt_by_id(uint8_t id, uint8_t type) { 26 | hid_report_map_t *rpt = hid_dev_rpt_tbl; 27 | 28 | for (uint8_t i = hid_dev_rpt_tbl_Len; i > 0; i--, rpt++) { 29 | if (rpt->id == id && rpt->type == type 30 | && rpt->mode == hidProtocolMode) { 31 | return rpt; 32 | } 33 | } 34 | 35 | return NULL; 36 | } 37 | 38 | void hid_dev_register_reports(uint8_t num_reports, hid_report_map_t *p_report) { 39 | hid_dev_rpt_tbl = p_report; 40 | hid_dev_rpt_tbl_Len = num_reports; 41 | return; 42 | } 43 | 44 | void hid_dev_send_report(esp_gatt_if_t gatts_if, uint16_t conn_id, uint8_t id, 45 | uint8_t type, uint8_t length, uint8_t *data) { 46 | hid_report_map_t *p_rpt; 47 | 48 | // get att handle for report 49 | if ((p_rpt = hid_dev_rpt_by_id(id, type)) != NULL) { 50 | // if notifications are enabled 51 | ESP_LOGD(HID_LE_PRF_TAG, "%s(), send the report, handle = %d", __func__, 52 | p_rpt->handle); 53 | esp_ble_gatts_send_indicate(gatts_if, conn_id, p_rpt->handle, length, 54 | data, false); 55 | } 56 | 57 | return; 58 | } 59 | 60 | 61 | -------------------------------------------------------------------------------- /components/ble/include/hal_ble.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | * 17 | * Copyright 2019 Benjamin Aigner 18 | */ 19 | 20 | /** @file 21 | * @brief This file is a wrapper for the BLE-HID example of Espressif. 22 | */ 23 | #ifndef _HAL_BLE_H_ 24 | #define _HAL_BLE_H_ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "common.h" 32 | 33 | #include "esp_bt.h" 34 | #include "esp_bt_defs.h" 35 | #include "esp_gap_ble_api.h" 36 | #include "esp_gatts_api.h" 37 | #include "esp_gatt_defs.h" 38 | #include "esp_bt_main.h" 39 | #include "esp_bt_device.h" 40 | #include "hid_dev.h" 41 | #include "nvs_flash.h" 42 | 43 | /** @brief Stack size for BLE task */ 44 | #define TASK_BLE_STACKSIZE 2048 45 | 46 | /** @brief Queue for sending keyboard reports 47 | * @see keyboard_command_t */ 48 | extern QueueHandle_t battery_q; 49 | 50 | /** @brief Queue for sending mouse reports 51 | * @see mouse_command_t */ 52 | extern QueueHandle_t mouse_q; 53 | 54 | /** @brief Queue for sending keyboard reports 55 | * @see keyboard_command_t */ 56 | extern QueueHandle_t keyboard_q; 57 | 58 | /** @brief Queue for sending joystick reports 59 | * @see joystick_command_t */ 60 | extern QueueHandle_t joystick_q; 61 | 62 | /** @brief Queue for sending media reports 63 | * @see media_command_t */ 64 | extern QueueHandle_t media_q; 65 | 66 | /** @brief Activate/deactivate pairing mode 67 | * @param enable If set to != 0, pairing will be enabled. Disabled if == 0 68 | * @return ESP_OK on success, ESP_FAIL otherwise*/ 69 | esp_err_t halBLESetPairing(uint8_t enable); 70 | 71 | /** @brief Get connection status 72 | * @return 0 if not connected, != 0 if connected */ 73 | uint8_t halBLEIsConnected(void); 74 | 75 | /** @brief En- or Disable BLE interface. 76 | * 77 | * This method is used to enable or disable the BLE interface. Currently, the ESP32 78 | * cannot use WiFi and BLE simultaneously. Therefore, when enabling wifi, it is 79 | * necessary to disable BLE prior calling taskWebGUIEnDisable. 80 | * 81 | * @note Calling this method prior to initializing BLE via halBLEInit will 82 | * result in an error! 83 | * @return ESP_OK on success, ESP_FAIL otherwise 84 | * @param onoff If != 0, switch on BLE, switch off if 0. 85 | * */ 86 | esp_err_t halBLEEnDisable(int onoff); 87 | 88 | /** @brief Reset the BLE data 89 | * 90 | * Used for slot/config switchers. 91 | * It resets the keycode array and sets all HID reports to 0 92 | * (release all keys, avoiding sticky keys on a config change) 93 | * @param exceptDevice if you want to reset only a part of the devices, set flags 94 | * accordingly: 95 | * 96 | * (1<<0) excepts keyboard 97 | * (1<<1) excepts joystick 98 | * (1<<2) excepts mouse 99 | * If nothing is set (exceptDevice = 0) all are reset 100 | * */ 101 | void halBLEReset(uint8_t exceptDevice); 102 | 103 | /** @brief Main init function to start HID interface (C interface) 104 | * @see hid_ble */ 105 | esp_err_t halBLEInit(uint8_t enableKeyboard, uint8_t enableMedia, 106 | uint8_t enableMouse, uint8_t enableJoystick); 107 | 108 | #endif /* _HAL_BLE_H_ */ 109 | -------------------------------------------------------------------------------- /components/espnowmk32/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "espnow_receive.c" "espnow_send.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES "nvs_flash" "ble" "rotencoder" "nvsfuncs" "esp_wifi" "freertos") 4 | -------------------------------------------------------------------------------- /components/espnowmk32/espnow_receive.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | * 17 | * Copyright 2018 Gal Zaidenstein. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | #include "freertos/FreeRTOS.h" 27 | #include "freertos/semphr.h" 28 | #include "freertos/timers.h" 29 | #include "nvs_flash.h" 30 | #include "esp_event_loop.h" 31 | #include "tcpip_adapter.h" 32 | #include "esp_wifi.h" 33 | #include "esp_wifi_types.h" 34 | #include "esp_log.h" 35 | #include "esp_system.h" 36 | #include "esp_now.h" 37 | 38 | #include "espnow_receive.h" 39 | #include "keyboard_config.h" 40 | #include "r_encoder.h" 41 | #include "nvs_keymaps.h" 42 | 43 | QueueHandle_t espnow_receive_q; 44 | 45 | //ESP-now tag for reports 46 | #define ESP_NOW_TAG "ESP-NOW" 47 | 48 | // Queue for received esp-now report 49 | static const uint8_t channel = 10; 50 | //uint8_t master_mac_adr[6]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; // Will be used in the future for setting a mac address manually 51 | 52 | static void wifi_initialize_receive(void){ 53 | 54 | ESP_LOGI(ESP_NOW_TAG,"Initialing WiFi"); 55 | uint8_t slave_mac_adr[6]; 56 | 57 | tcpip_adapter_init(); 58 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 59 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 60 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 61 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); 62 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)) ; // For some reason ESP-NOW only works if all devices are in the same mode 63 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); 64 | //esp_wifi_set_mac(ESP_IF_WIFI_STA, master_mac_adr); 65 | ESP_ERROR_CHECK(esp_wifi_start()); 66 | esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); // Make sure we are on the same channel 67 | ESP_ERROR_CHECK(esp_wifi_get_mac(ESP_IF_WIFI_STA,slave_mac_adr)); 68 | 69 | 70 | //Printout the mac ID (in case we change the starting one) 71 | printf("\nDEVICE MAC ADDRESS:["); 72 | for (int i=0;i<6; i++) 73 | { 74 | printf("%d:", slave_mac_adr[i]); 75 | } 76 | printf("]\n"); 77 | } 78 | 79 | //ESP-NOW callback upon receiving data 80 | static void espnow_recv_cb(const uint8_t *mac_addr, const uint8_t *data, int data_len){ 81 | ESP_LOGI(ESP_NOW_TAG,"Data received!"); 82 | uint8_t CURRENT_ENCODER[1]={0}; 83 | uint8_t CURRENT_MATRIX[MATRIX_ROWS][MATRIX_COLS]={0}; 84 | 85 | // for key reports 86 | if(data_len == MATRIX_ROWS*MATRIX_COLS){ 87 | memcpy(CURRENT_MATRIX, data, sizeof(CURRENT_MATRIX) ); 88 | xQueueSend(espnow_receive_q,(void*)&CURRENT_MATRIX, (TickType_t) 0); 89 | } 90 | 91 | // currently for encoder reports 92 | if(data_len==1){ 93 | memcpy(CURRENT_ENCODER, data, sizeof(CURRENT_ENCODER) ); 94 | r_encoder_command(CURRENT_ENCODER[0], slave_encoder_map[current_layout]); 95 | 96 | } 97 | 98 | } 99 | 100 | 101 | //Initialize receiving via ESP-NOW 102 | static void espnow_initialize_receive(void){ 103 | ESP_LOGI(ESP_NOW_TAG,"Initialing ESP-NOW"); 104 | esp_now_init(); 105 | esp_now_register_recv_cb(espnow_recv_cb); 106 | } 107 | 108 | void espnow_receive(void){ 109 | ESP_LOGI(ESP_NOW_TAG,"Initialing ESP-NOW functions for receiving data"); 110 | 111 | wifi_initialize_receive(); 112 | espnow_initialize_receive(); 113 | } 114 | -------------------------------------------------------------------------------- /components/espnowmk32/espnow_send.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | * 17 | * Copyright 2018 Gal Zaidenstein. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | 26 | #include "freertos/FreeRTOS.h" 27 | #include "freertos/timers.h" 28 | #include "nvs_flash.h" 29 | #include "esp_event_loop.h" 30 | #include "tcpip_adapter.h" 31 | #include "esp_wifi.h" 32 | #include "esp_wifi_types.h" 33 | #include "esp_log.h" 34 | #include "esp_system.h" 35 | #include "esp_now.h" 36 | #include "hal_ble.h" 37 | 38 | #include "espnow_send.h" 39 | #include "keyboard_config.h" 40 | 41 | #include "r_encoder.h" 42 | 43 | #define ESP_NOW_TAG "ESP-NOW" 44 | 45 | // Queue for sending esp-now reports 46 | QueueHandle_t espnow_matrix_send_q; 47 | QueueHandle_t espnow_encoder_send_q; 48 | //Mac adress of the main device (only mac address needed for ESP-NOW) 49 | static uint8_t master_mac_adr[6] = {0x84,0xCC,0xA8,0x2C,0xC2,0x2E}; // {0x80,0x7d,0x3a,0xba,0x26,0x88}; 50 | 51 | uint8_t channel = 10; 52 | static esp_now_peer_info_t Peer; 53 | static esp_now_peer_info_t *pPeer=&Peer; 54 | 55 | // Initializing WiFi 56 | void wifi_initialize_send(void){ 57 | 58 | ESP_LOGI(ESP_NOW_TAG,"Initialing WiFI!"); 59 | 60 | // Setting up the Wifi. 61 | uint8_t slave_mac_adr[6]; 62 | tcpip_adapter_init(); 63 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 64 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 65 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 66 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); 67 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)) ; // For some reason ESP-NOW only works if all devices are in the same mode 68 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); 69 | ESP_ERROR_CHECK(esp_wifi_start()); 70 | ESP_ERROR_CHECK(esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE) ); // Make sure we are on the same channel 71 | ESP_ERROR_CHECK(esp_wifi_get_mac(ESP_IF_WIFI_STA,slave_mac_adr)); 72 | 73 | //Printout the mac ID (in case we change the starting one) 74 | printf("DEVICE MAC ADDRESS:["); 75 | for(int i=0;i<6; i++) 76 | { 77 | printf("%d:", slave_mac_adr[i]); 78 | } 79 | printf("]"); 80 | } 81 | 82 | // Callback function after sending data 83 | void espnow_send_cb(const uint8_t *mac_addr, esp_now_send_status_t status){ 84 | 85 | 86 | switch(status){ 87 | case(ESP_NOW_SEND_SUCCESS): 88 | ESP_LOGI(ESP_NOW_TAG,"Data Sent successfully!"); 89 | break; 90 | 91 | case(ESP_NOW_SEND_FAIL): 92 | ESP_LOGI(ESP_NOW_TAG,"Data not Sent, trying a different channel"); 93 | break; 94 | 95 | break; 96 | } 97 | } 98 | 99 | // Function for sending state 100 | void espnow_send_state(void *pvParameters){ 101 | uint8_t CURRENT_MATRIX[MATRIX_ROWS][MATRIX_COLS]={0}; 102 | while(1) 103 | { 104 | //Wait to receive update matrix state 105 | if(xQueueReceive(espnow_matrix_send_q,&CURRENT_MATRIX,2)) 106 | { 107 | ESP_LOGI(ESP_NOW_TAG,"Sending Slave matrix state!"); 108 | //send the report 109 | esp_now_send(pPeer->peer_addr,(uint8_t*)&CURRENT_MATRIX,sizeof(CURRENT_MATRIX)); 110 | 111 | } 112 | 113 | #ifdef R_ENCODER_SLAVE 114 | uint8_t CURRENT_ENCODER[1]={0}; 115 | if(xQueueReceive(espnow_encoder_send_q,&CURRENT_ENCODER,2)) 116 | { 117 | ESP_LOGI(ESP_NOW_TAG,"Sending encoder state!"); 118 | //send the report 119 | esp_now_send(pPeer->peer_addr,(uint8_t*)&CURRENT_ENCODER,sizeof(CURRENT_ENCODER)); 120 | 121 | } 122 | #endif 123 | } 124 | 125 | } 126 | // Initialize sending via espnow 127 | void espnow_initialize_send(void){ 128 | 129 | ESP_LOGI(ESP_NOW_TAG,"Initialing ESP-NOW"); 130 | esp_now_init(); 131 | esp_now_register_send_cb(espnow_send_cb); 132 | 133 | //We need to assign a peer for each pad, will be improved for multiple pad functionality in the future. 134 | 135 | pPeer->channel = channel; 136 | memcpy(pPeer->peer_addr,master_mac_adr,6); 137 | pPeer->ifidx = ESP_IF_WIFI_STA; 138 | pPeer->encrypt = 0; 139 | esp_now_add_peer(pPeer); 140 | 141 | //Sending matrix state 142 | xTaskCreate(espnow_send_state, "Send matrix changes", 4096, NULL, configMAX_PRIORITIES, NULL); 143 | 144 | } 145 | 146 | void espnow_send(void){ 147 | 148 | ESP_LOGI(ESP_NOW_TAG,"Initialing ESP-NOW functions for sending data"); 149 | espnow_matrix_send_q = xQueueCreate(32,(2+MATRIX_ROWS*MATRIX_COLS)*sizeof(uint8_t)); 150 | #ifdef R_ENCODER_SLAVE 151 | r_encoder_setup(); 152 | espnow_encoder_send_q = xQueueCreate(32,sizeof(uint8_t)); 153 | #endif 154 | 155 | wifi_initialize_send(); 156 | espnow_initialize_send(); 157 | } -------------------------------------------------------------------------------- /components/espnowmk32/include/espnow_receive.h: -------------------------------------------------------------------------------- 1 | /* 2 | * espnow_split.h 3 | * 4 | * Created on: 12 Aug 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef ESPNOW_RECEIVE_H_ 9 | #define ESPNOW_RECEIVE_H_ 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | //Queue for receiving report from slave 18 | extern QueueHandle_t espnow_receive_q; 19 | 20 | /** @Setup the function for receiving data via espnow 21 | * */ 22 | void espnow_receive(void); 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | 28 | #endif /* ESPNOW_SPLIT_H_ */ 29 | -------------------------------------------------------------------------------- /components/espnowmk32/include/espnow_send.h: -------------------------------------------------------------------------------- 1 | /* 2 | * espnow_split.h 3 | * 4 | * Created on: 12 Aug 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef ESPNOW_SEND_H_ 9 | #define ESPNOW_SEND_H_ 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | //Queue for sending report from matrix scan 18 | extern QueueHandle_t espnow_matrix_send_q; 19 | extern QueueHandle_t espnow_encoder_send_q; 20 | 21 | /** @Setup the function for sending data via espnow 22 | * */ 23 | void espnow_send(void); 24 | 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif /* ESPNOW_SPLIT_H_ */ 31 | -------------------------------------------------------------------------------- /components/hidkeycodeconv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "keycode_conv.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES oled) 4 | -------------------------------------------------------------------------------- /components/hidkeycodeconv/include/keycode_conv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * keycode_conv.h 3 | * 4 | * Created on: 6 Oct 2018 5 | * Author: gal 6 | */ 7 | 8 | 9 | #ifndef KEYCODE_CONV_KEYCODE_CONV_H_ 10 | #define KEYCODE_CONV_KEYCODE_CONV_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include "keyboard_config.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | //Flag to enable or disable sending reports via BLE 22 | int BLE_EN; 23 | 24 | /** @brief Queue for receiving keyboard input 25 | * */ 26 | QueueHandle_t input_str_q; 27 | 28 | /* 29 | * @pause sending key reports and use keypress to enter char 30 | */ 31 | void enable_key_to_char(void); 32 | 33 | /* 34 | * @brief stop retrieving keypress to char and ireinit sending key reports 35 | */ 36 | void disable_key_to_char(void); 37 | 38 | /* 39 | * @brief retrieve char corresponding to keycode 40 | * 41 | * @param keycode keycode to convert to ascii 42 | * @param shifted indicated if shift/caps lock is pressed 43 | * 44 | */ 45 | char keycode_to_char(uint16_t keycode, uint8_t shifted); 46 | 47 | /* 48 | * @brief retrieve keycpde corresponding to char (or string) 49 | */ 50 | uint8_t char_to_keycode(char ascii_key); 51 | 52 | /* 53 | * @convert typing to string, return string on enter key 54 | */ 55 | char* input_string(void); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | 62 | #endif /* KEYCODE_CONV_KEYCODE_CONV_H_ */ 63 | -------------------------------------------------------------------------------- /components/hidkeycodeconv/keycode_conv.c: -------------------------------------------------------------------------------- 1 | #include "keycode_conv.h" 2 | #include "freertos/FreeRTOS.h" 3 | #include "freertos/task.h" 4 | #include "freertos/event_groups.h" 5 | #include "esp_log.h" 6 | #include "driver/gpio.h" 7 | #include "keymap.h" 8 | #include "key_definitions.h" 9 | 10 | #define TAG "KEY TO CHAR" 11 | 12 | #define CHAR_ILLEGAL 0xff 13 | #define CHAR_RETURN '\n' 14 | #define CHAR_ESCAPE 27 15 | #define CHAR_TAB '\t' 16 | #define CHAR_BACKSPACE 0x7f 17 | 18 | // Simplified US Keyboard with Shift modifier, taken from btstack's hid example 19 | 20 | /** 21 | * English (US) 22 | */ 23 | static const uint8_t keytable_us_none[] = { 24 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 0-3 */ 25 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', /* 4-13 */ 26 | 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', /* 14-23 */ 27 | 'u', 'v', 'w', 'x', 'y', 'z', /* 24-29 */ 28 | '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', /* 30-39 */ 29 | CHAR_RETURN, CHAR_ESCAPE, CHAR_BACKSPACE, CHAR_TAB, ' ', /* 40-44 */ 30 | '-', '=', '[', ']', '\\', CHAR_ILLEGAL, ';', '\'', 0x60, ',', /* 45-54 */ 31 | '.', '/', CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 55-60 */ 32 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 61-64 */ 33 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 65-68 */ 34 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 69-72 */ 35 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 73-76 */ 36 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 77-80 */ 37 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 81-84 */ 38 | '*', '-', '+', '\n', '1', '2', '3', '4', '5', /* 85-97 */ 39 | '6', '7', '8', '9', '0', '.', 0xa7, /* 97-100 */ 40 | }; 41 | 42 | static const uint8_t keytable_us_shift[] = { 43 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 0-3 */ 44 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 4-13 */ 45 | 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 14-23 */ 46 | 'U', 'V', 'W', 'X', 'Y', 'Z', /* 24-29 */ 47 | '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', /* 30-39 */ 48 | CHAR_RETURN, CHAR_ESCAPE, CHAR_BACKSPACE, CHAR_TAB, ' ', /* 40-44 */ 49 | '_', '+', '{', '}', '|', CHAR_ILLEGAL, ':', '"', 0x7E, '<', /* 45-54 */ 50 | '>', '?', CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 55-60 */ 51 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 61-64 */ 52 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 65-68 */ 53 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 69-72 */ 54 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 73-76 */ 55 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 77-80 */ 56 | CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, CHAR_ILLEGAL, /* 81-84 */ 57 | '*', '-', '+', '\n', '1', '2', '3', '4', '5', /* 85-97 */ 58 | '6', '7', '8', '9', '0', '.', 0xb1, /* 97-100 */ 59 | }; 60 | 61 | void suspend_ble(void) { 62 | BLE_EN = 0; 63 | ESP_LOGI(TAG, "Suspending hid reports"); 64 | 65 | } 66 | 67 | void enable_ble(void) { 68 | BLE_EN = 1; 69 | ESP_LOGI(TAG, "Resuming hid reports"); 70 | 71 | } 72 | 73 | /* 74 | * @brief retrieve chars corresponding to keycode 75 | */ 76 | char keycode_to_char(uint16_t keycode, uint8_t modifier) { 77 | 78 | char key_ascii = CHAR_ILLEGAL; 79 | if ((CHECK_BIT(modifier, 1) != 0) || (CHECK_BIT(modifier, 2) != 0)) { 80 | 81 | if (keycode <= 100) { 82 | key_ascii = keytable_us_shift[keycode]; 83 | } 84 | } 85 | 86 | else { 87 | if (keycode <= 100) { 88 | key_ascii = keytable_us_none[keycode]; 89 | } 90 | } 91 | return key_ascii; 92 | } 93 | 94 | /* 95 | * @brief retrieve keycode corresponding to char 96 | */ 97 | uint8_t char_to_keycode(char ascii_key) { 98 | 99 | uint8_t keycode = CHAR_ILLEGAL; 100 | 101 | for (int i = 0; i < 100; i++) { 102 | if ((ascii_key == keytable_us_none[i]) 103 | || (ascii_key == keytable_us_shift[i])) { 104 | keycode = i; 105 | 106 | } 107 | } 108 | 109 | return keycode; 110 | } 111 | 112 | /* 113 | * @convert typing to string, return string on enter key 114 | */ 115 | char* input_string(void) { 116 | 117 | input_str_q = xQueueCreate(32, REPORT_LEN * sizeof(uint8_t)); 118 | uint16_t keycode = CHAR_ILLEGAL; 119 | char *str_buff = (char *) malloc(sizeof(char) * 1); 120 | 121 | uint8_t report_state[REPORT_LEN]; 122 | int i = 0; 123 | while (keycode != KC_ENT) { 124 | if (xQueueReceive(input_str_q, &report_state, portMAX_DELAY)) { 125 | for (int key = 2; key < REPORT_LEN; key++) { 126 | 127 | keycode = report_state[key]; 128 | if (keycode == KC_ENT) { 129 | break; 130 | } 131 | char cur_char = keycode_to_char(keycode, report_state[0]); 132 | if (cur_char != CHAR_ILLEGAL) { 133 | str_buff[i] = cur_char; 134 | i++; 135 | str_buff = (char *) realloc(str_buff, sizeof(char) *(i + 1)); 136 | } 137 | 138 | } 139 | } 140 | } 141 | str_buff[i] = 0; // Null terminate 142 | vQueueDelete(input_str_q); 143 | return str_buff; 144 | } 145 | 146 | -------------------------------------------------------------------------------- /components/nvsfuncs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "nvs_funcs.c" "arr_conv.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES nvs_flash oled) 4 | -------------------------------------------------------------------------------- /components/nvsfuncs/arr_conv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | * 17 | * Copyright 2018 Gal Zaidenstein. 18 | */ 19 | 20 | #include 21 | #include "esp_log.h" 22 | #include "freertos/FreeRTOS.h" 23 | #include "freertos/task.h" 24 | #include "esp_system.h" 25 | #include "keyboard_config.h" 26 | #include 27 | 28 | //convert blob to keymap matrix 29 | void blob_to_key_mat(uint16_t layout_arr[MATRIX_ROWS*KEYMAP_COLS],uint16_t buffer[MATRIX_ROWS][KEYMAP_COLS]){ 30 | 31 | for(uint8_t row=0; row 2 | #include 3 | #include 4 | #include 5 | #include "keyboard_config.h" 6 | 7 | #ifndef ARR_CONV_H_ 8 | #define ARR_CONV_H_ 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* 15 | * @brief convert blob to keymap matrix, copy the data to the buffer 16 | */ 17 | void blob_to_key_mat(uint16_t layout_arr[MATRIX_ROWS*KEYMAP_COLS],uint16_t buffer[MATRIX_ROWS][KEYMAP_COLS]); 18 | 19 | /* 20 | * @brief convert keymap matrix to blob, copy the data to the buffer 21 | */ 22 | void key_mat_to_blob(uint16_t layout[MATRIX_ROWS][KEYMAP_COLS],uint16_t *buffer); 23 | 24 | /* 25 | * @brief convert string array to single string, copy the data to the buffer 26 | */ 27 | void str_arr_to_str(char (*layer_names)[MAX_LAYOUT_NAME_LENGTH], uint8_t layers, char **buffer); 28 | /* 29 | * @brief convert string to string array, copy the data to the buffer 30 | */ 31 | void str_to_str_arr(char *str, uint8_t layers,char ***buffer); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /* ARR_CONV_H_ */ 38 | -------------------------------------------------------------------------------- /components/nvsfuncs/include/nvs_funcs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * nvs_funcs.h 3 | * 4 | * Created on: 13 Sep 2018 5 | * Author: gal 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #ifndef NVS_FUNCS_H_ 14 | #define NVS_FUNCS_H_ 15 | 16 | #define NVS_CONFIG_OK 1 17 | #define NVS_CONFIG_ERR 0 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /* 24 | * @load the layouts from nvs 25 | */ 26 | void nvs_load_layouts(void); 27 | 28 | /* 29 | * @read a layout from nvs 30 | */ 31 | void nvs_read_layout(const char* layout_name,uint16_t buffer[MATRIX_ROWS][KEYMAP_COLS]); 32 | 33 | /* 34 | * @add a layout to nvs or overwrite existing one 35 | */ 36 | void nvs_write_layout(uint16_t layout[MATRIX_ROWS][KEYMAP_COLS],const char* layout_name); 37 | 38 | /* 39 | * @brief read keyboard configuration from nvs 40 | */ 41 | void nvs_read_keymap_cfg(void); 42 | 43 | /* 44 | * @brief write keyboard configuration to nvs (without keymaps) 45 | */ 46 | void nvs_write_keymap_cfg(uint8_t layers, char (*layer_names)[MAX_LAYOUT_NAME_LENGTH]); 47 | 48 | 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif /* NVS_FUNCS_H_ */ 55 | -------------------------------------------------------------------------------- /components/nvsfuncs/include/nvs_keymaps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * nvs_keymaps.h 3 | * 4 | * Created on: 19 Sep 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef NVS_KEYMAPS_H_ 9 | #define NVS_KEYMAPS_H_ 10 | #include 11 | 12 | //array for for holding the keymaps 13 | extern uint16_t ***layouts; 14 | 15 | //array for keymap names 16 | extern char **layer_names_arr; 17 | 18 | extern uint16_t **encoder_map; 19 | 20 | extern uint16_t **slave_encoder_map; 21 | 22 | //amount of arrays 23 | extern uint8_t layers_num; 24 | 25 | #endif /* NVS_KEYMAPS_H_ */ 26 | -------------------------------------------------------------------------------- /components/oled/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "oled_tasks.c" 2 | "u8g2_bitmap.c" 3 | "u8g2_box.c" 4 | "u8g2_buffer.c" 5 | "u8g2_circle.c" 6 | "u8g2_cleardisplay.c" 7 | "u8g2_d_memory.c" 8 | "u8g2_d_setup.c" 9 | "u8g2_esp32_hal.c" 10 | "u8g2_font.c" 11 | "u8g2_fonts.c" 12 | "u8g2_hvline.c" 13 | "u8g2_input_value.c" 14 | "u8g2_intersection.c" 15 | "u8g2_kerning.c" 16 | "u8g2_line.c" 17 | "u8g2_ll_hvline.c" 18 | "u8g2_message.c" 19 | "u8g2_polygon.c" 20 | "u8g2_selection_list.c" 21 | "u8g2_setup.c" 22 | "u8log.c" 23 | "u8log_u8g2.c" 24 | "u8log_u8x8.c" 25 | "u8x8_8x8.c" 26 | "u8x8_byte.c" 27 | "u8x8_cad.c" 28 | "u8x8_d_a2printer.c" 29 | "u8x8_d_il3820_296x128.c" 30 | "u8x8_d_ist3020.c" 31 | "u8x8_d_ks0108.c" 32 | "u8x8_d_lc7981.c" 33 | "u8x8_d_ld7032_60x32.c" 34 | "u8x8_d_ls013b7dh03.c" 35 | "u8x8_d_max7219.c" 36 | "u8x8_d_pcd8544_84x48.c" 37 | "u8x8_d_pcf8812.c" 38 | "u8x8_d_pcf8814_hx1230.c" 39 | "u8x8_d_sbn1661.c" 40 | "u8x8_d_sed1330.c" 41 | "u8x8_d_sh1106_64x32.c" 42 | "u8x8_d_sh1106_72x40.c" 43 | "u8x8_d_sh1107.c" 44 | "u8x8_d_sh1108.c" 45 | "u8x8_d_sh1122.c" 46 | "u8x8_d_ssd1305.c" 47 | "u8x8_d_ssd1306_48x64.c" 48 | "u8x8_d_ssd1306_64x32.c" 49 | "u8x8_d_ssd1306_64x48.c" 50 | "u8x8_d_ssd1306_96x16.c" 51 | "u8x8_d_ssd1306_128x32.c" 52 | "u8x8_d_ssd1306_128x64_noname.c" 53 | "u8x8_d_ssd1309.c" 54 | "u8x8_d_ssd1317.c" 55 | "u8x8_d_ssd1322.c" 56 | "u8x8_d_ssd1325.c" 57 | "u8x8_d_ssd1326.c" 58 | "u8x8_d_ssd1327.c" 59 | "u8x8_d_ssd1329.c" 60 | "u8x8_d_ssd1606_172x72.c" 61 | "u8x8_d_ssd1607_200x200.c" 62 | "u8x8_d_st7565.c" 63 | "u8x8_d_st7567.c" 64 | "u8x8_d_st7586s_erc240160.c" 65 | "u8x8_d_st7586s_s028hn118a.c" 66 | "u8x8_d_st7588.c" 67 | "u8x8_d_st7920.c" 68 | "u8x8_d_st75256.c" 69 | "u8x8_d_stdio.c" 70 | "u8x8_d_t6963.c" 71 | "u8x8_d_uc1601.c" 72 | "u8x8_d_uc1604.c" 73 | "u8x8_d_uc1608.c" 74 | "u8x8_d_uc1610.c" 75 | "u8x8_d_uc1611.c" 76 | "u8x8_d_uc1617.c" 77 | "u8x8_d_uc1638.c" 78 | "u8x8_d_uc1701_dogs102.c" 79 | "u8x8_d_uc1701_mini12864.c" 80 | "u8x8_debounce.c" 81 | "u8x8_display.c" 82 | "u8x8_fonts.c" 83 | "u8x8_gpio.c" 84 | "u8x8_input_value.c" 85 | "u8x8_message.c" 86 | "u8x8_selection_list.c" 87 | "u8x8_setup.c" 88 | "u8x8_string.c" 89 | "u8x8_u8toa.c" 90 | "u8x8_u16toa.c" 91 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 92 | REQUIRES "battery" "nvsfuncs") 93 | -------------------------------------------------------------------------------- /components/oled/include/oled_tasks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * oled_tasks.h 3 | * 4 | * Created on: 01 Sep 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef OLED_TASKS_H_ 9 | #define OLED_TASKS_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "u8g2.h" 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | //rotation defines 22 | #define LANDSCAPE U8G2_R0 23 | #define DEG90 U8G2_R1 24 | #define DEG180 U8G2_R2 25 | #define DEG270 U8G2_R3 26 | 27 | /** @brief Setup the oled screen 28 | * @param rotation - Set rotation 29 | * */ 30 | void init_oled(const u8g2_cb_t *rotation); 31 | 32 | /** @brief deinitialize the oled screen 33 | * */ 34 | 35 | void deinit_oled(void); 36 | 37 | /** @brief connecting waiting animation 38 | * */ 39 | void waiting_oled(void); 40 | 41 | /** @brief connected graphic 42 | * */ 43 | void ble_connected_oled(void); 44 | 45 | /** @brief connected graphic 46 | * */ 47 | void ble_slave_oled(void); 48 | 49 | /** @brief running oled task 50 | * */ 51 | void update_oled(void); 52 | 53 | /** @brief Queue for sending layer to oled 54 | **/ 55 | extern QueueHandle_t layer_recieve_q; 56 | 57 | /** @brief Queue for sending led status to oled 58 | **/ 59 | extern QueueHandle_t led_recieve_q; 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif /* OLED_TASKS_H_ */ 66 | -------------------------------------------------------------------------------- /components/oled/include/u8g2_esp32_hal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * u8g2_esp32_hal.h 3 | * 4 | * Created on: Feb 12, 2017 5 | * Author: kolban 6 | */ 7 | 8 | #ifndef U8G2_ESP32_HAL_H_ 9 | #define U8G2_ESP32_HAL_H_ 10 | #include "u8g2.h" 11 | #include "driver/gpio.h" 12 | #include "driver/spi_master.h" 13 | #include "driver/i2c.h" 14 | 15 | #define U8G2_ESP32_HAL_UNDEFINED (-1) 16 | 17 | #define I2C_MASTER_NUM I2C_NUM_0 // I2C port number for master dev 18 | #define I2C_MASTER_TX_BUF_DISABLE 0 // I2C master do not need buffer 19 | #define I2C_MASTER_RX_BUF_DISABLE 0 // I2C master do not need buffer 20 | #define I2C_MASTER_FREQ_HZ 400000 // I2C master clock frequency 21 | #define ACK_CHECK_EN 0x1 // I2C master will check ack from slave 22 | #define ACK_CHECK_DIS 0x0 // I2C master will not check ack from slave 23 | 24 | typedef struct { 25 | gpio_num_t clk; 26 | gpio_num_t mosi; 27 | gpio_num_t sda; // data for I²C 28 | gpio_num_t scl; // clock for I²C 29 | gpio_num_t cs; 30 | gpio_num_t reset; 31 | gpio_num_t dc; 32 | } u8g2_esp32_hal_t ; 33 | 34 | #define U8G2_ESP32_HAL_DEFAULT {U8G2_ESP32_HAL_UNDEFINED, U8G2_ESP32_HAL_UNDEFINED, U8G2_ESP32_HAL_UNDEFINED, U8G2_ESP32_HAL_UNDEFINED, U8G2_ESP32_HAL_UNDEFINED, U8G2_ESP32_HAL_UNDEFINED, U8G2_ESP32_HAL_UNDEFINED } 35 | 36 | void u8g2_esp32_hal_init(u8g2_esp32_hal_t u8g2_esp32_hal_param); 37 | uint8_t u8g2_esp32_spi_byte_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); 38 | uint8_t u8g2_esp32_i2c_byte_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); 39 | uint8_t u8g2_esp32_gpio_and_delay_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); 40 | #endif /* U8G2_ESP32_HAL_H_ */ 41 | -------------------------------------------------------------------------------- /components/oled/u8g2_bitmap.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_bitmap.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | 39 | void u8g2_SetBitmapMode(u8g2_t *u8g2, uint8_t is_transparent) { 40 | u8g2->bitmap_transparency = is_transparent; 41 | } 42 | 43 | /* 44 | x,y Position on the display 45 | len Length of bitmap line in pixel. Note: This differs from u8glib which had a bytecount here. 46 | b Pointer to the bitmap line. 47 | Only draw pixels which are set. 48 | */ 49 | 50 | void u8g2_DrawHorizontalBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) 51 | { 52 | uint8_t mask; 53 | uint8_t color = u8g2->draw_color; 54 | uint8_t ncolor = (color == 0 ? 1 : 0); 55 | 56 | #ifdef U8G2_WITH_INTERSECTION 57 | if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 58 | return; 59 | #endif /* U8G2_WITH_INTERSECTION */ 60 | 61 | mask = 128; 62 | while(len > 0) 63 | { 64 | if ( *b & mask ) { 65 | u8g2->draw_color = color; 66 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 67 | } else if ( u8g2->bitmap_transparency == 0 ) { 68 | u8g2->draw_color = ncolor; 69 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 70 | } 71 | 72 | x++; 73 | mask >>= 1; 74 | if ( mask == 0 ) 75 | { 76 | mask = 128; 77 | b++; 78 | } 79 | len--; 80 | } 81 | u8g2->draw_color = color; 82 | } 83 | 84 | 85 | /* u8glib compatible bitmap draw function */ 86 | void u8g2_DrawBitmap(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t cnt, u8g2_uint_t h, const uint8_t *bitmap) 87 | { 88 | u8g2_uint_t w; 89 | w = cnt; 90 | w *= 8; 91 | #ifdef U8G2_WITH_INTERSECTION 92 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 93 | return; 94 | #endif /* U8G2_WITH_INTERSECTION */ 95 | 96 | while( h > 0 ) 97 | { 98 | u8g2_DrawHorizontalBitmap(u8g2, x, y, w, bitmap); 99 | bitmap += cnt; 100 | y++; 101 | h--; 102 | } 103 | } 104 | 105 | 106 | 107 | void u8g2_DrawHXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) 108 | { 109 | uint8_t mask; 110 | uint8_t color = u8g2->draw_color; 111 | uint8_t ncolor = (color == 0 ? 1 : 0); 112 | #ifdef U8G2_WITH_INTERSECTION 113 | if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 114 | return; 115 | #endif /* U8G2_WITH_INTERSECTION */ 116 | 117 | mask = 1; 118 | while(len > 0) { 119 | if ( *b & mask ) { 120 | u8g2->draw_color = color; 121 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 122 | } else if ( u8g2->bitmap_transparency == 0 ) { 123 | u8g2->draw_color = ncolor; 124 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 125 | } 126 | x++; 127 | mask <<= 1; 128 | if ( mask == 0 ) 129 | { 130 | mask = 1; 131 | b++; 132 | } 133 | len--; 134 | } 135 | u8g2->draw_color = color; 136 | } 137 | 138 | 139 | void u8g2_DrawXBM(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) 140 | { 141 | u8g2_uint_t blen; 142 | blen = w; 143 | blen += 7; 144 | blen >>= 3; 145 | #ifdef U8G2_WITH_INTERSECTION 146 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 147 | return; 148 | #endif /* U8G2_WITH_INTERSECTION */ 149 | 150 | while( h > 0 ) 151 | { 152 | u8g2_DrawHXBM(u8g2, x, y, w, bitmap); 153 | bitmap += blen; 154 | y++; 155 | h--; 156 | } 157 | } 158 | 159 | 160 | 161 | 162 | 163 | 164 | void u8g2_DrawHXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t len, const uint8_t *b) 165 | { 166 | uint8_t mask; 167 | uint8_t color = u8g2->draw_color; 168 | uint8_t ncolor = (color == 0 ? 1 : 0); 169 | #ifdef U8G2_WITH_INTERSECTION 170 | if ( u8g2_IsIntersection(u8g2, x, y, x+len, y+1) == 0 ) 171 | return; 172 | #endif /* U8G2_WITH_INTERSECTION */ 173 | 174 | mask = 1; 175 | while(len > 0) 176 | { 177 | if( u8x8_pgm_read(b) & mask ) { 178 | u8g2->draw_color = color; 179 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 180 | } else if( u8g2->bitmap_transparency == 0 ) { 181 | u8g2->draw_color = ncolor; 182 | u8g2_DrawHVLine(u8g2, x, y, 1, 0); 183 | } 184 | 185 | x++; 186 | mask <<= 1; 187 | if ( mask == 0 ) 188 | { 189 | mask = 1; 190 | b++; 191 | } 192 | len--; 193 | } 194 | u8g2->draw_color = color; 195 | } 196 | 197 | 198 | void u8g2_DrawXBMP(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, const uint8_t *bitmap) 199 | { 200 | u8g2_uint_t blen; 201 | blen = w; 202 | blen += 7; 203 | blen >>= 3; 204 | #ifdef U8G2_WITH_INTERSECTION 205 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 206 | return; 207 | #endif /* U8G2_WITH_INTERSECTION */ 208 | 209 | while( h > 0 ) 210 | { 211 | u8g2_DrawHXBMP(u8g2, x, y, w, bitmap); 212 | bitmap += blen; 213 | y++; 214 | h--; 215 | } 216 | } 217 | 218 | 219 | -------------------------------------------------------------------------------- /components/oled/u8g2_box.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_box.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | /* 39 | draw a filled box 40 | restriction: does not work for w = 0 or h = 0 41 | */ 42 | void u8g2_DrawBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) 43 | { 44 | #ifdef U8G2_WITH_INTERSECTION 45 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 46 | return; 47 | #endif /* U8G2_WITH_INTERSECTION */ 48 | while( h != 0 ) 49 | { 50 | u8g2_DrawHVLine(u8g2, x, y, w, 0); 51 | y++; 52 | h--; 53 | } 54 | } 55 | 56 | 57 | /* 58 | draw a frame (empty box) 59 | restriction: does not work for w = 0 or h = 0 60 | ToDo: 61 | pixel in the corners are drawn twice. This could be optimized. 62 | */ 63 | void u8g2_DrawFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h) 64 | { 65 | u8g2_uint_t xtmp = x; 66 | 67 | #ifdef U8G2_WITH_INTERSECTION 68 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 69 | return; 70 | #endif /* U8G2_WITH_INTERSECTION */ 71 | 72 | u8g2_DrawHVLine(u8g2, x, y, w, 0); 73 | u8g2_DrawHVLine(u8g2, x, y, h, 1); 74 | x+=w; 75 | x--; 76 | u8g2_DrawHVLine(u8g2, x, y, h, 1); 77 | y+=h; 78 | y--; 79 | u8g2_DrawHVLine(u8g2, xtmp, y, w, 0); 80 | } 81 | 82 | 83 | 84 | 85 | void u8g2_DrawRBox(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) 86 | { 87 | u8g2_uint_t xl, yu; 88 | u8g2_uint_t yl, xr; 89 | 90 | #ifdef U8G2_WITH_INTERSECTION 91 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 92 | return; 93 | #endif /* U8G2_WITH_INTERSECTION */ 94 | 95 | xl = x; 96 | xl += r; 97 | yu = y; 98 | yu += r; 99 | 100 | xr = x; 101 | xr += w; 102 | xr -= r; 103 | xr -= 1; 104 | 105 | yl = y; 106 | yl += h; 107 | yl -= r; 108 | yl -= 1; 109 | 110 | u8g2_DrawDisc(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT); 111 | u8g2_DrawDisc(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT); 112 | u8g2_DrawDisc(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT); 113 | u8g2_DrawDisc(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT); 114 | 115 | { 116 | u8g2_uint_t ww, hh; 117 | 118 | ww = w; 119 | ww -= r; 120 | ww -= r; 121 | xl++; 122 | yu++; 123 | 124 | if ( ww >= 3 ) 125 | { 126 | ww -= 2; 127 | u8g2_DrawBox(u8g2, xl, y, ww, r+1); 128 | u8g2_DrawBox(u8g2, xl, yl, ww, r+1); 129 | } 130 | 131 | hh = h; 132 | hh -= r; 133 | hh -= r; 134 | //h--; 135 | if ( hh >= 3 ) 136 | { 137 | hh -= 2; 138 | u8g2_DrawBox(u8g2, x, yu, w, hh); 139 | } 140 | } 141 | } 142 | 143 | 144 | void u8g2_DrawRFrame(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r) 145 | { 146 | u8g2_uint_t xl, yu; 147 | 148 | #ifdef U8G2_WITH_INTERSECTION 149 | if ( u8g2_IsIntersection(u8g2, x, y, x+w, y+h) == 0 ) 150 | return; 151 | #endif /* U8G2_WITH_INTERSECTION */ 152 | 153 | xl = x; 154 | xl += r; 155 | yu = y; 156 | yu += r; 157 | 158 | { 159 | u8g2_uint_t yl, xr; 160 | 161 | xr = x; 162 | xr += w; 163 | xr -= r; 164 | xr -= 1; 165 | 166 | yl = y; 167 | yl += h; 168 | yl -= r; 169 | yl -= 1; 170 | 171 | u8g2_DrawCircle(u8g2, xl, yu, r, U8G2_DRAW_UPPER_LEFT); 172 | u8g2_DrawCircle(u8g2, xr, yu, r, U8G2_DRAW_UPPER_RIGHT); 173 | u8g2_DrawCircle(u8g2, xl, yl, r, U8G2_DRAW_LOWER_LEFT); 174 | u8g2_DrawCircle(u8g2, xr, yl, r, U8G2_DRAW_LOWER_RIGHT); 175 | } 176 | 177 | { 178 | u8g2_uint_t ww, hh; 179 | 180 | ww = w; 181 | ww -= r; 182 | ww -= r; 183 | hh = h; 184 | hh -= r; 185 | hh -= r; 186 | 187 | xl++; 188 | yu++; 189 | 190 | if ( ww >= 3 ) 191 | { 192 | ww -= 2; 193 | h--; 194 | u8g2_DrawHLine(u8g2, xl, y, ww); 195 | u8g2_DrawHLine(u8g2, xl, y+h, ww); 196 | } 197 | 198 | if ( hh >= 3 ) 199 | { 200 | hh -= 2; 201 | w--; 202 | u8g2_DrawVLine(u8g2, x, yu, hh); 203 | u8g2_DrawVLine(u8g2, x+w, yu, hh); 204 | } 205 | } 206 | } 207 | 208 | -------------------------------------------------------------------------------- /components/oled/u8g2_buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_buffer.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include 37 | #include "u8g2.h" 38 | 39 | /*============================================*/ 40 | void u8g2_ClearBuffer(u8g2_t *u8g2) 41 | { 42 | size_t cnt; 43 | cnt = u8g2_GetU8x8(u8g2)->display_info->tile_width; 44 | cnt *= u8g2->tile_buf_height; 45 | cnt *= 8; 46 | memset(u8g2->tile_buf_ptr, 0, cnt); 47 | } 48 | 49 | /*============================================*/ 50 | 51 | static void u8g2_send_tile_row(u8g2_t *u8g2, uint8_t src_tile_row, uint8_t dest_tile_row) 52 | { 53 | uint8_t *ptr; 54 | uint16_t offset; 55 | uint8_t w; 56 | 57 | w = u8g2_GetU8x8(u8g2)->display_info->tile_width; 58 | offset = src_tile_row; 59 | ptr = u8g2->tile_buf_ptr; 60 | offset *= w; 61 | offset *= 8; 62 | ptr += offset; 63 | u8x8_DrawTile(u8g2_GetU8x8(u8g2), 0, dest_tile_row, w, ptr); 64 | } 65 | 66 | /* 67 | write the buffer to the display RAM. 68 | For most displays, this will make the content visible to the user. 69 | Some displays (like the SSD1606) require a u8x8_RefreshDisplay() 70 | */ 71 | static void u8g2_send_buffer(u8g2_t *u8g2) U8X8_NOINLINE; 72 | static void u8g2_send_buffer(u8g2_t *u8g2) 73 | { 74 | uint8_t src_row; 75 | uint8_t src_max; 76 | uint8_t dest_row; 77 | uint8_t dest_max; 78 | 79 | src_row = 0; 80 | src_max = u8g2->tile_buf_height; 81 | dest_row = u8g2->tile_curr_row; 82 | dest_max = u8g2_GetU8x8(u8g2)->display_info->tile_height; 83 | 84 | do 85 | { 86 | u8g2_send_tile_row(u8g2, src_row, dest_row); 87 | src_row++; 88 | dest_row++; 89 | } while( src_row < src_max && dest_row < dest_max ); 90 | } 91 | 92 | /* same as u8g2_send_buffer but also send the DISPLAY_REFRESH message (used by SSD1606) */ 93 | void u8g2_SendBuffer(u8g2_t *u8g2) 94 | { 95 | u8g2_send_buffer(u8g2); 96 | u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) ); 97 | } 98 | 99 | /*============================================*/ 100 | void u8g2_SetBufferCurrTileRow(u8g2_t *u8g2, uint8_t row) 101 | { 102 | u8g2->tile_curr_row = row; 103 | u8g2->cb->update(u8g2); 104 | } 105 | 106 | void u8g2_FirstPage(u8g2_t *u8g2) 107 | { 108 | if ( u8g2->is_auto_page_clear ) 109 | { 110 | u8g2_ClearBuffer(u8g2); 111 | } 112 | u8g2_SetBufferCurrTileRow(u8g2, 0); 113 | } 114 | 115 | uint8_t u8g2_NextPage(u8g2_t *u8g2) 116 | { 117 | uint8_t row; 118 | u8g2_send_buffer(u8g2); 119 | row = u8g2->tile_curr_row; 120 | row += u8g2->tile_buf_height; 121 | if ( row >= u8g2_GetU8x8(u8g2)->display_info->tile_height ) 122 | { 123 | u8x8_RefreshDisplay( u8g2_GetU8x8(u8g2) ); 124 | return 0; 125 | } 126 | if ( u8g2->is_auto_page_clear ) 127 | { 128 | u8g2_ClearBuffer(u8g2); 129 | } 130 | u8g2_SetBufferCurrTileRow(u8g2, row); 131 | return 1; 132 | } 133 | -------------------------------------------------------------------------------- /components/oled/u8g2_cleardisplay.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_cleardisplay.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #include "u8g2.h" 36 | 37 | /* Clear screen buffer & display reliable for all u8g2 displays. */ 38 | /* This is done with u8g2 picture loop, because we can not use the u8x8 function in all cases */ 39 | void u8g2_ClearDisplay(u8g2_t *u8g2) 40 | { 41 | u8g2_FirstPage(u8g2); 42 | do { 43 | } while ( u8g2_NextPage(u8g2) ); 44 | /* 45 | This function is usually called during startup (u8g2.begin()). 46 | However the user might want to use full buffer mode with clear and 47 | send commands. 48 | This will not work because the current tile row is modified by the picture 49 | loop above. To fix this, reset the tile row to 0, issue #370 50 | A workaround would be, that the user sets the current tile row to 0 manually. 51 | */ 52 | u8g2_SetBufferCurrTileRow(u8g2, 0); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /components/oled/u8g2_fonts.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Galzai/MK32/99acf5c46a8468faa70301cba5fff2b94422554b/components/oled/u8g2_fonts.c -------------------------------------------------------------------------------- /components/oled/u8g2_input_value.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_input_value.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | /* 39 | return: 40 | 0: value is not changed (HOME/Break Button pressed) 41 | 1: value has been updated 42 | */ 43 | 44 | uint8_t u8g2_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post) 45 | { 46 | uint8_t line_height; 47 | uint8_t height; 48 | u8g2_uint_t pixel_height; 49 | u8g2_uint_t y, yy; 50 | u8g2_uint_t pixel_width; 51 | u8g2_uint_t x, xx; 52 | 53 | uint8_t local_value = *value; 54 | //uint8_t r; /* not used ??? */ 55 | uint8_t event; 56 | 57 | /* only horizontal strings are supported, so force this here */ 58 | u8g2_SetFontDirection(u8g2, 0); 59 | 60 | /* force baseline position */ 61 | u8g2_SetFontPosBaseline(u8g2); 62 | 63 | /* calculate line height */ 64 | line_height = u8g2_GetAscent(u8g2); 65 | line_height -= u8g2_GetDescent(u8g2); 66 | 67 | 68 | /* calculate overall height of the input value box */ 69 | height = 1; /* value input line */ 70 | height += u8x8_GetStringLineCnt(title); 71 | 72 | /* calculate the height in pixel */ 73 | pixel_height = height; 74 | pixel_height *= line_height; 75 | 76 | 77 | /* calculate offset from top */ 78 | y = 0; 79 | if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) 80 | { 81 | y = u8g2_GetDisplayHeight(u8g2); 82 | y -= pixel_height; 83 | y /= 2; 84 | } 85 | 86 | /* calculate offset from left for the label */ 87 | x = 0; 88 | pixel_width = u8g2_GetUTF8Width(u8g2, pre); 89 | pixel_width += u8g2_GetUTF8Width(u8g2, "0") * digits; 90 | pixel_width += u8g2_GetUTF8Width(u8g2, post); 91 | if ( pixel_width < u8g2_GetDisplayWidth(u8g2) ) 92 | { 93 | x = u8g2_GetDisplayWidth(u8g2); 94 | x -= pixel_width; 95 | x /= 2; 96 | } 97 | 98 | /* event loop */ 99 | for(;;) 100 | { 101 | u8g2_FirstPage(u8g2); 102 | do 103 | { 104 | /* render */ 105 | yy = y; 106 | yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title); 107 | xx = x; 108 | xx += u8g2_DrawUTF8(u8g2, xx, yy, pre); 109 | xx += u8g2_DrawUTF8(u8g2, xx, yy, u8x8_u8toa(local_value, digits)); 110 | u8g2_DrawUTF8(u8g2, xx, yy, post); 111 | } while( u8g2_NextPage(u8g2) ); 112 | 113 | #ifdef U8G2_REF_MAN_PIC 114 | return 0; 115 | #endif 116 | 117 | for(;;) 118 | { 119 | event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2)); 120 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 121 | { 122 | *value = local_value; 123 | return 1; 124 | } 125 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 126 | { 127 | return 0; 128 | } 129 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP ) 130 | { 131 | if ( local_value >= hi ) 132 | local_value = lo; 133 | else 134 | local_value++; 135 | break; 136 | } 137 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN ) 138 | { 139 | if ( local_value <= lo ) 140 | local_value = hi; 141 | else 142 | local_value--; 143 | break; 144 | } 145 | } 146 | } 147 | 148 | /* never reached */ 149 | //return r; 150 | } 151 | -------------------------------------------------------------------------------- /components/oled/u8g2_intersection.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_intersection.c 4 | 5 | Intersection calculation, code taken from u8g_clip.c 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8g2.h" 39 | 40 | #ifdef __GNUC__ 41 | #define U8G2_ALWAYS_INLINE __inline__ __attribute__((always_inline)) 42 | #else 43 | #define U8G2_ALWAYS_INLINE 44 | #endif 45 | 46 | 47 | #ifdef U8G2_WITH_INTERSECTION 48 | 49 | #ifdef OLD_VERSION_WITH_SYMETRIC_BOUNDARIES 50 | 51 | /* 52 | intersection assumptions: 53 | a1 <= a2 is always true 54 | 55 | minimized version 56 | ---1----0 1 b1 <= a2 && b1 > b2 57 | -----1--0 1 b2 >= a1 && b1 > b2 58 | ---1-1--- 1 b1 <= a2 && b2 >= a1 59 | */ 60 | 61 | 62 | /* 63 | calculate the intersection between a0/a1 and v0/v1 64 | The intersection check returns one if the range of a0/a1 has an intersection with v0/v1. 65 | The intersection check includes the boundary values v1 and a1. 66 | 67 | The following asserts will succeed: 68 | assert( u8g2_is_intersection_decision_tree(4, 6, 7, 9) == 0 ); 69 | assert( u8g2_is_intersection_decision_tree(4, 6, 6, 9) != 0 ); 70 | assert( u8g2_is_intersection_decision_tree(6, 9, 4, 6) != 0 ); 71 | assert( u8g2_is_intersection_decision_tree(7, 9, 4, 6) == 0 ); 72 | */ 73 | 74 | //static uint8_t U8G2_ALWAYS_INLINE u8g2_is_intersection_decision_tree(u8g_uint_t a0, u8g_uint_t a1, u8g_uint_t v0, u8g_uint_t v1) 75 | static uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1) 76 | { 77 | if ( v0 <= a1 ) 78 | { 79 | if ( v1 >= a0 ) 80 | { 81 | return 1; 82 | } 83 | else 84 | { 85 | if ( v0 > v1 ) 86 | { 87 | return 1; 88 | } 89 | else 90 | { 91 | return 0; 92 | } 93 | } 94 | } 95 | else 96 | { 97 | if ( v1 >= a0 ) 98 | { 99 | if ( v0 > v1 ) 100 | { 101 | return 1; 102 | } 103 | else 104 | { 105 | return 0; 106 | } 107 | } 108 | else 109 | { 110 | return 0; 111 | } 112 | } 113 | } 114 | 115 | #endif /* OLD_VERSION_WITH_SYMETRIC_BOUNDARIES */ 116 | 117 | 118 | /* 119 | version with asymetric boundaries. 120 | a1 and v1 are excluded 121 | v0 == v1 is not support end return 1 122 | */ 123 | uint8_t u8g2_is_intersection_decision_tree(u8g2_uint_t a0, u8g2_uint_t a1, u8g2_uint_t v0, u8g2_uint_t v1) 124 | { 125 | if ( v0 < a1 ) // v0 <= a1 126 | { 127 | if ( v1 > a0 ) // v1 >= a0 128 | { 129 | return 1; 130 | } 131 | else 132 | { 133 | if ( v0 > v1 ) // v0 > v1 134 | { 135 | return 1; 136 | } 137 | else 138 | { 139 | return 0; 140 | } 141 | } 142 | } 143 | else 144 | { 145 | if ( v1 > a0 ) // v1 >= a0 146 | { 147 | if ( v0 > v1 ) // v0 > v1 148 | { 149 | return 1; 150 | } 151 | else 152 | { 153 | return 0; 154 | } 155 | } 156 | else 157 | { 158 | return 0; 159 | } 160 | } 161 | } 162 | 163 | 164 | 165 | /* upper limits are not included (asymetric boundaries) */ 166 | uint8_t u8g2_IsIntersection(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t x1, u8g2_uint_t y1) 167 | { 168 | if ( u8g2_is_intersection_decision_tree(u8g2->user_y0, u8g2->user_y1, y0, y1) == 0 ) 169 | return 0; 170 | 171 | return u8g2_is_intersection_decision_tree(u8g2->user_x0, u8g2->user_x1, x0, x1); 172 | } 173 | 174 | 175 | #endif /* U8G2_WITH_INTERSECTION */ 176 | 177 | -------------------------------------------------------------------------------- /components/oled/u8g2_kerning.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_kerning.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | /* this function is used as "u8g2_get_kerning_cb" */ 39 | /* 40 | uint8_t u8g2_GetNullKerning(u8g2_t *u8g2, uint16_t e1, uint16_t e2) 41 | { 42 | return 0; 43 | } 44 | */ 45 | 46 | /* this function is used as "u8g2_get_kerning_cb" */ 47 | uint8_t u8g2_GetKerning(U8X8_UNUSED u8g2_t *u8g2, u8g2_kerning_t *kerning, uint16_t e1, uint16_t e2) 48 | { 49 | uint16_t i1, i2, cnt, end; 50 | if ( kerning == NULL ) 51 | return 0; 52 | 53 | /* search for the encoding in the first table */ 54 | cnt = kerning->first_table_cnt; 55 | cnt--; /* ignore the last element of the table, which is 0x0ffff */ 56 | for( i1 = 0; i1 < cnt; i1++ ) 57 | { 58 | if ( kerning->first_encoding_table[i1] == e1 ) 59 | break; 60 | } 61 | if ( i1 >= cnt ) 62 | return 0; /* e1 not part of the kerning table, return 0 */ 63 | 64 | /* get the upper index for i2 */ 65 | end = kerning->index_to_second_table[i1+1]; 66 | for( i2 = kerning->index_to_second_table[i1]; i2 < end; i2++ ) 67 | { 68 | if ( kerning->second_encoding_table[i2] == e2 ) 69 | break; 70 | } 71 | 72 | if ( i2 >= end ) 73 | return 0; /* e2 not part of any pair with e1, return 0 */ 74 | 75 | return kerning->kerning_values[i2]; 76 | } 77 | 78 | uint8_t u8g2_GetKerningByTable(U8X8_UNUSED u8g2_t *u8g2, const uint16_t *kt, uint16_t e1, uint16_t e2) 79 | { 80 | uint16_t i; 81 | i = 0; 82 | if ( kt == NULL ) 83 | return 0; 84 | for(;;) 85 | { 86 | if ( kt[i] == 0x0ffff ) 87 | break; 88 | if ( kt[i] == e1 && kt[i+1] == e2 ) 89 | return kt[i+2]; 90 | i+=3; 91 | } 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /components/oled/u8g2_line.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_box.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | 39 | void u8g2_DrawLine(u8g2_t *u8g2, u8g2_uint_t x1, u8g2_uint_t y1, u8g2_uint_t x2, u8g2_uint_t y2) 40 | { 41 | u8g2_uint_t tmp; 42 | u8g2_uint_t x,y; 43 | u8g2_uint_t dx, dy; 44 | u8g2_int_t err; 45 | u8g2_int_t ystep; 46 | 47 | uint8_t swapxy = 0; 48 | 49 | /* no intersection check at the moment, should be added... */ 50 | 51 | if ( x1 > x2 ) dx = x1-x2; else dx = x2-x1; 52 | if ( y1 > y2 ) dy = y1-y2; else dy = y2-y1; 53 | 54 | if ( dy > dx ) 55 | { 56 | swapxy = 1; 57 | tmp = dx; dx =dy; dy = tmp; 58 | tmp = x1; x1 =y1; y1 = tmp; 59 | tmp = x2; x2 =y2; y2 = tmp; 60 | } 61 | if ( x1 > x2 ) 62 | { 63 | tmp = x1; x1 =x2; x2 = tmp; 64 | tmp = y1; y1 =y2; y2 = tmp; 65 | } 66 | err = dx >> 1; 67 | if ( y2 > y1 ) ystep = 1; else ystep = -1; 68 | y = y1; 69 | 70 | #ifndef U8G2_16BIT 71 | if ( x2 == 255 ) 72 | x2--; 73 | #else 74 | if ( x2 == 0xffff ) 75 | x2--; 76 | #endif 77 | 78 | for( x = x1; x <= x2; x++ ) 79 | { 80 | if ( swapxy == 0 ) 81 | u8g2_DrawPixel(u8g2, x, y); 82 | else 83 | u8g2_DrawPixel(u8g2, y, x); 84 | err -= (uint8_t)dy; 85 | if ( err < 0 ) 86 | { 87 | y += (u8g2_uint_t)ystep; 88 | err += (u8g2_uint_t)dx; 89 | } 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /components/oled/u8g2_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8g2_message.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8g2.h" 37 | 38 | #define SPACE_BETWEEN_BUTTONS_IN_PIXEL 6 39 | #define SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL 3 40 | 41 | uint8_t u8g2_draw_button_line(u8g2_t *u8g2, u8g2_uint_t y, u8g2_uint_t w, uint8_t cursor, const char *s) 42 | { 43 | u8g2_uint_t button_line_width; 44 | 45 | uint8_t i; 46 | uint8_t cnt; 47 | uint8_t is_invert; 48 | 49 | u8g2_uint_t d; 50 | u8g2_uint_t x; 51 | 52 | cnt = u8x8_GetStringLineCnt(s); 53 | 54 | 55 | /* calculate the width of the button line */ 56 | button_line_width = 0; 57 | for( i = 0; i < cnt; i++ ) 58 | { 59 | button_line_width += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s)); 60 | } 61 | button_line_width += (cnt-1)*SPACE_BETWEEN_BUTTONS_IN_PIXEL; /* add some space between the buttons */ 62 | 63 | /* calculate the left offset */ 64 | d = 0; 65 | if ( button_line_width < w ) 66 | { 67 | d = w; 68 | d -= button_line_width; 69 | d /= 2; 70 | } 71 | 72 | /* draw the buttons */ 73 | x = d; 74 | for( i = 0; i < cnt; i++ ) 75 | { 76 | is_invert = 0; 77 | if ( i == cursor ) 78 | is_invert = 1; 79 | 80 | u8g2_DrawUTF8Line(u8g2, x, y, 0, u8x8_GetStringLineStart(i, s), 1, is_invert); 81 | x += u8g2_GetUTF8Width(u8g2, u8x8_GetStringLineStart(i, s)); 82 | x += SPACE_BETWEEN_BUTTONS_IN_PIXEL; 83 | } 84 | 85 | /* return the number of buttons */ 86 | return cnt; 87 | } 88 | 89 | /* 90 | title1: Multiple lines,separated by '\n' 91 | title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart() 92 | title3: Multiple lines,separated by '\n' 93 | buttons: one more more buttons separated by '\n' and terminated with '\0' 94 | side effects: 95 | u8g2_SetFontDirection(u8g2, 0); 96 | u8g2_SetFontPosBaseline(u8g2); 97 | */ 98 | 99 | uint8_t u8g2_UserInterfaceMessage(u8g2_t *u8g2, const char *title1, const char *title2, const char *title3, const char *buttons) 100 | { 101 | uint8_t height; 102 | uint8_t line_height; 103 | u8g2_uint_t pixel_height; 104 | u8g2_uint_t y, yy; 105 | 106 | uint8_t cursor = 0; 107 | uint8_t button_cnt; 108 | uint8_t event; 109 | 110 | /* only horizontal strings are supported, so force this here */ 111 | u8g2_SetFontDirection(u8g2, 0); 112 | 113 | /* force baseline position */ 114 | u8g2_SetFontPosBaseline(u8g2); 115 | 116 | 117 | /* calculate line height */ 118 | line_height = u8g2_GetAscent(u8g2); 119 | line_height -= u8g2_GetDescent(u8g2); 120 | 121 | /* calculate overall height of the message box in lines*/ 122 | height = 1; /* button line */ 123 | height += u8x8_GetStringLineCnt(title1); 124 | if ( title2 != NULL ) 125 | height++; 126 | height += u8x8_GetStringLineCnt(title3); 127 | 128 | /* calculate the height in pixel */ 129 | pixel_height = height; 130 | pixel_height *= line_height; 131 | 132 | /* ... and add the space between the text and the buttons */ 133 | pixel_height +=SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL; 134 | 135 | /* calculate offset from top */ 136 | y = 0; 137 | if ( pixel_height < u8g2_GetDisplayHeight(u8g2) ) 138 | { 139 | y = u8g2_GetDisplayHeight(u8g2); 140 | y -= pixel_height; 141 | y /= 2; 142 | } 143 | y += u8g2_GetAscent(u8g2); 144 | 145 | 146 | for(;;) 147 | { 148 | u8g2_FirstPage(u8g2); 149 | do 150 | { 151 | yy = y; 152 | /* draw message box */ 153 | 154 | yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title1); 155 | if ( title2 != NULL ) 156 | { 157 | u8g2_DrawUTF8Line(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), title2, 0, 0); 158 | yy+=line_height; 159 | } 160 | yy += u8g2_DrawUTF8Lines(u8g2, 0, yy, u8g2_GetDisplayWidth(u8g2), line_height, title3); 161 | yy += SPACE_BETWEEN_TEXT_AND_BUTTONS_IN_PIXEL; 162 | 163 | button_cnt = u8g2_draw_button_line(u8g2, yy, u8g2_GetDisplayWidth(u8g2), cursor, buttons); 164 | 165 | } while( u8g2_NextPage(u8g2) ); 166 | 167 | #ifdef U8G2_REF_MAN_PIC 168 | return 0; 169 | #endif 170 | 171 | for(;;) 172 | { 173 | event = u8x8_GetMenuEvent(u8g2_GetU8x8(u8g2)); 174 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 175 | return cursor+1; 176 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 177 | return 0; 178 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN ) 179 | { 180 | cursor++; 181 | if ( cursor >= button_cnt ) 182 | cursor = 0; 183 | break; 184 | } 185 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP ) 186 | { 187 | if ( cursor == 0 ) 188 | cursor = button_cnt; 189 | cursor--; 190 | break; 191 | } 192 | } 193 | } 194 | /* never reached */ 195 | //return 0; 196 | } 197 | 198 | -------------------------------------------------------------------------------- /components/oled/u8log_u8g2.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8log_u8g2.c 4 | 5 | 6 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 7 | 8 | Copyright (c) 2018, olikraus@gmail.com 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, 12 | are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, this list 15 | of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright notice, this 18 | list of conditions and the following disclaimer in the documentation and/or other 19 | materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 22 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | */ 36 | 37 | #include "u8g2.h" 38 | /* 39 | Draw the u8log text at the specified x/y position. 40 | x/y position is the reference position of the first char of the first line. 41 | the line height is 42 | u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2) + line_height_offset; 43 | line_height_offset can be set with u8log_SetLineHeightOffset() 44 | Use 45 | u8g2_SetFontRefHeightText(u8g2_t *u8g2); 46 | u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2); 47 | u8g2_SetFontRefHeightAll(u8g2_t *u8g2); 48 | to change the return values for u8g2_GetAscent and u8g2_GetDescent 49 | 50 | */ 51 | void u8g2_DrawLog(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8log_t *u8log) 52 | { 53 | u8g2_uint_t disp_x, disp_y; 54 | uint8_t buf_x, buf_y; 55 | uint8_t c; 56 | 57 | disp_y = y; 58 | u8g2_SetFontDirection(u8g2, 0); 59 | for( buf_y = 0; buf_y < u8log->height; buf_y++ ) 60 | { 61 | disp_x = x; 62 | for( buf_x = 0; buf_x < u8log->width; buf_x++ ) 63 | { 64 | c = u8log->screen_buffer[buf_y * u8log->width + buf_x]; 65 | disp_x += u8g2_DrawGlyph(u8g2, disp_x, disp_y, c); 66 | } 67 | disp_y += u8g2_GetAscent(u8g2) - u8g2_GetDescent(u8g2); 68 | disp_y += u8log->line_height_offset; 69 | } 70 | } 71 | 72 | /* 73 | u8lib callback for u8g2 74 | 75 | Only font direction 0 is supported: u8g2_SetFontDirection(u8g2, 0) 76 | Use 77 | u8g2_SetFontRefHeightText(u8g2_t *u8g2); 78 | u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2); 79 | u8g2_SetFontRefHeightAll(u8g2_t *u8g2); 80 | to change the top offset and the line height and 81 | u8log_SetLineHeightOffset(u8log_t *u8log, int8_t line_height_offset) 82 | to change the line height. 83 | 84 | */ 85 | void u8log_u8g2_cb(u8log_t * u8log) 86 | { 87 | u8g2_t *u8g2 = (u8g2_t *)(u8log->aux_data); 88 | if ( u8log->is_redraw_line || u8log->is_redraw_all ) 89 | { 90 | u8g2_FirstPage(u8g2); 91 | do 92 | { 93 | u8g2_DrawLog( u8g2, 0, u8g2_GetAscent(u8g2), u8log); 94 | } 95 | while( u8g2_NextPage(u8g2) ); 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /components/oled/u8log_u8x8.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8log_u8x8.c 4 | 5 | 6 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 7 | 8 | Copyright (c) 2018, olikraus@gmail.com 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without modification, 12 | are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, this list 15 | of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright notice, this 18 | list of conditions and the following disclaimer in the documentation and/or other 19 | materials provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 22 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | */ 36 | 37 | #include "u8x8.h" 38 | 39 | static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log) U8X8_NOINLINE; 40 | static void u8x8_DrawLogLine(u8x8_t *u8x8, uint8_t disp_x, uint8_t disp_y, uint8_t buf_y, u8log_t *u8log) 41 | { 42 | uint8_t buf_x; 43 | uint8_t c; 44 | for( buf_x = 0; buf_x < u8log->width; buf_x++ ) 45 | { 46 | c = u8log->screen_buffer[buf_y * u8log->width + buf_x]; 47 | u8x8_DrawGlyph(u8x8, disp_x, disp_y, c); 48 | disp_x++; 49 | } 50 | } 51 | 52 | void u8x8_DrawLog(u8x8_t *u8x8, uint8_t x, uint8_t y, u8log_t *u8log) 53 | { 54 | uint8_t buf_y; 55 | for( buf_y = 0; buf_y < u8log->height; buf_y++ ) 56 | { 57 | u8x8_DrawLogLine(u8x8, x, y, buf_y, u8log); 58 | y++; 59 | } 60 | } 61 | 62 | 63 | void u8log_u8x8_cb(u8log_t * u8log) 64 | { 65 | u8x8_t *u8x8 = (u8x8_t *)(u8log->aux_data); 66 | if ( u8log->is_redraw_all ) 67 | { 68 | u8x8_DrawLog(u8x8, 0, 0, u8log); 69 | } 70 | else if ( u8log->is_redraw_line ) 71 | { 72 | u8x8_DrawLogLine(u8x8, 0, u8log->redraw_line, u8log->redraw_line, u8log); 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /components/oled/u8x8_d_a2printer.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_a2printer.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | Use DC2 bitmap command of the A2 Micro panel termal printer 36 | double stroke 37 | 38 | 39 | */ 40 | 41 | 42 | #include "u8x8.h" 43 | 44 | #define LINE_MIN_DELAY_MS 15 45 | /* higher values improve quality */ 46 | /* however if the value is too high (>=5) then form feed does not work any more */ 47 | #define LINE_EXTRA_8PIXEL_DELAY_MS 3 48 | /* this must be a power of two and between 1 and 8 */ 49 | /* best quality only with 1 */ 50 | #define NO_OF_LINES_TO_SEND_WITHOUT_DELAY 1 51 | 52 | /* calculates the delay, based on the number of black pixel */ 53 | /* actually only "none-zero" bytes are calculated which is, of course not so accurate, but should be good enough */ 54 | uint16_t get_delay_in_milliseconds(uint8_t cnt, uint8_t *data) 55 | { 56 | uint8_t i; 57 | uint16_t time = LINE_MIN_DELAY_MS; 58 | for ( i = 0; i < cnt; i++ ) 59 | if ( data[i] != 0 ) 60 | time += LINE_EXTRA_8PIXEL_DELAY_MS; 61 | return time; 62 | } 63 | 64 | uint8_t u8x8_d_a2printer_common(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr) 65 | { 66 | uint8_t c, i, j; 67 | uint8_t *ptr; 68 | uint16_t delay_in_milliseconds; 69 | switch(msg) 70 | { 71 | /* U8X8_MSG_DISPLAY_SETUP_MEMORY is handled by the calling function */ 72 | /* 73 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 74 | break; 75 | */ 76 | case U8X8_MSG_DISPLAY_INIT: 77 | u8x8_d_helper_display_init(u8x8); 78 | // no setup required 79 | // u8x8_cad_SendSequence(u8x8, u8x8_d_a2printer_init_seq); 80 | break; 81 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 82 | // no powersave 83 | break; 84 | case U8X8_MSG_DISPLAY_DRAW_TILE: 85 | u8x8_cad_StartTransfer(u8x8); 86 | 87 | u8x8_cad_SendCmd(u8x8, 27); /* ESC */ 88 | u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */ 89 | /* increasing the "max printing dots" requires a good power supply, but LINE_EXTRA_8PIXEL_DELAY_MS could be reduced then */ 90 | u8x8_cad_SendCmd(u8x8, 0); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1) ... lower values improve, probably my current supply is not sufficient */ 91 | u8x8_cad_SendCmd(u8x8, 200); /* 3-255 Heating time,Unit(10us),Default:80(800us) */ 92 | u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us) ... does not have much influence */ 93 | 94 | //c = ((u8x8_tile_t *)arg_ptr)->cnt; /* number of tiles */ 95 | c = u8x8->display_info->tile_width; 96 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; /* data ptr to the tiles */ 97 | 98 | u8x8_cad_SendCmd(u8x8, 18); /* DC2 */ 99 | u8x8_cad_SendCmd(u8x8, 42 ); /* * */ 100 | u8x8_cad_SendCmd(u8x8, 8 ); /* height */ 101 | u8x8_cad_SendCmd(u8x8, c ); /* c, u8x8->display_info->tile_width */ 102 | 103 | for( j = 0; j < 8 / NO_OF_LINES_TO_SEND_WITHOUT_DELAY; j ++ ) 104 | { 105 | 106 | delay_in_milliseconds = 0; 107 | for( i = 0; i < NO_OF_LINES_TO_SEND_WITHOUT_DELAY; i++ ) 108 | { 109 | u8x8_cad_SendData(u8x8, c, ptr); /* c, note: SendData can not handle more than 255 bytes, send one line of data */ 110 | delay_in_milliseconds += get_delay_in_milliseconds(c, ptr); 111 | ptr += c; 112 | } 113 | 114 | while( delay_in_milliseconds > 200 ) 115 | { 116 | u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, 200, NULL); 117 | delay_in_milliseconds -= 200; 118 | } 119 | u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_MILLI, delay_in_milliseconds, NULL); 120 | } 121 | 122 | /* set parameters back to their default values */ 123 | u8x8_cad_SendCmd(u8x8, 27); /* ESC */ 124 | u8x8_cad_SendCmd(u8x8, 55 ); /* parameter command */ 125 | u8x8_cad_SendCmd(u8x8, 7); /* Max printing dots,Unit(8dots),Default:7(64 dots) 8*(x+1)*/ 126 | u8x8_cad_SendCmd(u8x8, 80); /* 3-255 Heating time,Unit(10us),Default:80(800us) */ 127 | u8x8_cad_SendCmd(u8x8, 2); /* 0-255 Heating interval,Unit(10us),Default:2(20us)*/ 128 | 129 | u8x8_cad_EndTransfer(u8x8); 130 | 131 | break; 132 | default: 133 | return 0; 134 | } 135 | return 1; 136 | } 137 | 138 | 139 | static const u8x8_display_info_t u8x8_a2printer_384x240_display_info = 140 | { 141 | /* most of the settings are not required, because this is a serial RS232 printer */ 142 | 143 | /* chip_enable_level = */ 1, 144 | /* chip_disable_level = */ 0, 145 | 146 | /* post_chip_enable_wait_ns = */ 5, 147 | /* pre_chip_disable_wait_ns = */ 5, 148 | /* reset_pulse_width_ms = */ 1, 149 | /* post_reset_wait_ms = */ 6, 150 | /* sda_setup_time_ns = */ 20, 151 | /* sck_pulse_width_ns = */ 140, 152 | /* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 153 | /* spi_mode = */ 0, /* old: sck_takeover_edge, new: active high (bit 1), rising edge (bit 0) */ 154 | /* i2c_bus_clock_100kHz = */ 4, 155 | /* data_setup_time_ns = */ 30, 156 | /* write_pulse_width_ns = */ 40, 157 | /* tile_width = */ 48, 158 | /* tile_hight = */ 30, 159 | /* default_x_offset = */ 0, 160 | /* flipmode_x_offset = */ 0, 161 | /* pixel_width = */ 384, 162 | /* pixel_height = */ 240 163 | }; 164 | 165 | uint8_t u8x8_d_a2printer_384x240(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 166 | { 167 | switch(msg) 168 | { 169 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 170 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_a2printer_384x240_display_info); 171 | break; 172 | default: 173 | return u8x8_d_a2printer_common(u8x8, msg, arg_int, arg_ptr); 174 | } 175 | return 1; 176 | } 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /components/oled/u8x8_d_ls013b7dh03.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_ls013b7dh03.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | The LS013B7DH02 is a simple display and controller 36 | --> no support for contrast adjustment, flip and power down. 37 | */ 38 | 39 | #include "u8x8.h" 40 | 41 | #define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7)) 42 | 43 | #define LS013B7DH03_CMD_UPDATE (0x01) 44 | #define LS013B7DH03_CMD_ALL_CLEAR (0x04) 45 | #define LS013B7DH03_VAL_TRAILER (0x00) 46 | 47 | static const u8x8_display_info_t u8x8_ls013b7dh03_128x128_display_info = 48 | { 49 | /* chip_enable_level = */ 1, 50 | /* chip_disable_level = */ 0, 51 | /* post_chip_enable_wait_ns = */ 50, 52 | /* pre_chip_disable_wait_ns = */ 50, 53 | /* reset_pulse_width_ms = */ 1, 54 | /* post_reset_wait_ms = */ 6, 55 | /* sda_setup_time_ns = */ 227, /* 227 nsec according to the datasheet */ 56 | /* sck_pulse_width_ns = */ 255, /* 450 nsec according to the datasheet */ 57 | /* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 58 | /* spi_mode = */ 2, /* active low, rising edge */ 59 | /* i2c_bus_clock_100kHz = */ 4, 60 | /* data_setup_time_ns = */ 100, 61 | /* write_pulse_width_ns = */ 100, 62 | /* tile_width = */ 16, 63 | /* tile_hight = */ 16, 64 | /* default_x_offset = */ 0, 65 | /* flipmode_x_offset = */ 0, 66 | /* pixel_width = */ 128, 67 | /* pixel_height = */ 128 68 | }; 69 | 70 | uint8_t u8x8_d_ls013b7dh03_128x128(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr) 71 | { 72 | uint8_t y, c, i; 73 | uint8_t *ptr; 74 | switch(msg) 75 | { 76 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 77 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls013b7dh03_128x128_display_info); 78 | break; 79 | case U8X8_MSG_DISPLAY_INIT: 80 | u8x8_d_helper_display_init(u8x8); 81 | 82 | /* clear screen */ 83 | u8x8_cad_StartTransfer(u8x8); 84 | u8x8_cad_SendCmd(u8x8, SWAP8(LS013B7DH03_CMD_ALL_CLEAR) ); 85 | u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER); 86 | u8x8_cad_EndTransfer(u8x8); 87 | 88 | break; 89 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 90 | /* not available for the ls013b7dh03 */ 91 | break; 92 | case U8X8_MSG_DISPLAY_DRAW_TILE: 93 | /* each tile is 8 lines, with the data starting at the left edge */ 94 | y = ((((u8x8_tile_t *)arg_ptr)->y_pos) * 8) + 1; 95 | 96 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 97 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 98 | 99 | /* send data mode byte */ 100 | u8x8_cad_StartTransfer(u8x8); 101 | u8x8_cad_SendCmd(u8x8, SWAP8(LS013B7DH03_CMD_UPDATE) ); 102 | 103 | /* send 8 lines of 16 bytes (=128 pixels) */ 104 | for( i = 0; i < 8; i++ ) 105 | { 106 | u8x8_cad_SendCmd(u8x8, SWAP8(y + i) ); 107 | u8x8_cad_SendData(u8x8, c, ptr); 108 | u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER); 109 | 110 | ptr += c; 111 | } 112 | 113 | /* finish with a trailing byte */ 114 | u8x8_cad_SendCmd(u8x8, LS013B7DH03_VAL_TRAILER); 115 | u8x8_cad_EndTransfer(u8x8); 116 | 117 | break; 118 | default: 119 | return 0; 120 | } 121 | return 1; 122 | } 123 | 124 | 125 | static const u8x8_display_info_t u8x8_ls027b7dh01_400x240_display_info = 126 | { 127 | /* chip_enable_level = */ 1, 128 | /* chip_disable_level = */ 0, 129 | /* post_chip_enable_wait_ns = */ 50, 130 | /* pre_chip_disable_wait_ns = */ 50, 131 | /* reset_pulse_width_ms = */ 1, 132 | /* post_reset_wait_ms = */ 6, 133 | /* sda_setup_time_ns = */ 227, /* 227 nsec according to the datasheet */ 134 | /* sck_pulse_width_ns = */ 255, /* 450 nsec according to the datasheet */ 135 | /* sck_clock_hz = */ 1000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 136 | /* spi_mode = */ 2, /* active low, rising edge */ 137 | /* i2c_bus_clock_100kHz = */ 4, 138 | /* data_setup_time_ns = */ 100, 139 | /* write_pulse_width_ns = */ 100, 140 | /* tile_width = */ 50, 141 | /* tile_hight = */ 30, 142 | /* default_x_offset = */ 0, 143 | /* flipmode_x_offset = */ 0, 144 | /* pixel_width = */ 400, 145 | /* pixel_height = */ 240 146 | }; 147 | 148 | uint8_t u8x8_d_ls027b7dh01_400x240(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, void *arg_ptr) 149 | { 150 | switch(msg) 151 | { 152 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 153 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_ls027b7dh01_400x240_display_info); 154 | break; 155 | default: 156 | return u8x8_d_ls013b7dh03_128x128(u8x8, msg, arg_int, arg_ptr); 157 | } 158 | return 1; 159 | } 160 | 161 | -------------------------------------------------------------------------------- /components/oled/u8x8_d_pcd8544_84x48.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_pcd8544_84x48.c (so called "Nokia 5110" displays) 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | */ 36 | #include "u8x8.h" 37 | 38 | 39 | 40 | 41 | static const uint8_t u8x8_d_pcd8544_84x48_init_seq[] = { 42 | 43 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 44 | 45 | U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ 46 | U8X8_C(0x006), /* temp. control: b10 = 2 */ 47 | U8X8_C(0x013), /* bias system 1:48 */ 48 | U8X8_C(0x0c0), /* medium Vop */ 49 | 50 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 51 | U8X8_C(0x008), /* blank */ 52 | U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */ 53 | 54 | U8X8_END_TRANSFER(), /* disable chip */ 55 | U8X8_END() /* end of sequence */ 56 | }; 57 | 58 | static const uint8_t u8x8_d_pcd8544_84x48_powersave0_seq[] = { 59 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 60 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 61 | U8X8_C(0x00c), /* display on */ 62 | U8X8_END_TRANSFER(), /* disable chip */ 63 | U8X8_END() /* end of sequence */ 64 | }; 65 | 66 | static const uint8_t u8x8_d_pcd8544_84x48_powersave1_seq[] = { 67 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 68 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 69 | U8X8_C(0x008), /* blank */ 70 | U8X8_C(0x024), /* power down (PD=1), horizontal increment (V=0), enter normal command set (H=0) */ 71 | U8X8_END_TRANSFER(), /* disable chip */ 72 | U8X8_END() /* end of sequence */ 73 | }; 74 | 75 | 76 | 77 | static const u8x8_display_info_t u8x8_pcd8544_84x48_display_info = 78 | { 79 | /* chip_enable_level = */ 0, 80 | /* chip_disable_level = */ 1, 81 | 82 | /* post_chip_enable_wait_ns = */ 5, 83 | /* pre_chip_disable_wait_ns = */ 5, 84 | /* reset_pulse_width_ms = */ 2, 85 | /* post_reset_wait_ms = */ 2, 86 | /* sda_setup_time_ns = */ 12, 87 | /* sck_pulse_width_ns = */ 75, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */ 88 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 89 | /* spi_mode = */ 0, /* active high, rising edge */ 90 | /* i2c_bus_clock_100kHz = */ 4, 91 | /* data_setup_time_ns = */ 30, 92 | /* write_pulse_width_ns = */ 40, 93 | /* tile_width = */ 11, /* width of 11*8=88 pixel */ 94 | /* tile_hight = */ 6, 95 | /* default_x_offset = */ 0, 96 | /* flipmode_x_offset = */ 0, 97 | /* pixel_width = */ 84, 98 | /* pixel_height = */ 48 99 | }; 100 | 101 | uint8_t u8x8_d_pcd8544_84x48(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 102 | { 103 | uint8_t x, c; 104 | uint8_t *ptr; 105 | switch(msg) 106 | { 107 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 108 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcd8544_84x48_display_info); 109 | break; 110 | case U8X8_MSG_DISPLAY_INIT: 111 | u8x8_d_helper_display_init(u8x8); 112 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_init_seq); 113 | break; 114 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 115 | if ( arg_int == 0 ) 116 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave0_seq); 117 | else 118 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcd8544_84x48_powersave1_seq); 119 | break; 120 | // case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 121 | // break; NOT SUPPORTED 122 | 123 | #ifdef U8X8_WITH_SET_CONTRAST 124 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 125 | u8x8_cad_StartTransfer(u8x8); 126 | u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */ 127 | u8x8_cad_SendCmd(u8x8, 0x080 | (arg_int >> 1) ); 128 | u8x8_cad_EndTransfer(u8x8); 129 | break; 130 | #endif 131 | case U8X8_MSG_DISPLAY_DRAW_TILE: 132 | u8x8_cad_StartTransfer(u8x8); 133 | 134 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 135 | x *= 8; 136 | x += u8x8->x_offset; 137 | u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 138 | u8x8_cad_SendCmd(u8x8, 0x080 | (x) ); /* set X address */ 139 | u8x8_cad_SendCmd(u8x8, 0x040 | (((u8x8_tile_t *)arg_ptr)->y_pos) ); /* set Y address */ 140 | 141 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 142 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 143 | c *= 8; 144 | do 145 | { 146 | if ( c + x > 84u ) 147 | { 148 | if ( x >= 84u ) 149 | break; 150 | c = 84u; 151 | c -= x; 152 | } 153 | u8x8_cad_SendData(u8x8, c, ptr); /* note: SendData can not handle more than 255 bytes */ 154 | x += c; 155 | arg_int--; 156 | } while( arg_int > 0 ); 157 | 158 | u8x8_cad_EndTransfer(u8x8); 159 | break; 160 | default: 161 | return 0; 162 | } 163 | return 1; 164 | } 165 | 166 | 167 | -------------------------------------------------------------------------------- /components/oled/u8x8_d_pcf8812.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_pcf8812.c 4 | 5 | pcf8812: 65x102 6 | pcf8814: 65x96 7 | 8 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 9 | 10 | Copyright (c) 2017, olikraus@gmail.com 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without modification, 14 | are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, this list 17 | of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright notice, this 20 | list of conditions and the following disclaimer in the documentation and/or other 21 | materials provided with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 24 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 25 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 35 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | 37 | */ 38 | 39 | 40 | #include "u8x8.h" 41 | 42 | 43 | 44 | static const uint8_t u8x8_d_pcf8812_96x65_init_seq[] = { 45 | 46 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 47 | 48 | U8X8_C(0x020), /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 49 | U8X8_C(0x008), /* blank display */ 50 | 51 | U8X8_C(0x021), /* activate chip (PD=0), horizontal increment (V=0), enter extended command set (H=1) */ 52 | U8X8_C(0x006), /* temp. control: b10 = 2 */ 53 | U8X8_C(0x013), /* bias system, 0x010..0x07 1:48 */ 54 | U8X8_C(0x09f), /* contrast setting, 0..127 */ 55 | //U8X8_CA(0x020 | 2, 0x080 | 0), /* contrast setting, pcf8814 */ 56 | 57 | U8X8_C(0x024), /* deactivate chip (PD=1), horizontal increment (V=0), enter normal command set (H=0) */ 58 | 59 | U8X8_END_TRANSFER(), /* disable chip */ 60 | U8X8_END() /* end of sequence */ 61 | }; 62 | 63 | static const uint8_t u8x8_d_pcf8812_96x65_powersave0_seq[] = { 64 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 65 | U8X8_C(0x020), /* power on */ 66 | U8X8_C(0x00c), /* display on */ 67 | U8X8_END_TRANSFER(), /* disable chip */ 68 | U8X8_END() /* end of sequence */ 69 | }; 70 | 71 | static const uint8_t u8x8_d_pcf8812_96x65_powersave1_seq[] = { 72 | U8X8_START_TRANSFER(), /* enable chip, delay is part of the transfer start */ 73 | U8X8_C(0x020), /* power on */ 74 | U8X8_C(0x008), /* blank display */ 75 | U8X8_C(0x024), /* power down */ 76 | U8X8_END_TRANSFER(), /* disable chip */ 77 | U8X8_END() /* end of sequence */ 78 | }; 79 | 80 | 81 | static uint8_t u8x8_d_pcf8812_96x65_generic(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 82 | { 83 | uint8_t x, c; 84 | uint8_t *ptr; 85 | switch(msg) 86 | { 87 | /* handled by the calling function 88 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 89 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info); 90 | break; 91 | */ 92 | case U8X8_MSG_DISPLAY_INIT: 93 | u8x8_d_helper_display_init(u8x8); 94 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_init_seq); 95 | break; 96 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 97 | if ( arg_int == 0 ) 98 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave0_seq); 99 | else 100 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_powersave1_seq); 101 | break; 102 | /* 103 | case U8X8_MSG_DISPLAY_SET_FLIP_MODE: 104 | if ( arg_int == 0 ) 105 | { 106 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip0_seq); 107 | u8x8->x_offset = u8x8->display_info->default_x_offset; 108 | } 109 | else 110 | { 111 | u8x8_cad_SendSequence(u8x8, u8x8_d_pcf8812_96x65_flip1_seq); 112 | u8x8->x_offset = u8x8->display_info->flipmode_x_offset; 113 | } 114 | break; 115 | */ 116 | #ifdef U8X8_WITH_SET_CONTRAST 117 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 118 | u8x8_cad_StartTransfer(u8x8); 119 | u8x8_cad_SendCmd(u8x8, 0x021 ); /* command mode, extended function set */ 120 | u8x8_cad_SendArg(u8x8, (arg_int>>1)|0x80 ); /* 0..127 for contrast */ 121 | u8x8_cad_EndTransfer(u8x8); 122 | break; 123 | #endif 124 | case U8X8_MSG_DISPLAY_DRAW_TILE: 125 | u8x8_cad_StartTransfer(u8x8); 126 | x = ((u8x8_tile_t *)arg_ptr)->x_pos; 127 | x *= 8; 128 | x += u8x8->x_offset; 129 | 130 | u8x8_cad_SendCmd(u8x8, 0x020 ); /* activate chip (PD=0), horizontal increment (V=0), enter normal command set (H=0) */ 131 | u8x8_cad_SendCmd(u8x8, 0x080 | x); 132 | u8x8_cad_SendCmd(u8x8, 0x040 | ((u8x8_tile_t *)arg_ptr)->y_pos); 133 | 134 | do 135 | { 136 | c = ((u8x8_tile_t *)arg_ptr)->cnt; 137 | ptr = ((u8x8_tile_t *)arg_ptr)->tile_ptr; 138 | u8x8_cad_SendData(u8x8, c*8, ptr); /* note: SendData can not handle more than 255 bytes */ 139 | /* 140 | do 141 | { 142 | u8x8_cad_SendData(u8x8, 8, ptr); 143 | ptr += 8; 144 | c--; 145 | } while( c > 0 ); 146 | */ 147 | arg_int--; 148 | } while( arg_int > 0 ); 149 | 150 | u8x8_cad_EndTransfer(u8x8); 151 | break; 152 | default: 153 | return 0; 154 | } 155 | return 1; 156 | } 157 | 158 | 159 | static const u8x8_display_info_t u8x8_pcf8812_96x65_display_info = 160 | { 161 | /* chip_enable_level = */ 0, 162 | /* chip_disable_level = */ 1, 163 | 164 | /* post_chip_enable_wait_ns = */ 100, 165 | /* pre_chip_disable_wait_ns = */ 100, 166 | /* reset_pulse_width_ms = */ 100, 167 | /* post_reset_wait_ms = */ 100, 168 | /* sda_setup_time_ns = */ 100, 169 | /* sck_pulse_width_ns = */ 100, 170 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 171 | /* spi_mode = */ 0, /* active high, rising edge */ 172 | /* i2c_bus_clock_100kHz = */ 4, 173 | /* data_setup_time_ns = */ 40, 174 | /* write_pulse_width_ns = */ 150, 175 | /* tile_width = */ 12, 176 | /* tile_hight = */ 9, 177 | /* default_x_offset = */ 0, 178 | /* flipmode_x_offset = */ 0, 179 | /* pixel_width = */ 96, 180 | /* pixel_height = */ 65 181 | }; 182 | 183 | uint8_t u8x8_d_pcf8812_96x65(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 184 | { 185 | if ( msg == U8X8_MSG_DISPLAY_SETUP_MEMORY ) 186 | { 187 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_pcf8812_96x65_display_info); 188 | return 1; 189 | } 190 | return u8x8_d_pcf8812_96x65_generic(u8x8, msg, arg_int, arg_ptr); 191 | } 192 | 193 | 194 | -------------------------------------------------------------------------------- /components/oled/u8x8_d_stdio.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_d_stdio.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include 37 | #include "u8x8.h" 38 | 39 | #define W 8 40 | #define H 2 41 | 42 | uint8_t bitmap[W*H*8]; 43 | 44 | void bitmap_place_tile(uint8_t x, uint8_t y, uint8_t *tile) 45 | { 46 | uint8_t i; 47 | for(i = 0; i < 8; i++ ) 48 | bitmap[x*8+y*W*8+i] = tile[i]; 49 | } 50 | 51 | void bitmap_show(void) 52 | { 53 | int x, y; 54 | for( y = 0; y < H*8; y++ ) 55 | { 56 | for( x = 0; x < W*8; x++ ) 57 | { 58 | if ( (bitmap[x+(y/8)*W*8] & (1<<((y&7)))) != 0 ) 59 | { 60 | printf("*"); 61 | } 62 | else 63 | { 64 | printf("."); 65 | } 66 | } 67 | printf("\n"); 68 | } 69 | } 70 | 71 | 72 | uint8_t u8x8_d_stdio(U8X8_UNUSED u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) 73 | { 74 | switch(msg) 75 | { 76 | case U8X8_MSG_DISPLAY_INIT: 77 | break; 78 | case U8X8_MSG_DISPLAY_SET_POWER_SAVE: 79 | if ( arg_int == 0 ) 80 | bitmap_show(); 81 | break; 82 | case U8X8_MSG_DISPLAY_SET_CONTRAST: 83 | break; 84 | case U8X8_MSG_DISPLAY_DRAW_TILE: 85 | bitmap_place_tile(((u8x8_tile_t *)arg_ptr)->x_pos, ((u8x8_tile_t *)arg_ptr)->y_pos, ((u8x8_tile_t *)arg_ptr)->tile_ptr); 86 | break; 87 | default: 88 | break; 89 | } 90 | return 1; 91 | } 92 | 93 | 94 | 95 | void u8x8_SetupStdio(u8x8_t *u8x8) 96 | { 97 | u8x8_SetupDefaults(u8x8); 98 | u8x8->display_cb = u8x8_d_stdio; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /components/oled/u8x8_debounce.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_debounce.c 4 | 5 | Key/button simple debounce algorithm (Addon for u8x8) 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8x8.h" 39 | 40 | static uint8_t u8x8_read_pin_state(u8x8_t *u8x8) 41 | { 42 | uint8_t i; 43 | uint8_t pin_state; 44 | 45 | pin_state = 255; /* be compatible with the setup of the default pin setup, which is 255 */ 46 | for( i = 0; i < U8X8_PIN_INPUT_CNT; i++ ) 47 | { 48 | pin_state <<= 1; 49 | 50 | /* the callback function should put the return value into this variable */ 51 | u8x8->gpio_result = 1; 52 | u8x8_gpio_call(u8x8, U8X8_MSG_GPIO(i+U8X8_PIN_OUTPUT_CNT), 0); 53 | pin_state |= u8x8->gpio_result & 1; 54 | } 55 | 56 | return pin_state; 57 | } 58 | 59 | /* 60 | return 0 to U8X8_PIN_INPUT_CNT-1 if there is a difference 61 | return U8X8_PIN_INPUT_CNT if there is no difference 62 | */ 63 | static uint8_t u8x8_find_first_diff(uint8_t a, uint8_t b) 64 | { 65 | uint8_t mask; 66 | uint8_t i; 67 | mask = 1; 68 | i = U8X8_PIN_INPUT_CNT; 69 | do 70 | { 71 | i--; 72 | if ( (a & mask) != (b & mask) ) 73 | return i; 74 | mask <<= 1; 75 | } while( i > 0 ); 76 | return U8X8_PIN_INPUT_CNT; 77 | } 78 | 79 | /* 80 | State A: 81 | u8x8->debounce_last_pin_state == current_state 82 | --> State A 83 | u8x8->debounce_last_pin_state != current_state 84 | --> u8x8->debounce_last_pin_state = current_state 85 | --> State B + cnt 86 | 87 | State B + cnt 88 | --> state-- 89 | 90 | State B 91 | u8x8->debounce_last_pin_state == current_state 92 | --> keypress detected 93 | --> State C 94 | u8x8->debounce_last_pin_state != current_state 95 | --> State A 96 | 97 | State C 98 | u8x8->debounce_last_pin_state == current_state 99 | --> State C 100 | u8x8->debounce_last_pin_state != current_state 101 | --> State A 102 | 103 | */ 104 | 105 | #ifdef __unix__xxxxxx_THIS_IS_DISABLED 106 | 107 | #include 108 | #include 109 | uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8) 110 | { 111 | int c; 112 | c = getc(stdin); 113 | switch(c) 114 | { 115 | case 'n': 116 | return U8X8_MSG_GPIO_MENU_NEXT; 117 | case 'p': 118 | return U8X8_MSG_GPIO_MENU_PREV; 119 | case 's': 120 | return U8X8_MSG_GPIO_MENU_SELECT; 121 | case 'h': 122 | return U8X8_MSG_GPIO_MENU_HOME; 123 | case 'x': 124 | exit(0); 125 | default: 126 | puts("press n, p, s, h or x"); 127 | break; 128 | } 129 | return 0; 130 | } 131 | 132 | 133 | #else /* __unix__ */ 134 | 135 | 136 | #define U8X8_DEBOUNCE_WAIT 2 137 | /* do debounce and return a GPIO msg which indicates the event */ 138 | /* returns 0, if there is no event */ 139 | #if defined(__GNUC__) && !defined(__CYGWIN__) 140 | # pragma weak u8x8_GetMenuEvent 141 | #endif 142 | uint8_t u8x8_GetMenuEvent(u8x8_t *u8x8) 143 | { 144 | uint8_t pin_state; 145 | uint8_t result_msg = 0; /* invalid message, no event */ 146 | 147 | pin_state = u8x8_read_pin_state(u8x8); 148 | 149 | /* States A, B, C & D are encoded in the upper 4 bit*/ 150 | switch(u8x8->debounce_state) 151 | { 152 | case 0x00: /* State A, default state */ 153 | if ( u8x8->debounce_default_pin_state != pin_state ) 154 | { 155 | //u8x8->debounce_last_pin_state = pin_state; 156 | u8x8->debounce_state = 0x010 + U8X8_DEBOUNCE_WAIT; 157 | } 158 | break; 159 | case 0x10: /* State B */ 160 | //if ( u8x8->debounce_last_pin_state != pin_state ) 161 | if ( u8x8->debounce_default_pin_state == pin_state ) 162 | { 163 | u8x8->debounce_state = 0x00; /* back to state A */ 164 | } 165 | else 166 | { 167 | /* keypress detected */ 168 | u8x8->debounce_last_pin_state = pin_state; 169 | //result_msg = U8X8_MSG_GPIO_MENU_NEXT; 170 | u8x8->debounce_state = 0x020 + U8X8_DEBOUNCE_WAIT; /* got to state C */ 171 | } 172 | break; 173 | 174 | case 0x20: /* State C */ 175 | if ( u8x8->debounce_last_pin_state != pin_state ) 176 | { 177 | u8x8->debounce_state = 0x00; /* back to state A */ 178 | } 179 | else 180 | { 181 | u8x8->debounce_state = 0x030; /* got to state D */ 182 | } 183 | break; 184 | 185 | case 0x30: /* State D */ 186 | /* wait until key release */ 187 | if ( u8x8->debounce_default_pin_state == pin_state ) 188 | { 189 | u8x8->debounce_state = 0x00; /* back to state A */ 190 | result_msg = U8X8_MSG_GPIO(u8x8_find_first_diff(u8x8->debounce_default_pin_state, u8x8->debounce_last_pin_state)+U8X8_PIN_OUTPUT_CNT); 191 | } 192 | else 193 | { 194 | //result_msg = U8X8_MSG_GPIO_MENU_NEXT; 195 | // maybe implement autorepeat here 196 | } 197 | break; 198 | default: 199 | u8x8->debounce_state--; /* count down, until there is a valid state */ 200 | break; 201 | } 202 | return result_msg; 203 | } 204 | 205 | #endif /* __unix__ */ 206 | -------------------------------------------------------------------------------- /components/oled/u8x8_display.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_display.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | Abstraction layer for the graphics controller. 36 | Main goal is the placement of a 8x8 pixel block (tile) on the display. 37 | 38 | */ 39 | 40 | 41 | #include "u8x8.h" 42 | 43 | 44 | /*==========================================*/ 45 | /* internal library function */ 46 | 47 | /* 48 | this is a helper function for the U8X8_MSG_DISPLAY_SETUP_MEMORY function. 49 | It can be called within the display callback function to carry out the usual standard tasks. 50 | 51 | */ 52 | void u8x8_d_helper_display_setup_memory(u8x8_t *u8x8, const u8x8_display_info_t *display_info) 53 | { 54 | /* 1) set display info struct */ 55 | u8x8->display_info = display_info; 56 | u8x8->x_offset = u8x8->display_info->default_x_offset; 57 | } 58 | 59 | /* 60 | this is a helper function for the U8X8_MSG_DISPLAY_INIT function. 61 | It can be called within the display callback function to carry out the usual standard tasks. 62 | 63 | */ 64 | void u8x8_d_helper_display_init(u8x8_t *u8x8) 65 | { 66 | /* 2) apply port directions to the GPIO lines and apply default values for the IO lines*/ 67 | u8x8_gpio_Init(u8x8); 68 | u8x8_cad_Init(u8x8); 69 | 70 | /* 3) do reset */ 71 | u8x8_gpio_SetReset(u8x8, 1); 72 | u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms); 73 | u8x8_gpio_SetReset(u8x8, 0); 74 | u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->reset_pulse_width_ms); 75 | u8x8_gpio_SetReset(u8x8, 1); 76 | u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_MILLI, u8x8->display_info->post_reset_wait_ms); 77 | } 78 | 79 | /*==========================================*/ 80 | /* official functions */ 81 | 82 | uint8_t u8x8_DrawTile(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr) 83 | { 84 | u8x8_tile_t tile; 85 | tile.x_pos = x; 86 | tile.y_pos = y; 87 | tile.cnt = cnt; 88 | tile.tile_ptr = tile_ptr; 89 | return u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, 1, (void *)&tile); 90 | } 91 | 92 | /* should be implemented as macro */ 93 | void u8x8_SetupMemory(u8x8_t *u8x8) 94 | { 95 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SETUP_MEMORY, 0, NULL); 96 | } 97 | 98 | void u8x8_InitDisplay(u8x8_t *u8x8) 99 | { 100 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_INIT, 0, NULL); 101 | } 102 | 103 | void u8x8_SetPowerSave(u8x8_t *u8x8, uint8_t is_enable) 104 | { 105 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_POWER_SAVE, is_enable, NULL); 106 | } 107 | 108 | void u8x8_SetFlipMode(u8x8_t *u8x8, uint8_t mode) 109 | { 110 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_FLIP_MODE, mode, NULL); 111 | } 112 | 113 | void u8x8_SetContrast(u8x8_t *u8x8, uint8_t value) 114 | { 115 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_SET_CONTRAST, value, NULL); 116 | } 117 | 118 | void u8x8_RefreshDisplay(u8x8_t *u8x8) 119 | { 120 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_REFRESH, 0, NULL); 121 | } 122 | 123 | void u8x8_ClearDisplayWithTile(u8x8_t *u8x8, const uint8_t *buf) 124 | { 125 | u8x8_tile_t tile; 126 | uint8_t h; 127 | 128 | tile.x_pos = 0; 129 | tile.cnt = 1; 130 | tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */ 131 | 132 | h = u8x8->display_info->tile_height; 133 | tile.y_pos = 0; 134 | do 135 | { 136 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile); 137 | tile.y_pos++; 138 | } while( tile.y_pos < h ); 139 | } 140 | 141 | void u8x8_ClearDisplay(u8x8_t *u8x8) 142 | { 143 | uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 144 | u8x8_ClearDisplayWithTile(u8x8, buf); 145 | } 146 | 147 | void u8x8_FillDisplay(u8x8_t *u8x8) 148 | { 149 | uint8_t buf[8] = { 255, 255, 255, 255, 255, 255, 255, 255 }; 150 | u8x8_ClearDisplayWithTile(u8x8, buf); 151 | } 152 | 153 | void u8x8_ClearLine(u8x8_t *u8x8, uint8_t line) 154 | { 155 | uint8_t buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 156 | u8x8_tile_t tile; 157 | if ( line < u8x8->display_info->tile_height ) 158 | { 159 | tile.x_pos = 0; 160 | tile.y_pos = line; 161 | tile.cnt = 1; 162 | tile.tile_ptr = (uint8_t *)buf; /* tile_ptr should be const, but isn't */ 163 | u8x8->display_cb(u8x8, U8X8_MSG_DISPLAY_DRAW_TILE, u8x8->display_info->tile_width, (void *)&tile); 164 | } 165 | } -------------------------------------------------------------------------------- /components/oled/u8x8_gpio.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_gpio.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | 37 | #include "u8x8.h" 38 | 39 | 40 | void u8x8_gpio_call(u8x8_t *u8x8, uint8_t msg, uint8_t arg) 41 | { 42 | u8x8->gpio_and_delay_cb(u8x8, msg, arg, NULL); 43 | } 44 | 45 | /* 46 | void u8x8_gpio_Delay(u8x8_t *u8x8, uint8_t msg, uint8_t dly) 47 | { 48 | u8x8->gpio_and_delay_cb(u8x8, msg, dly, NULL); 49 | } 50 | */ -------------------------------------------------------------------------------- /components/oled/u8x8_input_value.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_input_value.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8x8.h" 37 | 38 | /* 39 | return: 40 | 0: value is not changed (HOME/Break Button pressed) 41 | 1: value has been updated 42 | */ 43 | 44 | uint8_t u8x8_UserInterfaceInputValue(u8x8_t *u8x8, const char *title, const char *pre, uint8_t *value, uint8_t lo, uint8_t hi, uint8_t digits, const char *post) 45 | { 46 | uint8_t height; 47 | uint8_t y; 48 | uint8_t width; 49 | uint8_t x; 50 | uint8_t local_value = *value; 51 | uint8_t r; 52 | uint8_t event; 53 | 54 | /* calculate overall height of the input value box */ 55 | height = 1; /* button line */ 56 | height += u8x8_GetStringLineCnt(title); 57 | 58 | /* calculate offset from top */ 59 | y = 0; 60 | if ( height < u8x8_GetRows(u8x8) ) 61 | { 62 | y = u8x8_GetRows(u8x8); 63 | y -= height; 64 | y /= 2; 65 | } 66 | 67 | /* calculate offset from left for the label */ 68 | x = 0; 69 | width = u8x8_GetUTF8Len(u8x8, pre); 70 | width += digits; 71 | width += u8x8_GetUTF8Len(u8x8, post); 72 | if ( width < u8x8_GetCols(u8x8) ) 73 | { 74 | x = u8x8_GetCols(u8x8); 75 | x -= width; 76 | x /= 2; 77 | } 78 | 79 | /* render */ 80 | u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */ 81 | u8x8_SetInverseFont(u8x8, 0); 82 | y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title); 83 | x += u8x8_DrawUTF8(u8x8, x, y, pre); 84 | u8x8_DrawUTF8(u8x8, x+digits, y, post); 85 | u8x8_SetInverseFont(u8x8, 1); 86 | 87 | /* event loop */ 88 | u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits)); 89 | for(;;) 90 | { 91 | event = u8x8_GetMenuEvent(u8x8); 92 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 93 | { 94 | *value = local_value; 95 | r = 1; 96 | break; 97 | } 98 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 99 | { 100 | r = 0; 101 | break; 102 | } 103 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP ) 104 | { 105 | if ( local_value >= hi ) 106 | local_value = lo; 107 | else 108 | local_value++; 109 | u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits)); 110 | } 111 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN ) 112 | { 113 | if ( local_value <= lo ) 114 | local_value = hi; 115 | else 116 | local_value--; 117 | u8x8_DrawUTF8(u8x8, x, y, u8x8_u8toa(local_value, digits)); 118 | } 119 | } 120 | 121 | u8x8_SetInverseFont(u8x8, 0); 122 | return r; 123 | } 124 | -------------------------------------------------------------------------------- /components/oled/u8x8_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_message.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "u8x8.h" 37 | 38 | uint8_t u8x8_draw_button_line(u8x8_t *u8x8, uint8_t y, uint8_t w, uint8_t cursor, const char *s) 39 | { 40 | uint8_t i; 41 | uint8_t cnt; 42 | uint8_t total; 43 | uint8_t d; 44 | uint8_t x; 45 | cnt = u8x8_GetStringLineCnt(s); 46 | 47 | /* calculate the width of the button */ 48 | total = 0; 49 | for( i = 0; i < cnt; i++ ) 50 | { 51 | total += u8x8_GetUTF8Len(u8x8, u8x8_GetStringLineStart(i, s)); 52 | } 53 | total += (cnt-1); /* had one space between the buttons */ 54 | 55 | /* calculate the left offset */ 56 | d = 0; 57 | if ( total < w ) 58 | { 59 | d = w; 60 | d -= total; 61 | d /= 2; 62 | } 63 | 64 | /* draw the buttons */ 65 | x = d; 66 | u8x8_SetInverseFont(u8x8, 0); 67 | for( i = 0; i < cnt; i++ ) 68 | { 69 | if ( i == cursor ) 70 | u8x8_SetInverseFont(u8x8, 1); 71 | 72 | x+=u8x8_DrawUTF8(u8x8, x, y, u8x8_GetStringLineStart(i, s)); 73 | u8x8_SetInverseFont(u8x8, 0); 74 | x+=u8x8_DrawUTF8(u8x8, x, y, " "); 75 | } 76 | 77 | /* return the number of buttons */ 78 | return cnt; 79 | } 80 | 81 | /* 82 | title1: Multiple lines,separated by '\n' 83 | title2: A single line/string which is terminated by '\0' or '\n' . "title2" accepts the return value from u8x8_GetStringLineStart() 84 | title3: Multiple lines,separated by '\n' 85 | buttons: one more more buttons separated by '\n' and terminated with '\0' 86 | */ 87 | 88 | uint8_t u8x8_UserInterfaceMessage(u8x8_t *u8x8, const char *title1, const char *title2, const char *title3, const char *buttons) 89 | { 90 | uint8_t height; 91 | uint8_t y; 92 | uint8_t cursor = 0; 93 | uint8_t button_cnt; 94 | uint8_t event; 95 | 96 | u8x8_SetInverseFont(u8x8, 0); 97 | 98 | /* calculate overall height of the message box */ 99 | height = 1; /* button line */ 100 | height += u8x8_GetStringLineCnt(title1); 101 | if ( title2 != NULL ) 102 | height ++; 103 | height += u8x8_GetStringLineCnt(title3); 104 | 105 | /* calculate offset from top */ 106 | y = 0; 107 | if ( height < u8x8_GetRows(u8x8) ) 108 | { 109 | y = u8x8_GetRows(u8x8); 110 | y -= height; 111 | y /= 2; 112 | } 113 | 114 | /* draw message box */ 115 | 116 | u8x8_ClearDisplay(u8x8); /* required, because not everything is filled */ 117 | 118 | y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title1); 119 | if ( title2 != NULL ) 120 | { 121 | u8x8_DrawUTF8Line(u8x8, 0, y, u8x8_GetCols(u8x8), title2); 122 | y++; 123 | } 124 | y += u8x8_DrawUTF8Lines(u8x8, 0, y, u8x8_GetCols(u8x8), title3); 125 | 126 | button_cnt = u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons); 127 | 128 | for(;;) 129 | { 130 | event = u8x8_GetMenuEvent(u8x8); 131 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 132 | return cursor+1; 133 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 134 | break; 135 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_UP ) 136 | { 137 | cursor++; 138 | if ( cursor >= button_cnt ) 139 | cursor = 0; 140 | u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons); 141 | } 142 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_DOWN ) 143 | { 144 | if ( cursor == 0 ) 145 | cursor = button_cnt; 146 | cursor--; 147 | u8x8_draw_button_line(u8x8, y, u8x8_GetCols(u8x8), cursor, buttons); 148 | } 149 | } 150 | return 0; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /components/oled/u8x8_selection_list.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_selection_list.c 4 | 5 | selection list with scroll option 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8x8.h" 39 | 40 | /* 41 | increase the cursor position 42 | */ 43 | void u8sl_Next(u8sl_t *u8sl) 44 | { 45 | u8sl->current_pos++; 46 | if ( u8sl->current_pos >= u8sl->total ) 47 | { 48 | u8sl->current_pos = 0; 49 | u8sl->first_pos = 0; 50 | } 51 | else 52 | { 53 | if ( u8sl->first_pos + u8sl->visible <= u8sl->current_pos + 1 ) 54 | { 55 | u8sl->first_pos = u8sl->current_pos - u8sl->visible + 1; 56 | } 57 | } 58 | } 59 | 60 | void u8sl_Prev(u8sl_t *u8sl) 61 | { 62 | if ( u8sl->current_pos == 0 ) 63 | { 64 | u8sl->current_pos = u8sl->total - 1; 65 | u8sl->first_pos = 0; 66 | if ( u8sl->total > u8sl->visible ) 67 | u8sl->first_pos = u8sl->total - u8sl->visible; 68 | } 69 | else 70 | { 71 | u8sl->current_pos--; 72 | if ( u8sl->first_pos > u8sl->current_pos ) 73 | u8sl->first_pos = u8sl->current_pos; 74 | } 75 | } 76 | 77 | void u8x8_DrawSelectionList(u8x8_t *u8x8, u8sl_t *u8sl, u8x8_sl_cb sl_cb, const void *aux) 78 | { 79 | uint8_t i; 80 | for( i = 0; i < u8sl->visible; i++ ) 81 | { 82 | sl_cb(u8x8, u8sl, i+u8sl->first_pos, aux); 83 | } 84 | } 85 | 86 | /* selection list with string line */ 87 | void u8x8_sl_string_line_cb(u8x8_t *u8x8, u8sl_t *u8sl, uint8_t idx, const void *aux) 88 | { 89 | const char *s; 90 | uint8_t row; 91 | /* calculate offset from display upper border */ 92 | row = u8sl->y; 93 | 94 | /* calculate target pos */ 95 | row += idx; 96 | row -= u8sl->first_pos; 97 | 98 | /* check whether this is the current cursor line */ 99 | if ( idx == u8sl->current_pos ) 100 | u8x8_SetInverseFont(u8x8, 1); 101 | else 102 | u8x8_SetInverseFont(u8x8, 0); 103 | 104 | /* get the line from the array */ 105 | s = u8x8_GetStringLineStart(idx, (const char *)aux); 106 | 107 | /* draw the line */ 108 | if ( s == NULL ) 109 | s = ""; 110 | u8x8_DrawUTF8Line(u8x8, u8sl->x, row, u8x8_GetCols(u8x8), s); 111 | u8x8_SetInverseFont(u8x8, 0); 112 | } 113 | 114 | /* 115 | title: NULL for no title, valid str for title line. Can contain mutliple lines, separated by '\n' 116 | start_pos: default position for the cursor (starts with 1) 117 | sl: string list (list of strings separated by \n) 118 | returns 0 if user has pressed the home key 119 | returns the selected line+1 if user has pressed the select key (e.g. 1 for the first line) 120 | */ 121 | uint8_t u8x8_UserInterfaceSelectionList(u8x8_t *u8x8, const char *title, uint8_t start_pos, const char *sl) 122 | { 123 | u8sl_t u8sl; 124 | uint8_t event; 125 | uint8_t title_lines; 126 | 127 | if ( start_pos > 0 ) 128 | start_pos--; 129 | 130 | u8sl.visible = u8x8_GetRows(u8x8); 131 | u8sl.total = u8x8_GetStringLineCnt(sl); 132 | u8sl.first_pos = 0; 133 | u8sl.current_pos = start_pos; 134 | u8sl.x = 0; 135 | u8sl.y = 0; 136 | 137 | 138 | //u8x8_ClearDisplay(u8x8); /* not required because all is 100% filled */ 139 | u8x8_SetInverseFont(u8x8, 0); 140 | 141 | if ( title != NULL ) 142 | { 143 | title_lines = u8x8_DrawUTF8Lines(u8x8, u8sl.x, u8sl.y, u8x8_GetCols(u8x8), title); 144 | u8sl.y+=title_lines; 145 | u8sl.visible-=title_lines; 146 | } 147 | 148 | if ( u8sl.current_pos >= u8sl.total ) 149 | u8sl.current_pos = u8sl.total-1; 150 | 151 | 152 | u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); 153 | 154 | for(;;) 155 | { 156 | event = u8x8_GetMenuEvent(u8x8); 157 | if ( event == U8X8_MSG_GPIO_MENU_SELECT ) 158 | return u8sl.current_pos+1; 159 | else if ( event == U8X8_MSG_GPIO_MENU_HOME ) 160 | return 0; 161 | else if ( event == U8X8_MSG_GPIO_MENU_NEXT || event == U8X8_MSG_GPIO_MENU_DOWN ) 162 | { 163 | u8sl_Next(&u8sl); 164 | u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); 165 | } 166 | else if ( event == U8X8_MSG_GPIO_MENU_PREV || event == U8X8_MSG_GPIO_MENU_UP ) 167 | { 168 | u8sl_Prev(&u8sl); 169 | u8x8_DrawSelectionList(u8x8, &u8sl, u8x8_sl_string_line_cb, sl); 170 | } 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /components/oled/u8x8_setup.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_setup.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | 37 | #include "u8x8.h" 38 | 39 | /* universal dummy callback, which will be default for all callbacks */ 40 | uint8_t u8x8_dummy_cb(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) 41 | { 42 | /* the dummy callback will not handle any message and will fail for all messages */ 43 | return 0; 44 | } 45 | 46 | 47 | static const u8x8_display_info_t u8x8_null_display_info = 48 | { 49 | /* chip_enable_level = */ 0, 50 | /* chip_disable_level = */ 1, 51 | 52 | /* post_chip_enable_wait_ns = */ 0, 53 | /* pre_chip_disable_wait_ns = */ 0, 54 | /* reset_pulse_width_ms = */ 0, 55 | /* post_reset_wait_ms = */ 0, 56 | /* sda_setup_time_ns = */ 0, 57 | /* sck_pulse_width_ns = */ 0, /* half of cycle time (100ns according to datasheet), AVR: below 70: 8 MHz, >= 70 --> 4MHz clock */ 58 | /* sck_clock_hz = */ 4000000UL, /* since Arduino 1.6.0, the SPI bus speed in Hz. Should be 1000000000/sck_pulse_width_ns */ 59 | /* spi_mode = */ 0, /* active high, rising edge */ 60 | /* i2c_bus_clock_100kHz = */ 4, 61 | /* data_setup_time_ns = */ 0, 62 | /* write_pulse_width_ns = */ 0, 63 | /* tile_width = */ 1, /* 8x8 */ 64 | /* tile_hight = */ 1, 65 | /* default_x_offset = */ 0, 66 | /* flipmode_x_offset = */ 0, 67 | /* pixel_width = */ 8, 68 | /* pixel_height = */ 8 69 | }; 70 | 71 | 72 | /* a special null device */ 73 | uint8_t u8x8_d_null_cb(u8x8_t *u8x8, uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr) 74 | { 75 | switch(msg) 76 | { 77 | case U8X8_MSG_DISPLAY_SETUP_MEMORY: 78 | u8x8_d_helper_display_setup_memory(u8x8, &u8x8_null_display_info); 79 | break; 80 | case U8X8_MSG_DISPLAY_INIT: 81 | u8x8_d_helper_display_init(u8x8); 82 | break; 83 | } 84 | /* the null device callback will succeed for all messages */ 85 | return 1; 86 | } 87 | 88 | 89 | /* 90 | Description: 91 | Setup u8x8 92 | Args: 93 | u8x8 An empty u8x8 structure 94 | */ 95 | void u8x8_SetupDefaults(u8x8_t *u8x8) 96 | { 97 | u8x8->display_info = NULL; 98 | u8x8->display_cb = u8x8_dummy_cb; 99 | u8x8->cad_cb = u8x8_dummy_cb; 100 | u8x8->byte_cb = u8x8_dummy_cb; 101 | u8x8->gpio_and_delay_cb = u8x8_dummy_cb; 102 | u8x8->is_font_inverse_mode = 0; 103 | u8x8->device_address = 0; 104 | u8x8->utf8_state = 0; /* also reset by u8x8_utf8_init */ 105 | u8x8->i2c_address = 255; 106 | u8x8->debounce_default_pin_state = 255; /* assume all low active buttons */ 107 | 108 | #ifdef U8X8_USE_PINS 109 | { 110 | uint8_t i; 111 | for( i = 0; i < U8X8_PIN_CNT; i++ ) 112 | u8x8->pins[i] = U8X8_PIN_NONE; 113 | } 114 | #endif 115 | } 116 | 117 | 118 | /* 119 | Description: 120 | Setup u8x8 and assign the callback function. The dummy 121 | callback "u8x8_dummy_cb" can be used, if no callback is required. 122 | This setup will not communicate with the display itself. 123 | Use u8x8_InitDisplay() to send the startup code to the Display. 124 | Args: 125 | u8x8 An empty u8x8 structure 126 | display_cb Display/controller specific callback function 127 | cad_cb Display controller specific communication callback function 128 | byte_cb Display controller/communication specific callback funtion 129 | gpio_and_delay_cb Environment specific callback function 130 | 131 | */ 132 | void u8x8_Setup(u8x8_t *u8x8, u8x8_msg_cb display_cb, u8x8_msg_cb cad_cb, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) 133 | { 134 | /* setup defaults and reset pins to U8X8_PIN_NONE */ 135 | u8x8_SetupDefaults(u8x8); 136 | 137 | /* setup specific callbacks */ 138 | u8x8->display_cb = display_cb; 139 | u8x8->cad_cb = cad_cb; 140 | u8x8->byte_cb = byte_cb; 141 | u8x8->gpio_and_delay_cb = gpio_and_delay_cb; 142 | 143 | /* setup display info */ 144 | u8x8_SetupMemory(u8x8); 145 | } 146 | 147 | -------------------------------------------------------------------------------- /components/oled/u8x8_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_string.c 4 | 5 | string line procedures 6 | 7 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 8 | 9 | Copyright (c) 2016, olikraus@gmail.com 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 15 | * Redistributions of source code must retain the above copyright notice, this list 16 | of conditions and the following disclaimer. 17 | 18 | * Redistributions in binary form must reproduce the above copyright notice, this 19 | list of conditions and the following disclaimer in the documentation and/or other 20 | materials provided with the distribution. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 32 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 34 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "u8x8.h" 39 | 40 | uint8_t u8x8_GetStringLineCnt(const char *str) 41 | { 42 | char e; 43 | uint8_t line_cnt = 1; 44 | if ( str == NULL ) 45 | return 0; 46 | for(;;) 47 | { 48 | e = *str; 49 | if ( e == '\0' ) 50 | break; 51 | str++; 52 | if ( e == '\n' ) 53 | line_cnt++; 54 | } 55 | return line_cnt; 56 | } 57 | 58 | 59 | /* 60 | Assumes strings, separated by '\n' in "str". 61 | Returns the string at index "line_idx". First strng has line_idx = 0 62 | Example: 63 | Returns "xyz" for line_idx = 1 with str = "abc\nxyz" 64 | Support both UTF8 and normal strings. 65 | */ 66 | const char *u8x8_GetStringLineStart(uint8_t line_idx, const char *str ) 67 | { 68 | char e; 69 | uint8_t line_cnt = 1; 70 | 71 | if ( line_idx == 0 ) 72 | return str; 73 | 74 | for(;;) 75 | { 76 | e = *str; 77 | if ( e == '\0' ) 78 | break; 79 | str++; 80 | if ( e == '\n' ) 81 | { 82 | if ( line_cnt == line_idx ) 83 | return str; 84 | line_cnt++; 85 | } 86 | } 87 | return NULL; /* line not found */ 88 | } 89 | 90 | /* copy until first '\n' or '\0' in str */ 91 | /* Important: There is no string overflow check, ensure */ 92 | /* that the destination buffer is large enough */ 93 | void u8x8_CopyStringLine(char *dest, uint8_t line_idx, const char *str) 94 | { 95 | if ( dest == NULL ) 96 | return; 97 | str = u8x8_GetStringLineStart( line_idx, str ); 98 | if ( str != NULL ) 99 | { 100 | for(;;) 101 | { 102 | if ( *str == '\n' || *str == '\0' ) 103 | break; 104 | *dest = *str; 105 | dest++; 106 | str++; 107 | } 108 | } 109 | *dest = '\0'; 110 | } 111 | 112 | /* 113 | Draw a string 114 | Extend the string to size "w" 115 | Center the string within "w" 116 | return the size of the string 117 | 118 | */ 119 | uint8_t u8x8_DrawUTF8Line(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s) 120 | { 121 | uint8_t d, lw; 122 | uint8_t cx, dx; 123 | 124 | d = 0; 125 | 126 | lw = u8x8_GetUTF8Len(u8x8, s); 127 | if ( lw < w ) 128 | { 129 | d = w; 130 | d -=lw; 131 | d /= 2; 132 | } 133 | 134 | cx = x; 135 | dx = cx + d; 136 | while( cx < dx ) 137 | { 138 | u8x8_DrawUTF8(u8x8, cx, y, " "); 139 | cx++; 140 | } 141 | cx += u8x8_DrawUTF8(u8x8, cx, y, s); 142 | dx = x + w; 143 | while( cx < dx ) 144 | { 145 | u8x8_DrawUTF8(u8x8, cx, y, " "); 146 | cx++; 147 | } 148 | cx -= x; 149 | return cx; 150 | } 151 | 152 | /* 153 | draw several lines at position x,y. 154 | lines are stored in s and must be separated with '\n'. 155 | lines can be centered with respect to "w" 156 | if s == NULL nothing is drawn and 0 is returned 157 | returns the number of lines in s 158 | */ 159 | uint8_t u8x8_DrawUTF8Lines(u8x8_t *u8x8, uint8_t x, uint8_t y, uint8_t w, const char *s) 160 | { 161 | uint8_t i; 162 | uint8_t cnt; 163 | cnt = u8x8_GetStringLineCnt(s); 164 | for( i = 0; i < cnt; i++ ) 165 | { 166 | u8x8_DrawUTF8Line(u8x8, x, y, w, u8x8_GetStringLineStart(i, s)); 167 | y++; 168 | } 169 | return cnt; 170 | } 171 | -------------------------------------------------------------------------------- /components/oled/u8x8_u16toa.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_u16toa.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | 35 | */ 36 | 37 | 38 | #include "u8x8.h" 39 | 40 | const char *u8x8_u16toap(char * dest, uint16_t v) 41 | { 42 | uint8_t pos; 43 | uint8_t d; 44 | uint16_t c; 45 | c = 10000; 46 | for( pos = 0; pos < 5; pos++ ) 47 | { 48 | d = '0'; 49 | while( v >= c ) 50 | { 51 | v -= c; 52 | d++; 53 | } 54 | dest[pos] = d; 55 | c /= 10; 56 | } 57 | dest[5] = '\0'; 58 | return dest; 59 | } 60 | 61 | /* v = value, d = number of digits */ 62 | const char *u8x8_u16toa(uint16_t v, uint8_t d) 63 | { 64 | static char buf[6]; 65 | d = 5-d; 66 | return u8x8_u16toap(buf, v) + d; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /components/oled/u8x8_u8toa.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | u8x8_u8toa.c 4 | 5 | Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) 6 | 7 | Copyright (c) 2016, olikraus@gmail.com 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this list 14 | of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, this 17 | list of conditions and the following disclaimer in the documentation and/or other 18 | materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 22 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | 37 | #include "u8x8.h" 38 | 39 | static const unsigned char u8x8_u8toa_tab[3] = { 100, 10, 1 } ; 40 | const char *u8x8_u8toap(char * dest, uint8_t v) 41 | { 42 | uint8_t pos; 43 | uint8_t d; 44 | uint8_t c; 45 | for( pos = 0; pos < 3; pos++ ) 46 | { 47 | d = '0'; 48 | c = *(u8x8_u8toa_tab+pos); 49 | while( v >= c ) 50 | { 51 | v -= c; 52 | d++; 53 | } 54 | dest[pos] = d; 55 | } 56 | dest[3] = '\0'; 57 | return dest; 58 | } 59 | 60 | /* v = value, d = number of digits */ 61 | const char *u8x8_u8toa(uint8_t v, uint8_t d) 62 | { 63 | static char buf[4]; 64 | d = 3-d; 65 | return u8x8_u8toap(buf, v) + d; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /components/plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "plugins.c" "layout_server.c" "testFunc.c" "plugin_manager.c" 2 | INCLUDE_DIRS "include" 3 | REQUIRES "hidkeycodeconv" "wifiman" "json") 4 | -------------------------------------------------------------------------------- /components/plugins/include/layout_server.h: -------------------------------------------------------------------------------- 1 | /* 2 | * layout_server.h 3 | * 4 | * Created on: 21 Apr 2019 5 | * Author: gal 6 | */ 7 | 8 | #ifndef PLUGINS_LAYOUT_SERVER_H_ 9 | #define PLUGINS_LAYOUT_SERVER_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #include "plugin_manager.h" 16 | 17 | uint8_t killServer; 18 | 19 | #define OPENSSL_EXAMPLE_TASK_NAME "openssl_example" 20 | #define OPENSSL_EXAMPLE_TASK_STACK_WORDS 10240 21 | #define OPENSSL_EXAMPLE_TASK_PRIORITY 8 22 | 23 | #define OPENSSL_EXAMPLE_RECV_BUF_LEN 1024 24 | 25 | #define OPENSSL_EXAMPLE_LOCAL_TCP_PORT 443 26 | 27 | //Initialize the layout server 28 | void http_server(void * pvParameters); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* PLUGINS_LAYOUT_SERVER_H_ */ 35 | -------------------------------------------------------------------------------- /components/plugins/include/plugin_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * plugin_manager.h 3 | * 4 | * Created on: 21 Apr 2019 5 | * Author: gal 6 | */ 7 | 8 | #ifndef PLUGINS_PLUGIN_MANAGER_H_ 9 | #define PLUGINS_PLUGIN_MANAGER_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | #include "keycode_conv.h" 16 | #include "wifi_manager.h" 17 | 18 | uint8_t pluginEn; 19 | typedef void(*func_t)( void * pvParameters); //just to make things easier 20 | /* 21 | * @brief start a plugin FreeRTOS task 22 | * @param plugin pass a function to be opened as the plugin 23 | * @param wifi_enable set 0 if function does not require wiFi 24 | * @param block_ble_report set 0 if you do not wish to block keyboard reports 25 | */ 26 | void start_plugin_task(func_t plugin, int wifi_enable, int block_ble_report); 27 | 28 | 29 | /* 30 | * @@brief close the plugin that is currently running 31 | */ 32 | void close_plugin_task(void); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | 39 | 40 | #endif /* PLUGINS_PLUGIN_MANAGER_H_ */ 41 | -------------------------------------------------------------------------------- /components/plugins/include/plugins.h: -------------------------------------------------------------------------------- 1 | /* 2 | * plugins.h 3 | * 4 | * Created on: 21 Apr 2019 5 | * Author: gal 6 | */ 7 | 8 | #ifndef PLUGINS_PLUGINS_H_ 9 | #define PLUGINS_PLUGINS_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | #include "plugin_manager.h" 15 | 16 | 17 | #define DEFAULT_SSID "SSID" //default SSID for WiFi access point 18 | #define DEFAULT_PASSWORD "PASS" //default password for WiFi access point 19 | 20 | /* 21 | *@brief Add the headers for your plugins here, make sure the 22 | * function to be called is of type void and only takes argument void * pvParameters 23 | */ 24 | #include "layout_server.h" 25 | #include "testFunc.h" 26 | 27 | //Set the keycodes that indicate plugins here, make sure to set the first key code as PLUGIN_BASE_VAL 28 | enum plugin_keycodes { 29 | PN_CLOSE = PLUGIN_BASE_VAL, 30 | PN_LAYOUT, 31 | PN_TEST 32 | }; 33 | 34 | /* 35 | *@We create tasks for the plugins depending on the keycode pressed 36 | * edit this functing in plugins.c 37 | */ 38 | void plugin_launcher(uint16_t keycode); 39 | 40 | /** @brief Queue for sending mouse reports 41 | * @see mouse_command_t */ 42 | 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif /* PLUGINS_PLUGINS_H_ */ 49 | -------------------------------------------------------------------------------- /components/plugins/include/testFunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * testFunc.h 3 | * 4 | * Created on: 27 Apr 2019 5 | * Author: gal 6 | */ 7 | 8 | #ifndef PLUGINS_TESTFUNC_H_ 9 | #define PLUGINS_TESTFUNC_H_ 10 | 11 | void testFunc(void *pvParameters); 12 | 13 | 14 | 15 | #endif /* PLUGINS_TESTFUNC_H_ */ 16 | -------------------------------------------------------------------------------- /components/plugins/layout_server.c: -------------------------------------------------------------------------------- 1 | /* 2 | * layout_server.c 3 | * 4 | * Created on: 21 Apr 2019 5 | * Author: gal 6 | */ 7 | 8 | #include "layout_server.h" 9 | 10 | #include "freertos/FreeRTOS.h" 11 | #include "esp_wifi.h" 12 | #include "esp_system.h" 13 | #include "esp_event.h" 14 | #include "esp_log.h" 15 | #include "nvs_flash.h" 16 | #include "driver/gpio.h" 17 | #include "freertos/portmacro.h" 18 | #include "freertos/event_groups.h" 19 | #include "esp_log.h" 20 | #include "esp_netif.h" 21 | 22 | #include "lwip/err.h" 23 | #include "string.h" 24 | 25 | #include "cJSON.h" 26 | #define LAYOUT_TAG "Layout server" 27 | 28 | #define delay(ms) (vTaskDelay(ms/portTICK_RATE_MS)) 29 | char* json_unformatted; 30 | 31 | const static char http_html_hdr[] = 32 | "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n"; 33 | const static char http_index_hml[] = "" 34 | "\n" 35 | "\n" 36 | " \n" 37 | " \n" 41 | "HELLO ESP32\n" 42 | "\n" 43 | "\n" 44 | "

Hello World, from MK32!

\n" 45 | "\n" 46 | "\n"; 47 | 48 | 49 | #include "lwip/sys.h" 50 | #include "lwip/netdb.h" 51 | #include "lwip/api.h" 52 | 53 | 54 | static void http_server_netconn_serve(struct netconn *conn) 55 | { 56 | struct netbuf *inbuf; 57 | char *buf; 58 | u16_t buflen; 59 | err_t err; 60 | 61 | /* Read the data from the port, blocking if nothing yet there. 62 | We assume the request (the part we care about) is in one netbuf */ 63 | err = netconn_recv(conn, &inbuf); 64 | 65 | if (err == ERR_OK) { 66 | netbuf_data(inbuf, (void**)&buf, &buflen); 67 | 68 | // strncpy(_mBuffer, buf, buflen); 69 | 70 | /* Is this an HTTP GET command? (only check the first 5 chars, since 71 | there are other formats for GET, and we're keeping it very simple )*/ 72 | printf("buffer = %s \n", buf); 73 | if (buflen>=5 && 74 | buf[0]=='G' && 75 | buf[1]=='E' && 76 | buf[2]=='T' && 77 | buf[3]==' ' && 78 | buf[4]=='/' ) { 79 | printf("buf[5] = %c\n", buf[5]); 80 | /* Send the HTML header 81 | * subtract 1 from the size, since we dont send the \0 in the string 82 | * NETCONN_NOCOPY: our data is const static, so no need to copy it 83 | */ 84 | 85 | netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY); 86 | 87 | if(buf[5]=='h') { 88 | /* Send our HTML page */ 89 | netconn_write(conn, http_index_hml, sizeof(http_index_hml)-1, NETCONN_NOCOPY); 90 | } 91 | else if(buf[5]=='l') { 92 | /* Send our HTML page */ 93 | netconn_write(conn, http_index_hml, sizeof(http_index_hml)-1, NETCONN_NOCOPY); 94 | } 95 | else if(buf[5]=='j') { 96 | netconn_write(conn, json_unformatted, strlen(json_unformatted), NETCONN_NOCOPY); 97 | } 98 | else { 99 | netconn_write(conn, http_index_hml, sizeof(http_index_hml)-1, NETCONN_NOCOPY); 100 | } 101 | } 102 | 103 | } 104 | /* Close the connection (server closes in HTTP) */ 105 | netconn_close(conn); 106 | 107 | /* Delete the buffer (netconn_recv gives us ownership, 108 | so we have to make sure to deallocate the buffer) */ 109 | netbuf_delete(inbuf); 110 | } 111 | 112 | void http_server(void *pvParameters) 113 | { 114 | ESP_LOGI(LAYOUT_TAG, "Starting webserver"); 115 | struct netconn *conn, *newconn; 116 | err_t err; 117 | conn = netconn_new(NETCONN_TCP); 118 | netconn_bind(conn, NULL, 80); 119 | netconn_listen(conn); 120 | do { 121 | err = netconn_accept(conn, &newconn); 122 | if (err == ERR_OK) { 123 | http_server_netconn_serve(newconn); 124 | netconn_delete(newconn); 125 | } 126 | } while(err == ERR_OK); 127 | netconn_close(conn); 128 | netconn_delete(conn); 129 | ESP_LOGI(LAYOUT_TAG, "Webserver closed"); 130 | 131 | } 132 | 133 | 134 | -------------------------------------------------------------------------------- /components/plugins/plugin_manager.c: -------------------------------------------------------------------------------- 1 | /* 2 | * plugin_manager.c 3 | * 4 | * Created on: 21 Apr 2019 5 | * Author: gal 6 | */ 7 | #include "esp_log.h" 8 | #include "plugin_manager.h" 9 | 10 | TaskHandle_t pluginHandle; 11 | #define PLUGIN_LOG "Plugin Manager" 12 | 13 | int taskFlag = 0; 14 | int wifiFlag = 0; 15 | /* 16 | * @brief start a plugin FreeRTOS task 17 | */ 18 | void start_plugin_task(func_t plugin, int wifi_enable, int block_ble_report){ 19 | uint8_t no_err = 1; 20 | if(taskFlag == 1){ 21 | ESP_LOGE(PLUGIN_LOG, "Plugin already running!"); 22 | return; 23 | } 24 | else{ 25 | if(wifi_enable == 1){ 26 | no_err = wifi_connection_init(); 27 | wifiFlag = 1; 28 | } 29 | if(block_ble_report == 1){ 30 | BLE_EN = 0; 31 | } 32 | } 33 | //create the task 34 | if(no_err == 1){ 35 | ESP_LOGI(PLUGIN_LOG, "Starting plugin"); 36 | pluginEn = 1; 37 | xTaskCreatePinnedToCore(plugin, "Plugin task", 4096, NULL,configMAX_PRIORITIES,&pluginHandle, 1); 38 | taskFlag = 1; 39 | } 40 | if(no_err == 0){ 41 | ESP_LOGE(PLUGIN_LOG, "Error initializing plugin"); 42 | } 43 | } 44 | 45 | 46 | /* 47 | * @brief close the plugin that is currently running 48 | */ 49 | void close_plugin_task(void){ 50 | if(taskFlag != 1){ 51 | ESP_LOGE(PLUGIN_LOG, "No plugin running!"); 52 | } 53 | else{ 54 | 55 | taskFlag = 0; 56 | // vTaskSuspend(pluginHandle); 57 | 58 | if(wifiFlag == 1){ 59 | wifi_connection_deinit(); 60 | wifiFlag = 0; 61 | } 62 | if(BLE_EN == 0){ 63 | BLE_EN = 1; 64 | } 65 | 66 | vTaskDelete(pluginHandle); 67 | ESP_LOGI(PLUGIN_LOG, "Plugin closed"); 68 | } 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /components/plugins/plugins.c: -------------------------------------------------------------------------------- 1 | #include "plugins.h" 2 | 3 | //We create tasks for the plugins here 4 | void plugin_launcher(uint16_t keycode){ 5 | 6 | switch(keycode){ 7 | case PN_CLOSE: 8 | close_plugin_task(); 9 | break; 10 | 11 | case PN_LAYOUT: 12 | start_plugin_task(http_server, 1, 0); 13 | break; 14 | 15 | case PN_TEST: 16 | start_plugin_task(testFunc, 0, 0); 17 | break; 18 | 19 | default: 20 | break; 21 | } 22 | 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /components/plugins/testFunc.c: -------------------------------------------------------------------------------- 1 | #include "keycode_conv.h" 2 | #include "testFunc.h" 3 | #include "plugin_manager.h" 4 | //Test function that prints to serial monitor whatever is typed after pressing enter 5 | void testFunc(void *pvParameters){ 6 | while(1){ 7 | printf(input_string()); 8 | printf("\n"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /components/rotencoder/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "r_encoder.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES "ble") 4 | -------------------------------------------------------------------------------- /components/rotencoder/include/r_encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * r_encoder.h 3 | * 4 | * Created on: 18 Aug 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef R_ENCODER_H_ 9 | #define R_ENCODER_H_ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** @brief Setup the rotary encoder 16 | * */ 17 | void r_encoder_setup(void); 18 | 19 | /** @brief check rotary encoder status 20 | * */ 21 | uint8_t r_encoder_state(void); 22 | 23 | void r_encoder_command(uint8_t command, uint16_t encoder_commands[4]); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* R_ENCODER_H_ */ 30 | -------------------------------------------------------------------------------- /components/rotencoder/r_encoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 15 | * MA 02110-1301, USA. 16 | * 17 | * Copyright 2018 Gal Zaidenstein. 18 | */ 19 | 20 | #include "esp_system.h" 21 | #include "freertos/FreeRTOS.h" 22 | #include "freertos/task.h" 23 | #include "driver/gpio.h" 24 | #include "key_definitions.h" 25 | #include "keyboard_config.h" 26 | #include "key_definitions.h" 27 | #include "driver/pcnt.h" 28 | #include "hal_ble.h" 29 | 30 | int PastEncoderCount=0; 31 | 32 | //How to process encoder activity 33 | void r_encoder_command(uint8_t command, uint16_t encoder_commands[4]){ 34 | uint8_t type = encoder_commands[0]; 35 | uint8_t media_state[2] = {0}; 36 | uint8_t mouse_state[5] = {0}; 37 | uint8_t key_state[REPORT_LEN] = {0}; 38 | 39 | switch(type){ 40 | case MEDIA_ENCODER: 41 | if(command>=4){ 42 | command=3; 43 | } 44 | if(encoder_commands[command] == KC_MEDIA_NEXT_TRACK){ 45 | media_state[1] = 10; 46 | } 47 | if(encoder_commands[command] == KC_MEDIA_PREV_TRACK ){ 48 | media_state[1] = 111; 49 | } 50 | if(encoder_commands[command] == KC_MEDIA_STOP){ 51 | media_state[1] = 12; 52 | } 53 | if(encoder_commands[command] == KC_MEDIA_PLAY_PAUSE){ 54 | media_state[1] = 5; 55 | } 56 | if(encoder_commands[command] == KC_AUDIO_MUTE){ 57 | media_state[1] = 1; 58 | } 59 | if(encoder_commands[command] == KC_AUDIO_VOL_UP){ 60 | SET_BIT(media_state[0],6); 61 | } 62 | if(encoder_commands[command] == KC_AUDIO_VOL_DOWN){ 63 | SET_BIT(media_state[0],7); 64 | } 65 | xQueueSend(media_q,(void*)&media_state, (TickType_t) 0); 66 | break; 67 | 68 | case MOUSE_ENCODER: 69 | mouse_state[0] = 0; 70 | mouse_state[1] = 0; 71 | mouse_state[2] = 0; 72 | mouse_state[3] = 0; 73 | for(uint8_t i = 0;i < 3; i++){ 74 | if((CHECK_BIT(command,i)) != 0){ 75 | switch(encoder_commands[i + 1]){ 76 | case KC_MS_UP : 77 | mouse_state[2] = 15; 78 | break; 79 | 80 | case KC_MS_DOWN: 81 | mouse_state[2] = -15; 82 | break; 83 | 84 | case KC_MS_LEFT: 85 | mouse_state[1] = -15; 86 | break; 87 | 88 | case KC_MS_RIGHT: 89 | mouse_state[1] = 15; 90 | break; 91 | 92 | case KC_MS_BTN1: 93 | mouse_state[0] = 1; 94 | break; 95 | 96 | case KC_MS_BTN2: 97 | mouse_state[0] = 2; 98 | break; 99 | 100 | case KC_MS_WH_UP: 101 | mouse_state[3] = 1; 102 | break; 103 | case KC_MS_WH_DOWN: 104 | mouse_state[3] = -1; 105 | break; 106 | } 107 | } 108 | } 109 | xQueueSend(mouse_q,(void*)&mouse_state, (TickType_t) 0); 110 | break; 111 | 112 | case KEY_ENCODER: 113 | if(command >= 4){ 114 | command = 3; 115 | } 116 | key_state[2] = encoder_commands[command]; 117 | xQueueSend(keyboard_q,(void*)&key_state, (TickType_t) 0); 118 | break; 119 | } 120 | vTaskDelay(5 / portTICK_PERIOD_MS); 121 | } 122 | //Setting Pulse counter and encoder button 123 | void r_encoder_setup(void){ 124 | 125 | pcnt_config_t pcnt_config_a = { 126 | // Set PCNT input signal and control GPIOs 127 | .pulse_gpio_num = ENCODER_A_PIN, 128 | .ctrl_gpio_num = ENCODER_B_PIN, 129 | 130 | .unit = PCNT_UNIT_0, 131 | .channel = PCNT_CHANNEL_0, 132 | 133 | // What to do on the positive / negative edge of pulse input? 134 | .pos_mode = PCNT_COUNT_DIS, // Count up on the positive edge 135 | .neg_mode = PCNT_COUNT_INC, // Keep the counter value on the negative edge 136 | // What to do when control input is low or high? 137 | .lctrl_mode = PCNT_MODE_KEEP, // Reverse counting direction if low 138 | .hctrl_mode = PCNT_MODE_REVERSE, // Keep the primary counter mode if high 139 | // Set the maximum and minimum limit values to watch 140 | .counter_h_lim = INT16_MAX, 141 | .counter_l_lim = INT16_MIN, 142 | }; 143 | 144 | 145 | pcnt_unit_config(&pcnt_config_a); 146 | 147 | pcnt_set_filter_value(PCNT_UNIT_0, 1023); // Filter Runt Pulses 148 | pcnt_filter_enable(PCNT_UNIT_0); 149 | 150 | gpio_set_direction(ENCODER_A_PIN,GPIO_MODE_INPUT); 151 | gpio_set_pull_mode(ENCODER_A_PIN,GPIO_PULLUP_ONLY); 152 | gpio_set_direction(ENCODER_B_PIN,GPIO_MODE_INPUT); 153 | gpio_set_pull_mode(ENCODER_B_PIN,GPIO_FLOATING); 154 | 155 | pcnt_counter_pause(PCNT_UNIT_0); // Initial PCNT init 156 | pcnt_counter_clear(PCNT_UNIT_0); 157 | pcnt_counter_resume(PCNT_UNIT_0); 158 | 159 | //Encoder Button 160 | #ifdef ENCODER_S_PIN 161 | gpio_pad_select_gpio(ENCODER_S_PIN); 162 | gpio_set_direction(ENCODER_S_PIN, GPIO_MODE_INPUT); 163 | gpio_set_pull_mode(ENCODER_S_PIN,GPIO_PULLDOWN_ONLY); 164 | #endif 165 | 166 | } 167 | //Check encoder state, currently defined for Vol +/= and mute 168 | uint8_t r_encoder_state(void){ 169 | uint8_t EncoderState = 0x00; 170 | int16_t EncoderCount; 171 | pcnt_get_counter_value(PCNT_UNIT_0, &EncoderCount); 172 | if(EncoderCount > PastEncoderCount){ 173 | EncoderState = 1; 174 | } 175 | if(EncoderCount < PastEncoderCount){ 176 | EncoderState = 2; 177 | } 178 | #ifdef ENCODER_S_PIN 179 | if(gpio_get_level(ENCODER_S_PIN)==1){ 180 | EncoderState+= 4; 181 | } 182 | #endif 183 | PastEncoderCount = EncoderCount; 184 | return EncoderState; 185 | 186 | } 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /components/wifiman/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "wifi_manager.c" 2 | INCLUDE_DIRS "include" "${CMAKE_SOURCE_DIR}/main" 3 | REQUIRES nvs_flash plugins) 4 | -------------------------------------------------------------------------------- /components/wifiman/include/wifi_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi_manager.h 3 | * 4 | * Created on: 29 Sep 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef WIFI_MANAGER_WIFI_MANAGER_H_ 9 | #define WIFI_MANAGER_WIFI_MANAGER_H_ 10 | 11 | #include "keyboard_config.h" 12 | #include "esp_netif.h" 13 | #include "esp_wifi.h" 14 | #include "esp_wifi_types.h" 15 | #include "esp_event.h" 16 | 17 | 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #define MAX_AP_SSID_LEN 32 24 | #define MAX_AP_PASS_LEN 64 25 | #define MAX_AP_BSSID_LEN 6 26 | 27 | /* 28 | * names to for config data keys (for easy retrieval) 29 | * each key will be "retrieval name" with corresponding "ap ssid" appended at the end 30 | */ 31 | #define MAX_AP_KEY_LEN 64 32 | 33 | //Retrieval names 34 | #define AP_PASSWORD "password" 35 | #define AP_SCAN_METHOD "scan method" 36 | #define AP_BSSID_SET "bssid set" 37 | #define AP_BSSID "bssid" 38 | #define AP_CHANNEL "channel" 39 | #define AP_LISTEN_INTERVAL "interval" 40 | #define AP_SORT_METHOD "sort method" 41 | #define AP_THRESHOLD "threshold" 42 | 43 | #define NO_SSID_FOUND 0 44 | #define SSID_FOUND 1 45 | 46 | /** 47 | * @brief check if a previous wifi ap is available, if so connect to it. 48 | * otherwise prompt to enter connection manager 49 | */ 50 | uint8_t wifi_connection_init(void); 51 | 52 | /** 53 | * @brief scan for availabe wifi aps and select one to connect and store to nvs 54 | */ 55 | void wifi_availble_ap(void); 56 | 57 | /** 58 | * @brief retrieve a wifi ap config by ssid name and pass it to buffer, 59 | * if no ssid found return NO_SSID_FOUND otherwise returns SSID_FOUND 60 | */ 61 | uint8_t wifi_retrieve_ap(uint8_t ssid[MAX_AP_SSID_LEN],wifi_sta_config_t *ap_config); 62 | 63 | /** 64 | * @brief remove ap from nvs 65 | */ 66 | void wifi_del_ap(uint8_t ssid[MAX_AP_SSID_LEN]); 67 | 68 | /** 69 | * @brief store or update a wifi ap in nvs 70 | */ 71 | void wifi_store_ap(wifi_sta_config_t ap_config); 72 | 73 | /** 74 | * @brief disable wifi connection 75 | */ 76 | void wifi_connection_deinit(void); 77 | 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | 84 | #endif /* WIFI_MANAGER_WIFI_MANAGER_H_ */ 85 | -------------------------------------------------------------------------------- /keyboards/catiONE/keyboard_config.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_CONFIG_H 2 | #define KEYBOARD_CONFIG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "driver/gpio.h" 11 | #include "driver/touch_pad.h" 12 | #include "driver/adc.h" 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "freertos/event_groups.h" 16 | #include "oled_tasks.h" 17 | 18 | #define MODULE_ID "" 19 | #define GATTS_TAG "" // The device's name 20 | #define MAX_BT_DEVICENAME_LENGTH 40 21 | 22 | #define MASTER // undefine if you are not flashing the main controller 23 | //#define SPLIT_MASTER // undefine if keyboard is not split and master 24 | //#define SLAVE // undefine if keyboard is master 25 | 26 | #define DEBOUNCE 4 //debounce time in ms 27 | 28 | //Define matrix 29 | #define KEYPADS 1 // intended in order to create a Multiple keypad split boards 30 | #define MATRIX_ROWS 5 31 | #define MATRIX_COLS 12 // For split keyboards, define columns for one side only. 32 | 33 | //#define NKRO // does not work on Android and iOS!, we can get 18KRO on those 34 | #define LAYERS 3 // number of layers defined 35 | 36 | // Select diode direction 37 | #define COL2ROW 38 | //#define ROW2COL 39 | 40 | //Encoder definitions 41 | //#define R_ENCODER // undefine if no rotary encoder is used 42 | //#define R_ENCODER_SLAVE // undefine if no rotary encoder is used on slave pad 43 | //#define ENCODER_A_PIN GPIO_NUM_17 // encoder phase A pin 44 | #define ENCODER_A_PIN GPIO_NUM_36 // encoder phase A pin 45 | #define ENCODER_B_PIN GPIO_NUM_34// encoder phase B pin 46 | //#define ENCODER_S_PIN GPIO_NUM_16// encoder switch pin 47 | #define ENCODER_S_PIN GPIO_NUM_39// encoder switch pin 48 | 49 | //OLED Parameters 50 | //#define OLED_ENABLE //undefine if no oled is used 51 | #define ROTATION LANDSCAPE 52 | #define OLED_SDA_PIN GPIO_NUM_21 53 | #define OLED_SCL_PIN GPIO_NUM_22 54 | 55 | /*Battery monitoring 56 | * Please read check battery_monitor.h for resistor values before applying 57 | * use ADC1 only, */ 58 | 59 | //#define BATT_STAT //define to enable battery monitoring 60 | #define BATT_PIN ADC1_CHANNEL_7 //gpio pin 35, refer to the esp32 before modifying 61 | 62 | //deep sleep parameters, mind that reconnecting after deep sleep might take a minute or two 63 | #define SLEEP_MINS 45 // undefine if you do not need deep sleep, otherwise define number of minutes for deepsleep 64 | 65 | /* 66 | *---------------------------- Everything below here should not be modified for standard usage---------------------- 67 | * 68 | * */ 69 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 70 | #define SET_BIT(var,pos) (var |= 1LLU << pos); 71 | 72 | #define MAX_LAYER (LAYERS-1) 73 | #define MOD_LED_BYTES 2 //bytes for led status and modifiers 74 | #define MACRO_LEN 3 //keys for macros 75 | #define KEYMAP_COLS MATRIX_COLS*KEYPADS // used for a symmetrical split keyboard 76 | #define REPORT_LEN (MOD_LED_BYTES+MACRO_LEN+MATRIX_ROWS*KEYMAP_COLS) //size of hid reports with NKRO and room for 3 key macro 77 | #define REPORT_COUNT_BYTES (MATRIX_ROWS*KEYMAP_COLS+MACRO_LEN) 78 | 79 | #define PLUGIN_BASE_VAL 0x135 80 | #define LAYER_HOLD_MAX_VAL 0x134 81 | #define LAYER_HOLD_BASE_VAL 0x123 82 | #define MACRO_BASE_VAL 0x103 83 | #define LAYERS_BASE_VAL 0xFF 84 | 85 | #define ENCODER_SIZE 4 86 | #define MEDIA_ENCODER 0 87 | #define MOUSE_ENCODER 1 88 | #define KEY_ENCODER 2 89 | 90 | typedef struct config_data { 91 | char bt_device_name[MAX_BT_DEVICENAME_LENGTH]; 92 | } config_data_t; 93 | 94 | extern uint8_t current_layout; 95 | extern uint8_t curr_led; 96 | 97 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 98 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 99 | 100 | #define MAX_LAYOUT_NAME_LENGTH 15 101 | // array to hold names of layouts for oled 102 | extern char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH]; 103 | 104 | extern TaskHandle_t xKeyreportTask; 105 | 106 | #endif 107 | // 108 | -------------------------------------------------------------------------------- /keyboards/catiONE/keymap.c: -------------------------------------------------------------------------------- 1 | #ifndef KEYMAP_C 2 | #define KEYMAP_C 3 | 4 | #include "key_definitions.h" 5 | #include "keyboard_config.h" 6 | #include "keymap.h" 7 | #include "plugins.h" 8 | 9 | // A bit different from QMK, default returns you to the first layer, LOWER and raise increase/lower layer by order. 10 | #define DEFAULT 0x100 11 | #define LOWER 0x101 12 | #define RAISE 0x102 13 | 14 | // Keymaps are designed to be relatively interchangeable with QMK 15 | enum custom_keycodes { 16 | QWERTY, NUM, 17 | PLUGINS, 18 | }; 19 | 20 | //Set these for each layer and use when layers are needed in a hold-to use layer 21 | enum layer_holds { 22 | QWERTY_H = LAYER_HOLD_BASE_VAL, NUM_H,FUNCS_H 23 | }; 24 | 25 | // array to hold names of layouts for oled 26 | char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH] = { "QWERTY", "NUM", 27 | "Plugins", 28 | }; 29 | 30 | /* select a keycode for your macro 31 | * important - first macro must be initialized as MACRO_BASE_VAL 32 | * */ 33 | 34 | #define MACROS_NUM 2 35 | enum custom_macros { 36 | KC_CTRL_ALT_DELETE = MACRO_BASE_VAL, KC_ALT_F4, 37 | }; 38 | 39 | /*define what the macros do 40 | * important- make sure you you put the macros in the same order as the their enumeration 41 | */ 42 | uint16_t macros[MACROS_NUM][MACRO_LEN] = { 43 | // CTRL+ALT+DEL 44 | { KC_LCTRL, KC_LALT, KC_DEL }, 45 | //ALT +F4 46 | { KC_RALT, KC_LALT, KC_NO } }; 47 | 48 | /*Encoder keys for each layer by order, and for each pad 49 | * First variable states what usage the encoder has 50 | */ 51 | 52 | uint16_t default_encoder_map[LAYERS][ENCODER_SIZE] = { 53 | // |VOL + | VOL - | MUTE | 54 | { MEDIA_ENCODER, KC_AUDIO_VOL_UP, KC_AUDIO_VOL_DOWN, KC_AUDIO_MUTE }, 55 | // |Y+|Y-| LEFT CLICK| 56 | { MOUSE_ENCODER, KC_MS_UP, KC_MS_DOWN, KC_MS_BTN1 }, 57 | 58 | { MOUSE_ENCODER, KC_MS_UP, KC_MS_DOWN, KC_MS_BTN1 } }; 59 | 60 | uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE] = { 61 | // |VOL + | VOL - | MUTE | 62 | { MOUSE_ENCODER, KC_MS_WH_UP, KC_MS_WH_DOWN , KC_AUDIO_MUTE }, 63 | // |Y+|Y-| LEFT CLICK| 64 | { MOUSE_ENCODER, KC_MS_RIGHT, KC_MS_LEFT, KC_MS_BTN2 }, 65 | // |Y+|Y-| LEFT CLICK| 66 | { MOUSE_ENCODER, KC_MS_RIGHT, KC_MS_LEFT, KC_MS_BTN2 } }; 67 | 68 | // Fillers to make layering more clear 69 | #define _______ KC_TRNS 70 | #define XXXXXXX KC_NO 71 | 72 | //NOTE: For this keymap due to wiring constraints the the two last rows on the left are wired unconventionally 73 | // Each keymap is represented by an array, with an array that points to all the keymaps by order 74 | uint16_t _QWERTY[MATRIX_ROWS][KEYMAP_COLS]={ 75 | {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS}, 76 | {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_QUOT}, 77 | {KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_G, KC_M, KC_N, KC_E, KC_I, KC_O, KC_BSPC}, 78 | {KC_LSFT, KC_Z, KC_X, KC_C, KC_D, KC_V, KC_K, KC_H, KC_COMM, KC_DOT, KC_SLSH, KC_ENT}, 79 | {KC_LCTRL,KC_LALT, KC_LGUI, DEFAULT, RAISE, KC_SPC, NUM, LOWER, KC_BSLS, KC_LBRC, KC_RBRC, KC_EQL} 80 | }; 81 | 82 | uint16_t _NUM[MATRIX_ROWS][KEYMAP_COLS]={ 83 | {KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12}, 84 | {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT,XXXXXXX, XXXXXXX}, 85 | {XXXXXXX, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL}, 86 | {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_PGDN, KC_PGUP, KC_END, XXXXXXX, XXXXXXX}, 87 | {XXXXXXX, XXXXXXX, XXXXXXX, DEFAULT, RAISE, XXXXXXX, NUM, LOWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX} 88 | }; 89 | 90 | uint16_t _PLUGINS[MATRIX_ROWS][KEYMAP_COLS]={ 91 | {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX}, 92 | {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT,XXXXXXX, XXXXXXX}, 93 | {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX}, 94 | {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_HOME, KC_PGDN, KC_PGUP, KC_END, XXXXXXX, XXXXXXX}, 95 | {XXXXXXX, XXXXXXX, XXXXXXX, DEFAULT, RAISE, XXXXXXX, NUM, LOWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX} 96 | }; 97 | //Create an array that points to the various keymaps 98 | uint16_t (*default_layouts[])[MATRIX_ROWS][KEYMAP_COLS] = { &_QWERTY, &_NUM, 99 | &_PLUGINS 100 | }; 101 | 102 | uint8_t current_layout = 0; 103 | 104 | #endif 105 | 106 | -------------------------------------------------------------------------------- /keyboards/default/keyboard_config.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_CONFIG_H 2 | #define KEYBOARD_CONFIG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "driver/gpio.h" 11 | #include "driver/touch_pad.h" 12 | #include "driver/adc.h" 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "freertos/event_groups.h" 16 | #include "oled_tasks.h" 17 | 18 | #define MODULE_ID "LOLIN 32" 19 | #define GATTS_TAG "MK32 V3.0" // The device's name 20 | #define MAX_BT_DEVICENAME_LENGTH 40 21 | 22 | #define MASTER // undefine if you are not flashing the main controller 23 | #define SPLIT_MASTER // undefine if keyboard is not split and master 24 | //#define SLAVE // undefine if keyboard is master 25 | 26 | #define DEBOUNCE 4 //debounce time in ms 27 | 28 | //Define matrix 29 | #define KEYPADS 2 // intended in order to create a Multiple keypad split boards 30 | #define MATRIX_ROWS 6 31 | #define MATRIX_COLS 6 // For split keyboards, define columns for one side only. 32 | 33 | #define NKRO // does not work on Android and iOS!, we can get 18KRO on those 34 | #define LAYERS 3 // number of layers defined 35 | 36 | // Select diode direction 37 | #define COL2ROW 38 | //#define ROW2COL 39 | 40 | //Encoder definitions 41 | //#define R_ENCODER // undefine if no rotary encoder is used 42 | #define R_ENCODER_SLAVE // undefine if no rotary encoder is used on slave pad 43 | #define ENCODER_A_PIN GPIO_NUM_17 // encoder phase A pin 44 | #define ENCODER_B_PIN GPIO_NUM_34// encoder phase B pin 45 | #define ENCODER_S_PIN GPIO_NUM_16// encoder switch pin 46 | 47 | //OLED Parameters 48 | //#define OLED_ENABLE //undefine if no oled is used 49 | #define ROTATION DEG270 50 | #define OLED_SDA_PIN GPIO_NUM_21 51 | #define OLED_SCL_PIN GPIO_NUM_22 52 | 53 | /*Battery monitoring 54 | * Please read check battery_monitor.h for resistor values before applying 55 | * use ADC1 only, */ 56 | 57 | //#define BATT_STAT //define to enable battery monitoring 58 | #define BATT_PIN ADC1_CHANNEL_7 //gpio pin 35, refer to the esp32 before modifying 59 | 60 | //deep sleep parameters, mind that reconnecting after deep sleep might take a minute or two 61 | #define SLEEP_MINS 45 // undefine if you do not need deep sleep, otherwise define number of minutes for deepsleep 62 | 63 | /* 64 | *---------------------------- Everything below here should not be modified for standard usage---------------------- 65 | * 66 | * */ 67 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 68 | #define SET_BIT(var,pos) (var |= 1LLU << pos); 69 | 70 | #define MAX_LAYER (LAYERS-1) 71 | #define MOD_LED_BYTES 2 //bytes for led status and modifiers 72 | #define MACRO_LEN 3 //keys for macros 73 | #define KEYMAP_COLS MATRIX_COLS*KEYPADS // used for a symmetrical split keyboard 74 | #define REPORT_LEN (MOD_LED_BYTES+MACRO_LEN+MATRIX_ROWS*KEYMAP_COLS) //size of hid reports with NKRO and room for 3 key macro 75 | #define REPORT_COUNT_BYTES (MATRIX_ROWS*KEYMAP_COLS+MACRO_LEN) 76 | 77 | #define PLUGIN_BASE_VAL 0x135 78 | #define LAYER_HOLD_MAX_VAL 0x134 79 | #define LAYER_HOLD_BASE_VAL 0x123 80 | #define MACRO_BASE_VAL 0x103 81 | #define LAYERS_BASE_VAL 0xFF 82 | 83 | #define ENCODER_SIZE 4 84 | #define MEDIA_ENCODER 0 85 | #define MOUSE_ENCODER 1 86 | #define KEY_ENCODER 2 87 | 88 | typedef struct config_data { 89 | char bt_device_name[MAX_BT_DEVICENAME_LENGTH]; 90 | } config_data_t; 91 | 92 | extern uint8_t current_layout; 93 | extern uint8_t curr_led; 94 | 95 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 96 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 97 | 98 | #define MAX_LAYOUT_NAME_LENGTH 15 99 | // array to hold names of layouts for oled 100 | extern char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH]; 101 | 102 | extern TaskHandle_t xKeyreportTask; 103 | 104 | #endif 105 | // 106 | -------------------------------------------------------------------------------- /keyboards/letSplitIsh/keyboard_config.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_CONFIG_H 2 | #define KEYBOARD_CONFIG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "driver/gpio.h" 11 | #include "driver/touch_pad.h" 12 | #include "driver/adc.h" 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "freertos/event_groups.h" 16 | #include "oled_tasks.h" 17 | 18 | #define MODULE_ID "LOLIN 32" 19 | #define GATTS_TAG "MK32 V3.0" // The device's name 20 | #define MAX_BT_DEVICENAME_LENGTH 40 21 | 22 | #define MASTER // undefine if you are not flashing the main controller 23 | #define SPLIT_MASTER // undefine if keyboard is not split and master 24 | //#define SLAVE // undefine if keyboard is master 25 | 26 | #define DEBOUNCE 7 //debounce time in ms 27 | 28 | //Define matrix 29 | #define KEYPADS 2 // intended in order to create a Multiple keypad split boards 30 | #define MATRIX_ROWS 4 31 | #define MATRIX_COLS 6 // For split keyboards, define columns for one side only. 32 | 33 | #define LAYERS 3 // number of layers defined 34 | 35 | // Select diode direction 36 | #define COL2ROW 37 | //#define ROW2COL 38 | 39 | //Encoder definitions 40 | #define R_ENCODER // undefine if no rotary encoder is used 41 | //#define R_ENCODER_SLAVE // undefine if no rotary encoder is used on slave pad 42 | #define ENCODER_A_PIN GPIO_NUM_32 // encoder phase A pin 43 | #define ENCODER_B_PIN GPIO_NUM_33// encoder phase B pin 44 | #define ENCODER_S_PIN GPIO_NUM_27// encoder switch pin 45 | 46 | //OLED Parameters 47 | #define OLED_ENABLE //undefine if no oled is used 48 | #define ROTATION LANDSCAPE 49 | #define OLED_SDA_PIN GPIO_NUM_23 50 | #define OLED_SCL_PIN GPIO_NUM_22 51 | 52 | /*Battery monitoring 53 | * Please read check battery_monitor.h for resistor values before applying 54 | * use ADC1 only, */ 55 | 56 | #define BATT_STAT //define to enable battery monitoring 57 | #define BATT_PIN ADC1_CHANNEL_7 //gpio pin 35, refer to the esp32 before modifying 58 | 59 | //deep sleep parameters, mind that reconnecting after deep sleep might take a minute or two 60 | #define SLEEP_MINS 5 // undefine if you do not need deep sleep, otherwise define number of minutes for deepsleep 61 | 62 | /* 63 | *---------------------------- Everything below here should not be modified for standard usage---------------------- 64 | * 65 | * */ 66 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 67 | #define SET_BIT(var,pos) (var |= 1UL << pos); 68 | 69 | #define MAX_LAYER (LAYERS-1) 70 | #define MOD_LED_BYTES 2 //bytes for led status and modifiers 71 | #define MACRO_LEN 3 //keys for macros 72 | #define KEYMAP_COLS MATRIX_COLS*KEYPADS // used for a symmetrical split keyboard 73 | #define REPORT_LEN (MOD_LED_BYTES+MACRO_LEN+MATRIX_ROWS*KEYMAP_COLS) //size of hid reports with NKRO and room for 3 key macro 74 | #define REPORT_COUNT_BYTES (MATRIX_ROWS*KEYMAP_COLS+MACRO_LEN) 75 | 76 | #define PLUGIN_BASE_VAL 0x135 77 | #define LAYER_HOLD_MAX_VAL 0x134 78 | #define LAYER_HOLD_BASE_VAL 0x123 79 | #define MACRO_BASE_VAL 0x103 80 | #define LAYERS_BASE_VAL 0xFF 81 | 82 | #define ENCODER_SIZE 4 83 | #define MEDIA_ENCODER 0 84 | #define MOUSE_ENCODER 1 85 | #define KEY_ENCODER 2 86 | 87 | typedef struct config_data { 88 | char bt_device_name[MAX_BT_DEVICENAME_LENGTH]; 89 | } config_data_t; 90 | 91 | extern uint8_t current_layout; 92 | extern uint8_t curr_led; 93 | 94 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 95 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 96 | 97 | #define MAX_LAYOUT_NAME_LENGTH 15 98 | // array to hold names of layouts for oled 99 | extern char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH]; 100 | 101 | extern TaskHandle_t xKeyreportTask; 102 | 103 | #endif 104 | // 105 | -------------------------------------------------------------------------------- /keyboards/letSplitIsh/keymap.c: -------------------------------------------------------------------------------- 1 | #ifndef KEYMAP_C 2 | #define KEYMAP_C 3 | 4 | #include "key_definitions.h" 5 | #include "keyboard_config.h" 6 | #include "keymap.h" 7 | #include "plugins.h" 8 | 9 | // A bit different from QMK, default returns you to the first layer, LOWER and raise increase/lower layer by order. 10 | #define DEFAULT 0x100 11 | #define LOWER 0x101 12 | #define RAISE 0x102 13 | 14 | // Keymaps are designed to be relatively interchangeable with QMK 15 | enum custom_keycodes { 16 | QWERTY, NUM, 17 | PLUGINS, 18 | }; 19 | 20 | //Set these for each layer and use when layers are needed in a hold-to use layer 21 | enum layer_holds { 22 | QWERTY_H = LAYER_HOLD_BASE_VAL, NUM_H,FUNCS_H 23 | }; 24 | 25 | // array to hold names of layouts for oled 26 | char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH] = { "QWERTY", "NUM", 27 | "Plugins", 28 | }; 29 | 30 | /* select a keycode for your macro 31 | * important - first macro must be initialized as MACRO_BASE_VAL 32 | * */ 33 | 34 | #define MACROS_NUM 2 35 | enum custom_macros { 36 | KC_CTRL_ALT_DELETE = MACRO_BASE_VAL, KC_ALT_F4, 37 | }; 38 | 39 | /*define what the macros do 40 | * important- make sure you you put the macros in the same order as the their enumeration 41 | */ 42 | uint16_t macros[MACROS_NUM][MACRO_LEN] = { 43 | // CTRL+ALT+DEL 44 | { KC_LCTRL, KC_LALT, KC_DEL }, 45 | //ALT +F4 46 | { KC_RALT, KC_LALT, KC_NO } }; 47 | 48 | /*Encoder keys for each layer by order, and for each pad 49 | * First variable states what usage the encoder has 50 | */ 51 | 52 | uint16_t default_encoder_map[LAYERS][ENCODER_SIZE] = { 53 | // |VOL + | VOL - | MUTE | 54 | { MEDIA_ENCODER, KC_AUDIO_VOL_UP, KC_AUDIO_VOL_DOWN, KC_AUDIO_MUTE }, 55 | // |Y+|Y-| LEFT CLICK| 56 | { MOUSE_ENCODER, KC_MS_UP, KC_MS_DOWN, KC_MS_BTN1 }, 57 | 58 | { MOUSE_ENCODER, KC_MS_UP, KC_MS_DOWN, KC_MS_BTN1 } }; 59 | 60 | uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE] = { 61 | // |VOL + | VOL - | MUTE | 62 | { MEDIA_ENCODER, KC_AUDIO_VOL_UP, KC_AUDIO_VOL_DOWN, KC_AUDIO_MUTE }, 63 | // |Y+|Y-| LEFT CLICK| 64 | { MOUSE_ENCODER, KC_MS_RIGHT, KC_MS_LEFT, KC_MS_BTN2 }, 65 | // |Y+|Y-| LEFT CLICK| 66 | { MOUSE_ENCODER, KC_MS_RIGHT, KC_MS_LEFT, KC_MS_BTN2 } }; 67 | 68 | // Fillers to make layering more clear 69 | #define _______ KC_TRNS 70 | #define XXXXXXX KC_NO 71 | 72 | // Each keymap is represented by an array, with an array that points to all the keymaps by order 73 | uint16_t _QWERTY[MATRIX_ROWS][KEYMAP_COLS]={ 74 | 75 | /* Qwerty 76 | * ,------------------------------------------------------------------------------------. 77 | * | Esc | Q | W | E | R | T | Y | U | I | O | P | Bksp | 78 | * |------+------+------+-------+------+-------------+------+------+------+------+------| 79 | * | Tab | A | S | D | F | G | H | J | K | L | ; | ' | 80 | * |------+------+------+-------+------+------|------+------+------+------+------+------| 81 | * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | 82 | * |------+------+------+-------+------+------+------+------+------+------+------+------| 83 | * | Ctrl | GUI | Alt |Default|Lower |Space |Space |Raise | Left | Down | Up |Right | 84 | * `------------------------------------------------------------------------------------' 85 | */ 86 | 87 | {KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC }, 88 | {KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT }, 89 | {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT } , 90 | {KC_LCTRL,KC_LGUI, KC_LALT, DEFAULT, NUM_H, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT } 91 | 92 | }; 93 | 94 | uint16_t _NUM[MATRIX_ROWS][KEYMAP_COLS]={ 95 | 96 | /* Nums 97 | * ,-----------------------------------------------------------------------------------. 98 | * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp | 99 | * |------+------+------+------+------+-------------+------+------+------+------+------| 100 | * | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | 101 | * |------+------+------+------+------+------|------+------+------+------+------+------| 102 | * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |Pg Up |Pg Dn | | 103 | * |------+------+------+------+------+------+------+------+------+------+------+------| 104 | * | | | | | | | | | | | | 105 | * `-----------------------------------------------------------------------------------' 106 | */ 107 | 108 | {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC }, 109 | {KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS }, 110 | {KC_LSFT, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGUP, KC_PGDN, KC_ENT } , 111 | {KC_LCTRL,KC_LGUI, KC_LALT, DEFAULT, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT } 112 | 113 | }; 114 | 115 | uint16_t _PLUGINS[MATRIX_ROWS][KEYMAP_COLS]={ 116 | 117 | /* PLUGINS 118 | * -----------------------------------------------------------------------------------------' 119 | */ 120 | 121 | {PN_CLOSE,PN_LAYOUT,PN_TEST, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC }, 122 | {KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT }, 123 | {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT } , 124 | {KC_LCTRL,KC_LGUI, KC_LALT, DEFAULT, NUM_H, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT } 125 | 126 | }; 127 | //Create an array that points to the various keymaps 128 | uint16_t (*default_layouts[])[MATRIX_ROWS][KEYMAP_COLS] = { &_QWERTY, &_NUM, 129 | &_PLUGINS 130 | }; 131 | 132 | uint8_t current_layout = 0; 133 | 134 | #endif 135 | 136 | -------------------------------------------------------------------------------- /keyboards/x32k/keyboard_config.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_CONFIG_H 2 | #define KEYBOARD_CONFIG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "driver/gpio.h" 11 | #include "driver/touch_pad.h" 12 | #include "driver/adc.h" 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "freertos/event_groups.h" 16 | #include "oled_tasks.h" 17 | 18 | #define MODULE_ID "LOLIN 32" 19 | #define GATTS_TAG "MK32 V3.0" // The device's name 20 | #define MAX_BT_DEVICENAME_LENGTH 40 21 | 22 | #define MASTER // undefine if you are not flashing the main controller 23 | #define SPLIT_MASTER // undefine if keyboard is not split and master 24 | //#define SLAVE // undefine if keyboard is master 25 | 26 | #define DEBOUNCE 7 //debounce time in ms 27 | 28 | //Define matrix 29 | #define KEYPADS 2 // intended in order to create a Multiple keypad split boards 30 | #define MATRIX_ROWS 6 31 | #define MATRIX_COLS 6 // For split keyboards, define columns for one side only. 32 | 33 | #define LAYERS 3 // number of layers defined 34 | 35 | // Select diode direction 36 | #define COL2ROW 37 | //#define ROW2COL 38 | 39 | //Encoder definitions 40 | #define R_ENCODER // undefine if no rotary encoder is used 41 | //#define R_ENCODER_SLAVE // undefine if no rotary encoder is used on slave pad 42 | #define ENCODER_A_PIN GPIO_NUM_17 // encoder phase A pin 43 | #define ENCODER_B_PIN GPIO_NUM_34// encoder phase B pin 44 | #define ENCODER_S_PIN GPIO_NUM_16// encoder switch pin 45 | 46 | //OLED Parameters 47 | //#define OLED_ENABLE //undefine if no oled is used 48 | #define ROTATION DEG90 49 | #define OLED_SDA_PIN GPIO_NUM_21 50 | #define OLED_SCL_PIN GPIO_NUM_22 51 | 52 | /*Battery monitoring 53 | * Please read check battery_monitor.h for resistor values before applying 54 | * use ADC1 only, */ 55 | 56 | #define BATT_STAT //define to enable battery monitoring 57 | #define BATT_PIN ADC1_CHANNEL_7 //gpio pin 35, refer to the esp32 before modifying 58 | 59 | //deep sleep parameters, mind that reconnecting after deep sleep might take a minute or two 60 | #define SLEEP_MINS 5 // undefine if you do not need deep sleep, otherwise define number of minutes for deepsleep 61 | 62 | /* 63 | *---------------------------- Everything below here should not be modified for standard usage---------------------- 64 | * 65 | * */ 66 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 67 | #define SET_BIT(var,pos) (var |= 1UL << pos); 68 | 69 | #define MAX_LAYER (LAYERS-1) 70 | #define MOD_LED_BYTES 2 //bytes for led status and modifiers 71 | #define MACRO_LEN 3 //keys for macros 72 | #define KEYMAP_COLS MATRIX_COLS*KEYPADS // used for a symmetrical split keyboard 73 | #define REPORT_LEN (MOD_LED_BYTES+MACRO_LEN+MATRIX_ROWS*KEYMAP_COLS) //size of hid reports with NKRO and room for 3 key macro 74 | #define REPORT_COUNT_BYTES (MATRIX_ROWS*KEYMAP_COLS+MACRO_LEN) 75 | 76 | #define PLUGIN_BASE_VAL 0x135 77 | #define LAYER_HOLD_MAX_VAL 0x134 78 | #define LAYER_HOLD_BASE_VAL 0x123 79 | #define MACRO_BASE_VAL 0x103 80 | #define LAYERS_BASE_VAL 0xFF 81 | 82 | #define ENCODER_SIZE 4 83 | #define MEDIA_ENCODER 0 84 | #define MOUSE_ENCODER 1 85 | #define KEY_ENCODER 2 86 | 87 | typedef struct config_data { 88 | char bt_device_name[MAX_BT_DEVICENAME_LENGTH]; 89 | } config_data_t; 90 | 91 | extern uint8_t current_layout; 92 | extern uint8_t curr_led; 93 | 94 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 95 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 96 | 97 | #define MAX_LAYOUT_NAME_LENGTH 15 98 | // array to hold names of layouts for oled 99 | extern char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH]; 100 | 101 | extern TaskHandle_t xKeyreportTask; 102 | 103 | #endif 104 | // 105 | -------------------------------------------------------------------------------- /keyboards/x32k/keymap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * keymap.h 3 | * 4 | * Created on: 20 Sep 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef MAIN_KEYMAP_H_ 9 | #define MAIN_KEYMAP_H_ 10 | 11 | #include "keyboard_config.h" 12 | 13 | extern uint16_t (*default_layouts[])[MATRIX_ROWS][KEYMAP_COLS]; 14 | 15 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 16 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 17 | 18 | #endif /* MAIN_KEYMAP_H_ */ 19 | -------------------------------------------------------------------------------- /keyboards/x32k/matrix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix.h 3 | * 4 | * Created on: 6 Oct 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef MATRIX_H_ 9 | #define MATRIX_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "keyboard_config.h" 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | extern uint8_t MATRIX_STATE[MATRIX_ROWS][MATRIX_COLS]; 23 | extern uint8_t SLAVE_MATRIX_STATE[MATRIX_ROWS][MATRIX_COLS]; 24 | extern uint8_t (*matrix_states[])[MATRIX_ROWS][MATRIX_COLS]; 25 | 26 | /* 27 | * @brief deinitialize rtc pins 28 | */ 29 | void rtc_matrix_deinit(void); 30 | 31 | /* 32 | * @brief initialize rtc pins 33 | */ 34 | void rtc_matrix_setup(void); 35 | 36 | /* 37 | * @brief initialize matrix 38 | */ 39 | void matrix_setup(void); 40 | 41 | /* 42 | * @brief scan matrix 43 | */ 44 | void scan_matrix(void); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | #endif /* MATRIX_H_ */ 50 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "mk32_main.cpp" "keymap.c" "matrix.c" "keypress_handles.c" 2 | INCLUDE_DIRS "." 3 | REQUIRES "battery" "ble" "oled" "nvsfuncs" "plugins" "espnowmk32" "rotencoder") 4 | -------------------------------------------------------------------------------- /main/keyboard_config.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_CONFIG_H 2 | #define KEYBOARD_CONFIG_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "driver/gpio.h" 11 | #include "driver/touch_pad.h" 12 | #include "driver/adc.h" 13 | #include "freertos/FreeRTOS.h" 14 | #include "freertos/task.h" 15 | #include "freertos/event_groups.h" 16 | #include "oled_tasks.h" 17 | 18 | #define MODULE_ID "LOLIN 32" 19 | #define GATTS_TAG "MK32 V3.0" // The device's name 20 | #define MAX_BT_DEVICENAME_LENGTH 40 21 | 22 | #define MASTER // undefine if you are not flashing the main controller 23 | #define SPLIT_MASTER // undefine if keyboard is not split and master 24 | //#define SLAVE // undefine if keyboard is master 25 | 26 | #define DEBOUNCE 4 //debounce time in ms 27 | 28 | //Define matrix 29 | #define KEYPADS 2 // intended in order to create a Multiple keypad split boards 30 | #define MATRIX_ROWS 6 31 | #define MATRIX_COLS 6 // For split keyboards, define columns for one side only. 32 | 33 | #define NKRO // does not work on Android and iOS!, we can get 18KRO on those 34 | #define LAYERS 3 // number of layers defined 35 | 36 | // Select diode direction 37 | #define COL2ROW 38 | //#define ROW2COL 39 | 40 | //Encoder definitions 41 | //#define R_ENCODER // undefine if no rotary encoder is used 42 | #define R_ENCODER_SLAVE // undefine if no rotary encoder is used on slave pad 43 | #define ENCODER_A_PIN GPIO_NUM_17 // encoder phase A pin 44 | #define ENCODER_B_PIN GPIO_NUM_34// encoder phase B pin 45 | #define ENCODER_S_PIN GPIO_NUM_16// encoder switch pin 46 | 47 | //OLED Parameters 48 | //#define OLED_ENABLE //undefine if no oled is used 49 | #define ROTATION DEG270 50 | #define OLED_SDA_PIN GPIO_NUM_21 51 | #define OLED_SCL_PIN GPIO_NUM_22 52 | 53 | /*Battery monitoring 54 | * Please read check battery_monitor.h for resistor values before applying 55 | * use ADC1 only, */ 56 | 57 | //#define BATT_STAT //define to enable battery monitoring 58 | #define BATT_PIN ADC1_CHANNEL_7 //gpio pin 35, refer to the esp32 before modifying 59 | 60 | //deep sleep parameters, mind that reconnecting after deep sleep might take a minute or two 61 | #define SLEEP_MINS 45 // undefine if you do not need deep sleep, otherwise define number of minutes for deepsleep 62 | 63 | /* 64 | *---------------------------- Everything below here should not be modified for standard usage---------------------- 65 | * 66 | * */ 67 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 68 | #define SET_BIT(var,pos) (var |= 1LLU << pos); 69 | 70 | #define MAX_LAYER (LAYERS-1) 71 | #define MOD_LED_BYTES 2 //bytes for led status and modifiers 72 | #define MACRO_LEN 3 //keys for macros 73 | #define KEYMAP_COLS MATRIX_COLS*KEYPADS // used for a symmetrical split keyboard 74 | #define REPORT_LEN (MOD_LED_BYTES+MACRO_LEN+MATRIX_ROWS*KEYMAP_COLS) //size of hid reports with NKRO and room for 3 key macro 75 | #define REPORT_COUNT_BYTES (MATRIX_ROWS*KEYMAP_COLS+MACRO_LEN) 76 | 77 | #define PLUGIN_BASE_VAL 0x135 78 | #define LAYER_HOLD_MAX_VAL 0x134 79 | #define LAYER_HOLD_BASE_VAL 0x123 80 | #define MACRO_BASE_VAL 0x103 81 | #define LAYERS_BASE_VAL 0xFF 82 | 83 | #define ENCODER_SIZE 4 84 | #define MEDIA_ENCODER 0 85 | #define MOUSE_ENCODER 1 86 | #define KEY_ENCODER 2 87 | 88 | typedef struct config_data { 89 | char bt_device_name[MAX_BT_DEVICENAME_LENGTH]; 90 | } config_data_t; 91 | 92 | extern uint8_t current_layout; 93 | extern uint8_t curr_led; 94 | 95 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 96 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 97 | 98 | #define MAX_LAYOUT_NAME_LENGTH 15 99 | // array to hold names of layouts for oled 100 | extern char default_layout_names[LAYERS][MAX_LAYOUT_NAME_LENGTH]; 101 | 102 | extern TaskHandle_t xKeyreportTask; 103 | 104 | #endif 105 | // 106 | -------------------------------------------------------------------------------- /main/keymap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * keymap.h 3 | * 4 | * Created on: 20 Sep 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef MAIN_KEYMAP_H_ 9 | #define MAIN_KEYMAP_H_ 10 | 11 | #include "keyboard_config.h" 12 | 13 | extern uint16_t (*default_layouts[])[MATRIX_ROWS][KEYMAP_COLS]; 14 | 15 | extern uint16_t default_encoder_map[LAYERS][ENCODER_SIZE]; 16 | extern uint16_t default_slave_encoder_map[LAYERS][ENCODER_SIZE]; 17 | 18 | #endif /* MAIN_KEYMAP_H_ */ 19 | -------------------------------------------------------------------------------- /main/matrix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix.h 3 | * 4 | * Created on: 6 Oct 2018 5 | * Author: gal 6 | */ 7 | 8 | #ifndef MATRIX_H_ 9 | #define MATRIX_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "keyboard_config.h" 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | extern uint8_t MATRIX_STATE[MATRIX_ROWS][MATRIX_COLS]; 23 | extern uint8_t SLAVE_MATRIX_STATE[MATRIX_ROWS][MATRIX_COLS]; 24 | extern uint8_t (*matrix_states[])[MATRIX_ROWS][MATRIX_COLS]; 25 | 26 | /* 27 | * @brief deinitialize rtc pins 28 | */ 29 | void rtc_matrix_deinit(void); 30 | 31 | /* 32 | * @brief initialize rtc pins 33 | */ 34 | void rtc_matrix_setup(void); 35 | 36 | /* 37 | * @brief initialize matrix 38 | */ 39 | void matrix_setup(void); 40 | 41 | /* 42 | * @brief scan matrix 43 | */ 44 | void scan_matrix(void); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | #endif /* MATRIX_H_ */ 50 | -------------------------------------------------------------------------------- /partitions.csv: -------------------------------------------------------------------------------- 1 | # Espressif ESP32 Partition Table,,,, 2 | # Name, Type, SubType, Offset, Size 3 | nvs, data, nvs, 0x9000, 0x4000 4 | otadata, data, ota, 0xd000, 0x2000 5 | phy_init, data, phy, 0xf000, 0x1000 6 | factory, 0, 0, 0x10000, 3M 7 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | docker run --rm -i -t --privileged mk32:latest /bin/bash 4 | --------------------------------------------------------------------------------