cimdit/cimdit.ino

159 lines
3.9 KiB
C++

/**
* \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 <HID-Project.h>
#ifdef HAVE_DISPLAY
#include <Adafruit_SSD1306.h>
#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;
}
}
}
}