/** * \file cimdit.ino * \brief main functions * \author GrumpyDeveloper (Sascha Nitsch) * \copyright 2022 Sascha Nitsch * Licensed under MIT license * */ /// use a custom keyboard layout #define HID_CUSTOM_LAYOUT /// use german keyboard layout #define LAYOUT_GERMAN #define HAVE_DISPLAY #ifdef HAVE_DISPLAY /// no splash screen on OLED #define SSD1306_NO_SPLASH /// OLED display width, in pixels #define SCREEN_WIDTH 128 /// OLED display height, in pixels #define SCREEN_HEIGHT 32 /// OLED screen address #define SCREEN_ADDRESS 0x3C #endif // library includes #include #ifdef HAVE_DISPLAY #include #endif // own includes #include "cimdithal.h" /// update usb devices every x ms if needed #define UPDATE_INTERVAL 100 /// our hardware abstraction layer CimditHAL hal; /// flag if the rotary interrupt has been triggered volatile bool outstandingRotInterrupt = false; /// interrupt service routine for rotatry change interrupt void rotInt() { outstandingRotInterrupt = true; } /// next update time in ms uint32_t nextUpdate = 0; #ifdef HAVE_DISPLAY /// our display Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); #endif /// display /// /// initial setup void setup() { Serial.begin(115200); hal.begin(); attachInterrupt(digitalPinToInterrupt(7), rotInt, RISING); // initialize USB related things Keyboard.begin(); Mouse.begin(); Gamepad.begin(); #ifdef HAVE_DISPLAY // init display display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); display.clearDisplay(); display.display(); #endif } /// main loop void loop() { hal.readFromHardware(outstandingRotInterrupt); if (outstandingRotInterrupt) { outstandingRotInterrupt = false; return; } if (hal.m_millis < nextUpdate && hal.m_millis > ROLLOVER_INTERVAL) return; nextUpdate = hal.m_millis + UPDATE_INTERVAL; uint8_t rotaryChanged = hal.rotaryChanged(); if (rotaryChanged) { for (uint8_t i = 0; i < 7; ++i) { if (rotaryChanged & 1) { // temporary debug output Serial.print(F("rot ")); Serial.print(i); Serial.print(F(" => ")); Serial.println(hal.getEncoder(i)); // end of temporary debug output } rotaryChanged >>= 1; } } uint16_t analogChanged = hal.analogChanged(); if (analogChanged) { for (uint8_t i = 0; i < 4; ++i) { if (analogChanged & 1) { uint16_t analog = hal.getAnalog(i); // temporary debug output int16_t analogMapped16 = map(analog, 0, 1024, -32767, 32768); int8_t analogMapped8 = map(analog, 0, 1024, -127, 127); switch(i) { case 0: Gamepad.xAxis(analogMapped16); break; case 1: Gamepad.yAxis(analogMapped16); break; case 2: Gamepad.zAxis(analogMapped8); break; case 3: Gamepad.rxAxis(analogMapped16); break; default: break; } Serial.print(F("analog ")); Serial.print(i); Serial.print(F(": ")); Serial.println(analogMapped16); // end of temporary debug output } analogChanged >>= 1; } Gamepad.write(); } uint64_t buttonsChanged = hal.buttonsChanged(); if (buttonsChanged) { for (uint8_t i = 0; i < 64; ++i) { if (buttonsChanged & 0xFF) { // quickcheck for 8 bits at a time if (buttonsChanged & 1) { // temporary debug output Serial.print(F("button ")); Serial.print(i); Serial.print(F(" ")); bool pressed = hal.getButton(i); Serial.println(pressed); if (i<32) { if (pressed) Gamepad.press(i+1); else Gamepad.release(i+1); } // end of temporary debug output } buttonsChanged >>= 1; } else { buttonsChanged >>= 8; i += 8; } } } }