Skip to content

Commit

Permalink
Merge pull request #6 from drashna/feature/qmk_bootloader_hid
Browse files Browse the repository at this point in the history
  • Loading branch information
fauxpark committed Jul 18, 2021
2 parents 596cb24 + b2efce1 commit c7c5f65
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 65 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@
Documentation/
node_modules/
Bootloaders/DFU/Keyboard.h
.vscode/ipch/
Bootloaders/HID/Keyboard.h
.vscode/ipch/
.DS_Store
42 changes: 40 additions & 2 deletions Bootloaders/HID/BootloaderHID.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,31 @@ int main(void)
/* Setup hardware required for the bootloader */
SetupHardware();

/* Turn on first LED on the board to indicate that the bootloader has started */
LEDs_SetAllLEDs(LEDS_LED1 | LEDS_LED2);

/* Enable global interrupts so that the USB stack can function */
GlobalInterruptEnable();

while (RunBootloader)
#if (BOARD == BOARD_QMK)
USB_USBTask();
uint16_t keypress = 0;
#endif

while (RunBootloader) {
USB_USBTask();
#if (BOARD == BOARD_QMK)
bool pressed = (PIN(QMK_ESC_INPUT) & NUM(QMK_ESC_INPUT));
if ((keypress > 5000) && pressed) {
break;
}
if (pressed) {
keypress++;
} else {
keypress = 0;
}
#endif
}

/* Wait a short time to end all USB transactions and then disconnect */
_delay_us(1000);
Expand Down Expand Up @@ -113,8 +133,27 @@ static void SetupHardware(void)
MCUCR = (1 << IVCE);
MCUCR = (1 << IVSEL);

#if (BOARD == BOARD_QMK)
// output setup
DDR(QMK_ESC_OUTPUT) |= NUM(QMK_ESC_OUTPUT);
PORT(QMK_ESC_OUTPUT) |= NUM(QMK_ESC_OUTPUT);

// input setup
DDR(QMK_ESC_INPUT) |= NUM(QMK_ESC_INPUT);
#endif

/* Initialize USB subsystem */
USB_Init();
LEDs_Init();

/* Bootloader active LED toggle timer initialization */
TIMSK1 = (1 << TOIE1);
TCCR1B = ((1 << CS11) | (1 << CS10));
}

/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
ISR(TIMER1_OVF_vect, ISR_BLOCK) {
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
}

/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
Expand Down Expand Up @@ -208,4 +247,3 @@ void EVENT_USB_Device_ControlRequest(void)
break;
}
}

2 changes: 2 additions & 0 deletions Bootloaders/HID/BootloaderHID.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
#include "Descriptors.h"

#include <LUFA/Drivers/USB/USB.h>
#include <LUFA/Drivers/Board/LEDs.h>
#include <LUFA/Platform/Platform.h>
#include <LUFA/Common/Common.h>

/* Preprocessor Checks: */
#if !defined(__OPTIMIZE_SIZE__)
Expand Down
49 changes: 46 additions & 3 deletions Bootloaders/HID/Descriptors.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@
*/

#include "Descriptors.h"
#include "Keyboard.h"

#ifndef MANUFACTURER
#define MANUFACTURER QMK
#endif
#ifndef PRODUCT
#define PRODUCT Keyboard
#endif

/** 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
Expand Down Expand Up @@ -77,8 +85,8 @@ const USB_Descriptor_Device_t DeviceDescriptor =
.ProductID = 0x2067,
.ReleaseNumber = VERSION_BCD(0,0,1),

.ManufacturerStrIndex = NO_DESCRIPTOR,
.ProductStrIndex = NO_DESCRIPTOR,
.ManufacturerStrIndex = STRING_ID_Manufacturer,
.ProductStrIndex = STRING_ID_Product,
.SerialNumStrIndex = NO_DESCRIPTOR,

.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
Expand Down Expand Up @@ -144,6 +152,24 @@ const USB_Descriptor_Configuration_t ConfigurationDescriptor =
},
};

/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
*/
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);

/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(LSTR(MANUFACTURER));

/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
* Descriptor.
*/
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(LSTR(PRODUCT));

/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
* documentation) by the application code so that the address and size of a requested descriptor can be given
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
Expand All @@ -155,6 +181,7 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
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;
Expand All @@ -180,8 +207,24 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
Address = &HIDReport;
Size = sizeof(HIDReport);
}
else if (DescriptorType == DTYPE_String) {
if (DescriptorNumber == STRING_ID_Language)
{
Address = &LanguageString;
Size = LanguageString.Header.Size;
}
else if (DescriptorNumber == STRING_ID_Manufacturer)
{
Address = &ManufacturerString;
Size = ManufacturerString.Header.Size;
}
else if (DescriptorNumber == STRING_ID_Product)
{
Address = &ProductString;
Size = ProductString.Header.Size;
}
}

*DescriptorAddress = Address;
return Size;
}

19 changes: 17 additions & 2 deletions Bootloaders/HID/Descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,16 @@
{
INTERFACE_ID_GenericHID = 0, /**< GenericHID interface descriptor ID */
};

/** Enum for the device string descriptor IDs within the device. Each string descriptor should
* have a unique ID index associated with it, which can be used to refer to the string from
* other descriptors.
*/
enum StringDescriptors_t
{
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
STRING_ID_Product = 2, /**< Product string ID */
};
/* Macros: */
/** Endpoint address of the HID data IN endpoint. */
#define HID_IN_EPADDR (ENDPOINT_DIR_IN | 1)
Expand All @@ -76,5 +85,11 @@
const void** const DescriptorAddress)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);

#endif
// convert to L string
#define LSTR(s) XLSTR(s)
#define XLSTR(s) L ## #s
// convert to string
#define STR(s) XSTR(s)
#define XSTR(s) #s

#endif
14 changes: 7 additions & 7 deletions Bootloaders/HID/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

# Run "make help" for target help.

MCU = at90usb1287
ARCH = AVR8
BOARD = USBKEY
F_CPU = 8000000
F_USB = $(F_CPU)
MCU ?= atmega32u4
ARCH ?= AVR8
BOARD = QMK
F_CPU ?= 16000000
F_USB ?= $(F_CPU)
OPTIMIZATION = s
TARGET = BootloaderHID
SRC = $(TARGET).c Descriptors.c $(LUFA_SRC_USB)
Expand All @@ -27,8 +27,8 @@ LTO = Y
# Flash size and bootloader section sizes of the target, in KB. These must
# match the target's total FLASH size and the bootloader size set in the
# device's fuses.
FLASH_SIZE_KB := 128
BOOT_SECTION_SIZE_KB := 8
FLASH_SIZE_KB ?= 32
BOOT_SECTION_SIZE_KB ?= 4

# Bootloader address calculation formulas
# Do not modify these macros, but rather modify the dependent values above.
Expand Down

0 comments on commit c7c5f65

Please sign in to comment.