You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Kaleidoscope/doc/plugin/ATMegaKeyboard.md

83 lines
2.4 KiB

# ATMegaKeyboard
A lot of custom keyboards are built upon the ATMega MCU (most often an
`atmega32u4`), and the vast majority of them follow a similar architecture, so
much so that the vast majority of code can be lifted out into a base class,
making porting to these keyboards trivial. All we have to do is tell it our
pinout, and we're all done.
## Porting hardware using the ATMegaKeyboard class
The plugin assumes a simple matrix layout, which we can tell it by using the
`ATMEGA_KEYBOARD_CONFIG` macro, which takes two arguments: a list of row and
column pins. In the `.cpp`, simply use `ATMEGA_KEYBOARD_DATA`, with the hardware
object as its argument:
```c++
// Kaleidoscope-Vendor-ExampleHardware.h
#define KALEIDOSCOPE_WITH_ATMEGA_KEYBOARD 1
#include "kaleidoscope/hardware/vendor/ExampleHardware.h"
// kaleidoscope/hardware/vendor/ExampleHardware.h
namespace kaleidoscope {
namespace hardware {
namespace vendor {
class ExampleKeyboard: public ATMegaKeyboard {
public:
ExampleKeyboard() {}
ATMEGA_KEYBOARD_CONFIG(
ROW_PIN_LIST({PIN_D1, PIN_D2}),
COL_PIN_LIST({PIN_F6, PIN_F7})
);
static constexpr int8_t led_count = 0;
};
#define KEYMAP( \
r0c0 ,r0c1 \
,r1c0 ,r1c1 \
) \
{ r0c0 ,r0c1 }, \
{ r1c0 ,r1c1 }
}
}
}
// kaleidoscope/hardware/vendor/ExampleHardware.cpp
namespace kaleidoscope {
namespace hardware {
namespace vendor {
ATMEGA_KEYBOARD_DATA(ExampleHardware);
constexpr int8_t ExampleHardware::led_count;
}
}
}
HARDWARE_IMPLEMENTATION KeyboardHardware;
kaleidoscope::hardware::vendor::ExampleHardware &ExampleHardware = KeyboardHardware;
```
## Overriding methods
For performance and space-saving reasons, the base class does not use virtual
methods. Instead, whenever it calls a method of its own, it will call it through
the `KeyboardHardware` singleton object, which is always an instance of the
exact hardware plugin. Thus, implementing a function in the subclass will shadow
the one in the base class.
This can be used to implement more efficient methods, would it be needed. The
[Atreus][hardware:atreus] port does this, for example, by overriding the generic
`readCols` with a more specialised, faster implementation.
## Further reading
See the [Planck][hardware:planck] and [Atreus][hardware:atreus] ports for an
example of how this class can be used in practice.
[hardware:planck]: ../../src/kaleidoscope/hardware/olkb/Planck.h
[hardware:atreus]: ../../src/kaleidoscope/hardware/technomancy/Atreus.h