commit 2c8312da0ad20e87036079ce602a5fe954d3c727
parent cd1848565c4953bf02e8f4a1f3f5d8a8942d0687
Author: Lukas F. Hartmann <lukas@mntre.com>
Date: Mon, 13 Dec 2021 22:18:46 +0100
kbd: implement media controller device; move matrix to .h files to make make happy
Diffstat:
10 files changed, 509 insertions(+), 328 deletions(-)
diff --git a/reform2-keyboard-fw/README.md b/reform2-keyboard-fw/README.md
@@ -4,8 +4,8 @@
- `constants.h`: Define which keyboard variant you want to build for
- `keyboard.c`: Main entrypoint that includes the chosen matrix file (keyboard layout)
-- `matrix.c`: Keyboard layout definition (default)
-- `matrix_*.c`: Alternative layouts
+- `matrix.h`: Keyboard layout definition (default)
+- `matrix_*.h`: Alternative layouts
- `backlight.c`: Keyboard backlight control
- `menu.c`: OLED Menu handling
- `oled.c`: OLED graphics control
@@ -47,5 +47,3 @@ To build, type:
To flash, put your keyboard into [flashing mode](https://mntre.com/reform2/handbook/parts.html#keyboard-firmware) and run:
`sudo ./flash.sh`
-
-
diff --git a/reform2-keyboard-fw/constants.h b/reform2-keyboard-fw/constants.h
@@ -7,8 +7,8 @@
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
-#define KBD_FW_REV "R1 20210927"
-//#define KBD_VARIANT_STANDALONE
+#define KBD_FW_REV "R1 20211213"
+#define KBD_VARIANT_STANDALONE
#define KBD_VARIANT_QWERTY_US
//#define KBD_VARIANT_NEO2
//#define KBD_VARIANT_ELLEN
diff --git a/reform2-keyboard-fw/descriptors.c b/reform2-keyboard-fw/descriptors.c
@@ -23,10 +23,42 @@
*/
const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
{
- /* Use the HID class driver's standard Keyboard report.
- * Max simultaneous keys: 6
- */
- HID_DESCRIPTOR_KEYBOARD(6)
+ /* Use the HID class driver's standard Keyboard report.
+ * Max simultaneous keys: 6
+ */
+ HID_DESCRIPTOR_KEYBOARD(6)
+};
+
+/** HID class report descriptor. This is a special descriptor constructed with values from the
+ * USBIF HID class specification to describe the reports and capabilities of the HID device. This
+ * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
+ * the device will send, and what it may be sent back from the host. Refer to the HID specification for
+ * more details on HID report descriptors.
+ */
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MediaControlReport[] =
+{
+ HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer Page */
+ HID_RI_USAGE(8, 0x01), /* Consumer Controls */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_USAGE(8, 0xB0), /* Play */
+ HID_RI_USAGE(8, 0xB1), /* Pause */
+ HID_RI_USAGE(8, 0xB3), /* Fast Forward */
+ HID_RI_USAGE(8, 0xB4), /* Rewind */
+ HID_RI_USAGE(8, 0xB5), /* Next Track */
+ HID_RI_USAGE(8, 0xB6), /* Previous Track */
+ HID_RI_USAGE(8, 0xB7), /* Stop */
+ HID_RI_USAGE(8, 0xCD), /* Play/Pause (toggle) */
+ HID_RI_USAGE(8, 0xE2), /* Mute */
+ HID_RI_USAGE(8, 0xE9), /* Volume Up */
+ HID_RI_USAGE(8, 0xEA), /* Volume Down */
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_REPORT_COUNT(8, 0x0B),
+ HID_RI_LOGICAL_MINIMUM(8, 0),
+ HID_RI_LOGICAL_MAXIMUM(8, 1),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+ HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_INPUT(8, HID_IOF_CONSTANT),
+ HID_RI_END_COLLECTION(0),
};
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
@@ -36,24 +68,24 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
*/
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
{
- .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
- .USBSpecification = VERSION_BCD(1,1,0),
- .Class = USB_CSCP_NoDeviceClass,
- .SubClass = USB_CSCP_NoDeviceSubclass,
- .Protocol = USB_CSCP_NoDeviceProtocol,
+ .USBSpecification = VERSION_BCD(1,1,0),
+ .Class = USB_CSCP_NoDeviceClass,
+ .SubClass = USB_CSCP_NoDeviceSubclass,
+ .Protocol = USB_CSCP_NoDeviceProtocol,
- .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
- .VendorID = 0x03EB,
- .ProductID = 0x2042,
- .ReleaseNumber = VERSION_BCD(0,0,1),
+ .VendorID = 0x03EB,
+ .ProductID = 0x2042,
+ .ReleaseNumber = VERSION_BCD(0,0,1),
- .ManufacturerStrIndex = STRING_ID_Manufacturer,
- .ProductStrIndex = STRING_ID_Product,
- .SerialNumStrIndex = NO_DESCRIPTOR,
+ .ManufacturerStrIndex = STRING_ID_Manufacturer,
+ .ProductStrIndex = STRING_ID_Product,
+ .SerialNumStrIndex = NO_DESCRIPTOR,
- .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
};
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
@@ -63,57 +95,94 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
*/
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
{
- .Config =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+ .TotalInterfaces = 2,
- .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
- .TotalInterfaces = 1,
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
- .ConfigurationNumber = 1,
- .ConfigurationStrIndex = NO_DESCRIPTOR,
+ .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
- .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
- .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
- },
+ .HID1_KeyboardInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
- .HID_Interface =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+ .InterfaceNumber = INTERFACE_ID_Keyboard,
+ .AlternateSetting = 0x00,
- .InterfaceNumber = INTERFACE_ID_Keyboard,
- .AlternateSetting = 0x00,
+ .TotalEndpoints = 1,
- .TotalEndpoints = 1,
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_KeyboardBootProtocol,
- .Class = HID_CSCP_HIDClass,
- .SubClass = HID_CSCP_BootSubclass,
- .Protocol = HID_CSCP_KeyboardBootProtocol,
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
- .InterfaceStrIndex = NO_DESCRIPTOR
- },
+ .HID1_KeyboardHID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
- .HID_KeyboardHID =
- {
- .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(KeyboardReport)
+ },
- .HIDSpec = VERSION_BCD(1,1,1),
- .CountryCode = 0x00,
- .TotalReportDescriptors = 1,
- .HIDReportType = HID_DTYPE_Report,
- .HIDReportLength = sizeof(KeyboardReport)
- },
+ .HID1_ReportINEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
- .HID_ReportINEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+ .EndpointAddress = KEYBOARD_EPADDR,
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = HID_EPSIZE,
+ .PollingIntervalMS = 10
+ },
- .EndpointAddress = KEYBOARD_EPADDR,
- .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = KEYBOARD_EPSIZE,
- .PollingIntervalMS = 0x05
- },
+ .HID2_MediaControlInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = INTERFACE_ID_MediaControl,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_NonBootSubclass,
+ .Protocol = HID_CSCP_NonBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .HID2_MediaControlHID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(1,1,1),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(MediaControlReport)
+ },
+
+ .HID2_ReportINEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = MEDIACONTROL_EPADDR,
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = HID_EPSIZE,
+ .PollingIntervalMS = 100
+ },
};
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
@@ -144,51 +213,67 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
const uint16_t wIndex,
const void** const DescriptorAddress)
{
- const uint8_t DescriptorType = (wValue >> 8);
- const uint8_t DescriptorNumber = (wValue & 0xFF);
-
- const void* Address = NULL;
- uint16_t Size = NO_DESCRIPTOR;
-
- switch (DescriptorType)
- {
- case DTYPE_Device:
- Address = &DeviceDescriptor;
- Size = sizeof(USB_Descriptor_Device_t);
- break;
- case DTYPE_Configuration:
- Address = &ConfigurationDescriptor;
- Size = sizeof(USB_Descriptor_Configuration_t);
- break;
- case DTYPE_String:
- switch (DescriptorNumber)
- {
- case STRING_ID_Language:
- Address = &LanguageString;
- Size = pgm_read_byte(&LanguageString.Header.Size);
- break;
- case STRING_ID_Manufacturer:
- Address = &ManufacturerString;
- Size = pgm_read_byte(&ManufacturerString.Header.Size);
- break;
- case STRING_ID_Product:
- Address = &ProductString;
- Size = pgm_read_byte(&ProductString.Header.Size);
- break;
- }
-
- break;
- case HID_DTYPE_HID:
- Address = &ConfigurationDescriptor.HID_KeyboardHID;
- Size = sizeof(USB_HID_Descriptor_HID_t);
- break;
- case HID_DTYPE_Report:
- Address = &KeyboardReport;
- Size = sizeof(KeyboardReport);
- break;
- }
-
- *DescriptorAddress = Address;
- return Size;
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case STRING_ID_Language:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case STRING_ID_Manufacturer:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case STRING_ID_Product:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ }
+ break;
+ case HID_DTYPE_HID:
+ switch (wIndex)
+ {
+ case INTERFACE_ID_Keyboard:
+ Address = &ConfigurationDescriptor.HID1_KeyboardHID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+ case INTERFACE_ID_MediaControl:
+ Address = &ConfigurationDescriptor.HID2_MediaControlHID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ break;
+ }
+ break;
+ case HID_DTYPE_Report:
+ switch (wIndex)
+ {
+ case INTERFACE_ID_Keyboard:
+ Address = &KeyboardReport;
+ Size = sizeof(KeyboardReport);
+ break;
+ case INTERFACE_ID_MediaControl:
+ Address = &MediaControlReport;
+ Size = sizeof(MediaControlReport);
+ break;
+ }
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
}
-
diff --git a/reform2-keyboard-fw/descriptors.h b/reform2-keyboard-fw/descriptors.h
@@ -27,9 +27,13 @@
USB_Descriptor_Configuration_Header_t Config;
// Keyboard HID Interface
- USB_Descriptor_Interface_t HID_Interface;
- USB_HID_Descriptor_HID_t HID_KeyboardHID;
- USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
+ USB_Descriptor_Interface_t HID1_KeyboardInterface;
+ USB_HID_Descriptor_HID_t HID1_KeyboardHID;
+ USB_Descriptor_Endpoint_t HID1_ReportINEndpoint;
+ // Media Control HID Interface
+ USB_Descriptor_Interface_t HID2_MediaControlInterface;
+ USB_HID_Descriptor_HID_t HID2_MediaControlHID;
+ USB_Descriptor_Endpoint_t HID2_ReportINEndpoint;
} USB_Descriptor_Configuration_t;
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
@@ -39,6 +43,7 @@
enum InterfaceDescriptors_t
{
INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */
+ INTERFACE_ID_MediaControl = 1, /**< Media Control interface descriptor ID */
};
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
@@ -56,8 +61,11 @@
/** Endpoint address of the Keyboard HID reporting IN endpoint. */
#define KEYBOARD_EPADDR (ENDPOINT_DIR_IN | 1)
- /** Size in bytes of the Keyboard HID reporting IN endpoint. */
- #define KEYBOARD_EPSIZE 8
+ /** Endpoint address of the Media Control HID reporting IN endpoint. */
+ #define MEDIACONTROL_EPADDR (ENDPOINT_DIR_IN | 3)
+
+ /** Size in bytes of HID reporting IN endpoints. */
+ #define HID_EPSIZE 8
/* Function Prototypes: */
//uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
@@ -66,4 +74,3 @@
// ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
#endif
-
diff --git a/reform2-keyboard-fw/keyboard.c b/reform2-keyboard-fw/keyboard.c
@@ -26,13 +26,14 @@
#include "scancodes.h"
#ifdef KBD_VARIANT_ELLEN
-#include "matrix_ellen.c"
+#include "matrix_ellen.h"
#else
-#include "matrix.c"
+#include "matrix.h"
#endif
/** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
+static uint8_t PrevMediaControlHIDReportBuffer[sizeof(USB_MediaReport_Data_t)];
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
@@ -46,7 +47,7 @@ USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
.ReportINEndpoint =
{
.Address = KEYBOARD_EPADDR,
- .Size = KEYBOARD_EPSIZE,
+ .Size = HID_EPSIZE,
.Banks = 1,
},
.PrevReportINBuffer = PrevKeyboardHIDReportBuffer,
@@ -54,6 +55,23 @@ USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
},
};
+/** LUFA HID Class driver interface configuration and state information for the Media Controller */
+USB_ClassInfo_HID_Device_t MediaControl_HID_Interface =
+ {
+ .Config =
+ {
+ .InterfaceNumber = INTERFACE_ID_MediaControl,
+ .ReportINEndpoint =
+ {
+ .Address = MEDIACONTROL_EPADDR,
+ .Size = HID_EPSIZE,
+ .Banks = 1,
+ },
+ .PrevReportINBuffer = PrevMediaControlHIDReportBuffer,
+ .PrevReportINBufferSize = sizeof(PrevMediaControlHIDReportBuffer),
+ },
+ };
+
uint8_t matrix_debounce[KBD_COLS*KBD_ROWS];
uint8_t matrix_state[KBD_COLS*KBD_ROWS];
@@ -79,8 +97,39 @@ void reset_keyboard_state(void) {
last_meta_key = 0;
}
+inline bool is_media_key(uint8_t keycode) {
+ return (keycode>=HID_KEYBOARD_SC_MEDIA_PLAY);
+}
+
+bool get_media_keys(uint8_t keycode, USB_MediaReport_Data_t* mcr) {
+ bool media_key = false;
+ if (keycode == HID_KEYBOARD_SC_MEDIA_MUTE) {
+ if (mcr) mcr->Mute = 1;
+ media_key = true;
+ } else if (keycode == HID_KEYBOARD_SC_MEDIA_VOLUME_UP) {
+ if (mcr) mcr->VolumeUp = 1;
+ media_key = true;
+ } else if (keycode == HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN) {
+ if (mcr) mcr->VolumeDown = 1;
+ media_key = true;
+ } else if (keycode == HID_KEYBOARD_SC_MEDIA_BACKWARD) {
+ if (mcr) mcr->PreviousTrack = 1;
+ media_key = true;
+ } else if (keycode == HID_KEYBOARD_SC_MEDIA_FORWARD) {
+ if (mcr) mcr->NextTrack = 1;
+ media_key = true;
+ } else if (keycode == HID_KEYBOARD_SC_MEDIA_PLAY) {
+ if (mcr) mcr->PlayPause = 1;
+ media_key = true;
+ }
+ return media_key;
+}
+
+#define MAX_SCANCODES 6
+static uint8_t pressed_scancodes[MAX_SCANCODES] = {0,0,0,0,0,0};
+
// usb_report_mode: if you pass 0, you can leave KeyboardReport NULL
-void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardReport) {
+int process_keyboard(uint8_t* resulting_scancodes) {
// how many keys are pressed this round
uint8_t total_pressed = 0;
uint8_t used_key_codes = 0;
@@ -98,7 +147,7 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
// wait for signal to stabilize
// TODO maybe not necessary
- _delay_us(10);
+ //_delay_us(10);
// check input COLs
for (int x=0; x<14; x++) {
@@ -170,14 +219,14 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
if (stay_meta == 2) {
reset_keyboard_state();
enter_meta_mode();
- return;
+ return 0;
}
}
} else if (!last_meta_key) {
// not meta mode, regular key: report keypress via USB
- // 6 keys is a hard limit in the HID descriptor :/
- if (usb_report_mode && KeyboardReport && used_key_codes<6) {
- KeyboardReport->KeyCode[used_key_codes++] = keycode;
+ // 6 keys is the limit in the HID descriptor
+ if (used_key_codes < MAX_SCANCODES && resulting_scancodes) {
+ resulting_scancodes[used_key_codes++] = keycode;
}
}
}
@@ -195,13 +244,13 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
if (!media_toggle) {
media_toggle = 1;
active_matrix = matrix_fn_toggled;
- } else {
+ } else {
media_toggle = 0;
- active_matrix = matrix_fn;
+ active_matrix = matrix_fn;
}
}
circle = 0;
- }
+ }
}
}
@@ -217,6 +266,8 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
// if no more keys are held down, allow a new meta command
if (total_pressed<1) last_meta_key = 0;
+
+ return used_key_codes;
}
int main(void)
@@ -238,8 +289,9 @@ int main(void)
for (;;)
{
- process_keyboard(0, NULL);
+ process_keyboard(NULL);
HID_Device_USBTask(&Keyboard_HID_Interface);
+ HID_Device_USBTask(&MediaControl_HID_Interface);
USB_USBTask();
counter++;
#ifndef KBD_VARIANT_STANDALONE
@@ -309,6 +361,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
bool ConfigSuccess = true;
ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
+ ConfigSuccess &= HID_Device_ConfigureEndpoints(&MediaControl_HID_Interface);
USB_Device_EnableSOFEvents();
}
@@ -317,12 +370,14 @@ void EVENT_USB_Device_ConfigurationChanged(void)
void EVENT_USB_Device_ControlRequest(void)
{
HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
+ HID_Device_ProcessControlRequest(&MediaControl_HID_Interface);
}
/** Event handler for the USB device Start Of Frame event. */
void EVENT_USB_Device_StartOfFrame(void)
{
HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
+ HID_Device_MillisecondElapsed(&MediaControl_HID_Interface);
}
/** HID class driver callback function for the creation of HID reports to the host.
@@ -342,11 +397,30 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn
void* ReportData,
uint16_t* const ReportSize)
{
- USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
-
- process_keyboard(1, KeyboardReport);
-
- *ReportSize = sizeof(USB_KeyboardReport_Data_t);
+ int num_keys = process_keyboard(pressed_scancodes);
+ if (num_keys > MAX_SCANCODES) num_keys = MAX_SCANCODES;
+
+ if (HIDInterfaceInfo == &Keyboard_HID_Interface) {
+ // host asks for a keyboard report
+ USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+ *ReportSize = sizeof(USB_KeyboardReport_Data_t);
+ for (int i=0; i<num_keys; i++) {
+ uint8_t sc = pressed_scancodes[i];
+ if (!is_media_key(sc)) {
+ KeyboardReport->KeyCode[i] = sc;
+ }
+ }
+ } else if (HIDInterfaceInfo == &MediaControl_HID_Interface) {
+ // host asks for a media control report
+ USB_MediaReport_Data_t* MediaControlReport = (USB_MediaReport_Data_t*)ReportData;
+ *ReportSize = sizeof(USB_MediaReport_Data_t);
+ for (int i=0; i<num_keys; i++) {
+ uint8_t sc = pressed_scancodes[i];
+ if (is_media_key(sc)) {
+ get_media_keys(sc, MediaControlReport);
+ }
+ }
+ }
return false;
}
diff --git a/reform2-keyboard-fw/keyboard.h b/reform2-keyboard-fw/keyboard.h
@@ -125,6 +125,23 @@
HID_KEYBOARD_SC_DOWN_ARROW,\
HID_KEYBOARD_SC_RIGHT_ARROW
+// MediaController USB Report
+typedef struct
+{
+ unsigned Play : 1;
+ unsigned Pause : 1;
+ unsigned FForward : 1;
+ unsigned Rewind : 1;
+ unsigned NextTrack : 1;
+ unsigned PreviousTrack : 1;
+ unsigned Stop : 1;
+ unsigned PlayPause : 1;
+ unsigned Mute : 1;
+ unsigned VolumeUp : 1;
+ unsigned VolumeDown : 1;
+ unsigned RESERVED : 5;
+} ATTR_PACKED USB_MediaReport_Data_t;
+
void setup_hardware(void);
void reset_keyboard_state(void);
diff --git a/reform2-keyboard-fw/matrix.c b/reform2-keyboard-fw/matrix.c
@@ -1,71 +0,0 @@
-/*
- MNT Reform 2.0 Keyboard Firmware
- See keyboard.c for Copyright
- SPDX-License-Identifier: MIT
-*/
-
-#include "keyboard.h"
-
-// Every line of `matrix` is a row of the keyboard, starting from the top.
-// Check keyboard.h for the definitions of the default rows.
-uint8_t matrix[KBD_MATRIX_SZ] = {
- MATRIX_DEFAULT_ROW_1,
- MATRIX_DEFAULT_ROW_2,
- MATRIX_DEFAULT_ROW_3,
- MATRIX_DEFAULT_ROW_4,
- MATRIX_DEFAULT_ROW_5,
- MATRIX_DEFAULT_ROW_6,
-
- // Marker for layout editor (FIXME)
- KBD_EDITOR_MARKER
-};
-
-// When holding down HYPER
-uint8_t matrix_fn[KBD_MATRIX_SZ] = {
- // Media keys (not working, FIXME)
- KEY_ESCAPE,
- KEY_F1,
- KEY_F2,
- KEY_F3,
- KEY_F4,
- KEY_F5,
- KEY_F6,
- HID_KEYBOARD_SC_MEDIA_BACKWARD,
- HID_KEYBOARD_SC_MEDIA_PLAY,
- HID_KEYBOARD_SC_MEDIA_FORWARD,
- 173, // mute
- 174, // volume down
- 175, // volume up
- KEY_CIRCLE,
-
- MATRIX_DEFAULT_ROW_2,
- MATRIX_DEFAULT_ROW_3,
- MATRIX_DEFAULT_ROW_4,
- MATRIX_DEFAULT_ROW_5,
- MATRIX_DEFAULT_ROW_6
-};
-
-// Second layer (toggled by HYPER+CIRCLE)
-uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
- // Custom top row
- KEY_ESCAPE,
- KEY_F1,
- KEY_F2,
- KEY_F3,
- KEY_F4,
- KEY_F5,
- KEY_F6,
- HID_KEYBOARD_SC_MEDIA_BACKWARD,
- HID_KEYBOARD_SC_MEDIA_PLAY,
- HID_KEYBOARD_SC_MEDIA_FORWARD,
- 173,
- 174,
- 175,
- KEY_CIRCLE,
-
- MATRIX_DEFAULT_ROW_2,
- MATRIX_DEFAULT_ROW_3,
- MATRIX_DEFAULT_ROW_4,
- MATRIX_DEFAULT_ROW_5,
- MATRIX_DEFAULT_ROW_6
-};
diff --git a/reform2-keyboard-fw/matrix.h b/reform2-keyboard-fw/matrix.h
@@ -0,0 +1,71 @@
+/*
+ MNT Reform 2.0 Keyboard Firmware
+ See keyboard.c for Copyright
+ SPDX-License-Identifier: MIT
+*/
+
+#include "keyboard.h"
+
+// Every line of `matrix` is a row of the keyboard, starting from the top.
+// Check keyboard.h for the definitions of the default rows.
+uint8_t matrix[KBD_MATRIX_SZ] = {
+ MATRIX_DEFAULT_ROW_1,
+ MATRIX_DEFAULT_ROW_2,
+ MATRIX_DEFAULT_ROW_3,
+ MATRIX_DEFAULT_ROW_4,
+ MATRIX_DEFAULT_ROW_5,
+ MATRIX_DEFAULT_ROW_6,
+
+ // Marker for layout editor (FIXME)
+ KBD_EDITOR_MARKER
+};
+
+// When holding down HYPER
+uint8_t matrix_fn[KBD_MATRIX_SZ] = {
+ // Media keys (not working, FIXME)
+ KEY_ESCAPE,
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ HID_KEYBOARD_SC_MEDIA_BACKWARD,
+ HID_KEYBOARD_SC_MEDIA_PLAY,
+ HID_KEYBOARD_SC_MEDIA_FORWARD,
+ HID_KEYBOARD_SC_MEDIA_MUTE,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
+ KEY_CIRCLE,
+
+ MATRIX_DEFAULT_ROW_2,
+ MATRIX_DEFAULT_ROW_3,
+ MATRIX_DEFAULT_ROW_4,
+ MATRIX_DEFAULT_ROW_5,
+ MATRIX_DEFAULT_ROW_6
+};
+
+// Second layer (toggled by HYPER+CIRCLE)
+uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
+ // Custom top row
+ KEY_ESCAPE,
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ HID_KEYBOARD_SC_MEDIA_BACKWARD,
+ HID_KEYBOARD_SC_MEDIA_PLAY,
+ HID_KEYBOARD_SC_MEDIA_FORWARD,
+ HID_KEYBOARD_SC_MEDIA_MUTE,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
+ KEY_CIRCLE,
+
+ MATRIX_DEFAULT_ROW_2,
+ MATRIX_DEFAULT_ROW_3,
+ MATRIX_DEFAULT_ROW_4,
+ MATRIX_DEFAULT_ROW_5,
+ MATRIX_DEFAULT_ROW_6
+};
diff --git a/reform2-keyboard-fw/matrix_ellen.c b/reform2-keyboard-fw/matrix_ellen.c
@@ -1,125 +0,0 @@
-/*
- MNT Reform 2.0 Keyboard Firmware
- See keyboard.c for Copyright
- SPDX-License-Identifier: MIT
-*/
-
-#include "keyboard.h"
-
-// Every line of `matrix` is a row of the keyboard, starting from the top.
-// Check keyboard.h for the definitions of the default rows.
-uint8_t matrix[KBD_MATRIX_SZ] = {
- MATRIX_DEFAULT_ROW_1,
- MATRIX_DEFAULT_ROW_2,
- MATRIX_DEFAULT_ROW_3,
- MATRIX_DEFAULT_ROW_4,
- MATRIX_DEFAULT_ROW_5,
-
- // Custom row six
- HID_KEYBOARD_SC_LEFT_CONTROL,
- HID_KEYBOARD_SC_LEFT_ALT,
- HID_KEYBOARD_SC_LEFT_GUI,
- KEY_SPACE,
- KEY_SPACE,
- KEY_SPACE,
- KEY_SPACE,
- HID_KEYBOARD_SC_RIGHT_ALT,
- HID_KEYBOARD_SC_EXECUTE,
- HID_KEYBOARD_SC_LEFT_ARROW,
- HID_KEYBOARD_SC_DOWN_ARROW,
- HID_KEYBOARD_SC_RIGHT_ARROW,
-
- // Marker for layout editor (FIXME)
- KBD_EDITOR_MARKER
-};
-
-// When holding down HYPER
-uint8_t matrix_fn[KBD_MATRIX_SZ] = {
- // Custom top row
- KEY_ESCAPE,
- KEY_F1,
- KEY_F2,
- KEY_F3,
- KEY_F4,
- KEY_F5,
- KEY_F6,
- HID_KEYBOARD_SC_MEDIA_BACKWARD,
- HID_KEYBOARD_SC_MEDIA_PLAY,
- HID_KEYBOARD_SC_MEDIA_FORWARD,
- 173, // mute
- 174, // volume down
- 175, // volume up
- KEY_CIRCLE,
-
- MATRIX_DEFAULT_ROW_2,
- MATRIX_DEFAULT_ROW_3,
- MATRIX_DEFAULT_ROW_4,
-
- // Custom row 5
- HID_KEYBOARD_SC_LEFT_SHIFT,
- HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE,
- KEY_Z,
- KEY_X,
- KEY_C,
- KEY_V,
- KEY_B,
- KEY_N,
- KEY_M,
- HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN,
- HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN,
- KEY_SLASH_AND_QUESTION_MARK,
- HID_KEYBOARD_SC_PAGE_UP,
- HID_KEYBOARD_SC_RIGHT_SHIFT,
-
- // Custom row 6
- HID_KEYBOARD_SC_LEFT_CONTROL,
- HID_KEYBOARD_SC_LEFT_ALT,
- HID_KEYBOARD_SC_LEFT_GUI,
- KEY_SPACE,
- KEY_SPACE,
- KEY_SPACE,
- KEY_SPACE,
- HID_KEYBOARD_SC_RIGHT_ALT,
- HID_KEYBOARD_SC_EXECUTE,
- HID_KEYBOARD_SC_HOME,
- HID_KEYBOARD_SC_PAGE_DOWN,
- HID_KEYBOARD_SC_END
-};
-
-// Second layer (toggled by HYPER+CIRCLE)
-uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
- // Custom top row
- KEY_ESCAPE,
- KEY_F1,
- KEY_F2,
- KEY_F3,
- KEY_F4,
- KEY_F5,
- KEY_F6,
- HID_KEYBOARD_SC_MEDIA_BACKWARD,
- HID_KEYBOARD_SC_MEDIA_PLAY,
- HID_KEYBOARD_SC_MEDIA_FORWARD,
- 173,
- 174,
- 175,
- KEY_CIRCLE,
-
- MATRIX_DEFAULT_ROW_2,
- MATRIX_DEFAULT_ROW_3,
- MATRIX_DEFAULT_ROW_4,
- MATRIX_DEFAULT_ROW_5,
-
- // Custom row six
- HID_KEYBOARD_SC_LEFT_CONTROL,
- HID_KEYBOARD_SC_LEFT_ALT,
- HID_KEYBOARD_SC_LEFT_GUI,
- KEY_SPACE,
- KEY_SPACE,
- KEY_SPACE,
- KEY_SPACE,
- HID_KEYBOARD_SC_RIGHT_ALT,
- HID_KEYBOARD_SC_EXECUTE,
- HID_KEYBOARD_SC_LEFT_ARROW,
- HID_KEYBOARD_SC_DOWN_ARROW,
- HID_KEYBOARD_SC_RIGHT_ARROW
-};
diff --git a/reform2-keyboard-fw/matrix_ellen.h b/reform2-keyboard-fw/matrix_ellen.h
@@ -0,0 +1,125 @@
+/*
+ MNT Reform 2.0 Keyboard Firmware
+ See keyboard.c for Copyright
+ SPDX-License-Identifier: MIT
+*/
+
+#include "keyboard.h"
+
+// Every line of `matrix` is a row of the keyboard, starting from the top.
+// Check keyboard.h for the definitions of the default rows.
+uint8_t matrix[KBD_MATRIX_SZ] = {
+ MATRIX_DEFAULT_ROW_1,
+ MATRIX_DEFAULT_ROW_2,
+ MATRIX_DEFAULT_ROW_3,
+ MATRIX_DEFAULT_ROW_4,
+ MATRIX_DEFAULT_ROW_5,
+
+ // Custom row six
+ HID_KEYBOARD_SC_LEFT_CONTROL,
+ HID_KEYBOARD_SC_LEFT_ALT,
+ HID_KEYBOARD_SC_LEFT_GUI,
+ KEY_SPACE,
+ KEY_SPACE,
+ KEY_SPACE,
+ KEY_SPACE,
+ HID_KEYBOARD_SC_RIGHT_ALT,
+ HID_KEYBOARD_SC_EXECUTE,
+ HID_KEYBOARD_SC_LEFT_ARROW,
+ HID_KEYBOARD_SC_DOWN_ARROW,
+ HID_KEYBOARD_SC_RIGHT_ARROW,
+
+ // Marker for layout editor (FIXME)
+ KBD_EDITOR_MARKER
+};
+
+// When holding down HYPER
+uint8_t matrix_fn[KBD_MATRIX_SZ] = {
+ // Custom top row
+ KEY_ESCAPE,
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ HID_KEYBOARD_SC_MEDIA_BACKWARD,
+ HID_KEYBOARD_SC_MEDIA_PLAY,
+ HID_KEYBOARD_SC_MEDIA_FORWARD,
+ HID_KEYBOARD_SC_MEDIA_MUTE,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
+ KEY_CIRCLE,
+
+ MATRIX_DEFAULT_ROW_2,
+ MATRIX_DEFAULT_ROW_3,
+ MATRIX_DEFAULT_ROW_4,
+
+ // Custom row 5
+ HID_KEYBOARD_SC_LEFT_SHIFT,
+ HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE,
+ KEY_Z,
+ KEY_X,
+ KEY_C,
+ KEY_V,
+ KEY_B,
+ KEY_N,
+ KEY_M,
+ HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN,
+ HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN,
+ KEY_SLASH_AND_QUESTION_MARK,
+ HID_KEYBOARD_SC_PAGE_UP,
+ HID_KEYBOARD_SC_RIGHT_SHIFT,
+
+ // Custom row 6
+ HID_KEYBOARD_SC_LEFT_CONTROL,
+ HID_KEYBOARD_SC_LEFT_ALT,
+ HID_KEYBOARD_SC_LEFT_GUI,
+ KEY_SPACE,
+ KEY_SPACE,
+ KEY_SPACE,
+ KEY_SPACE,
+ HID_KEYBOARD_SC_RIGHT_ALT,
+ HID_KEYBOARD_SC_EXECUTE,
+ HID_KEYBOARD_SC_HOME,
+ HID_KEYBOARD_SC_PAGE_DOWN,
+ HID_KEYBOARD_SC_END
+};
+
+// Second layer (toggled by HYPER+CIRCLE)
+uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
+ // Custom top row
+ KEY_ESCAPE,
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ HID_KEYBOARD_SC_MEDIA_BACKWARD,
+ HID_KEYBOARD_SC_MEDIA_PLAY,
+ HID_KEYBOARD_SC_MEDIA_FORWARD,
+ HID_KEYBOARD_SC_MEDIA_MUTE,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+ HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
+ KEY_CIRCLE,
+
+ MATRIX_DEFAULT_ROW_2,
+ MATRIX_DEFAULT_ROW_3,
+ MATRIX_DEFAULT_ROW_4,
+ MATRIX_DEFAULT_ROW_5,
+
+ // Custom row six
+ HID_KEYBOARD_SC_LEFT_CONTROL,
+ HID_KEYBOARD_SC_LEFT_ALT,
+ HID_KEYBOARD_SC_LEFT_GUI,
+ KEY_SPACE,
+ KEY_SPACE,
+ KEY_SPACE,
+ KEY_SPACE,
+ HID_KEYBOARD_SC_RIGHT_ALT,
+ HID_KEYBOARD_SC_EXECUTE,
+ HID_KEYBOARD_SC_LEFT_ARROW,
+ HID_KEYBOARD_SC_DOWN_ARROW,
+ HID_KEYBOARD_SC_RIGHT_ARROW
+};