reform

MNT Reform: Open Source Portable Computer
Log (Feed) | Files | Refs (Tags) | README

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:
Mreform2-keyboard-fw/README.md | 6++----
Mreform2-keyboard-fw/constants.h | 4++--
Mreform2-keyboard-fw/descriptors.c | 289+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Mreform2-keyboard-fw/descriptors.h | 19+++++++++++++------
Mreform2-keyboard-fw/keyboard.c | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mreform2-keyboard-fw/keyboard.h | 17+++++++++++++++++
Dreform2-keyboard-fw/matrix.c | 71-----------------------------------------------------------------------
Areform2-keyboard-fw/matrix.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dreform2-keyboard-fw/matrix_ellen.c | 125-------------------------------------------------------------------------------
Areform2-keyboard-fw/matrix_ellen.h | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 +};