diff --git a/arduino_tests/BlueMicro840_BLE_hid_keyboard_tester/BlueMicro840_BLE_hid_keyboard_tester.ino b/arduino_tests/BlueMicro840_BLE_hid_keyboard_tester/BlueMicro840_BLE_hid_keyboard_tester.ino deleted file mode 100644 index 2c6b8ba1..00000000 --- a/arduino_tests/BlueMicro840_BLE_hid_keyboard_tester/BlueMicro840_BLE_hid_keyboard_tester.ino +++ /dev/null @@ -1,215 +0,0 @@ -// select the following board: "Nordic nRF52840DK (PCA10056)" -// select the programmer "Bootloader DFU for Bluefruit nrf52" -// double-reset the BlueMicro840 -// Select the serial port shown in Tools -> Port -// compile and upload -// once flashed, disconnect and reconnect the USB cable. -// the board should now show up as a USB keyboard -// go to the following website to test it -// https://config.qmk.fm/#/test -// using a wire, ground each GPIO, one pin at a time and see if a key is "pressed" -#include - -BLEDis bledis; -BLEHidAdafruit blehid; - - #define D3 6 - #define D2 8 - #define D1 15 - #define D0 17 - #define D4 20 - #define C6 13 - #define D7 24 - #define E6 9 - #define B4 10 - #define B5 38 //1.06 = 32+6 - - #define F4 30 - #define F5 26 - #define F6 29 - #define F7 2 - #define B1 45 //1.13 = 32+13 - #define B3 3 - #define B2 28 - #define B6 43 //1.11 = 32+11 - #define BLUE_LED 32+10 - #define RED_LED 32+4 - #define LED_RED 32+4 - -// Array of pins and its keycode -// For keycode definition see BLEHidGeneric.h -uint8_t pins[] = { D3, D2, D1, D0, D4, C6, D7, E6, B4, B5, F4, F5, F6, F7, B1, B3, B2, B6 }; -uint8_t hidcode[] = { HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3, HID_KEY_4, HID_KEY_5, HID_KEY_6, HID_KEY_7, HID_KEY_8, HID_KEY_9, HID_KEY_A, HID_KEY_B, HID_KEY_C, HID_KEY_D, HID_KEY_E, HID_KEY_F, HID_KEY_G, HID_KEY_H}; - -uint8_t pincount = sizeof(pins)/sizeof(pins[0]); - -// Modifier keys, only take cares of Shift -// ATL, CTRL, CMD keys are left for user excersie. -uint8_t shiftPin = 11; - -bool keyPressedPreviously = false; - -void setup() -{ - Serial.begin(115200); - //while ( !Serial ) delay(10); // for nrf52840 with native usb - - Serial.println("Bluefruit52 HID Keyscan Example"); - Serial.println("-------------------------------\n"); - - Serial.println(); - Serial.println("Go to your phone's Bluetooth settings to pair your device"); - Serial.println("then open an application that accepts keyboard input"); - - Serial.println(); - Serial.println("Wire configured Pin to GND to send key"); - Serial.println("Wire Shift Keky to GND if you want to send it in upper case"); - Serial.println(); - - Bluefruit.begin(); - Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); - - // Configure and Start Device Information Service - bledis.setManufacturer("Adafruit Industries"); - bledis.setModel("Bluefruit Feather 52"); - bledis.begin(); - - // set up pin as input - for (uint8_t i=0; i= 20m - * ( The smaller the connection interval the faster we could send data). - * However for HID and MIDI device, Apple could accept min connection interval - * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max - * connection interval to 11.25 ms and 15 ms respectively for best performance. - */ - blehid.begin(); - - // Set callback for set LED from central - blehid.setKeyboardLedCallback(set_keyboard_led); - - /* Set connection interval (min, max) to your perferred value. - * Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms - * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms - */ - /* Bluefruit.Periph.setConnInterval(9, 12); */ - - // Set up and start advertising - startAdv(); -} - -void startAdv(void) -{ - // Advertising packet - Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); - Bluefruit.Advertising.addTxPower(); - Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD); - - // Include BLE HID service - Bluefruit.Advertising.addService(blehid); - - // There is enough room for the dev name in the advertising packet - Bluefruit.Advertising.addName(); - - /* Start Advertising - * - Enable auto advertising if disconnected - * - Interval: fast mode = 20 ms, slow mode = 152.5 ms - * - Timeout for fast mode is 30 seconds - * - Start(timeout) with timeout = 0 will advertise forever (until connected) - * - * For recommended advertising interval - * https://developer.apple.com/library/content/qa/qa1931/_index.html - */ - Bluefruit.Advertising.restartOnDisconnect(true); - Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms - Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode - Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds -} - -void loop() -{ - /*-------------- Scan Pin Array and send report ---------------------*/ - bool anyKeyPressed = false; - - uint8_t modifier = 0; - uint8_t count=0; - uint8_t keycode[6] = { 0 }; - - // scan modifier key (only SHIFT), user implement ATL, CTRL, CMD if needed - if ( 0 == digitalRead(shiftPin) ) - { - modifier |= KEYBOARD_MODIFIER_LEFTSHIFT; - } - - // scan normal key and send report - for(uint8_t i=0; i < pincount; i++) - { - if ( 0 == digitalRead(pins[i]) ) - { - // if pin is active (low), add its hid code to key report - keycode[count++] = hidcode[i]; - - // 6 is max keycode per report - if ( count == 6) - { - blehid.keyboardReport(modifier, keycode); - - // reset report - count = 0; - memset(keycode, 0, 6); - } - - // used later - anyKeyPressed = true; - keyPressedPreviously = true; - } - } - - // Send any remaining keys (not accumulated up to 6) - if ( count ) - { - blehid.keyboardReport(modifier, keycode); - } - - // Send All-zero report to indicate there is no keys pressed - // Most of the time, it is, though we don't need to send zero report - // every loop(), only a key is pressed in previous loop() - if ( !anyKeyPressed && keyPressedPreviously ) - { - keyPressedPreviously = false; - blehid.keyRelease(); - } - - // Poll interval - delay(10); -} - -/** - * Callback invoked when received Set LED from central. - * Must be set previously with setKeyboardLedCallback() - * - * The LED bit map is as follows: (also defined by KEYBOARD_LED_* ) - * Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) - */ -void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap) -{ - (void) conn_handle; - - // light up Red Led if any bits is set - if ( led_bitmap ) - { - ledOn( LED_RED ); - } - else - { - ledOff( LED_RED ); - } -} diff --git a/arduino_tests/BlueMicro840_USB_hid_keyboard_tester/BlueMicro840_USB_hid_keyboard_tester.ino b/arduino_tests/BlueMicro840_USB_hid_keyboard_tester/BlueMicro840_USB_hid_keyboard_tester.ino deleted file mode 100644 index c1beb8bf..00000000 --- a/arduino_tests/BlueMicro840_USB_hid_keyboard_tester/BlueMicro840_USB_hid_keyboard_tester.ino +++ /dev/null @@ -1,155 +0,0 @@ -// make sure you get the Adafruit TinyUSB Library. -// to install the Adafruit TinyUSB Library, to to Tools -> Manage Libraries... and search for TinyUSB - -// select the following board: "Nordic nRF52840DK (PCA10056)" -// select the programmer "Bootloader DFU for Bluefruit nrf52" -// double-reset the BlueMicro840 -// Select the serial port shown in Tools -> Port -// compile and upload -// once flashed, disconnect and reconnect the USB cable. -// the board should now show up as a USB keyboard -// go to the following website to test it -// https://config.qmk.fm/#/test -// using a wire, ground each GPIO, one pin at a time and see if a key is "pressed" - - - -#include "Adafruit_TinyUSB.h" - -// HID report descriptor using TinyUSB's template -// Single Report (no ID) descriptor -uint8_t const desc_hid_report[] = -{ - TUD_HID_REPORT_DESC_KEYBOARD(), -}; - -Adafruit_USBD_HID usb_hid; - #define D3 6 - #define D2 8 - #define D1 15 - #define D0 17 - #define D4 20 - #define C6 13 - #define D7 24 - #define E6 9 - #define B4 10 - #define B5 38 //1.06 = 32+6 - - #define F4 30 - #define F5 26 - #define F6 29 - #define F7 2 - #define B1 45 //1.13 = 32+13 - #define B3 3 - #define B2 28 - #define B6 43 //1.11 = 32+11 - #define BLUE_LED 32+10 - #define RED_LED 32+4 - #define LED_RED 32+4 - -// Array of pins and its keycode -// For keycode definition see BLEHidGeneric.h -uint8_t pins[] = { D3, D2, D1, D0, D4, C6, D7, E6, B4, B5, F4, F5, F6, F7, B1, B3, B2, B6 }; -uint8_t hidcode[] = { HID_KEY_0, HID_KEY_1, HID_KEY_2, HID_KEY_3, HID_KEY_4, HID_KEY_5, HID_KEY_6, HID_KEY_7, HID_KEY_8, HID_KEY_9, HID_KEY_A, HID_KEY_B, HID_KEY_C, HID_KEY_D, HID_KEY_E, HID_KEY_F, HID_KEY_G, HID_KEY_H}; - -uint8_t pincount = sizeof(pins)/sizeof(pins[0]); - -// the setup function runs once when you press reset or power the board -void setup() -{ - usb_hid.setPollInterval(2); - usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report)); - usb_hid.setReportCallback(NULL, hid_report_callback); - - usb_hid.begin(); - - // led pin - pinMode(RED_LED, OUTPUT); - digitalWrite(RED_LED, LOW); - - // Set up pin as input - for (uint8_t i=0; i -#include - - // This array cannot be allocated on stack (hence "static") and it must - // be in RAM. -static uint32_t m_buffer_tx[I2S_BUFFER_SIZE]; - - -void setuprgb(void) -{ - //Serial.println("setuprgb"); - NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos); // Enable transmission - NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos); // Enable MCK generator - NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos; // MCKFREQ = 3.2 MHz - NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_32X << I2S_CONFIG_RATIO_RATIO_Pos; // Ratio = 32 - NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos; // Master mode, 16Bit, left aligned - NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos; - NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_LEFT << I2S_CONFIG_ALIGN_ALIGN_Pos; - NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S << I2S_CONFIG_FORMAT_FORMAT_Pos; // Format = I2S - NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_STEREO << I2S_CONFIG_CHANNELS_CHANNELS_Pos; // Use stereo - - - NRF_I2S->PSEL.MCK = 0xFF;//(PIN_MCK << I2S_PSEL_MCK_PIN_Pos)| (I2S_PSEL_MCK_CONNECT_Disconnected << I2S_PSEL_MCK_CONNECT_Pos); // Configure pins // - NRF_I2S->PSEL.SCK = (PIN_SCK << I2S_PSEL_SCK_PIN_Pos)| (I2S_PSEL_SCK_CONNECT_Connected << I2S_PSEL_SCK_CONNECT_Pos); /// must be connected - however we don't need it for RGB LEDs. recommend using p0.23 when we have these pins unused - NRF_I2S->PSEL.LRCK = (PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos)| (I2S_PSEL_LRCK_CONNECT_Connected << I2S_PSEL_LRCK_CONNECT_Pos); /// must be connected - however we don't need it for RGB LEDs. recommend using p0.24 when we have these pins unused - NRF_I2S->PSEL.SDOUT = (PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos)| (I2S_PSEL_SDOUT_CONNECT_Connected << I2S_PSEL_SDOUT_CONNECT_Pos); /// must be connected - this is the data line for the RGB LEDs - NRF_I2S->INTENSET = I2S_INTENSET_TXPTRUPD_Msk; - NRF_I2S->ENABLE = 0; - // NVIC_ClearPendingIRQ(I2S_IRQn); - - // NVIC_EnableIRQ(I2S_IRQn); - - - // Since we are not updating the TXD pointer, the sine wave will play over and over again. - // The TXD pointer can be updated after the EVENTS_TXPTRUPD arrives. -} - - - -void set_led_data(uint8_t rval,uint8_t gval,uint8_t bval) -{ - //Serial.println(val); - for(int i = 0; i < 3*NLEDS; i += 3) { - m_buffer_tx[i] = calcChannelValue(gval);; - m_buffer_tx[i+1] = calcChannelValue(rval); - m_buffer_tx[i+2] = calcChannelValue(bval); - - } - - // reset - m_buffer_tx[3*NLEDS] = 0; - m_buffer_tx[3*NLEDS+1] = 0; - m_buffer_tx[3*NLEDS+2] = 0; - m_buffer_tx[3*NLEDS+3] = 0; - m_buffer_tx[3*NLEDS+4] = 0; - m_buffer_tx[3*NLEDS+5] = 0; - m_buffer_tx[3*NLEDS+6] = 0; - m_buffer_tx[3*NLEDS+7] = 0; - m_buffer_tx[3*NLEDS+8] = 0; - m_buffer_tx[3*NLEDS+9] = 0; - m_buffer_tx[3*NLEDS+10] = 0; - m_buffer_tx[3*NLEDS+11] = 0; - -} - -void copy_led_data(rgb_led_t values[]) -{ - for(int i = 0; i < NLEDS; i++) { - m_buffer_tx[i*3] = values[i].green; - m_buffer_tx[i*3+1] = values[i].red; - m_buffer_tx[i*3+2] = values[i].blue; - } - - // reset - m_buffer_tx[3*NLEDS] = 0; - m_buffer_tx[3*NLEDS+1] = 0; - m_buffer_tx[3*NLEDS+2] = 0; - m_buffer_tx[3*NLEDS+3] = 0; - m_buffer_tx[3*NLEDS+4] = 0; - m_buffer_tx[3*NLEDS+5] = 0; - m_buffer_tx[3*NLEDS+6] = 0; - m_buffer_tx[3*NLEDS+7] = 0; - m_buffer_tx[3*NLEDS+8] = 0; - m_buffer_tx[3*NLEDS+9] = 0; - m_buffer_tx[3*NLEDS+10] = 0; - m_buffer_tx[3*NLEDS+11] = 0; - -} - -uint32_t calcChannelValue(uint8_t level) -{ - uint32_t val = 0; - // 0 - if(level == 0) { - val = 0x88888888; - } - // 255 - else if (level == 255) { - val = 0xeeeeeeee; - } - else { - // apply 4-bit 0xe HIGH pattern wherever level bits are 1. - val = 0x88888888; - for (uint8_t i = 0; i < 8; i++) { - if((1 << i) & level) { - uint32_t mask = ~(0x0f << 4*i); - uint32_t patt = (0x0e << 4*i); - val = (val & mask) | patt; - } - } - // swap 16 bits - val = (val >> 16) | (val << 16); - } - - return val; -} - -bool rgbCheckStatus(void) { - bool status = NRF_I2S->ENABLE; - if (NRF_I2S->EVENTS_TXPTRUPD != 0) - { - NRF_I2S->EVENTS_TXPTRUPD = 0; - NRF_I2S->ENABLE = 0; - } - - return status; -} - -void rgbstart(void) -{ - // Configure data pointer - NRF_I2S->EVENTS_TXPTRUPD = 0; - NRF_I2S->EVENTS_RXPTRUPD = 0; - NRF_I2S->EVENTS_STOPPED = 0; - NRF_I2S->TXD.PTR = (uint32_t)&m_buffer_tx[0]; - NRF_I2S->RXTXD.MAXCNT = sizeof(m_buffer_tx) / sizeof(uint32_t); - NRF_I2S->ENABLE = 1; - NRF_I2S->TASKS_START = 1; // Start transmitting I2S data -} diff --git a/arduino_tests/I2S_tester/I2S.h b/arduino_tests/I2S_tester/I2S.h deleted file mode 100644 index fe1dbe30..00000000 --- a/arduino_tests/I2S_tester/I2S.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef I2S_H -#define I2S_H - -#include - -#define PIN_MCK (11) //MOSI = B2 // 24 = WS2812B -#define PIN_SCK (22) //MISO = B3 // 22 = factory reset -#define PIN_LRCK (20) // = B4 // 20 = DFU -#define PIN_SDOUT (24) // = B // 11 = COL10 - -#define NLEDS 1 -#define RESET_BITS 12 -#define I2S_BUFFER_SIZE 3*NLEDS + RESET_BITS - -//uint32_t m_buffer_tx[I2S_BUFFER_SIZE]; - -typedef struct -{ - uint8_t green; // Brightness of green (0 to 255) - uint8_t red; // Brightness of red (0 to 255) - uint8_t blue; // Brightness of blue (0 to 255) -} rgb_led_t; - -void setuprgb(void); -void rgbstart(void); -bool rgbCheckStatus(void) ; -uint32_t calcChannelValue(uint8_t level); - -void copy_led_data(rgb_led_t values[]); -void set_led_data(uint8_t rval,uint8_t gval,uint8_t bval); -void I2S_IRQHandler(void); - -#endif /* I2S_H */ diff --git a/arduino_tests/I2S_tester/I2S_tester.ino b/arduino_tests/I2S_tester/I2S_tester.ino deleted file mode 100644 index a154ded4..00000000 --- a/arduino_tests/I2S_tester/I2S_tester.ino +++ /dev/null @@ -1,136 +0,0 @@ -/********************************************************************* - This is an example for our nRF52 based Bluefruit LE modules - - Pick one up today in the adafruit shop! - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - MIT license, check LICENSE for more information - All text above, and the splash screen below must be included in - any redistribution -*********************************************************************/ - -#include -//#include "WS2812.h" -#include "I2S.h" - -uint8_t rgbval=0; - - -rgb_led_t led_array[NLEDS]; - - - - -/**************************************************************************************************************************/ -// Battery Service and functions -BLEBas blebas; - - -/**************************************************************************************************************************/ -// Start Advertizing Bluetooth Services -void startAdv(void) -{ - // Advertising packet - Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); - Bluefruit.Advertising.addTxPower(); - Bluefruit.ScanResponse.addName(); - Bluefruit.Advertising.restartOnDisconnect(true); - Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms - Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode - Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds -} - - -/**************************************************************************************************************************/ -// Connect Callback -void connect_callback(uint16_t conn_handle) -{ - //connection_state = STATE_CONNECTED; -} - - -/**************************************************************************************************************************/ -// Disconnect Callback -void disconnect_callback(uint16_t conn_handle, uint8_t reason) -{ - (void) conn_handle; - (void) reason; - -// connection_state = STATE_DISCONNECTED; -} - - -//********************************************************************************************// -void setup() -{ - -Serial.begin(115200); - // this code enables the NFC pins to be GPIO. - if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ - // Serial.println("Fix NFC pins"); - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy); - NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy); - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy); - //Serial.println("Done"); - delay(500); - - NVIC_SystemReset(); - } // end of NFC switch code. - - - - Bluefruit.begin(); - // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 - Bluefruit.setTxPower(4); - Bluefruit.setName("BlueMicroTester"); - Bluefruit.Periph.setConnectCallback(connect_callback); - Bluefruit.Periph.setDisconnectCallback(disconnect_callback); - - - // Configure and Start Battery Service - blebas.begin(); - blebas.write(100); // put the battery level at 100% - until it is updated by the battery monitoring loop. - - startAdv(); // Set up and start advertising - -Serial.println("setup setup rgb"); - setuprgb(); - -} - - - - - - -//********************************************************************************************// -//* Main Loop Task - runs Display updates *// -//********************************************************************************************// -void loop() -{ - //Serial.println("loop"); - if(!rgbCheckStatus()) - { - // Serial.println("update RGB"); - - for(int i = 0; i < NLEDS; i++) - { - led_array[i].red = rgbval; - led_array[i].green = rgbval; - led_array[i].blue = rgbval; - } - - copy_led_data(led_array); - rgbval=rgbval+1; - if (rgbval>128+64){rgbval=0;} - rgbstart(); - // delay(250); - } - -} diff --git a/arduino_tests/KB_Key_Tester/KB_Key_Tester.ino b/arduino_tests/KB_Key_Tester/KB_Key_Tester.ino index 03667960..9c76f89b 100644 --- a/arduino_tests/KB_Key_Tester/KB_Key_Tester.ino +++ b/arduino_tests/KB_Key_Tester/KB_Key_Tester.ino @@ -84,14 +84,18 @@ void matrix_key_end(bool singlekey) //************************************************************************* void matrix_key_test(bool singlekey) { - #ifdef NRF52840_XXAA - // below tests all nrf52840 GPIOs except 32kHz xtal and reset - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; - - #else - // below tests all nrf52832 GPIOs except 32kHz xtal and reset - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; - #endif +#ifdef NRF52840_XXAA + #ifdef ARDUINO_NICE_NANO + //Use this for nicenano - 14 and 16 are connected to 18 - reset line + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #else + // below tests all nrf52840 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #endif +#else + // below tests all nrf52832 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; +#endif uint8_t pincount = sizeof(pins)/sizeof(pins[0]); diff --git a/arduino_tests/KB_Matrix_Tester/KB_Matrix_Tester.ino b/arduino_tests/KB_Matrix_Tester/KB_Matrix_Tester.ino index 20d63a17..98788c7b 100644 --- a/arduino_tests/KB_Matrix_Tester/KB_Matrix_Tester.ino +++ b/arduino_tests/KB_Matrix_Tester/KB_Matrix_Tester.ino @@ -11,13 +11,16 @@ namespace std { } } #ifdef NRF52840_XXAA -// below tests all nrf52840 GPIOs except 32kHz xtal and reset -uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; -// Use this for nicenano (and comment the above line): -// uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #ifdef ARDUINO_NICE_NANO + //Use this for nicenano - 14 and 16 are connected to 18 - reset line + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #else + // below tests all nrf52840 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #endif #else -// below tests all nrf52832 GPIOs except 32kHz xtal and reset -uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; + // below tests all nrf52832 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; #endif uint8_t pincount = sizeof(pins)/sizeof(pins[0]); diff --git a/arduino_tests/SwEncoderCallback_encoderpad/SwEncoderCallback_encoderpad.ino b/arduino_tests/SwEncoderCallback_encoderpad/SwEncoderCallback_encoderpad.ino deleted file mode 100644 index 68e4c9d5..00000000 --- a/arduino_tests/SwEncoderCallback_encoderpad/SwEncoderCallback_encoderpad.ino +++ /dev/null @@ -1,64 +0,0 @@ -/********************************************************************* - This is an example for our nRF52 based Bluefruit LE modules - - Pick one up today in the adafruit shop! - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - MIT license, check LICENSE for more information - All text above, and the splash screen below must be included in - any redistribution -*********************************************************************/ - -#include -#include "RotaryEncoder.h" - -// 2021-01-23 - The encoder macropad with diodes and connected encoders at the A/B pins for multiplexing encoders doesn't work... - -#define PIN_A 26 //ROW 1 -#define PIN_B 25 //ROW 2 - -#define COL_1 29 -#define COL_2 30 -#define COL_3 2 -#define COL_4 3 - -SwRotaryEncoder swEncoder; - -void setup() -{ - Serial.begin(115200); - while ( !Serial ) delay(10); // for nrf52840 with native usb - - Serial.println("Bluefruit52 SW Rotary Encoder Callback Example"); - Serial.println("----------------------------------------------\n"); - - // Initialize Encoder - swEncoder.begin(PIN_A, PIN_B); - swEncoder.setCallback(encoder_callback); - pinMode(COL_1, OUTPUT); - digitalWrite(COL_1, LOW); - pinMode(COL_2, INPUT); - pinMode(COL_3, INPUT); - pinMode(COL_4, INPUT); -} - -void loop() -{ - // do nothing -} - -void encoder_callback(int step) -{ - if ( step > 0 ) - { - Serial.print(step); - Serial.println("Right"); - }else - { - Serial.print(step); - Serial.println("Left"); - } -} diff --git a/arduino_tests/WS2812.cpp b/arduino_tests/WS2812.cpp deleted file mode 100644 index d2a97c99..00000000 --- a/arduino_tests/WS2812.cpp +++ /dev/null @@ -1,270 +0,0 @@ - -//#include -//#include -//#include -#include -#include "WS2812.h" - -#define NLEDS 6 -/**************************************************************************************************************************/ -// WS2812B I2S Functions - -//volatile uint8_t i2s_ws2812b_drive_m_blocks_transferred = 0; -//volatile bool i2s_ws2812b_drive_flag_first_buffer = false; -//rgb_led_t *i2s_ws2812b_drive_tx_led_array; - - -/*void i2s_ws2812b_drive_set_buff(rgb_led_t * rgb_led, uint8_t *p_xfer, uint16_t xbuff_length) -{ - rgb_led_t* p_led = rgb_led; - int8_t offset = 1; - - for(uint16_t i_led=0;i_led<(xbuff_length/I2S_WS2812B_DRIVE_BUF_SIZE_PER_LED);i_led++) - { - uint32_t rgb_data = (p_led->green << 16) | (p_led->red << 8 ) | p_led->blue; - for(uint8_t i_rgb=0;i_rgbgreen = 0; - p->red = 0; - p->blue = 0; - p++; - } -} - -void ws2812b_drive_current_cap(rgb_led_t * led_array, uint16_t num_leds, uint32_t limit) -{ - uint32_t sum0 = ws2812b_drive_calc_current(led_array, num_leds); - if ( sum0 > limit ) { - // fact = (limit - num_leds) / (sum0 - num_leds); - int32_t factn = limit - num_leds; - if ( factn < 0 ) - { - factn = 1; - } - int32_t factd = sum0 - num_leds; - if ( factd < 0 ) - { - factd = 1; - } - - rgb_led_t * p = led_array; - rgb_led_t dnext; - for(uint16_t i=0;igreen * factn / factd; - dnext.red = p->red * factn / factd; - dnext.blue = p->blue * factn / factd; - - if ( dnext.green == 0 && p->green > 0 ) - { - dnext.green = 1; - } - if ( dnext.red == 0 && p->red > 0 ) - { - dnext.red = 1; - } - if ( dnext.blue == 0 && p->blue > 0 ) - { - dnext.blue = 1; - } - *p = dnext; - p++; - } // i - } -} - -uint32_t ws2812b_drive_calc_current(rgb_led_t * led_array, uint16_t num_leds) -{ - uint32_t sum = 0; - rgb_led_t * p = led_array; - for(uint16_t i=0;igreen + p->red + p->blue; - p++; - } - - return(num_leds + (sum*45)/(255*3)); // mA -} - -void ws2812b_drive_dim(rgb_led_t * led_array, uint16_t num_leds, float dim ) -{ - rgb_led_t * p = led_array; - for(uint16_t i=0;igreen *= dim; - p->red *= dim; - p->blue *= dim; - - p++; - } // i - -} -*/ -/**************************************************************************************************************************/ -// RGB Color Functions - -//static rgb_led_t [NLEDS] led_array_base; -/* -void flashing_random_init(rgb_led_t * led_array_base, uint16_t num_leds) -{ - - - // initialize led_array (base color array) - for(uint16_t i=0;i>2); - led_array_base[i].red = (MAX_INTENSE+MIN_INTENSE)/2 * ((c&2)>>1); - led_array_base[i].blue = (MAX_INTENSE+MIN_INTENSE)/2 * ((c&1)>>0); - } - - -} - - - -void flashing_random(rgb_led_t * led_array_out) -{ - int16_t nextc; - { - for(uint16_t i=0;i MAX_INTENSE ) - { - nextc = MAX_INTENSE; - } - led_array_out[i].green = nextc; - - nextc = led_array_out[i].red + rand()%3 -1; - if ( nextc < MIN_INTENSE ) - { - nextc = MIN_INTENSE; - } - - if ( nextc > MAX_INTENSE ) - { - nextc = MAX_INTENSE; - } - led_array_out[i].red = nextc; - - nextc = led_array_out[i].blue + rand()%3 -1; - if ( nextc < MIN_INTENSE ) - { - nextc = MIN_INTENSE; - } - - if ( nextc > MAX_INTENSE ) - { - nextc = MAX_INTENSE; - } - led_array_out[i].blue = nextc; - } - - } -}*/ diff --git a/arduino_tests/WS2812.h b/arduino_tests/WS2812.h deleted file mode 100644 index f98ada6e..00000000 --- a/arduino_tests/WS2812.h +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - -#define I2S_WS2812B_DRIVE_PATTERN_0 ((uint8_t)0x08) // Bit pattern for data "0" is "HLLL". -#define I2S_WS2812B_DRIVE_PATTERN_1 ((uint8_t)0x0e) // Bit pattern for data "1" is "HHHL". -#define I2S_WS2812B_DRIVE_BUF_SIZE_PER_LED (12) // buffer size for each LED (8bit * 4 * 3 ) - -#define NUM_LEDS (6) // Number of LEDs (LED総数) -#define MAX_INTENSE (64) // Max intense of random LEDs for "flashing_random" (flashing_random用のランダム色LEDの最大輝度) -#define MAX_INTENSE2 (255) // Max intense of "shooting start" running bright LEDs for all demos. -#define MAX_INTENSE3 (64) // Max intense of "rainbow LEDs" for "running_rainbow" and "running_rainbowv" demos. -#define MIN_INTENSE (1) // Minimum intense of randaom LEDs for "flashing_random" (flashing_random用のランダム色LEDの最小輝度) -#define ROW_SIZE (17) // Count of LEDs for each line (1巻き分のLEDの数) -#define CURRENT_LIMIT (1500) // Current limit of LEDs (mA) (総電流制限値) -#define FADE_IN_MS (6000) // Fade in/out period (フェードイン・アウトの秒数) - - - - -//void i2s_ws2812b_drive_set_buff(rgb_led_t * rgb_led, uint8_t *p_xfer, uint16_t xbuff_length); -//static void i2s_ws2812b_drive_handler(uint32_t const * p_data_received,uint32_t * p_data_to_send,uint16_t number_of_words); -//void i2s_ws2812b_drive_xfer(rgb_led_t *led_array, uint16_t num_leds, uint8_t drive_pin); -//void ws2812b_drive_set_blank(rgb_led_t * rgb_led, uint16_t num_leds); -//void ws2812b_drive_current_cap(rgb_led_t * led_array, uint16_t num_leds, uint32_t limit); -//uint32_t ws2812b_drive_calc_current(rgb_led_t * led_array, uint16_t num_leds); - -//void ws2812b_drive_dim(rgb_led_t * led_array, uint16_t num_leds, float dim ); -//void flashing_random_init(rgb_led_t * led_array_base, uint16_t num_leds); -//void flashing_random(rgb_led_t * led_array_out); diff --git a/arduino_tests/bluehand_tester/bluehand_tester.ino b/arduino_tests/bluehand_tester/bluehand_tester.ino new file mode 100644 index 00000000..22367b3a --- /dev/null +++ b/arduino_tests/bluehand_tester/bluehand_tester.ino @@ -0,0 +1,223 @@ + + +#include +#include +BLEDis bledis; +BLEHidAdafruit blehid; +int pinlist1 [2] ={ 42, 36}; +uint8_t pins[] = { 29, 2, 28, 3, 10, 9, 24, 13}; +#ifndef PIN_BUZZER +#define PIN_BUZZER 45 //1.13 +#endif + + +// A few music note frequencies as defined in this tone example: +// https://www.arduino.cc/en/Tutorial/toneMelody +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 + +// Define note durations. You only need to adjust the whole note +// time and other notes will be subdivided from it directly. +#define WHOLE 2200 // Length of time in milliseconds of a whole note (i.e. a full bar). +#define HALF WHOLE/2 +#define QUARTER HALF/2 +#define EIGHTH QUARTER/2 +#define EIGHTH_TRIPLE QUARTER/3 +#define SIXTEENTH EIGHTH/2 + +// Play a note of the specified frequency and for the specified duration. +// Hold is an optional bool that specifies if this note should be held a +// little longer, i.e. for eigth notes that are tied together. +// While waiting for a note to play the waitBreath delay function is used +// so breath detection and pixel animation continues to run. No tones +// will play if the slide switch is in the -/off position or all the +// candles have been blown out. +void playNote(int frequency, int duration, bool hold=false, bool measure=true) { + (void) measure; + + if (hold) { + // For a note that's held play it a little longer than the specified duration + // so it blends into the next tone (but there's still a small delay to + // hear the next note). + tone(PIN_BUZZER, frequency, duration + duration/32); + } + else { + // For a note that isn't held just play it for the specified duration. + tone(PIN_BUZZER, frequency, duration); + } + + delay(duration + duration/16); +} + +// Song to play when the candles are blown out. +void celebrateSong() { + // Play a little charge melody, from: + // https://en.wikipedia.org/wiki/Charge_(fanfare) + // Note the explicit boolean parameters in particular the measure=false + // at the end. This means the notes will play without any breath measurement + // logic. Without this false value playNote will try to keep waiting for candles + // to blow out during the celebration song! + playNote(NOTE_G4, EIGHTH_TRIPLE, true, false); + playNote(NOTE_C5, EIGHTH_TRIPLE, true, false); + playNote(NOTE_E5, EIGHTH_TRIPLE, false, false); + playNote(NOTE_G5, EIGHTH, true, false); + playNote(NOTE_E5, SIXTEENTH, false); + playNote(NOTE_G5, HALF, false); +} + +void setup() { + + +// this is the code needed to change the default voltage from the on chip voltage regulator. +// see https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.0.pdf page 45 + + if (NRF_UICR->REGOUT0 != UICR_REGOUT0_VOUT_3V3) { + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->REGOUT0 = UICR_REGOUT0_VOUT_3V3; + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + delay(500); + NVIC_SystemReset(); + } + +// this code is needed to switch the nfc pins to standard GPIOs. + if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy); + NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy); + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy); + Serial.println("Done"); + delay(500); + NVIC_SystemReset(); + } + + // Initialize serial output and Circuit Playground library. + Serial.begin(115200); + + pinMode(PIN_BUZZER, OUTPUT); + digitalWrite(PIN_BUZZER, LOW); + + + Bluefruit.begin(); + Bluefruit.setTxPower(4); + Bluefruit.setName("BlueHand"); + bledis.setManufacturer("jpconstantineau.com"); + bledis.setModel("BlueHand Tester"); + bledis.begin(); + blehid.begin(); + startAdv(); + for (int i = 0; i< 2; i++ ) + { + pinMode(pinlist1[i], OUTPUT); + } + + // set up pin as input + for (uint8_t i=0; i<8; i++) + { + pinMode(pins[i], INPUT_PULLUP); + } + + + celebrateSong(); +} + +void flashpin(int pinno) +{ + digitalWrite(pinno, LOW); delay(100); digitalWrite(pinno, HIGH); delay(100);digitalWrite(pinno, LOW); + } + +void startAdv(void) +{ + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD); + + // Include BLE HID service + Bluefruit.Advertising.addService(blehid); + + // There is enough room for the dev name in the advertising packet + Bluefruit.Advertising.addName(); + + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds + + +} + +void loop() { + static int i = 0; + flashpin(pinlist1[i]); + i++; + if (i ==2){i=0;} + + if ( 0 == digitalRead(pins[0]) ) + { + playNote(NOTE_A4, SIXTEENTH, false); + } + if ( 0 == digitalRead(pins[1]) ) + { + playNote(NOTE_B4, SIXTEENTH, false); + } + + if ( 0 == digitalRead(pins[2]) ) + { + playNote(NOTE_C5, SIXTEENTH, false); + } + if ( 0 == digitalRead(pins[3]) ) + { + playNote(NOTE_D5, SIXTEENTH, false); + } + if ( 0 == digitalRead(pins[4]) ) + { + playNote(NOTE_E5, SIXTEENTH, false); + } + if ( 0 == digitalRead(pins[5]) ) + { + playNote(NOTE_F5, SIXTEENTH, false); + } + + if ( 0 == digitalRead(pins[6]) ) + { + playNote(NOTE_G5, SIXTEENTH, false); + } + if ( 0 == digitalRead(pins[7]) ) + { + playNote(NOTE_A5, SIXTEENTH, false); + } + +} + +void rtos_idle_callback(void) +{ + // Don't call any other FreeRTOS blocking API() + // Perform background task(s) here +} diff --git a/arduino_tests/flash_tests/flash_tests.ino b/arduino_tests/flash_tests/flash_tests.ino deleted file mode 100644 index 069c7faf..00000000 --- a/arduino_tests/flash_tests/flash_tests.ino +++ /dev/null @@ -1,241 +0,0 @@ -/********************************************************************* - This is an example for our nRF52 based Bluefruit LE modules - - Pick one up today in the adafruit shop! - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - MIT license, check LICENSE for more information - All text above, and the splash screen below must be included in - any redistribution -*********************************************************************/ - -#include -#include - - typedef struct { - bool ledbacklight; - bool ledrgb; - bool VCCSwitchAvailable; - bool VCCSwitchEnabled; - bool ChargerControlAvailable; - bool ChargerControlEnabled; - bool WakeUpBLELED; - bool WakeUpKBLED; - uint32_t timerkeyscaninterval; - uint32_t timerbatteryinterval; - } PersistentState; - -PersistentState persistentdata; -PersistentState saveddata; - -#define FILENAME "/adafruit.txt" -#define FILENAME_BSP "/bsp.txt" -#define FILENAME_VERSION "/compiled.txt" -#define FILENAME_DATA "/kb_state.dat" -// ARDUINO_BSP_VERSION -#define CONTENTS "Adafruit Little File System test file contents" - -const char compile_date[] = __DATE__ " " __TIME__; - -Adafruit_LittleFS_Namespace::File file(InternalFS); -Adafruit_LittleFS_Namespace::File file_bsp(InternalFS); -Adafruit_LittleFS_Namespace::File file_version(InternalFS); -Adafruit_LittleFS_Namespace::File file_data(InternalFS); - -void save_data() -{ - Serial.print("Open " FILENAME_DATA " file to write ... "); - if( file_data.open(FILENAME_DATA, Adafruit_LittleFS_Namespace::FILE_O_WRITE) ) - { - Serial.println("OK"); -Serial.println(file_data.position()); - file_data.truncate(0); - Serial.println(file_data.position()); - file_data.seek (0); - Serial.println(file_data.position()); - //file_data.write(reinterpret_cast( &persistentdata), sizeof( PersistentState)); - auto* raw_data = reinterpret_cast(std::addressof(persistentdata)); - Serial.println(raw_data); - file_data.write(raw_data, sizeof(PersistentState)); - file_data.flush(); - Serial.println(file_data.position()); - Serial.println(file_data.size()); - file_data.close(); - }else - { - Serial.println("Failed!"); - } -} - -void load_data() -{ - file_data.open(FILENAME_DATA, Adafruit_LittleFS_Namespace::FILE_O_READ); - if ( file_data ) // file existed - { - Serial.println(FILENAME_DATA " file exists"); - - uint32_t readlen; - - readlen = file_data.read(reinterpret_cast(&saveddata), sizeof(PersistentState)); - file_data.close(); - Serial.println(reinterpret_cast(&saveddata)); - Serial.println(saveddata.timerbatteryinterval); - Serial.println(saveddata.timerkeyscaninterval); - - persistentdata.ledbacklight = saveddata.ledbacklight; - persistentdata.ledrgb = saveddata.ledrgb; - persistentdata.VCCSwitchAvailable = saveddata.VCCSwitchAvailable; - persistentdata.VCCSwitchEnabled = saveddata.VCCSwitchEnabled; - persistentdata.ChargerControlAvailable = saveddata.ChargerControlAvailable; - persistentdata.ChargerControlEnabled = saveddata.ChargerControlEnabled; - persistentdata.WakeUpBLELED = saveddata.WakeUpBLELED; - persistentdata.WakeUpKBLED = saveddata.WakeUpKBLED; - persistentdata.timerkeyscaninterval = saveddata.timerkeyscaninterval; - persistentdata.timerbatteryinterval = saveddata.timerbatteryinterval; - } else - { - persistentdata.ledbacklight = true; - persistentdata.ledrgb = true; - persistentdata.VCCSwitchAvailable = true; - persistentdata.VCCSwitchEnabled = true; - persistentdata.ChargerControlAvailable = true; - persistentdata.ChargerControlEnabled = true; - persistentdata.WakeUpBLELED = true; - persistentdata.WakeUpKBLED = true; - persistentdata.timerkeyscaninterval =42; - persistentdata.timerbatteryinterval = 0; - } -} - -// the setup function runs once when you press reset or power the board -void setup() -{ - - persistentdata.ledbacklight = true; - persistentdata.ledrgb = true; - persistentdata.VCCSwitchAvailable = true; - persistentdata.VCCSwitchEnabled = true; - persistentdata.ChargerControlAvailable = true; - persistentdata.ChargerControlEnabled = true; - persistentdata.WakeUpBLELED = true; - persistentdata.WakeUpKBLED = true; - persistentdata.timerkeyscaninterval =42; - persistentdata.timerbatteryinterval = 0; - Serial.begin(115200); - while ( !Serial ) delay(10); // for nrf52840 with native usb - - Serial.println("Internal Read Write File Example"); - Serial.println(); - - // Wait for user input to run. Otherwise the code will - // always run immediately after flash and create the FILENAME in advance - Serial.print("Enter to any keys to continue:"); - while ( !Serial.available() ) - { - delay(1); - } - Serial.println(); - Serial.println(); - - // Initialize Internal File System - InternalFS.begin(); - - file.open(FILENAME, Adafruit_LittleFS_Namespace::FILE_O_READ); - file_bsp.open(FILENAME_BSP, Adafruit_LittleFS_Namespace::FILE_O_READ); - file_version.open(FILENAME_VERSION, Adafruit_LittleFS_Namespace::FILE_O_READ); - - - - if ( file ) // file existed - { - Serial.println(FILENAME " file exists"); - - uint32_t readlen; - char buffer[64] = { 0 }; - readlen = file.read(buffer, sizeof(buffer)); - - buffer[readlen] = 0; - Serial.println(buffer); - file.close(); - }else - { - Serial.print("Open " FILENAME " file to write ... "); - - if( file.open(FILENAME, Adafruit_LittleFS_Namespace::FILE_O_WRITE) ) - { - Serial.println("OK"); - file.write(CONTENTS, strlen(CONTENTS)); - file.close(); - }else - { - Serial.println("Failed!"); - } - } - - if ( file_bsp ) // file existed - { - Serial.println(FILENAME_BSP " file exists"); - uint32_t readlen; - char buffer[64] = { 0 }; - readlen = file_bsp.read(buffer, sizeof(buffer)); - buffer[readlen] = 0; // adds a null character to finish the string - Serial.println(buffer); - file_bsp.close(); - }else - { - Serial.print("Open " FILENAME_BSP " file to write ... "); - if( file_bsp.open(FILENAME_BSP, Adafruit_LittleFS_Namespace::FILE_O_WRITE) ) - { - Serial.println("OK"); - file_bsp.write(ARDUINO_BSP_VERSION, strlen(ARDUINO_BSP_VERSION)); - file_bsp.close(); - }else - { - Serial.println("Failed!"); - } - } - - if ( file_version ) // file existed - { - Serial.println(FILENAME_VERSION " file exists"); - uint32_t readlen; - char buffer[64] = { 0 }; - readlen = file_version.read(buffer, sizeof(buffer)); - buffer[readlen] = 0; // adds a null character to finish the string - Serial.println(buffer); - file_version.close(); - }else - { - Serial.print("Open " FILENAME_VERSION " file to write ... "); - if( file_version.open(FILENAME_VERSION, Adafruit_LittleFS_Namespace::FILE_O_WRITE) ) - { - Serial.println("OK"); - file_version.write(compile_date, strlen(compile_date)); - file_version.close(); - }else - { - Serial.println("Failed!"); - } - } - - - load_data(); - persistentdata.timerbatteryinterval++; - save_data(); - - - Serial.println("Done"); -} - -// the loop function runs over and over again forever -void loop() -{ - load_data(); - persistentdata.timerbatteryinterval = millis(); - save_data(); - delay(3000); - -} diff --git a/arduino_tests/hid_keyboard/hid_keyboard.ino b/arduino_tests/hid_keyboard/hid_keyboard.ino deleted file mode 100644 index 10ed810d..00000000 --- a/arduino_tests/hid_keyboard/hid_keyboard.ino +++ /dev/null @@ -1,193 +0,0 @@ -/********************************************************************* - This is an example for our nRF52 based Bluefruit LE modules - - Pick one up today in the adafruit shop! - - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - MIT license, check LICENSE for more information - All text above, and the splash screen below must be included in - any redistribution -*********************************************************************/ -#include -#include "Adafruit_TinyUSB.h" - -/* This sketch demonstrates multiple report USB HID. - * Press button pin will move - * - mouse toward bottom right of monitor - * - send 'a' key - * - * Depending on the board, the button pin - * and its active state (when pressed) are different - */ -#if defined ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS - const int pin = 4; // Left Button - bool activeState = true; -#elif defined ARDUINO_NRF52840_FEATHER - const int pin = 7; // UserSw - bool activeState = false; -#else - const int pin = 12; - bool activeState = false; -#endif - - -// Report ID -enum -{ - RID_KEYBOARD = 1, - RID_MOUSE -}; - -// HID report descriptor using TinyUSB's template -uint8_t const desc_hid_report[] = -{ - TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(RID_KEYBOARD), ), - TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(RID_MOUSE), ) -}; - -// USB HID object -Adafruit_USBD_HID usb_hid; - -BLEDis bledis; -BLEHidAdafruit blehid; - -bool hasKeyPressed = false; - -void setup() -{ - Serial.begin(115200); - // while ( !Serial ) delay(10); // for nrf52840 with native usb - serial must be connected for this to continue... - - Serial.println("Bluefruit52 HID Keyboard Example"); - Serial.println("--------------------------------\n"); - - Serial.println(); - Serial.println("Go to your phone's Bluetooth settings to pair your device"); - Serial.println("then open an application that accepts keyboard input"); - - Serial.println(); - Serial.println("Enter the character(s) to send:"); - Serial.println(); - - Bluefruit.begin(); - Bluefruit.setTxPower(4); // Check bluefruit.h for supported values - Bluefruit.setName("Bluefruit52"); - - // Configure and Start Device Information Service - bledis.setManufacturer("Adafruit Industries"); - bledis.setModel("Bluefruit Feather 52"); - bledis.begin(); - - /* Start BLE HID - * Note: Apple requires BLE device must have min connection interval >= 20m - * ( The smaller the connection interval the faster we could send data). - * However for HID and MIDI device, Apple could accept min connection interval - * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max - * connection interval to 11.25 ms and 15 ms respectively for best performance. - */ - blehid.begin(); - - // Set callback for set LED from central - blehid.setKeyboardLedCallback(set_keyboard_led); - - /* Set connection interval (min, max) to your perferred value. - * Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms - * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms - */ - /* Bluefruit.Periph.setConnInterval(9, 12); */ - - // Set up and start advertising - startAdv(); - - usb_hid.setPollInterval(2); - usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report)); - - usb_hid.begin(); - - // Set up button, pullup opposite to active state - pinMode(pin, activeState ? INPUT_PULLDOWN : INPUT_PULLUP); - - // wait until device mounted - while( !USBDevice.mounted() ) delay(1); -} - -void startAdv(void) -{ - // Advertising packet - Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); - Bluefruit.Advertising.addTxPower(); - Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD); - - // Include BLE HID service - Bluefruit.Advertising.addService(blehid); - - // There is enough room for the dev name in the advertising packet - Bluefruit.Advertising.addName(); - - /* Start Advertising - * - Enable auto advertising if disconnected - * - Interval: fast mode = 20 ms, slow mode = 152.5 ms - * - Timeout for fast mode is 30 seconds - * - Start(timeout) with timeout = 0 will advertise forever (until connected) - * - * For recommended advertising interval - * https://developer.apple.com/library/content/qa/qa1931/_index.html - */ - Bluefruit.Advertising.restartOnDisconnect(true); - Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms - Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode - Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds -} - -void loop() -{ - // Only send KeyRelease if previously pressed to avoid sending - // multiple keyRelease reports (that consume memory and bandwidth) - if ( hasKeyPressed ) - { - hasKeyPressed = false; - blehid.keyRelease(); - - // Delay a bit after a report - delay(5); - } - - if (Serial.available()) - { - char ch = (char) Serial.read(); - - // echo - Serial.write(ch); - - blehid.keyPress(ch); - hasKeyPressed = true; - - // Delay a bit after a report - delay(5); - } -} - -/** - * Callback invoked when received Set LED from central. - * Must be set previously with setKeyboardLedCallback() - * - * The LED bit map is as follows: (also defined by KEYBOARD_LED_* ) - * Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) - */ -void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap) -{ - (void) conn_handle; - - // light up Red Led if any bits is set - if ( led_bitmap ) - { - ledOn( LED_RED ); - } - else - { - ledOff( LED_RED ); - } -} diff --git a/arduino_tests/board_tester/Tools/board_tester.ino.zip b/arduino_tests/nrf52832_tester/Tools/board_tester.ino.zip similarity index 100% rename from arduino_tests/board_tester/Tools/board_tester.ino.zip rename to arduino_tests/nrf52832_tester/Tools/board_tester.ino.zip diff --git a/arduino_tests/board_tester/Tools/bootloader.bat b/arduino_tests/nrf52832_tester/Tools/bootloader.bat similarity index 100% rename from arduino_tests/board_tester/Tools/bootloader.bat rename to arduino_tests/nrf52832_tester/Tools/bootloader.bat diff --git a/arduino_tests/board_tester/Tools/burn-BSP.bat b/arduino_tests/nrf52832_tester/Tools/burn-BSP.bat similarity index 100% rename from arduino_tests/board_tester/Tools/burn-BSP.bat rename to arduino_tests/nrf52832_tester/Tools/burn-BSP.bat diff --git a/arduino_tests/board_tester/Tools/burntester.bat b/arduino_tests/nrf52832_tester/Tools/burntester.bat similarity index 100% rename from arduino_tests/board_tester/Tools/burntester.bat rename to arduino_tests/nrf52832_tester/Tools/burntester.bat diff --git a/arduino_tests/board_tester/Tools/flash - Copy.bat b/arduino_tests/nrf52832_tester/Tools/flash - Copy.bat similarity index 100% rename from arduino_tests/board_tester/Tools/flash - Copy.bat rename to arduino_tests/nrf52832_tester/Tools/flash - Copy.bat diff --git a/arduino_tests/board_tester/Tools/flash-Ergotravel-left.bat b/arduino_tests/nrf52832_tester/Tools/flash-Ergotravel-left.bat similarity index 100% rename from arduino_tests/board_tester/Tools/flash-Ergotravel-left.bat rename to arduino_tests/nrf52832_tester/Tools/flash-Ergotravel-left.bat diff --git a/arduino_tests/board_tester/Tools/flash-Ergotravel-right.bat b/arduino_tests/nrf52832_tester/Tools/flash-Ergotravel-right.bat similarity index 100% rename from arduino_tests/board_tester/Tools/flash-Ergotravel-right.bat rename to arduino_tests/nrf52832_tester/Tools/flash-Ergotravel-right.bat diff --git a/arduino_tests/board_tester/Tools/flash.bat b/arduino_tests/nrf52832_tester/Tools/flash.bat similarity index 100% rename from arduino_tests/board_tester/Tools/flash.bat rename to arduino_tests/nrf52832_tester/Tools/flash.bat diff --git a/arduino_tests/board_tester/Tools/runall.bat b/arduino_tests/nrf52832_tester/Tools/runall.bat similarity index 100% rename from arduino_tests/board_tester/Tools/runall.bat rename to arduino_tests/nrf52832_tester/Tools/runall.bat diff --git a/arduino_tests/board_tester/Tools/unlock.bat b/arduino_tests/nrf52832_tester/Tools/unlock.bat similarity index 100% rename from arduino_tests/board_tester/Tools/unlock.bat rename to arduino_tests/nrf52832_tester/Tools/unlock.bat diff --git a/arduino_tests/board_tester/board_tester.ino b/arduino_tests/nrf52832_tester/nrf52832_tester.ino similarity index 100% rename from arduino_tests/board_tester/board_tester.ino rename to arduino_tests/nrf52832_tester/nrf52832_tester.ino diff --git a/arduino_tests/nrf52840_USB_BLE/nrf52840_USB_BLE.ino b/arduino_tests/nrf52840_USB_BLE/nrf52840_USB_BLE.ino deleted file mode 100644 index 25dde68a..00000000 --- a/arduino_tests/nrf52840_USB_BLE/nrf52840_USB_BLE.ino +++ /dev/null @@ -1,51 +0,0 @@ -/* - Blink - - Turns an LED on for one second, then off for one second, repeatedly. - - Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO - it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to - the correct LED pin independent of which board is used. - If you want to know what pin the on-board LED is connected to on your Arduino - model, check the Technical Specs of your board at: - https://www.arduino.cc/en/Main/Products - - modified 8 May 2014 - by Scott Fitzgerald - modified 2 Sep 2016 - by Arturo Guadalupi - modified 8 Sep 2016 - by Colby Newman - - This example code is in the public domain. - - http://www.arduino.cc/en/Tutorial/Blink -*/ -#include -// the setup function runs once when you press reset or power the board -void setup() { - // initialize digital pin LED_BUILTIN as an output. - USBDevice.begin(); - Serial.begin(115200); - pinMode(32+10 , OUTPUT); - pinMode(32+4 , OUTPUT); -} - -// the loop function runs over and over again forever -void loop() { - //USBDevice.attach(); - if (USBDevice.ready() ) - // if (USBDevice.mounted() ) - // if (USBDevice.suspended() ) - { - ledOn( 32+10 ); - } - else - { - ledOff( 32+10 ); - } - digitalWrite(32+4 , HIGH); // turn the LED on (HIGH is the voltage level) - delay(1000); // wait for a second - digitalWrite(32+4 , LOW); // turn the LED off by making the voltage LOW - delay(1000); // wait for a second -} diff --git a/arduino_tests/nrf52840_hid_keyboard/nrf52840_hid_keyboard.ino b/arduino_tests/nrf52840_hid_keyboard/nrf52840_hid_keyboard.ino deleted file mode 100644 index 4c30e308..00000000 --- a/arduino_tests/nrf52840_hid_keyboard/nrf52840_hid_keyboard.ino +++ /dev/null @@ -1,135 +0,0 @@ -/********************************************************************* - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - MIT license, check LICENSE for more information - Copyright (c) 2019 Ha Thach for Adafruit Industries - All text above, and the splash screen below must be included in - any redistribution -*********************************************************************/ - -#include "Adafruit_TinyUSB.h" - -/* This sketch demonstrates USB HID keyboard. - * - PIN A0-A5 is used to send digit '0' to '5' respectively - * - LED will be used as Caplock indicator - */ - -// HID report descriptor using TinyUSB's template -// Single Report (no ID) descriptor -uint8_t const desc_hid_report[] = -{ - TUD_HID_REPORT_DESC_KEYBOARD(), -}; - -Adafruit_USBD_HID usb_hid; -#define BUTTON 32+6 -#define LED 32+4 - -// Array of pins and its keycode -// For keycode definition see BLEHidGeneric.h -uint8_t pins[] = { BUTTON }; -uint8_t hidcode[] = { HID_KEY_0}; - -uint8_t pincount = sizeof(pins)/sizeof(pins[0]); - -// the setup function runs once when you press reset or power the board -void setup() -{ - usb_hid.setPollInterval(2); - usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report)); - usb_hid.setReportCallback(NULL, hid_report_callback); - - usb_hid.begin(); - - // led pin - pinMode(LED, OUTPUT); - digitalWrite(LED, LOW); - - // Set up pin as input - for (uint8_t i=0; ivbat_per); - printline(0, 8, stat->vbat_mv); - printline(0, 18, stat->rssi_prph); - printline(0, 28, stat->peer_name_prph); - - char buffer[50]; - u8g2.setFont(u8g2_font_helvB12_tf); // choose a suitable font - sprintf(buffer, "%d", stat->layer); - u8g2.drawStr(0, 128, buffer); -#endif +void drawStatus(PersistentState* cfg, DynamicState* stat) +{ + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + u8g2.setFontMode(1); // Transparent + u8g2.setFontDirection(0); + battery(22,19,stat->vbat_per); + printline(0,8,stat->vbat_mv); + printline(0,18,stat->rssi_prph); + printline(0,28,stat->peer_name_prph); + + char buffer [50]; + u8g2.setFont(u8g2_font_helvB12_tf); // choose a suitable font + sprintf(buffer, "%d", stat->layer); + u8g2.drawStr(0,128,buffer); + #endif } -void drawDebug(PersistentState *cfg, DynamicState *stat) { -#ifdef BLUEMICRO_CONFIGURED_DISPLAY - u8g2.setFontMode(1); // Transparent - u8g2.setFontDirection(0); - battery(22, 19, stat->vbat_per); - printline(0, 8, stat->vbat_mv); - printline(0, 18, stat->rssi_prph); - printline(0, 28, stat->peer_name_prph); - - char buffer[50]; - u8g2.setFont(u8g2_font_helvB12_tf); // choose a suitable font - sprintf(buffer, "%d", stat->layer); - u8g2.drawStr(0, 128, buffer); -#endif +void drawDebug(PersistentState* cfg, DynamicState* stat) +{ + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + u8g2.setFontMode(1); // Transparent + u8g2.setFontDirection(0); + battery(22,19,stat->vbat_per); + printline(0,8,stat->vbat_mv); + printline(0,18,stat->rssi_prph); + printline(0,28,stat->peer_name_prph); + + char buffer [50]; + u8g2.setFont(u8g2_font_helvB12_tf); // choose a suitable font + sprintf(buffer, "%d", stat->layer); + u8g2.drawStr(0,128,buffer); + #endif } + /**************************************************************************************************************************/ \ No newline at end of file diff --git a/firmware/BlueMicro_display.h b/firmware/BlueMicro_display.h index ed95bbb8..1818c2a7 100644 --- a/firmware/BlueMicro_display.h +++ b/firmware/BlueMicro_display.h @@ -7,81 +7,83 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BLUEMICRO_DISPLAY_H #define BLUEMICRO_DISPLAY_H -#include "datastructures.h" -#include "firmware_config.h" -#include "keyboard_config.h" -#include "nrf52gpio.h" #include #include +#include "keyboard_config.h" +#include "firmware_config.h" +#include "nrf52gpio.h" +#include "datastructures.h" // see fonts here: https://github.com/olikraus/u8g2/wiki/fntlistall -// see constructors here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp +// see constructors here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp -#ifdef BLUEMICRO_CONFIGURED_DISPLAY -#include -#ifdef U8X8_HAVE_HW_SPI -#include -#endif -#ifdef U8X8_HAVE_HW_I2C -#include -#endif + +#ifdef BLUEMICRO_CONFIGURED_DISPLAY + #include + + #ifdef U8X8_HAVE_HW_SPI + #include + #endif + #ifdef U8X8_HAVE_HW_I2C + #include + #endif #endif -enum DisplayUpdateType { - DISPLAY_UPDATE_STARTUP = 0, - DISPLAY_UPDATE_STATUS = 1, - DISPLAY_UPDATE_DEBUG = 2, -}; - -class BlueMicro_Display { -public: - BlueMicro_Display(PersistentState *cfg, DynamicState *stat); - - void begin(void); - void update(void); - - void setStartupDisplayCallback(updateDisplay_cb_t callback); - void setStatusDisplayCallback(updateDisplay_cb_t callback); - void setDebugDisplayCallback(updateDisplay_cb_t callback); - void changeUpdateMode(DisplayUpdateType mode); - void sleep(void); - void clear(); - -private: - DisplayUpdateType updatemode; - - updateDisplay_cb_t _startupUpdateDisplay_cb; // this one is called during bootup - updateDisplay_cb_t _statusUpdateDisplay_cb; // this one is called regularly - updateDisplay_cb_t _debugUpdateDisplay_cb; // this one is called on demand - - PersistentState *config; - DynamicState *status; -}; - -void battery(uint8_t x, uint8_t y, uint8_t data); -void printline(uint8_t x, uint8_t y, char *data); -void printline(uint8_t x, uint8_t y, int8_t data); -void printline(uint8_t x, uint8_t y, uint16_t data); -void printline(uint8_t x, uint8_t y, uint32_t data); - -void drawStartup(PersistentState *cfg, DynamicState *stat); -void drawStatus(PersistentState *cfg, DynamicState *stat); -void drawDebug(PersistentState *cfg, DynamicState *stat); + + enum DisplayUpdateType { + DISPLAY_UPDATE_STARTUP = 0, + DISPLAY_UPDATE_STATUS = 1, + DISPLAY_UPDATE_DEBUG = 2, + }; + + + + class BlueMicro_Display { + public: + BlueMicro_Display(PersistentState* cfg, DynamicState* stat); + + void begin(void); + void update(void); + + void setStartupDisplayCallback(updateDisplay_cb_t callback); + void setStatusDisplayCallback(updateDisplay_cb_t callback); + void setDebugDisplayCallback(updateDisplay_cb_t callback); + void changeUpdateMode(DisplayUpdateType mode); + void sleep(void); + void clear(); + + private: + DisplayUpdateType updatemode; + + updateDisplay_cb_t _startupUpdateDisplay_cb; // this one is called during bootup + updateDisplay_cb_t _statusUpdateDisplay_cb; // this one is called regularly + updateDisplay_cb_t _debugUpdateDisplay_cb; // this one is called on demand + + PersistentState* config; + DynamicState* status; + }; + + void battery(uint8_t x, uint8_t y,uint8_t data); + void printline(uint8_t x, uint8_t y,char* data); + void printline(uint8_t x, uint8_t y,int8_t data); + void printline(uint8_t x, uint8_t y,uint16_t data); + void printline(uint8_t x, uint8_t y,uint32_t data); + + void drawStartup(PersistentState* cfg, DynamicState* stat); + void drawStatus(PersistentState* cfg, DynamicState* stat); + void drawDebug(PersistentState* cfg, DynamicState* stat); #endif // DISPLAY_H \ No newline at end of file diff --git a/firmware/BlueMicro_tone.cpp b/firmware/BlueMicro_tone.cpp index 53098bce..ce4fe58f 100644 --- a/firmware/BlueMicro_tone.cpp +++ b/firmware/BlueMicro_tone.cpp @@ -7,75 +7,90 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "BlueMicro_tone.h" -BlueMicro_tone::BlueMicro_tone(PersistentState *cfg, DynamicState *stat) // Constructor + +BlueMicro_tone::BlueMicro_tone(PersistentState* cfg, DynamicState* stat) // Constructor +{ + config=cfg; + status=stat; + _pin = 0; /// default is 0 - this ensures that a pin is set before playing anything. +} + +void BlueMicro_tone::setSpeakerPin(uint8_t pin) { - config = cfg; - status = stat; - _pin = 0; /// default is 0 - this ensures that a pin is set before playing anything. + _pin = pin; } -void BlueMicro_tone::setSpeakerPin(uint8_t pin) { _pin = pin; } -void BlueMicro_tone::playTone(toneList_t toneToPlay) { toneQueue.push(toneToPlay); } +void BlueMicro_tone::playTone(toneList_t toneToPlay) +{ + toneQueue.push(toneToPlay); +} + -void BlueMicro_tone::playToneNow(unsigned int frequency, unsigned long duration) { - if (_pin) { -#ifdef SPEAKER_PIN +void BlueMicro_tone::playToneNow(unsigned int frequency, unsigned long duration) +{ + if (_pin) + { + #ifdef SPEAKER_PIN digitalWrite(SPEAKER_PIN, HIGH); delay(50); -#endif + #endif - tone(_pin, frequency, duration); - delay(duration); + tone(_pin, frequency, duration); + delay(duration); -#ifdef SPEAKER_PIN + #ifdef SPEAKER_PIN digitalWrite(SPEAKER_PIN, LOW); -#endif + #endif } } -void BlueMicro_tone::playAllQueuedTonesNow() { - while (!toneQueue.empty()) { - NRF_WDT->RR[0] = WDT_RR_RR_Reload; // pet watchdog + +void BlueMicro_tone::playAllQueuedTonesNow() +{ + while (!toneQueue.empty()) + { + NRF_WDT->RR[0] = WDT_RR_RR_Reload; // pet watchdog processTones(); } } // cppcheck-suppress unusedFunction -void BlueMicro_tone::clearAllQueuedTones() { - while (!toneQueue.empty()) - toneQueue.pop(); +void BlueMicro_tone::clearAllQueuedTones() +{ + while (!toneQueue.empty()) toneQueue.pop(); } -void BlueMicro_tone::processTones() { - if (!toneQueue.empty()) { - if (millis() - toneDelay < 750) - return; + +void BlueMicro_tone::processTones() +{ + if (!toneQueue.empty()) + { + if (millis() - toneDelay < 750) return; toneList_t toneToPlay = toneQueue.front(); toneQueue.pop(); - if (_pin) { -#ifdef SPEAKER_PIN + if (_pin) + { + #ifdef SPEAKER_PIN digitalWrite(_pin, HIGH); delay(50); -#endif + #endif - switch (toneToPlay) { + switch (toneToPlay) + { case TONE_STARTUP: tone(_pin, NOTE_E4, 50); delay(65); @@ -83,28 +98,29 @@ void BlueMicro_tone::processTones() { delay(65); tone(_pin, NOTE_E5, 50); delay(65); - break; + break; case TONE_BLE_PROFILE: - for (uint8_t clicks = 0; clicks < (config->BLEProfile + 1); clicks++) { + for (uint8_t clicks = 0; clicks < (config->BLEProfile + 1); clicks++) + { tone(_pin, TONE_A320_CLICK, 15); delay(250); } - break; + break; case TONE_BLE_CONNECT: tone(_pin, NOTE_B5, 100); delay(100); tone(_pin, NOTE_E6, 350); delay(350); - break; + break; case TONE_BLE_DISCONNECT: tone(_pin, NOTE_E6, 100); delay(100); tone(_pin, NOTE_B5, 350); delay(350); - break; + break; case TONE_SLEEP: tone(_pin, NOTE_E5, 50); @@ -113,12 +129,12 @@ void BlueMicro_tone::processTones() { delay(65); tone(_pin, NOTE_E4, 50); delay(65); - break; - } + break; + } -#ifdef SPEAKER_PIN + #ifdef SPEAKER_PIN digitalWrite(SPEAKER_PIN, LOW); -#endif + #endif } toneDelay = millis(); } @@ -128,26 +144,34 @@ void BlueMicro_tone::processTones() { // Hold is an optional bool that specifies if this note should be held a // little longer, i.e. for eigth notes that are tied together. // While waiting for a note to play the waitBreath delay function is used -// so breath detection and pixel animation continues to run. +// so breath detection and pixel animation continues to run. // cppcheck-suppress unusedFunction -void BlueMicro_tone::playNoteNow(int frequency, int duration, bool hold = false) { +void BlueMicro_tone::playNoteNow(int frequency, int duration, bool hold=false) { if (hold) { // For a note that's held play it a little longer than the specified duration - // so it blends into the next tone (but there's still a small delay to + // so it blends into the next tone (but there's still a small delay to // hear the next note). - tone(_pin, frequency, duration + duration / 32); - } else { + tone(_pin, frequency, duration + duration/32); + } + else { // For a note that isn't held just play it for the specified duration. tone(_pin, frequency, duration); } - delay(duration + duration / 16); + delay(duration + duration/16); +} + +void BlueMicro_tone::playNoteNow(int frequency, int duration) +{ + playNoteNow( frequency, duration, false); } -void BlueMicro_tone::playNoteNow(int frequency, int duration) { playNoteNow(frequency, duration, false); } -std::queue BlueMicro_tone::toneQueue; -uint32_t BlueMicro_tone::toneDelay = 0; -PersistentState *BlueMicro_tone::config = NULL; -DynamicState *BlueMicro_tone::status = NULL; +#ifdef ENABLE_AUDIO + // std::queue BlueMicro_tone::toneQueue; + // uint32_t BlueMicro_tone::toneDelay = 0; + // PersistentState* BlueMicro_tone::config = NULL; + //DynamicState* BlueMicro_tone::status = NULL; +#endif + diff --git a/firmware/BlueMicro_tone.h b/firmware/BlueMicro_tone.h index 32b6d75b..057576dd 100644 --- a/firmware/BlueMicro_tone.h +++ b/firmware/BlueMicro_tone.h @@ -7,157 +7,164 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BLUEMICRO_TONE_H #define BLUEMICRO_TONE_H -#include "datastructures.h" #include #include +#include "datastructures.h" /************************************************************************************************** // A few music note frequencies as defined in this tone example: // https://www.arduino.cc/en/Tutorial/toneMelody **************************************************************************************************/ -#define NOTE_B0 31 -#define NOTE_C1 33 +#define NOTE_B0 31 +#define NOTE_C1 33 #define NOTE_CS1 35 -#define NOTE_D1 37 +#define NOTE_D1 37 #define NOTE_DS1 39 -#define NOTE_E1 41 -#define NOTE_F1 44 +#define NOTE_E1 41 +#define NOTE_F1 44 #define NOTE_FS1 46 -#define NOTE_G1 49 +#define NOTE_G1 49 #define NOTE_GS1 52 -#define NOTE_A1 55 +#define NOTE_A1 55 #define NOTE_AS1 58 -#define NOTE_B1 62 -#define NOTE_C2 65 +#define NOTE_B1 62 +#define NOTE_C2 65 #define NOTE_CS2 69 -#define NOTE_D2 73 +#define NOTE_D2 73 #define NOTE_DS2 78 -#define NOTE_E2 82 -#define NOTE_F2 87 +#define NOTE_E2 82 +#define NOTE_F2 87 #define NOTE_FS2 93 -#define NOTE_G2 98 +#define NOTE_G2 98 #define NOTE_GS2 104 -#define NOTE_A2 110 +#define NOTE_A2 110 #define NOTE_AS2 117 -#define NOTE_B2 123 -#define NOTE_C3 131 +#define NOTE_B2 123 +#define NOTE_C3 131 #define NOTE_CS3 139 -#define NOTE_D3 147 +#define NOTE_D3 147 #define NOTE_DS3 156 -#define NOTE_E3 165 -#define NOTE_F3 175 +#define NOTE_E3 165 +#define NOTE_F3 175 #define NOTE_FS3 185 -#define NOTE_G3 196 +#define NOTE_G3 196 #define NOTE_GS3 208 -#define NOTE_A3 220 +#define NOTE_A3 220 #define NOTE_AS3 233 -#define NOTE_B3 247 -#define NOTE_C4 262 +#define NOTE_B3 247 +#define NOTE_C4 262 #define NOTE_CS4 277 -#define NOTE_D4 294 +#define NOTE_D4 294 #define NOTE_DS4 311 -#define NOTE_E4 330 -#define NOTE_F4 349 +#define NOTE_E4 330 +#define NOTE_F4 349 #define NOTE_FS4 370 -#define NOTE_G4 392 +#define NOTE_G4 392 #define NOTE_GS4 415 -#define NOTE_A4 440 +#define NOTE_A4 440 #define NOTE_AS4 466 -#define NOTE_B4 494 -#define NOTE_C5 523 +#define NOTE_B4 494 +#define NOTE_C5 523 #define NOTE_CS5 554 -#define NOTE_D5 587 +#define NOTE_D5 587 #define NOTE_DS5 622 -#define NOTE_E5 659 -#define NOTE_F5 698 +#define NOTE_E5 659 +#define NOTE_F5 698 #define NOTE_FS5 740 -#define NOTE_G5 784 +#define NOTE_G5 784 #define NOTE_GS5 831 -#define NOTE_A5 880 +#define NOTE_A5 880 #define NOTE_AS5 932 -#define NOTE_B5 988 -#define NOTE_C6 1047 +#define NOTE_B5 988 +#define NOTE_C6 1047 #define NOTE_CS6 1109 -#define NOTE_D6 1175 +#define NOTE_D6 1175 #define NOTE_DS6 1245 -#define NOTE_E6 1319 -#define NOTE_F6 1397 +#define NOTE_E6 1319 +#define NOTE_F6 1397 #define NOTE_FS6 1480 -#define NOTE_G6 1568 +#define NOTE_G6 1568 #define NOTE_GS6 1661 -#define NOTE_A6 1760 +#define NOTE_A6 1760 #define NOTE_AS6 1865 -#define NOTE_B6 1976 -#define NOTE_C7 2093 +#define NOTE_B6 1976 +#define NOTE_C7 2093 #define NOTE_CS7 2217 -#define NOTE_D7 2349 +#define NOTE_D7 2349 #define NOTE_DS7 2489 -#define NOTE_E7 2637 -#define NOTE_F7 2794 +#define NOTE_E7 2637 +#define NOTE_F7 2794 #define NOTE_FS7 2960 -#define NOTE_G7 3136 +#define NOTE_G7 3136 #define NOTE_GS7 3322 -#define NOTE_A7 3520 +#define NOTE_A7 3520 #define NOTE_AS7 3729 -#define NOTE_B7 3951 -#define NOTE_C8 4186 +#define NOTE_B7 3951 +#define NOTE_C8 4186 #define NOTE_CS8 4435 -#define NOTE_D8 4699 +#define NOTE_D8 4699 #define NOTE_DS8 4978 -#define TONE_LOCK_HIGH NOTE_C6 -#define TONE_LOCK_LOW NOTE_C5 -#define TONE_A320_CLICK 1570 +#define TONE_LOCK_HIGH NOTE_C6 +#define TONE_LOCK_LOW NOTE_C5 +#define TONE_A320_CLICK 1570 // Define note durations. You only need to adjust the whole note // time and other notes will be subdivided from it directly. -#define WHOLE 2000 // Length of time in milliseconds of a whole note (i.e. a full bar). -#define HALF WHOLE / 2 -#define QUARTER HALF / 2 -#define EIGHTH QUARTER / 2 -#define EIGHTH_TRIPLE QUARTER / 3 -#define SIXTEENTH EIGHTH / 2 +#define WHOLE 2000 // Length of time in milliseconds of a whole note (i.e. a full bar). +#define HALF WHOLE/2 +#define QUARTER HALF/2 +#define EIGHTH QUARTER/2 +#define EIGHTH_TRIPLE QUARTER/3 +#define SIXTEENTH EIGHTH/2 + /************************************************************************************************** - * + * **************************************************************************************************/ -typedef enum { TONE_STARTUP, TONE_BLE_PROFILE, TONE_BLE_CONNECT, TONE_BLE_DISCONNECT, TONE_SLEEP } toneList_t; + typedef enum { + TONE_STARTUP, + TONE_BLE_PROFILE, + TONE_BLE_CONNECT, + TONE_BLE_DISCONNECT, + TONE_SLEEP + } toneList_t; + class BlueMicro_tone { -public: - BlueMicro_tone(PersistentState *cfg, DynamicState *stat); - void setSpeakerPin(uint8_t pin); - void playTone(toneList_t toneToPlay); - void playToneNow(unsigned int frequency, unsigned long duration); - void playNoteNow(int frequency, int duration, bool hold); - void playNoteNow(int frequency, int duration); - void playAllQueuedTonesNow(); - void clearAllQueuedTones(); - void processTones(); - -private: - uint8_t _pin; - static std::queue toneQueue; - static uint32_t toneDelay; - static PersistentState *config; - static DynamicState *status; + public: + BlueMicro_tone(PersistentState* cfg, DynamicState* stat); + void setSpeakerPin(uint8_t pin); + void playTone(toneList_t toneToPlay); + void playToneNow(unsigned int frequency, unsigned long duration); + void playNoteNow(int frequency, int duration, bool hold); + void playNoteNow(int frequency, int duration); + void playAllQueuedTonesNow(); + void clearAllQueuedTones(); + void processTones(); + + private: + uint8_t _pin; + std::queue toneQueue; + uint32_t toneDelay; + PersistentState* config; + DynamicState* status; }; + + #endif \ No newline at end of file diff --git a/firmware/HID.cpp b/firmware/HID.cpp index cdd2a044..3ae270b3 100644 --- a/firmware/HID.cpp +++ b/firmware/HID.cpp @@ -7,134 +7,62 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "HID.h" -uint16_t hid_GetMediaUsageCode(uint16_t keycode) { + +uint16_t hid_GetMediaUsageCode(uint16_t keycode) +{ uint16_t usagecode = 0; - switch (keycode) { - case KC_SYSTEM_POWER: - usagecode = HID_USAGE_CONSUMER_POWER; - break; - case KC_SYSTEM_RESET: - usagecode = HID_USAGE_CONSUMER_RESET; - break; - case KC_SYSTEM_SLEEP: - usagecode = HID_USAGE_CONSUMER_SLEEP; - break; - case KC_DISPLAY_BRIGHTI: - usagecode = HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT; - break; - case KC_DISPLAY_BRIGHTD: - usagecode = HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT; - break; - case KC_RADIO_CONTROL: - usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS; - break; - case KC_RADIO_BUTTONS: - usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS; - break; - case KC_RADIO_LED: - usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_LED; - break; - case KC_RADIO_SWITCH: - usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH; - break; - case KC_MEDIA_PLAY_PAUSE: - usagecode = HID_USAGE_CONSUMER_PLAY_PAUSE; - break; - case KC_MEDIA_NEXT_TRACK: - usagecode = HID_USAGE_CONSUMER_SCAN_NEXT; - break; - case KC_MEDIA_PREV_TRACK: - usagecode = HID_USAGE_CONSUMER_SCAN_PREVIOUS; - break; - case KC_MEDIA_STOP: - usagecode = HID_USAGE_CONSUMER_STOP; - break; - case KC_AUDIO_VOL: - usagecode = HID_USAGE_CONSUMER_VOLUME; - break; - case KC_AUDIO_MUTE: - usagecode = HID_USAGE_CONSUMER_MUTE; - break; - case KC_AUDIO_BASS: - usagecode = HID_USAGE_CONSUMER_BASS; - break; - case KC_AUDIO_TREBLE: - usagecode = HID_USAGE_CONSUMER_TREBLE; - break; - case KC_AUDIO_BASS_BOOST: - usagecode = HID_USAGE_CONSUMER_BASS_BOOST; - break; - case KC_AUDIO_VOL_UP: - usagecode = HID_USAGE_CONSUMER_VOLUME_INCREMENT; - break; - case KC_AUDIO_VOL_DOWN: - usagecode = HID_USAGE_CONSUMER_VOLUME_DECREMENT; - break; - case KC_AUDIO_BASS_UP: - usagecode = HID_USAGE_CONSUMER_BASS_INCREMENT; - break; - case KC_AUDIO_BASS_DOWN: - usagecode = HID_USAGE_CONSUMER_BASS_DECREMENT; - break; - case KC_AUDIO_TREBLE_UP: - usagecode = HID_USAGE_CONSUMER_TREBLE_INCREMENT; - break; - case KC_AUDIO_TREBLE_DOWN: - usagecode = HID_USAGE_CONSUMER_TREBLE_DECREMENT; - break; - case KC_MSEL: - usagecode = HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION; - break; - case KC_WWW: - usagecode = HID_USAGE_CONSUMER_AL_EMAIL_READER; - break; - case KC_CALCULATOR: - usagecode = HID_USAGE_CONSUMER_AL_CALCULATOR; - break; - case KC_MYCM: - usagecode = HID_USAGE_CONSUMER_AL_LOCAL_BROWSER; - break; + switch (keycode) + { + case KC_SYSTEM_POWER: usagecode = HID_USAGE_CONSUMER_POWER; break; + case KC_SYSTEM_RESET: usagecode = HID_USAGE_CONSUMER_RESET; break; + case KC_SYSTEM_SLEEP: usagecode = HID_USAGE_CONSUMER_SLEEP; break; + case KC_DISPLAY_BRIGHTI: usagecode = HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT; break; + case KC_DISPLAY_BRIGHTD: usagecode = HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT; break; + case KC_RADIO_CONTROL: usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS; break; + case KC_RADIO_BUTTONS: usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS; break; + case KC_RADIO_LED: usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_LED; break; + case KC_RADIO_SWITCH: usagecode = HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH; break; + case KC_MEDIA_PLAY_PAUSE: usagecode = HID_USAGE_CONSUMER_PLAY_PAUSE; break; + case KC_MEDIA_NEXT_TRACK: usagecode = HID_USAGE_CONSUMER_SCAN_NEXT; break; + case KC_MEDIA_PREV_TRACK: usagecode = HID_USAGE_CONSUMER_SCAN_PREVIOUS; break; + case KC_MEDIA_STOP: usagecode = HID_USAGE_CONSUMER_STOP; break; + case KC_AUDIO_VOL: usagecode = HID_USAGE_CONSUMER_VOLUME; break; + case KC_AUDIO_MUTE: usagecode = HID_USAGE_CONSUMER_MUTE; break; + case KC_AUDIO_BASS: usagecode = HID_USAGE_CONSUMER_BASS; break; + case KC_AUDIO_TREBLE: usagecode = HID_USAGE_CONSUMER_TREBLE; break; + case KC_AUDIO_BASS_BOOST: usagecode = HID_USAGE_CONSUMER_BASS_BOOST; break; + case KC_AUDIO_VOL_UP: usagecode = HID_USAGE_CONSUMER_VOLUME_INCREMENT; break; + case KC_AUDIO_VOL_DOWN: usagecode = HID_USAGE_CONSUMER_VOLUME_DECREMENT; break; + case KC_AUDIO_BASS_UP: usagecode = HID_USAGE_CONSUMER_BASS_INCREMENT; break; + case KC_AUDIO_BASS_DOWN: usagecode = HID_USAGE_CONSUMER_BASS_DECREMENT; break; + case KC_AUDIO_TREBLE_UP: usagecode = HID_USAGE_CONSUMER_TREBLE_INCREMENT; break; + case KC_AUDIO_TREBLE_DOWN: usagecode = HID_USAGE_CONSUMER_TREBLE_DECREMENT; break; + case KC_MSEL: usagecode = HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION; break; + case KC_WWW: usagecode = HID_USAGE_CONSUMER_AL_EMAIL_READER; break; + case KC_CALCULATOR: usagecode = HID_USAGE_CONSUMER_AL_CALCULATOR; break; + case KC_MYCM: usagecode = HID_USAGE_CONSUMER_AL_LOCAL_BROWSER; break; - case KC_WWW_SEARCH: - usagecode = HID_USAGE_CONSUMER_AC_SEARCH; - break; - case KC_WWW_HOME: - usagecode = HID_USAGE_CONSUMER_AC_HOME; - break; - case KC_WWW_BACK: - usagecode = HID_USAGE_CONSUMER_AC_BACK; - break; - case KC_WWW_FORWARD: - usagecode = HID_USAGE_CONSUMER_AC_FORWARD; - break; - case KC_WWW_STOP: - usagecode = HID_USAGE_CONSUMER_AC_STOP; - break; - case KC_WWW_REFRESH: - usagecode = HID_USAGE_CONSUMER_AC_REFRESH; - break; - case KC_WWW_FAVORITES: - usagecode = HID_USAGE_CONSUMER_AC_BOOKMARKS; - break; - case KC_AC_PAN: - usagecode = HID_USAGE_CONSUMER_AC_PAN; - break; + case KC_WWW_SEARCH: usagecode = HID_USAGE_CONSUMER_AC_SEARCH; break; + case KC_WWW_HOME: usagecode = HID_USAGE_CONSUMER_AC_HOME; break; + case KC_WWW_BACK: usagecode = HID_USAGE_CONSUMER_AC_BACK; break; + case KC_WWW_FORWARD: usagecode = HID_USAGE_CONSUMER_AC_FORWARD; break; + case KC_WWW_STOP: usagecode = HID_USAGE_CONSUMER_AC_STOP; break; + case KC_WWW_REFRESH: usagecode = HID_USAGE_CONSUMER_AC_REFRESH; break; + case KC_WWW_FAVORITES: usagecode = HID_USAGE_CONSUMER_AC_BOOKMARKS; break; + case KC_AC_PAN: usagecode = HID_USAGE_CONSUMER_AC_PAN; break; } return usagecode; -} \ No newline at end of file + } \ No newline at end of file diff --git a/firmware/HID.h b/firmware/HID.h index 4ccafb8c..968ef536 100644 --- a/firmware/HID.h +++ b/firmware/HID.h @@ -7,26 +7,26 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + #ifndef HID_H #define HID_H -#include "advanced_keycodes.h" -#include "hid_keycodes.h" #include +#include "hid_keycodes.h" +#include "advanced_keycodes.h" uint16_t hid_GetMediaUsageCode(uint16_t keycode); + #endif \ No newline at end of file diff --git a/firmware/Key.cpp b/firmware/Key.cpp index 08415c19..c0dca877 100644 --- a/firmware/Key.cpp +++ b/firmware/Key.cpp @@ -24,8 +24,9 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE // should be called with the keycode of the default layer Key::Key(uint32_t activation) { - activations[0][0] = static_cast(activation & 0x0000FFFF); - durations[0][0] = static_cast((activation & 0x00FF0000) >> 16); + + keydefs[0][0].activations = static_cast(activation & 0x0000FFFF); + keydefs[0][0].durations = static_cast((activation & 0x00FF0000) >> 16); // last method is the "release" method lastMethod = Method::NONE; @@ -53,11 +54,11 @@ void Key::addActivation(const uint8_t layer, const Method method, const uint32_t break; } - keycode = activations[--tempLayer][methodIndex]; + keycode = keydefs[--tempLayer][methodIndex].activations; } - activations[layer][methodIndex] = keycode; - durations[layer][methodIndex] = static_cast((activation & 0x00FF0000) >> 16); + keydefs[layer][methodIndex].activations = keycode; + keydefs[layer][methodIndex].durations = static_cast((activation & 0x00FF0000) >> 16); /* * tell the state to make sure to look for the added @@ -73,7 +74,7 @@ void Key::press(const unsigned long currentMillis) { state.press(currentMillis); void Key::clear(const unsigned long currentMillis) { state.clear(currentMillis); } -std::pair Key::getActiveActivation(uint8_t layer) { +KeyDefinition Key::getActiveActivation(uint8_t layer) { Method method; switch (state.getState()) { @@ -94,7 +95,8 @@ std::pair Key::getActiveActivation(uint8_t layer) { break; default: lastMethod = Method::NONE; - lastActivation = std::make_pair(0, Duration::MOMENTARY); + lastActivation.activations = 0; + lastActivation.durations = Duration::MOMENTARY; return lastActivation; } @@ -109,7 +111,7 @@ std::pair Key::getActiveActivation(uint8_t layer) { */ if (method != lastMethod) { lastMethod = method; - lastActivation = std::make_pair(activations[layer][methodIndex], durations[layer][methodIndex]); + lastActivation = keydefs[layer][methodIndex]; return lastActivation; } /* @@ -119,11 +121,14 @@ std::pair Key::getActiveActivation(uint8_t layer) { * the layer key doesn't change the meaning of a key * inside that layer */ - else if ((lastMethod == Method::PRESS || lastMethod == Method::MT_HOLD) && lastActivation.second != Duration::TOGGLE) + else if ((lastMethod == Method::PRESS || lastMethod == Method::MT_HOLD) && lastActivation.durations != Duration::TOGGLE) // else if ((lastMethod == Method::PRESS ) && lastActivation.second != Duration::TOGGLE) { return lastActivation; } else { - return std::make_pair(0, Duration::MOMENTARY); + KeyDefinition elseActivation; + elseActivation.activations = 0; + elseActivation.durations = Duration::MOMENTARY; + return elseActivation; } -} +} \ No newline at end of file diff --git a/firmware/Key.h b/firmware/Key.h index 6351f336..367e4758 100644 --- a/firmware/Key.h +++ b/firmware/Key.h @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "KeyState.h" @@ -30,11 +27,15 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #define KEY_H #ifndef MAX_NO_LAYERS -#define MAX_NO_LAYERS 10 // 6 +#define MAX_NO_LAYERS 10 //6 #endif -using ActArray = std::array, MAX_NO_LAYERS>; -using DurArray = std::array, MAX_NO_LAYERS>; +typedef struct { + uint16_t activations; + Duration durations __attribute__((packed)); +} KeyDefinition; + +using KeyDefinitionArray = std::array, MAX_NO_LAYERS>; class Key { public: @@ -44,15 +45,13 @@ class Key { void press(unsigned long currentMillis); void clear(unsigned long currentMillis); void addActivation(const uint8_t layer, const Method method, const uint32_t activation); - std::pair getActiveActivation(uint8_t layer); + KeyDefinition getActiveActivation(uint8_t layer); private: Method lastMethod; - std::pair lastActivation; + KeyDefinition lastActivation; KeyState state; - - ActArray activations; - DurArray durations; + KeyDefinitionArray keydefs; }; #endif /* KEY_H */ diff --git a/firmware/KeyScanner.cpp b/firmware/KeyScanner.cpp index 1a311895..849a7e37 100644 --- a/firmware/KeyScanner.cpp +++ b/firmware/KeyScanner.cpp @@ -7,470 +7,451 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "KeyScanner.h" -KeyScanner::KeyScanner(PersistentState *cfg, DynamicState *stat) { // Constructor - config = cfg; - status = stat; + +KeyScanner::KeyScanner(PersistentState* cfg, DynamicState* stat) { // Constructor + config=cfg; + status=stat; } /**************************************************************************************************************************/ // KEYPRESS - THIS ROUTINE ENACTS A KEYPRESS - DEBOUNCE SHOULD BE HANDLED BY CALLER /**************************************************************************************************************************/ -void KeyScanner::press(unsigned long currentMillis, const int &row, const int &col) { - matrix[row][col].press(currentMillis); - lastPressed = currentMillis; +void KeyScanner::press(unsigned long currentMillis, const int& row, const int& col){ + matrix[row][col].press(currentMillis); + lastPressed = currentMillis; } /**************************************************************************************************************************/ // KEYRELEASE - THIS ROUTINE ENACTS A KEYRELEASE - DEBOUNCE SHOULD BE HANDLED BY CALLER /**************************************************************************************************************************/ -void KeyScanner::release(unsigned long currentMillis, const int &row, const int &col) { matrix[row][col].clear(currentMillis); } +void KeyScanner::release(unsigned long currentMillis, const int& row, const int& col){ + matrix[row][col].clear(currentMillis); +} /**************************************************************************************************************************/ // Called by callback function when remote data is received /**************************************************************************************************************************/ -void KeyScanner::updateRemoteLayer(uint8_t data) { remoteLayer = data; } +void KeyScanner::updateRemoteLayer(uint16_t data) +{ + remoteLayer = data; +} /**************************************************************************************************************************/ // Called by callback function when remote data is received /**************************************************************************************************************************/ -void KeyScanner::updateRemoteReport(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4, uint8_t data5, uint8_t data6) { - remoteMod = data0; - remoteReport[0] = data0; - remoteReport[1] = data1; - remoteReport[2] = data2; - remoteReport[3] = data3; - remoteReport[4] = data4; - remoteReport[5] = data5; - remoteReport[6] = data6; +void KeyScanner::updateRemoteReport(uint8_t data0, uint8_t data1, uint8_t data2,uint8_t data3, uint8_t data4, uint8_t data5,uint8_t data6) +{ + remoteMod=data0; + remoteReport[0]= data0; + remoteReport[1]= data1; + remoteReport[2]= data2; + remoteReport[3]= data3; + remoteReport[4]= data4; + remoteReport[5]= data5; + remoteReport[6]= data6; } + + + /**************************************************************************************************************************/ void KeyScanner::resetReport() { - bufferposition = 1; - currentMod = 0; - currentReport[0] = 0; - currentReport[1] = 0; - currentReport[2] = 0; - currentReport[3] = 0; - currentReport[4] = 0; - currentReport[5] = 0; - currentReport[6] = 0; + bufferposition = 0; + currentMod = 0; + currentReport.keycode[0] = 0; + currentReport.keycode[1] = 0; + currentReport.keycode[2] = 0; + currentReport.keycode[3] = 0; + currentReport.keycode[4] = 0; + currentReport.keycode[5] = 0; + currentReport.modifier = 0; + currentReport.layer = 0; } + /**************************************************************************************************************************/ -void KeyScanner::copyRemoteReport() { -#if BLE_PERIPHERAL == 1 // PERIPHERAL MUST BE HANDLED DIFFERENTLY THAN CENTRAL - OTHERWISE, THE REPORTS WILL JUST KEEP BOUNCING FROM ONE BOARD TO THE OTHER - resetReport(); +void KeyScanner::copyRemoteReport() +{ +#if BLE_PERIPHERAL == 1 // PERIPHERAL MUST BE HANDLED DIFFERENTLY THAN CENTRAL - OTHERWISE, THE REPORTS WILL JUST KEEP BOUNCING FROM ONE BOARD TO THE OTHER + resetReport(); #else - currentMod = remoteMod; - // currentReport[0] = remoteReport[0]; - bufferposition = 1; - if (remoteReport[1] > 0) { - currentReport[bufferposition] = remoteReport[1]; - bufferposition++; - } - if (remoteReport[2] > 0) { - currentReport[bufferposition] = remoteReport[2]; - bufferposition++; - } - if (remoteReport[3] > 0) { - currentReport[bufferposition] = remoteReport[3]; - bufferposition++; - } - if (remoteReport[4] > 0) { - currentReport[bufferposition] = remoteReport[4]; - bufferposition++; - } - if (remoteReport[5] > 0) { - currentReport[bufferposition] = remoteReport[5]; - bufferposition++; - } - if (remoteReport[6] > 0) { - currentReport[bufferposition] = remoteReport[6]; - bufferposition++; - } + currentMod = remoteMod; + currentReport.modifier = remoteMod; + bufferposition = 0; + if (remoteReport[1]>0){currentReport.keycode[bufferposition] = remoteReport[1]; bufferposition++; } + if (remoteReport[2]>0){currentReport.keycode[bufferposition] = remoteReport[2]; bufferposition++; } + if (remoteReport[3]>0){currentReport.keycode[bufferposition] = remoteReport[3]; bufferposition++; } + if (remoteReport[4]>0){currentReport.keycode[bufferposition] = remoteReport[4]; bufferposition++; } + if (remoteReport[5]>0){currentReport.keycode[bufferposition] = remoteReport[5]; bufferposition++; } + if (remoteReport[6]>0){currentReport.keycode[bufferposition] = remoteReport[6]; bufferposition++; } #endif } /**************************************************************************************************************************/ -uint8_t KeyScanner::getlayer(uint16_t layers) { - // this will return the highest layer - uint8_t layerid = 0; - if (layers > 0) // skip the calc if no layers are selected - { +uint8_t KeyScanner::getlayer(uint16_t layers) +{ + //this will return the highest layer + uint8_t layerid = 0; + if (layers>0)// skip the calc if no layers are selected + { while (layers >>= 1) { - layerid++; + layerid++; + } } - } - return layerid; + return layerid; } /**************************************************************************************************************************/ /* - * loop through the entire matrix, checking for + * loop through the entire matrix, checking for * activated keys and adding the activated ones * into a buffer */ -void KeyScanner::updateBuffer() { - activeKeys.clear(); - bool emptyOneshot = false; - // bool emptyOneshotLayer = false; - std::copy(encoderKeys.begin(), encoderKeys.end(), back_inserter(activeKeys)); - // for (auto keycode : encoderKeys) //Consider using std::copy algorithm instead of a raw loop. - // { - // activeKeys.push_back(keycode); - // } - - encoderKeys.clear(); - - // call the tri layer functions... - process_user_layers(detectedlayerkeys); - - uint8_t layer = getlayer(detectedlayerkeys); - - status->layer = layer; - - for (int row = 0; row < MATRIX_ROWS; ++row) { - for (auto &key : matrix[row]) { - uint16_t activeKeycode; - Duration duration; - std::tie(activeKeycode, duration) = key.getActiveActivation(layer); - - if (activeKeycode != 0) { - activeKeys.push_back(activeKeycode); - - /* - * define behavior of - * toggle and oneshot keys - * respectively - * - * empty oneshot when a keycode that's before - * the modifiers is pressed - */ - if (duration == Duration::TOGGLE) { - auto it = std::find(toggleBuffer.begin(), toggleBuffer.end(), activeKeycode); - if (it != toggleBuffer.end()) { - toggleBuffer.erase(it); - } else { - toggleBuffer.push_back(activeKeycode); - } - } else if (duration == Duration::ONE_SHOT) { - auto it = std::find(oneshotBuffer.begin(), oneshotBuffer.end(), activeKeycode); - if (it != oneshotBuffer.end()) { - ; - } else { - oneshotBuffer.push_back(activeKeycode); - uint8_t keyValue = static_cast(activeKeycode & 0x00FF); - if (keyValue >= LAYER_0 && keyValue <= LAYER_F) { - oneshotLayer = - oneshotLayer | - (1 << (keyValue - - 0xF0)); // Add layer to layer mask for next scan They must be handled separately due to needing layers ahead of picking up keycodes. - } - } +void KeyScanner::updateBuffer() +{ + activeKeys.clear(); + bool emptyOneshot = false; + //bool emptyOneshotLayer = false; + std::copy(encoderKeys.begin(), encoderKeys.end(), back_inserter(activeKeys)); + //for (auto keycode : encoderKeys) //Consider using std::copy algorithm instead of a raw loop. + // { + // activeKeys.push_back(keycode); + // } + + encoderKeys.clear(); + +// call the tri layer functions... +process_user_layers(detectedlayerkeys); - } else if ((activeKeycode & 0x00FF) < 0xE0) // it's active, not a modifier, not a layer, not toggle and not one shot, ignore attached modifiers... +uint8_t layer = getlayer(detectedlayerkeys); + +status->layer = layer; + + for(int row = 0; row < MATRIX_ROWS; ++row) { + for (auto& key : matrix[row]) { - emptyOneshot = true; + KeyDefinition activeKey = key.getActiveActivation(layer); + uint16_t activeKeycode = activeKey.activations; + Duration duration = activeKey.durations; + + if (activeKeycode != 0) + { + activeKeys.push_back(activeKeycode); + + /* + * define behavior of + * toggle and oneshot keys + * respectively + * + * empty oneshot when a keycode that's before + * the modifiers is pressed + */ + if (duration == Duration::TOGGLE) + { + auto it = std::find(toggleBuffer.begin(), toggleBuffer.end(), activeKeycode); + if (it != toggleBuffer.end()) + { + toggleBuffer.erase(it); + } + else + { + toggleBuffer.push_back(activeKeycode); + } + } + else if (duration == Duration::ONE_SHOT) + { + auto it = std::find(oneshotBuffer.begin(), oneshotBuffer.end(), activeKeycode); + if (it != oneshotBuffer.end()) + { + ; + } + else + { + oneshotBuffer.push_back(activeKeycode); + uint8_t keyValue = static_cast(activeKeycode & 0x00FF); + if (keyValue >= LAYER_0 && keyValue <= LAYER_F) + { + oneshotLayer = oneshotLayer | (1 << (keyValue - 0xF0)) ; // Add layer to layer mask for next scan They must be handled separately due to needing layers ahead of picking up keycodes. + } + } + + } + else if ((activeKeycode & 0x00FF) < 0xE0) // it's active, not a modifier, not a layer, not toggle and not one shot, ignore attached modifiers... + { + emptyOneshot = true; + + } + + } } - } } - } - - /* - * empty the toggle - * buffer into the main buffer and empty the - * oneshot buffer if a non-oneshot - * key has been pressed - */ - - std::copy(toggleBuffer.begin(), toggleBuffer.end(), back_inserter(activeKeys)); - - if (emptyOneshot) { - std::copy(oneshotBuffer.begin(), oneshotBuffer.end(), back_inserter(activeKeys)); - oneshotBuffer.clear(); - oneshotLayer = 0; - } + + /* + * empty the toggle + * buffer into the main buffer and empty the + * oneshot buffer if a non-oneshot + * key has been pressed + */ + + std::copy(toggleBuffer.begin(), toggleBuffer.end(), back_inserter(activeKeys)); + + if (emptyOneshot) + { + std::copy(oneshotBuffer.begin(), oneshotBuffer.end(), back_inserter(activeKeys)); + oneshotBuffer.clear(); + oneshotLayer = 0; + } } /**************************************************************************************************************************/ // inspired by QMK's update_tri_layer_state... Modified to replace instead of adding to detected layer keys // can be called multiple times to catch multiple 2-layer patterns /**************************************************************************************************************************/ -void KeyScanner::process_for_tri_layers(uint8_t if_layer1, uint8_t and_layer2, uint8_t use_layer3) { - uint16_t mask12 = (1UL << if_layer1) | (1UL << and_layer2); // merge the two layers with bitwise shifts to detect the triggered layer keys - uint16_t mask3 = 1UL << use_layer3; // create a mask to return the resulting layer - detectedlayerkeys = (detectedlayerkeys & mask12) == mask12 - ? ((detectedlayerkeys & ~mask12) | mask3) - : (detectedlayerkeys); // if detectedlayerkeys has mask12 in it,remove mask12 and add extra layer; otherwise return as is. +void KeyScanner::process_for_tri_layers(uint8_t if_layer1, uint8_t and_layer2, uint8_t use_layer3) +{ + uint16_t mask12 = (1UL << if_layer1) | (1UL << and_layer2); // merge the two layers with bitwise shifts to detect the triggered layer keys + uint16_t mask3 = 1UL << use_layer3; // create a mask to return the resulting layer + detectedlayerkeys = (detectedlayerkeys & mask12) == mask12 ? ((detectedlayerkeys & ~mask12) | mask3) : (detectedlayerkeys); // if detectedlayerkeys has mask12 in it,remove mask12 and add extra layer; otherwise return as is. } -void KeyScanner::add_to_encoderKeys(uint16_t keycode) { encoderKeys.push_back(keycode); } +void KeyScanner::add_to_encoderKeys(uint16_t keycode) +{ + encoderKeys.push_back(keycode); +} -#if USER_LAYER_FUNCTION == 1 -void process_user_layers(uint16_t layermask) { ; } +#if USER_LAYER_FUNCTION == 1 +void process_user_layers(uint16_t layermask) +{ + ; +} #endif /**************************************************************************************************************************/ // Scan for layer changes - must do this first. /**************************************************************************************************************************/ -bool KeyScanner::updateLayer() { - uint16_t prevlayer = localLayer; // remember last layer mask - detectedlayerkeys = localLayer | remoteLayer | oneshotLayer; // merge the layer masks - - // read through the matrix and select all of the - // currently pressed keys - updateBuffer(); - - /* - * iterate through all of the currently pressed keys, if - * a layer key is pressed, change the layer mask accordingly - * if no other layers are set in the buffer, the default - * layer should be chosen (=0) - */ - localLayer = 0; // reset the layer mask before we fill it again - for (auto keycode : activeKeys) { - // the first byte is the actual HID keycode of the key - uint8_t keyValue = static_cast(keycode & 0x00FF); - if (keyValue >= LAYER_0 && keyValue <= LAYER_F) { - localLayer = localLayer | (1 << (keyValue - 0xF0)); // Add layer to layer mask for next scan +bool KeyScanner::updateLayer() +{ + uint16_t prevlayer = localLayer; // remember last layer mask + detectedlayerkeys = localLayer | remoteLayer | oneshotLayer; // merge the layer masks + // TODO: check is remotelayer being sent/received is a bitmasked layer + // oneshotLayer is a bitmasked layer + // localLayer is a bitmasked layer + + + // read through the matrix and select all of the + // currently pressed keys + updateBuffer(); + + /* + * iterate through all of the currently pressed keys, if + * a layer key is pressed, change the layer mask accordingly + * if no other layers are set in the buffer, the default + * layer should be chosen (=0) + */ + localLayer = 0; // reset the layer mask before we fill it again + for (auto keycode : activeKeys) + { + // the first byte is the actual HID keycode of the key + uint8_t keyValue = static_cast(keycode & 0x00FF); + if (keyValue >= LAYER_0 && keyValue <= LAYER_F) + { + localLayer = localLayer | (1 << (keyValue - 0xF0)) ; // Add layer to layer mask for next scan + } } - } - - layerChanged = (prevlayer != localLayer); - return layerChanged; + + + layerChanged = (prevlayer != localLayer); + return layerChanged; } + /**************************************************************************************************************************/ -bool KeyScanner::getReport() { - previousReport[0] = currentReport[0]; - previousReport[1] = currentReport[1]; - previousReport[2] = currentReport[2]; - previousReport[3] = currentReport[3]; - previousReport[4] = currentReport[4]; - previousReport[5] = currentReport[5]; - previousReport[6] = currentReport[6]; - previousReport[7] = currentReport[7]; - - resetReport(); - copyRemoteReport(); - updateLayer(); - if (remotespecialkeycode > 0) { - activeKeys.push_back(remotespecialkeycode); - remotespecialkeycode = 0; - } - - // process single-key substs (macros) first. - if (combos.anyMacrosConfigured()) { - if (combos.anyMacrosActive(activeKeys)) { - activeKeys = combos.processActiveMacros(activeKeys); +bool KeyScanner::getReport() +{ + previousReport = currentReport; + + resetReport(); + copyRemoteReport(); + updateLayer(); + if (remotespecialkeycode>0){ + activeKeys.push_back(remotespecialkeycode); + remotespecialkeycode=0; } - } - // process combos before generating HID reports - if (combos.anyCombosConfigured()) { - uint8_t triggercount = combos.countActiveCombosKeys(activeKeys); - if (triggercount > 1) // we have a potential combo present - { - uint8_t activecount = combos.findActiveCombos(activeKeys); - if (activecount > 0) // at least 1 - { - if (activecount == 1) // exactly 1 - { - activeKeys = combos.processActiveKeycodewithCombos(activeKeys); - combotimer = status->timestamp; // reset timers to current timestamp. - triggerkeytimer = status->timestamp; - } else // more than 2 + #ifdef ENABLE_COMBOS + // process single-key substs (macros) first. + if (combos.anyMacrosConfigured()) { - if (status->timestamp - combotimer > 200) // timeout to send biggest one... - { - activeKeys = combos.processActiveKeycodewithCombos(activeKeys); - combotimer = status->timestamp; // reset timers to current timestamp. - triggerkeytimer = status->timestamp; - } else // we are still transitioning remove all potential combo keys... - { - activeKeys = combos.processActiveKeycodewithComboKeys(activeKeys); - } + if(combos.anyMacrosActive(activeKeys)) + { + activeKeys = combos.processActiveMacros(activeKeys); + } } - } else { // if none are active, we might have to remove keycodes in case we are transitionning to/from a combo - if (status->timestamp - combotimer < 75) // Transitionning out of a combo + + // process combos before generating HID reports + if (combos.anyCombosConfigured()) + { + uint8_t triggercount = combos.countActiveCombosKeys(activeKeys); + if (triggercount>1)// we have a potential combo present + { + uint8_t activecount = combos.findActiveCombos(activeKeys); + if (activecount>0) // at least 1 + { + if (activecount==1) // exactly 1 + { + activeKeys = combos.processActiveKeycodewithCombos(activeKeys); + combotimer = status->timestamp; // reset timers to current timestamp. + triggerkeytimer = status->timestamp; + } + else // more than 2 + { + if (status->timestamp - combotimer > 200)// timeout to send biggest one... + { + activeKeys = combos.processActiveKeycodewithCombos(activeKeys); + combotimer = status->timestamp; // reset timers to current timestamp. + triggerkeytimer = status->timestamp; + } + else // we are still transitioning remove all potential combo keys... + { + activeKeys = combos.processActiveKeycodewithComboKeys(activeKeys); + } + } + } + else + { // if none are active, we might have to remove keycodes in case we are transitionning to/from a combo + if (status->timestamp - combotimer < 75)// Transitionning out of a combo + { + activeKeys = combos.processActiveKeycodewithComboKeys(activeKeys); + } + } + } + else + { + if (triggercount==1) // we have a key used in a combo being pressed + { + // check if we have a "mono" + /* if (combos.findActiveCombos(activeKeys)) // at least 1 + { + if (combos.keycodebuffertosend.empty()) // buffer has stuff in it - skip adding the "mono" + { + activeKeys = combos.processActiveKeycodewithCombos(activeKeys); + combotimer = status->timestamp; // reset timers to current timestamp. + triggerkeytimer = status->timestamp; + } + } + else */ + if (status->timestamp - triggerkeytimer < 75)// Transitionning out/in of a combo + { + activeKeys = combos.processActiveKeycodewithComboKeys(activeKeys); + } + } + else + { + triggerkeytimer = status->timestamp; + combotimer = status->timestamp; + } + } + } + + #endif + + for (auto keycode : activeKeys) + { + auto hidKeycode = static_cast(keycode & 0x00FF); + auto extraModifiers = static_cast((keycode & 0xFF00) >> 8); + + if (hidKeycode >= KC_A && hidKeycode <= KC_EXSEL) { - activeKeys = combos.processActiveKeycodewithComboKeys(activeKeys); + currentReport.keycode[bufferposition] = hidKeycode; + bufferposition++; } - } - } else { - if (triggercount == 1) // we have a key used in a combo being pressed - { - // check if we have a "mono" - /* if (combos.findActiveCombos(activeKeys)) // at least 1 - { - if (combos.keycodebuffertosend.empty()) // buffer has stuff in it - skip adding the "mono" - { - activeKeys = combos.processActiveKeycodewithCombos(activeKeys); - combotimer = status->timestamp; // reset timers to current timestamp. - triggerkeytimer = status->timestamp; - } - } - else */ - if (status->timestamp - triggerkeytimer < 75) // Transitionning out/in of a combo + + //check if the hid keycode contains a modifier. // also check for macros. + switch (hidKeycode) { + case KC_LCTRL: currentMod |= 1; currentMod |= extraModifiers; break; + case KC_LSHIFT: currentMod |= 2; currentMod |= extraModifiers; break; + case KC_LALT: currentMod |= 4; currentMod |= extraModifiers; break; + case KC_LGUI: currentMod |= 8; currentMod |= extraModifiers; break; + case KC_RCTRL: currentMod |= 16; currentMod |= extraModifiers; break; + case KC_RSHIFT: currentMod |= 32; currentMod |= extraModifiers; break; + case KC_RALT: currentMod |= 64; currentMod |= extraModifiers; break; + case KC_RGUI: currentMod |= 128; currentMod |= extraModifiers; break; + case KC_RESERVED_A5: if(!processingmacros){macro = keycode; processingmacros=true; } extraModifiers=0; break; // KC_RESERVED_A5 is the keycode marker for user macros. + case KC_RESERVED_A6: if(!processingmacros){specialfunction = keycode; processingmacros=true;} extraModifiers=0; break; // KC_RESERVED_A6 is the keycode marker for special keyboard functions. + case KC_RESERVED_A7: if(!processingmacros){consumer = keycode; processingmacros=true;} extraModifiers=0; break; // KC_RESERVED_A7 is the keycode marker for consumer reports. + case KC_RESERVED_A8: consumer = keycode; extraModifiers=0; break; // KC_RESERVED_A8 is the keycode marker for repeating consumer reports. + case KC_RESERVED_A9: mouse = keycode; extraModifiers=0; break; // KC_RESERVED_A8 is the keycode marker for mouse reports. Mousekeys can be repeated... We therefore don't need the macro logic + case KC_RESERVED_AA: special_key = keycode; extraModifiers=0; break; // KC_RESERVED_AA is the keycode marker for special keys. + case KC_RESERVED_AB: if(!processingmacros){specialfunction = keycode; processingmacros=true;} extraModifiers=0; break; // KC_RESERVED_AB keycode for marking this as a specialfunction for international/special characters (ALT-0233 = é). + } + //add all of the extra modifiers into the curren modifier + currentMod |= extraModifiers; + if (bufferposition == 6) { - activeKeys = combos.processActiveKeycodewithComboKeys(activeKeys); + bufferposition = 0; } - } else { - triggerkeytimer = status->timestamp; - combotimer = status->timestamp; - } } - } - for (auto keycode : activeKeys) { - auto hidKeycode = static_cast(keycode & 0x00FF); - auto extraModifiers = static_cast((keycode & 0xFF00) >> 8); + currentReport.modifier = currentMod; + currentReport.layer = localLayer; + - if (hidKeycode >= KC_A && hidKeycode <= KC_EXSEL) { - currentReport[bufferposition] = hidKeycode; - ++bufferposition; - } +if (activeKeys.empty() && processingmacros) {processingmacros = false;} - // check if the hid keycode contains a modifier. // also check for macros. - switch (hidKeycode) { - case KC_LCTRL: - currentMod |= 1; - currentMod |= extraModifiers; - break; - case KC_LSHIFT: - currentMod |= 2; - currentMod |= extraModifiers; - break; - case KC_LALT: - currentMod |= 4; - currentMod |= extraModifiers; - break; - case KC_LGUI: - currentMod |= 8; - currentMod |= extraModifiers; - break; - case KC_RCTRL: - currentMod |= 16; - currentMod |= extraModifiers; - break; - case KC_RSHIFT: - currentMod |= 32; - currentMod |= extraModifiers; - break; - case KC_RALT: - currentMod |= 64; - currentMod |= extraModifiers; - break; - case KC_RGUI: - currentMod |= 128; - currentMod |= extraModifiers; - break; - case KC_RESERVED_A5: - if (!processingmacros) { - macro = keycode; - processingmacros = true; - } - extraModifiers = 0; - break; // KC_RESERVED_A5 is the keycode marker for user macros. - case KC_RESERVED_A6: - if (!processingmacros) { - specialfunction = keycode; - processingmacros = true; - } - extraModifiers = 0; - break; // KC_RESERVED_A6 is the keycode marker for special keyboard functions. - case KC_RESERVED_A7: - if (!processingmacros) { - consumer = keycode; - processingmacros = true; - } - extraModifiers = 0; - break; // KC_RESERVED_A7 is the keycode marker for consumer reports. - case KC_RESERVED_A8: - consumer = keycode; - extraModifiers = 0; - break; // KC_RESERVED_A8 is the keycode marker for repeating consumer reports. - case KC_RESERVED_A9: - mouse = keycode; - extraModifiers = 0; - break; // KC_RESERVED_A8 is the keycode marker for mouse reports. Mousekeys can be repeated... We therefore don't need the macro logic - case KC_RESERVED_AA: - special_key = keycode; - extraModifiers = 0; - break; // KC_RESERVED_AA is the keycode marker for special keys. - case KC_RESERVED_AB: - if (!processingmacros) { - specialfunction = keycode; - processingmacros = true; - } - extraModifiers = 0; - break; // KC_RESERVED_AB keycode for marking this as a specialfunction for international/special characters (ALT-0233 = é). + if(currentReport != previousReport) + { + reportChanged = true; + status->lastreporttime = status->timestamp; + if (processingmacros) + if ((currentReport.modifier == 0 ) + && (currentReport.keycode[0] == 0 ) + && (currentReport.keycode[1] == 0 ) + && (currentReport.keycode[2] == 0 ) + && (currentReport.keycode[3] == 0 ) + && (currentReport.keycode[4] == 0 ) + && (currentReport.keycode[5] == 0 )) + {processingmacros=false; macro=0; specialfunction=0; consumer=0; mouse=0;} } - // add all of the extra modifiers into the curren modifier - currentMod |= extraModifiers; - if (bufferposition == 7) { - bufferposition = 1; + else + {reportChanged = false; + } - } - - currentReport[0] = currentMod; - currentReport[7] = localLayer; - - if (activeKeys.empty() && processingmacros) { - processingmacros = false; - } - - if ((currentReport[0] != previousReport[0]) | (currentReport[1] != previousReport[1]) | (currentReport[2] != previousReport[2]) | - (currentReport[3] != previousReport[3]) | (currentReport[4] != previousReport[4]) | (currentReport[5] != previousReport[5]) | - (currentReport[6] != previousReport[6]) | (currentReport[7] != previousReport[7])) { - reportChanged = true; - status->lastreporttime = status->timestamp; - if (processingmacros) - if ((currentReport[0] == 0) && (currentReport[1] == 0) && (currentReport[2] == 0) && (currentReport[3] == 0) && (currentReport[4] == 0) && - (currentReport[5] == 0) && (currentReport[6] == 0)) { - processingmacros = false; - macro = 0; - specialfunction = 0; - consumer = 0; - mouse = 0; - } - } else { - reportChanged = false; - } - if ((status->timestamp) - (status->lastreporttime) > 125) // make sure we have at least 1 report every 125 ms even if we don't type. - { - reportChanged = true; - status->lastreporttime = status->timestamp; - } - - return reportChanged; + if ((status->timestamp)-(status->lastreporttime) > 125) // make sure we have at least 1 report every 125 ms even if we don't type. + { + reportChanged = true; + status->lastreporttime = status->timestamp; + } + + + return reportChanged; } -unsigned long KeyScanner::getLastPressed() { return lastPressed; } +unsigned long KeyScanner::getLastPressed() +{ + return lastPressed; +} /**************************************************************************************************************************/ -uint8_t KeyScanner::currentReport[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint8_t KeyScanner::remoteReport[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint8_t KeyScanner::previousReport[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -bool KeyScanner::layerChanged = false; -bool KeyScanner::reportChanged = false; -bool KeyScanner::processingmacros = false; +HIDKeyboard KeyScanner::currentReport = {0, {0, 0 ,0, 0, 0, 0}, 0}; +HIDKeyboard KeyScanner::previousReport = {0, {0, 0 ,0, 0, 0, 0}, 0}; + +uint8_t KeyScanner::remoteReport[8] = {0, 0, 0 ,0, 0, 0, 0, 0}; + +bool KeyScanner::layerChanged = false; +bool KeyScanner::reportChanged = false; +bool KeyScanner::processingmacros = false; uint16_t KeyScanner::detectedlayerkeys = 0; uint16_t KeyScanner::localLayer = 0; uint16_t KeyScanner::macro = 0; @@ -488,12 +469,12 @@ uint8_t KeyScanner::remoteMod = 0; uint8_t KeyScanner::currentMod = 0; unsigned long KeyScanner::lastPressed = 0; uint8_t KeyScanner::bufferposition = 0; -std::vector KeyScanner::activeKeys{}; -std::vector KeyScanner::encoderKeys{}; -std::vector KeyScanner::macroBuffer{}; -std::vector KeyScanner::toggleBuffer{}; -std::vector KeyScanner::leaderBuffer{}; -std::vector KeyScanner::oneshotBuffer{}; - -PersistentState *KeyScanner::config = NULL; -DynamicState *KeyScanner::status = NULL; +std::vector KeyScanner::activeKeys {}; +std::vector KeyScanner::encoderKeys {}; +std::vector KeyScanner::macroBuffer {}; +std::vector KeyScanner::toggleBuffer {}; +std::vector KeyScanner::leaderBuffer {}; +std::vector KeyScanner::oneshotBuffer {}; + +PersistentState* KeyScanner::config = NULL; +DynamicState* KeyScanner::status = NULL; diff --git a/firmware/KeyScanner.h b/firmware/KeyScanner.h index 9b771a28..9f728dbc 100644 --- a/firmware/KeyScanner.h +++ b/firmware/KeyScanner.h @@ -7,95 +7,99 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ //#include #ifndef KEYSCANNER_H #define KEYSCANNER_H -#include "Key.h" //already included through keymap.h do we need it here? -#include "KeyState.h" -#include "advanced_keycodes.h" -#include "combo_engine.h" -#include "firmware_config.h" +#include +#include +#include +#include +#include #include "hid_keycodes.h" #include "keyboard_config.h" +#include "firmware_config.h" #include "keymap.h" -#include -#include -#include -#include -#include +#include "KeyState.h" +#include "advanced_keycodes.h" +#include "combo_engine.h" +#include "Key.h" //already included through keymap.h do we need it here? + -#ifndef USER_LAYER_FUNCTION -#define USER_LAYER_FUNCTION 1 +#ifndef USER_LAYER_FUNCTION +#define USER_LAYER_FUNCTION 1 void process_user_layers(uint16_t layermask); #endif class KeyScanner { -public: - KeyScanner(PersistentState *cfg, DynamicState *stat); - - static void press(unsigned long millis, const int &row, const int &col); - static void release(unsigned long millis, const int &row, const int &col); - static void updateRemoteReport(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4, uint8_t data5, uint8_t data6); - static void updateRemoteLayer(uint8_t data0); - static void process_for_tri_layers(uint8_t if_layer1, uint8_t and_layer2, uint8_t use_layer3); - static void add_to_encoderKeys(uint16_t keycode); - static bool getReport(); - static unsigned long getLastPressed(); - static bool layerChanged; - static bool reportChanged; - static uint16_t macro; - static uint16_t specialfunction; - static uint16_t consumer; - static uint16_t mouse; - static uint16_t localLayer; - static uint16_t special_key; - static uint16_t remotespecialkeycode; - static uint8_t currentReport[8]; - - static uint8_t bufferposition; - -private: - static void resetReport(); - static void updateBuffer(); - static bool updateLayer(); - - static void copyRemoteReport(); - - static uint8_t getlayer(uint16_t layers); - static bool processingmacros; - static uint16_t oneshotLayer; - static uint8_t remoteReport[8]; - static uint8_t previousReport[8]; - static unsigned long lastPressed; - static uint16_t detectedlayerkeys; - static uint16_t remoteLayer; - static uint32_t combotimer; - static uint32_t triggerkeytimer; - static uint8_t remoteMod; - static uint8_t currentMod; - - static std::vector activeKeys; - static std::vector encoderKeys; - static std::vector macroBuffer; // not used - static std::vector toggleBuffer; - static std::vector leaderBuffer; // not used - static std::vector oneshotBuffer; - - static PersistentState *config; - static DynamicState *status; + public: + + KeyScanner(PersistentState* cfg, DynamicState* stat); + + static void press(unsigned long millis, const int& row, const int& col); + static void release(unsigned long millis, const int& row, const int& col); + static void updateRemoteReport(uint8_t data0 , uint8_t data1, uint8_t data2,uint8_t data3, uint8_t data4, uint8_t data5,uint8_t data6); + static void updateRemoteLayer(uint16_t data0); + static void process_for_tri_layers(uint8_t if_layer1, uint8_t and_layer2, uint8_t use_layer3); + static void add_to_encoderKeys(uint16_t keycode); + static bool getReport(); + static unsigned long getLastPressed(); + static bool layerChanged; + static bool reportChanged; + static uint16_t macro; + static uint16_t specialfunction; + static uint16_t consumer; + static uint16_t mouse; + static uint16_t localLayer; + static uint16_t special_key; + static uint16_t remotespecialkeycode; + //static uint8_t currentReport[8]; + static HIDKeyboard currentReport; + + static uint8_t bufferposition; + + private: + static void resetReport(); + static void updateBuffer(); + static bool updateLayer(); + + static void copyRemoteReport(); + + + static uint8_t getlayer(uint16_t layers); + static bool processingmacros; + static uint16_t oneshotLayer; + static uint8_t remoteReport[8]; + //static HIDKeyboard remoteReport; + //static uint8_t previousReport[8]; + static HIDKeyboard previousReport; + + static unsigned long lastPressed; + static uint16_t detectedlayerkeys; + static uint16_t remoteLayer; + static uint32_t combotimer; + static uint32_t triggerkeytimer; + static uint8_t remoteMod; + static uint8_t currentMod; + + static std::vector activeKeys; + static std::vector encoderKeys; + static std::vector macroBuffer; // not used + static std::vector toggleBuffer; + static std::vector leaderBuffer; // not used + static std::vector oneshotBuffer; + + static PersistentState* config; + static DynamicState* status; }; #endif /* KEYSCANNER_H */ diff --git a/firmware/KeyState.cpp b/firmware/KeyState.cpp index dad98323..574210a1 100644 --- a/firmware/KeyState.cpp +++ b/firmware/KeyState.cpp @@ -7,80 +7,98 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "KeyState.h" KeyState::KeyState() { - state = State::RELEASED; - lastChanged = 0; - canDoubletap = false; - checkDoubleTap = false; - checkModTap = false; + state = State::RELEASED; + lastChanged = 0; + canDoubletap = false; + checkDoubleTap = false; + checkModTap = false; } -void KeyState::addMethod(Method method) { - if (method == Method::MT_TAP || method == Method::MT_HOLD) { - checkModTap = true; - } else if (method == Method::DT_TAP || method == Method::DT_DOUBLETAP) { - checkDoubleTap = true; - } +void KeyState::addMethod(Method method) +{ + if (method == Method::MT_TAP || method == Method::MT_HOLD) { + checkModTap = true; + } + else if (method == Method::DT_TAP || method == Method::DT_DOUBLETAP) + { + checkDoubleTap = true; + } } -void KeyState::press(unsigned long currentMillis) { - // the time between now and the last change - unsigned long timeElapsed = currentMillis - lastChanged; - - /* - * if the state is pressed and a certain amount of time has passed - * since the state has been changed, the key is held - * if the previous state isn't pressed, then set it to - * pressed now and update the change time - */ - if (state == State::PRESSED && timeElapsed > TIME_TILL_HOLD && checkModTap) { - state = State::MT_HELD; - lastChanged = currentMillis; - } else if ((state == State::RELEASED || state == State::MT_TAPPED)) { - if (canDoubletap && checkDoubleTap) { - state = State::DT_DOUBLETAPPED; - canDoubletap = false; - } else { - state = State::PRESSED; - canDoubletap = true; +void KeyState::press(unsigned long currentMillis) +{ + // the time between now and the last change + unsigned long timeElapsed = currentMillis - lastChanged; + + /* + * if the state is pressed and a certain amount of time has passed + * since the state has been changed, the key is held + * if the previous state isn't pressed, then set it to + * pressed now and update the change time + */ + if (state == State::PRESSED && timeElapsed > TIME_TILL_HOLD && checkModTap) + { + state = State::MT_HELD; + lastChanged = currentMillis; + } + else if ((state == State::RELEASED || state == State::MT_TAPPED)) + { + if (canDoubletap && checkDoubleTap) + { + state = State::DT_DOUBLETAPPED; + canDoubletap = false; + } + else + { + state = State::PRESSED; + canDoubletap = true; + } + + lastChanged = currentMillis; } +} - lastChanged = currentMillis; - } +void KeyState::clear(unsigned long currentMillis) +{ + // the time between now and the last change + unsigned long timeElapsed = currentMillis - lastChanged; + + // if the previous state was pressed, then set the state to + // tapped, otherwise set it to released + if (state == State::PRESSED && checkModTap) + { + state = State::MT_TAPPED; + lastChanged = currentMillis; + } + else if (timeElapsed > DOUBLETAP_TIME_LIMIT && canDoubletap && checkDoubleTap) + { + state = State::DT_TAPPED; + lastChanged = currentMillis; + canDoubletap = false; + } + else if (state != State::RELEASED && timeElapsed > TIME_TILL_RELEASE) + { + state = State::RELEASED; + lastChanged = currentMillis; + } } -void KeyState::clear(unsigned long currentMillis) { - // the time between now and the last change - unsigned long timeElapsed = currentMillis - lastChanged; - - // if the previous state was pressed, then set the state to - // tapped, otherwise set it to released - if (state == State::PRESSED && checkModTap) { - state = State::MT_TAPPED; - lastChanged = currentMillis; - } else if (timeElapsed > DOUBLETAP_TIME_LIMIT && canDoubletap && checkDoubleTap) { - state = State::DT_TAPPED; - lastChanged = currentMillis; - canDoubletap = false; - } else if (state != State::RELEASED && timeElapsed > TIME_TILL_RELEASE) { - state = State::RELEASED; - lastChanged = currentMillis; - } +KeyState::State KeyState::getState() const +{ + return state; } -KeyState::State KeyState::getState() const { return state; } + diff --git a/firmware/KeyState.h b/firmware/KeyState.h index 25ae79f3..a3260b10 100644 --- a/firmware/KeyState.h +++ b/firmware/KeyState.h @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "advanced_keycodes.h" @@ -25,58 +22,64 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #ifndef KEY_STATE #define KEY_STATE -#include "firmware_config.h" + #include "keyboard_config.h" +#include "firmware_config.h" + + + #ifndef DOUBLETAP_TIME_LIMIT -#define DOUBLETAP_TIME_LIMIT 200 + #define DOUBLETAP_TIME_LIMIT 200 #endif #ifndef TIME_TILL_HOLD -#define TIME_TILL_HOLD 200 + #define TIME_TILL_HOLD 200 #endif #ifndef TIME_TILL_RELEASE -#define TIME_TILL_RELEASE 20 // was 80 + #define TIME_TILL_RELEASE 20 // was 80 #endif enum class Method { - PRESS = 0, - MT_TAP = 1, - MT_HOLD = 2, - DT_TAP = 3, - DT_DOUBLETAP = 4, - NONE = 5, + PRESS = 0, + MT_TAP = 1, + MT_HOLD = 2, + DT_TAP = 3, + DT_DOUBLETAP = 4, + NONE = 5, }; -class KeyState { -public: - KeyState(); - - void press(unsigned long currentMillis); - void clear(unsigned long currentMillis); - - void addMethod(Method method); +class KeyState +{ + public: + KeyState(); + + void press(unsigned long currentMillis); + void clear(unsigned long currentMillis); - enum class State { - RELEASED, // simply released - PRESSED, // a simple press + void addMethod(Method method); - MT_TAPPED, // a released press - MT_HELD, // a constant press + enum class State + { + RELEASED, // simply released + PRESSED, // a simple press - DT_TAPPED, // if a tap can't be doubled anymore - DT_DOUBLETAPPED // two presses with a release/tap in between - }; + MT_TAPPED, // a released press + MT_HELD, // a constant press + + DT_TAPPED, // if a tap can't be doubled anymore + DT_DOUBLETAPPED // two presses with a release/tap in between + }; - State getState() const; + State getState() const; -private: - bool canDoubletap; - bool checkModTap, checkDoubleTap; + private: + bool canDoubletap; + bool checkModTap, checkDoubleTap; - // std::array<5, bool> checkMethods; + //std::array<5, bool> checkMethods; - State state; - unsigned long lastChanged; + State state; + unsigned long lastChanged; }; #endif diff --git a/firmware/LedPwm.cpp b/firmware/LedPwm.cpp index ca4969c1..19a52376 100644 --- a/firmware/LedPwm.cpp +++ b/firmware/LedPwm.cpp @@ -7,123 +7,109 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "LedPwm.h" -// extern PersistentState keyboardconfig; +//extern PersistentState keyboardconfig; int16_t pwmval = DEFAULT_PWM_VALUE; + uint16_t pwmstepsize = 128; uint16_t pwmmaxvalue = DEFAULT_PWM_MAX_VALUE; bool breathingincreasing = true; uint8_t PWMMode = 1; /**************************************************************************************************************************/ -void setPWMMode(int mode) { PWMMode = mode; } +void setPWMMode(int mode) +{ + PWMMode = mode; +} + +void incPWMStepSize(){ +if (pwmstepsize < (1024 - pwmstepsize)) {pwmstepsize = pwmstepsize+8 ;} else {pwmstepsize = 1024 ;} -void incPWMStepSize() { - if (pwmstepsize < (1024 - pwmstepsize)) { - pwmstepsize = pwmstepsize + 8; - } else { - pwmstepsize = 1024; - } } -void decPWMStepSize() { +void decPWMStepSize(){ - if (pwmstepsize > 8) { - pwmstepsize = pwmstepsize - 8; - } else { - pwmstepsize = 8; - } +if (pwmstepsize > 8) {pwmstepsize = pwmstepsize-8 ;} else {pwmstepsize = 8 ;} } -void incPWMMaxVal() { - if (pwmmaxvalue < (DEFAULT_PWM_MAX_VALUE - pwmstepsize * 4)) { - pwmmaxvalue = pwmmaxvalue + pwmstepsize * 4; - } else { - pwmmaxvalue = DEFAULT_PWM_MAX_VALUE; - } +void incPWMMaxVal(){ + if (pwmmaxvalue < (DEFAULT_PWM_MAX_VALUE - pwmstepsize*4)) {pwmmaxvalue = pwmmaxvalue+pwmstepsize*4 ;} else {pwmmaxvalue = DEFAULT_PWM_MAX_VALUE ;} } -void decPWMMaxVal() { - if (pwmmaxvalue > pwmstepsize * 4) { - pwmmaxvalue = pwmmaxvalue - pwmstepsize * 4; - } else { - pwmmaxvalue = 0; - } +void decPWMMaxVal(){ + if (pwmmaxvalue > pwmstepsize*4) {pwmmaxvalue = pwmmaxvalue-pwmstepsize*4 ;} else {pwmmaxvalue = 0 ;} +} +void PWMSetMaxVal() +{ + pwmmaxvalue = DEFAULT_PWM_MAX_VALUE ; } -void PWMSetMaxVal() { pwmmaxvalue = DEFAULT_PWM_MAX_VALUE; } -void stepPWMMode() { +void stepPWMMode() +{ PWMMode++; - if (PWMMode > 3) { - PWMMode = 0; - } + if (PWMMode > 3){PWMMode=0;} } + /**************************************************************************************************************************/ -void updatePWM(unsigned long timesincelastkeypress) { updatePWM(PWMMode, timesincelastkeypress); } -void updatePWM(int mode, unsigned long timesincelastkeypress) { +void updatePWM(unsigned long timesincelastkeypress) +{ +updatePWM(PWMMode, timesincelastkeypress); +} +void updatePWM(int mode, unsigned long timesincelastkeypress) +{ - switch (mode) { + switch (mode) + { case 0: // OFF. - sendPWM(0); - break; - - case 1: // Bright when typing, dim when not typing - if (timesincelastkeypress < PWM_TOUCH_INTERVAL) { - pwmval = pwmmaxvalue; - - } else { - if (pwmval > pwmstepsize) { - pwmval = pwmval - pwmstepsize; - } else { - pwmval = 0; - } - } - sendPWM(cie_lightness(pwmval)); - if (pwmval < pwmstepsize) { sendPWM(0); - } break; - case 2: // Breathing - if (breathingincreasing) { - if (pwmval < (pwmmaxvalue - pwmstepsize)) { - pwmval = pwmval + pwmstepsize; - } else { - pwmval = pwmmaxvalue; - breathingincreasing = false; - } - - } else { - if (pwmval > pwmstepsize) { - pwmval = pwmval - pwmstepsize; - } else { - pwmval = 0; - breathingincreasing = true; - } - } - sendPWM(cie_lightness(pwmval)); - if (pwmval < pwmstepsize) { - sendPWM(0); - } + case 1: // Bright when typing, dim when not typing + if (timesincelastkeypress pwmstepsize) {pwmval = pwmval-pwmstepsize ;} else {pwmval = 0 ;} + } + sendPWM(cie_lightness(pwmval)); + if (pwmval pwmstepsize) {pwmval = pwmval-pwmstepsize ;} else {pwmval = 0 ;breathingincreasing = true;} + } + sendPWM(cie_lightness(pwmval)); + if (pwmval #include "keyboard_config.h" +#include "firmware_config.h" #include "nrf52gpio.h" -#include + void updatePWM(int mode, unsigned long timesincelastkeypress); void updatePWM(unsigned long timesincelastkeypress); + void setPWMMode(int mode); uint16_t cie_lightness(uint16_t v); void PWMSetMaxVal(); diff --git a/firmware/LedRGB.cpp b/firmware/LedRGB.cpp index 2d00c406..e7828373 100644 --- a/firmware/LedRGB.cpp +++ b/firmware/LedRGB.cpp @@ -7,23 +7,20 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "LedRGB.h" #ifdef NEOPIXEL_AVAILABLE -Adafruit_NeoPixel pixels = Adafruit_NeoPixel(); + Adafruit_NeoPixel pixels = Adafruit_NeoPixel(); #endif uint8_t RGBval = 150; @@ -36,146 +33,126 @@ uint32_t rgb_mode = RGB_MODE_PLAIN; // s is the saturation, as a number between 0 and 255. // v is the value, as a number between 0 and 255. // what is HSV and how does it compare to RGB?: https://www.kirupa.com/design/little_about_color_hsv_rgb.htm -rgb_color hsvToRgb(uint16_t h, uint8_t s, uint8_t v) { - uint8_t f = (h % 60) * 255 / 60; - uint8_t p = (255 - s) * (uint16_t)v / 255; - uint8_t q = (255 - f * (uint16_t)s / 255) * (uint16_t)v / 255; - uint8_t t = (255 - (255 - f) * (uint16_t)s / 255) * (uint16_t)v / 255; - uint8_t r = 0, g = 0, b = 0; - switch ((h / 60) % 6) { - case 0: - r = v; - g = t; - b = p; - break; - case 1: - r = q; - g = v; - b = p; - break; - case 2: - r = p; - g = v; - b = t; - break; - case 3: - r = p; - g = q; - b = v; - break; - case 4: - r = t; - g = p; - b = v; - break; - case 5: - r = v; - g = p; - b = q; - break; - } - return rgb_color(r, g, b); +rgb_color hsvToRgb(uint16_t h, uint8_t s, uint8_t v) +{ + uint8_t f = (h % 60) * 255 / 60; + uint8_t p = (255 - s) * (uint16_t)v / 255; + uint8_t q = (255 - f * (uint16_t)s / 255) * (uint16_t)v / 255; + uint8_t t = (255 - (255 - f) * (uint16_t)s / 255) * (uint16_t)v / 255; + uint8_t r = 0, g = 0, b = 0; + switch((h / 60) % 6){ + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } + return rgb_color(r, g, b); } -void setupRGB(void) { -#ifdef NEOPIXEL_AVAILABLE - pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) - pixels.setPin(WS2812B_LED_PIN); - pixels.updateLength(WS2812B_LED_COUNT); -#endif -} -void updateRGBmode(uint32_t mode) { rgb_mode = mode; } -void updateRGB(unsigned long timesincelastkeypress) { +void setupRGB(void) +{ + #ifdef NEOPIXEL_AVAILABLE + pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) + pixels.setPin(WS2812B_LED_PIN); + pixels.updateLength(WS2812B_LED_COUNT); + #endif +} +void updateRGBmode(uint32_t mode) +{ + rgb_mode = mode; +} - if (timesincelastkeypress < PWM_TOUCH_INTERVAL) { +void updateRGB(unsigned long timesincelastkeypress) +{ + +if (timesincelastkeypress 1) {RGBval -- ;} else {RGBval = 0 ;} - if (timesincelastkeypress / 10 > 255) { - RGBval = 0; - } else { - RGBval = 255 - timesincelastkeypress / 10; - } - } +}else +{ + // if (RGBval > 1) {RGBval -- ;} else {RGBval = 0 ;} + if (timesincelastkeypress/10>255) + { + RGBval = 0; + } + else + { + RGBval = 255 - timesincelastkeypress/10; + } + + +} #ifdef NEOPIXEL_AVAILABLE - pixels.clear(); - uint16_t time = millis() >> 2; - switch (rgb_mode) { - case 0: // OFF - // cppcheck-suppress unsignedLessThanZero - for (uint16_t i = 0; i < WS2812B_LED_COUNT; i++) { // For each pixel... - pixels.setPixelColor(i, 0, 0, 0); - } - break; - case RGB_MODE_PLAIN: // RAINBOW - - // cppcheck-suppress unsignedLessThanZero - for (uint16_t i = 0; i < WS2812B_LED_COUNT; i++) { // For each pixel... - byte x = (time >> 2) - (i << 3); - colors[i] = hsvToRgb((uint32_t)x * 359 / 256, 255, RGBval); - pixels.setPixelColor(i, colors[i].red, colors[i].green, colors[i].blue); - } - break; - case RGB_MODE_BREATHE: - break; - case RGB_MODE_RAINBOW: - break; - case RGB_MODE_SWIRL: - break; - case RGB_MODE_SNAKE: - break; - case RGB_MODE_KNIGHT: - break; - case RGB_MODE_XMAS: - break; - case RGB_MODE_GRADIENT: - break; - case RGB_MODE_RGBTEST: - if (RGBcounter > 3) - RGBcounter = 1; - // cppcheck-suppress unsignedLessThanZero - for (uint16_t i = 0; i < WS2812B_LED_COUNT; i++) { // For each pixel... - if (RGBcounter == 1) { - colors[i].red = RGBval; - } else { - colors[i].red = 0; - } - if (RGBcounter == 2) { - colors[i].green = RGBval; - } else { - colors[i].green = 0; - } - if (RGBcounter == 3) { - colors[i].blue = RGBval; - } else { - colors[i].blue = 0; - } - pixels.setPixelColor(i, colors[i].red, colors[i].green, colors[i].blue); - } - RGBcounter++; - break; - default: - // unknown mode. switch to mode 0 - // cppcheck-suppress unsignedLessThanZero - for (int i = 0; i < WS2812B_LED_COUNT; i++) { // For each pixel... - pixels.setPixelColor(i, 0, 0, 0); +pixels.clear(); +uint16_t time = millis() >> 2; +switch (rgb_mode) + { + case 0: // OFF + // cppcheck-suppress unsignedLessThanZero + for(uint16_t i=0; i> 2) - (i << 3); + colors[i] = hsvToRgb((uint32_t)x * 359 / 256, 255, RGBval); + pixels.setPixelColor(i, colors[i].red, colors[i].green, colors[i].blue); + } + break; + case RGB_MODE_BREATHE: + break; + case RGB_MODE_RAINBOW: + break; + case RGB_MODE_SWIRL: + break; + case RGB_MODE_SNAKE: + break; + case RGB_MODE_KNIGHT: + break; + case RGB_MODE_XMAS: + break; + case RGB_MODE_GRADIENT: + break; + case RGB_MODE_RGBTEST: + if (RGBcounter>3) RGBcounter = 1; + // cppcheck-suppress unsignedLessThanZero + for(uint16_t i=0; i +#include "keyboard_config.h" +#include "firmware_config.h" -#include "advanced_keycodes.h" #include "hid_keycodes.h" +#include "advanced_keycodes.h" #ifdef ARDUINO_NRF52_ADAFRUIT -// do nothing since the Adafruit BSP doesn't have NeoPixel included + // do nothing since the Adafruit BSP doesn't have NeoPixel included #endif #ifdef ARDUINO_NRF52_COMMUNITY -#include -#define NEOPIXEL_AVAILABLE 1 + #include + #define NEOPIXEL_AVAILABLE 1 #endif -typedef struct rgb_color { - unsigned char red, green, blue; - rgb_color(){}; - rgb_color(uint8_t r, uint8_t g, uint8_t b) : red(r), green(g), blue(b){}; -} rgb_color; + typedef struct rgb_color + { + unsigned char red, green, blue; + rgb_color() {}; + rgb_color(uint8_t r, uint8_t g, uint8_t b) : red(r), green(g), blue(b) {}; + } rgb_color; #ifdef ARDUINO_NRF52_COMMUNITY -extern Adafruit_NeoPixel pixels; + extern Adafruit_NeoPixel pixels; #endif void setupRGB(void); diff --git a/firmware/advanced_keycodes.h b/firmware/advanced_keycodes.h index 35f5610b..2a852d4c 100644 --- a/firmware/advanced_keycodes.h +++ b/firmware/advanced_keycodes.h @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include @@ -26,12 +23,12 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #define ADVANCED_KEYCODES_H enum class Duration { - MOMENTARY = 0, - TOGGLE = 1, - ONE_SHOT = 2, + MOMENTARY = 0, + TOGGLE = 1, + ONE_SHOT = 2, }; -#define MOD(M, KC) ((uint16_t)KC | (uint16_t)M) +#define MOD(M, KC) ((uint16_t) KC | (uint16_t) M) #define BIT_LCTRL (1) #define BIT_LSHIFT (2) @@ -51,18 +48,16 @@ enum class Duration { #define MOD_RALT (BIT_RALT << 8) #define MOD_RGUI (BIT_RGUI << 8) -#define MC(KC) (((uint16_t)KC << 8) | KC_RESERVED_A5) // move KC to upper 8 bits and use KC_RESERVED_A5 keycode for marking this as a macro. -#define KB(KC) (((uint16_t)KC << 8) | KC_RESERVED_A6) // move KC to upper 8 bits and use KC_RESERVED_A6 keycode for marking this as a special keyboard function. -#define MK(KC) (((uint16_t)KC << 8) | KC_RESERVED_A7) // move KC to upper 8 bits and use KC_RESERVED_A7 keycode for marking this as a media key. -#define MR(KC) (((uint16_t)KC << 8) | KC_RESERVED_A8) // move KC to upper 8 bits and use KC_RESERVED_A8 keycode for marking this as a repeating media key. -#define MS(KC) (((uint16_t)KC << 8) | KC_RESERVED_A9) // move KC to upper 8 bits and use KC_RESERVED_A9 keycode for marking this as a mouse key. -#define KS(KC) (((uint16_t)KC << 8) | KC_RESERVED_AA) // move KC to upper 8 bits and use KC_RESERVED_AA keycode for marking this as a special key. -#define KI(KC) \ - (((uint16_t)KC << 8) | \ - KC_RESERVED_AB) // move KC to upper 8 bits and use KC_RESERVED_AB keycode for marking this as a macro for international/special characters (ALT-0233 = é). +#define MC(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_A5 ) // move KC to upper 8 bits and use KC_RESERVED_A5 keycode for marking this as a macro. +#define KB(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_A6 ) // move KC to upper 8 bits and use KC_RESERVED_A6 keycode for marking this as a special keyboard function. +#define MK(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_A7 ) // move KC to upper 8 bits and use KC_RESERVED_A7 keycode for marking this as a media key. +#define MR(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_A8 ) // move KC to upper 8 bits and use KC_RESERVED_A8 keycode for marking this as a repeating media key. +#define MS(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_A9 ) // move KC to upper 8 bits and use KC_RESERVED_A9 keycode for marking this as a mouse key. +#define KS(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_AA ) // move KC to upper 8 bits and use KC_RESERVED_AA keycode for marking this as a special key. +#define KI(KC) (((uint16_t) KC << 8 ) | KC_RESERVED_AB ) // move KC to upper 8 bits and use KC_RESERVED_AB keycode for marking this as a macro for international/special characters (ALT-0233 = é). #define TG(KC) ((static_cast(Duration::TOGGLE) << 16) | KC) #define OS(KC) ((static_cast(Duration::ONE_SHOT) << 16) | KC) -#define MAC(KC) ((static_cast(Duration::ONE_SHOT) << 16) | (KC << 8) | KC_RESERVED_A5) +#define MAC(KC) ((static_cast(Duration::ONE_SHOT) << 16) | (KC << 8 ) | KC_RESERVED_A5) #define S(KC) MOD(MOD_LSHIFT, KC) #define SEND_KC(KC) (static_cast(KC & 0x00FF)) @@ -70,9 +65,9 @@ enum class Duration { // define any shift/ctl/alt key combinations #define KC_TILD MOD(MOD_LSHIFT, KC_GRV) #define KC_EXLM MOD(MOD_LSHIFT, KC_1) -#define KC_AT MOD(MOD_LSHIFT, KC_2) +#define KC_AT MOD(MOD_LSHIFT, KC_2) #define KC_HASH MOD(MOD_LSHIFT, KC_3) -#define KC_DLR MOD(MOD_LSHIFT, KC_4) +#define KC_DLR MOD(MOD_LSHIFT, KC_4) #define KC_PERC MOD(MOD_LSHIFT, KC_5) #define KC_CIRC MOD(MOD_LSHIFT, KC_6) #define KC_AMPR MOD(MOD_LSHIFT, KC_7) @@ -88,14 +83,14 @@ enum class Duration { #define KC_COLN MOD(MOD_LSHIFT, KC_SCLN) #define KC_DQUO MOD(MOD_LSHIFT, KC_QUOTE) -#define KC_DQT KC_DQUO +#define KC_DQT KC_DQUO -#define KC_LT MOD(MOD_LSHIFT, KC_COMMA) -#define KC_GT MOD(MOD_LSHIFT, KC_DOT) +#define KC_LT MOD(MOD_LSHIFT, KC_COMMA) +#define KC_GT MOD(MOD_LSHIFT, KC_DOT) #define KC_QUES MOD(MOD_LSHIFT, KC_SLASH) -#define KC_NUTL MOD(MOD_LSHIFT, KC_NUHS) // Non-US # and ~ -#define KC_NUPI MOD(MOD_LSHIFT, KC_NUBS) // Non-US \ and | +#define KC_NUTL MOD(MOD_LSHIFT,KC_NUHS) // Non-US # and ~ +#define KC_NUPI MOD(MOD_LSHIFT,KC_NUBS) // Non-US \ and | #define LALT(KEY) MOD(MOD_LALT, KEY) #define RALT(KEY) MOD(MOD_RALT, KEY) @@ -106,4 +101,5 @@ enum class Duration { #define LGUI(KEY) MOD(MOD_LGUI, KEY) #define RGUI(KEY) MOD(MOD_RGUI, KEY) + #endif diff --git a/firmware/bluetooth.cpp b/firmware/bluetooth.cpp index a66871bf..73c13c36 100644 --- a/firmware/bluetooth.cpp +++ b/firmware/bluetooth.cpp @@ -7,91 +7,91 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // To learn more about BLE, refer to https://learn.adafruit.com/introduction-to-bluetooth-low-energy/introduction #include "bluetooth.h" -BLEDis bledis; // Device Information Service +BLEDis bledis; // Device Information Service extern KeyScanner keys; extern PersistentState keyboardconfig; extern DynamicState keyboardstate; extern Battery batterymonitor; -#if BLE_HID == 1 -uint16_t hid_conn_hdl; -#endif - -extern BLEBas blebas; -StatePayload statedata; - -#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD -Payload Linkdata; -BLEService KBLinkService = BLEService(UUID128_SVC_KEYBOARD_LINK); // Keyboard Link Service - Slave/Server Side -BLECharacteristic KBLinkChar_Layers = BLECharacteristic(UUID128_CHR_KEYBOARD_LAYERS); -BLECharacteristic KBLinkChar_Layer_Request = BLECharacteristic(UUID128_CHR_KEYBOARD_LAYER_REQUEST); -BLECharacteristic KBLinkChar_Buffer = BLECharacteristic(UUID128_CHR_KEYBOARD_BUFFER); + #if BLE_HID == 1 + uint16_t hid_conn_hdl; + #endif + +extern BLEBas blebas; +StatePayload statedata; + +#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD + Payload Linkdata; + BLEService KBLinkService = BLEService(UUID128_SVC_KEYBOARD_LINK); // Keyboard Link Service - Slave/Server Side + BLECharacteristic KBLinkChar_Layers = BLECharacteristic(UUID128_CHR_KEYBOARD_LAYERS); + BLECharacteristic KBLinkChar_Layer_Request = BLECharacteristic(UUID128_CHR_KEYBOARD_LAYER_REQUEST); + BLECharacteristic KBLinkChar_Buffer = BLECharacteristic(UUID128_CHR_KEYBOARD_BUFFER); #endif -#if BLE_HID == 1 // THIS IS USUALLY ON THE MASTER/CENTRAL BOARD -BLEHidAdafruit blehid; // HID Service +#if BLE_HID == 1 // THIS IS USUALLY ON THE MASTER/CENTRAL BOARD + BLEHidAdafruit blehid; // HID Service #endif // ToDo: provision for multiple master/slave links #if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD -BLEClientService KBLinkClientService = BLEClientService(UUID128_SVC_KEYBOARD_LINK); // Keyboard Link Service Client - Master/Client Side -BLEClientCharacteristic KBLinkClientChar_Layers = BLEClientCharacteristic(UUID128_CHR_KEYBOARD_LAYERS); -BLEClientCharacteristic KBLinkClientChar_Layer_Request = BLEClientCharacteristic(UUID128_CHR_KEYBOARD_LAYER_REQUEST); -BLEClientCharacteristic KBLinkClientChar_Buffer = BLEClientCharacteristic(UUID128_CHR_KEYBOARD_BUFFER); + BLEClientService KBLinkClientService = BLEClientService(UUID128_SVC_KEYBOARD_LINK); // Keyboard Link Service Client - Master/Client Side + BLEClientCharacteristic KBLinkClientChar_Layers = BLEClientCharacteristic(UUID128_CHR_KEYBOARD_LAYERS); + BLEClientCharacteristic KBLinkClientChar_Layer_Request = BLEClientCharacteristic(UUID128_CHR_KEYBOARD_LAYER_REQUEST); + BLEClientCharacteristic KBLinkClientChar_Buffer = BLEClientCharacteristic(UUID128_CHR_KEYBOARD_BUFFER); #endif /**************************************************************************************************************************/ -void bt_setup(uint8_t BLEProfile) { - ble_gap_conn_params_t _ppcp; - _ppcp = ((ble_gap_conn_params_t){ - .min_conn_interval = 6, - .max_conn_interval = 12, - .slave_latency = 5, - .conn_sup_timeout = 2000 / 10 // in 10ms unit +void bt_setup(uint8_t BLEProfile) +{ +ble_gap_conn_params_t _ppcp; + _ppcp = ((ble_gap_conn_params_t) { + .min_conn_interval = 6, + .max_conn_interval = 12, + .slave_latency = 5, + .conn_sup_timeout = 2000 / 10 // in 10ms unit }); - - // Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); // OK for nrf52840 - // Bluefruit.configPrphBandwidth(BANDWIDTH_HIGH); - // Bluefruit.configCentralBandwidth(BANDWIDTH_HIGH); - Bluefruit.begin(PERIPHERAL_COUNT, CENTRAL_COUNT); // Defined in firmware_config.h - - Bluefruit.autoConnLed(false); // make sure the BlueFruit connection LED is not toggled. - Bluefruit.setTxPower(DEVICE_POWER); // Defined in bluetooth_config.h - Bluefruit.setName(DEVICE_NAME); // Defined in keyboard_config.h - Bluefruit.configUuid128Count(UUID128_COUNT); // Defined in bluetooth_config.h - Bluefruit.configServiceChanged(true); // helps troubleshooting... - Bluefruit.setAppearance(BLE_APPEARANCE_HID_KEYBOARD); // How the device appears once connected + + //Bluefruit.configPrphBandwidth(BANDWIDTH_MAX); // OK for nrf52840 +// Bluefruit.configPrphBandwidth(BANDWIDTH_HIGH); + // Bluefruit.configCentralBandwidth(BANDWIDTH_HIGH); + Bluefruit.begin(PERIPHERAL_COUNT,CENTRAL_COUNT); // Defined in firmware_config.h + + + Bluefruit.autoConnLed(false); // make sure the BlueFruit connection LED is not toggled. + Bluefruit.setTxPower(DEVICE_POWER); // Defined in bluetooth_config.h + Bluefruit.setName(DEVICE_NAME); // Defined in keyboard_config.h + Bluefruit.configUuid128Count(UUID128_COUNT); // Defined in bluetooth_config.h + Bluefruit.configServiceChanged(true); // helps troubleshooting... + Bluefruit.setAppearance(BLE_APPEARANCE_HID_KEYBOARD); // How the device appears once connected Bluefruit.setRssiCallback(rssi_changed_callback); //********Bluefruit.setConnInterval(9, 12); // 0.10.1: not needed for master... - // https://devzone.nordicsemi.com/nordic/power/w/opp/2/online-power-profiler-for-ble - // Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms - // Bluefruit.Periph.setConnSlaveLatency(10); // TODO: add this when 0.22.0 gets released! This will reduce power consumption significantly. - - // sd_ble_gap_ppcp_get(&_ppcp); - //_ppcp.slave_latency = 30; - sd_ble_gap_ppcp_set(&_ppcp); + //https://devzone.nordicsemi.com/nordic/power/w/opp/2/online-power-profiler-for-ble + // Bluefruit.Periph.setConnInterval(6, 12); // 7.5 - 15 ms + // Bluefruit.Periph.setConnSlaveLatency(10); // TODO: add this when 0.22.0 gets released! This will reduce power consumption significantly. + +//sd_ble_gap_ppcp_get(&_ppcp); +//_ppcp.slave_latency = 30; +sd_ble_gap_ppcp_set(&_ppcp); Bluefruit.Periph.setConnectCallback(prph_connect_callback); - Bluefruit.Periph.setDisconnectCallback(prph_disconnect_callback); + Bluefruit.Periph.setDisconnectCallback(prph_disconnect_callback); // Set MAC address based on active BLE profile - if (BLEProfile > 0) { + if (BLEProfile > 0) + { ble_gap_addr_t gap_addr; gap_addr = Bluefruit.getAddr(); gap_addr.addr[0] += BLEProfile; @@ -99,73 +99,75 @@ void bt_setup(uint8_t BLEProfile) { } // Configure and Start Device Information Service - bledis.setManufacturer(MANUFACTURER_NAME); // Defined in keyboard_config.h - bledis.setModel(DEVICE_MODEL); // Defined in keyboard_config.h + bledis.setManufacturer(MANUFACTURER_NAME); // Defined in keyboard_config.h + bledis.setModel(DEVICE_MODEL); // Defined in keyboard_config.h bledis.begin(); + // Configure and Start Battery Service blebas.begin(); - blebas.write(100); // put the battery level at 100% - until it is updated by the battery monitoring loop. + blebas.write(100); // put the battery level at 100% - until it is updated by the battery monitoring loop. batterymonitor.readVBAT(); // Get a single ADC sample and throw it away - - statedata.command = 0; - statedata.layer = 0; - statedata.timesync = 0; - -#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD - - Linkdata.report[0] = 0; // initialize the slave to master link data... - Linkdata.report[1] = 0; - Linkdata.report[2] = 0; - Linkdata.report[3] = 0; - Linkdata.report[4] = 0; - Linkdata.report[5] = 0; - Linkdata.report[6] = 0; - Linkdata.report[7] = 0; - Linkdata.command = 0; - Linkdata.timesync = 0; + + statedata.command =0; + statedata.layer =0; + statedata.timesync=0; + +#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD + + Linkdata.keycode[0] =0; // initialize the slave to master link data... + Linkdata.keycode[1] =0; + Linkdata.keycode[2] =0; + Linkdata.keycode[3] =0; + Linkdata.keycode[4] =0; + Linkdata.keycode[5] =0; + Linkdata.layer =0; + Linkdata.modifier =0; + //Linkdata.command = 0; + //Linkdata.timesync = 0; Linkdata.specialkeycode = 0; Linkdata.batterylevel = 0; // Configure Keyboard Link Service KBLinkService.begin(); - - KBLinkChar_Layers.setProperties(CHR_PROPS_NOTIFY + CHR_PROPS_READ); + + KBLinkChar_Layers.setProperties(CHR_PROPS_NOTIFY+ CHR_PROPS_READ); KBLinkChar_Layers.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS); + KBLinkChar_Layers.setMaxLen(sizeof(statedata)); KBLinkChar_Layers.setFixedLen(sizeof(statedata)); KBLinkChar_Layers.setUserDescriptor("Keyboard Layer"); - KBLinkChar_Layers.setCccdWriteCallback( - cccd_callback, true); /// 0.10.1 - second parameter is the "use adafruit calback" to call adafruit's method before ours. Not sure what it does. + KBLinkChar_Layers.setCccdWriteCallback(cccd_callback,true); /// 0.10.1 - second parameter is the "use adafruit calback" to call adafruit's method before ours. Not sure what it does. KBLinkChar_Layers.begin(); - KBLinkChar_Layers.write(&statedata, sizeof(statedata)); // initialize with layer 0 + KBLinkChar_Layers.write(&statedata, sizeof(statedata)); // initialize with layer 0 KBLinkChar_Layer_Request.setProperties(CHR_PROPS_WRITE + CHR_PROPS_WRITE_WO_RESP); - KBLinkChar_Layer_Request.setPermission(SECMODE_NO_ACCESS, SECMODE_OPEN); + KBLinkChar_Layer_Request.setPermission(SECMODE_NO_ACCESS, SECMODE_OPEN ); + KBLinkChar_Layer_Request.setMaxLen(sizeof(statedata)); KBLinkChar_Layer_Request.setFixedLen(sizeof(statedata)); KBLinkChar_Layer_Request.setUserDescriptor("Keyboard Layer Request"); KBLinkChar_Layer_Request.setWriteCallback(layer_request_callback); KBLinkChar_Layer_Request.begin(); - KBLinkChar_Layer_Request.write(&statedata, sizeof(statedata)); // initialize with empty buffer - - KBLinkChar_Buffer.setProperties(CHR_PROPS_NOTIFY + CHR_PROPS_READ); + KBLinkChar_Layer_Request.write(&statedata, sizeof(statedata)); // initialize with empty buffer + + KBLinkChar_Buffer.setProperties(CHR_PROPS_NOTIFY+ CHR_PROPS_READ); KBLinkChar_Buffer.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS); + KBLinkChar_Buffer.setMaxLen(sizeof(Linkdata)); KBLinkChar_Buffer.setFixedLen(sizeof(Linkdata)); KBLinkChar_Buffer.setUserDescriptor("Keyboard Master/Slave Payload"); - KBLinkChar_Buffer.setCccdWriteCallback( - cccd_callback, true); /// 0.10.1 - second parameter is the "use adafruit calback" to call adafruit's method before ours. Not sure what it does. + KBLinkChar_Buffer.setCccdWriteCallback(cccd_callback,true); /// 0.10.1 - second parameter is the "use adafruit calback" to call adafruit's method before ours. Not sure what it does. KBLinkChar_Buffer.begin(); - KBLinkChar_Buffer.write(&Linkdata, sizeof(Linkdata)); // initialize with empty buffer + KBLinkChar_Buffer.write(&Linkdata, sizeof(Linkdata)); // initialize with empty buffer -#endif - - /* Start BLE HID + #endif + + /* Start BLE HID * Note: Apple requires BLE device must have min connection interval >= 20m * ( The smaller the connection interval the faster we could send data). - * However for HID and MIDI device, Apple could accept min connection interval + * However for HID and MIDI device, Apple could accept min connection interval * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max * connection interval to 11.25 ms and 15 ms respectively for best performance. */ - + #if BLE_HID == 1 blehid.begin(); // Set callback for set LED from central @@ -174,32 +176,34 @@ void bt_setup(uint8_t BLEProfile) { /* Set connection interval (min, max) to your perferred value. * Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms - * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms + * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms */ -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD + #if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD KBLinkClientService.begin(); KBLinkClientChar_Layers.begin(); KBLinkClientChar_Layers.setNotifyCallback(notify_callback); KBLinkClientChar_Buffer.begin(); KBLinkClientChar_Buffer.setNotifyCallback(notify_callback); - KBLinkClientChar_Layer_Request.begin(); + KBLinkClientChar_Layer_Request.begin(); Bluefruit.Scanner.setRxCallback(scan_callback); Bluefruit.Scanner.restartOnDisconnect(true); - Bluefruit.Scanner.filterRssi(FILTER_RSSI_BELOW_STRENGTH); // limits very far away devices - reduces load - Bluefruit.Scanner.filterUuid(BLEUART_UUID_SERVICE, UUID128_SVC_KEYBOARD_LINK); // looks specifically for these 2 services (A OR B) - reduces load - Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms Interval = 100ms, Window = 50 ms - Bluefruit.Scanner.useActiveScan(false); // If true, will fetch scan response data - Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after 0 seconds + Bluefruit.Scanner.filterRssi(FILTER_RSSI_BELOW_STRENGTH); // limits very far away devices - reduces load + Bluefruit.Scanner.filterUuid(BLEUART_UUID_SERVICE, UUID128_SVC_KEYBOARD_LINK); // looks specifically for these 2 services (A OR B) - reduces load + Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms Interval = 100ms, Window = 50 ms + Bluefruit.Scanner.useActiveScan(false); // If true, will fetch scan response data + Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after 0 seconds Bluefruit.Central.setConnectCallback(cent_connect_callback); Bluefruit.Central.setDisconnectCallback(cent_disconnect_callback); #endif + } -ble_gap_addr_t bt_getMACAddr(void) { +ble_gap_addr_t bt_getMACAddr(void) +{ ble_gap_addr_t gap_addr; gap_addr = Bluefruit.getAddr(); return gap_addr; @@ -208,186 +212,211 @@ ble_gap_addr_t bt_getMACAddr(void) { /**************************************************************************************************************************/ // /**************************************************************************************************************************/ -void bt_startAdv(void) { +void bt_startAdv(void) +{ // Advertising packet Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); Bluefruit.Advertising.addTxPower(); -#if BLE_HID == 1 + #if BLE_HID == 1 Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD); - Bluefruit.Advertising.addService(blehid); // Include BLE HID service -#endif - -#if BLE_PERIPHERAL == 1 - Bluefruit.Advertising.addUuid(UUID128_SVC_KEYBOARD_LINK); - Bluefruit.Advertising.addUuid(UUID128_CHR_KEYBOARD_LAYERS); - Bluefruit.Advertising.addUuid(UUID128_CHR_KEYBOARD_LAYER_REQUEST); - Bluefruit.Advertising.addUuid(UUID128_CHR_KEYBOARD_BUFFER); - Bluefruit.Advertising.addService(KBLinkService); /// Advertizing Keyboard Link Service -#endif - - // There is no other service for Central + Bluefruit.Advertising.addService(blehid); // Include BLE HID service + #endif + + #if BLE_PERIPHERAL ==1 + Bluefruit.Advertising.addUuid(UUID128_SVC_KEYBOARD_LINK); + Bluefruit.Advertising.addUuid(UUID128_CHR_KEYBOARD_LAYERS); + Bluefruit.Advertising.addUuid(UUID128_CHR_KEYBOARD_LAYER_REQUEST); + Bluefruit.Advertising.addUuid(UUID128_CHR_KEYBOARD_BUFFER); + Bluefruit.Advertising.addService(KBLinkService); /// Advertizing Keyboard Link Service + #endif + + // There is no other service for Central // ToDo: Consider Configuration Service... Save config to board, reset to default values, go to DFU, etc... - + // There is probably not enough room for the dev name in the advertising packet. Putting it in the ScanResponse Packet - // Bluefruit.ScanResponse.addName(); + //Bluefruit.ScanResponse.addName(); Bluefruit.Advertising.addName(); - + /* Start Advertising * - Enable auto advertising if disconnected * - Interval: fast mode = 20 ms, slow mode = 152.5 ms * - Timeout for fast mode is 30 seconds * - Start(timeout) with timeout = 0 will advertise forever (until connected) - * + * * For recommended advertising interval - * https://developer.apple.com/library/content/qa/qa1931/_index.html + * https://developer.apple.com/library/content/qa/qa1931/_index.html */ - + Bluefruit.Advertising.restartOnDisconnect(true); - Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms - Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode - Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds - + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds + Bluefruit.Advertising.setSlowCallback(advertizing_slow_callback); Bluefruit.Advertising.setStopCallback(advertizing_stop_callback); } -void bt_stopAdv() { Bluefruit.Advertising.stop(); } - -// typedef void (*stop_callback_t) (void); -// typedef void (*slow_callback_t) (void); -void advertizing_slow_callback(void) { - // drop fast - keyboardstate.statusble = keyboardstate.statusble & (~1); // bitwise AND NOT - // add is_running - keyboardstate.statusble = keyboardstate.statusble | (4); // bitwise OR - // add slow - keyboardstate.statusble = keyboardstate.statusble | (2); // bitwise OR -} -void advertizing_stop_callback(void) { - // drop slow - keyboardstate.statusble = keyboardstate.statusble & (~2); // bitwise AND NOT - // drop is_running - keyboardstate.statusble = keyboardstate.statusble & (~4); // bitwise AND NOT +void bt_stopAdv() +{ + Bluefruit.Advertising.stop(); } -void rssi_changed_callback(uint16_t conn_hdl, int8_t rssi) { - if (conn_hdl == keyboardstate.conn_handle_prph) { + // typedef void (*stop_callback_t) (void); + //typedef void (*slow_callback_t) (void); + void advertizing_slow_callback(void) + { + // drop fast + keyboardstate.statusble = keyboardstate.statusble & (~1); // bitwise AND NOT + // add is_running + keyboardstate.statusble = keyboardstate.statusble | (4); // bitwise OR + // add slow + keyboardstate.statusble = keyboardstate.statusble | (2); // bitwise OR + } + void advertizing_stop_callback(void) + { + // drop slow + keyboardstate.statusble = keyboardstate.statusble & (~2); // bitwise AND NOT + // drop is_running + keyboardstate.statusble = keyboardstate.statusble & (~4); // bitwise AND NOT + } + +void rssi_changed_callback(uint16_t conn_hdl, int8_t rssi) +{ + if (conn_hdl == keyboardstate.conn_handle_prph) + { keyboardstate.rssi_prph = rssi; keyboardstate.rssi_prph_updated = true; - } else if (conn_hdl == keyboardstate.conn_handle_cent) { + } else + if (conn_hdl == keyboardstate.conn_handle_cent) + { keyboardstate.rssi_cent = rssi; keyboardstate.rssi_cent_updated = true; - } else if (conn_hdl == keyboardstate.conn_handle_cccd) { + } else + if (conn_hdl == keyboardstate.conn_handle_cccd) + { keyboardstate.rssi_cccd = rssi; keyboardstate.rssi_cccd_updated = true; - } + } + } -void updateBLEStatus(void) { +void updateBLEStatus(void) +{ keyboardstate.statusble = 0; - if (Bluefruit.Advertising.isRunning()) { + if (Bluefruit.Advertising.isRunning()) + { keyboardstate.statusble = keyboardstate.statusble | (4); // bitwise OR } - if (Bluefruit.connected() > 0) { + if (Bluefruit.connected()>0) + { keyboardstate.statusble = keyboardstate.statusble | (32); // bitwise OR } + + } /**************************************************************************************************************************/ // This callback is called when a Notification update even occurs (This occurs on the client) /**************************************************************************************************************************/ -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD -void notify_callback(BLEClientCharacteristic *chr, uint8_t *data, uint16_t len) { +#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD +void notify_callback(BLEClientCharacteristic* chr, uint8_t* data, uint16_t len) +{ - Payload remotedata; + Payload remotedata; - LOG_LV1("CB NOT", "notify_callback: want %i got %i [0] %i [1] %i [2] %i [3] %i [4] %i [5] %i [6] %i", sizeof(remotedata), len, data[0], data[1], data[2], - data[3], data[4], data[5], data[6]); - if (len > 0) // check if there really is data... + LOG_LV1("CB NOT","notify_callback: want %i got %i [0] %i [1] %i [2] %i [3] %i [4] %i [5] %i [6] %i" , sizeof(remotedata),len, data[0], data[1], data[2], data[3], data[4], data[5], data[6]); + if (len>0) // check if there really is data... { - if (chr->uuid == KBLinkClientChar_Layers.uuid) { - LOG_LV1("CB NOT", "notify_callback: Layers Data"); - KeyScanner::updateRemoteLayer(data[0]); // Layer is only a single uint8 - } + if (chr->uuid == KBLinkClientChar_Layers.uuid){ + LOG_LV1("CB NOT","notify_callback: Layers Data"); + KeyScanner::updateRemoteLayer(data[0]); // Layer is only a single uint8 + } - if (chr->uuid == KBLinkClientChar_Buffer.uuid) { - LOG_LV1("CB NOT", "notify_callback: Buffer Data"); - if (len >= sizeof(remotedata)) { - remotedata = *(Payload *)data; - KeyScanner::updateRemoteReport(remotedata.report[0], remotedata.report[1], remotedata.report[2], remotedata.report[3], remotedata.report[4], - remotedata.report[5], remotedata.report[6]); - KeyScanner::updateRemoteLayer(remotedata.report[7]); - KeyScanner::remotespecialkeycode = remotedata.specialkeycode; + if (chr->uuid == KBLinkClientChar_Buffer.uuid){ + LOG_LV1("CB NOT","notify_callback: Buffer Data"); + if (len >= sizeof(remotedata)) + { + remotedata=*(Payload*) data; + KeyScanner::updateRemoteReport(remotedata.modifier,remotedata.keycode[0],remotedata.keycode[1],remotedata.keycode[2], remotedata.keycode[3],remotedata.keycode[4], remotedata.keycode[5]); + KeyScanner::updateRemoteLayer(remotedata.layer); + KeyScanner::remotespecialkeycode = remotedata.specialkeycode; + } } - } + } } #endif /**************************************************************************************************************************/ // This callback is called when a Notification subscription event occurs (This occurs on the server) /**************************************************************************************************************************/ -#if BLE_PERIPHERAL == 1 -void cccd_callback(uint16_t conn_hdl, BLECharacteristic *chr, uint16_t cccd_value) { - // this is called on the slave board... - char peer_name[32] = {0}; - BLEConnection *connection = Bluefruit.Connection(conn_hdl); + #if BLE_PERIPHERAL == 1 +void cccd_callback(uint16_t conn_hdl, BLECharacteristic* chr, uint16_t cccd_value) +{ +// this is called on the slave board... + char peer_name[32] = { 0 }; + BLEConnection* connection = Bluefruit.Connection(conn_hdl); connection->getPeerName(peer_name, sizeof(peer_name)); - LOG_LV1("CENTRL", "Connected to %i %s", conn_hdl, peer_name); + LOG_LV1("CENTRL","Connected to %i %s",conn_hdl,peer_name ); connection->monitorRssi(6); - strcpy(keyboardstate.peer_name_cccd, peer_name); + strcpy (keyboardstate.peer_name_cccd,peer_name); keyboardstate.conn_handle_cccd = conn_hdl; - LOG_LV1("CBCCCD", "notify_callback: %i ", cccd_value); - - // Check the characteristic this CCCD update is associated with in case - // this handler is used for multiple CCCD records. - if (chr->uuid == KBLinkChar_Layers.uuid) { - if (chr->notifyEnabled()) { - LOG_LV1("CBCCCD", "Layers 'Notify' enabled"); - } else { - LOG_LV1("CBCCCD", "Layers 'Notify' disabled"); + LOG_LV1("CBCCCD","notify_callback: %i " ,cccd_value); + + // Check the characteristic this CCCD update is associated with in case + // this handler is used for multiple CCCD records. + if (chr->uuid == KBLinkChar_Layers.uuid) { + if (chr->notifyEnabled()) { + LOG_LV1("CBCCCD","Layers 'Notify' enabled"); + } else { + LOG_LV1("CBCCCD","Layers 'Notify' disabled"); + } } - } - if (chr->uuid == KBLinkChar_Layer_Request.uuid) { - if (chr->notifyEnabled()) { - LOG_LV1("CBCCCD", "KBLinkChar_Layer_Request 'Notify' enabled"); - } else { - LOG_LV1("CBCCCD", "KBLinkChar_Layer_Request 'Notify' disabled"); - } - } - if (chr->uuid == KBLinkChar_Buffer.uuid) { - if (chr->notifyEnabled()) { - LOG_LV1("CBCCCD", "KBLinkChar_Buffer 'Notify' enabled"); - } else { - LOG_LV1("CBCCCD", "KBLinkChar_Buffer 'Notify' disabled"); - } - } + if (chr->uuid == KBLinkChar_Layer_Request.uuid) { + if (chr->notifyEnabled()) { + LOG_LV1("CBCCCD","KBLinkChar_Layer_Request 'Notify' enabled"); + } else { + LOG_LV1("CBCCCD","KBLinkChar_Layer_Request 'Notify' disabled"); + } + } + if (chr->uuid == KBLinkChar_Buffer.uuid) { + if (chr->notifyEnabled()) { + LOG_LV1("CBCCCD","KBLinkChar_Buffer 'Notify' enabled"); + } else { + LOG_LV1("CBCCCD","KBLinkChar_Buffer 'Notify' disabled"); + } + } + } /**************************************************************************************************************************/ // This callback is called layer_request when characteristic is being written to. This occurs on the server (Peripheral) // Called by KBLinkChar_Layer_Request /**************************************************************************************************************************/ -void layer_request_callback(uint16_t conn_hdl, BLECharacteristic *chr, uint8_t *data, uint16_t len) { - LOG_LV1("CB_CHR", "layer_request_callback: len %i offset %i data %i", len, data[0]); - if (len >= sizeof(statedata)) { - statedata = *(StatePayload *)data; // update state - KeyScanner::updateRemoteLayer(statedata.layer); - } +void layer_request_callback (uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) +{ +LOG_LV1("CB_CHR","layer_request_callback: len %i offset %i data %i" ,len, data[0]); + if (len >= sizeof(statedata)) + { + statedata=*(StatePayload*) data; // update state + KeyScanner::updateRemoteLayer(statedata.layer); + } } #endif /**************************************************************************************************************************/ // This callback is called when the master connects to a slave /**************************************************************************************************************************/ -void prph_connect_callback(uint16_t conn_handle) { - char peer_name[32] = {0}; - BLEConnection *connection = Bluefruit.Connection(conn_handle); - connection->getPeerName(peer_name, sizeof(peer_name)); - LOG_LV1("PRPH", "Connected to %i %s", conn_handle, peer_name); - connection->monitorRssi(6); - strcpy(keyboardstate.peer_name_prph, peer_name); - - if (strncmp(peer_name, keyboardconfig.BLEProfileName[keyboardconfig.BLEProfile], sizeof(peer_name))) { +void prph_connect_callback(uint16_t conn_handle) +{ +char peer_name[32] = { 0 }; +BLEConnection* connection = Bluefruit.Connection(conn_handle); +connection->getPeerName(peer_name, sizeof(peer_name)); +LOG_LV1("PRPH","Connected to %i %s",conn_handle,peer_name ); +connection->monitorRssi(6); +strcpy (keyboardstate.peer_name_prph,peer_name); + + if (strncmp(peer_name, keyboardconfig.BLEProfileName[keyboardconfig.BLEProfile], sizeof(peer_name))) + { strncpy(keyboardconfig.BLEProfileName[keyboardconfig.BLEProfile], peer_name, sizeof(peer_name)); keyboardstate.save2flash = true; } @@ -397,95 +426,106 @@ void prph_connect_callback(uint16_t conn_handle) { #ifdef ARDUINO_NRF52_ADAFRUIT uint16_t ediv = keyboardconfig.BLEProfile; // we have to do something different for it to compile fine... #endif - if (ediv != keyboardconfig.BLEProfileEdiv[keyboardconfig.BLEProfile]) { + if (ediv != keyboardconfig.BLEProfileEdiv[keyboardconfig.BLEProfile]) + { keyboardconfig.BLEProfileEdiv[keyboardconfig.BLEProfile] = ediv; keyboardstate.save2flash = true; } - keyboardstate.conn_handle_prph = conn_handle; +keyboardstate.conn_handle_prph = conn_handle; - keyboardstate.statusble = keyboardstate.statusble | (8); // bitwise OR +keyboardstate.statusble = keyboardstate.statusble | (8); // bitwise OR - // drop fast - keyboardstate.statusble = keyboardstate.statusble & (~1); // bitwise AND NOT - // drop slow - keyboardstate.statusble = keyboardstate.statusble & (~2); // bitwise AND NOT - // drop is_running - keyboardstate.statusble = keyboardstate.statusble & (~4); // bitwise AND NOT + // drop fast + keyboardstate.statusble = keyboardstate.statusble & (~1); // bitwise AND NOT + // drop slow + keyboardstate.statusble = keyboardstate.statusble & (~2); // bitwise AND NOT + // drop is_running + keyboardstate.statusble = keyboardstate.statusble & (~4); // bitwise AND NOT // if HID then save connection handle to HID_connection handle #if BLE_HID == 1 - hid_conn_hdl = conn_handle; +hid_conn_hdl = conn_handle; #endif } /**************************************************************************************************************************/ // This callback is called when the master disconnects from a slave /**************************************************************************************************************************/ -void prph_disconnect_callback(uint16_t conn_handle, uint8_t reason) { - (void)conn_handle; - (void)reason; - LOG_LV1("PRPH", "Disconnected"); - - // keyboardstate.statusble = keyboardstate.statusble & (~8); // bitwise AND NOT - keyboardstate.statusble = 0; +void prph_disconnect_callback(uint16_t conn_handle, uint8_t reason) +{ + (void) conn_handle; + (void) reason; + LOG_LV1("PRPH","Disconnected" ); + +//keyboardstate.statusble = keyboardstate.statusble & (~8); // bitwise AND NOT +keyboardstate.statusble = 0; // if HID then save connection handle to HID_connection handle #if BLE_HID == 1 - hid_conn_hdl = 0; +hid_conn_hdl = 0; #endif } /**************************************************************************************************************************/ // This callback is called when the scanner finds a device. This happens on the Client/Central /**************************************************************************************************************************/ -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD -void scan_callback(ble_gap_evt_adv_report_t *report) { - if (Bluefruit.Scanner.checkReportForService(report, KBLinkClientService)) { - LOG_LV1("KBLINK", "KBLink service detected. Connecting ... "); +#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD +void scan_callback(ble_gap_evt_adv_report_t* report) +{ + if ( Bluefruit.Scanner.checkReportForService(report, KBLinkClientService) ) + { + LOG_LV1("KBLINK","KBLink service detected. Connecting ... "); Bluefruit.Central.connect(report); - } + } } + + + /**************************************************************************************************************************/ // This callback is called when the central connects to a peripheral /**************************************************************************************************************************/ -void cent_connect_callback(uint16_t conn_handle) { // this runs on the master but when connecting to a slave. - char peer_name[32] = {0}; - BLEConnection *connection = Bluefruit.Connection(conn_handle); +void cent_connect_callback(uint16_t conn_handle) +{// this runs on the master but when connecting to a slave. + char peer_name[32] = { 0 }; + BLEConnection* connection = Bluefruit.Connection(conn_handle); connection->getPeerName(peer_name, sizeof(peer_name)); - LOG_LV1("CENTRL", "Connected to %i %s", conn_handle, peer_name); + LOG_LV1("CENTRL","Connected to %i %s",conn_handle,peer_name ); connection->monitorRssi(6); - strcpy(keyboardstate.peer_name_cent, peer_name); - keyboardstate.conn_handle_cent = conn_handle; +strcpy (keyboardstate.peer_name_cent,peer_name); +keyboardstate.conn_handle_cent = conn_handle; - if (KBLinkClientService.discover(conn_handle)) // validating that KBLink service is available to this connection + if (KBLinkClientService.discover(conn_handle )) // validating that KBLink service is available to this connection { if (KBLinkClientChar_Layers.discover()) { - KBLinkClientChar_Layers.enableNotify(); - } + KBLinkClientChar_Layers.enableNotify(); + } if (KBLinkClientChar_Buffer.discover()) { - KBLinkClientChar_Buffer.enableNotify(); - } + KBLinkClientChar_Buffer.enableNotify(); + } - if (KBLinkClientChar_Layer_Request.discover()) { - LOG_LV1("CENTRL", "Connected and KBLinkClientChar_Layer_Request.discover() successful"); - } - } else { - LOG_LV1("CENTRL", "No KBLink Service on this connection"); + if (KBLinkClientChar_Layer_Request.discover()) { + LOG_LV1("CENTRL","Connected and KBLinkClientChar_Layer_Request.discover() successful"); + } + } + else + { + LOG_LV1("CENTRL","No KBLink Service on this connection" ); // disconect since we couldn't find KBLink service Bluefruit.disconnect(conn_handle); - } + } keyboardstate.statusble = keyboardstate.statusble | (16); // bitwise OR } /**************************************************************************************************************************/ // This callback is called when the central disconnects from a peripheral /**************************************************************************************************************************/ -void cent_disconnect_callback(uint16_t conn_handle, uint8_t reason) { - (void)conn_handle; - (void)reason; - LOG_LV1("CENTRL", "Disconnected"); +void cent_disconnect_callback(uint16_t conn_handle, uint8_t reason) +{ + (void) conn_handle; + (void) reason; + LOG_LV1("CENTRL","Disconnected" ); // if the half disconnects, we need to make sure that the received buffer is set to empty. - KeyScanner::updateRemoteLayer(0); // Layer is only a single uint8 - KeyScanner::updateRemoteReport(0, 0, 0, 0, 0, 0, 0); - keyboardstate.statusble = keyboardstate.statusble & (~16); // bitwise AND NOT + KeyScanner::updateRemoteLayer(0); // Layer is only a single uint8 + KeyScanner::updateRemoteReport(0,0,0, 0,0, 0, 0); + keyboardstate.statusble = keyboardstate.statusble & (~16); // bitwise AND NOT } #endif @@ -497,228 +537,168 @@ void cent_disconnect_callback(uint16_t conn_handle, uint8_t reason) { * The LED bit map is as follows: (also defined by KEYBOARD_LED_* ) * Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) */ -void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap) { - (void)conn_handle; +void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap) +{ + (void) conn_handle; // light up Red Led if any bits is set - /* if ( led_bitmap ) - { - ledOn( STATUS_KB_LED_PIN ); - } - else - { - ledOff( STATUS_KB_LED_PIN ); - }*/ +/* if ( led_bitmap ) + { + ledOn( STATUS_KB_LED_PIN ); + } + else + { + ledOff( STATUS_KB_LED_PIN ); + }*/ keyboardstate.statuskb = led_bitmap; - // KeyScanner::ledStatus = led_bitmap; + //KeyScanner::ledStatus = led_bitmap; } -bool bt_isConnected() { return Bluefruit.connected(); } +bool bt_isConnected() +{ + return Bluefruit.connected(); +} -void bt_disconnect() { -#if BLE_HID == 1 +void bt_disconnect() +{ + #if BLE_HID == 1 Bluefruit.disconnect(hid_conn_hdl); -#endif + #endif } /**************************************************************************************************************************/ -void sendlayer(uint8_t layer) { -#if BLE_CENTRAL == 1 - LOG_LV1("CENTRAL", "Sending Layer %i %i", millis(), layer); - if (KBLinkClientChar_Layer_Request.discovered()) { - statedata.layer = layer; - uint16_t msg = KBLinkClientChar_Layer_Request.write_resp(&statedata, sizeof(statedata)); // Central->Peripheral uses the write mechanism - LOG_LV1("CENTRAL", "Sending Layer results %i", msg); - } else { - LOG_LV1("CENTRAL", "Sending Layer failed KBLinkClientChar_Layer_Request.discover() not true "); - } -#endif +void sendlayer(uint8_t layer) +{ + #if BLE_CENTRAL ==1 + LOG_LV1("CENTRAL","Sending Layer %i %i" ,millis(),layer ); + if (KBLinkClientChar_Layer_Request.discovered()) { + statedata.layer =layer; + uint16_t msg = KBLinkClientChar_Layer_Request.write_resp(&statedata, sizeof(statedata)); // Central->Peripheral uses the write mechanism + LOG_LV1("CENTRAL","Sending Layer results %i" ,msg); + } else + { + LOG_LV1("CENTRAL","Sending Layer failed KBLinkClientChar_Layer_Request.discover() not true "); + } + #endif } /**************************************************************************************************************************/ -void bt_sendKeys(std::array currentReport) { -#if BLE_HID == 1 - uint8_t keycode[6]; - // uint8_t layer = 0; - uint8_t mods = 0; - mods = currentReport[0]; // modifiers - keycode[0] = currentReport[1]; // Buffer - keycode[1] = currentReport[2]; // Buffer - keycode[2] = currentReport[3]; // Buffer - keycode[3] = currentReport[4]; // Buffer - keycode[4] = currentReport[5]; // Buffer - keycode[5] = currentReport[6]; // Buffer - // layer = currentReport[7]; // Layer - blehid.keyboardReport(hid_conn_hdl, mods, keycode); - LOG_LV2("HID", "Sending blehid.keyboardReport "); -#endif -#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD - Linkdata.report[0] = currentReport[0]; // initialize the slave to master link data... - Linkdata.report[1] = currentReport[1]; - Linkdata.report[2] = currentReport[2]; - Linkdata.report[3] = currentReport[3]; - Linkdata.report[4] = currentReport[4]; - Linkdata.report[5] = currentReport[5]; - Linkdata.report[6] = currentReport[6]; - Linkdata.report[7] = currentReport[7]; - Linkdata.command = 0; - Linkdata.timesync = 0; - Linkdata.specialkeycode = 0; - Linkdata.batterylevel = batterymonitor.vbat_per; - LOG_LV1("KB-P2C", " KBLinkChar_Buffer.notify sendKeys sending %i [1] %i", sizeof(Linkdata), Linkdata.report[1]); - KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); -#endif -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD - ; // Don't send keys to slaves -#endif -} +void bt_sendKeys(HIDKeyboard currentReport) +{ + + #if BLE_HID == 1 + uint8_t keycode[6]; + uint8_t mods = 0; + mods = currentReport.modifier; // modifiers + keycode[0] = currentReport.keycode[0]; // Buffer + keycode[1] = currentReport.keycode[1]; // Buffer + keycode[2] = currentReport.keycode[2]; // Buffer + keycode[3] = currentReport.keycode[3]; // Buffer + keycode[4] = currentReport.keycode[4]; // Buffer + keycode[5] = currentReport.keycode[5]; // Buffer + blehid.keyboardReport(hid_conn_hdl,mods, keycode); + LOG_LV2("HID","Sending blehid.keyboardReport " ); + #endif + #if BLE_PERIPHERAL ==1 // PERIPHERAL IS THE SLAVE BOARD + Linkdata.modifier =currentReport.modifier; // initialize the slave to master link data... + Linkdata.keycode[0] =currentReport.keycode[0]; + Linkdata.keycode[1] =currentReport.keycode[1]; + Linkdata.keycode[2] =currentReport.keycode[2]; + Linkdata.keycode[3] =currentReport.keycode[3]; + Linkdata.keycode[4] =currentReport.keycode[4]; + Linkdata.keycode[5] =currentReport.keycode[5]; + Linkdata.layer =currentReport.layer; + //Linkdata.command = 0; + //Linkdata.timesync = 0; + Linkdata.specialkeycode = 0; + Linkdata.batterylevel = batterymonitor.vbat_per; + LOG_LV1("KB-P2C"," KBLinkChar_Buffer.notify sendKeys sending %i [1] %i",sizeof(Linkdata),Linkdata.keycode[0]); + KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); + #endif + #if BLE_CENTRAL ==1 // CENTRAL IS THE MASTER BOARD + ; // Don't send keys to slaves + #endif -/**************************************************************************************************************************/ -void bt_sendKeys(uint8_t currentReport[8]) { -#if BLE_HID == 1 - uint8_t keycode[6]; - // uint8_t layer = 0; - uint8_t mods = 0; - mods = currentReport[0]; // modifiers - keycode[0] = currentReport[1]; // Buffer - keycode[1] = currentReport[2]; // Buffer - keycode[2] = currentReport[3]; // Buffer - keycode[3] = currentReport[4]; // Buffer - keycode[4] = currentReport[5]; // Buffer - keycode[5] = currentReport[6]; // Buffer - // layer = currentReport[7]; // Layer - blehid.keyboardReport(hid_conn_hdl, mods, keycode); - LOG_LV2("HID", "Sending blehid.keyboardReport "); -#endif -#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD - Linkdata.report[0] = currentReport[0]; // initialize the slave to master link data... - Linkdata.report[1] = currentReport[1]; - Linkdata.report[2] = currentReport[2]; - Linkdata.report[3] = currentReport[3]; - Linkdata.report[4] = currentReport[4]; - Linkdata.report[5] = currentReport[5]; - Linkdata.report[6] = currentReport[6]; - Linkdata.report[7] = currentReport[7]; - Linkdata.command = 0; - Linkdata.timesync = 0; - Linkdata.specialkeycode = 0; - Linkdata.batterylevel = batterymonitor.vbat_per; - LOG_LV1("KB-P2C", " KBLinkChar_Buffer.notify sendKeys sending %i [1] %i", sizeof(Linkdata), Linkdata.report[1]); - KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); -#endif -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD - ; // Don't send keys to slaves -#endif } + /**************************************************************************************************************************/ #ifndef MOVE_STEP -#define MOVE_STEP 8 + #define MOVE_STEP 8 #endif -void bt_sendMouseKey(uint16_t keycode) { +void bt_sendMouseKey(uint16_t keycode) +{ static uint8_t movestep = MOVE_STEP; -#if BLE_HID == 1 - switch (keycode) { - case KC_MS_OFF: - blehid.mouseButtonRelease(hid_conn_hdl); - break; - case KC_MS_UP: - blehid.mouseMove(hid_conn_hdl, 0, -movestep); - break; - case KC_MS_DOWN: - blehid.mouseMove(hid_conn_hdl, 0, movestep); - break; - case KC_MS_LEFT: - blehid.mouseMove(hid_conn_hdl, -movestep, 0); - break; - case KC_MS_RIGHT: - blehid.mouseMove(hid_conn_hdl, movestep, 0); - break; - - case KC_MS_ACCEL0: - movestep = MOVE_STEP / MOVE_STEP; - break; - case KC_MS_ACCEL1: - movestep = MOVE_STEP; - break; - case KC_MS_ACCEL2: - movestep = MOVE_STEP + MOVE_STEP; - break; - - case KC_MS_BTN1: - blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_LEFT); - break; - case KC_MS_BTN2: - blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_RIGHT); - break; - case KC_MS_BTN3: - blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_MIDDLE); - break; - case KC_MS_BTN4: - blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_BACKWARD); - break; - case KC_MS_BTN5: - blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_FORWARD); - break; - - case KC_MS_WH_UP: - blehid.mouseScroll(hid_conn_hdl, -1); - break; - case KC_MS_WH_DOWN: - blehid.mouseScroll(hid_conn_hdl, 1); - break; - case KC_MS_WH_LEFT: - blehid.mousePan(hid_conn_hdl, -1); - break; - case KC_MS_WH_RIGHT: - blehid.mousePan(hid_conn_hdl, 1); - break; + #if BLE_HID == 1 + switch (keycode) + { + case KC_MS_OFF: blehid.mouseButtonRelease(hid_conn_hdl); break; + case KC_MS_UP: blehid.mouseMove(hid_conn_hdl, 0, -movestep); break; + case KC_MS_DOWN: blehid.mouseMove(hid_conn_hdl, 0, movestep); break; + case KC_MS_LEFT: blehid.mouseMove(hid_conn_hdl, -movestep, 0); break; + case KC_MS_RIGHT: blehid.mouseMove(hid_conn_hdl, movestep, 0); break; + + case KC_MS_ACCEL0: movestep = MOVE_STEP/MOVE_STEP; break; + case KC_MS_ACCEL1: movestep = MOVE_STEP; break; + case KC_MS_ACCEL2: movestep = MOVE_STEP+MOVE_STEP; break; + + case KC_MS_BTN1: blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_LEFT); break; + case KC_MS_BTN2: blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_RIGHT); break; + case KC_MS_BTN3: blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_MIDDLE); break; + case KC_MS_BTN4: blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_BACKWARD); break; + case KC_MS_BTN5: blehid.mouseButtonPress(hid_conn_hdl, MOUSE_BUTTON_FORWARD); break; + + case KC_MS_WH_UP: blehid.mouseScroll(hid_conn_hdl, -1); break; + case KC_MS_WH_DOWN: blehid.mouseScroll(hid_conn_hdl, 1); break; + case KC_MS_WH_LEFT: blehid.mousePan(hid_conn_hdl, -1); break; + case KC_MS_WH_RIGHT: blehid.mousePan(hid_conn_hdl, 1); break; } -#endif -#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD - Linkdata.report[0] = 0; // initialize the slave to master link data... - Linkdata.report[1] = 0; - Linkdata.report[2] = 0; - Linkdata.report[3] = 0; - Linkdata.report[4] = 0; - Linkdata.report[5] = 0; - Linkdata.report[6] = 0; - Linkdata.report[7] = 0; - Linkdata.command = 0; - Linkdata.timesync = 0; - Linkdata.specialkeycode = keycode; - Linkdata.batterylevel = batterymonitor.vbat_per; - LOG_LV1("KB-P2C", " KBLinkChar_Buffer.notify sendMouseKey"); - KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); -#endif -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD - ; // Don't send keys to slaves -#endif + #endif + #if BLE_PERIPHERAL ==1 // PERIPHERAL IS THE SLAVE BOARD + Linkdata.keycode[0] = 0; // initialize the slave to master link data... + Linkdata.keycode[1] = 0; + Linkdata.keycode[2] = 0; + Linkdata.keycode[3] = 0; + Linkdata.keycode[4] = 0; + Linkdata.keycode[5] = 0; + Linkdata.modifier = 0; + Linkdata.layer = 0; + //Linkdata.command = 0; + //Linkdata.timesync = 0; + Linkdata.specialkeycode = keycode; + Linkdata.batterylevel = batterymonitor.vbat_per; + LOG_LV1("KB-P2C"," KBLinkChar_Buffer.notify sendMouseKey"); + KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); + #endif + #if BLE_CENTRAL ==1 // CENTRAL IS THE MASTER BOARD + ; // Don't send keys to slaves + #endif } /**************************************************************************************************************************/ -void bt_sendMediaKey(uint16_t keycode) { -#if BLE_HID == 1 - blehid.consumerKeyPress(hid_conn_hdl, hid_GetMediaUsageCode(keycode)); - delay(HIDREPORTINGINTERVAL); - blehid.consumerKeyRelease(); // TODO: do I need this here??? -#endif -#if BLE_PERIPHERAL == 1 // PERIPHERAL IS THE SLAVE BOARD - Linkdata.report[0] = 0; // initialize the slave to master link data... - Linkdata.report[1] = 0; - Linkdata.report[2] = 0; - Linkdata.report[3] = 0; - Linkdata.report[4] = 0; - Linkdata.report[5] = 0; - Linkdata.report[6] = 0; - Linkdata.report[7] = 0; - Linkdata.command = 0; - Linkdata.timesync = 0; - Linkdata.specialkeycode = keycode; - Linkdata.batterylevel = batterymonitor.vbat_per; - LOG_LV1("KB-P2C", " KBLinkChar_Buffer.notify sendMediaKey"); - KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); -#endif -#if BLE_CENTRAL == 1 // CENTRAL IS THE MASTER BOARD - ; // Don't send keys to slaves -#endif +void bt_sendMediaKey(uint16_t keycode) +{ + #if BLE_HID == 1 + blehid.consumerKeyPress(hid_conn_hdl, hid_GetMediaUsageCode(keycode)); + delay(HIDREPORTINGINTERVAL); + blehid.consumerKeyRelease();// TODO: do I need this here??? + #endif + #if BLE_PERIPHERAL ==1 // PERIPHERAL IS THE SLAVE BOARD + Linkdata.keycode[0] = 0; // initialize the slave to master link data... + Linkdata.keycode[1] = 0; + Linkdata.keycode[2] = 0; + Linkdata.keycode[3] = 0; + Linkdata.keycode[4] = 0; + Linkdata.keycode[5] = 0; + Linkdata.layer = 0; + Linkdata.modifier = 0; + //Linkdata.command = 0; + //Linkdata.timesync = 0; + Linkdata.specialkeycode = keycode; + Linkdata.batterylevel = batterymonitor.vbat_per; + LOG_LV1("KB-P2C"," KBLinkChar_Buffer.notify sendMediaKey"); + KBLinkChar_Buffer.notify(&Linkdata, sizeof(Linkdata)); + #endif + #if BLE_CENTRAL ==1 // CENTRAL IS THE MASTER BOARD + ; // Don't send keys to slaves + #endif } /**************************************************************************************************************************/ diff --git a/firmware/bluetooth.h b/firmware/bluetooth.h index 308df231..c8ac6295 100644 --- a/firmware/bluetooth.h +++ b/firmware/bluetooth.h @@ -7,82 +7,80 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BLUETOOTH_H #define BLUETOOTH_H -#include "bluetooth_config.h" +#include #include "firmware_config.h" +#include "bluetooth_config.h" #include "nrf52gpio.h" -#include #undef min #undef max -#include "HID.h" #include "KeyScanner.h" -#include "datastructures.h" #include "nrf52battery.h" +#include "datastructures.h" +#include "HID.h" -typedef struct { // Payload for BLE messages between split boards. Intended for slave to master - // BLE messages have a size limit of 20 bytes. Any extra and we have to do some ATT_MTU magic... - uint8_t report[8]; // 8 bytes - uint32_t command; // 4 bytes - uint32_t timesync; // 4 bytes - uint8_t batterylevel; // 1 byte - uint16_t specialkeycode; // 2 bytes = 19 bytes... sizeof gets 20 bytes... -} Payload; - -typedef struct { // Payload for BLE messages between split boards. Intended for master to slave - // BLE messages have a size limit of 20 bytes. Any extra and we have to do some ATT_MTU magic... - uint8_t layer; // 1 byte - uint32_t command; // 4 bytes - uint32_t timesync; // 4 bytes -} StatePayload; - -void updateBLEStatus(void); -void bt_setup(uint8_t BLEProfile); -void bt_startAdv(void); -void bt_disconnect(void); -bool bt_isConnected(void); -void bt_stopAdv(void); -ble_gap_addr_t bt_getMACAddr(void); -void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap); - -void bt_sendKeys(uint8_t currentReport[8]); -void bt_sendKeys(std::array currentReport); -void bt_sendMediaKey(uint16_t keycode); -void bt_sendMouseKey(uint16_t keycode); -void rssi_changed_callback(uint16_t conn_hdl, int8_t rssi); -void advertizing_slow_callback(void); -void advertizing_stop_callback(void); -void prph_connect_callback(uint16_t conn_handle); -void prph_disconnect_callback(uint16_t conn_handle, uint8_t reason); - -#if BLE_PERIPHERAL == 1 | BLE_CENTRAL == 1 -void sendlayer(uint8_t layer); -#endif - -#if BLE_PERIPHERAL == 1 -void cccd_callback(uint16_t conn_hdl, BLECharacteristic *chr, uint16_t cccd_value); -void layer_request_callback(uint16_t conn_hdl, BLECharacteristic *chr, uint8_t *data, uint16_t len); -#endif - -#if BLE_CENTRAL == 1 -void notify_callback(BLEClientCharacteristic *chr, uint8_t *data, uint16_t len); -void scan_callback(ble_gap_evt_adv_report_t *report); -void cent_connect_callback(uint16_t conn_handle); -void cent_disconnect_callback(uint16_t conn_handle, uint8_t reason); -#endif + typedef __packed struct { // Payload for BLE messages between split boards. Intended for slave to master + // BLE messages have a size limit of 20 bytes. Any extra and we have to do some ATT_MTU magic... + uint8_t keycode[6]; // 6 bytes + uint8_t modifier; // 1 byte + uint8_t batterylevel; // 1 byte + uint16_t layer; // 2 byte + //uint32_t command; // 4 bytes + //uint32_t timesync; // 4 bytes + + uint16_t specialkeycode; // 2 bytes = 20 bytes... + } Payload; + + typedef __packed struct { // Payload for BLE messages between split boards. Intended for master to slave + // BLE messages have a size limit of 20 bytes. Any extra and we have to do some ATT_MTU magic... + uint32_t command; // 4 bytes + uint32_t timesync; // 4 bytes + uint16_t layer; // 1 byte + } StatePayload; + + void updateBLEStatus(void); + void bt_setup(uint8_t BLEProfile); + void bt_startAdv(void); + void bt_disconnect(void); + bool bt_isConnected(void); + void bt_stopAdv(void); + ble_gap_addr_t bt_getMACAddr(void); + void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap); + void bt_sendKeys(HIDKeyboard currentReport); + void bt_sendMediaKey(uint16_t keycode); + void bt_sendMouseKey(uint16_t keycode); + void rssi_changed_callback(uint16_t conn_hdl, int8_t rssi); + void advertizing_slow_callback(void); + void advertizing_stop_callback(void); + void prph_connect_callback(uint16_t conn_handle); + void prph_disconnect_callback(uint16_t conn_handle, uint8_t reason); + + #if BLE_PERIPHERAL ==1 | BLE_CENTRAL ==1 + void sendlayer(uint8_t layer); + #endif + + #if BLE_PERIPHERAL == 1 + void cccd_callback(uint16_t conn_hdl,BLECharacteristic* chr, uint16_t cccd_value) ; + void layer_request_callback (uint16_t conn_hdl,BLECharacteristic* chr, uint8_t* data, uint16_t len); + #endif + + #if BLE_CENTRAL == 1 + void notify_callback(BLEClientCharacteristic* chr, uint8_t* data, uint16_t len); + void scan_callback(ble_gap_evt_adv_report_t* report); + void cent_connect_callback(uint16_t conn_handle); + void cent_disconnect_callback(uint16_t conn_handle, uint8_t reason); + #endif #endif /* BLUETOOTH_H */ diff --git a/firmware/bluetooth_config.h b/firmware/bluetooth_config.h index 67f574e3..be462e09 100644 --- a/firmware/bluetooth_config.h +++ b/firmware/bluetooth_config.h @@ -7,30 +7,29 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BLUETOOTH_CONFIG_H #define BLUETOOTH_CONFIG_H -// NEW BLE KEYBOARD LINK BLE SERVICE & CHARACTERISTICS -- randomly generated UUID. DO NOT CHANGE. -#define UUID128_SVC_KEYBOARD_LINK 0xf9ed59d396fa4752a7dfb16d7b9e0443 // SERVICE TO BE RUN ON SLAVES. "CLIENT" TO RUN ON MASTER -#define UUID128_CHR_KEYBOARD_LAYERS 0xccccc76aa03d43f993ec2fc6d82a7902 // 1 Byte for Active Layer -#define UUID128_CHR_KEYBOARD_LAYER_REQUEST 0xae31cd09b0734df5b5bd20baaf18239c // 1 Byte for request from Master to Slaves to change layer -#define UUID128_CHR_KEYBOARD_BUFFER 0x220f9018372a46da81d3cd196a57d5ab // 7 Bytes for passing HID MODS and BUFFER from Slave to Master + +// NEW BLE KEYBOARD LINK BLE SERVICE & CHARACTERISTICS -- randomly generated UUID. DO NOT CHANGE. +#define UUID128_SVC_KEYBOARD_LINK 0xf9ed59d396fa4752a7dfb16d7b9e0443 // SERVICE TO BE RUN ON SLAVES. "CLIENT" TO RUN ON MASTER +#define UUID128_CHR_KEYBOARD_LAYERS 0xccccc76aa03d43f993ec2fc6d82a7902 // 1 Byte for Active Layer +#define UUID128_CHR_KEYBOARD_LAYER_REQUEST 0xae31cd09b0734df5b5bd20baaf18239c // 1 Byte for request from Master to Slaves to change layer +#define UUID128_CHR_KEYBOARD_BUFFER 0x220f9018372a46da81d3cd196a57d5ab // 7 Bytes for passing HID MODS and BUFFER from Slave to Master #define UUID128_COUNT 4 + /***************************************************************************/ /* Maximum current (current peaks) when radio is ON broadcasting */ /* Measured on E73 modules without power circuitry */ @@ -45,8 +44,8 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE /* -12 17.93 mA */ /* -8 18.87 mA */ /* -4 19.03 mA */ -/* 0 19.99 mA */ -/* 4 30.52 mA (1) */ +/* 0 19.99 mA */ +/* 4 30.52 mA (1) */ /* 8 n/a 42.64 mA (1) */ /* */ /* Notes: */ @@ -65,16 +64,17 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE /* Note that this only applies when connected */ /***************************************************************************/ -// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 +// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4 #ifndef DEVICE_POWER -#define DEVICE_POWER 0 // Use 0. This uses less power and allows for a longer battery life. See above... + #define DEVICE_POWER 0 // Use 0. This uses less power and allows for a longer battery life. See above... #endif #define FILTER_RSSI_BELOW_STRENGTH -90 // These can be modified. Not sure of what values are allowed. -#define PNP_ID_VENDOR_ID_SOURCE 0x02 /**< Vendor ID Source. */ -#define PNP_ID_VENDOR_ID 0x1915 /**< Vendor ID. */ -#define PNP_ID_PRODUCT_ID 0xEEEE /**< Product ID. */ -#define PNP_ID_PRODUCT_VERSION 0x0001 /**< Product Version. */ +#define PNP_ID_VENDOR_ID_SOURCE 0x02 /**< Vendor ID Source. */ +#define PNP_ID_VENDOR_ID 0x1915 /**< Vendor ID. */ +#define PNP_ID_PRODUCT_ID 0xEEEE /**< Product ID. */ +#define PNP_ID_PRODUCT_VERSION 0x0001 /**< Product Version. */ + #endif /* BLUETOOTH_CONFIG_H */ diff --git a/firmware/combo_engine.cpp b/firmware/combo_engine.cpp index 304e017e..312bf43d 100644 --- a/firmware/combo_engine.cpp +++ b/firmware/combo_engine.cpp @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -25,41 +22,47 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #include "combo_engine.h" -ComboEngine combos; - -ComboEngine::ComboEngine() { - /*combolist = {}; - monolist = {}; - substlist = {}; - macrolist = {}; - activecombos = {}; - activesubst = {}; - keycodesused_multi = {}; - keycodesused_single = {}; - keycodebuffertosend = {};*/ // these get initialized with empty vectors anyways... - activemacrosent = false; - activecomboscount = 0; - activesubstcount = 0; - activemacrocount = 0; +#ifdef ENABLE_COMBOS + ComboEngine combos; +#endif + + +ComboEngine::ComboEngine() +{ + /*combolist = {}; + monolist = {}; + substlist = {}; + macrolist = {}; + activecombos = {}; + activesubst = {}; + keycodesused_multi = {}; + keycodesused_single = {}; + keycodebuffertosend = {};*/ // these get initialized with empty vectors anyways... + activemacrosent= false; + activecomboscount = 0; + activesubstcount = 0; + activemacrocount = 0; } // cppcheck-suppress unusedFunction -void ComboEngine::clearLists() { - combolist.clear(); - monolist.clear(); - substlist.clear(); - macrolist.clear(); - keycodesused_multi.clear(); - keycodesused_single.clear(); +void ComboEngine::clearLists() +{ + combolist.clear(); + monolist.clear(); + substlist.clear(); + macrolist.clear(); + keycodesused_multi.clear(); + keycodesused_single.clear(); } /**************************************************************************************************************************/ /* COMBOS BELOW... */ /**************************************************************************************************************************/ // cppcheck-suppress unusedFunction -void ComboEngine::addComboToList(trigger_keycodes_t trigger, uint16_t keycode) { +void ComboEngine::addComboToList(trigger_keycodes_t trigger, uint16_t keycode) +{ std::sort(trigger.begin(), trigger.end()); // pre-sorts before adding to combolist. - if (trigger.size() > 1) // combos should always replace 2 keystrokes with 1... + if (trigger.size()>1) // combos should always replace 2 keystrokes with 1... { combolist.push_back(make_pair(trigger, keycode)); keycodesused_multi.insert(keycodesused_multi.end(), trigger.begin(), trigger.end()); @@ -69,116 +72,124 @@ void ComboEngine::addComboToList(trigger_keycodes_t trigger, uint16_t keycode) { } // cppcheck-suppress unusedFunction -bool ComboEngine::anyCombosConfigured() { return combolist.size() > 0; } +bool ComboEngine::anyCombosConfigured() +{ + return combolist.size()>0; +} -uint8_t ComboEngine::findActiveCombos(trigger_keycodes_t activekeycodes) { - activecombos.clear(); - activesubst.clear(); - std::sort(activekeycodes.begin(), activekeycodes.end()); // include needs both to be sorted. - std::copy_if(combolist.begin(), combolist.end(), std::back_inserter(activecombos), - [activekeycodes](combo_t combo) { return std::includes(activekeycodes.begin(), activekeycodes.end(), combo.first.begin(), combo.first.end()); }); - std::copy_if(substlist.begin(), substlist.end(), std::back_inserter(activesubst), - [activekeycodes](subst_t combo) { return std::includes(activekeycodes.begin(), activekeycodes.end(), combo.first.begin(), combo.first.end()); }); - activecomboscount = activecombos.size(); - activesubstcount = activesubst.size(); - return activecomboscount + activesubstcount; + +uint8_t ComboEngine::findActiveCombos(trigger_keycodes_t activekeycodes) +{ + activecombos.clear(); + activesubst.clear(); + std::sort(activekeycodes.begin(), activekeycodes.end()); // include needs both to be sorted. + std::copy_if (combolist.begin(), combolist.end(), std::back_inserter(activecombos), [activekeycodes] (combo_t combo){ return std::includes(activekeycodes.begin(),activekeycodes.end(), combo.first.begin(), combo.first.end() );} ); + std::copy_if (substlist.begin(), substlist.end(), std::back_inserter(activesubst), [activekeycodes] (subst_t combo){ return std::includes(activekeycodes.begin(),activekeycodes.end(), combo.first.begin(), combo.first.end() );} ); + activecomboscount = activecombos.size(); + activesubstcount = activesubst.size(); + return activecomboscount + activesubstcount; } -uint8_t ComboEngine::countActiveCombosKeys(trigger_keycodes_t activekeycodes) { + +uint8_t ComboEngine::countActiveCombosKeys(trigger_keycodes_t activekeycodes) +{ trigger_keycodes_t keycodesusedbycombos = keycodesused_multi; // this includes both combos and substs - return std::count_if(activekeycodes.begin(), activekeycodes.end(), [keycodesusedbycombos](uint16_t keycode) { - return (std::binary_search(keycodesusedbycombos.begin(), keycodesusedbycombos.end(), keycode)); - }); + return std::count_if(activekeycodes.begin(), activekeycodes.end(), [keycodesusedbycombos] (uint16_t keycode){return (std::binary_search(keycodesusedbycombos.begin(),keycodesusedbycombos.end(),keycode));}); } -combo_t ComboEngine::findLargestCombo() { - combo_t it = - *std::max_element(activecombos.begin(), activecombos.end(), [](combo_t comboa, combo_t combob) { return (comboa.first.size() < combob.first.size()); }); - return it; + +combo_t ComboEngine::findLargestCombo() +{ + combo_t it = *std::max_element(activecombos.begin(), activecombos.end(),[](combo_t comboa, combo_t combob){return (comboa.first.size() < combob.first.size());} ); + return it; } -trigger_keycodes_t ComboEngine::processActiveKeycodewithComboKeys(trigger_keycodes_t activekeycodes) { - trigger_keycodes_t keycodesusedbycombos = keycodesused_multi; // this includes both combos and substs - activekeycodes.erase(std::remove_if(activekeycodes.begin(), activekeycodes.end(), - [keycodesusedbycombos](uint16_t keycode) { - return (std::binary_search(keycodesusedbycombos.begin(), keycodesusedbycombos.end(), keycode)); - }), - activekeycodes.end()); - return activekeycodes; + +trigger_keycodes_t ComboEngine::processActiveKeycodewithComboKeys(trigger_keycodes_t activekeycodes) +{ + trigger_keycodes_t keycodesusedbycombos = keycodesused_multi; // this includes both combos and substs + activekeycodes.erase(std::remove_if(activekeycodes.begin(), activekeycodes.end(), [keycodesusedbycombos] (uint16_t keycode){return (std::binary_search(keycodesusedbycombos.begin(),keycodesusedbycombos.end(),keycode));}),activekeycodes.end()); + return activekeycodes; } -trigger_keycodes_t ComboEngine::processActiveKeycodewithCombos(trigger_keycodes_t activekeycodes) { + +trigger_keycodes_t ComboEngine::processActiveKeycodewithCombos(trigger_keycodes_t activekeycodes) +{ combo_t comboToUse = {}; subst_t substToUse = {}; uint8_t combosize = 0; uint8_t substsize = 0; trigger_keycodes_t keycodesToRemove; - if (activecomboscount) { - comboToUse = findLargestCombo(); - combosize = comboToUse.first.size(); - } - if (activesubstcount) { - substToUse = findLargestSubst(); - substsize = substToUse.first.size(); - } - - if (combosize < substsize) { - keycodesToRemove = substToUse.first; - addKeycodeStringToBuffer(substToUse.second); - } else { - keycodesToRemove = comboToUse.first; - activekeycodes.push_back(comboToUse.second); - } - activekeycodes.erase( - std::remove_if(activekeycodes.begin(), activekeycodes.end(), - [keycodesToRemove](uint16_t keycode) { return (std::binary_search(keycodesToRemove.begin(), keycodesToRemove.end(), keycode)); }), - activekeycodes.end()); - return activekeycodes; + if (activecomboscount) {comboToUse = findLargestCombo(); combosize = comboToUse.first.size();} + if (activesubstcount) {substToUse = findLargestSubst(); substsize = substToUse.first.size();} + + if (combosize 0; } +bool ComboEngine::anySubstConfigured() +{ + return substlist.size()>0; +} + -subst_t ComboEngine::findLargestSubst() { - subst_t it = - *std::max_element(activesubst.begin(), activesubst.end(), [](subst_t comboa, subst_t combob) { return (comboa.first.size() < combob.first.size()); }); - return it; +subst_t ComboEngine::findLargestSubst() +{ + subst_t it = *std::max_element(activesubst.begin(), activesubst.end(),[](subst_t comboa, subst_t combob){return (comboa.first.size() < combob.first.size());} ); + return it; } /**************************************************************************************************************************/ /* BUFFER OPERATIONS BELOW... */ /**************************************************************************************************************************/ -void ComboEngine::addKeycodeStringToBuffer(trigger_keycodes_t keycodestosend) { - keycodebuffertosend.reserve(keycodebuffertosend.size() + keycodestosend.size()); - keycodebuffertosend.insert(keycodebuffertosend.end(), keycodestosend.begin(), keycodestosend.end()); +void ComboEngine::addKeycodeStringToBuffer(trigger_keycodes_t keycodestosend) +{ + keycodebuffertosend.reserve(keycodebuffertosend.size()+keycodestosend.size()); + keycodebuffertosend.insert(keycodebuffertosend.end(), keycodestosend.begin(),keycodestosend.end()); } -void ComboEngine::addKeycodeStringToList(trigger_keycodes_t trigger, trigger_keycodes_t keycodestosend) { + +void ComboEngine::addKeycodeStringToList(trigger_keycodes_t trigger, trigger_keycodes_t keycodestosend) +{ std::sort(trigger.begin(), trigger.end()); // pre-sorts before adding to substlist. - if (trigger.size() > 1) { + if (trigger.size()>1) + { substlist.push_back(make_pair(trigger, keycodestosend)); keycodesused_multi.insert(keycodesused_multi.end(), trigger.begin(), trigger.end()); std::sort(keycodesused_multi.begin(), keycodesused_multi.end()); // needed for the next operation @@ -192,33 +203,33 @@ void ComboEngine::addKeycodeStringToList(trigger_keycodes_t trigger, trigger_key } } -bool ComboEngine::anyMacrosConfigured() { return macrolist.size() > 0; } +bool ComboEngine::anyMacrosConfigured() +{ + return macrolist.size()>0; +} -bool ComboEngine::anyMacrosActive(trigger_keycodes_t activekeycodes) { +bool ComboEngine::anyMacrosActive(trigger_keycodes_t activekeycodes) +{ activemacrocount = 0; activemacro.clear(); std::sort(activekeycodes.begin(), activekeycodes.end()); // include needs both to be sorted. - std::copy_if(macrolist.begin(), macrolist.end(), std::back_inserter(activemacro), - [activekeycodes](subst_t combo) { return std::includes(activekeycodes.begin(), activekeycodes.end(), combo.first.begin(), combo.first.end()); }); + std::copy_if (macrolist.begin(), macrolist.end(), std::back_inserter(activemacro), [activekeycodes] (subst_t combo){ return std::includes(activekeycodes.begin(),activekeycodes.end(), combo.first.begin(), combo.first.end() );} ); activemacrocount = activemacro.size(); - if (activemacrocount < 1) { - activemacrosent = false; - } // reset sent state when no macros are triggered. - return activemacrocount > 0; + if (activemacrocount<1){activemacrosent = false;} // reset sent state when no macros are triggered. + return activemacrocount>0; } -trigger_keycodes_t ComboEngine::processActiveMacros(trigger_keycodes_t activekeycodes) { +trigger_keycodes_t ComboEngine::processActiveMacros(trigger_keycodes_t activekeycodes) +{ subst_t macro = activemacro.back(); - trigger_keycodes_t keycodesToRemove = macro.first; - if (!activemacrosent) { - addKeycodeStringToBuffer(macro.second); // send the macro to the buffer - activemacrosent = true; // set sent state so that it doesn't get sent twice. Will be reset in anyMacrosActive + trigger_keycodes_t keycodesToRemove = macro.first; + if (!activemacrosent) + { + addKeycodeStringToBuffer(macro.second); // send the macro to the buffer + activemacrosent = true; // set sent state so that it doesn't get sent twice. Will be reset in anyMacrosActive } // remove trigger regardless of sent or not. - activekeycodes.erase( - std::remove_if(activekeycodes.begin(), activekeycodes.end(), - [keycodesToRemove](uint16_t keycode) { return (std::binary_search(keycodesToRemove.begin(), keycodesToRemove.end(), keycode)); }), - activekeycodes.end()); + activekeycodes.erase(std::remove_if(activekeycodes.begin(), activekeycodes.end(), [keycodesToRemove] (uint16_t keycode){return (std::binary_search(keycodesToRemove.begin(),keycodesToRemove.end(),keycode));}),activekeycodes.end()); return activekeycodes; } \ No newline at end of file diff --git a/firmware/combo_engine.h b/firmware/combo_engine.h index 5969c8f4..71a16f16 100644 --- a/firmware/combo_engine.h +++ b/firmware/combo_engine.h @@ -7,94 +7,102 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef COMBO_ENGINE_H #define COMBO_ENGINE_H -#include "advanced_keycodes.h" -#include "hid_keycodes.h" -#include #include #include -#include -#include #include +#include +#include +#include +#include "hid_keycodes.h" +#include "advanced_keycodes.h" +#include "keymap.h" -typedef std::vector trigger_keycodes_t; -typedef std::pair combo_t; -typedef std::vector combolist_t; -typedef std::pair subst_t; -typedef std::vector substlist_t; +typedef std::vector trigger_keycodes_t; +typedef std::pair combo_t; +typedef std::vector < combo_t > combolist_t; -template bool IsSubset(std::vector A, std::vector B) { - std::sort(A.begin(), A.end()); - std::sort(B.begin(), B.end()); - return std::includes(A.begin(), A.end(), B.begin(), B.end()); +typedef std::pair subst_t; +typedef std::vector < subst_t > substlist_t; + +template +bool IsSubset(std::vector A, std::vector B) +{ + std::sort(A.begin(), A.end()); + std::sort(B.begin(), B.end()); + return std::includes(A.begin(), A.end(), B.begin(), B.end()); } -template bool IsSubsetPreSorted(std::vector A, std::vector B) { return std::includes(A.begin(), A.end(), B.begin(), B.end()); } +template +bool IsSubsetPreSorted(std::vector A, std::vector B) +{ + return std::includes(A.begin(), A.end(), B.begin(), B.end()); +} -#define COMB(name, key, ...) combos.addComboToList(trigger_keycodes_t{__VA_ARGS__}, key); +#define COMB(name, key, ...) combos.addComboToList(trigger_keycodes_t {__VA_ARGS__}, key); -// SUBS(substitution_test, "I'd just like to interject for a moment.", KC_H, KC_J, KC_K, KC_L); -#define SUBS(name, stringtosend, ...) combos.addSubstitutionToList(trigger_keycodes_t{__VA_ARGS__}, stringtosend); +//SUBS(substitution_test, "I'd just like to interject for a moment.", KC_H, KC_J, KC_K, KC_L); +#define SUBS(name, stringtosend, ...) combos.addSubstitutionToList(trigger_keycodes_t {__VA_ARGS__}, stringtosend); -// KEYS(keys_hello_world_test, {KC_H, KC_E, KC_L, KC_L, KC_O, KC_SPC, KC_W, KC_O, KC_R, KC_L, KC_D}, KC_A, KC_R, KC_T, KC_S) -#define KEYS(name, keycodestosend, ...) combos.addKeycodeStringToList(trigger_keycodes_t{__VA_ARGS__}, trigger_keycodes_t keycodestosend); +//KEYS(keys_hello_world_test, {KC_H, KC_E, KC_L, KC_L, KC_O, KC_SPC, KC_W, KC_O, KC_R, KC_L, KC_D}, KC_A, KC_R, KC_T, KC_S) +#define KEYS(name, keycodestosend, ...) combos.addKeycodeStringToList(trigger_keycodes_t {__VA_ARGS__}, trigger_keycodes_t keycodestosend); class ComboEngine { -public: - ComboEngine(); - void addComboToList(trigger_keycodes_t trigger, uint16_t keycode); - void addSubstitutionToList(trigger_keycodes_t trigger, char *stringtosend); - void addKeycodeStringToList(trigger_keycodes_t trigger, trigger_keycodes_t keycodestosend); - void addKeycodeStringToBuffer(trigger_keycodes_t keycodestosend); - void clearLists(); - bool anyCombosConfigured(); - bool anySubstConfigured(); - bool anyMacrosConfigured(); - bool anyMacrosActive(trigger_keycodes_t activekeycodes); - uint8_t findActiveCombos(trigger_keycodes_t activekeycodes); - uint8_t countActiveCombosKeys(trigger_keycodes_t activekeycodes); - trigger_keycodes_t processActiveKeycodewithCombos(trigger_keycodes_t activekeycodes); - trigger_keycodes_t convertCStrToKeycodeVector(char *stringtoconvert); - trigger_keycodes_t processActiveKeycodewithComboKeys(trigger_keycodes_t activekeycodes); - trigger_keycodes_t processActiveMacros(trigger_keycodes_t activekeycodes); - - trigger_keycodes_t keycodebuffertosend; - -private: - combo_t findLargestCombo(); - subst_t findLargestSubst(); - - combolist_t combolist; // multi-key swap - combolist_t monolist; // single-key swap - substlist_t substlist; // multi-key macro - substlist_t macrolist; // single-key macro - trigger_keycodes_t keycodesused_multi; // keys used for multi - trigger_keycodes_t keycodesused_single; // keys used for single - combolist_t activecombos; - substlist_t activesubst; - substlist_t activemacro; - uint8_t activecomboscount; - uint8_t activesubstcount; - uint8_t activemacrocount; - - bool activemacrosent; + public: + ComboEngine(); + void addComboToList(trigger_keycodes_t trigger, uint16_t keycode); + void addSubstitutionToList(trigger_keycodes_t trigger,char* stringtosend); + void addKeycodeStringToList(trigger_keycodes_t trigger, trigger_keycodes_t keycodestosend); + void addKeycodeStringToBuffer(trigger_keycodes_t keycodestosend); + void clearLists(); + bool anyCombosConfigured(); + bool anySubstConfigured(); + bool anyMacrosConfigured(); + bool anyMacrosActive(trigger_keycodes_t activekeycodes); + uint8_t findActiveCombos(trigger_keycodes_t activekeycodes); + uint8_t countActiveCombosKeys(trigger_keycodes_t activekeycodes); + trigger_keycodes_t processActiveKeycodewithCombos(trigger_keycodes_t activekeycodes); + trigger_keycodes_t convertCStrToKeycodeVector(char* stringtoconvert); + trigger_keycodes_t processActiveKeycodewithComboKeys(trigger_keycodes_t activekeycodes); + trigger_keycodes_t processActiveMacros(trigger_keycodes_t activekeycodes); + + trigger_keycodes_t keycodebuffertosend; + + private: + combo_t findLargestCombo(); + subst_t findLargestSubst(); + + combolist_t combolist; // multi-key swap + combolist_t monolist; // single-key swap + substlist_t substlist; // multi-key macro + substlist_t macrolist; // single-key macro + trigger_keycodes_t keycodesused_multi; //keys used for multi + trigger_keycodes_t keycodesused_single; //keys used for single + combolist_t activecombos; + substlist_t activesubst; + substlist_t activemacro; + uint8_t activecomboscount; + uint8_t activesubstcount; + uint8_t activemacrocount; + + bool activemacrosent; }; -extern ComboEngine combos; +#ifdef ENABLE_COMBOS + extern ComboEngine combos; +#endif + -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/firmware/datastructures.h b/firmware/datastructures.h index 39d7bf91..ed9ba0d5 100644 --- a/firmware/datastructures.h +++ b/firmware/datastructures.h @@ -7,19 +7,16 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ +*/ #ifndef DATASTRUCTURES_H #define DATASTRUCTURES_H #include @@ -28,55 +25,58 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE // this should be incremented every time the PersistentState structure definition is updated. // This will ensure that the SETTINGS_FILE file is reset when the structure is updated. -typedef union { - struct { - uint8_t version; - uint8_t mode; - uint8_t user1; - uint8_t user2; - - uint32_t matrixscaninterval; // timer interval = normal priority - uint32_t batteryinterval; // timer interval = normal priority - uint32_t keysendinterval; // normal priority - uint32_t lowpriorityloopinterval; - uint32_t lowestpriorityloopinterval; - - uint8_t pinBLELED; - uint8_t pinKBLED; - uint8_t pinPWMLED; - uint8_t pinRGBLED; - - uint8_t pinVCCSwitch; - uint8_t pinChargerControl; - - bool enableBLELED; - bool enableKBLED; - bool enablePWMLED; - bool enableRGBLED; - - bool polarityBLELED; - bool polarityKBLED; - bool polarityPWMLED; - bool enableVCCSwitch; - - bool polarityVCCSwitch; - bool enableChargerControl; - bool polarityChargerControl; - bool enableDisplay; - - bool enableSerial; - bool enableAudio; - bool dummy1; - bool dummy2; - - uint8_t connectionMode; - uint8_t BLEProfile; - uint16_t BLEProfileEdiv[3]; - - char BLEProfileName[3][32]; - }; - char data[140]; -} PersistentState; // meant for configuration and things that we want to store in flash so that we can pick it up on the next reboot. + typedef union { + struct { + uint8_t version; + uint8_t mode; + uint8_t user1; + uint8_t user2; + + uint32_t matrixscaninterval; // timer interval = normal priority + uint32_t batteryinterval; // timer interval = normal priority + uint32_t keysendinterval; // normal priority + uint32_t lowpriorityloopinterval; + uint32_t lowestpriorityloopinterval; + + uint8_t pinBLELED; + uint8_t pinKBLED; + uint8_t pinPWMLED; + uint8_t pinRGBLED; + + uint8_t pinVCCSwitch; + uint8_t pinChargerControl; + + bool enableBLELED; + bool enableKBLED; + bool enablePWMLED; + bool enableRGBLED; + + bool polarityBLELED; + bool polarityKBLED; + bool polarityPWMLED; + bool enableVCCSwitch; + + bool polarityVCCSwitch; + bool enableChargerControl; + bool polarityChargerControl; + bool enableDisplay; + + bool enableSerial; + bool enableAudio; + bool dummy1; + bool dummy2; + + uint8_t connectionMode; + uint8_t BLEProfile; + uint16_t BLEProfileEdiv[3]; + + char BLEProfileName[3][32]; + + }; + char data[140]; } PersistentState; // meant for configuration and things that we want to store in flash so that we can pick it up on the next reboot. + + + typedef struct { uint32_t timestamp; @@ -163,4 +163,51 @@ enum backgroundTaskID { BACKGROUND_TASK_RGBLED }; +struct HIDKeyboard { + uint8_t modifier; + uint8_t keycode[6]; + uint16_t layer; + + bool operator!= (const HIDKeyboard &c2) + { + return !(*this == c2); + } + + inline bool operator== (const HIDKeyboard &c2) + { + return (keycode[0]==c2.keycode[0]) && + (modifier==c2.modifier ) && + (layer==c2.layer ) && + (keycode[1]==c2.keycode[1]) && + (keycode[2]==c2.keycode[2]) && + (keycode[3]==c2.keycode[3]) && + (keycode[4]==c2.keycode[4]) && + (keycode[5]==c2.keycode[5]) ; + + } + + } ; + + + + + +typedef struct { + uint8_t buttons; + int8_t x; + int8_t y; + int8_t wheel; + int8_t pan; + } HIDMouse; + +typedef struct { + uint16_t usage_code; + } HIDConsumer; + +typedef struct { + HIDKeyboard keyboard; + HIDMouse mouse; + HIDConsumer consumer; + } HIDMessages; + #endif diff --git a/firmware/debug_cli.cpp b/firmware/debug_cli.cpp index 1caf6548..fd3c9b74 100644 --- a/firmware/debug_cli.cpp +++ b/firmware/debug_cli.cpp @@ -7,23 +7,21 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "debug_cli.h" //************************************************************************* -uint8_t testlink(uint8_t setpin, uint8_t readpin) { +uint8_t testlink(uint8_t setpin, uint8_t readpin) +{ uint8_t result = 0; pinMode(setpin, OUTPUT); pinMode(readpin, INPUT_PULLDOWN); @@ -33,42 +31,54 @@ uint8_t testlink(uint8_t setpin, uint8_t readpin) { uint8_t final = digitalRead(readpin); pinMode(setpin, INPUT); pinMode(readpin, INPUT); - if (!initial) { - result = final * 1; + if (!initial) + { + result =final*1; } return result; + } //************************************************************************* -void matrix_key_init_separator(bool singlekey) { Serial.println("-----------------------------------------------------------------"); } -void helpline(void) { - Serial.println(""); - Serial.println("Type 'h' to get a list of commands with descriptions"); +void matrix_key_init_separator(bool singlekey) +{ + Serial.println("-----------------------------------------------------------------"); +} +void helpline(void) +{ + Serial.println(""); + Serial.println("Type 'h' to get a list of commands with descriptions"); } //************************************************************************* -void matrix_key_init(bool singlekey) { - while (Serial.available() > 0) { - Serial.read(); // clean up serial buffer +void matrix_key_init(bool singlekey) +{ + while (Serial.available() > 0) + { + Serial.read(); // clean up serial buffer } matrix_key_init_separator(singlekey); - if (singlekey) { + if (singlekey) + { Serial.println(" KEY in a MATRIX GPIO TESTER"); - } else { + } + else + { Serial.println(" MATRIX GPIO TESTER"); } matrix_key_init_separator(singlekey); Serial.println("Press each key for 1 second, one at a time"); - if (!singlekey) { - Serial.println("GPIO Data will only be updated when new rows/columns are detected"); - Serial.println("The order shown will be depend on the sequence of keys you press"); + if(!singlekey) + { + Serial.println("GPIO Data will only be updated when new rows/columns are detected"); + Serial.println("The order shown will be depend on the sequence of keys you press"); } Serial.println("Diode Pins: Cathode = Positive, Anode = Negative"); matrix_key_init_separator(singlekey); Serial.println(" if DIODE_DIRECTION = COL2ROW"); - Serial.println(" POS = MATRIX_COL_PINS"); - Serial.println(" NEG = MATRIX_ROW_PINS"); + Serial.println(" POS = MATRIX_COL_PINS"); + Serial.println(" NEG = MATRIX_ROW_PINS"); Serial.println(" else // DIODE_DIRECTION = ROW2COL"); Serial.println(" POS = MATRIX_ROW_PINS"); - Serial.println(" NEG = MATRIX_COL_PINS"); + Serial.println(" NEG = MATRIX_COL_PINS"); matrix_key_init_separator(singlekey); Serial.println("If GPIOs are shown on both POS and NEG, "); Serial.println("you have a wire/short between these GPIOs and not a diode"); @@ -78,7 +88,8 @@ void matrix_key_init(bool singlekey) { matrix_key_init_separator(singlekey); } -void matrix_key_end(bool singlekey) { +void matrix_key_end(bool singlekey) +{ matrix_key_init_separator(singlekey); Serial.println("Done"); matrix_key_init_separator(singlekey); @@ -86,195 +97,208 @@ void matrix_key_end(bool singlekey) { } //************************************************************************* -void matrix_key_test(bool singlekey) { -#ifdef NRF52840_XXAA -// below tests all nrf52840 GPIOs except 32kHz xtal and reset -#ifdef NICENANO // 14 and 16 are connected to 18 - reset line - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; -#else - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; -#endif -#else - // below tests all nrf52832 GPIOs except 32kHz xtal and reset - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; -#endif +void matrix_key_test(bool singlekey) +{ + #ifdef NRF52840_XXAA + #ifdef ARDUINO_NICE_NANO + //Use this for nicenano - 14 and 16 are connected to 18 - reset line + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #else + // below tests all nrf52840 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #endif + #else + // below tests all nrf52832 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; + #endif - uint8_t pincount = sizeof(pins) / sizeof(pins[0]); - - static std::vector pospins; - static std::vector negpins; - while (Serial.available() == 0) { + uint8_t pincount = sizeof(pins)/sizeof(pins[0]); + + static std::vector pospins; + static std::vector negpins; + while (Serial.available() == 0) + { updateWDT(); - if (singlekey) { + if(singlekey){ pospins.clear(); - negpins.clear(); + negpins.clear(); } - + bool updated = false; - for (uint8_t i = 0; i < pincount; i++) { - for (uint8_t j = 0; j < pincount; j++) { - if (testlink(pins[i], pins[j])) { - auto it = std::find(pospins.begin(), pospins.end(), pins[i]); - if (it != pospins.end()) { - // do nothing - } else { - pospins.push_back(pins[i]); - updated = true; - } - it = std::find(negpins.begin(), negpins.end(), pins[j]); - if (it != negpins.end()) { - // do nothing - } else { - negpins.push_back(pins[j]); - updated = true; + for (uint8_t i=0; i 0) { - Serial.read(); + while (Serial.available() > 0) + { + Serial.read(); } - pospins.clear(); // clear up the buffers in case we test again - negpins.clear(); + pospins.clear();//clear up the buffers in case we test again + negpins.clear(); } + /**************************************************************************************************************************/ -void gpiotester() { - keyscantimer.stop(); +void gpiotester(){ + keyscantimer.stop(); batterytimer.stop(); -#ifdef NRF52840_XXAA -// below tests all nrf52840 GPIOs except 32kHz xtal and reset -#ifdef NICENANO // 14 and 16 are connected to 18 - reset line - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; -#else - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; -#endif -#else - // below tests all nrf52832 GPIOs except 32kHz xtal and reset - uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; -#endif - uint8_t pincount = sizeof(pins) / sizeof(pins[0]); + #ifdef NRF52840_XXAA + // below tests all nrf52840 GPIOs except 32kHz xtal and reset + #ifdef ARDUINO_NICE_NANO // 14 and 16 are connected to 18 - reset line + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #else + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; + #endif + #else + // below tests all nrf52832 GPIOs except 32kHz xtal and reset + uint8_t pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; + #endif +uint8_t pincount = sizeof(pins)/sizeof(pins[0]); Serial.println("GPIO TESTER"); Serial.println("-------------------------------\n"); - Serial.println(); - Serial.println("i\tGPIO\tGPIO\tFloat \tP.Up \tP.Down\tstatus"); + Serial.println(); +Serial.println("i\tGPIO\tGPIO\tFloat \tP.Up \tP.Down\tstatus"); + + // set up pin as input - for (uint8_t i = 0; i < pincount; i++) { + for (uint8_t i=0; i 0) { - - char incomingCharacter = Serial.read(); - switch (incomingCharacter) { - case 'd': - enterSerialDfu(); + while (Serial.available() > 0) { + updateWDT(); + char incomingCharacter = Serial.read(); + switch (incomingCharacter) { + case 'd': + enterSerialDfu(); break; + - case 'b': - Serial.println("Clear Bonds"); - Serial.println("-------------------------------\n"); - - Serial.println(); - Serial.println("----- Before -----\n"); - bond_print_list(BLE_GAP_ROLE_PERIPH); - bond_print_list(BLE_GAP_ROLE_CENTRAL); - // Bluefruit.clearBonds(); //removed in next BSP? - Bluefruit.Central.clearBonds(); + case 'b': + Serial.println("Clear Bonds"); + Serial.println("-------------------------------\n"); - Serial.println(); - Serial.println("----- After -----\n"); + Serial.println(); + Serial.println("----- Before -----\n"); + bond_print_list(BLE_GAP_ROLE_PERIPH); + bond_print_list(BLE_GAP_ROLE_CENTRAL); + // Bluefruit.clearBonds(); //removed in next BSP? + Bluefruit.Central.clearBonds(); - bond_print_list(BLE_GAP_ROLE_PERIPH); - bond_print_list(BLE_GAP_ROLE_CENTRAL); + Serial.println(); + Serial.println("----- After -----\n"); + + bond_print_list(BLE_GAP_ROLE_PERIPH); + bond_print_list(BLE_GAP_ROLE_CENTRAL); break; - case 'r': - NVIC_SystemReset(); + case 'r': + NVIC_SystemReset(); break; case 'e': InternalFS.format(); @@ -282,85 +306,90 @@ void handleSerial() { case 'u': enterUf2Dfu(); break; - case 'i': - Serial.println("Bluefruit 52 HW Info"); - Serial.println(""); - // Unique Device ID - Serial.print("Device ID : "); - Serial.print(DEVICE_ID_HIGH, HEX); - Serial.println(DEVICE_ID_LOW, HEX); + case 'i': + Serial.println("Bluefruit 52 HW Info"); + Serial.println(""); + // Unique Device ID + Serial.print("Device ID : "); + Serial.print(DEVICE_ID_HIGH, HEX); + Serial.println(DEVICE_ID_LOW, HEX); - // MCU Variant; - Serial.printf("MCU Variant: nRF%X 0x%08X\n", NRF_FICR->INFO.PART, NRF_FICR->INFO.VARIANT); - Serial.printf("Memory : Flash = %d KB, RAM = %d KB\n", NRF_FICR->INFO.FLASH, NRF_FICR->INFO.RAM); + // MCU Variant; + Serial.printf("MCU Variant: nRF%X 0x%08X\n",NRF_FICR->INFO.PART, NRF_FICR->INFO.VARIANT); + Serial.printf("Memory : Flash = %d KB, RAM = %d KB\n", NRF_FICR->INFO.FLASH, NRF_FICR->INFO.RAM); - Serial.println("Keyboard Name : " DEVICE_NAME " "); - Serial.println("Keyboard Model : " DEVICE_MODEL " "); - Serial.println("Keyboard Mfg : " MANUFACTURER_NAME " "); + Serial.println("Keyboard Name : " DEVICE_NAME " "); + Serial.println("Keyboard Model : " DEVICE_MODEL " "); + Serial.println("Keyboard Mfg : " MANUFACTURER_NAME " "); Serial.println(""); - sprintf(buffer, "Device Power : %f", DEVICE_POWER * 1.0); - Serial.println(buffer); - sprintf(buffer, "Filter RSSI : %i", FILTER_RSSI_BELOW_STRENGTH); - Serial.println(buffer); - Serial.println("Type\t RSSI\t name"); - sprintf(buffer, "cent\t %i\t %s", keyboardstate.rssi_cent, keyboardstate.peer_name_cent); - Serial.println(buffer); - sprintf(buffer, "prph\t %i\t %s", keyboardstate.rssi_prph, keyboardstate.peer_name_prph); - Serial.println(buffer); - sprintf(buffer, "cccd\t %i\t %s", keyboardstate.rssi_cccd, keyboardstate.peer_name_cccd); + sprintf(buffer,"Device Power : %f", DEVICE_POWER*1.0); Serial.println(buffer); + sprintf(buffer,"Filter RSSI : %i", FILTER_RSSI_BELOW_STRENGTH); Serial.println(buffer); + Serial.println("Type\t RSSI\t name"); + sprintf(buffer,"cent\t %i\t %s",keyboardstate.rssi_cent, keyboardstate.peer_name_cent);Serial.println(buffer); + sprintf(buffer,"prph\t %i\t %s",keyboardstate.rssi_prph, keyboardstate.peer_name_prph);Serial.println(buffer); + sprintf(buffer,"cccd\t %i\t %s",keyboardstate.rssi_cccd, keyboardstate.peer_name_cccd);Serial.println(buffer); Serial.println(""); - dbgPrintVersion(); - dbgMemInfo(); + dbgPrintVersion(); + dbgMemInfo(); break; - case ' ': - Serial.println(" ____ _ __ __ _ ____ _ _____ "); - Serial.println("| __ )| |_ _ ___| \\/ (_) ___ _ __ ___ | __ )| | | ____|"); - Serial.println("| _ \\| | | | |/ _ \\ |\\/| | |/ __| '__/ _ \\ | _ \\| | | _| "); - Serial.println("| |_) | | |_| | __/ | | | | (__| | | (_) | | |_) | |___| |___ "); - Serial.println("|____/|_|\\__,_|\\___|_| |_|_|\\___|_| \\___/___|____/|_____|_____|"); - Serial.println(" |_____| "); - helpline(); + case ' ': + Serial.println(" ____ _ __ __ _ ____ _ _____ "); + Serial.println("| __ )| |_ _ ___| \\/ (_) ___ _ __ ___ | __ )| | | ____|"); + Serial.println("| _ \\| | | | |/ _ \\ |\\/| | |/ __| '__/ _ \\ | _ \\| | | _| "); + Serial.println("| |_) | | |_| | __/ | | | | (__| | | (_) | | |_) | |___| |___ "); + Serial.println("|____/|_|\\__,_|\\___|_| |_|_|\\___|_| \\___/___|____/|_____|_____|"); + Serial.println(" |_____| "); + helpline(); break; - case 'h': - Serial.println(""); - Serial.println("b Clear Bonds - Warning! Disconnects BLE from Computer!"); - Serial.println("d Enter Serial DFU - Warning! Disconnects BLE from Computer!"); - Serial.println("u Enter UF2 DFU - Warning! Disconnects BLE from Computer!"); - Serial.println("e flash reset - Warning! Disconnects BLE from Computer!"); - Serial.println("r reboot - Warning! Disconnects BLE from Computer!"); - Serial.println("c restore default configuration - Warning! Disconnects BLE from Computer!"); + case 'h': + Serial.println(""); + Serial.println("b Clear Bonds - Warning! Disconnects BLE from Computer!"); + Serial.println("d Enter Serial DFU - Warning! Disconnects BLE from Computer!"); + Serial.println("u Enter UF2 DFU - Warning! Disconnects BLE from Computer!"); + Serial.println("e flash reset - Warning! Disconnects BLE from Computer!"); + Serial.println("r reboot - Warning! Disconnects BLE from Computer!"); + Serial.println("c restore default configuration - Warning! Disconnects BLE from Computer!"); - Serial.println("i Show Device Information"); - Serial.println("p Show Battery Information"); - Serial.println("g run GPIO Tester"); - Serial.println("m full matrix gpio tester"); - Serial.println("k single key matrix gpio tester"); - Serial.println(""); + + + Serial.println("i Show Device Information"); + Serial.println("p Show Battery Information"); + Serial.println("g run GPIO Tester"); + Serial.println("m full matrix gpio tester"); + Serial.println("k single key matrix gpio tester"); + Serial.println(""); break; - case 'p': - intval = batterymonitor.vbat_per; + case 'p': + intval = batterymonitor.vbat_per; - switch (batterymonitor.batt_type) { - case BATT_UNKNOWN: - snprintf(buffer, sizeof(buffer), "VDD = %.0f mV, VBatt = %.0f mV", batterymonitor.vbat_vdd * 1.0, batterymonitor.vbat_mv * 1.0); + switch (batterymonitor.batt_type) + { + case BATT_UNKNOWN: + snprintf (buffer, sizeof(buffer), "VDD = %.0f mV, VBatt = %.0f mV", batterymonitor.vbat_vdd*1.0, batterymonitor.vbat_mv*1.0); break; - case BATT_CR2032: - if (intval > 99) { - snprintf(buffer, sizeof(buffer), "VDD = %.0f mV (%4d %%)", batterymonitor.vbat_mv * 1.0, intval); - } else { - snprintf(buffer, sizeof(buffer), "VDD = %.0f mV (%3d %%)", batterymonitor.vbat_mv * 1.0, intval); - } - + case BATT_CR2032: + if (intval>99) + { + snprintf (buffer, sizeof(buffer), "VDD = %.0f mV (%4d %%)", batterymonitor.vbat_mv*1.0, intval); + } + else + { + snprintf (buffer, sizeof(buffer), "VDD = %.0f mV (%3d %%)", batterymonitor.vbat_mv*1.0, intval); + } + break; - case BATT_LIPO: - if (intval > 99) { - sprintf(buffer, "LIPO = %.0f mV (%4d %%)", batterymonitor.vbat_mv * 1.0, intval); - } else { - sprintf(buffer, "LIPO = %.0f mV (%3d %%)", batterymonitor.vbat_mv * 1.0, intval); - } + case BATT_LIPO: + if (intval>99) + { + sprintf (buffer, "LIPO = %.0f mV (%4d %%)", batterymonitor.vbat_mv*1.0, intval); + } + else + { + sprintf (buffer, "LIPO = %.0f mV (%3d %%)", batterymonitor.vbat_mv*1.0, intval); + } break; case BATT_VDDH: if (intval>99) @@ -375,31 +404,31 @@ void handleSerial() { } Serial.println(buffer); break; - case 'g': - gpiotester(); + case 'g': + gpiotester(); break; - case 'm': - keyscantimer.stop(); - batterytimer.stop(); - matrix_key_init(false); - matrix_key_test(false); - matrix_key_end(false); - keyscantimer.start(); - batterytimer.start(); + case 'm': + keyscantimer.stop(); + batterytimer.stop(); + matrix_key_init(false); + matrix_key_test(false); + matrix_key_end(false); + keyscantimer.start(); + batterytimer.start(); break; - case 'k': - keyscantimer.stop(); - batterytimer.stop(); - matrix_key_init(true); - matrix_key_test(true); - matrix_key_end(true); - keyscantimer.start(); - batterytimer.start(); + case 'k': + keyscantimer.stop(); + batterytimer.stop(); + matrix_key_init(true); + matrix_key_test(true); + matrix_key_end(true); + keyscantimer.start(); + batterytimer.start(); break; case 'c': - resetConfig(); - saveConfig(); + resetConfig(); + saveConfig(); break; } - } + } } \ No newline at end of file diff --git a/firmware/debug_cli.h b/firmware/debug_cli.h index 078f1486..840f9875 100644 --- a/firmware/debug_cli.h +++ b/firmware/debug_cli.h @@ -7,43 +7,40 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DEBUG_CLI_H #define DEBUG_CLI_H +#include #include #include -#include -#include "bluetooth_config.h" -#include "datastructures.h" +#include +#include #include "firmware.h" #include "firmware_config.h" +#include "bluetooth_config.h" #include "nrf52battery.h" #include "nrf52gpio.h" -#include -#include +#include "datastructures.h" typedef volatile uint32_t REG32; #define pREG32 (REG32 *) -#define DEVICE_ID_HIGH (*(pREG32(0x10000060))) -#define DEVICE_ID_LOW (*(pREG32(0x10000064))) -#define MAC_ADDRESS_HIGH (*(pREG32(0x100000a8))) -#define MAC_ADDRESS_LOW (*(pREG32(0x100000a4))) +#define DEVICE_ID_HIGH (*(pREG32 (0x10000060))) +#define DEVICE_ID_LOW (*(pREG32 (0x10000064))) +#define MAC_ADDRESS_HIGH (*(pREG32 (0x100000a8))) +#define MAC_ADDRESS_LOW (*(pREG32 (0x100000a4))) extern SoftwareTimer keyscantimer, batterytimer; extern Battery batterymonitor; @@ -59,4 +56,5 @@ void matrix_key_end(bool singlekey); void matrix_key_test(bool singlekey); void helpline(void); + #endif /* DEBUG_CLI_H */ diff --git a/firmware/firmware.h b/firmware/firmware.h index e6253e5a..c2a1fdd4 100644 --- a/firmware/firmware.h +++ b/firmware/firmware.h @@ -7,60 +7,58 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIRMWARE_H #define FIRMWARE_H #undef min #undef max -#include "BlueMicro_display.h" -#include "BlueMicro_tone.h" +#include "firmware_config.h" +#include "bluetooth_config.h" +#include "keymap.h" #include "KeyScanner.h" +#include "sleep.h" +#include "bluetooth.h" +#include "nrf52battery.h" #include "LedPwm.h" #include "LedRGB.h" -#include "bluetooth.h" -#include "bluetooth_config.h" -#include "combo_engine.h" +#include "nrf52gpio.h" #include "datastructures.h" #include "debug_cli.h" -#include "firmware_config.h" -#include "keymap.h" -#include "nrf52battery.h" -#include "nrf52gpio.h" -#include "sleep.h" #include "usb.h" +#include "BlueMicro_display.h" +#include "BlueMicro_tone.h" +#include "combo_engine.h" + -void setupConfig(void); -void loadConfig(void); -void saveConfig(void); -void resetConfig(void); -void setupMatrix(void); -void scanMatrix(void); -void sendKeyPresses(void); -void LowestPriorityloop(void); -void NormalPriorityloop(void); -void keyscantimer_callback(TimerHandle_t _handle); -void batterytimer_callback(TimerHandle_t _handle); -void RGBtimer_callback(TimerHandle_t _handle); -void addStringToQueue(const char *str); -void UpdateQueue(void); -void addKeycodeToQueue(const uint16_t keycode); -void addKeycodeToQueue(const uint16_t keycode, const uint8_t modifier); -void process_keyboard_function(uint16_t keycode); -#ifndef USER_MACRO_FUNCTION -#define USER_MACRO_FUNCTION 1 -void process_user_macros(uint16_t macroid); -#endif + void setupConfig(void); + void loadConfig(void); + void saveConfig(void); + void resetConfig(void); + void setupMatrix(void); + void scanMatrix(void); + void sendKeyPresses(void); + void LowestPriorityloop(void); + void NormalPriorityloop(void); + void keyscantimer_callback(TimerHandle_t _handle); + void batterytimer_callback(TimerHandle_t _handle); + void RGBtimer_callback(TimerHandle_t _handle); + void addStringToQueue(const char* str); + void UpdateQueue(void); + void addKeycodeToQueue(const uint16_t keycode); + void addKeycodeToQueue(const uint16_t keycode, const uint8_t modifier); + void process_keyboard_function(uint16_t keycode); + #ifndef USER_MACRO_FUNCTION + #define USER_MACRO_FUNCTION 1 + void process_user_macros(uint16_t macroid); + #endif #endif /* FIRMWARE_H */ diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 6071405f..3c970f92 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -25,80 +22,79 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE // need to add this to resolve an issue when linking. // see https://forum.arduino.cc/index.php?topic=319795.0 namespace std { -void __throw_length_error(char const *) {} -} // namespace std + void __throw_length_error(char const*) { + } +} -namespace std { -void __throw_bad_alloc() { - while (true) - ; +namespace std +{ + void __throw_bad_alloc() { while(true); } } -} // namespace std /* About the firmware: - * + * * https://github.com/jpconstantineau/BlueMicro_BLE - * - * + * + * */ -/* Making Changes - * - * Edit the following files: - * keyboard_config.h: This file contains the Bluetooth definition as well as the Single/Left/Right configuration of your keyboard. - * hardware_config.h: This file contains the pin assignments for the keyboard and nRF52 module you use. - * keymap.cpp: This file contains your keymap. - * keymap.h: This file contains your keymap helper definitions and macros. - * - * The folder "keyboards" contains a number of example config files you can copy to get started. - */ + /* Making Changes + * + * Edit the following files: + * keyboard_config.h: This file contains the Bluetooth definition as well as the Single/Left/Right configuration of your keyboard. + * hardware_config.h: This file contains the pin assignments for the keyboard and nRF52 module you use. + * keymap.cpp: This file contains your keymap. + * keymap.h: This file contains your keymap helper definitions and macros. + * + * The folder "keyboards" contains a number of example config files you can copy to get started. + */ -/* Required Software and Libraries - * - * Follow the steps for the Adafruit NRF52 BSP - * https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/arduino-bsp-setup - * - */ + /* Required Software and Libraries + * + * Follow the steps for the Adafruit NRF52 BSP + * https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/arduino-bsp-setup + * + */ -/* Compiling and Flashing - * - * Once you have completed installing the required libraries, you should be able to compile and flash the firmware. - * - * Board Selected: - * Most nrf52832 based boards: Adafruit nRF52 Feather - * Most nrf52840 based boards: PCA10056 - * Programmer: Bootloader DFU for BlueFruit nRF52 - * - * Note that for serial DFU (Device Firmware Upgrade) you may need to manually press the "reset" button if the serial reset circuitry using the DTR line is not - * used. For PCA10056 boards, you may need to manually "double-reset" to put the board in DFU mode. - */ + /* Compiling and Flashing + * + * Once you have completed installing the required libraries, you should be able to compile and flash the firmware. + * + * Board Selected: + * Most nrf52832 based boards: Adafruit nRF52 Feather + * Most nrf52840 based boards: PCA10056 + * Programmer: Bootloader DFU for BlueFruit nRF52 + * + * Note that for serial DFU (Device Firmware Upgrade) you may need to manually press the "reset" button if the serial reset circuitry using the DTR line is not used. + * For PCA10056 boards, you may need to manually "double-reset" to put the board in DFU mode. + */ -/* Flashing the Bootloader - * - * In order to flash the bootloader and the Nordic Softdevice, you will need a j-link (SWD flasher) - * The Adafruit library uses nrfutil; which in turns calls the j-link libraries from Segger. - * Segger manufactures the genuine J-link. They also provide the j-link embedded in the Nordic nRF52832-DK. - * The cheapest Genuine Segger J-link is the J-Link EDU Mini. - * There are a number of chinese J-Link clones that may work with the j-link software your mileage may vary... - * - * Required Bootloader: Depends on board you have. - * - * Follow the instructions at Adafruit (link above) to download, install the necessary software - * - * Other SWD programmers are available but other software will need to be used to flash the bootloader to the device. - * Unless you have experience with these devices, we cannot recommend going with them if you are just starting out. - * Such device include: - * ST-Link V2 - OpenOCD - * Black Magic Probe - arm-none-eabi-gdb - * - * Refer to Joric's wiki for more information on flashing the bootloader using other tools - * https://github.com/joric/nrfmicro/wiki/Bootloader - */ + /* Flashing the Bootloader + * + * In order to flash the bootloader and the Nordic Softdevice, you will need a j-link (SWD flasher) + * The Adafruit library uses nrfutil; which in turns calls the j-link libraries from Segger. + * Segger manufactures the genuine J-link. They also provide the j-link embedded in the Nordic nRF52832-DK. + * The cheapest Genuine Segger J-link is the J-Link EDU Mini. + * There are a number of chinese J-Link clones that may work with the j-link software your mileage may vary... + * + * Required Bootloader: Depends on board you have. + * + * Follow the instructions at Adafruit (link above) to download, install the necessary software + * + * Other SWD programmers are available but other software will need to be used to flash the bootloader to the device. + * Unless you have experience with these devices, we cannot recommend going with them if you are just starting out. + * Such device include: + * ST-Link V2 - OpenOCD + * Black Magic Probe - arm-none-eabi-gdb + * + * Refer to Joric's wiki for more information on flashing the bootloader using other tools + * https://github.com/joric/nrfmicro/wiki/Bootloader + */ -/* Useful Tools - * - * http://www.keyboardtester.com/ - * https://config.qmk.fm/#/test - * http://gadzikowski.com/nkeyrollover.html - * - */ + /* Useful Tools + * + * http://www.keyboardtester.com/ + * https://config.qmk.fm/#/test + * http://gadzikowski.com/nkeyrollover.html + * + */ diff --git a/firmware/firmware_config.h b/firmware/firmware_config.h index 6fba0dc5..5ed0b163 100644 --- a/firmware/firmware_config.h +++ b/firmware/firmware_config.h @@ -7,25 +7,22 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FIRMWARE_CONFIG_H #define FIRMWARE_CONFIG_H -#include "datastructures.h" #include "hardware_variants.h" #include "keyboard_config.h" +#include "datastructures.h" // THIS FILE USES THE USER KEYBOARD DEFINITION FILES TO CONFIGURE THE REST OF THE OPTIONS // NOTE THAT OPTIONS NOT DEFINED BY THE USER WILL BE SET TO THEIR DEFAULTS IN THIS FILE @@ -37,39 +34,40 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #define BLE_HID 1 #define BLE_CENTRAL 1 #define CENTRAL_COUNT 1 -#define PERIPHERAL_COUNT 1 // 1 +#define PERIPHERAL_COUNT 1 //1 #define BLE_PERIPHERAL 0 #define DEVICE_NAME DEVICE_NAME_L // override name #elif KEYBOARD_SIDE == RIGHT #define BLE_HID 0 #define BLE_CENTRAL 0 #define CENTRAL_COUNT 0 -#define PERIPHERAL_COUNT 1 // 1 +#define PERIPHERAL_COUNT 1 //1 #define BLE_PERIPHERAL 1 #define DEVICE_NAME DEVICE_NAME_R // override name #elif KEYBOARD_SIDE == SINGLE #define BLE_HID 1 #define BLE_CENTRAL 0 #define CENTRAL_COUNT 0 -#define PERIPHERAL_COUNT 1 // 1 +#define PERIPHERAL_COUNT 1 //1 #define BLE_PERIPHERAL 0 -#ifndef DEVICE_NAME +#ifndef DEVICE_NAME #define DEVICE_NAME DEVICE_NAME_M #endif #elif KEYBOARD_SIDE == TEST -#define BLE_CENTRAL 0 /// -#define BLE_PERIPHERAL 0 /// -#define BLE_PAIRS 0 /// NOT SURE WHAT THIS ACTIVATES -#define BLE_HID 1 // 1 // -#define PERIPHERAL_COUNT 1 // 1 +#define BLE_CENTRAL 0 /// +#define BLE_PERIPHERAL 0 /// +#define BLE_PAIRS 0 /// NOT SURE WHAT THIS ACTIVATES +#define BLE_HID 1 //1 // +#define PERIPHERAL_COUNT 1 //1 #define CENTRAL_COUNT 0 -#ifndef DEVICE_NAME +#ifndef DEVICE_NAME #define DEVICE_NAME DEVICE_NAME_M #endif #endif -#ifndef DEBOUNCETIME -#define DEBOUNCETIME 3 // changing this to 1 and you will have problems with the debounce logic - repeated keys perhaps... + +#ifndef DEBOUNCETIME +#define DEBOUNCETIME 3 // changing this to 1 and you will have problems with the debounce logic - repeated keys perhaps... #endif #ifndef HIDREPORTINGINTERVAL @@ -79,6 +77,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #define LOWPRIORITYLOOPINTERVAL 128 #endif + // Battery Service definitions. #ifndef BATTERY_TYPE @@ -86,149 +85,152 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #endif #ifndef VBAT_PIN -#define VBAT_PIN 31 // make sure we have a default analog pin to do something with... +#define VBAT_PIN 31 // make sure we have a default analog pin to do something with... #endif #ifndef BATTERYINTERVAL #define BATTERYINTERVAL 30000 #endif -#define SLEEPING_DELAY 30000 // when it's not connected, 30 seconds is good. -#define SLEEPING_DELAY_CONNECTED 600000 // 2 minutes is way too fast and really ennoying. making it 10 minutes -#define SLEEP_ACTIVE 1 // 1 = it will go to sleep. 0 = sleep will not be activated. +#define SLEEPING_DELAY 30000 // when it's not connected, 30 seconds is good. +#define SLEEPING_DELAY_CONNECTED 600000 // 2 minutes is way too fast and really ennoying. making it 10 minutes +#define SLEEP_ACTIVE 1 // 1 = it will go to sleep. 0 = sleep will not be activated. -#ifndef DEFAULT_PWM_MAX_VALUE -#define DEFAULT_PWM_MAX_VALUE 0x7FFF // PWM max intensity +#ifndef DEFAULT_PWM_MAX_VALUE +#define DEFAULT_PWM_MAX_VALUE 0x7FFF // PWM max intensity #endif -#ifndef DEFAULT_PWM_VALUE -#define DEFAULT_PWM_VALUE 0x7FFF // PWM default intensity +#ifndef DEFAULT_PWM_VALUE +#define DEFAULT_PWM_VALUE 0x7FFF // PWM default intensity #endif #ifndef BACKLIGHT_LED_PIN -#define BACKLIGHT_LED_PIN 0 -#ifndef BACKLIGHT_PWM_ON -#define BACKLIGHT_PWM_ON 0 -#endif + #define BACKLIGHT_LED_PIN 0 + #ifndef BACKLIGHT_PWM_ON + #define BACKLIGHT_PWM_ON 0 + #endif #else -#ifndef BACKLIGHT_PWM_ON -#define BACKLIGHT_PWM_ON 1 -#endif + #ifndef BACKLIGHT_PWM_ON + #define BACKLIGHT_PWM_ON 1 + #endif #endif #ifndef WS2812B_LED_PIN -#define WS2812B_LED_PIN 0 -#ifndef WS2812B_LED_COUNT -#define WS2812B_LED_COUNT 0 -#endif -#ifndef WS2812B_LED_ON -#define WS2812B_LED_ON 0 -#endif -#endif - -#ifndef WS2812B_LED_ON // it would have been created if a LED_PIN did not exist -#define WS2812B_LED_ON 1 -#endif - -#ifndef WS2812B_LED_COUNT // it would have been created if a LED_PIN did not exist -#define WS2812B_LED_COUNT 1 -#endif - -#ifndef STATUS_BLE_LED_PIN // setup default value if not set -#define STATUS_BLE_LED_PIN LED_BLUE -#ifndef BLE_LED_ACTIVE // setup default value if not set -#define BLE_LED_ACTIVE 0 -#endif -#ifndef BLE_LED_POLARITY // setup default value if not set -#define BLE_LED_POLARITY 1 -#endif + #define WS2812B_LED_PIN 0 + #ifndef WS2812B_LED_COUNT + #define WS2812B_LED_COUNT 0 + #endif + #ifndef WS2812B_LED_ON + #define WS2812B_LED_ON 0 + #endif +#endif + + #ifndef WS2812B_LED_ON // it would have been created if a LED_PIN did not exist + #define WS2812B_LED_ON 1 + #endif + + #ifndef WS2812B_LED_COUNT // it would have been created if a LED_PIN did not exist + #define WS2812B_LED_COUNT 1 + #endif + + +#ifndef STATUS_BLE_LED_PIN // setup default value if not set + #define STATUS_BLE_LED_PIN LED_BLUE + #ifndef BLE_LED_ACTIVE // setup default value if not set + #define BLE_LED_ACTIVE 0 + #endif + #ifndef BLE_LED_POLARITY // setup default value if not set + #define BLE_LED_POLARITY 1 + #endif #else -#ifndef BLE_LED_ACTIVE // setup default value if not set -#define BLE_LED_ACTIVE 1 -#endif -#ifndef BLE_LED_POLARITY // setup default value if not set -#define BLE_LED_POLARITY 1 -#endif -#endif - -#ifndef STATUS_KB_LED_PIN // setup default value if not set -#define STATUS_KB_LED_PIN LED_RED -#ifndef STATUS_KB_LED_ACTIVE // setup default value if not set -#define STATUS_KB_LED_ACTIVE 0 -#endif -#ifndef STATUS_KB_LED_POLARITY // setup default value if not set -#define STATUS_KB_LED_POLARITY 1 -#endif + #ifndef BLE_LED_ACTIVE // setup default value if not set + #define BLE_LED_ACTIVE 1 + #endif + #ifndef BLE_LED_POLARITY // setup default value if not set + #define BLE_LED_POLARITY 1 + #endif +#endif + +#ifndef STATUS_KB_LED_PIN // setup default value if not set + #define STATUS_KB_LED_PIN LED_RED + #ifndef STATUS_KB_LED_ACTIVE // setup default value if not set + #define STATUS_KB_LED_ACTIVE 0 + #endif + #ifndef STATUS_KB_LED_POLARITY // setup default value if not set + #define STATUS_KB_LED_POLARITY 1 + #endif #else -#ifndef STATUS_KB_LED_ACTIVE // setup default value if not set -#define STATUS_KB_LED_ACTIVE 1 -#endif -#ifndef STATUS_KB_LED_POLARITY // setup default value if not set -#define STATUS_KB_LED_POLARITY 1 -#endif + #ifndef STATUS_KB_LED_ACTIVE // setup default value if not set + #define STATUS_KB_LED_ACTIVE 1 + #endif + #ifndef STATUS_KB_LED_POLARITY // setup default value if not set + #define STATUS_KB_LED_POLARITY 1 + #endif #endif -#define PWM_TOUCH_INTERVAL 1000 // detection time since last keypress. +#define PWM_TOUCH_INTERVAL 1000 // detection time since last keypress. #ifndef VBAT_PIN -#define VBAT_PIN (A7) + #define VBAT_PIN (A7) #endif -#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 -#ifdef ARDUINO_NRF52840_FEATHER // these settings are specific to the NRF52840_FEATHER not the NRF52840 Chip. -#define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT -#define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider +#define VBAT_MV_PER_LSB (0.73242188F) // 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 +#ifdef ARDUINO_NRF52840_FEATHER // these settings are specific to the NRF52840_FEATHER not the NRF52840 Chip. + #define VBAT_DIVIDER (0.5F) // 150K + 150K voltage divider on VBAT + #define VBAT_DIVIDER_COMP (2.0F) // Compensation factor for the VBAT divider #else -#define VBAT_DIVIDER (0.71275837F) // 2M + 0.806M voltage divider on VBAT = (2M / (0.806M + 2M)) -#define VBAT_DIVIDER_COMP (1.403F) // Compensation factor for the VBAT divider + #define VBAT_DIVIDER (0.71275837F) // 2M + 0.806M voltage divider on VBAT = (2M / (0.806M + 2M)) + #define VBAT_DIVIDER_COMP (1.403F) // Compensation factor for the VBAT divider #endif #define VDDHDIV5DIV2SCALE (6000) #define VDDHDIV5DIV2RANGE (1023) #ifdef VCC_PIN -#define VCC_ENABLE_GPIO 1 -#ifndef VCC_POLARITY_ON -#define VCC_POLARITY_ON 1 -#endif -#ifndef VCC_DEFAULT_ON -#define VCC_DEFAULT_ON 1 -#endif -#else -#define VCC_ENABLE_GPIO 0 + #define VCC_ENABLE_GPIO 1 + #ifndef VCC_POLARITY_ON + #define VCC_POLARITY_ON 1 + #endif + #ifndef VCC_DEFAULT_ON + #define VCC_DEFAULT_ON 1 + #endif + #else + #define VCC_ENABLE_GPIO 0 #endif #ifndef VCC_DEFAULT_ON -#define VCC_DEFAULT_ON 0 + #define VCC_DEFAULT_ON 0 #endif + + #ifdef CHARGER_PIN -#define VCC_ENABLE_CHARGER 1 -#ifndef CHARGER_POLARITY_ON -#define CHARGER_POLARITY_ON 1 -#endif -#else -#define VCC_ENABLE_CHARGER 0 + #define VCC_ENABLE_CHARGER 1 + #ifndef CHARGER_POLARITY_ON + #define CHARGER_POLARITY_ON 1 + #endif + #else + #define VCC_ENABLE_CHARGER 0 #endif #ifndef SERIAL_DEBUG_CLI_DEFAULT_ON -#define SERIAL_DEBUG_CLI_DEFAULT_ON 1 + #define SERIAL_DEBUG_CLI_DEFAULT_ON 1 #endif // OLED DISPLAY CONFIG #ifdef ARDUINO_NRF52_ADAFRUIT -// do nothing since the Adafruit BSP doesn't have U8g2lib included + // do nothing since the Adafruit BSP doesn't have U8g2lib included #endif #ifdef ARDUINO_NRF52_COMMUNITY -#ifdef DISPLAY_U8G2_CONSTRUCTOR -#ifdef I2C_SDA_PIN -#ifdef I2C_SCK_PIN // everything needed is defined! -#define BLUEMICRO_CONFIGURED_DISPLAY 1 -#ifndef DISPLAY_U8G2_ROTATION // check for overriding default rotation -#define DISPLAY_U8G2_ROTATION U8G2_R1 // options are here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp#rotation -#endif -#endif -#endif -#endif + #ifdef DISPLAY_U8G2_CONSTRUCTOR + #ifdef I2C_SDA_PIN + #ifdef I2C_SCK_PIN // everything needed is defined! + #define BLUEMICRO_CONFIGURED_DISPLAY 1 + #ifndef DISPLAY_U8G2_ROTATION // check for overriding default rotation + #define DISPLAY_U8G2_ROTATION U8G2_R1 // options are here: https://github.com/olikraus/u8g2/wiki/u8g2setupcpp#rotation + #endif + #endif + #endif + #endif #endif #endif /* FIRMWARE_CONFIG_H */ diff --git a/firmware/firmware_main.cpp b/firmware/firmware_main.cpp index 4ef30833..1de7fffc 100644 --- a/firmware/firmware_main.cpp +++ b/firmware/firmware_main.cpp @@ -7,30 +7,27 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /**************************************************************************************************************************/ +#include +#include #include "firmware.h" #include -#include #include -#include /**************************************************************************************************************************/ // Keyboard Matrix -byte rows[] MATRIX_ROW_PINS; // Contains the GPIO Pin Numbers defined in keyboard_config.h -byte columns[] MATRIX_COL_PINS; // Contains the GPIO Pin Numbers defined in keyboard_config.h +byte rows[] MATRIX_ROW_PINS; // Contains the GPIO Pin Numbers defined in keyboard_config.h +byte columns[] MATRIX_COL_PINS; // Contains the GPIO Pin Numbers defined in keyboard_config.h SoftwareTimer keyscantimer, batterytimer; @@ -40,30 +37,34 @@ File file(InternalFS); PersistentState keyboardconfig; DynamicState keyboardstate; -BlueMicro_tone speaker(&keyboardconfig, &keyboardstate); /// A speaker to play notes and tunes... -led_handler statusLEDs(&keyboardconfig, &keyboardstate); /// Typically a Blue LED and a Red LED +#ifdef ENABLE_AUDIO + BlueMicro_tone speaker(&keyboardconfig, &keyboardstate); /// A speaker to play notes and tunes... +#endif +led_handler statusLEDs(&keyboardconfig, &keyboardstate); /// Typically a Blue LED and a Red LED + + #ifdef BLUEMICRO_CONFIGURED_DISPLAY -BlueMicro_Display OLED(&keyboardconfig, &keyboardstate); /// Typically a Blue LED and a Red LED + BlueMicro_Display OLED(&keyboardconfig, &keyboardstate); /// Typically a Blue LED and a Red LED #endif KeyScanner keys(&keyboardconfig, &keyboardstate); Battery batterymonitor; static std::vector stringbuffer; // buffer for macros to type into... -static std::vector> reportbuffer; +static std::vector reportbuffer; /**************************************************************************************************************************/ void setupConfig() { InternalFS.begin(); loadConfig(); - keyboardstate.statusble = 0; // initialize to a known state. - keyboardstate.statuskb = 0; // initialize to a known state. + keyboardstate.statusble=0; //initialize to a known state. + keyboardstate.statuskb=0; //initialize to a known state. - keyboardstate.user1 = 0; // initialize to a known state. - keyboardstate.user2 = 0; // initialize to a known state. - keyboardstate.user3 = 0; // initialize to a known state. + keyboardstate.user1=0; //initialize to a known state. + keyboardstate.user2=0; //initialize to a known state. + keyboardstate.user3=0; //initialize to a known state. keyboardstate.helpmode = false; keyboardstate.timestamp = millis(); @@ -76,73 +77,79 @@ void setupConfig() { keyboardstate.needUnpair = false; keyboardstate.needFSReset = false; keyboardstate.save2flash = false; + } /**************************************************************************************************************************/ -void loadConfig() { +void loadConfig() +{ file.open(SETTINGS_FILE, FILE_O_READ); - if (file) { + if(file) + { file.read(&keyboardconfig, sizeof(keyboardconfig)); file.close(); - } else { + } + else + { resetConfig(); saveConfig(); } - if (keyboardconfig.version != BLUEMICRO_CONFIG_VERSION) // SETTINGS_FILE format changed. we need to reset and re-save it. - { + if (keyboardconfig.version != BLUEMICRO_CONFIG_VERSION) // SETTINGS_FILE format changed. we need to reset and re-save it. + { resetConfig(); saveConfig(); - } + } } /**************************************************************************************************************************/ -void resetConfig() { - keyboardconfig.version = BLUEMICRO_CONFIG_VERSION; - keyboardconfig.pinPWMLED = BACKLIGHT_LED_PIN; - keyboardconfig.pinRGBLED = WS2812B_LED_PIN; - keyboardconfig.pinBLELED = STATUS_BLE_LED_PIN; - keyboardconfig.pinKBLED = STATUS_KB_LED_PIN; - - keyboardconfig.enablePWMLED = BACKLIGHT_PWM_ON; - keyboardconfig.enableRGBLED = WS2812B_LED_ON; - keyboardconfig.enableBLELED = BLE_LED_ACTIVE; - keyboardconfig.enableKBLED = STATUS_KB_LED_ACTIVE; - - keyboardconfig.polarityBLELED = BLE_LED_POLARITY; - keyboardconfig.polarityKBLED = STATUS_KB_LED_POLARITY; - - keyboardconfig.enableVCCSwitch = VCC_ENABLE_GPIO; - keyboardconfig.polarityVCCSwitch = VCC_DEFAULT_ON; - - keyboardconfig.enableChargerControl = VCC_ENABLE_CHARGER; - keyboardconfig.polarityChargerControl = true; - -#ifdef BLUEMICRO_CONFIGURED_DISPLAY - keyboardconfig.enableDisplay = true; // enabled if it's compiled with one... -#else - keyboardconfig.enableDisplay = false; // disabled if it's not compiled with one... -#endif - -#ifdef SPEAKER_PIN - keyboardconfig.enableAudio = true; // enabled if it's compiled with one... -#else - keyboardconfig.enableAudio = false; // disabled if it's not compiled with one... -#endif - - keyboardconfig.enableSerial = SERIAL_DEBUG_CLI_DEFAULT_ON; - - keyboardconfig.mode = 0; - keyboardconfig.user1 = 0; - keyboardconfig.user2 = 0; - - keyboardconfig.matrixscaninterval = HIDREPORTINGINTERVAL; - keyboardconfig.batteryinterval = BATTERYINTERVAL; - keyboardconfig.keysendinterval = HIDREPORTINGINTERVAL; - keyboardconfig.lowpriorityloopinterval = LOWPRIORITYLOOPINTERVAL; - keyboardconfig.lowestpriorityloopinterval = HIDREPORTINGINTERVAL * 2; - keyboardconfig.connectionMode = CONNECTION_MODE_AUTO; +void resetConfig() +{ + keyboardconfig.version=BLUEMICRO_CONFIG_VERSION; + keyboardconfig.pinPWMLED=BACKLIGHT_LED_PIN; + keyboardconfig.pinRGBLED=WS2812B_LED_PIN; + keyboardconfig.pinBLELED=STATUS_BLE_LED_PIN; + keyboardconfig.pinKBLED=STATUS_KB_LED_PIN; + + keyboardconfig.enablePWMLED=BACKLIGHT_PWM_ON; + keyboardconfig.enableRGBLED=WS2812B_LED_ON; + keyboardconfig.enableBLELED=BLE_LED_ACTIVE; + keyboardconfig.enableKBLED=STATUS_KB_LED_ACTIVE; + + keyboardconfig.polarityBLELED=BLE_LED_POLARITY; + keyboardconfig.polarityKBLED=STATUS_KB_LED_POLARITY; + + keyboardconfig.enableVCCSwitch=VCC_ENABLE_GPIO; + keyboardconfig.polarityVCCSwitch=VCC_DEFAULT_ON; + + keyboardconfig.enableChargerControl=VCC_ENABLE_CHARGER; + keyboardconfig.polarityChargerControl=true; + + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + keyboardconfig.enableDisplay = true;// enabled if it's compiled with one... + #else + keyboardconfig.enableDisplay = false;// disabled if it's not compiled with one... + #endif + + #ifdef SPEAKER_PIN + keyboardconfig.enableAudio = true;// enabled if it's compiled with one... + #else + keyboardconfig.enableAudio = false;// disabled if it's not compiled with one... + #endif + + keyboardconfig.enableSerial = SERIAL_DEBUG_CLI_DEFAULT_ON; + + keyboardconfig.mode = 0; + keyboardconfig.user1 = 0; + keyboardconfig.user2 = 0; + + keyboardconfig.matrixscaninterval=HIDREPORTINGINTERVAL; + keyboardconfig.batteryinterval=BATTERYINTERVAL; + keyboardconfig.keysendinterval=HIDREPORTINGINTERVAL; + keyboardconfig.lowpriorityloopinterval=LOWPRIORITYLOOPINTERVAL; + keyboardconfig.lowestpriorityloopinterval = HIDREPORTINGINTERVAL*2; + keyboardconfig.connectionMode = CONNECTION_MODE_AUTO; keyboardconfig.BLEProfile = 0; keyboardconfig.BLEProfileEdiv[0] = 0xFFFF; keyboardconfig.BLEProfileEdiv[1] = 0xFFFF; @@ -150,131 +157,147 @@ void resetConfig() { strcpy(keyboardconfig.BLEProfileName[0], "unpaired"); strcpy(keyboardconfig.BLEProfileName[1], "unpaired"); strcpy(keyboardconfig.BLEProfileName[2], "unpaired"); + + } /**************************************************************************************************************************/ -void saveConfig() { +void saveConfig() +{ InternalFS.remove(SETTINGS_FILE); - if (file.open(SETTINGS_FILE, FILE_O_WRITE)) { - file.write((uint8_t *)&keyboardconfig, sizeof(keyboardconfig)); + if (file.open(SETTINGS_FILE, FILE_O_WRITE)) + { + file.write((uint8_t*)&keyboardconfig, sizeof(keyboardconfig)); file.close(); } } + + + /**************************************************************************************************************************/ // put your setup code here, to run once: /**************************************************************************************************************************/ // cppcheck-suppress unusedFunction void setup() { - setupGpio(); // checks that NFC functions on GPIOs are disabled. + setupGpio(); // checks that NFC functions on GPIOs are disabled. setupWDT(); -#ifdef BLUEMICRO_CONFIGURED_DISPLAY - OLED.begin(); -#endif - + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + OLED.begin(); + #endif + setupConfig(); +#ifdef ENABLE_AUDIO + #ifdef SPEAKER_PIN + speaker.setSpeakerPin(SPEAKER_PIN); + #endif + #endif -#ifdef SPEAKER_PIN - speaker.setSpeakerPin(SPEAKER_PIN); -#endif - - if (keyboardconfig.enableSerial) { - Serial.begin(115200); - Serial.println(" ____ _ __ __ _ ____ _ _____ "); - Serial.println("| __ )| |_ _ ___| \\/ (_) ___ _ __ ___ | __ )| | | ____|"); - Serial.println("| _ \\| | | | |/ _ \\ |\\/| | |/ __| '__/ _ \\ | _ \\| | | _| "); - Serial.println("| |_) | | |_| | __/ | | | | (__| | | (_) | | |_) | |___| |___ "); - Serial.println("|____/|_|\\__,_|\\___|_| |_|_|\\___|_| \\___/___|____/|_____|_____|"); - Serial.println(" |_____| "); - Serial.println(""); - Serial.println("Type 'h' to get a list of commands with descriptions"); + if (keyboardconfig.enableSerial) + { + Serial.begin(115200); + Serial.println(" ____ _ __ __ _ ____ _ _____ "); + Serial.println("| __ )| |_ _ ___| \\/ (_) ___ _ __ ___ | __ )| | | ____|"); + Serial.println("| _ \\| | | | |/ _ \\ |\\/| | |/ __| '__/ _ \\ | _ \\| | | _| "); + Serial.println("| |_) | | |_| | __/ | | | | (__| | | (_) | | |_) | |___| |___ "); + Serial.println("|____/|_|\\__,_|\\___|_| |_|_|\\___|_| \\___/___|____/|_____|_____|"); + Serial.println(" |_____| "); + Serial.println(""); + Serial.println("Type 'h' to get a list of commands with descriptions"); } + + LOG_LV1("BLEMIC","Starting %s" ,DEVICE_NAME); - LOG_LV1("BLEMIC", "Starting %s", DEVICE_NAME); - - if (keyboardconfig.enableVCCSwitch) { + if(keyboardconfig.enableVCCSwitch) + { switchVCC(keyboardconfig.polarityVCCSwitch); // turn on VCC when starting up if needed. } - if (keyboardconfig.enableChargerControl) { + if(keyboardconfig.enableChargerControl) + { switchCharger(keyboardconfig.polarityChargerControl); // turn on Charger when starting up if needed. } keyscantimer.begin(keyboardconfig.matrixscaninterval, keyscantimer_callback); - // batterytimer.begin(keyboardconfig.batteryinterval, batterytimer_callback); + //batterytimer.begin(keyboardconfig.batteryinterval, batterytimer_callback); bt_setup(keyboardconfig.BLEProfile); usb_setup(); // does nothing for 832 - see usb.cpp // Set up keyboard matrix and start advertising setupKeymap(); // this is where we can change the callback for our LEDs... setupMatrix(); - bt_startAdv(); + bt_startAdv(); keyscantimer.start(); - // batterytimer.start(); + //batterytimer.start(); stringbuffer.clear(); reportbuffer.clear(); - if (keyboardconfig.enablePWMLED) { - setupPWM( - keyboardconfig.pinPWMLED); // PWM contributes 500uA to the bottom line on a 840 device. see - // https://devzone.nordicsemi.com/f/nordic-q-a/40912/pwm-power-consumption-nrf52840 (there is no electrical specification) + if(keyboardconfig.enablePWMLED) + { + setupPWM(keyboardconfig.pinPWMLED); //PWM contributes 500uA to the bottom line on a 840 device. see https://devzone.nordicsemi.com/f/nordic-q-a/40912/pwm-power-consumption-nrf52840 (there is no electrical specification) } - if (keyboardconfig.enableRGBLED) { - setupRGB(); // keyboardconfig.pinRGBLED + if(keyboardconfig.enableRGBLED) + { + setupRGB();//keyboardconfig.pinRGBLED } statusLEDs.enable(); - statusLEDs.hello(); // blinks Status LEDs a couple as last step of setup. + statusLEDs.hello(); // blinks Status LEDs a couple as last step of setup. Scheduler.startLoop(LowestPriorityloop, 1024, TASK_PRIO_LOWEST, "l1"); // this loop contains LED,RGB & PWM and Display updates. -// Scheduler.startLoop(NormalPriorityloop, 1024, TASK_PRIO_NORMAL, "n1"); // this has nothing in it... -#ifdef BLUEMICRO_CONFIGURED_DISPLAY - if (keyboardconfig.enableDisplay) { - OLED.changeUpdateMode(DISPLAY_UPDATE_STATUS); - } else { - OLED.sleep(); - } -#endif - + //Scheduler.startLoop(NormalPriorityloop, 1024, TASK_PRIO_NORMAL, "n1"); // this has nothing in it... + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + if(keyboardconfig.enableDisplay) + { + OLED.changeUpdateMode(DISPLAY_UPDATE_STATUS); + } + else + { + OLED.sleep(); + } + #endif +#ifdef ENABLE_AUDIO speaker.playTone(TONE_STARTUP); speaker.playTone(TONE_BLE_PROFILE); + #endif + }; /**************************************************************************************************************************/ // /**************************************************************************************************************************/ void setupMatrix(void) { - // inits all the columns as INPUT - for (const auto &column : columns) { - LOG_LV2("BLEMIC", "Setting to INPUT Column: %i", column); - pinMode(column, INPUT); - } + //inits all the columns as INPUT + for (const auto& column : columns) { + LOG_LV2("BLEMIC","Setting to INPUT Column: %i" ,column); + pinMode(column, INPUT); + } - // inits all the rows as INPUT_PULLUP - for (const auto &row : rows) { - LOG_LV2("BLEMIC", "Setting to INPUT_PULLUP Row: %i", row); - pinMode(row, INPUT_PULLUP); - } + //inits all the rows as INPUT_PULLUP + for (const auto& row : rows) { + LOG_LV2("BLEMIC","Setting to INPUT_PULLUP Row: %i" ,row); + pinMode(row, INPUT_PULLUP); + } }; - /**************************************************************************************************************************/ - // Keyboard Scanning - /**************************************************************************************************************************/ +/**************************************************************************************************************************/ +// Keyboard Scanning +/**************************************************************************************************************************/ #if DIODE_DIRECTION == COL2ROW -#define writeRow(r) digitalWrite(r, LOW) +#define writeRow(r) digitalWrite(r,LOW) #define modeCol(c) pinMode(c, INPUT_PULLUP) #ifdef NRF52840_XXAA -#define gpioIn (((uint64_t)(NRF_P1->IN) ^ 0xffffffff) << 32) | (NRF_P0->IN) ^ 0xffffffff +#define gpioIn (((uint64_t)(NRF_P1->IN)^0xffffffff)<<32)|(NRF_P0->IN)^0xffffffff #else -#define gpioIn (NRF_GPIO->IN) ^ 0xffffffff +#define gpioIn (NRF_GPIO->IN)^0xffffffff #endif #else -#define writeRow(r) digitalWrite(r, HIGH) +#define writeRow(r) digitalWrite(r,HIGH) #define modeCol(c) pinMode(c, INPUT_PULLDOWN) #ifdef NRF52840_XXAA -#define gpioIn (((uint64_t)NRF_P1->IN) << 32) | (NRF_P0->IN) +#define gpioIn (((uint64_t)NRF_P1->IN)<<32)|(NRF_P0->IN) #else #define gpioIn NRF_GPIO->IN #endif @@ -291,107 +314,117 @@ void setupMatrix(void) { /**************************************************************************************************************************/ void scanMatrix() { - keyboardstate.timestamp = millis(); // lets call it once per scan instead of once per key in the matrix - - static PINDATATYPE pindata[MATRIX_ROWS][DEBOUNCETIME]; + keyboardstate.timestamp = millis(); // lets call it once per scan instead of once per key in the matrix + + static PINDATATYPE pindata[MATRIX_ROWS][DEBOUNCETIME]; - static uint8_t head = 0; // points us to the head of the debounce array; + static uint8_t head = 0; // points us to the head of the debounce array; - for (int i = 0; i < MATRIX_COLS; ++i) { - modeCol(columns[i]); - } + for (int i = 0; i < MATRIX_COLS; ++i){ + modeCol(columns[i]); + } - for (int j = 0; j < MATRIX_ROWS; ++j) { - // set the current row as OUPUT and LOW - PINDATATYPE pinreg = 0; + for (int j = 0; j < MATRIX_ROWS; ++j){ + // set the current row as OUPUT and LOW + PINDATATYPE pinreg = 0; - pinMode(rows[j], OUTPUT); - writeRow(rows[j]); + pinMode(rows[j], OUTPUT); + writeRow(rows[j]); - nrfx_coredep_delay_us(1); // need for the GPIO lines to settle down electrically before reading. - pindata[j][head] = gpioIn; // press is active high regardless of diode dir + nrfx_coredep_delay_us(1); // need for the GPIO lines to settle down electrically before reading. + pindata[j][head] = gpioIn; // press is active high regardless of diode dir - // debounce happens here - we want to press a button as soon as possible, and release it only when all bounce has left - for (int d = 0; d < DEBOUNCETIME; ++d) - pinreg |= pindata[j][d]; + //debounce happens here - we want to press a button as soon as possible, and release it only when all bounce has left + for (int d = 0; d < DEBOUNCETIME; ++d) + pinreg |= pindata[j][d]; + + for (int i = 0; i < MATRIX_COLS; ++i){ + int ulPin = g_ADigitalPinMap[columns[i]]; + if((pinreg>>ulPin)&1) KeyScanner::press(keyboardstate.timestamp, j, i); + else KeyScanner::release(keyboardstate.timestamp, j, i); + } - for (int i = 0; i < MATRIX_COLS; ++i) { - int ulPin = g_ADigitalPinMap[columns[i]]; - if ((pinreg >> ulPin) & 1) - KeyScanner::press(keyboardstate.timestamp, j, i); - else - KeyScanner::release(keyboardstate.timestamp, j, i); + pinMode(rows[j], INPUT); // 'disables' the row that was just scanned + } + for (int i = 0; i < MATRIX_COLS; ++i) { //Scanning done, disabling all columns + pinMode(columns[i], INPUT); } - pinMode(rows[j], INPUT); // 'disables' the row that was just scanned - } - for (int i = 0; i < MATRIX_COLS; ++i) { // Scanning done, disabling all columns - pinMode(columns[i], INPUT); - } - - head++; - if (head >= DEBOUNCETIME) - head = 0; // reset head to 0 when we reach the end of our buffer + head++; + if(head >= DEBOUNCETIME) head = 0; // reset head to 0 when we reach the end of our buffer } + /**************************************************************************************************************************/ // THIS IS THE DEFAULT process_user_macros FUNCTION WHICH IS OVERRIDEN BY USER ONE. /**************************************************************************************************************************/ -#if USER_MACRO_FUNCTION == 1 -void process_user_macros(uint16_t macroid) { - switch ((macroid)) { - case MC(KC_A): - addStringToQueue("Macro Example 1"); - break; - } -} +#if USER_MACRO_FUNCTION == 1 + void process_user_macros(uint16_t macroid) + { + switch ((macroid)) + { + case MC(KC_A): + addStringToQueue( "Macro Example 1"); + break; + } + } #endif -void UpdateQueue() { - stringbuffer.insert(stringbuffer.end(), combos.keycodebuffertosend.rbegin(), combos.keycodebuffertosend.rend()); - combos.keycodebuffertosend.clear(); +void UpdateQueue() +{ + #ifdef ENABLE_COMBOS + stringbuffer.insert(stringbuffer.end(), combos.keycodebuffertosend.rbegin(),combos.keycodebuffertosend.rend()); + combos.keycodebuffertosend.clear(); + #endif + } /**************************************************************************************************************************/ // macro string queue management /**************************************************************************************************************************/ -void addStringToQueue(const char *str) { +void addStringToQueue(const char* str) +{ auto it = stringbuffer.begin(); char ch; - while ((ch = *str++) != 0) { - uint8_t modifier = (hid_ascii_to_keycode[(uint8_t)ch][0]) ? KEYBOARD_MODIFIER_LEFTSHIFT : 0; + while( (ch = *str++) != 0 ) + { + uint8_t modifier = ( hid_ascii_to_keycode[(uint8_t)ch][0] ) ? KEYBOARD_MODIFIER_LEFTSHIFT : 0; uint8_t keycode = hid_ascii_to_keycode[(uint8_t)ch][1]; - uint16_t keyreport = MOD(modifier << 8, keycode); + uint16_t keyreport = MOD( modifier << 8 , keycode); it = stringbuffer.insert(it, keyreport); } + } /**************************************************************************************************************************/ /**************************************************************************************************************************/ -void addKeycodeToQueue(const uint16_t keycode) { +void addKeycodeToQueue(const uint16_t keycode) +{ auto it = stringbuffer.begin(); auto hidKeycode = static_cast(keycode & 0x00FF); - if (hidKeycode >= KC_A && hidKeycode <= KC_EXSEL) // only insert keycodes if they are valid keyboard codes... - { - it = stringbuffer.insert(it, keycode); + if (hidKeycode >= KC_A && hidKeycode <= KC_EXSEL) // only insert keycodes if they are valid keyboard codes... + { + it = stringbuffer.insert(it, keycode); + } } -} -void addKeycodeToQueue(const uint16_t keycode, const uint8_t modifier) { +void addKeycodeToQueue(const uint16_t keycode, const uint8_t modifier) +{ auto it = stringbuffer.begin(); auto hidKeycode = static_cast(keycode & 0x00FF); - // auto extraModifiers = static_cast((keycode & 0xFF00) >> 8); - - if (hidKeycode >= KC_A && hidKeycode <= KC_EXSEL) // only insert keycodes if they are valid keyboard codes... - { - uint16_t keyreport = MOD(modifier << 8, hidKeycode); - it = stringbuffer.insert(it, keyreport); - } -} + // auto extraModifiers = static_cast((keycode & 0xFF00) >> 8); + + if (hidKeycode >= KC_A && hidKeycode <= KC_EXSEL) // only insert keycodes if they are valid keyboard codes... + { + uint16_t keyreport = MOD( modifier << 8 , hidKeycode); + it = stringbuffer.insert(it, keyreport); + } + } /**************************************************************************************************************************/ /**************************************************************************************************************************/ -void process_keyboard_function(uint16_t keycode) { - char buffer[50]; +void process_keyboard_function(uint16_t keycode) +{ + char buffer [50]; uint8_t intval; switch (keycode) { case RESET: @@ -412,18 +445,24 @@ void process_keyboard_function(uint16_t keycode) { // Bluefruit.Central.clearBonds(); break; case DFU: + #ifdef ENABLE_AUDIO speaker.playTone(TONE_SLEEP); speaker.playAllQueuedTonesNow(); + #endif enterOTADfu(); break; case SERIAL_DFU: + #ifdef ENABLE_AUDIO speaker.playTone(TONE_SLEEP); speaker.playAllQueuedTonesNow(); + #endif enterSerialDfu(); break; case UF2_DFU: + #ifdef ENABLE_AUDIO speaker.playTone(TONE_SLEEP); speaker.playAllQueuedTonesNow(); + #endif enterUf2Dfu(); break; case HELP_MODE: @@ -663,338 +702,227 @@ void process_keyboard_function(uint16_t keycode) { addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); break; - case PRINT_INFO: - addStringToQueue("Keyboard Name : " DEVICE_NAME " "); - addKeycodeToQueue(KC_ENTER); - addStringToQueue("Keyboard Model : " DEVICE_MODEL " "); - addKeycodeToQueue(KC_ENTER); - addStringToQueue("Keyboard Mfg : " MANUFACTURER_NAME " "); - addKeycodeToQueue(KC_ENTER); - addStringToQueue("BSP Library : " ARDUINO_BSP_VERSION " "); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Bootloader : %s", getBootloaderVersion()); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Serial No : %s", getMcuUniqueID()); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Device Power : %f", DEVICE_POWER * 1.0); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - switch (keyboardconfig.connectionMode) { - case CONNECTION_MODE_AUTO: - addStringToQueue("CONNECTION_MODE_AUTO"); + case PRINT_INFO: + addStringToQueue("Keyboard Name : " DEVICE_NAME " "); addKeycodeToQueue(KC_ENTER); + addStringToQueue("Keyboard Model : " DEVICE_MODEL " "); addKeycodeToQueue(KC_ENTER); + addStringToQueue("Keyboard Mfg : " MANUFACTURER_NAME " "); addKeycodeToQueue(KC_ENTER); + addStringToQueue("BSP Library : " ARDUINO_BSP_VERSION " "); addKeycodeToQueue(KC_ENTER); + sprintf(buffer,"Bootloader : %s", getBootloaderVersion()); + addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); - break; - case CONNECTION_MODE_USB_ONLY: - addStringToQueue("CONNECTION_MODE_USB_ONLY"); + sprintf(buffer,"Serial No : %s", getMcuUniqueID()); + addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); - break; - case CONNECTION_MODE_BLE_ONLY: - addStringToQueue("CONNECTION_MODE_BLE_ONLY"); + sprintf(buffer,"Device Power : %f", DEVICE_POWER*1.0); + addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); + switch (keyboardconfig.connectionMode) + { + case CONNECTION_MODE_AUTO: + addStringToQueue("CONNECTION_MODE_AUTO"); addKeycodeToQueue(KC_ENTER); + break; + case CONNECTION_MODE_USB_ONLY: + addStringToQueue("CONNECTION_MODE_USB_ONLY"); addKeycodeToQueue(KC_ENTER); + break; + case CONNECTION_MODE_BLE_ONLY: + addStringToQueue("CONNECTION_MODE_BLE_ONLY"); addKeycodeToQueue(KC_ENTER); + break; + } + switch (keyboardstate.connectionState) + { + case CONNECTION_USB: + addStringToQueue("CONNECTION_USB"); addKeycodeToQueue(KC_ENTER); + break; + + case CONNECTION_BT: + addStringToQueue("CONNECTION_BLE"); addKeycodeToQueue(KC_ENTER); + break; + + case CONNECTION_NONE: + addStringToQueue("CONNECTION_NONE"); addKeycodeToQueue(KC_ENTER); + break; + } + break; + case PRINT_BLE: + addStringToQueue("Keyboard Name: " DEVICE_NAME " "); addKeycodeToQueue(KC_ENTER); + sprintf(buffer,"Device Power : %i", DEVICE_POWER); addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); + sprintf(buffer,"Filter RSSI : %i", FILTER_RSSI_BELOW_STRENGTH); addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); + addStringToQueue("Type\t RSSI\t name"); addKeycodeToQueue(KC_ENTER); + sprintf(buffer,"cent\t %i\t %s",keyboardstate.rssi_cent, keyboardstate.peer_name_cent);addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); + sprintf(buffer,"prph\t %i\t %s",keyboardstate.rssi_prph, keyboardstate.peer_name_prph);addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); + sprintf(buffer,"cccd\t %i\t %s",keyboardstate.rssi_cccd, keyboardstate.peer_name_cccd);addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); + sprintf(buffer, "Profile 1: %s", keyboardconfig.BLEProfileName[0]); + addStringToQueue(buffer); + if (keyboardconfig.BLEProfile == 0) addStringToQueue(" (active)"); addKeycodeToQueue(KC_ENTER); - break; - } - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - addStringToQueue("CONNECTION_USB"); + sprintf(buffer, "Profile 2: %s", keyboardconfig.BLEProfileName[1]); + addStringToQueue(buffer); + if (keyboardconfig.BLEProfile == 1) addStringToQueue(" (active)"); addKeycodeToQueue(KC_ENTER); - break; - - case CONNECTION_BT: - addStringToQueue("CONNECTION_BLE"); + sprintf(buffer, "Profile 3: %s", keyboardconfig.BLEProfileName[2]); + addStringToQueue(buffer); + if (keyboardconfig.BLEProfile == 2) addStringToQueue(" (active)"); + addKeycodeToQueue(KC_ENTER); + addKeycodeToQueue(KC_ENTER); + ble_gap_addr_t gap_addr; + gap_addr = bt_getMACAddr(); + sprintf(buffer, "BT MAC Addr: %02X:%02X:%02X:%02X:%02X:%02X", gap_addr.addr[5], gap_addr.addr[4], gap_addr.addr[3], gap_addr.addr[2], gap_addr.addr[1], gap_addr.addr[0]); + addStringToQueue(buffer); addKeycodeToQueue(KC_ENTER); - break; - - case CONNECTION_NONE: - addStringToQueue("CONNECTION_NONE"); addKeycodeToQueue(KC_ENTER); break; - } - break; - case PRINT_BLE: - addStringToQueue("Keyboard Name: " DEVICE_NAME " "); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Device Power : %i", DEVICE_POWER); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Filter RSSI : %i", FILTER_RSSI_BELOW_STRENGTH); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - addStringToQueue("Type\t RSSI\t name"); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "cent\t %i\t %s", keyboardstate.rssi_cent, keyboardstate.peer_name_cent); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "prph\t %i\t %s", keyboardstate.rssi_prph, keyboardstate.peer_name_prph); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "cccd\t %i\t %s", keyboardstate.rssi_cccd, keyboardstate.peer_name_cccd); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Profile 1: %s", keyboardconfig.BLEProfileName[0]); - addStringToQueue(buffer); - if (keyboardconfig.BLEProfile == 0) - addStringToQueue(" (active)"); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Profile 2: %s", keyboardconfig.BLEProfileName[1]); - addStringToQueue(buffer); - if (keyboardconfig.BLEProfile == 1) - addStringToQueue(" (active)"); - addKeycodeToQueue(KC_ENTER); - sprintf(buffer, "Profile 3: %s", keyboardconfig.BLEProfileName[2]); - addStringToQueue(buffer); - if (keyboardconfig.BLEProfile == 2) - addStringToQueue(" (active)"); - addKeycodeToQueue(KC_ENTER); - addKeycodeToQueue(KC_ENTER); - ble_gap_addr_t gap_addr; - gap_addr = bt_getMACAddr(); - sprintf(buffer, "BT MAC Addr: %02X:%02X:%02X:%02X:%02X:%02X", gap_addr.addr[5], gap_addr.addr[4], gap_addr.addr[3], gap_addr.addr[2], gap_addr.addr[1], - gap_addr.addr[0]); - addStringToQueue(buffer); - addKeycodeToQueue(KC_ENTER); - addKeycodeToQueue(KC_ENTER); - break; - case PRINT_HELP: - break; - case SLEEP_NOW: - if (keyboardstate.connectionState != CONNECTION_USB) - sleepNow(); + case PRINT_HELP: + break; + case SLEEP_NOW: + if (keyboardstate.connectionState != CONNECTION_USB) sleepNow(); break; - case WIN_A_GRAVE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_4) break; // Alt 0224 a grave - case WIN_A_ACUTE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_5) break; // Alt 0225 a acute - case WIN_A_CIRCU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_6) break; // Alt 0226 a circumflex - case WIN_A_TILDE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_7) break; // Alt 0227 a tilde - case WIN_A_UMLAU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_8) break; // Alt 0228 a umlaut - - case WIN_A_GRAVE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_2) break; // Alt 0192 A grave - case WIN_A_ACUTE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_3) break; // Alt 0193 A acute - case WIN_A_CIRCU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_4) break; // Alt 0194 A circumflex - case WIN_A_TILDE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_5) break; // Alt 0195 A tilde - case WIN_A_UMLAU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_6) break; // Alt 0196 A umlaut - - case WIN_C_CEDIL: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_1) break; // Alt 0231 c cedilla - case WIN_C_CEDIL_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_9) break; // Alt 0199 C cedilla - - case WIN_E_GRAVE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_2) break; - case WIN_E_ACUTE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_3) break; - case WIN_E_CIRCU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_4) break; - case WIN_E_UMLAU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_5) break; - - case WIN_I_GRAVE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_6) break; // Alt 0236 i grave - case WIN_I_ACUTE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_7) break; // Alt 0237 i acute - case WIN_I_CIRCU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_8) break; // Alt 0238 i circumflex - case WIN_I_UMLAU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_9) break; // Alt 0239 i umlaut - - case WIN_I_GRAVE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_4) break; // Alt 0204 I grave - case WIN_I_ACUTE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_5) break; // Alt 0205 I acute - case WIN_I_CIRCU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_6) break; // Alt 0206 I circumflex - case WIN_I_UMLAU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_7) break; // Alt 0207 I umlaut - - case WIN_N_TILDE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_6, KC_KP_4) break; // Alt 164 n tilde - case WIN_N_TILDE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_6, KC_KP_5) break; // Alt 165 N tilde - - case WIN_O_GRAVE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_2) break; // Alt 0242 o grave - case WIN_O_ACUTE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_3) break; // Alt 0243 o acute - case WIN_O_CIRCU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_4) break; // Alt 0244 o circumflex - case WIN_O_TILDE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_5) break; // Alt 0245 o tilde - case WIN_O_UMLAU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_6) break; // Alt 0246 o umlaut - - case WIN_O_GRAVE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_0) break; // Alt 0210 O grave - case WIN_O_ACUTE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_1) break; // Alt 0211 O acute - case WIN_O_CIRCU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_2) break; // Alt 0212 O circumflex - case WIN_O_TILDE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_3) break; // Alt 0213 O tilde - case WIN_O_UMLAU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_4) break; // Alt 0214 O umlaut - - case WIN_S_CARON: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_5, KC_KP_4) break; // Alt 0154 s caron - case WIN_S_CARON_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_3, KC_KP_8) break; // Alt 0138 S caron - - case WIN_U_GRAVE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_9) break; // Alt 0249 u grave - case WIN_U_ACUTE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_0) break; // Alt 0250 u acute - case WIN_U_CIRCU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_1) break; // Alt 0251 u circumflex - case WIN_U_UMLAU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_2) break; // Alt 0252 u umlaut - - case WIN_U_GRAVE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_1) break; // Alt 0217 U grave - case WIN_U_ACUTE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_8) break; // Alt 0218 U acute - case WIN_U_CIRCU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_9) break; // Alt 0219 U circumflex - case WIN_U_UMLAU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_0) break; // Alt 0220 U umlaut - - case WIN_Y_ACUTE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_3) break; // Alt 0253 y acute - case WIN_Y_UMLAU: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_5) break; // Alt 0255 y umlaut - - case WIN_Y_ACUTE_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_1) break; // Alt 0221 Y tilde - case WIN_Y_UMLAU_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_5, KC_KP_9) break; // Alt 0159 Y umlaut - - case WIN_Z_CARON: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_5, KC_KP_4) break; // Alt 0154 z caron - case WIN_Z_CARON_CAP: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_3, KC_KP_8) break; // Alt 0138 Z caron - - case SYM_DEGREE: - EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_7, KC_KP_6) break; // Alt 0176 degree symbol - - case BLEPROFILE_1: - // if (keyboardstate.connectionState != CONNECTION_USB) // reseting/rebooting KB when BLE Profile switching on USB would be ennoying... - { -#ifdef ARDUINO_NRF52_COMMUNITY - keyboardconfig.BLEProfile = 0; - keyboardstate.save2flash = true; - keyboardstate.needReset = true; -#endif -#ifdef ARDUINO_NRF52_ADAFRUIT - ; // do nothing since the Adafruit BSP doesn't support ediv. -#endif - } + case WIN_A_GRAVE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_4) break; //Alt 0224 a grave + case WIN_A_ACUTE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_5) break;//Alt 0225 a acute + case WIN_A_CIRCU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_6) break; //Alt 0226 a circumflex + case WIN_A_TILDE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_7) break; //Alt 0227 a tilde + case WIN_A_UMLAU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_8) break; //Alt 0228 a umlaut + + case WIN_A_GRAVE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_2) break; //Alt 0192 A grave + case WIN_A_ACUTE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_3) break; //Alt 0193 A acute + case WIN_A_CIRCU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_4) break; //Alt 0194 A circumflex + case WIN_A_TILDE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_5) break; //Alt 0195 A tilde + case WIN_A_UMLAU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_6) break; //Alt 0196 A umlaut + + case WIN_C_CEDIL: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_1) break; //Alt 0231 c cedilla + case WIN_C_CEDIL_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_9, KC_KP_9) break;//Alt 0199 C cedilla + + case WIN_E_GRAVE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_2) break; + case WIN_E_ACUTE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_3) break; + case WIN_E_CIRCU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_4) break; + case WIN_E_UMLAU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_5) break; + + case WIN_I_GRAVE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_6) break;//Alt 0236 i grave + case WIN_I_ACUTE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_7) break;//Alt 0237 i acute + case WIN_I_CIRCU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_8) break;//Alt 0238 i circumflex + case WIN_I_UMLAU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_3, KC_KP_9) break; //Alt 0239 i umlaut + + case WIN_I_GRAVE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_4) break;//Alt 0204 I grave + case WIN_I_ACUTE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_5) break; //Alt 0205 I acute + case WIN_I_CIRCU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_6) break; //Alt 0206 I circumflex + case WIN_I_UMLAU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_0, KC_KP_7) break;//Alt 0207 I umlaut + + case WIN_N_TILDE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_6, KC_KP_4) break;//Alt 164 n tilde + case WIN_N_TILDE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_6, KC_KP_5) break; //Alt 165 N tilde + + case WIN_O_GRAVE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_2) break; //Alt 0242 o grave + case WIN_O_ACUTE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_3) break; //Alt 0243 o acute + case WIN_O_CIRCU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_4) break; //Alt 0244 o circumflex + case WIN_O_TILDE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_5) break; //Alt 0245 o tilde + case WIN_O_UMLAU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_6) break; //Alt 0246 o umlaut + + case WIN_O_GRAVE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_0) break; //Alt 0210 O grave + case WIN_O_ACUTE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_1) break; //Alt 0211 O acute + case WIN_O_CIRCU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_2) break;//Alt 0212 O circumflex + case WIN_O_TILDE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_3) break; //Alt 0213 O tilde + case WIN_O_UMLAU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_4) break; //Alt 0214 O umlaut + + case WIN_S_CARON: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_5, KC_KP_4) break; //Alt 0154 s caron + case WIN_S_CARON_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_3, KC_KP_8) break; //Alt 0138 S caron + + case WIN_U_GRAVE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_4, KC_KP_9) break; //Alt 0249 u grave + case WIN_U_ACUTE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_0) break; //Alt 0250 u acute + case WIN_U_CIRCU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_1) break; //Alt 0251 u circumflex + case WIN_U_UMLAU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_2) break;//Alt 0252 u umlaut + + case WIN_U_GRAVE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_1) break; //Alt 0217 U grave + case WIN_U_ACUTE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_8) break;//Alt 0218 U acute + case WIN_U_CIRCU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_1, KC_KP_9) break;//Alt 0219 U circumflex + case WIN_U_UMLAU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_0) break; //Alt 0220 U umlaut + + case WIN_Y_ACUTE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_3) break; //Alt 0253 y acute + case WIN_Y_UMLAU: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_5, KC_KP_5) break; //Alt 0255 y umlaut + + case WIN_Y_ACUTE_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_2, KC_KP_2, KC_KP_1) break; //Alt 0221 Y tilde + case WIN_Y_UMLAU_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_5, KC_KP_9) break; //Alt 0159 Y umlaut + + case WIN_Z_CARON: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_5, KC_KP_4) break; //Alt 0154 z caron + case WIN_Z_CARON_CAP: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_3, KC_KP_8) break; //Alt 0138 Z caron + + case SYM_DEGREE: EXPAND_ALT_CODE(KC_KP_0, KC_KP_1, KC_KP_7, KC_KP_6) break; // Alt 0176 degree symbol + + case BLEPROFILE_1: + // if (keyboardstate.connectionState != CONNECTION_USB) // reseting/rebooting KB when BLE Profile switching on USB would be ennoying... + { + #ifdef ARDUINO_NRF52_COMMUNITY + keyboardconfig.BLEProfile = 0; + keyboardstate.save2flash = true; + keyboardstate.needReset = true; + #endif + #ifdef ARDUINO_NRF52_ADAFRUIT + ; // do nothing since the Adafruit BSP doesn't support ediv. + #endif + } break; - case BLEPROFILE_2: - // if (keyboardstate.connectionState != CONNECTION_USB) // reseting/rebooting KB when BLE Profile switching on USB would be ennoying... - { -#ifdef ARDUINO_NRF52_COMMUNITY - keyboardconfig.BLEProfile = 1; - keyboardstate.save2flash = true; - keyboardstate.needReset = true; -#endif -#ifdef ARDUINO_NRF52_ADAFRUIT - ; // do nothing since the Adafruit BSP doesn't support ediv. -#endif - } + case BLEPROFILE_2: + // if (keyboardstate.connectionState != CONNECTION_USB) // reseting/rebooting KB when BLE Profile switching on USB would be ennoying... + { + #ifdef ARDUINO_NRF52_COMMUNITY + keyboardconfig.BLEProfile = 1; + keyboardstate.save2flash = true; + keyboardstate.needReset = true; + #endif + #ifdef ARDUINO_NRF52_ADAFRUIT + ; // do nothing since the Adafruit BSP doesn't support ediv. + #endif + } break; - case BLEPROFILE_3: + case BLEPROFILE_3: // if (keyboardstate.connectionState != CONNECTION_USB) // reseting/rebooting KB when BLE Profile switching on USB would be ennoying... - { -#ifdef ARDUINO_NRF52_COMMUNITY - keyboardconfig.BLEProfile = 2; - keyboardstate.save2flash = true; - keyboardstate.needReset = true; -#endif -#ifdef ARDUINO_NRF52_ADAFRUIT - ; // do nothing since the Adafruit BSP doesn't support ediv. -#endif - } + { + #ifdef ARDUINO_NRF52_COMMUNITY + keyboardconfig.BLEProfile = 2; + keyboardstate.save2flash = true; + keyboardstate.needReset = true; + #endif + #ifdef ARDUINO_NRF52_ADAFRUIT + ; // do nothing since the Adafruit BSP doesn't support ediv. + #endif + } break; - case BATTERY_CALC_DEFAULT: - batterymonitor.setmvToPercentCallback(mvToPercent_default); - batterymonitor.updateBattery(); // force an update - break; - case BATTERY_CALC_TEST: - batterymonitor.setmvToPercentCallback(mvToPercent_test); - batterymonitor.updateBattery(); // force an update + case BATTERY_CALC_DEFAULT: + batterymonitor.setmvToPercentCallback(mvToPercent_default); + batterymonitor.updateBattery(); // force an update break; + case BATTERY_CALC_TEST: + batterymonitor.setmvToPercentCallback(mvToPercent_test); + batterymonitor.updateBattery(); // force an update + break; + } } /**************************************************************************************************************************/ /**************************************************************************************************************************/ -void process_user_special_keys() { - uint8_t mods = KeyScanner::currentReport[0]; - LOG_LV1("SPECIAL", "PROCESS: %i %i %i %i %i %i %i %i %i", KeyScanner::special_key, mods, KeyScanner::currentReport[1], KeyScanner::currentReport[2], - KeyScanner::currentReport[3], KeyScanner::currentReport[4], KeyScanner::currentReport[5], KeyScanner::currentReport[6], KeyScanner::bufferposition); - switch (KeyScanner::special_key) { - case KS(KC_ESC): - switch (mods) { - case 0: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_ESC; - KeyScanner::reportChanged = true; - break; - case BIT_LCTRL: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; - break; - case BIT_LSHIFT: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = BIT_LSHIFT; - break; - case BIT_LALT: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; - break; - case BIT_LGUI: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; - break; - case BIT_RCTRL: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; - break; - case BIT_RSHIFT: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; - break; - case BIT_RALT: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; +void process_user_special_keys() +{ + uint8_t mods = KeyScanner::currentReport.modifier ; + LOG_LV1("SPECIAL","PROCESS: %i %i %i %i %i %i %i %i %i" ,KeyScanner::special_key,mods, KeyScanner::currentReport.keycode[0],KeyScanner::currentReport.keycode[1],KeyScanner::currentReport.keycode[2], KeyScanner::currentReport.keycode[3],KeyScanner::currentReport.keycode[4], KeyScanner::currentReport.keycode[5],KeyScanner::bufferposition ); + switch(KeyScanner::special_key) + { + case KS(KC_ESC): + switch (mods) + { + case 0: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_ESC; KeyScanner::reportChanged = true; break; + case BIT_LCTRL: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + case BIT_LSHIFT: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = BIT_LSHIFT; break; + case BIT_LALT: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + case BIT_LGUI: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + case BIT_RCTRL: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + case BIT_RSHIFT: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + case BIT_RALT: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + case BIT_RGUI: KeyScanner::currentReport.keycode[KeyScanner::bufferposition] = KC_GRAVE; KeyScanner::reportChanged = true; KeyScanner::currentReport.modifier = 0; break; + } break; - case BIT_RGUI: - KeyScanner::currentReport[KeyScanner::bufferposition] = KC_GRAVE; - KeyScanner::reportChanged = true; - KeyScanner::currentReport[0] = 0; + default: break; - } - break; - default: - break; } } @@ -1003,135 +931,126 @@ void process_user_special_keys() { /**************************************************************************************************************************/ void sendKeyPresses() { - KeyScanner::getReport(); // get state data - Data is in KeyScanner::currentReport + KeyScanner::getReport(); // get state data - Data is in KeyScanner::currentReport - if (KeyScanner::special_key > 0) { - process_user_special_keys(); - KeyScanner::special_key = 0; + if (KeyScanner::special_key > 0){ + process_user_special_keys(); + KeyScanner::special_key = 0; } - if (KeyScanner::macro > 0) { - process_user_macros(KeyScanner::macro); - KeyScanner::macro = 0; - } + if (KeyScanner::macro > 0){ + process_user_macros(KeyScanner::macro); + KeyScanner::macro = 0; + + } UpdateQueue(); if (!stringbuffer.empty()) // if the macro buffer isn't empty, send the first character of the buffer... which is located at the back of the queue - { - std::array reportarray = {0, 0, 0, 0, 0, 0, 0, 0}; + { + HIDKeyboard reportarray = {0, {0, 0 ,0, 0, 0, 0}, 0}; uint16_t keyreport = stringbuffer.back(); stringbuffer.pop_back(); - - reportarray[0] = static_cast((keyreport & 0xFF00) >> 8); // mods - reportarray[1] = static_cast(keyreport & 0x00FF); + + reportarray.modifier = static_cast((keyreport & 0xFF00) >> 8);// mods + reportarray.keycode[0] = static_cast(keyreport & 0x00FF); auto buffer_iterator = reportbuffer.begin(); buffer_iterator = reportbuffer.insert(buffer_iterator, reportarray); - uint16_t lookahead_keyreport = stringbuffer.back(); - if (lookahead_keyreport == keyreport) // if the next key is the same, make sure to send a key release before sending it again... but keep the mods. - { - reportarray[0] = static_cast((keyreport & 0xFF00) >> 8); // mods; - reportarray[1] = 0; - buffer_iterator = reportbuffer.begin(); - buffer_iterator = reportbuffer.insert(buffer_iterator, reportarray); - } - } + uint16_t lookahead_keyreport = stringbuffer.back(); + if (lookahead_keyreport == keyreport) // if the next key is the same, make sure to send a key release before sending it again... but keep the mods. + { + reportarray.modifier = static_cast((keyreport & 0xFF00) >> 8);// mods; + reportarray.keycode[0] = 0; + buffer_iterator = reportbuffer.begin(); + buffer_iterator = reportbuffer.insert(buffer_iterator, reportarray); + } + } + + if (!reportbuffer.empty()) // if the report buffer isn't empty, send the first character of the buffer... which is located at the end of the queue - { - std::array reportarray = reportbuffer.back(); + { + HIDKeyboard reportarray = reportbuffer.back(); reportbuffer.pop_back(); - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - usb_sendKeys(reportarray); - delay(keyboardconfig.keysendinterval * 2); - break; - case CONNECTION_BT: - bt_sendKeys(reportarray); - delay(keyboardconfig.keysendinterval * 2); - break; - case CONNECTION_NONE: // save the report for when we reconnect - auto it = reportbuffer.end(); - it = reportbuffer.insert(it, reportarray); - break; + switch (keyboardstate.connectionState) + { + case CONNECTION_USB: usb_sendKeys(reportarray); delay(keyboardconfig.keysendinterval*2); break; + case CONNECTION_BT: bt_sendKeys(reportarray); delay(keyboardconfig.keysendinterval*2); break; + case CONNECTION_NONE: // save the report for when we reconnect + auto it = reportbuffer.end(); + it = reportbuffer.insert(it, reportarray); + break; } - + if (reportbuffer.empty()) // make sure to send an empty report when done... + { + HIDKeyboard emptyReport = {0, {0, 0 ,0, 0, 0, 0}, 0}; + switch (keyboardstate.connectionState) + { + case CONNECTION_USB: usb_sendKeys(emptyReport); delay(keyboardconfig.keysendinterval*2); break; + case CONNECTION_BT: bt_sendKeys(emptyReport); delay(keyboardconfig.keysendinterval*2); break; + case CONNECTION_NONE: // save the report for when we reconnect + auto it = reportbuffer.end(); + it = reportbuffer.insert(it, emptyReport); + break; + } + } + // KeyScanner::processingmacros=0; + } + else if ((KeyScanner::reportChanged)) //any new key presses anywhere? + { + switch (keyboardstate.connectionState) { - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - usb_sendKeys({0, 0, 0, 0, 0, 0, 0, 0}); - delay(keyboardconfig.keysendinterval * 2); - break; - case CONNECTION_BT: - bt_sendKeys({0, 0, 0, 0, 0, 0, 0, 0}); - delay(keyboardconfig.keysendinterval * 2); - break; + case CONNECTION_USB: usb_sendKeys(KeyScanner::currentReport); break; + case CONNECTION_BT: bt_sendKeys(KeyScanner::currentReport); break; case CONNECTION_NONE: // save the report for when we reconnect - auto it = reportbuffer.end(); - it = reportbuffer.insert(it, {0, 0, 0, 0, 0, 0, 0, 0}); - break; - } + auto it = reportbuffer.begin(); + it = reportbuffer.insert(it, KeyScanner::currentReport); + break; } - // KeyScanner::processingmacros=0; - } else if ((KeyScanner::reportChanged)) // any new key presses anywhere? + LOG_LV1("MXSCAN","SEND: %i %i %i %i %i %i %i %i %i " ,keyboardstate.timestamp,KeyScanner::currentReport.modifier, KeyScanner::currentReport.keycode[0],KeyScanner::currentReport.keycode[1],KeyScanner::currentReport.keycode[2], KeyScanner::currentReport.keycode[3],KeyScanner::currentReport.keycode[4], KeyScanner::currentReport.keycode[5],KeyScanner::currentReport.layer); + } else if (KeyScanner::specialfunction > 0) { - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - usb_sendKeys(KeyScanner::currentReport); - break; - case CONNECTION_BT: - bt_sendKeys(KeyScanner::currentReport); - break; - case CONNECTION_NONE: // save the report for when we reconnect - auto it = reportbuffer.begin(); - it = reportbuffer.insert(it, {KeyScanner::currentReport[0], KeyScanner::currentReport[1], KeyScanner::currentReport[2], KeyScanner::currentReport[3], - KeyScanner::currentReport[4], KeyScanner::currentReport[5], KeyScanner::currentReport[6], KeyScanner::currentReport[7]}); - break; - } - LOG_LV1("MXSCAN", "SEND: %i %i %i %i %i %i %i %i %i ", keyboardstate.timestamp, KeyScanner::currentReport[0], KeyScanner::currentReport[1], - KeyScanner::currentReport[2], KeyScanner::currentReport[3], KeyScanner::currentReport[4], KeyScanner::currentReport[5], - KeyScanner::currentReport[6], KeyScanner::currentReport[7]); - } else if (KeyScanner::specialfunction > 0) { process_keyboard_function(KeyScanner::specialfunction); - KeyScanner::specialfunction = 0; - } else if (KeyScanner::consumer > 0) { - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - usb_sendMediaKey(KeyScanner::consumer); - break; - case CONNECTION_BT: - bt_sendMediaKey(KeyScanner::consumer); - break; - case CONNECTION_NONE: + KeyScanner::specialfunction = 0; + } else if (KeyScanner::consumer > 0) + { + switch (keyboardstate.connectionState) + { + case CONNECTION_USB: usb_sendMediaKey(KeyScanner::consumer); break; + case CONNECTION_BT: bt_sendMediaKey(KeyScanner::consumer); break; + case CONNECTION_NONE: + #ifdef ENABLE_AUDIO speaker.playTone(TONE_BLE_DISCONNECT); - break; // we have lost a report! + #endif + break; // we have lost a report! } - KeyScanner::consumer = 0; - } else if (KeyScanner::mouse > 0) { - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - usb_sendMouseKey(KeyScanner::mouse); - break; - case CONNECTION_BT: - bt_sendMouseKey(KeyScanner::mouse); - break; - case CONNECTION_NONE: - speaker.playTone(TONE_BLE_DISCONNECT); + KeyScanner::consumer = 0; + } else if (KeyScanner::mouse > 0) + { + switch (keyboardstate.connectionState) + { + case CONNECTION_USB: usb_sendMouseKey(KeyScanner::mouse); break; + case CONNECTION_BT: bt_sendMouseKey(KeyScanner::mouse); break; + case CONNECTION_NONE: + #ifdef ENABLE_AUDIO + speaker.playTone(TONE_BLE_DISCONNECT); + #endif break; // we have lost a report! } - KeyScanner::mouse = 0; - } - -#if BLE_PERIPHERAL == 1 | BLE_CENTRAL == 1 /**************************************************/ - if (KeyScanner::layerChanged || (keyboardstate.timestamp - keyboardstate.lastupdatetime > 1000)) // layer comms - { - keyboardstate.lastupdatetime = keyboardstate.timestamp; - sendlayer(KeyScanner::localLayer); - LOG_LV1("MXSCAN", "Layer %i %i", keyboardstate.timestamp, KeyScanner::localLayer); - KeyScanner::layerChanged = false; // mark layer as "not changed" since last update + KeyScanner::mouse = 0; } -#endif /**************************************************/ + + + #if BLE_PERIPHERAL ==1 | BLE_CENTRAL ==1 /**************************************************/ + if(KeyScanner::layerChanged || (keyboardstate.timestamp-keyboardstate.lastupdatetime > 1000)) //layer comms + { + keyboardstate.lastupdatetime = keyboardstate.timestamp; + sendlayer(KeyScanner::localLayer); + LOG_LV1("MXSCAN","Layer %i %i" ,keyboardstate.timestamp,KeyScanner::localLayer); + KeyScanner::layerChanged = false; // mark layer as "not changed" since last update + } + #endif /**************************************************/ } // keyscantimer is being called instead @@ -1141,44 +1060,47 @@ void keyscantimer_callback(TimerHandle_t _handle) { // since timers are repeated non stop, we dont want the duration of code running within the timer to vary and potentially // go longer than the interval time. -#if MATRIX_SCAN == 1 - scanMatrix(); -#endif -#if SEND_KEYS == 1 - sendKeyPresses(); -#endif - keyboardstate.lastuseractiontime = max(KeyScanner::getLastPressed(), keyboardstate.lastuseractiontime); // use the latest time to check for sleep... - unsigned long timesincelastkeypress = keyboardstate.timestamp - keyboardstate.lastuseractiontime; + #if MATRIX_SCAN == 1 + scanMatrix(); + #endif + #if SEND_KEYS == 1 + sendKeyPresses(); + #endif + keyboardstate.lastuseractiontime = max(KeyScanner::getLastPressed(),keyboardstate.lastuseractiontime); // use the latest time to check for sleep... + unsigned long timesincelastkeypress = keyboardstate.timestamp - keyboardstate.lastuseractiontime; + + #if SLEEP_ACTIVE == 1 + switch (keyboardstate.connectionState) + { + case CONNECTION_USB: + // never sleep in this case + break; -#if SLEEP_ACTIVE == 1 - switch (keyboardstate.connectionState) { - case CONNECTION_USB: - // never sleep in this case - break; + case CONNECTION_BT: + gotoSleep(timesincelastkeypress, true); + break; - case CONNECTION_BT: - gotoSleep(timesincelastkeypress, true); - break; + case CONNECTION_NONE: + gotoSleep(timesincelastkeypress, false); + break; + } + #endif - case CONNECTION_NONE: - gotoSleep(timesincelastkeypress, false); - break; - } -#endif + #if BLE_CENTRAL == 1 // this is for the master half... + if ((timesincelastkeypress<10)&&(!Bluefruit.Central.connected()&&(!Bluefruit.Scanner.isRunning()))) + { + Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after 0 seconds (); + } + #endif -#if BLE_CENTRAL == 1 // this is for the master half... - if ((timesincelastkeypress < 10) && (!Bluefruit.Central.connected() && (!Bluefruit.Scanner.isRunning()))) { - Bluefruit.Scanner.start(0); // 0 = Don't stop scanning after 0 seconds (); - } -#endif } //********************************************************************************************// //* Battery Monitoring Task - runs infrequently *// //********************************************************************************************// // TODO: move to lower priority loop. updating battery infomation isnt critical // timers have NORMAL priorities (HIGHEST>HIGH>NORMAL>LOW>LOWEST) -// void batterytimer_callback(TimerHandle_t _handle) -//{ +//void batterytimer_callback(TimerHandle_t _handle) +//{ // batterymonitor.updateBattery(); //} @@ -1186,7 +1108,7 @@ void keyscantimer_callback(TimerHandle_t _handle) { //* Loop to send keypresses - moved to loop instead of timer due to delay() in processing macros *// //********************************************************************************************// // this loop has NORMAL priority(HIGHEST>HIGH>NORMAL>LOW>LOWEST) -// void NormalPriorityloop(void) +//void NormalPriorityloop(void) //{ // delay (keyboardconfig.keysendinterval); //} @@ -1195,71 +1117,87 @@ void keyscantimer_callback(TimerHandle_t _handle) { // put your main code here, to run repeatedly: /**************************************************************************************************************************/ // cppcheck-suppress unusedFunction -void loop() { // has task priority TASK_PRIO_LOW +void loop() { // has task priority TASK_PRIO_LOW updateWDT(); - +#ifdef ENABLE_AUDIO speaker.processTones(); - - if (keyboardconfig.enableSerial) { +#endif + if (keyboardconfig.enableSerial) + { handleSerial(); } - switch (keyboardconfig.connectionMode) { - case CONNECTION_MODE_AUTO: // automatically switch between BLE and USB when connecting/disconnecting USB - if (usb_isConnected()) { - if (keyboardstate.connectionState != CONNECTION_USB) { - if (bt_isConnected()) - bt_disconnect(); - bt_stopAdv(); - keyboardstate.connectionState = CONNECTION_USB; - keyboardstate.lastuseractiontime = millis(); // a USB connection will reset sleep timer... - // speaker.playTone(TONE_BLE_CONNECT); - } - } else if (bt_isConnected()) { - if (keyboardstate.connectionState != CONNECTION_BT) { - keyboardstate.connectionState = CONNECTION_BT; - keyboardstate.lastuseractiontime = millis(); // a BLE connection will reset sleep timer... - // speaker.playTone(TONE_BLE_CONNECT); - } - } else { - if (keyboardstate.connectionState != CONNECTION_NONE) { - bt_startAdv(); - keyboardstate.connectionState = CONNECTION_NONE; - // speaker.playTone(TONE_BLE_DISCONNECT); - // disconnecting won't reset sleep timer. - } - } - break; - case CONNECTION_MODE_USB_ONLY: - if (usb_isConnected()) { - if (keyboardstate.connectionState != CONNECTION_USB) { + switch (keyboardconfig.connectionMode) + { + case CONNECTION_MODE_AUTO: // automatically switch between BLE and USB when connecting/disconnecting USB + if (usb_isConnected()) + { + if (keyboardstate.connectionState != CONNECTION_USB) + { + if (bt_isConnected()) bt_disconnect(); + bt_stopAdv(); + keyboardstate.connectionState = CONNECTION_USB; + keyboardstate.lastuseractiontime = millis(); // a USB connection will reset sleep timer... + //speaker.playTone(TONE_BLE_CONNECT); + } + } + else if (bt_isConnected()) + { + if (keyboardstate.connectionState != CONNECTION_BT) + { + keyboardstate.connectionState = CONNECTION_BT; + keyboardstate.lastuseractiontime = millis(); // a BLE connection will reset sleep timer... + //speaker.playTone(TONE_BLE_CONNECT); + } + } + else + { + if (keyboardstate.connectionState != CONNECTION_NONE) + { + bt_startAdv(); + keyboardstate.connectionState = CONNECTION_NONE; + //speaker.playTone(TONE_BLE_DISCONNECT); + // disconnecting won't reset sleep timer. + } + } + break; + case CONNECTION_MODE_USB_ONLY: + if (usb_isConnected()) + { + if (keyboardstate.connectionState != CONNECTION_USB) + { + if (bt_isConnected()) bt_disconnect(); + bt_stopAdv(); + keyboardstate.connectionState = CONNECTION_USB; + } + } + else // if USB not connected but we are in USB Mode only... + { + keyboardstate.connectionState = CONNECTION_NONE; + } + break; + case CONNECTION_MODE_BLE_ONLY: if (bt_isConnected()) - bt_disconnect(); - bt_stopAdv(); - keyboardstate.connectionState = CONNECTION_USB; - } - } else // if USB not connected but we are in USB Mode only... - { - keyboardstate.connectionState = CONNECTION_NONE; - } - break; - case CONNECTION_MODE_BLE_ONLY: - if (bt_isConnected()) { - keyboardstate.connectionState = CONNECTION_BT; - } else { - if (keyboardstate.connectionState != CONNECTION_NONE) { - bt_startAdv(); - keyboardstate.connectionState = CONNECTION_NONE; - } - } - break; + { + keyboardstate.connectionState = CONNECTION_BT; + } + else + { + if (keyboardstate.connectionState != CONNECTION_NONE) + { + bt_startAdv(); + keyboardstate.connectionState = CONNECTION_NONE; + } + } + break; } // TODO: check for battery filtering when switching USB in/out // none of these things can be done in the timer event callbacks - if (keyboardstate.needUnpair) { + if (keyboardstate.needUnpair) + { bt_disconnect(); - char filename[32] = {0}; + char filename[32] = { 0 }; sprintf(filename, "/adafruit/bond_prph/%04x", keyboardconfig.BLEProfileEdiv[keyboardconfig.BLEProfile]); InternalFS.remove(filename); @@ -1268,113 +1206,127 @@ void loop() { // has task priority TASK_PRIO_LOW keyboardstate.save2flash = true; keyboardstate.needReset = true; } - if (keyboardstate.save2flash) { + if (keyboardstate.save2flash) + { saveConfig(); keyboardstate.save2flash = false; } - if (keyboardstate.needFSReset) { + if (keyboardstate.needFSReset) + { InternalFS.format(); keyboardstate.needReset = true; } - if (keyboardstate.needReset) - NVIC_SystemReset(); // this reboots the keyboard. + if (keyboardstate.needReset) NVIC_SystemReset(); // this reboots the keyboard. - delay(keyboardconfig.lowpriorityloopinterval); - -}; // loop is called for serials comms and saving to flash. + delay (keyboardconfig.lowpriorityloopinterval); + +}; // loop is called for serials comms and saving to flash. /**************************************************************************************************************************/ -void LowestPriorityloop() { // this loop has LOWEST priority (HIGHEST>HIGH>NORMAL>LOW>LOWEST) +void LowestPriorityloop() +{ // this loop has LOWEST priority (HIGHEST>HIGH>NORMAL>LOW>LOWEST) // it's setup to do 1 thing every call. This way, we won't take too much time from keyboard functions. - + backgroundTaskID toprocess = BACKGROUND_TASK_NONE; + - keyboardstate.lastuseractiontime = max(KeyScanner::getLastPressed(), keyboardstate.lastuseractiontime); // use the latest time to check for sleep... - unsigned long timesincelastkeypress = keyboardstate.timestamp - KeyScanner::getLastPressed(); + keyboardstate.lastuseractiontime = max(KeyScanner::getLastPressed(),keyboardstate.lastuseractiontime); // use the latest time to check for sleep... + unsigned long timesincelastkeypress = keyboardstate.timestamp - KeyScanner::getLastPressed(); updateBLEStatus(); - - if ((keyboardstate.timestamp - keyboardstate.batterytimer) > keyboardconfig.batteryinterval) // this is typically every 30 seconds... + + if ((keyboardstate.timestamp - keyboardstate.batterytimer) > keyboardconfig.batteryinterval) // this is typically every 30 seconds... { if (timesincelastkeypress > 1000) // update if we haven't typed for 1 second { toprocess = BACKGROUND_TASK_BATTERY; } } - if ((keyboardstate.timestamp - keyboardstate.displaytimer) > 250) // update even if we type but update 4 times a second. - { // TODO check if there is new data to display too! - toprocess = BACKGROUND_TASK_DISPLAY; - } - - if ((keyboardstate.timestamp - keyboardstate.audiotimer) > 500) { // TODO: check if there is new audio to play! - toprocess = BACKGROUND_TASK_AUDIO; - } - if (keyboardconfig.enableRGBLED) { - if ((keyboardstate.timestamp - keyboardstate.rgbledtimer) > 50) { - toprocess = BACKGROUND_TASK_RGBLED; + if ((keyboardstate.timestamp - keyboardstate.displaytimer) > 250) // update even if we type but update 4 times a second. + { // TODO check if there is new data to display too! + toprocess = BACKGROUND_TASK_DISPLAY; } - } - if (keyboardconfig.enablePWMLED) { - if ((keyboardstate.timestamp - keyboardstate.pwmledtimer) > 50) { - toprocess = BACKGROUND_TASK_PWMLED; + if ((keyboardstate.timestamp - keyboardstate.audiotimer) > 500) + { // TODO: check if there is new audio to play! + toprocess = BACKGROUND_TASK_AUDIO; } - } + if(keyboardconfig.enableRGBLED) + { + if ((keyboardstate.timestamp - keyboardstate.rgbledtimer) > 50) + { + toprocess = BACKGROUND_TASK_RGBLED; + } + } - if ((keyboardstate.timestamp - keyboardstate.statusledtimer) > 100) { // TODO: check if there is new audio to play! - toprocess = BACKGROUND_TASK_STATUSLED; - } + if(keyboardconfig.enablePWMLED) + { + if ((keyboardstate.timestamp - keyboardstate.pwmledtimer) > 50) + { + toprocess = BACKGROUND_TASK_PWMLED; + } + } + + if ((keyboardstate.timestamp - keyboardstate.statusledtimer) > 100) + { // TODO: check if there is new audio to play! + toprocess = BACKGROUND_TASK_STATUSLED; + } - switch (toprocess) { - case BACKGROUND_TASK_NONE: +switch (toprocess) +{ + case BACKGROUND_TASK_NONE: break; - case BACKGROUND_TASK_AUDIO: + case BACKGROUND_TASK_AUDIO: keyboardstate.audiotimer = keyboardstate.timestamp; break; - case BACKGROUND_TASK_BATTERY: - batterymonitor.updateBattery(); - keyboardstate.batterytimer = keyboardstate.timestamp; - keyboardstate.batt_type = batterymonitor.batt_type; - keyboardstate.vbat_mv = batterymonitor.vbat_mv; - keyboardstate.vbat_per = batterymonitor.vbat_per; - keyboardstate.vbat_vdd = batterymonitor.vbat_vdd; + case BACKGROUND_TASK_BATTERY: + batterymonitor.updateBattery(); + keyboardstate.batterytimer = keyboardstate.timestamp; + keyboardstate.batt_type = batterymonitor.batt_type; + keyboardstate.vbat_mv = batterymonitor.vbat_mv; + keyboardstate.vbat_per = batterymonitor.vbat_per; + keyboardstate.vbat_vdd = batterymonitor.vbat_vdd; break; - case BACKGROUND_TASK_DISPLAY: - keyboardstate.displaytimer = keyboardstate.timestamp; -#ifdef BLUEMICRO_CONFIGURED_DISPLAY - if (keyboardconfig.enableDisplay) { - OLED.update(); - } else { - OLED.sleep(); - } -#endif + case BACKGROUND_TASK_DISPLAY: + keyboardstate.displaytimer = keyboardstate.timestamp; + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + if(keyboardconfig.enableDisplay) + { + OLED.update(); + } + else + { + OLED.sleep(); + } + #endif break; - case BACKGROUND_TASK_STATUSLED: + case BACKGROUND_TASK_STATUSLED: keyboardstate.statusledtimer = keyboardstate.timestamp; statusLEDs.update(); break; - case BACKGROUND_TASK_PWMLED: + case BACKGROUND_TASK_PWMLED: keyboardstate.pwmledtimer = keyboardstate.timestamp; updatePWM(timesincelastkeypress); break; - case BACKGROUND_TASK_RGBLED: + case BACKGROUND_TASK_RGBLED: keyboardstate.rgbledtimer = keyboardstate.timestamp; updateRGB(timesincelastkeypress); break; - } - delay(keyboardconfig.lowestpriorityloopinterval); // wait not too long } + delay(keyboardconfig.lowestpriorityloopinterval); // wait not too long +} + + //********************************************************************************************// //* Idle Task - runs when there is nothing to do *// //* Any impact of placing code here on current consumption? *// //********************************************************************************************// -// cppcheck-suppress unusedFunction +// cppcheck-suppress unusedFunction extern "C" void vApplicationIdleHook(void) { // Don't call any other FreeRTOS blocking API() // Perform background task(s) here // this task has LOWEST priority (HIGHEST>HIGH>NORMAL>LOW>LOWEST) - sd_power_mode_set(NRF_POWER_MODE_LOWPWR); // 944uA - // sd_power_mode_set(NRF_POWER_MODE_CONSTLAT); // 1.5mA - sd_app_evt_wait(); // puts the nrf52 to sleep when there is nothing to do. You need this to reduce power consumption. (removing this will increase current to - // 8mA) + sd_power_mode_set(NRF_POWER_MODE_LOWPWR); // 944uA + //sd_power_mode_set(NRF_POWER_MODE_CONSTLAT); // 1.5mA + sd_app_evt_wait(); // puts the nrf52 to sleep when there is nothing to do. You need this to reduce power consumption. (removing this will increase current to 8mA) }; diff --git a/firmware/hardware_config.h b/firmware/hardware_config.h index 52b15560..e6f41504 100644 --- a/firmware/hardware_config.h +++ b/firmware/hardware_config.h @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef HARDWARE_CONFIG_H @@ -29,23 +26,20 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE #define MATRIX_ROWS 4 #define MATRIX_COLS 7 -#define MATRIX_ROW_PINS \ - { 13, 24, 9, 10 } -#define MATRIX_COL_PINS \ - { 26, 29, 2, 45, 3, 28, 43 } -#define UNUSED_PINS \ - {} -#define BACKLIGHT_LED_PIN 38 -#define DEFAULT_PWM_VALUE 10000 // PWM intensity +#define MATRIX_ROW_PINS {13, 24, 9, 10 } +#define MATRIX_COL_PINS {26, 29, 2, 45, 3, 28, 43 } +#define UNUSED_PINS {} +#define BACKLIGHT_LED_PIN 38 +#define DEFAULT_PWM_VALUE 10000 // PWM intensity #define BACKLIGHT_PWM_ON 1 /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW #define BATTERY_TYPE BATT_LIPO -#define VBAT_PIN 31 +#define VBAT_PIN 31 #define VCC_PIN 12 #define VCC_POLARITY_ON 1 -#define STATUS_BLE_LED_PIN 19 // blue = 0.19 -#define STATUS_KB_LED_PIN 17 // red = 0.17 - +#define STATUS_BLE_LED_PIN 19 //blue = 0.19 +#define STATUS_KB_LED_PIN 17 //red = 0.17 + #endif /* HARDWARE_CONFIG_H */ diff --git a/firmware/hardware_variants.h b/firmware/hardware_variants.h index 87657498..a52e9649 100644 --- a/firmware/hardware_variants.h +++ b/firmware/hardware_variants.h @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -29,22 +26,16 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVE // THIS FILE CONTAINS THE MACRO DEFINITIONS THAT USERS MAY USE IN THEIR keymap.cpp/h FILES. // FOR DATASTRUCTURES USED BY USER FUNCTIONS, SEE datastructures.h -#define NODIODES 0 -#define COL2ROW 0 // TODO: add automatic selection of ANTI-GHOSTING... -#define ROW2COL 1 +#define NODIODES 0 +#define COL2ROW 0 // TODO: add automatic selection of ANTI-GHOSTING... +#define ROW2COL 1 #define TEST 0 #define LEFT 1 #define RIGHT 2 #define SINGLE 3 -#define KEYMAP2ARRAY(OTHERMACROHERE) \ - { OTHERMACROHERE } -#define ADDLAYER(LAYER_INPUT, METHOD_INPUT, KEYMAP_INPUT) \ - for (int row = 0; row < MATRIX_ROWS; ++row) { \ - for (int col = 0; col < MATRIX_COLS; ++col) { \ - matrix[row][col].addActivation(LAYER_INPUT, METHOD_INPUT, KEYMAP_INPUT[row][col]); \ - } \ - } +#define KEYMAP2ARRAY(OTHERMACROHERE) {OTHERMACROHERE} +#define ADDLAYER(LAYER_INPUT,METHOD_INPUT,KEYMAP_INPUT ) for (int row = 0; row < MATRIX_ROWS; ++row) { for (int col = 0; col < MATRIX_COLS; ++col){ matrix[row][col].addActivation(LAYER_INPUT, METHOD_INPUT, KEYMAP_INPUT[row][col]);}} #define _PINNUM(port, pin) ((port)*32 + (pin)) -#endif /*HARDWAREVARIANTS_H*/ \ No newline at end of file +#endif /*HARDWAREVARIANTS_H*/ \ No newline at end of file diff --git a/firmware/hid_keycodes.h b/firmware/hid_keycodes.h index b3e15b3d..beb14dbb 100644 --- a/firmware/hid_keycodes.h +++ b/firmware/hid_keycodes.h @@ -7,21 +7,18 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* -These keycodes are based on Universal Serial Bus HID Usage Tables Document +These keycodes are based on Universal Serial Bus HID Usage Tables Document Version 1.12 Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf @@ -37,11 +34,11 @@ Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 #define KC_RCTL KC_RCTRL #define KC_LSFT KC_LSHIFT #define KC_RSFT KC_RSHIFT -#define KC_ESC KC_ESCAPE +#define KC_ESC KC_ESCAPE #define KC_BSPC KC_BSPACE -#define KC_ENT KC_ENTER -#define KC_DEL KC_DELETE -#define KC_INS KC_INSERT +#define KC_ENT KC_ENTER +#define KC_DEL KC_DELETE +#define KC_INS KC_INSERT #define KC_CAPS KC_CAPSLOCK #define KC_CLCK KC_CAPSLOCK #define KC_RGHT KC_RIGHT @@ -49,12 +46,12 @@ Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 #define KC_PSCR KC_PSCREEN #define KC_SLCK KC_SCROLLLOCK #define KC_PAUS KC_PAUSE -#define KC_BRK KC_PAUSE +#define KC_BRK KC_PAUSE #define KC_NLCK KC_NUMLOCK -#define KC_SPC KC_SPACE +#define KC_SPC KC_SPACE #define KC_MINS KC_MINUS -#define KC_EQL KC_EQUAL -#define KC_GRV KC_GRAVE +#define KC_EQL KC_EQUAL +#define KC_GRV KC_GRAVE #define KC_RBRC KC_RBRACKET #define KC_LBRC KC_LBRACKET #define KC_COMM KC_COMMA @@ -62,17 +59,17 @@ Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 #define KC_SLSH KC_SLASH #define KC_SCLN KC_SCOLON #define KC_QUOT KC_QUOTE -#define KC_APP KC_APPLICATION +#define KC_APP KC_APPLICATION #define KC_NUHS KC_NONUS_HASH #define KC_NUBS KC_NONUS_BSLASH #define KC_LCAP KC_LOCKING_CAPS #define KC_LNUM KC_LOCKING_NUM #define KC_LSCR KC_LOCKING_SCROLL #define KC_ERAS KC_ALT_ERASE -#define KC_CLR KC_CLEAR +#define KC_CLR KC_CLEAR /* Japanese specific */ #define KC_ZKHK KC_GRAVE -#define KC_RO KC_INT1 +#define KC_RO KC_INT1 #define KC_KANA KC_INT2 #define KC_JYEN KC_INT3 #define KC_HENK KC_INT4 @@ -81,16 +78,16 @@ Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 #define KC_HAEN KC_LANG1 #define KC_HANJ KC_LANG2 /* Keypad */ -#define KC_P1 KC_KP_1 -#define KC_P2 KC_KP_2 -#define KC_P3 KC_KP_3 -#define KC_P4 KC_KP_4 -#define KC_P5 KC_KP_5 -#define KC_P6 KC_KP_6 -#define KC_P7 KC_KP_7 -#define KC_P8 KC_KP_8 -#define KC_P9 KC_KP_9 -#define KC_P0 KC_KP_0 +#define KC_P1 KC_KP_1 +#define KC_P2 KC_KP_2 +#define KC_P3 KC_KP_3 +#define KC_P4 KC_KP_4 +#define KC_P5 KC_KP_5 +#define KC_P6 KC_KP_6 +#define KC_P7 KC_KP_7 +#define KC_P8 KC_KP_8 +#define KC_P9 KC_KP_9 +#define KC_P0 KC_KP_0 #define KC_PDOT KC_KP_DOT #define KC_PCMM KC_KP_COMMA #define KC_PSLS KC_KP_SLASH @@ -123,7 +120,7 @@ Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 #define KC_ACL2 KC_MS_ACCEL2 /* Transparent */ -#define KC_TRANSPARENT 1 +#define KC_TRANSPARENT 1 #define KC_TRNS KC_TRANSPARENT /* GUI key aliases */ #define KC_LCMD KC_LGUI @@ -133,189 +130,188 @@ Chapter 10: Keyboard/Keypad Page(0x07) - Page 53 #define _______ KC_TRNS #define XXXXXXX KC_NO -#define KC_LABK KC_LT -#define KC_RABK KC_GT +#define KC_LABK KC_LT +#define KC_RABK KC_GT /* USB HID Keyboard/Keypad Usage(0x07) */ enum hid_keyboard_keypad_usage { - KC_NO = 0x00, - KC_ROLL_OVER, // this is equivalent to KC_TRANSPARENT - KC_POST_FAIL, - KC_UNDEFINED, - KC_A, - KC_B, - KC_C, - KC_D, - KC_E, - KC_F, - KC_G, - KC_H, - KC_I, - KC_J, - KC_K, - KC_L, - KC_M, /* 0x10 */ - KC_N, - KC_O, - KC_P, - KC_Q, - KC_R, - KC_S, - KC_T, - KC_U, - KC_V, - KC_W, - KC_X, - KC_Y, - KC_Z, - KC_1, - KC_2, - KC_3, /* 0x20 */ - KC_4, - KC_5, - KC_6, - KC_7, - KC_8, - KC_9, - KC_0, - KC_ENTER, - KC_ESCAPE, - KC_BSPACE, - KC_TAB, - KC_SPACE, - KC_MINUS, - KC_EQUAL, - KC_LBRACKET, - KC_RBRACKET, /* 0x30 */ - KC_BSLASH, /* \ (and |) */ - KC_NONUS_HASH, /* Non-US # and ~ (Typically near the Enter key) */ - KC_SCOLON, /* ; (and :) */ - KC_QUOTE, /* ' and " */ - KC_GRAVE, /* Grave accent and tilde */ - KC_COMMA, /* , and < */ - KC_DOT, /* . and > */ - KC_SLASH, /* / and ? */ - KC_CAPSLOCK, - KC_F1, - KC_F2, - KC_F3, - KC_F4, - KC_F5, - KC_F6, - KC_F7, /* 0x40 */ - KC_F8, - KC_F9, - KC_F10, - KC_F11, - KC_F12, - KC_PSCREEN, - KC_SCROLLLOCK, - KC_PAUSE, - KC_INSERT, - KC_HOME, - KC_PGUP, - KC_DELETE, - KC_END, - KC_PGDOWN, - KC_RIGHT, - KC_LEFT, /* 0x50 */ - KC_DOWN, - KC_UP, - KC_NUMLOCK, - KC_KP_SLASH, - KC_KP_ASTERISK, - KC_KP_MINUS, - KC_KP_PLUS, - KC_KP_ENTER, - KC_KP_1, - KC_KP_2, - KC_KP_3, - KC_KP_4, - KC_KP_5, - KC_KP_6, - KC_KP_7, - KC_KP_8, /* 0x60 */ - KC_KP_9, - KC_KP_0, - KC_KP_DOT, - KC_NONUS_BSLASH, /* Non-US \ and | (Typically near the Left-Shift key) */ - KC_APPLICATION, - KC_POWER, - KC_KP_EQUAL, - KC_F13, - KC_F14, - KC_F15, - KC_F16, - KC_F17, - KC_F18, - KC_F19, - KC_F20, - KC_F21, /* 0x70 */ - KC_F22, - KC_F23, - KC_F24, - KC_EXECUTE, - KC_HELP, - KC_MENU, - KC_SELECT, - KC_STOP, - KC_AGAIN, - KC_UNDO, - KC_CUT, - KC_COPY, - KC_PASTE, - KC_FIND, - KC_MUTE, - KC_VOLUP, /* 0x80 */ - KC_VOLDOWN, - KC_LOCKING_CAPS, /* locking Caps Lock */ - KC_LOCKING_NUM, /* locking Num Lock */ - KC_LOCKING_SCROLL, /* locking Scroll Lock */ - KC_KP_COMMA, - KC_KP_EQUAL_AS400, /* equal sign on AS/400 */ - KC_INT1, - KC_INT2, - KC_INT3, - KC_INT4, - KC_INT5, - KC_INT6, - KC_INT7, - KC_INT8, - KC_INT9, - KC_LANG1, /* 0x90 */ - KC_LANG2, - KC_LANG3, - KC_LANG4, - KC_LANG5, - KC_LANG6, - KC_LANG7, - KC_LANG8, - KC_LANG9, - KC_ALT_ERASE, - KC_SYSREQ, - KC_CANCEL, - KC_CLEAR, - KC_PRIOR, - KC_RETURN, - KC_SEPARATOR, - KC_OUT, /* 0xA0 */ - KC_OPER, - KC_CLEAR_AGAIN, - KC_CRSEL, - KC_EXSEL, /* 0xA4 */ - - KC_RESERVED_A5, - /*0xA5 to 0xAF - RESERVED*/ // Used as macro identifier - KC_RESERVED_A6, // this is used for special keyboard functions - KC_RESERVED_A7, - KC_RESERVED_A8, - KC_RESERVED_A9, - KC_RESERVED_AA, - KC_RESERVED_AB, - KC_RESERVED_AC, - KC_RESERVED_AD, - KC_RESERVED_AE, - KC_RESERVED_AF, + KC_NO = 0x00, + KC_ROLL_OVER, // this is equivalent to KC_TRANSPARENT + KC_POST_FAIL, + KC_UNDEFINED, + KC_A, + KC_B, + KC_C, + KC_D, + KC_E, + KC_F, + KC_G, + KC_H, + KC_I, + KC_J, + KC_K, + KC_L, + KC_M, /* 0x10 */ + KC_N, + KC_O, + KC_P, + KC_Q, + KC_R, + KC_S, + KC_T, + KC_U, + KC_V, + KC_W, + KC_X, + KC_Y, + KC_Z, + KC_1, + KC_2, + KC_3, /* 0x20 */ + KC_4, + KC_5, + KC_6, + KC_7, + KC_8, + KC_9, + KC_0, + KC_ENTER, + KC_ESCAPE, + KC_BSPACE, + KC_TAB, + KC_SPACE, + KC_MINUS, + KC_EQUAL, + KC_LBRACKET, + KC_RBRACKET, /* 0x30 */ + KC_BSLASH, /* \ (and |) */ + KC_NONUS_HASH, /* Non-US # and ~ (Typically near the Enter key) */ + KC_SCOLON, /* ; (and :) */ + KC_QUOTE, /* ' and " */ + KC_GRAVE, /* Grave accent and tilde */ + KC_COMMA, /* , and < */ + KC_DOT, /* . and > */ + KC_SLASH, /* / and ? */ + KC_CAPSLOCK, + KC_F1, + KC_F2, + KC_F3, + KC_F4, + KC_F5, + KC_F6, + KC_F7, /* 0x40 */ + KC_F8, + KC_F9, + KC_F10, + KC_F11, + KC_F12, + KC_PSCREEN, + KC_SCROLLLOCK, + KC_PAUSE, + KC_INSERT, + KC_HOME, + KC_PGUP, + KC_DELETE, + KC_END, + KC_PGDOWN, + KC_RIGHT, + KC_LEFT, /* 0x50 */ + KC_DOWN, + KC_UP, + KC_NUMLOCK, + KC_KP_SLASH, + KC_KP_ASTERISK, + KC_KP_MINUS, + KC_KP_PLUS, + KC_KP_ENTER, + KC_KP_1, + KC_KP_2, + KC_KP_3, + KC_KP_4, + KC_KP_5, + KC_KP_6, + KC_KP_7, + KC_KP_8, /* 0x60 */ + KC_KP_9, + KC_KP_0, + KC_KP_DOT, + KC_NONUS_BSLASH, /* Non-US \ and | (Typically near the Left-Shift key) */ + KC_APPLICATION, + KC_POWER, + KC_KP_EQUAL, + KC_F13, + KC_F14, + KC_F15, + KC_F16, + KC_F17, + KC_F18, + KC_F19, + KC_F20, + KC_F21, /* 0x70 */ + KC_F22, + KC_F23, + KC_F24, + KC_EXECUTE, + KC_HELP, + KC_MENU, + KC_SELECT, + KC_STOP, + KC_AGAIN, + KC_UNDO, + KC_CUT, + KC_COPY, + KC_PASTE, + KC_FIND, + KC_MUTE, + KC_VOLUP, /* 0x80 */ + KC_VOLDOWN, + KC_LOCKING_CAPS, /* locking Caps Lock */ + KC_LOCKING_NUM, /* locking Num Lock */ + KC_LOCKING_SCROLL, /* locking Scroll Lock */ + KC_KP_COMMA, + KC_KP_EQUAL_AS400, /* equal sign on AS/400 */ + KC_INT1, + KC_INT2, + KC_INT3, + KC_INT4, + KC_INT5, + KC_INT6, + KC_INT7, + KC_INT8, + KC_INT9, + KC_LANG1, /* 0x90 */ + KC_LANG2, + KC_LANG3, + KC_LANG4, + KC_LANG5, + KC_LANG6, + KC_LANG7, + KC_LANG8, + KC_LANG9, + KC_ALT_ERASE, + KC_SYSREQ, + KC_CANCEL, + KC_CLEAR, + KC_PRIOR, + KC_RETURN, + KC_SEPARATOR, + KC_OUT, /* 0xA0 */ + KC_OPER, + KC_CLEAR_AGAIN, + KC_CRSEL, + KC_EXSEL, /* 0xA4 */ + + KC_RESERVED_A5, /*0xA5 to 0xAF - RESERVED*/ // Used as macro identifier + KC_RESERVED_A6, // this is used for special keyboard functions + KC_RESERVED_A7, + KC_RESERVED_A8, + KC_RESERVED_A9, + KC_RESERVED_AA, + KC_RESERVED_AB, + KC_RESERVED_AC, + KC_RESERVED_AD, + KC_RESERVED_AE, + KC_RESERVED_AF, #if 0 /* NOTE: Following codes(0xB0-DD) are not used but are in the HID Document. Leaving them for reference. */ KC_KP_00 = 0xB0, @@ -365,274 +361,274 @@ enum hid_keyboard_keypad_usage { KC_KP_HEXADECIMAL, /* 0xDD */ #endif - /* Modifiers */ - KC_LCTRL = 0xE0, - KC_LSHIFT, - KC_LALT, - KC_LGUI, - KC_RCTRL, - KC_RSHIFT, - KC_RALT, - KC_RGUI, - + /* Modifiers */ + KC_LCTRL = 0xE0, + KC_LSHIFT, + KC_LALT, + KC_LGUI, + KC_RCTRL, + KC_RSHIFT, + KC_RALT, + KC_RGUI, + + }; -#define LAYER_0 0xF0 -#define LAYER_1 0xF1 -#define LAYER_2 0xF2 -#define LAYER_3 0xF3 -#define LAYER_4 0xF4 -#define LAYER_5 0xF5 -#define LAYER_6 0xF6 -#define LAYER_7 0xF7 -#define LAYER_8 0xF8 -#define LAYER_9 0xF9 -#define LAYER_A 0xFA -#define LAYER_B 0xFB -#define LAYER_C 0xFC -#define LAYER_D 0xFD -#define LAYER_E 0xFE -#define LAYER_F 0xFF - -#define RESET KB(KC_A) -#define DEBUG KB(KC_B) -#define EEPROM_RESET KB(KC_C) -#define EEP_RST EEPROM_RESET -#define DFU KB(KC_D) -#define SERIAL_DFU KB(KC_E) -#define UF2_DFU KB(KC_ESC) -#define CLEAR_BONDS KB(KC_F) - -#define BL_TOGG KB(KC_G) -#define BL_STEP KB(KC_H) -#define BL_ON KB(KC_I) -#define BL_OFF KB(KC_J) -#define BL_INC KB(KC_K) -#define BL_DEC KB(KC_L) -#define BL_BRTG KB(KC_M) -#define BL_REACT KB(KC_N) -#define BL_STEPINC KB(KC_O) -#define BL_STEPDEC KB(KC_P) - -#define OUT_AUTO KB(KC_Q) -#define OUT_USB KB(KC_R) -#define OUT_BT KB(KC_S) - -#define RGB_TOG KB(KC_T) -#define RGB_MODE_FORWARD KB(KC_U) -#define RGB_MOD RGB_MODE_FORWARD -#define RGB_MODE_REVERSE KB(KC_V) -#define RGB_RMOD RGB_MODE_REVERSE -#define RGB_HUI KB(KC_W) -#define RGB_HUD KB(KC_X) -#define RGB_SAI KB(KC_Y) -#define RGB_SAD KB(KC_Z) -#define RGB_VAI KB(KC_1) -#define RGB_VAD KB(KC_2) -#define RGB_MODE_PLAIN KB(KC_3) -#define RGB_M_P RGB_MODE_PLAIN -#define RGB_MODE_BREATHE KB(KC_4) -#define RGB_M_B RGB_MODE_BREATHE -#define RGB_MODE_RAINBOW KB(KC_5) -#define RGB_M_R RGB_MODE_RAINBOW -#define RGB_MODE_SWIRL KB(KC_6) -#define RGB_M_SW RGB_MODE_SWIRL -#define RGB_MODE_SNAKE KB(KC_7) -#define RGB_M_SN RGB_MODE_SNAKE -#define RGB_MODE_KNIGHT KB(KC_8) -#define RGB_M_K RGB_MODE_KNIGHT -#define RGB_MODE_XMAS KB(KC_9) -#define RGB_M_X RGB_MODE_XMAS -#define RGB_MODE_GRADIENT KB(KC_0) -#define RGB_M_G RGB_MODE_GRADIENT -#define RGB_MODE_RGBTEST KB(KC_F1) -#define RGB_M_T RGB_MODE_RGBTEST -#define RGB_SPI KB(KC_F2) -#define RGB_SPD KB(KC_F3) - -#define PRINT_BATTERY KB(KC_F4) -#define PRINT_INFO KB(KC_F5) -#define PRINT_BLE KB(KC_F6) -#define PRINT_HELP KB(KC_F7) -#define BLEPROFILE_1 KB(KC_F8) -#define BLEPROFILE_2 KB(KC_F9) -#define BLEPROFILE_3 KB(KC_F10) -#define SLEEP_NOW KB(KC_F11) -#define HELP_MODE KB(KC_F12) - -#define BATTERY_CALC_DEFAULT KB(KC_F13) -#define BATTERY_CALC_TEST KB(KC_F14) +#define LAYER_0 0xF0 +#define LAYER_1 0xF1 +#define LAYER_2 0xF2 +#define LAYER_3 0xF3 +#define LAYER_4 0xF4 +#define LAYER_5 0xF5 +#define LAYER_6 0xF6 +#define LAYER_7 0xF7 +#define LAYER_8 0xF8 +#define LAYER_9 0xF9 +#define LAYER_A 0xFA +#define LAYER_B 0xFB +#define LAYER_C 0xFC +#define LAYER_D 0xFD +#define LAYER_E 0xFE +#define LAYER_F 0xFF + +#define RESET KB(KC_A) +#define DEBUG KB(KC_B) +#define EEPROM_RESET KB(KC_C) +#define EEP_RST EEPROM_RESET +#define DFU KB(KC_D) +#define SERIAL_DFU KB(KC_E) +#define UF2_DFU KB(KC_ESC) +#define CLEAR_BONDS KB(KC_F) + +#define BL_TOGG KB(KC_G) +#define BL_STEP KB(KC_H) +#define BL_ON KB(KC_I) +#define BL_OFF KB(KC_J) +#define BL_INC KB(KC_K) +#define BL_DEC KB(KC_L) +#define BL_BRTG KB(KC_M) +#define BL_REACT KB(KC_N) +#define BL_STEPINC KB(KC_O) +#define BL_STEPDEC KB(KC_P) + +#define OUT_AUTO KB(KC_Q) +#define OUT_USB KB(KC_R) +#define OUT_BT KB(KC_S) + +#define RGB_TOG KB(KC_T) +#define RGB_MODE_FORWARD KB(KC_U) +#define RGB_MOD RGB_MODE_FORWARD +#define RGB_MODE_REVERSE KB(KC_V) +#define RGB_RMOD RGB_MODE_REVERSE +#define RGB_HUI KB(KC_W) +#define RGB_HUD KB(KC_X) +#define RGB_SAI KB(KC_Y) +#define RGB_SAD KB(KC_Z) +#define RGB_VAI KB(KC_1) +#define RGB_VAD KB(KC_2) +#define RGB_MODE_PLAIN KB(KC_3) +#define RGB_M_P RGB_MODE_PLAIN +#define RGB_MODE_BREATHE KB(KC_4) +#define RGB_M_B RGB_MODE_BREATHE +#define RGB_MODE_RAINBOW KB(KC_5) +#define RGB_M_R RGB_MODE_RAINBOW +#define RGB_MODE_SWIRL KB(KC_6) +#define RGB_M_SW RGB_MODE_SWIRL +#define RGB_MODE_SNAKE KB(KC_7) +#define RGB_M_SN RGB_MODE_SNAKE +#define RGB_MODE_KNIGHT KB(KC_8) +#define RGB_M_K RGB_MODE_KNIGHT +#define RGB_MODE_XMAS KB(KC_9) +#define RGB_M_X RGB_MODE_XMAS +#define RGB_MODE_GRADIENT KB(KC_0) +#define RGB_M_G RGB_MODE_GRADIENT +#define RGB_MODE_RGBTEST KB(KC_F1) +#define RGB_M_T RGB_MODE_RGBTEST +#define RGB_SPI KB(KC_F2) +#define RGB_SPD KB(KC_F3) + +#define PRINT_BATTERY KB(KC_F4) +#define PRINT_INFO KB(KC_F5) +#define PRINT_BLE KB(KC_F6) +#define PRINT_HELP KB(KC_F7) +#define BLEPROFILE_1 KB(KC_F8) +#define BLEPROFILE_2 KB(KC_F9) +#define BLEPROFILE_3 KB(KC_F10) +#define SLEEP_NOW KB(KC_F11) +#define HELP_MODE KB(KC_F12) + +#define BATTERY_CALC_DEFAULT KB(KC_F13) +#define BATTERY_CALC_TEST KB(KC_F14) #define BATTERY_CALC_FILTERED KB(KC_F15) // TODO: bring the akudaikon filtered method for switching between USB connected/not connected. // Power Control -#define KC_SYSTEM_POWER MK(KC_A) // HID_USAGE_CONSUMER_POWER -#define KC_SYSTEM_RESET MK(KC_B) // HID_USAGE_CONSUMER_RESET -#define KC_SYSTEM_SLEEP MK(KC_C) // HID_USAGE_CONSUMER_SLEEP +#define KC_SYSTEM_POWER MK(KC_A) //HID_USAGE_CONSUMER_POWER +#define KC_SYSTEM_RESET MK(KC_B) //HID_USAGE_CONSUMER_RESET +#define KC_SYSTEM_SLEEP MK(KC_C) //HID_USAGE_CONSUMER_SLEEP // Screen Brightness -#define KC_DISPLAY_BRIGHTI MK(KC_D) // HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT -#define KC_DISPLAY_BRIGHTD MK(KC_E) // HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT +#define KC_DISPLAY_BRIGHTI MK(KC_D) //HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT +#define KC_DISPLAY_BRIGHTD MK(KC_E) //HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT -// These HID usages operate only on mobile systems (battery powered) and -// require Windows 8 (build 8302 or greater). -#define KC_RADIO_CONTROL MK(KC_F) // HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS -#define KC_RADIO_BUTTONS MK(KC_G) // HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS -#define KC_RADIO_LED MK(KC_H) // HID_USAGE_CONSUMER_WIRELESS_RADIO_LED -#define KC_RADIO_SWITCH MK(KC_I) // HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH + // These HID usages operate only on mobile systems (battery powered) and + // require Windows 8 (build 8302 or greater). +#define KC_RADIO_CONTROL MK(KC_F) // HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS +#define KC_RADIO_BUTTONS MK(KC_G) // HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS +#define KC_RADIO_LED MK(KC_H) // HID_USAGE_CONSUMER_WIRELESS_RADIO_LED +#define KC_RADIO_SWITCH MK(KC_I) // HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH // Media Control -#define KC_MEDIA_PLAY_PAUSE MK(KC_K) // HID_USAGE_CONSUMER_PLAY_PAUSE -#define KC_MEDIA_NEXT_TRACK MK(KC_L) // HID_USAGE_CONSUMER_SCAN_NEXT -#define KC_MEDIA_PREV_TRACK MK(KC_M) // HID_USAGE_CONSUMER_SCAN_PREVIOUS -#define KC_MEDIA_STOP MK(KC_N) // HID_USAGE_CONSUMER_STOP -#define KC_AUDIO_VOL MK(KC_O) // HID_USAGE_CONSUMER_VOLUME -#define KC_AUDIO_MUTE MK(KC_P) // HID_USAGE_CONSUMER_MUTE -#define KC_AUDIO_BASS MK(KC_Q) // HID_USAGE_CONSUMER_BASS -#define KC_AUDIO_TREBLE MK(KC_R) // HID_USAGE_CONSUMER_TREBLE -#define KC_AUDIO_BASS_BOOST MK(KC_S) // HID_USAGE_CONSUMER_BASS_BOOST -#define KC_AUDIO_VOL_UP MR(KC_T) // HID_USAGE_CONSUMER_VOLUME_INCREMENT -#define KC_AUDIO_VOL_DOWN MR(KC_U) // HID_USAGE_CONSUMER_VOLUME_DECREMENT -#define KC_AUDIO_BASS_UP MR(KC_V) // HID_USAGE_CONSUMER_BASS_INCREMENT -#define KC_AUDIO_BASS_DOWN MR(KC_W) // HID_USAGE_CONSUMER_BASS_DECREMENT -#define KC_AUDIO_TREBLE_UP MR(KC_X) // HID_USAGE_CONSUMER_TREBLE_INCREMENT -#define KC_AUDIO_TREBLE_DOWN MR(KC_Y) // HID_USAGE_CONSUMER_TREBLE_DECREMENT - -// Application Launcher -#define KC_MSEL MK(KC_Z) // HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION -#define KC_WWW MK(KC_1) // HID_USAGE_CONSUMER_AL_EMAIL_READER -#define KC_MAIL KC_WWW // not sure about this one... -#define KC_CALCULATOR MK(KC_2) // HID_USAGE_CONSUMER_AL_CALCULATOR -#define KC_MYCM MK(KC_3) // HID_USAGE_CONSUMER_AL_LOCAL_BROWSER +#define KC_MEDIA_PLAY_PAUSE MK(KC_K) //HID_USAGE_CONSUMER_PLAY_PAUSE +#define KC_MEDIA_NEXT_TRACK MK(KC_L) //HID_USAGE_CONSUMER_SCAN_NEXT +#define KC_MEDIA_PREV_TRACK MK(KC_M) //HID_USAGE_CONSUMER_SCAN_PREVIOUS +#define KC_MEDIA_STOP MK(KC_N) //HID_USAGE_CONSUMER_STOP +#define KC_AUDIO_VOL MK(KC_O) //HID_USAGE_CONSUMER_VOLUME +#define KC_AUDIO_MUTE MK(KC_P) //HID_USAGE_CONSUMER_MUTE +#define KC_AUDIO_BASS MK(KC_Q) //HID_USAGE_CONSUMER_BASS +#define KC_AUDIO_TREBLE MK(KC_R) //HID_USAGE_CONSUMER_TREBLE +#define KC_AUDIO_BASS_BOOST MK(KC_S) //HID_USAGE_CONSUMER_BASS_BOOST +#define KC_AUDIO_VOL_UP MR(KC_T) //HID_USAGE_CONSUMER_VOLUME_INCREMENT +#define KC_AUDIO_VOL_DOWN MR(KC_U) //HID_USAGE_CONSUMER_VOLUME_DECREMENT +#define KC_AUDIO_BASS_UP MR(KC_V) //HID_USAGE_CONSUMER_BASS_INCREMENT +#define KC_AUDIO_BASS_DOWN MR(KC_W) //HID_USAGE_CONSUMER_BASS_DECREMENT +#define KC_AUDIO_TREBLE_UP MR(KC_X) //HID_USAGE_CONSUMER_TREBLE_INCREMENT +#define KC_AUDIO_TREBLE_DOWN MR(KC_Y) //HID_USAGE_CONSUMER_TREBLE_DECREMENT + + // Application Launcher +#define KC_MSEL MK(KC_Z) //HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION +#define KC_WWW MK(KC_1) //HID_USAGE_CONSUMER_AL_EMAIL_READER +#define KC_MAIL KC_WWW // not sure about this one... +#define KC_CALCULATOR MK(KC_2) //HID_USAGE_CONSUMER_AL_CALCULATOR +#define KC_MYCM MK(KC_3) //HID_USAGE_CONSUMER_AL_LOCAL_BROWSER // Browser/Explorer Specific -#define KC_WWW_SEARCH MK(KC_4) // HID_USAGE_CONSUMER_AC_SEARCH -#define KC_WWW_HOME MK(KC_5) // HID_USAGE_CONSUMER_AC_HOME -#define KC_WWW_BACK MK(KC_6) // HID_USAGE_CONSUMER_AC_BACK -#define KC_WWW_FORWARD MK(KC_7) // HID_USAGE_CONSUMER_AC_FORWARD -#define KC_WWW_STOP MK(KC_8) // HID_USAGE_CONSUMER_AC_STOP -#define KC_WWW_REFRESH MK(KC_9) // HID_USAGE_CONSUMER_AC_REFRESH -#define KC_WWW_FAVORITES MK(KC_0) // HID_USAGE_CONSUMER_AC_BOOKMARKS - -// Mouse Horizontal scroll -#define KC_AC_PAN MK(KC_F1) // HID_USAGE_CONSUMER_AC_PAN - -#define KC_PWR KC_SYSTEM_POWER -#define KC_SLEP KC_SYSTEM_SLEEP -#define KC_MUTE KC_AUDIO_MUTE -#define KC_VOLU KC_AUDIO_VOL_UP -#define KC_VOLD KC_AUDIO_VOL_DOWN -#define KC_MNXT KC_MEDIA_NEXT_TRACK -#define KC_MPRV KC_MEDIA_PREV_TRACK -#define KC_MSTP KC_MEDIA_STOP -#define KC_MPLY KC_MEDIA_PLAY_PAUSE -#define KC_CALC KC_CALCULATOR -#define KC_WSCH KC_WWW_SEARCH -#define KC_WHOM KC_WWW_HOME -#define KC_WBAK KC_WWW_BACK -#define KC_WFWD KC_WWW_FORWARD -#define KC_WSTP KC_WWW_STOP -#define KC_WREF KC_WWW_REFRESH -#define KC_WFAV KC_WWW_FAVORITES +#define KC_WWW_SEARCH MK(KC_4) //HID_USAGE_CONSUMER_AC_SEARCH +#define KC_WWW_HOME MK(KC_5) //HID_USAGE_CONSUMER_AC_HOME +#define KC_WWW_BACK MK(KC_6) //HID_USAGE_CONSUMER_AC_BACK +#define KC_WWW_FORWARD MK(KC_7) //HID_USAGE_CONSUMER_AC_FORWARD +#define KC_WWW_STOP MK(KC_8) //HID_USAGE_CONSUMER_AC_STOP +#define KC_WWW_REFRESH MK(KC_9) //HID_USAGE_CONSUMER_AC_REFRESH +#define KC_WWW_FAVORITES MK(KC_0) //HID_USAGE_CONSUMER_AC_BOOKMARKS + + // Mouse Horizontal scroll +#define KC_AC_PAN MK(KC_F1) //HID_USAGE_CONSUMER_AC_PAN + +#define KC_PWR KC_SYSTEM_POWER +#define KC_SLEP KC_SYSTEM_SLEEP +#define KC_MUTE KC_AUDIO_MUTE +#define KC_VOLU KC_AUDIO_VOL_UP +#define KC_VOLD KC_AUDIO_VOL_DOWN +#define KC_MNXT KC_MEDIA_NEXT_TRACK +#define KC_MPRV KC_MEDIA_PREV_TRACK +#define KC_MSTP KC_MEDIA_STOP +#define KC_MPLY KC_MEDIA_PLAY_PAUSE +#define KC_CALC KC_CALCULATOR +#define KC_WSCH KC_WWW_SEARCH +#define KC_WHOM KC_WWW_HOME +#define KC_WBAK KC_WWW_BACK +#define KC_WFWD KC_WWW_FORWARD +#define KC_WSTP KC_WWW_STOP +#define KC_WREF KC_WWW_REFRESH +#define KC_WFAV KC_WWW_FAVORITES + // Mouse keycodes... -#define KC_MS_OFF MS(KC_A) -#define KC_MS_UP MS(KC_B) -#define KC_MS_DOWN MS(KC_C) -#define KC_MS_LEFT MS(KC_D) -#define KC_MS_RIGHT MS(KC_E) -#define KC_MS_BTN1 MS(KC_F) -#define KC_MS_BTN2 MS(KC_G) -#define KC_MS_BTN3 MS(KC_H) -#define KC_MS_BTN4 MS(KC_I) -#define KC_MS_BTN5 MS(KC_J) -#define KC_MS_WH_UP MS(KC_K) -#define KC_MS_WH_DOWN MS(KC_L) -#define KC_MS_WH_DN KC_MS_WH_DOWN -#define KC_MS_WH_LEFT MS(KC_M) -#define KC_MS_WH_RIGHT MS(KC_N) -#define KC_MS_ACCEL0 MS(KC_O) // Slow speed = 1 -#define KC_MS_ACCEL1 MS(KC_P) // normal speed = #define MOVE_STEP 8; you can redefine it in your keyboard_config.h -#define KC_MS_ACCEL2 MS(KC_Q) // fast speed = 2*MOVE_STEP +#define KC_MS_OFF MS(KC_A) +#define KC_MS_UP MS(KC_B) +#define KC_MS_DOWN MS(KC_C) +#define KC_MS_LEFT MS(KC_D) +#define KC_MS_RIGHT MS(KC_E) +#define KC_MS_BTN1 MS(KC_F) +#define KC_MS_BTN2 MS(KC_G) +#define KC_MS_BTN3 MS(KC_H) +#define KC_MS_BTN4 MS(KC_I) +#define KC_MS_BTN5 MS(KC_J) +#define KC_MS_WH_UP MS(KC_K) +#define KC_MS_WH_DOWN MS(KC_L) +#define KC_MS_WH_DN KC_MS_WH_DOWN +#define KC_MS_WH_LEFT MS(KC_M) +#define KC_MS_WH_RIGHT MS(KC_N) +#define KC_MS_ACCEL0 MS(KC_O) // Slow speed = 1 +#define KC_MS_ACCEL1 MS(KC_P) // normal speed = #define MOVE_STEP 8; you can redefine it in your keyboard_config.h +#define KC_MS_ACCEL2 MS(KC_Q) // fast speed = 2*MOVE_STEP + // these international characters work on windows -#define WIN_A_GRAVE KI(KC_A) // Alt 0224 a grave -#define WIN_A_ACUTE KI(KC_B) // Alt 0225 a acute -#define WIN_A_CIRCU KI(KC_C) // Alt 0226 a circumflex -#define WIN_A_TILDE KI(KC_D) // Alt 0227 a tilde -#define WIN_A_UMLAU KI(KC_E) // Alt 0228 a umlaut - -#define WIN_A_GRAVE_CAP KI(KC_F) // Alt 0192 A grave -#define WIN_A_ACUTE_CAP KI(KC_G) // Alt 0193 A acute -#define WIN_A_CIRCU_CAP KI(KC_H) // Alt 0194 A circumflex -#define WIN_A_TILDE_CAP KI(KC_I) // Alt 0195 A tilde -#define WIN_A_UMLAU_CAP KI(KC_J) // Alt 0196 A umlaut - -#define WIN_C_CEDIL KI(KC_K) // Alt 0231 c cedilla -#define WIN_C_CEDIL_CAP KI(KC_L) // Alt 0199 C cedilla - -#define WIN_E_GRAVE KI(KC_M) // Alt 0232 e grave -#define WIN_E_ACUTE KI(KC_N) // Alt 0233 e acute -#define WIN_E_CIRCU KI(KC_O) // Alt 0234 e circumflex -#define WIN_E_UMLAU KI(KC_P) // Alt 0235 e umlaut - -#define WIN_E_GRAVE_CAP KI(KC_Q) // Alt 0200 E grave -#define WIN_E_ACUTE_CAP KI(KC_R) // Alt 0201 E acute -#define WIN_E_CIRCU_CAP KI(KC_S) // Alt 0202 E circumflex -#define WIN_E_UMLAU_CAP KI(KC_T) // Alt 0203 E umlaut - -#define WIN_I_GRAVE KI(KC_U) // Alt 0236 i grave -#define WIN_I_ACUTE KI(KC_V) // Alt 0237 i acute -#define WIN_I_CIRCU KI(KC_W) // Alt 0238 i circumflex -#define WIN_I_UMLAU KI(KC_X) // Alt 0239 i umlaut - -#define WIN_I_GRAVE_CAP KI(KC_Y) // Alt 0204 I grave -#define WIN_I_ACUTE_CAP KI(KC_Z) // Alt 0205 I acute -#define WIN_I_CIRCU_CAP KI(KC_DOT) // Alt 0206 I circumflex -#define WIN_I_UMLAU_CAP KI(KC_COMMA) // Alt 0207 I umlaut - -#define WIN_N_TILDE KI(KC_SPACE) // Alt 164 n tilde -#define WIN_N_TILDE_CAP KI(KC_BSPACE) // Alt 165 N tilde - -#define WIN_O_GRAVE KI(KC_1) // Alt 0242 o grave -#define WIN_O_ACUTE KI(KC_2) // Alt 0243 o acute -#define WIN_O_CIRCU KI(KC_3) // Alt 0244 o circumflex -#define WIN_O_TILDE KI(KC_4) // Alt 0245 o tilde -#define WIN_O_UMLAU KI(KC_5) // Alt 0246 o umlaut - -#define WIN_O_GRAVE_CAP KI(KC_6) // Alt 0210 O grave -#define WIN_O_ACUTE_CAP KI(KC_7) // Alt 0211 O acute -#define WIN_O_CIRCU_CAP KI(KC_8) // Alt 0212 O circumflex -#define WIN_O_TILDE_CAP KI(KC_9) // Alt 0213 O tilde -#define WIN_O_UMLAU_CAP KI(KC_0) // Alt 0214 O umlaut - -#define WIN_S_CARON KI(KC_MINUS) // Alt 0154 s caron -#define WIN_S_CARON_CAP KI(KC_EQUAL) // Alt 0138 S caron - -#define WIN_U_GRAVE KI(KC_F1) // Alt 0249 u grave -#define WIN_U_ACUTE KI(KC_F2) // Alt 0250 u acute -#define WIN_U_CIRCU KI(KC_F3) // Alt 0251 u circumflex -#define WIN_U_UMLAU KI(KC_F4) // Alt 0252 u umlaut - -#define WIN_U_GRAVE_CAP KI(KC_F5) // Alt 0217 U grave -#define WIN_U_ACUTE_CAP KI(KC_F6) // Alt 0218 U acute -#define WIN_U_CIRCU_CAP KI(KC_F7) // Alt 0219 U circumflex -#define WIN_U_UMLAU_CAP KI(KC_F8) // Alt 0220 U umlaut - -#define WIN_Y_ACUTE KI(KC_F9) // Alt 0253 y acute -#define WIN_Y_UMLAU KI(KC_F10) // Alt 0255 y umlaut - -#define WIN_Y_ACUTE_CAP KI(KC_F11) // Alt 0221 Y tilde -#define WIN_Y_UMLAU_CAP KI(KC_F12) // Alt 0159 Y umlaut - -#define WIN_Z_CARON KI(KC_F13) // Alt 0154 z caron -#define WIN_Z_CARON_CAP KI(KC_F14) // Alt 0138 Z caron - -#define SYM_DEGREE KI(KC_F15) // alt 0176 degree symbol - -#define EXPAND_ALT_CODE(CODE1, CODE2, CODE3, CODE4) \ - addKeycodeToQueue(CODE1, BIT_LALT); \ - addKeycodeToQueue(CODE2, BIT_LALT); \ - addKeycodeToQueue(CODE3, BIT_LALT); \ - addKeycodeToQueue(CODE4, BIT_LALT); +#define WIN_A_GRAVE KI(KC_A) //Alt 0224 a grave +#define WIN_A_ACUTE KI(KC_B) //Alt 0225 a acute +#define WIN_A_CIRCU KI(KC_C) //Alt 0226 a circumflex +#define WIN_A_TILDE KI(KC_D) //Alt 0227 a tilde +#define WIN_A_UMLAU KI(KC_E) //Alt 0228 a umlaut + +#define WIN_A_GRAVE_CAP KI(KC_F) //Alt 0192 A grave +#define WIN_A_ACUTE_CAP KI(KC_G) //Alt 0193 A acute +#define WIN_A_CIRCU_CAP KI(KC_H) //Alt 0194 A circumflex +#define WIN_A_TILDE_CAP KI(KC_I) //Alt 0195 A tilde +#define WIN_A_UMLAU_CAP KI(KC_J) //Alt 0196 A umlaut + +#define WIN_C_CEDIL KI(KC_K) //Alt 0231 c cedilla +#define WIN_C_CEDIL_CAP KI(KC_L) //Alt 0199 C cedilla + +#define WIN_E_GRAVE KI(KC_M) //Alt 0232 e grave +#define WIN_E_ACUTE KI(KC_N) //Alt 0233 e acute +#define WIN_E_CIRCU KI(KC_O) //Alt 0234 e circumflex +#define WIN_E_UMLAU KI(KC_P) //Alt 0235 e umlaut + +#define WIN_E_GRAVE_CAP KI(KC_Q) //Alt 0200 E grave +#define WIN_E_ACUTE_CAP KI(KC_R) //Alt 0201 E acute +#define WIN_E_CIRCU_CAP KI(KC_S) //Alt 0202 E circumflex +#define WIN_E_UMLAU_CAP KI(KC_T) //Alt 0203 E umlaut + +#define WIN_I_GRAVE KI(KC_U) //Alt 0236 i grave +#define WIN_I_ACUTE KI(KC_V) //Alt 0237 i acute +#define WIN_I_CIRCU KI(KC_W) //Alt 0238 i circumflex +#define WIN_I_UMLAU KI(KC_X) //Alt 0239 i umlaut + +#define WIN_I_GRAVE_CAP KI(KC_Y) //Alt 0204 I grave +#define WIN_I_ACUTE_CAP KI(KC_Z) //Alt 0205 I acute +#define WIN_I_CIRCU_CAP KI(KC_DOT) //Alt 0206 I circumflex +#define WIN_I_UMLAU_CAP KI(KC_COMMA) //Alt 0207 I umlaut + +#define WIN_N_TILDE KI(KC_SPACE) //Alt 164 n tilde +#define WIN_N_TILDE_CAP KI(KC_BSPACE) //Alt 165 N tilde + +#define WIN_O_GRAVE KI(KC_1) //Alt 0242 o grave +#define WIN_O_ACUTE KI(KC_2) //Alt 0243 o acute +#define WIN_O_CIRCU KI(KC_3) //Alt 0244 o circumflex +#define WIN_O_TILDE KI(KC_4) //Alt 0245 o tilde +#define WIN_O_UMLAU KI(KC_5) //Alt 0246 o umlaut + +#define WIN_O_GRAVE_CAP KI(KC_6) //Alt 0210 O grave +#define WIN_O_ACUTE_CAP KI(KC_7) //Alt 0211 O acute +#define WIN_O_CIRCU_CAP KI(KC_8) //Alt 0212 O circumflex +#define WIN_O_TILDE_CAP KI(KC_9) //Alt 0213 O tilde +#define WIN_O_UMLAU_CAP KI(KC_0) //Alt 0214 O umlaut + +#define WIN_S_CARON KI(KC_MINUS) //Alt 0154 s caron +#define WIN_S_CARON_CAP KI(KC_EQUAL) //Alt 0138 S caron + +#define WIN_U_GRAVE KI(KC_F1) //Alt 0249 u grave +#define WIN_U_ACUTE KI(KC_F2) //Alt 0250 u acute +#define WIN_U_CIRCU KI(KC_F3) //Alt 0251 u circumflex +#define WIN_U_UMLAU KI(KC_F4) //Alt 0252 u umlaut + +#define WIN_U_GRAVE_CAP KI(KC_F5) //Alt 0217 U grave +#define WIN_U_ACUTE_CAP KI(KC_F6) //Alt 0218 U acute +#define WIN_U_CIRCU_CAP KI(KC_F7) //Alt 0219 U circumflex +#define WIN_U_UMLAU_CAP KI(KC_F8) //Alt 0220 U umlaut + +#define WIN_Y_ACUTE KI(KC_F9) //Alt 0253 y acute +#define WIN_Y_UMLAU KI(KC_F10) //Alt 0255 y umlaut + +#define WIN_Y_ACUTE_CAP KI(KC_F11) //Alt 0221 Y tilde +#define WIN_Y_UMLAU_CAP KI(KC_F12) //Alt 0159 Y umlaut + +#define WIN_Z_CARON KI(KC_F13) //Alt 0154 z caron +#define WIN_Z_CARON_CAP KI(KC_F14) //Alt 0138 Z caron + +#define SYM_DEGREE KI(KC_F15) //alt 0176 degree symbol + +#define EXPAND_ALT_CODE(CODE1, CODE2, CODE3, CODE4) addKeycodeToQueue(CODE1,BIT_LALT); addKeycodeToQueue(CODE2,BIT_LALT); addKeycodeToQueue(CODE3,BIT_LALT); addKeycodeToQueue(CODE4,BIT_LALT); #endif /* HID_KEYCODES_H */ + diff --git a/firmware/keyboard_config.h b/firmware/keyboard_config.h index 9f6dc310..0f162efa 100644 --- a/firmware/keyboard_config.h +++ b/firmware/keyboard_config.h @@ -7,44 +7,60 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef KEYBOARD_CONFIG_H #define KEYBOARD_CONFIG_H #include "hardware_config.h" + #define KEYBOARD_SIDE SINGLE // CHANGE THIS FOR THE KEYBOARD TO MATCH WHAT IS BEING FLASHED. OPTIONS: LEFT RIGHT SINGLE -#define DEVICE_NAME_R "ErgoTravelBLE_R" /**< Name of device. Will be included in the advertising data. */ -#define DEVICE_NAME_L "ErgoTravelBLE_L" /**< Name of device. Will be included in the advertising data. */ -#define DEVICE_NAME_M "ErgoTravelBLE" /**< Name of device. Will be included in the advertising data. */ +#define DEVICE_NAME_R "ErgoTravelBLE_R" /**< Name of device. Will be included in the advertising data. */ +#define DEVICE_NAME_L "ErgoTravelBLE_L" /**< Name of device. Will be included in the advertising data. */ +#define DEVICE_NAME_M "ErgoTravelBLE" /**< Name of device. Will be included in the advertising data. */ + +#define DEVICE_MODEL "ErgoTravelBLE_V1" /**< Name of device. Will be included in the advertising data. */ + +#define MANUFACTURER_NAME "JPConstantineau.com" /**< Manufacturer. Will be passed to Device Information Service. */ -#define DEVICE_MODEL "ErgoTravelBLE_V1" /**< Name of device. Will be included in the advertising data. */ -#define MANUFACTURER_NAME "JPConstantineau.com" /**< Manufacturer. Will be passed to Device Information Service. */ #if KEYBOARD_SIDE == RIGHT -#define KEYMAP(k00, k01, k02, k03, k04, k05, k06, k10, k11, k12, k13, k14, k15, k16, k20, k21, k22, k23, k24, k25, k26, k30, k31, k32, k33, k34, k35, k36) \ - { \ - {k06, k05, k04, k03, k02, k01, k00}, {k16, k15, k14, k13, k12, k11, k10}, {k26, k25, k24, k23, k22, k21, k20}, { k36, k35, k34, k33, k32, k31, k30 } \ - } +#define KEYMAP( \ + k00, k01, k02, k03, k04, k05, k06, \ + k10, k11, k12, k13, k14, k15, k16, \ + k20, k21, k22, k23, k24, k25, k26, \ + k30, k31, k32, k33, k34, k35, k36 \ +) \ +{ \ + { k06, k05, k04, k03, k02, k01, k00 }, \ + { k16, k15, k14, k13, k12, k11, k10 }, \ + { k26, k25, k24, k23, k22, k21, k20 }, \ + { k36, k35, k34, k33, k32, k31, k30 } \ +} #else -#define KEYMAP(k00, k01, k02, k03, k04, k05, k06, k10, k11, k12, k13, k14, k15, k16, k20, k21, k22, k23, k24, k25, k26, k30, k31, k32, k33, k34, k35, k36) \ - { \ - {k00, k01, k02, k03, k04, k05, k06}, {k10, k11, k12, k13, k14, k15, k16}, {k20, k21, k22, k23, k24, k25, k26}, { k30, k31, k32, k33, k34, k35, k36 } \ - } +#define KEYMAP( \ + k00, k01, k02, k03, k04, k05, k06, \ + k10, k11, k12, k13, k14, k15, k16, \ + k20, k21, k22, k23, k24, k25, k26, \ + k30, k31, k32, k33, k34, k35, k36 \ +) \ +{ \ + { k00, k01, k02, k03, k04, k05, k06 }, \ + { k10, k11, k12, k13, k14, k15, k16 }, \ + { k20, k21, k22, k23, k24, k25, k26 }, \ + { k30, k31, k32, k33, k34, k35, k36 } \ +} #endif diff --git a/firmware/keyboards/4x4Backpack/keymaps/artseyio/keymap.h b/firmware/keyboards/4x4Backpack/keymaps/artseyio/keymap.h index cc073884..2253c465 100644 --- a/firmware/keyboards/4x4Backpack/keymaps/artseyio/keymap.h +++ b/firmware/keyboards/4x4Backpack/keymaps/artseyio/keymap.h @@ -18,17 +18,19 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P */ #include +#include #include "hid_keycodes.h" #include "keyboard_config.h" #include "advanced_keycodes.h" #include "Key.h" -#include +#define ENABLE_COMBOS #include "combo_engine.h" #ifndef KEYMAP_H #define KEYMAP_H + #define NUM_LAYERS 6 #define _L0 0 diff --git a/firmware/keyboards/4x4Backpack/keymaps/testbench6/keymap.h b/firmware/keyboards/4x4Backpack/keymaps/testbench6/keymap.h index 2771f8f0..9dd81071 100644 --- a/firmware/keyboards/4x4Backpack/keymaps/testbench6/keymap.h +++ b/firmware/keyboards/4x4Backpack/keymaps/testbench6/keymap.h @@ -29,6 +29,8 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #ifndef KEYMAP_H #define KEYMAP_H +#define ENABLE_COMBOS + #define NUM_LAYERS 2 #define _L0 0 diff --git a/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.cpp b/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.cpp index 55e16af1..e19c8cad 100644 --- a/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.cpp +++ b/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.cpp @@ -43,8 +43,25 @@ void setupKeymap() { RotaryEncoder.setCallback(encoder_callback); // Set callback RotaryEncoder.start(); // Start encoder -resetleds(); +/* +setled(1); delay(100); +setled(2); delay(100); +setled(3); delay(100); +setled(4); delay(100); +setled(5); delay(100); +setled(6); delay(100); +setled(7); delay(100); +setled(8); delay(100); +setled(9); delay(100);*/ +resetleds(); +/* + speaker.playNoteNow(NOTE_G4, EIGHTH_TRIPLE, true); + speaker.playNoteNow(NOTE_C5, EIGHTH_TRIPLE, true); + speaker.playNoteNow(NOTE_E5, EIGHTH_TRIPLE, false); + speaker.playNoteNow(NOTE_G5, EIGHTH, true); + speaker.playNoteNow(NOTE_E5, SIXTEENTH, false); + speaker.playNoteNow(NOTE_G5, HALF, false);*/ } void resetleds () @@ -63,6 +80,72 @@ resetleds(); digitalWrite(LEDROW2, LOW); } + void setled(int lednumber) + { + +switch ((lednumber)) + { + case 0: + resetleds(); + break; + case 1: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW0, HIGH); + break; + case 2: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW1, HIGH); + break; + case 3: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW2, HIGH); + break; + case 4: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL1, INPUT); + digitalWrite(LEDROW0, HIGH); + break; + case 5: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL1, INPUT); + digitalWrite(LEDROW1, HIGH); + break; + case 6: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL1, INPUT); + digitalWrite(LEDROW2, HIGH); + break; + case 7: + resetleds(); + pinMode(LEDCOL1, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW0, HIGH); + break; + case 8: + resetleds(); + pinMode(LEDCOL1, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW1, HIGH); + break; + case 9: + resetleds(); + pinMode(LEDCOL1, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW2, HIGH); + break; + } + + } + void encoder_callback(int step) { keyboardstate.encoder1pos = keyboardstate.encoder1pos + step; @@ -102,42 +185,22 @@ void process_user_macros(uint16_t macroid) { case MODE0: keyboardstate.user1 = 0; - resetleds(); break; case MODE1: - keyboardstate.user1 = 1; - resetleds(); - pinMode(LEDCOL0, INPUT); - pinMode(LEDCOL2, INPUT); - digitalWrite(LEDROW0, HIGH); + keyboardstate.user1 = 1; break; case MODE2: keyboardstate.user1 = 2; - resetleds(); - pinMode(LEDCOL0, INPUT); - pinMode(LEDCOL2, INPUT); - digitalWrite(LEDROW1, HIGH); break; case MODE3: keyboardstate.user1 = 3; - resetleds(); - pinMode(LEDCOL0, INPUT); - pinMode(LEDCOL2, INPUT); - digitalWrite(LEDROW2, HIGH); break; case MODE4: keyboardstate.user1 = 4; - resetleds(); - pinMode(LEDCOL0, INPUT); - pinMode(LEDCOL1, INPUT); - digitalWrite(LEDROW0, HIGH); break; case MODE5: keyboardstate.user1 = 0; - resetleds(); - pinMode(LEDCOL0, INPUT); - pinMode(LEDCOL1, INPUT); - digitalWrite(LEDROW1, HIGH); break; } + setled(keyboardstate.user1); } \ No newline at end of file diff --git a/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.h b/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.h index 2746c44e..bea37f90 100644 --- a/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.h +++ b/firmware/keyboards/CNCEncoderPad/keymaps/resolve/keymap.h @@ -27,7 +27,9 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #include "RotaryEncoder.h" #ifndef KEYMAP_H #define KEYMAP_H - +#define ENABLE_AUDIO +#include "BlueMicro_tone.h" +extern BlueMicro_tone speaker; #define NUM_LAYERS 2 #define _L0 0 @@ -45,6 +47,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P void setupKeymap(); void encoder_callback(int step); void resetleds (void); +void setled(int lednumber); extern std::array, MATRIX_ROWS> matrix; extern DynamicState keyboardstate; diff --git a/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.cpp b/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.cpp index 6b27a373..feeb9586 100644 --- a/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.cpp +++ b/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.cpp @@ -24,11 +24,30 @@ std::array, MATRIX_ROWS> matrix = void setupKeymap() { ; -// Code below makes sure that the encoder gets configured. - + // Code below makes sure that the encoder gets configured. RotaryEncoder.begin(ENCODER_PAD_A, ENCODER_PAD_B); // Initialize Encoder RotaryEncoder.setCallback(encoder_callback); // Set callback - RotaryEncoder.start(); // Start encoder + RotaryEncoder.start(); // Start encoder + + // flash the leds in sequence to make sure they run fine... + setled(1); delay(100); + setled(2); delay(100); + setled(3); delay(100); + setled(4); delay(100); + setled(5); delay(100); + setled(6); delay(100); + setled(7); delay(100); + setled(8); delay(100); + setled(9); delay(100); + resetleds(); + + // Play an obvious tune to check that speaker/buzzer works fine... + speaker.playNoteNow(NOTE_G4, EIGHTH_TRIPLE, true); + speaker.playNoteNow(NOTE_C5, EIGHTH_TRIPLE, true); + speaker.playNoteNow(NOTE_E5, EIGHTH_TRIPLE, false); + speaker.playNoteNow(NOTE_G5, EIGHTH, true); + speaker.playNoteNow(NOTE_E5, SIXTEENTH, false); + speaker.playNoteNow(NOTE_G5, HALF, false); } @@ -43,7 +62,7 @@ void encoder_callback(int step) { switch(layer) { - case _L0: KeyScanner::add_to_encoderKeys(KC_AUDIO_VOL_UP); break; + case _L0: KeyScanner::add_to_encoderKeys(LSFT(KC_DOT)); break; case _L1: KeyScanner::add_to_encoderKeys(KC_RIGHT); break; case _L2: KeyScanner::add_to_encoderKeys(LSFT(KC_RIGHT)); break; default: ; @@ -53,7 +72,7 @@ void encoder_callback(int step) { switch(layer) { - case _L0: KeyScanner::add_to_encoderKeys(KC_AUDIO_VOL_DOWN); break; + case _L0: KeyScanner::add_to_encoderKeys(LSFT(KC_COMMA)); break; case _L1: KeyScanner::add_to_encoderKeys(KC_LEFT);break; case _L2: KeyScanner::add_to_encoderKeys(LSFT(KC_LEFT));break; default: ; @@ -62,3 +81,84 @@ void encoder_callback(int step) keyboardstate.encoder1pos = 0; } } + +// Utility functions to handle LEDs + void resetleds () + { + pinMode(LEDCOL0, OUTPUT); + pinMode(LEDCOL1, OUTPUT); + pinMode(LEDCOL2, OUTPUT); + pinMode(LEDROW0, OUTPUT); + pinMode(LEDROW1, OUTPUT); + pinMode(LEDROW2, OUTPUT); + digitalWrite(LEDCOL0, LOW); + digitalWrite(LEDCOL1, LOW); + digitalWrite(LEDCOL2, LOW); + digitalWrite(LEDROW0, LOW); + digitalWrite(LEDROW1, LOW); + digitalWrite(LEDROW2, LOW); + } + + void setled(int lednumber) + { + switch ((lednumber)) + { + case 0: + resetleds(); + break; + case 1: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW0, HIGH); + break; + case 2: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW1, HIGH); + break; + case 3: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW2, HIGH); + break; + case 4: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL1, INPUT); + digitalWrite(LEDROW0, HIGH); + break; + case 5: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL1, INPUT); + digitalWrite(LEDROW1, HIGH); + break; + case 6: + resetleds(); + pinMode(LEDCOL0, INPUT); + pinMode(LEDCOL1, INPUT); + digitalWrite(LEDROW2, HIGH); + break; + case 7: + resetleds(); + pinMode(LEDCOL1, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW0, HIGH); + break; + case 8: + resetleds(); + pinMode(LEDCOL1, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW1, HIGH); + break; + case 9: + resetleds(); + pinMode(LEDCOL1, INPUT); + pinMode(LEDCOL2, INPUT); + digitalWrite(LEDROW2, HIGH); + break; + } + } \ No newline at end of file diff --git a/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.h b/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.h index 55c84af3..527a1c40 100644 --- a/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.h +++ b/firmware/keyboards/CNCEncoderPad/keymaps/test/keymap.h @@ -27,6 +27,9 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #include "RotaryEncoder.h" #ifndef KEYMAP_H #define KEYMAP_H +#define ENABLE_AUDIO +#include "BlueMicro_tone.h" +extern BlueMicro_tone speaker; #define NUM_LAYERS 2 @@ -36,6 +39,8 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P void setupKeymap(); void encoder_callback(int step); +void resetleds (void); +void setled(int lednumber); extern std::array, MATRIX_ROWS> matrix; extern DynamicState keyboardstate; #endif /* KEYMAP_H */ diff --git a/firmware/keyboards/blue_wizard/keymaps/default/keymap.h b/firmware/keyboards/blue_wizard/keymaps/default/keymap.h index 8ce13612..bdea2f10 100644 --- a/firmware/keyboards/blue_wizard/keymaps/default/keymap.h +++ b/firmware/keyboards/blue_wizard/keymaps/default/keymap.h @@ -21,7 +21,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #include "hid_keycodes.h" #include "keyboard_config.h" #include "advanced_keycodes.h" -#define MAX_NO_LAYERS 5 //needs to be one greater than the number of layers implimented. Too large of a number will cause crashing due to dynamic memory limits. +#define MAX_NO_LAYERS 3 //needs to be one greater than the number of layers implimented. Too large of a number will cause crashing due to dynamic memory limits. #include "Key.h" #include diff --git a/firmware/keyboards/cradio/hardware/pca10056/nicenano/hardware_config.h b/firmware/keyboards/cradio/hardware/pca10056/nicenano/hardware_config.h index 6d1a077f..3a505752 100644 --- a/firmware/keyboards/cradio/hardware/pca10056/nicenano/hardware_config.h +++ b/firmware/keyboards/cradio/hardware/pca10056/nicenano/hardware_config.h @@ -28,7 +28,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define MATRIX_COL_PINS { 11, 47, 2, 29, 31, 45, 43, 10, 9, 6, 17, 20, 22, 24, 32, 36, 38} #define UNUSED_PINS {} - +#define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -37,4 +37,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define VBAT_PIN 4 #define VCC_PIN 13 #define VCC_POLARITY_ON 0 + + #define STATUS_BLE_LED_PIN 15 //blue = 0.15 + #endif /* HARDWARE_CONFIG_H */ diff --git a/firmware/keyboards/crkbd/hardware/pca10056/nicenano/hardware_config.h b/firmware/keyboards/crkbd/hardware/pca10056/nicenano/hardware_config.h index 39349a0e..2c4bc3fe 100644 --- a/firmware/keyboards/crkbd/hardware/pca10056/nicenano/hardware_config.h +++ b/firmware/keyboards/crkbd/hardware/pca10056/nicenano/hardware_config.h @@ -27,6 +27,8 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define MATRIX_ROW_PINS { 22, 24, 32, 11 } #define MATRIX_COL_PINS { 31, 29, 2, 47, 45, 43 } +#define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) + #define UNUSED_PINS {} /* COL2ROW or ROW2COL */ @@ -37,8 +39,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define WS2812B_LED_COUNT 27 #define WS2812B_LED_ON 1 #define BATTERY_TYPE BATT_LIPO - #define VBAT_PIN 4 - #define STATUS_BLE_LED_PIN 19 //blue = 0.19 + #define STATUS_KB_LED_PIN 17 //red = 0.17 #define VCC_PIN 13 #define VCC_POLARITY_ON 0 diff --git a/firmware/keyboards/dactyl_manuform5x6/hardware/pca10056/nicenano/hardware_config.h b/firmware/keyboards/dactyl_manuform5x6/hardware/pca10056/nicenano/hardware_config.h index 32106943..2ef8a162 100644 --- a/firmware/keyboards/dactyl_manuform5x6/hardware/pca10056/nicenano/hardware_config.h +++ b/firmware/keyboards/dactyl_manuform5x6/hardware/pca10056/nicenano/hardware_config.h @@ -46,5 +46,5 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define STATUS_BLE_LED_PIN 15 //blue = 0.15 //#define STATUS_KB_LED_PIN 0 //no RED LED - + #define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) #endif /* HARDWARE_CONFIG_H */ \ No newline at end of file diff --git a/firmware/keyboards/dactyl_manuform6x6/hardware/pca10056/nicenano/hardware_config.h b/firmware/keyboards/dactyl_manuform6x6/hardware/pca10056/nicenano/hardware_config.h index 1858dd8a..b1cccc5a 100644 --- a/firmware/keyboards/dactyl_manuform6x6/hardware/pca10056/nicenano/hardware_config.h +++ b/firmware/keyboards/dactyl_manuform6x6/hardware/pca10056/nicenano/hardware_config.h @@ -39,6 +39,9 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define WS2812B_LED_COUNT 12 #define WS2812B_LED_ON 0 // LEDs are disabled by default + + #define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) + #define BATTERY_TYPE BATT_LIPO #define VBAT_PIN 4 #define VCC_PIN 13 diff --git a/firmware/keyboards/helix/hardware/pca10056/nice_nano/hardware_config.h b/firmware/keyboards/helix/hardware/pca10056/nice_nano/hardware_config.h index 1bba7af6..31a222e1 100644 --- a/firmware/keyboards/helix/hardware/pca10056/nice_nano/hardware_config.h +++ b/firmware/keyboards/helix/hardware/pca10056/nice_nano/hardware_config.h @@ -46,6 +46,10 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define VCC_POLARITY_ON 0 #define STATUS_BLE_LED_PIN 15 //blue = 0.15 //#define STATUS_KB_LED_PIN 0 //no RED LED + + #define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) + + // OLED DEFINITION #define I2C_SDA_PIN 17 #define I2C_SCK_PIN 20 diff --git a/firmware/keyboards/lily58/hardware/pca10056/nice_nano/hardware_config.h b/firmware/keyboards/lily58/hardware/pca10056/nice_nano/hardware_config.h index 85661172..6d3df745 100644 --- a/firmware/keyboards/lily58/hardware/pca10056/nice_nano/hardware_config.h +++ b/firmware/keyboards/lily58/hardware/pca10056/nice_nano/hardware_config.h @@ -45,6 +45,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define VCC_POLARITY_ON 0 #define STATUS_BLE_LED_PIN 15 //blue = 0.15 //#define STATUS_KB_LED_PIN 0 //no RED LED +#define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) // OLED DEFINITION #define I2C_SDA_PIN 17 diff --git a/firmware/keyboards/luddite/keymaps/default/keymap.cpp b/firmware/keyboards/luddite/keymaps/default/keymap.cpp index 1779920b..c29508bb 100644 --- a/firmware/keyboards/luddite/keymaps/default/keymap.cpp +++ b/firmware/keyboards/luddite/keymaps/default/keymap.cpp @@ -98,16 +98,19 @@ void process_user_macros(uint16_t macroid) case CHARGE: // Play a little charge melody, from: // https://en.wikipedia.org/wiki/Charge_(fanfare) + #ifdef ENABLE_AUDIO speaker.playNoteNow(NOTE_G4, EIGHTH_TRIPLE, true); speaker.playNoteNow(NOTE_C5, EIGHTH_TRIPLE, true); speaker.playNoteNow(NOTE_E5, EIGHTH_TRIPLE, false); speaker.playNoteNow(NOTE_G5, EIGHTH, true); speaker.playNoteNow(NOTE_E5, SIXTEENTH, false); speaker.playNoteNow(NOTE_G5, HALF, false); + #endif break; case BIRTHDAY: // Play happy birthday tune, from: // http://www.irish-folk-songs.com/happy-birthday-tin-whistle-sheet-music.html#.WXFJMtPytBw + #ifdef ENABLE_AUDIO speaker.playNoteNow(NOTE_D4, EIGHTH, true); speaker.playNoteNow(NOTE_D4, EIGHTH); speaker.playNoteNow(NOTE_E4, QUARTER); // Bar 1 @@ -133,6 +136,7 @@ void process_user_macros(uint16_t macroid) speaker.playNoteNow(NOTE_G4, QUARTER); speaker.playNoteNow(NOTE_A4, QUARTER); speaker.playNoteNow(NOTE_G4, HALF); // Bar 8 + #endif break; } } diff --git a/firmware/keyboards/luddite/keymaps/default/keymap.h b/firmware/keyboards/luddite/keymaps/default/keymap.h index e518675a..fc052d45 100644 --- a/firmware/keyboards/luddite/keymaps/default/keymap.h +++ b/firmware/keyboards/luddite/keymaps/default/keymap.h @@ -23,6 +23,8 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #include "advanced_keycodes.h" #include "Key.h" #include + +#define ENABLE_AUDIO #include "BlueMicro_tone.h" #ifndef KEYMAP_H @@ -44,7 +46,9 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P #define CHARGE MC(KC_Y) #define BIRTHDAY MC(KC_Z) +#ifdef ENABLE_AUDIO extern BlueMicro_tone speaker; +#endif void setupKeymap(); extern std::array, MATRIX_ROWS> matrix; diff --git a/firmware/keyboards/semaphore/hardware/pca10056/nicenano/hardware_config.h b/firmware/keyboards/semaphore/hardware/pca10056/nicenano/hardware_config.h index 9afa5852..b158335c 100644 --- a/firmware/keyboards/semaphore/hardware/pca10056/nicenano/hardware_config.h +++ b/firmware/keyboards/semaphore/hardware/pca10056/nicenano/hardware_config.h @@ -25,7 +25,7 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P /* key matrix size */ #define MATRIX_ROWS 5 #define MATRIX_COLS 6 -#define NICENANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) +#define ARDUINO_NICE_NANO 1 // used in debug_cli.cpp to bypass 0.14 and 0.16 that are directly connected to 0.18 (reset) #define MATRIX_ROW_PINS {10, 9, 22, 24, 32 } #define MATRIX_COL_PINS {31, 29, 2, 47, 45, 43 } diff --git a/firmware/keymap.cpp b/firmware/keymap.cpp index 7322dc7b..eae61ce7 100644 --- a/firmware/keymap.cpp +++ b/firmware/keymap.cpp @@ -7,173 +7,225 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "keymap.h" // Initialize matrix with nothing... std::array, MATRIX_ROWS> matrix = - KEYMAP2ARRAY(KEYMAP(KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO)); + KEYMAP2ARRAY(KEYMAP( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO + )); + void setupKeymap() { - // no layers for single keymap - // this is a keymap that's used for testing that each key is responding properly to key presses - // flash this keymap to both left and right to test whether each half works properly. - // once tested, you can flash the left and right to their respective halves. - uint32_t layer0_single[MATRIX_ROWS][MATRIX_COLS] = KEYMAP(KC_1, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_2, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_3, KC_Z, - KC_X, KC_C, KC_V, KC_B, KC_N, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0); - - /* Qwerty LEFT - * ,------------------------------------------------. - * | Esc | Q | W | E | R | T | Y* | - * |------+------+------+------+------+-------------| - * | Tab | A | S | D | F | G | H* | - * |------+------+------+------+------+------|------| - * | Shift| Z | X | C | V | B |Space | - * |------+------+------+------+------+------+------' - * | Ctrl | GUI | Alt | L(3) | L(1) |Space | - * `-----------------------------------------' - */ - - uint32_t layer0_left[MATRIX_ROWS][MATRIX_COLS] = KEYMAP(PRINT_BLE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_LSFT, - KC_Z, KC_X, KC_C, KC_V, KC_B, KC_SPC, KC_LCTL, KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC, _______); - - /* Qwerty RIGHT - * ,------------------------------------------------. - * | = | Y | U | I | O | P | Bksp | - * |------+------+------+------+------+-------------| - * | \ | H | J | K | L | ; | ' | - * |------+------+------+------+------+------|------| - * | Space| N | M | , | . | / |Enter | - * `------+------+------+------+------+------+------| - * | Space| L(2) | Left | Down | Up |Right | - * `-----------------------------------------' - */ - - uint32_t layer0_right[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_EQUAL, KC_Y, KC_U, KC_I, KC_O, KC_P, PRINT_BLE, KC_BSLS, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, KC_SPC, KC_N, KC_M, KC_COMMA, KC_DOT, - KC_SLSH, KC_ENT, _______, KC_SPC, LAYER_2, KC_LEFT, KC_UP, KC_DOWN, KC_RIGHT); - - /* Layer 1 (Raise) LEFT - * ,------------------------------------------------. - * | ` | 1 | 2 | 3 | 4 | 5 | - | - * |------+------+------+------+------+-------------| - * | Del | F1 | F2 | F3 | F4 | F5 | [ | - * |------+------+------+------+------+------|------| - * | Shift| F7 | F8 | F9 | F10 | F11 |Space | - * |------+------+------+------+------+------+------' - * | Ctrl | GUI | Alt | L(3) | L(1) |Space | - * `-----------------------------------------' - */ - uint32_t layer1_left[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_MINUS, KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_LBRC, KC_LSFT, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, - KC_SPC, KC_LCTL, KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC, _______); - - /* Layer 1 (Raise) RIGHT - * ,------------------------------------------------. - * | + | 6 | 7 | 8 | 9 | 0 | Del | - * |------+------+------+------+------+-------------| - * | ] | F6 | - | = | [ | ] | \ | - * |------+------+------+------+------+------|------| - * | Space| F12 | ~ | | | _ | _ |Enter | - * `------+------+------+------+------+------+------| - * | Space| L(2)*| Left | Down | Up |Right | - * `-----------------------------------------' - */ - uint32_t layer1_right[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_PLUS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, KC_RBRC, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, KC_SPC, KC_F12, KC_TILD, KC_PIPE, - KC_UNDS, KC_UNDS, KC_ENTER, _______, KC_SPC, LAYER_2, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT); - - /* Layer 2 (lower) LEFT - * ,------------------------------------------------. - * | ~ | ! | @ | # | $ | % | _ | - * |------+------+------+------+------+-------------| - * | Del | F1 | F2 | F3 | F4 | F5 | ( | - * |------+------+------+------+------+------|------| - * | Shift| F7 | F8 | F9 | F10 | F11 |Space | - * |------+------+------+------+------+------+------' - * | Ctrl | GUI | Alt | L(3) | L(1) |Space | - * `-----------------------------------------' - */ - uint32_t layer2_left[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_UNDS, KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_LPRN, KC_LSFT, KC_F7, KC_F8, KC_F9, - KC_F10, KC_F11, KC_SPC, KC_LCTL, KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC, _______); - - /* Layer 2 (lower) RIGHT - * ,------------------------------------------------. - * | = | ^ | & | * | ( | ) | Del | - * |------+------+------+------+------+-------------| - * | ) | F6 | _ | + | { | } | | | - * |------+------+------+------+------+------|------| - * | Space| F12 |ISO ~ |ISO | | [ | ] |ENTER | - * `------+------+------+------+------+------+------| - * | Space| L(2)*| Left | Down | Up |Right | - * `-----------------------------------------' - */ - uint32_t layer2_right[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_EQUAL, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, KC_RPRN, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, KC_SPC, KC_F12, - KC_NUTL, KC_NUPI, KC_LBRC, KC_RBRC, KC_ENTER, _______, KC_SPC, LAYER_2, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT); - - /* Layer 3 LEFT - * ,------------------------------------------------. - * | ESC* | F1 | F2 | F3 | F4 | F5 |PRTSCR| - * |------+------+------+------+------+-------------| - * | CAPL*| PUP* | NEXT*| PLAY*| PREV*| VOL+*| MUTE*| - * |------+------+------+------+------+------|------| - * | Shift|PDOWN*| INS* | HOME*| END* | VOL-*|Space | - * |------+------+------+------+------+------+------' - * | Ctrl | GUI | Alt | L(3) | L(1) |Space | - * `-----------------------------------------' - */ - uint32_t layer3_left[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_PSCREEN, KC_CAPSLOCK, KC_PGUP, KC_MEDIA_NEXT_TRACK, KC_MEDIA_PLAY_PAUSE, KC_MEDIA_PREV_TRACK, - KC_VOLU, KC_MUTE, KC_LSFT, KC_PGDN, KC_INS, KC_HOME, KC_END, KC_VOLD, KC_SPC, KC_LCTL, KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC, _______); - - /* Layer 3 RIGHT - * ,------------------------------------------------. - * |NULOCK| F6 | F7 | F8 | F9 | F10 | NUM- | - * |------+------+------+------+------+-------------| - * | | NUM1 | NUM2 | NUM3 | NUM4 | NUM5 | NUM+ | - * |------+------+------+------+------+------|------| - * | Space| NUM6 | NUM7 | NUM8 | NUM9 | NUM10|NENTER| - * `------+------+------+------+------+------+------| - * | Space| L(2)*|NUMINS| NUM. | NUM* | NUM/ | - * `-----------------------------------------' - */ - uint32_t layer3_right[MATRIX_ROWS][MATRIX_COLS] = - KEYMAP(KC_NUMLOCK, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_KP_MINUS, XXXXXXX, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_4, KC_KP_5, KC_KP_PLUS, KC_SPC, KC_KP_6, - KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_0, KC_KP_ENTER, _______, KC_SPC, LAYER_2, KC_INSERT, KC_KP_DOT, KC_KP_ASTERISK, KC_KP_SLASH); - - for (int row = 0; row < MATRIX_ROWS; ++row) { - for (int col = 0; col < MATRIX_COLS; ++col) { -#if KEYBOARD_SIDE == SINGLE - matrix[row][col].addActivation(_L0, Method::PRESS, layer0_single[row][col]); -#endif -#if KEYBOARD_SIDE == LEFT - matrix[row][col].addActivation(_L0, Method::PRESS, layer0_left[row][col]); - matrix[row][col].addActivation(_L1, Method::PRESS, layer1_left[row][col]); - matrix[row][col].addActivation(_L2, Method::PRESS, layer2_left[row][col]); - matrix[row][col].addActivation(_L3, Method::PRESS, layer3_left[row][col]); -#endif -#if KEYBOARD_SIDE == RIGHT - matrix[row][col].addActivation(_L0, Method::PRESS, layer0_right[row][col]); - matrix[row][col].addActivation(_L1, Method::PRESS, layer1_right[row][col]); - matrix[row][col].addActivation(_L2, Method::PRESS, layer2_right[row][col]); - matrix[row][col].addActivation(_L3, Method::PRESS, layer3_right[row][col]); -#endif - // if you want to add Tap/Hold or Tap/Doubletap activations, then you add them below. + // no layers for single keymap + // this is a keymap that's used for testing that each key is responding properly to key presses + // flash this keymap to both left and right to test whether each half works properly. + // once tested, you can flash the left and right to their respective halves. + uint32_t layer0_single[MATRIX_ROWS][MATRIX_COLS] = KEYMAP( + KC_1, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, + KC_2, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, + KC_3, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, + KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0 + ); + + +/* Qwerty LEFT + * ,------------------------------------------------. + * | Esc | Q | W | E | R | T | Y* | + * |------+------+------+------+------+-------------| + * | Tab | A | S | D | F | G | H* | + * |------+------+------+------+------+------|------| + * | Shift| Z | X | C | V | B |Space | + * |------+------+------+------+------+------+------' + * | Ctrl | GUI | Alt | L(3) | L(1) |Space | + * `-----------------------------------------' + */ + +uint32_t layer0_left[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( + PRINT_BLE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, + KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_SPC, + KC_LCTL, KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC,_______ + ); + + /* Qwerty RIGHT + * ,------------------------------------------------. + * | = | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+-------------| + * | \ | H | J | K | L | ; | ' | + * |------+------+------+------+------+------|------| + * | Space| N | M | , | . | / |Enter | + * `------+------+------+------+------+------+------| + * | Space| L(2) | Left | Down | Up |Right | + * `-----------------------------------------' + */ + +uint32_t layer0_right[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( + KC_EQUAL, KC_Y, KC_U, KC_I, KC_O, KC_P, PRINT_BLE, + KC_BSLS, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, + KC_SPC, KC_N, KC_M, KC_COMMA,KC_DOT, KC_SLSH, KC_ENT, + _______, KC_SPC, LAYER_2, KC_LEFT, KC_UP, KC_DOWN, KC_RIGHT + ); + + + + /* Layer 1 (Raise) LEFT + * ,------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | - | + * |------+------+------+------+------+-------------| + * | Del | F1 | F2 | F3 | F4 | F5 | [ | + * |------+------+------+------+------+------|------| + * | Shift| F7 | F8 | F9 | F10 | F11 |Space | + * |------+------+------+------+------+------+------' + * | Ctrl | GUI | Alt | L(3) | L(1) |Space | + * `-----------------------------------------' + */ + uint32_t layer1_left[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( \ + KC_GRAVE,KC_1, KC_2, KC_3, KC_4, KC_5, KC_MINUS, \ + KC_DEL ,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 , KC_LBRC, \ + KC_LSFT ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,KC_F11 , KC_SPC, \ + KC_LCTL , KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC,_______ \ + ); + + + /* Layer 1 (Raise) RIGHT + * ,------------------------------------------------. + * | + | 6 | 7 | 8 | 9 | 0 | Del | + * |------+------+------+------+------+-------------| + * | ] | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------|------| + * | Space| F12 | ~ | | | _ | _ |Enter | + * `------+------+------+------+------+------+------| + * | Space| L(2)*| Left | Down | Up |Right | + * `-----------------------------------------' + */ + uint32_t layer1_right[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( \ + KC_PLUS, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \ + KC_RBRC, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \ + KC_SPC, KC_F12, KC_TILD, KC_PIPE, KC_UNDS, KC_UNDS, KC_ENTER, \ + _______, KC_SPC, LAYER_2, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT \ + ); + + /* Layer 2 (lower) LEFT + * ,------------------------------------------------. + * | ~ | ! | @ | # | $ | % | _ | + * |------+------+------+------+------+-------------| + * | Del | F1 | F2 | F3 | F4 | F5 | ( | + * |------+------+------+------+------+------|------| + * | Shift| F7 | F8 | F9 | F10 | F11 |Space | + * |------+------+------+------+------+------+------' + * | Ctrl | GUI | Alt | L(3) | L(1) |Space | + * `-----------------------------------------' + */ + uint32_t layer2_left[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( \ + KC_TILD ,KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_UNDS, \ + KC_DEL ,KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_LPRN, \ + KC_LSFT ,KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_SPC, \ + KC_LCTL ,KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC, _______ \ + ); + +/* Layer 2 (lower) RIGHT + * ,------------------------------------------------. + * | = | ^ | & | * | ( | ) | Del | + * |------+------+------+------+------+-------------| + * | ) | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------|------| + * | Space| F12 |ISO ~ |ISO | | [ | ] |ENTER | + * `------+------+------+------+------+------+------| + * | Space| L(2)*| Left | Down | Up |Right | + * `-----------------------------------------' + */ + uint32_t layer2_right[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( \ + KC_EQUAL, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \ + KC_RPRN, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \ + KC_SPC, KC_F12, KC_NUTL, KC_NUPI, KC_LBRC, KC_RBRC, KC_ENTER, \ + _______, KC_SPC, LAYER_2, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT \ + ); + +/* Layer 3 LEFT + * ,------------------------------------------------. + * | ESC* | F1 | F2 | F3 | F4 | F5 |PRTSCR| + * |------+------+------+------+------+-------------| + * | CAPL*| PUP* | NEXT*| PLAY*| PREV*| VOL+*| MUTE*| + * |------+------+------+------+------+------|------| + * | Shift|PDOWN*| INS* | HOME*| END* | VOL-*|Space | + * |------+------+------+------+------+------+------' + * | Ctrl | GUI | Alt | L(3) | L(1) |Space | + * `-----------------------------------------' + */ + uint32_t layer3_left[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( \ + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_PSCREEN, \ + KC_CAPSLOCK, KC_PGUP, KC_MEDIA_NEXT_TRACK,KC_MEDIA_PLAY_PAUSE, KC_MEDIA_PREV_TRACK, KC_VOLU, KC_MUTE, \ + KC_LSFT, KC_PGDN, KC_INS, KC_HOME, KC_END, KC_VOLD, KC_SPC, \ + KC_LCTL , KC_LGUI, KC_LALT, LAYER_3, LAYER_1, KC_SPC, _______ \ + ); + + /* Layer 3 RIGHT + * ,------------------------------------------------. + * |NULOCK| F6 | F7 | F8 | F9 | F10 | NUM- | + * |------+------+------+------+------+-------------| + * | | NUM1 | NUM2 | NUM3 | NUM4 | NUM5 | NUM+ | + * |------+------+------+------+------+------|------| + * | Space| NUM6 | NUM7 | NUM8 | NUM9 | NUM10|NENTER| + * `------+------+------+------+------+------+------| + * | Space| L(2)*|NUMINS| NUM. | NUM* | NUM/ | + * `-----------------------------------------' + */ + uint32_t layer3_right[MATRIX_ROWS][MATRIX_COLS] = + KEYMAP( \ + KC_NUMLOCK, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_KP_MINUS, \ + XXXXXXX, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_4, KC_KP_5, KC_KP_PLUS, \ + KC_SPC , KC_KP_6, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_0, KC_KP_ENTER, \ + _______, KC_SPC, LAYER_2, KC_INSERT, KC_KP_DOT, KC_KP_ASTERISK, KC_KP_SLASH \ + ); + + + for (int row = 0; row < MATRIX_ROWS; ++row) + { + for (int col = 0; col < MATRIX_COLS; ++col) + { + #if KEYBOARD_SIDE == SINGLE + matrix[row][col].addActivation(_L0, Method::PRESS, layer0_single[row][col]); + #endif + #if KEYBOARD_SIDE == LEFT + matrix[row][col].addActivation(_L0, Method::PRESS, layer0_left[row][col]); + matrix[row][col].addActivation(_L1, Method::PRESS, layer1_left[row][col]); + matrix[row][col].addActivation(_L2, Method::PRESS, layer2_left[row][col]); + matrix[row][col].addActivation(_L3, Method::PRESS, layer3_left[row][col]); + #endif + #if KEYBOARD_SIDE == RIGHT + matrix[row][col].addActivation(_L0, Method::PRESS, layer0_right[row][col]); + matrix[row][col].addActivation(_L1, Method::PRESS, layer1_right[row][col]); + matrix[row][col].addActivation(_L2, Method::PRESS, layer2_right[row][col]); + matrix[row][col].addActivation(_L3, Method::PRESS, layer3_right[row][col]); + #endif + // if you want to add Tap/Hold or Tap/Doubletap activations, then you add them below. + + } } - } } + + + + + + diff --git a/firmware/keymap.h b/firmware/keymap.h index 2d22f798..8cbbe5a9 100644 --- a/firmware/keymap.h +++ b/firmware/keymap.h @@ -7,34 +7,31 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "Key.h" -#include "advanced_keycodes.h" -#include "hardware_variants.h" +#include #include "hid_keycodes.h" +#include "hardware_variants.h" #include "keyboard_config.h" +#include "advanced_keycodes.h" +#include "Key.h" #include -#include #ifndef KEYMAP_H #define KEYMAP_H -#define _L0 0 -#define _L1 1 -#define _L2 2 -#define _L3 3 +#define _L0 0 +#define _L1 1 +#define _L2 2 +#define _L3 3 void setupKeymap(); extern std::array, MATRIX_ROWS> matrix; diff --git a/firmware/nrf52battery.cpp b/firmware/nrf52battery.cpp index 72c72f0d..bc90b50c 100644 --- a/firmware/nrf52battery.cpp +++ b/firmware/nrf52battery.cpp @@ -7,95 +7,95 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "nrf52battery.h" /**************************************************************************************************************************/ -BLEBas blebas; // Battery Service - -Battery::Battery() { // Constructor - vbat_raw = 0; - vbat_mv = 0; - vbat_vdd = 0; - vbat_per = 0; - batt_type = BATT_UNKNOWN; - _mvToPercent_cb = mvToPercent_default; + BLEBas blebas; // Battery Service + +Battery::Battery() { // Constructor + vbat_raw = 0; + vbat_mv = 0; + vbat_vdd = 0; + vbat_per = 0; + batt_type = BATT_UNKNOWN; + _mvToPercent_cb = mvToPercent_default; } + /**************************************************************************************************************************/ -uint32_t Battery::analogReadVDD() { +uint32_t Battery::analogReadVDD() +{ // thanks to vladkozlov69 on github. // from https://gist.github.com/vladkozlov69/2500a27cd93245d71573164cda789539 - // uint32_t pin = SAADC_CH_PSELP_PSELP_VDD; - // uint32_t resolution; - int16_t value; + // uint32_t pin = SAADC_CH_PSELP_PSELP_VDD; + //uint32_t resolution; + int16_t value; - // resolution = 10; + //resolution = 10; - NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit; - NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos); - for (int i = 0; i < 8; i++) { - NRF_SAADC->CH[i].PSELN = SAADC_CH_PSELP_PSELP_NC; - NRF_SAADC->CH[i].PSELP = SAADC_CH_PSELP_PSELP_NC; - } - NRF_SAADC->CH[0].CONFIG = ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) | - ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) | - ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) | - ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) | - ((SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) | - ((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk); - NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELP_PSELP_VDD; - NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD; + NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_10bit; - NRF_SAADC->RESULT.PTR = (uint32_t)&value; - NRF_SAADC->RESULT.MAXCNT = 1; // One sample + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos); + for (int i = 0; i < 8; i++) + { + NRF_SAADC->CH[i].PSELN = SAADC_CH_PSELP_PSELP_NC; + NRF_SAADC->CH[i].PSELP = SAADC_CH_PSELP_PSELP_NC; + } + NRF_SAADC->CH[0].CONFIG = ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) + | ((SAADC_CH_CONFIG_RESP_Bypass << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) + | ((SAADC_CH_CONFIG_GAIN_Gain1_6 << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) + | ((SAADC_CH_CONFIG_REFSEL_Internal << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) + | ((SAADC_CH_CONFIG_TACQ_3us << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) + | ((SAADC_CH_CONFIG_MODE_SE << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk); + NRF_SAADC->CH[0].PSELN = SAADC_CH_PSELP_PSELP_VDD; + NRF_SAADC->CH[0].PSELP = SAADC_CH_PSELP_PSELP_VDD; - NRF_SAADC->TASKS_START = 0x01UL; - while (!NRF_SAADC->EVENTS_STARTED) - ; - NRF_SAADC->EVENTS_STARTED = 0x00UL; + NRF_SAADC->RESULT.PTR = (uint32_t)&value; + NRF_SAADC->RESULT.MAXCNT = 1; // One sample - NRF_SAADC->TASKS_SAMPLE = 0x01UL; + NRF_SAADC->TASKS_START = 0x01UL; - while (!NRF_SAADC->EVENTS_END) - ; - NRF_SAADC->EVENTS_END = 0x00UL; - NRF_SAADC->TASKS_STOP = 0x01UL; + while (!NRF_SAADC->EVENTS_STARTED); + NRF_SAADC->EVENTS_STARTED = 0x00UL; - while (!NRF_SAADC->EVENTS_STOPPED) - ; - NRF_SAADC->EVENTS_STOPPED = 0x00UL; + NRF_SAADC->TASKS_SAMPLE = 0x01UL; - if (value < 0) { - value = 0; - } + while (!NRF_SAADC->EVENTS_END); + NRF_SAADC->EVENTS_END = 0x00UL; + NRF_SAADC->TASKS_STOP = 0x01UL; - NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos); + while (!NRF_SAADC->EVENTS_STOPPED); + NRF_SAADC->EVENTS_STOPPED = 0x00UL; - return value; + if (value < 0) + { + value = 0; + } + + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos); + + return value; } /**************************************************************************************************************************/ uint32_t Battery::readVBAT(void) { analogReference(AR_INTERNAL_3_0); // Set the analog reference to 3.0V (default = 3.6V) analogReadResolution(12); // Set the resolution to 12-bit (0..4095) // Can be 8, 10, 12 or 14 delay(1); // Let the ADC settle OK since we are calling this from the long term monitoring loop - vbat_raw = analogRead(VBAT_PIN); // Get the raw 12-bit, 0..3000mV ADC value + vbat_raw = analogRead(VBAT_PIN); // Get the raw 12-bit, 0..3000mV ADC value analogReference(AR_DEFAULT); // Set the ADC back to the default settings - just in case we use it somewhere else analogReadResolution(10); // Set the ADC back to the default settings - just in case we use it somewhere else return vbat_raw; @@ -163,45 +163,48 @@ void Battery::updateBattery(void) vbat_mv = vbat_raw * VBAT_MV_PER_LSB * VBAT_DIVIDER_COMP; if (vbat_mv>3400) batt_type=BATT_LIPO; break; - case BATT_CR2032: - vbat_vdd = analogReadVDD() * 3600 / 1024; // returns a uint32_t value of the mV. 0.6V*6/10bits - vbat_mv = vbat_vdd; + case BATT_CR2032: + vbat_vdd = analogReadVDD()*3600/1024; // returns a uint32_t value of the mV. 0.6V*6/10bits + vbat_mv = vbat_vdd; break; - case BATT_LIPO: - vbat_raw = readVBAT(); // Get a raw ADC reading - // Convert the raw value to compensated mv, taking the resistor- - // divider into account (providing the actual LIPO voltage) - // ADC range is 0..3000mV and resolution is 12-bit (0..4095), - // VBAT voltage divider is 2M + 0.806M, which needs to be added back - vbat_mv = vbat_raw * VBAT_MV_PER_LSB * VBAT_DIVIDER_COMP; + case BATT_LIPO: + vbat_raw = readVBAT(); // Get a raw ADC reading + // Convert the raw value to compensated mv, taking the resistor- + // divider into account (providing the actual LIPO voltage) + // ADC range is 0..3000mV and resolution is 12-bit (0..4095), + // VBAT voltage divider is 2M + 0.806M, which needs to be added back + vbat_mv = vbat_raw * VBAT_MV_PER_LSB * VBAT_DIVIDER_COMP; break; case BATT_VDDH: vbat_raw = readVDDH(); vbat_mv = vbat_raw * VDDHDIV5DIV2SCALE * VDDHDIV5DIV2RANGE; break; } - - _mvToPercent_cb(vbat_per, vbat_mv, batt_type); // Convert from raw mv to percentage (default is based on LIPO chemistry) - blebas.notify(vbat_per); // update the Battery Service. Use notify instead of write to ensure that subscribers receive the new value. + + _mvToPercent_cb(vbat_per, vbat_mv, batt_type); // Convert from raw mv to percentage (default is based on LIPO chemistry) + blebas.notify(vbat_per); // update the Battery Service. Use notify instead of write to ensure that subscribers receive the new value. } /**************************************************************************************************************************/ -void Battery::setmvToPercentCallback(mvToPercent_cb_t callback) { _mvToPercent_cb = callback; } +void Battery::setmvToPercentCallback(mvToPercent_cb_t callback) +{ + _mvToPercent_cb = callback; +} /**************************************************************************************************************************/ // Callbacks must be defined outside of the class. /**************************************************************************************************************************/ -void mvToPercent_default(uint8_t &vbat_per, uint32_t mvolts, uint8_t batt_type) { - switch (batt_type) { - case BATT_UNKNOWN: - vbat_per = 50; +void mvToPercent_default(uint8_t & vbat_per, uint32_t mvolts, uint8_t batt_type) +{ + switch (batt_type) + { + case BATT_UNKNOWN: + vbat_per = 50; break; - case BATT_CR2032: - if (mvolts < 2600) - vbat_per = 0; - if (mvolts > 3000) - vbat_per = 100; - mvolts -= 2600; - vbat_per = (mvolts / 4); // the range really meeds testing... /4 = 2600 to 3000 /2 = 2800 to 3000 + case BATT_CR2032: + if(mvolts<2600) vbat_per= 0; + if(mvolts >3000) vbat_per= 100; + mvolts -= 2600; + vbat_per= (mvolts /4 ); // the range really meeds testing... /4 = 2600 to 3000 /2 = 2800 to 3000 break; case BATT_LIPO: if(mvolts<3300) vbat_per= 0; @@ -227,6 +230,7 @@ void mvToPercent_default(uint8_t &vbat_per, uint32_t mvolts, uint8_t batt_type) } /**************************************************************************************************************************/ -void mvToPercent_test(uint8_t &vbat_per, uint32_t mvolts, uint8_t batt_type) { - vbat_per = mvolts / 100; // converts mvolts (3000 - 4200 mv on lipo) to 30-42% to see mv directly in battery service... +void mvToPercent_test(uint8_t & vbat_per, uint32_t mvolts, uint8_t batt_type) +{ + vbat_per = mvolts/100; // converts mvolts (3000 - 4200 mv on lipo) to 30-42% to see mv directly in battery service... } diff --git a/firmware/nrf52battery.h b/firmware/nrf52battery.h index cdbc13da..b85bf4c3 100644 --- a/firmware/nrf52battery.h +++ b/firmware/nrf52battery.h @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BATTERY_BM_H diff --git a/firmware/nrf52gpio.cpp b/firmware/nrf52gpio.cpp index bf23d7c9..dbf7ad32 100644 --- a/firmware/nrf52gpio.cpp +++ b/firmware/nrf52gpio.cpp @@ -7,168 +7,181 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "nrf52gpio.h" -led_handler::led_handler(PersistentState *cfg, DynamicState *stat) { - config = cfg; - status = stat; - callback = defaultLedCallback; + +led_handler::led_handler (PersistentState* cfg, DynamicState* stat) +{ + config=cfg; + status=stat; + callback=defaultLedCallback; enabled = false; }; -void led_handler::setCallback(ledupdateCallback cb) { callback = cb; } -void led_handler::enable() { +void led_handler::setCallback(ledupdateCallback cb) +{ + callback = cb; +} + + +void led_handler::enable() +{ if (config->enableBLELED) { pinMode(config->pinBLELED, OUTPUT); } - if (config->enableKBLED) { + if (config->enableKBLED){ pinMode(config->pinKBLED, OUTPUT); } enabled = true; } -void led_handler::disable() { - if (config->enableBLELED) { - pinMode(config->pinBLELED, INPUT); +void led_handler::disable() +{ + if (config->enableBLELED) { + pinMode(config->pinBLELED, INPUT); } - if (config->enableKBLED) { - pinMode(config->pinKBLED, INPUT); + if (config->enableKBLED){ + pinMode(config->pinKBLED, INPUT); } enabled = false; } -void led_handler::hello() { - if (!enabled) { - enable(); - } - if (config->enableBLELED) { - digitalWrite(config->pinBLELED, (config->polarityBLELED)); - } - if (config->enableKBLED) { - digitalWrite(config->pinKBLED, (config->polarityKBLED)); - } - delay(200); - if (config->enableBLELED) { - digitalWrite(config->pinBLELED, !(config->polarityBLELED)); - } - if (config->enableKBLED) { - digitalWrite(config->pinKBLED, !(config->polarityKBLED)); - } - delay(200); - if (config->enableBLELED) { - digitalWrite(config->pinBLELED, (config->polarityBLELED)); - } - if (config->enableKBLED) { - digitalWrite(config->pinKBLED, (config->polarityKBLED)); - } - delay(200); - if (config->enableBLELED) { - digitalWrite(config->pinBLELED, !(config->polarityBLELED)); - } - if (config->enableKBLED) { - digitalWrite(config->pinKBLED, !(config->polarityKBLED)); - } - delay(200); +void led_handler::hello() +{ + if (!enabled){enable();} + if (config->enableBLELED) { + digitalWrite(config->pinBLELED, (config->polarityBLELED) ); + } + if (config->enableKBLED){ + digitalWrite(config->pinKBLED, (config->polarityKBLED) ); + } + delay(200); + if (config->enableBLELED) { + digitalWrite(config->pinBLELED, !(config->polarityBLELED) ); + } + if (config->enableKBLED){ + digitalWrite(config->pinKBLED, !(config->polarityKBLED) ); + } + delay(200); + if (config->enableBLELED) { + digitalWrite(config->pinBLELED, (config->polarityBLELED) ); + } + if (config->enableKBLED){ + digitalWrite(config->pinKBLED, (config->polarityKBLED) ); + } + delay(200); + if (config->enableBLELED) { + digitalWrite(config->pinBLELED, !(config->polarityBLELED) ); + } + if (config->enableKBLED){ + digitalWrite(config->pinKBLED, !(config->polarityKBLED) ); + } + delay(200); + } -void led_handler::sleep() { - disable(); // put in high-z so that it doesn't turn on the LED when sleeping... +void led_handler::sleep() +{ + disable(); // put in high-z so that it doesn't turn on the LED when sleeping... } -void led_handler::update() { - if (enabled) { // must be enabled - if (callback != NULL) { // callback must be defined - callback(config, status); +void led_handler::update() +{ + if (enabled){ // must be enabled + if(callback!=NULL){ // callback must be defined + callback(config, status); + } } - } + } /////////////////////////////////////////////////////////////////////////////////////////////////////// -void defaultLedCallback(PersistentState *config, DynamicState *status) { - - // do something looking at config and status and adjust LED states... - // BLE LED - // (0 = 1) Fast Advertizing - // (1 = 2) Slow Advertizing - // (2 = 4) Advertizing running - // (3 = 8) PRPH Connected - // (4 = 16) CENT Connected - // (5 = 32) Connected - - if (config->enableBLELED) { - digitalWrite(config->pinBLELED, (status->statusble > 0 && status->statusble < 8) ? config->polarityBLELED : !(config->polarityBLELED)); - } - // Keyboard Status LED - // The LED bit map is as follows: - // Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) - // KEYBOARD_LED_NUMLOCK - // KEYBOARD_LED_CAPSLOCK - // KEYBOARD_LED_SCROLLLOCK - // KEYBOARD_LED_COMPOSE - // KEYBOARD_LED_KANA - if (config->enableKBLED) { - digitalWrite(config->pinKBLED, ((status->statuskb) & KEYBOARD_LED_CAPSLOCK) ? config->polarityKBLED : !(config->polarityKBLED)); - } + void defaultLedCallback(PersistentState* config, DynamicState* status) +{ + + // do something looking at config and status and adjust LED states... + // BLE LED + // (0 = 1) Fast Advertizing + // (1 = 2) Slow Advertizing + // (2 = 4) Advertizing running + // (3 = 8) PRPH Connected + // (4 = 16) CENT Connected + // (5 = 32) Connected + + if (config->enableBLELED) { + digitalWrite(config->pinBLELED, (status->statusble>0 && status->statusble<8) ? config->polarityBLELED : !(config->polarityBLELED) ); + } + // Keyboard Status LED + // The LED bit map is as follows: + // Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) + // KEYBOARD_LED_NUMLOCK + // KEYBOARD_LED_CAPSLOCK + // KEYBOARD_LED_SCROLLLOCK + // KEYBOARD_LED_COMPOSE + // KEYBOARD_LED_KANA + if (config->enableKBLED){ + digitalWrite(config->pinKBLED, ((status->statuskb)&KEYBOARD_LED_CAPSLOCK) ? config->polarityKBLED : !(config->polarityKBLED) ); + } } + /////////////////////////////////////////////////////////////////////////////////////////////////////// -void setupGpio() { - // this code enables the NFC pins to be GPIO. - if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)) { - // Serial.println("Fix NFC pins"); - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - ; - NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - ; - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - ; - // Serial.println("Done"); - delay(500); - NVIC_SystemReset(); - } // end of NFC switch code. +void setupGpio() +{ + // this code enables the NFC pins to be GPIO. + if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ + // Serial.println("Fix NFC pins"); + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy); + NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy); + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy); + //Serial.println("Done"); + delay(500); + NVIC_SystemReset(); + } // end of NFC switch code. } /**************************************************************************************************************************/ static uint8_t ledpinsaved; -static int16_t buf[] = {(int16_t)(1 << 15) | (int16_t)DEFAULT_PWM_VALUE}; // Inverse polarity (bit 15), 1500us duty cycle -void setupPWM(uint8_t ledpin) { +static int16_t buf[] = {(int16_t)(1 << 15) | (int16_t) DEFAULT_PWM_VALUE}; // Inverse polarity (bit 15), 1500us duty cycle +void setupPWM(uint8_t ledpin) +{ ledpinsaved = ledpin; // Configure BACKLIGHT_LED_PIN as output, and set it to 0 pinMode(ledpinsaved, OUTPUT); digitalWrite(ledpinsaved, LOW); - - NRF_PWM1->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_8; // 1 us - NRF_PWM1->PSEL.OUT[0] = ledpinsaved; // Supports Port 0 and 1 of nRF52840 - NRF_PWM1->MODE = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos); - NRF_PWM1->DECODER = (PWM_DECODER_LOAD_Common << PWM_DECODER_LOAD_Pos) | (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos); - NRF_PWM1->LOOP = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos); - NRF_PWM1->COUNTERTOP = 10000; // 5ms period = 200 Hz PWM frequency - + + NRF_PWM1->PRESCALER = PWM_PRESCALER_PRESCALER_DIV_8; // 1 us + NRF_PWM1->PSEL.OUT[0] = ledpinsaved; // Supports Port 0 and 1 of nRF52840 + NRF_PWM1->MODE = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos); + NRF_PWM1->DECODER = (PWM_DECODER_LOAD_Common << PWM_DECODER_LOAD_Pos) | + (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos); + NRF_PWM1->LOOP = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos); + NRF_PWM1->COUNTERTOP = 10000; // 5ms period = 200 Hz PWM frequency + + NRF_PWM1->SEQ[0].CNT = ((sizeof(buf) / sizeof(uint16_t)) << PWM_SEQ_CNT_CNT_Pos); NRF_PWM1->SEQ[0].ENDDELAY = 0; NRF_PWM1->SEQ[0].PTR = (uint32_t)&buf[0]; NRF_PWM1->SEQ[0].REFRESH = 0; NRF_PWM1->SHORTS = 0; -} + + } /**************************************************************************************************************************/ @@ -177,48 +190,62 @@ void sendPWM(uint16_t value) // max value for PWM is 15 bits // 16th bit is used for inverse polarity { - value = value & 0x7FFF; // dropping the 16th bit. DEFAULT_PWM_MAX_VALUE - if (value == 0) { - NRF_PWM1->ENABLE = 0; // Turn off PWM peripheral - } else { - buf[0] = (1 << 15) | value; // Inverse polarity (bit 15), 1500us duty cycle - NRF_PWM1->SEQ[0].PTR = (uint32_t)&buf[0]; - NRF_PWM1->ENABLE = 1; - NRF_PWM1->TASKS_SEQSTART[0] = 1; - } + value = value & 0x7FFF; // dropping the 16th bit. DEFAULT_PWM_MAX_VALUE + if (value == 0) + { + NRF_PWM1->ENABLE = 0; // Turn off PWM peripheral + } + else + { + buf[0] = (1 << 15) | value; // Inverse polarity (bit 15), 1500us duty cycle + NRF_PWM1->SEQ[0].PTR = (uint32_t)&buf[0]; + NRF_PWM1->ENABLE = 1; + NRF_PWM1->TASKS_SEQSTART[0] = 1; + } } + /**************************************************************************************************************************/ -void switchVCC(bool value) { -#if VCC_ENABLE_GPIO == 1 +void switchVCC(bool value) +{ + #if VCC_ENABLE_GPIO == 1 pinMode(VCC_PIN, OUTPUT); - if (value) { - digitalWrite(VCC_PIN, VCC_POLARITY_ON); - } else { - digitalWrite(VCC_PIN, !VCC_POLARITY_ON); + if(value) + { + digitalWrite(VCC_PIN, VCC_POLARITY_ON); + } + else + { + digitalWrite(VCC_PIN, !VCC_POLARITY_ON); } -#endif + #endif } -void switchCharger(bool value) { -#if VCC_ENABLE_CHARGER == 1 +void switchCharger(bool value) +{ + #if VCC_ENABLE_CHARGER == 1 pinMode(CHARGER_PIN, OUTPUT); - if (value) { - digitalWrite(CHARGER_PIN, CHARGER_POLARITY_ON); - } else { - digitalWrite(CHARGER_PIN, !CHARGER_POLARITY_ON); + if(value) + { + digitalWrite(CHARGER_PIN, CHARGER_POLARITY_ON); } -#endif + else + { + digitalWrite(CHARGER_PIN, !CHARGER_POLARITY_ON); + } + #endif } -void setupWDT() { +void setupWDT() +{ // Configure WDT - NRF_WDT->CONFIG = 0x00; // stop WDT when sleeping - NRF_WDT->CRV = 5 * 32768 + 1; // set timeout (5 sec) - NRF_WDT->RREN = 0x01; // enable the RR[0] reload register - NRF_WDT->TASKS_START = 1; // start WDT + NRF_WDT->CONFIG = 0x00; // stop WDT when sleeping + NRF_WDT->CRV = 5 * 32768 + 1; // set timeout (5 sec) + NRF_WDT->RREN = 0x01; // enable the RR[0] reload register + NRF_WDT->TASKS_START = 1; // start WDT } -void updateWDT() { - NRF_WDT->RR[0] = WDT_RR_RR_Reload; // pet watchdog +void updateWDT() +{ + NRF_WDT->RR[0] = WDT_RR_RR_Reload; // pet watchdog } \ No newline at end of file diff --git a/firmware/nrf52gpio.h b/firmware/nrf52gpio.h index b26baa18..c8313443 100644 --- a/firmware/nrf52gpio.h +++ b/firmware/nrf52gpio.h @@ -7,46 +7,45 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF52GPIO_H #define NRF52GPIO_H -#include "firmware_config.h" -#include "hardware_variants.h" #include #include +#include "hardware_variants.h" +#include "firmware_config.h" + + class led_handler + { + public: + led_handler(PersistentState* cfg, DynamicState* stat); + void setCallback(ledupdateCallback cb); + void update(); + void enable(); + void disable(); + void hello(); + void sleep(); + + private: + bool enabled; + ledupdateCallback callback; + PersistentState* config; + DynamicState* status; + }; + +void defaultLedCallback(PersistentState* config, DynamicState* status); -class led_handler { -public: - led_handler(PersistentState *cfg, DynamicState *stat); - void setCallback(ledupdateCallback cb); - void update(); - void enable(); - void disable(); - void hello(); - void sleep(); - -private: - bool enabled; - ledupdateCallback callback; - PersistentState *config; - DynamicState *status; -}; - -void defaultLedCallback(PersistentState *config, DynamicState *status); void setupGpio(void); diff --git a/firmware/sleep.cpp b/firmware/sleep.cpp index eb09e329..3802ec62 100644 --- a/firmware/sleep.cpp +++ b/firmware/sleep.cpp @@ -7,17 +7,14 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "sleep.h" @@ -27,70 +24,76 @@ extern led_handler statusLEDs; /// Typically a Blue and Red LED // Prepare sense pins for waking up from complete shutdown /**************************************************************************************************************************/ void prepareSleep() { + - for (int j = 0; j < MATRIX_ROWS; ++j) { - // set the current row as OUPUT and LOW + for(int j = 0; j < MATRIX_ROWS; ++j) { + //set the current row as OUPUT and LOW pinMode(rows[j], OUTPUT); -#if DIODE_DIRECTION == COL2ROW - digitalWrite(rows[j], LOW); // 'enables' a specific row to be "low" -#else - digitalWrite(rows[j], HIGH); // 'enables' a specific row to be "HIGH" -#endif + #if DIODE_DIRECTION == COL2ROW + digitalWrite(rows[j], LOW); // 'enables' a specific row to be "low" + #else + digitalWrite(rows[j], HIGH); // 'enables' a specific row to be "HIGH" + #endif } - // loops thru all of the columns + //loops thru all of the columns for (int i = 0; i < MATRIX_COLS; ++i) { -#if DIODE_DIRECTION == COL2ROW - pinMode(columns[i], INPUT_PULLUP_SENSE); // 'enables' the column High Value on the diode; becomes "LOW" when pressed - Sense makes it wake up when sleeping -#else - pinMode(columns[i], - INPUT_PULLDOWN_SENSE); // 'enables' the column High Value on the diode; becomes "LOW" when pressed - Sense makes it wake up when sleeping -#endif + #if DIODE_DIRECTION == COL2ROW + pinMode(columns[i], INPUT_PULLUP_SENSE); // 'enables' the column High Value on the diode; becomes "LOW" when pressed - Sense makes it wake up when sleeping + #else + pinMode(columns[i], INPUT_PULLDOWN_SENSE); // 'enables' the column High Value on the diode; becomes "LOW" when pressed - Sense makes it wake up when sleeping + #endif } -#ifdef BLUEMICRO_CONFIGURED_DISPLAY - OLED.sleep(); -#endif + #ifdef BLUEMICRO_CONFIGURED_DISPLAY + OLED.sleep(); + #endif +#ifdef ENABLE_AUDIO + #ifdef SPEAKER_PIN + pinMode(SPEAKER_PIN, OUTPUT); + digitalWrite(SPEAKER_PIN, LOW); + tone(SPEAKER_PIN, NOTE_E5, 50); + delay(65); + tone(SPEAKER_PIN, NOTE_A4, 50); + delay(65); + tone(SPEAKER_PIN, NOTE_E4, 50); + delay(65); + digitalWrite(SPEAKER_PIN, LOW); + pinMode(SPEAKER_PIN, INPUT); + #endif + #endif -#ifdef SPEAKER_PIN - pinMode(SPEAKER_PIN, OUTPUT); - digitalWrite(SPEAKER_PIN, LOW); - tone(SPEAKER_PIN, NOTE_E5, 50); - delay(65); - tone(SPEAKER_PIN, NOTE_A4, 50); - delay(65); - tone(SPEAKER_PIN, NOTE_E4, 50); - delay(65); - digitalWrite(SPEAKER_PIN, LOW); - pinMode(SPEAKER_PIN, INPUT); -#endif + #if VCC_ENABLE_GPIO ==1 + switchVCC(false); // turn off VCC when going to sleep. This isn't an optional thing... + #endif -#if VCC_ENABLE_GPIO == 1 - switchVCC(false); // turn off VCC when going to sleep. This isn't an optional thing... -#endif - - statusLEDs.sleep(); - sendPWM(0); // forces PWM backlight off + statusLEDs.sleep(); + sendPWM(0); // forces PWM backlight off + } -void sleepNow() { - delay(300); // delay to let any keys be released +void sleepNow() +{ + delay(300); // delay to let any keys be released prepareSleep(); -#if WS2812B_LED_ON == 1 - suspendRGB(); -#endif + #if WS2812B_LED_ON == 1 + suspendRGB(); + #endif sd_power_system_off(); } /**************************************************************************************************************************/ -void gotoSleep(unsigned long timesincelastkeypress, bool connected) { +void gotoSleep(unsigned long timesincelastkeypress,bool connected) +{ // shutdown when unconnected and no keypresses for SLEEPING_DELAY ms - if ((timesincelastkeypress > SLEEPING_DELAY) && (!connected)) { - LOG_LV2("SLEEP", "Not Connected Sleep %i", timesincelastkeypress); + if ((timesincelastkeypress>SLEEPING_DELAY)&&(!connected)) + { + LOG_LV2("SLEEP","Not Connected Sleep %i", timesincelastkeypress); sleepNow(); - } + } // shutdown when unconnected and no keypresses for SLEEPING_DELAY_CONNECTED ms - if ((timesincelastkeypress > SLEEPING_DELAY_CONNECTED) && (connected)) { - LOG_LV2("SLEEP", "Connected Sleep %i", timesincelastkeypress); + if ((timesincelastkeypress>SLEEPING_DELAY_CONNECTED)&&(connected)) + { + LOG_LV2("SLEEP","Connected Sleep %i", timesincelastkeypress); sleepNow(); - } + } } diff --git a/firmware/sleep.h b/firmware/sleep.h index b1aefdcd..73e86463 100644 --- a/firmware/sleep.h +++ b/firmware/sleep.h @@ -7,39 +7,36 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SLEEP_H #define SLEEP_H -#include "BlueMicro_display.h" -#include "BlueMicro_tone.h" -#include "LedPwm.h" -#include "LedRGB.h" -#include "firmware_config.h" -#include "keyboard_config.h" -#include "nrf52gpio.h" #include #include +#include "keyboard_config.h" +#include "firmware_config.h" +#include "nrf52gpio.h" +#include "LedRGB.h" +#include "LedPwm.h" +#include "BlueMicro_display.h" +#include "BlueMicro_tone.h" // Keyboard Matrix -extern byte rows[]; // Contains the GPIO Pin Numbers defined in keyboard_config.h -extern byte columns[]; // Contains the GPIO Pin Numbers defined in keyboard_config.h +extern byte rows[] ; // Contains the GPIO Pin Numbers defined in keyboard_config.h +extern byte columns[] ; // Contains the GPIO Pin Numbers defined in keyboard_config.h #ifdef BLUEMICRO_CONFIGURED_DISPLAY extern BlueMicro_Display OLED; #endif void prepareSleep(void); void sleepNow(void); -void gotoSleep(unsigned long timesincelastkeypress, bool connected); +void gotoSleep(unsigned long timesincelastkeypress,bool connected); #endif \ No newline at end of file diff --git a/firmware/usb.cpp b/firmware/usb.cpp index bc37a898..c5147a46 100644 --- a/firmware/usb.cpp +++ b/firmware/usb.cpp @@ -7,43 +7,48 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "usb.h" + extern DynamicState keyboardstate; // Report ID -enum { +enum +{ RID_KEYBOARD = 1, RID_MOUSE, RID_CONSUMER_CONTROL, // Media, volume etc .. }; #ifdef TINYUSB_AVAILABLE -// HID report descriptor using TinyUSB's template -// Single Report (no ID) descriptor -uint8_t const desc_hid_report[] = {TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID_KEYBOARD)), TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(RID_MOUSE)), - TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(RID_CONSUMER_CONTROL))}; - -extern Adafruit_USBD_Device USBDevice; -Adafruit_USBD_HID USBhid; + // HID report descriptor using TinyUSB's template + // Single Report (no ID) descriptor + uint8_t const desc_hid_report[] = + { + TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID_KEYBOARD)), + TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID(RID_MOUSE)), + TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(RID_CONSUMER_CONTROL)) + }; + + extern Adafruit_USBD_Device USBDevice; + Adafruit_USBD_HID USBhid; #endif -void usb_setup() { -#ifdef TINYUSB_AVAILABLE + +void usb_setup() +{ + #ifdef TINYUSB_AVAILABLE USBDevice.setManufacturerDescriptor(MANUFACTURER_NAME); USBDevice.setProductDescriptor(DEVICE_NAME); @@ -51,135 +56,91 @@ void usb_setup() { USBhid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report)); USBhid.setReportCallback(NULL, hid_report_callback); USBhid.begin(); -#endif + #endif } -bool usb_isConnected() { -#ifdef TINYUSB_AVAILABLE - return USBhid.ready() && !USBDevice.suspended(); -#else - return false; -#endif +bool usb_isConnected() +{ + #ifdef TINYUSB_AVAILABLE + return USBhid.ready() && !USBDevice.suspended(); + #else + return false; + #endif } -void usb_wakeup() { -#ifdef TINYUSB_AVAILABLE - if (USBDevice.suspended()) { +void usb_wakeup() +{ + #ifdef TINYUSB_AVAILABLE + if (USBDevice.suspended()) + { // Wake up host if we are in suspend mode and REMOTE_WAKEUP feature is enabled by host USBDevice.remoteWakeup(); } -#endif + #endif } -void usb_sendKeys(std::array currentReport) { -#ifdef TINYUSB_AVAILABLE - uint8_t keycode[6]; - uint8_t mods = 0; - mods = currentReport[0]; // modifiers - keycode[0] = currentReport[1]; // Buffer - keycode[1] = currentReport[2]; // Buffer - keycode[2] = currentReport[3]; // Buffer - keycode[3] = currentReport[4]; // Buffer - keycode[4] = currentReport[5]; // Buffer - keycode[5] = currentReport[6]; // Buffer - - USBhid.keyboardReport(RID_KEYBOARD, mods, keycode); -#endif +void usb_sendKeys(HIDKeyboard currentReport) +{ + #ifdef TINYUSB_AVAILABLE + USBhid.keyboardReport(RID_KEYBOARD, currentReport.modifier, currentReport.keycode); + #endif } -void usb_sendKeys(uint8_t currentReport[8]) { -#ifdef TINYUSB_AVAILABLE - uint8_t keycode[6]; - uint8_t mods = 0; - - mods = currentReport[0]; // modifiers - keycode[0] = currentReport[1]; // Buffer - keycode[1] = currentReport[2]; // Buffer - keycode[2] = currentReport[3]; // Buffer - keycode[3] = currentReport[4]; // Buffer - keycode[4] = currentReport[5]; // Buffer - keycode[5] = currentReport[6]; // Buffer - - USBhid.keyboardReport(RID_KEYBOARD, mods, keycode); -#endif -} -void usb_sendMediaKey(uint16_t keycode) { -#ifdef TINYUSB_AVAILABLE - USBhid.sendReport16(RID_CONSUMER_CONTROL, hid_GetMediaUsageCode(keycode)); -#endif +void usb_sendMediaKey(uint16_t keycode) +{ + #ifdef TINYUSB_AVAILABLE + USBhid.sendReport16(RID_CONSUMER_CONTROL, hid_GetMediaUsageCode(keycode)); + #endif } -#define MOVE_STEP 1 -void usb_sendMouseKey(uint16_t keycode) { -#ifdef TINYUSB_AVAILABLE - switch (keycode) { - case KC_MS_OFF: - USBhid.mouseButtonRelease(RID_MOUSE); - break; - case KC_MS_BTN1: - USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_LEFT); - break; - case KC_MS_BTN2: - USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_RIGHT); - break; - case KC_MS_BTN3: - USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_MIDDLE); - break; - case KC_MS_BTN4: - USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_BACKWARD); - break; - case KC_MS_BTN5: - USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_FORWARD); - break; + +#define MOVE_STEP 1 +void usb_sendMouseKey(uint16_t keycode) +{ + #ifdef TINYUSB_AVAILABLE + switch (keycode) + { + case KC_MS_OFF: USBhid.mouseButtonRelease(RID_MOUSE); break; + case KC_MS_BTN1: USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_LEFT); break; + case KC_MS_BTN2: USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_RIGHT); break; + case KC_MS_BTN3: USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_MIDDLE); break; + case KC_MS_BTN4: USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_BACKWARD); break; + case KC_MS_BTN5: USBhid.mouseButtonPress(RID_MOUSE, MOUSE_BUTTON_FORWARD); break; } -#endif + #endif } -void usb_sendMouseMove(uint16_t keycode, uint16_t steps) { -#ifdef TINYUSB_AVAILABLE - switch (keycode) { - case KC_MS_UP: - USBhid.mouseMove(RID_MOUSE, 0, -steps); - break; - case KC_MS_DOWN: - USBhid.mouseMove(RID_MOUSE, 0, steps); - break; - case KC_MS_LEFT: - USBhid.mouseMove(RID_MOUSE, -steps, 0); - break; - case KC_MS_RIGHT: - USBhid.mouseMove(RID_MOUSE, steps, 0); - break; - - case KC_MS_WH_UP: - USBhid.mouseScroll(RID_MOUSE, -1, 0); - break; - case KC_MS_WH_DOWN: - USBhid.mouseScroll(RID_MOUSE, 1, 0); - break; - case KC_MS_WH_LEFT: - USBhid.mouseScroll(RID_MOUSE, 0, -1); - break; - case KC_MS_WH_RIGHT: - USBhid.mouseScroll(RID_MOUSE, 0, 1); - break; +void usb_sendMouseMove(uint16_t keycode, uint16_t steps) +{ + #ifdef TINYUSB_AVAILABLE + switch (keycode) + { + case KC_MS_UP: USBhid.mouseMove(RID_MOUSE, 0, -steps); break; + case KC_MS_DOWN: USBhid.mouseMove(RID_MOUSE, 0, steps); break; + case KC_MS_LEFT: USBhid.mouseMove(RID_MOUSE, -steps, 0); break; + case KC_MS_RIGHT: USBhid.mouseMove(RID_MOUSE, steps, 0); break; + + case KC_MS_WH_UP: USBhid.mouseScroll(RID_MOUSE, -1, 0); break; + case KC_MS_WH_DOWN: USBhid.mouseScroll(RID_MOUSE, 1, 0); break; + case KC_MS_WH_LEFT: USBhid.mouseScroll(RID_MOUSE, 0, -1); break; + case KC_MS_WH_RIGHT: USBhid.mouseScroll(RID_MOUSE, 0, 1); break; } -#endif + #endif } -// Output report callback for LED indicator such as Caplocks -void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) { -#ifdef TINYUSB_AVAILABLE - if (report_id != RID_KEYBOARD) - return; - - // LED indicator is output report with only 1 byte length - if (report_type != HID_REPORT_TYPE_OUTPUT) - return; - // The LED bit map is as follows: (also defined by KEYBOARD_LED_* ) - // Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) - keyboardstate.statuskb = buffer[1]; -#endif +// Output report callback for LED indicator such as Caplocks +void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +{ + #ifdef TINYUSB_AVAILABLE + if (report_id != RID_KEYBOARD) return; + + // LED indicator is output report with only 1 byte length + if (report_type != HID_REPORT_TYPE_OUTPUT) return; + + // The LED bit map is as follows: (also defined by KEYBOARD_LED_* ) + // Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0) + keyboardstate.statuskb = buffer[1]; + #endif } \ No newline at end of file diff --git a/firmware/usb.h b/firmware/usb.h index e9ac3537..bd9c1e50 100644 --- a/firmware/usb.h +++ b/firmware/usb.h @@ -7,48 +7,48 @@ Redistribution and use in source and binary forms, with or without modification, 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without -specific prior written permission. +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + #ifndef USB_H #define USB_H -#include "HID.h" -#include "datastructures.h" -#include "firmware_config.h" -#include "keymap.h" -#include - -#ifdef NRF52840_XXAA // only the 840 has USB available. -#ifdef ARDUINO_NRF52_ADAFRUIT -// do nothing since the Adafruit BSP doesn't support ediv. -#endif -#ifdef ARDUINO_NRF52_COMMUNITY -#include "Adafruit_TinyUSB.h" -#define TINYUSB_AVAILABLE 1 -#endif -#endif - -// these functions will be defined for all cases (nrf52832 and nrf52840) but will work differently. -void usb_setup(); -bool usb_isConnected(); -void usb_wakeup(); -void usb_sendKeys(uint8_t currentReport[8]); -void usb_sendKeys(std::array currentReport); -void usb_sendMediaKey(uint16_t keycode); -void usb_sendMouseKey(uint16_t keycode); -void usb_sendMouseMove(uint16_t keycode, uint16_t steps); -void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize); + #include + #include "firmware_config.h" + #include "keymap.h" + #include "datastructures.h" + #include "HID.h" + + #ifdef NRF52840_XXAA // only the 840 has USB available. + #ifdef ARDUINO_NRF52_ADAFRUIT + // do nothing since the Adafruit BSP doesn't support ediv. + #endif + #ifdef ARDUINO_NRF52_COMMUNITY + #include "Adafruit_TinyUSB.h" + #define TINYUSB_AVAILABLE 1 + #endif + #endif + + + + // these functions will be defined for all cases (nrf52832 and nrf52840) but will work differently. + void usb_setup(); + bool usb_isConnected(); + void usb_wakeup(); + void usb_sendKeys(HIDKeyboard currentReport); + void usb_sendMediaKey(uint16_t keycode); + void usb_sendMouseKey(uint16_t keycode); + void usb_sendMouseMove(uint16_t keycode, uint16_t steps); + void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); #endif \ No newline at end of file